1. #include <iostream> 
  2. #define MAXSIZE  20 
  3. using namespace std; 
  4.  
  5. int total = 4; 
  6.  
  7.  
  8. typedef char ElemType; 
  9. typedef struct  
  10.     ElemType elem[MAXSIZE]; 
  11.     int top; 
  12. }SqStack; 
  13.  
  14. typedef struct  
  15.     float elem[MAXSIZE]; 
  16.     int top; 
  17. }FSqStack; 
  18.  
  19. typedef struct LinkNode 
  20.     int data; 
  21.     struct LinkNode *next; 
  22. }LinkStack; 
  23.  
  24.  
  25.  
  26. SqStack *pst = NULL; 
  27.  
  28. template<typename T> 
  29. void InitSqStack(T *&st) 
  30.     st->top = -1; 
  31.  
  32. template<typename T> 
  33. int StackEmpty(T *&st) 
  34.     return st->top == -1 ? 1 : 0; 
  35.  
  36. template<typename T,typename N> 
  37. int Push(T *&st, N e) 
  38.     if(st->top >= MAXSIZE - 1) 
  39.         return -1; 
  40.     st->top++; 
  41.     st->elem[st->top] = e; 
  42.     return 1; 
  43.  
  44. template<typename T,typename N> 
  45. int Pop(T *&st, N &e) 
  46.     if(st->top < 0) 
  47.         return -1; 
  48.     e = st->elem[st->top]; 
  49.     st->top--; 
  50.     return 1; 
  51.  
  52.  
  53. //一下是链栈的初始化 
  54. int InitLinkStack(LinkStack *&ls) 
  55.     ls = (LinkStack *)malloc(sizeof(LinkStack)); 
  56.     ls->next = NULL; 
  57.     return 1; 
  58.  
  59. int Push(LinkStack *&ls, int e) 
  60.     LinkStack *temp = (LinkStack *)malloc(sizeof(LinkStack));    
  61.     if(temp == NULL) return -1; 
  62.     temp->data = e; 
  63.     temp->next = ls; 
  64.     ls = temp; 
  65.     return 1; 
  66.  
  67. int Pop(LinkStack *&ls,int &e) 
  68.     LinkStack *temp = NULL; 
  69.   
  70.     if(ls == NULL ||ls->next == NULL)         //此处应该把ls == NULL 的顺序放在前面, 要不然会发生非法内存访问 
  71.     {   cout<<"栈已经为空"<<endl; 
  72.         return -1;  
  73.     } 
  74.     else 
  75.     { 
  76.         temp = ls; 
  77.         e = temp->data; 
  78.         ls = ls->next; 
  79.         free(temp); 
  80.     } 
  81.     return 1; 
  82.  
  83. int StackEmpty(LinkStack *&lt) 
  84.     if(lt == NULL || lt->next == NULL) 
  85.         return 1; 
  86.     else return 0; 
  87.  
  88. int DelLinkStack(LinkStack *&ls) 
  89.     LinkStack *temp = ls; 
  90.     if(ls == NULL)  return 1; 
  91.     while(temp != NULL) 
  92.     { 
  93.         temp = ls->next; 
  94.         free(ls); 
  95.         if(temp == NULL){ ls = NULL;  return 1;  }        //此处应该把ls 赋值为NULL 。 有利于其他函数进行判断 
  96.         ls = temp; 
  97.     } 
  98.     ls = NULL; 
  99.     return 1; 
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108. void tran(char exp[], char postExp[])    //本函数的目的是把算术表达式转换为后缀表达式(逆波兰表达式),然后根据该后缀表达式求值 
  109.     int loop1=0, loop2=0; 
  110.     SqStack *op = (SqStack *)malloc(sizeof(SqStack));  //此处定义一个符号栈指针 
  111.     char c = exp[loop1++], temp; 
  112.     if(op == NULL )  return ; 
  113.     InitSqStack(op); 
  114.     while(c != '\0')              //遍历表达式exp 
  115.     {   //cout<<c<<endl; 
  116.         switch(c) 
  117.         { 
  118.         case '(':               //遇到'('的时候把它进栈 
  119.             Push(op,c); 
  120.             c = exp[loop1++]; 
  121.             break;  
  122.         case ')':               //遇到')'的时候把 '( '以后的符号 出栈,把出栈的符号放进postExp后缀数组中 
  123.             if(!StackEmpty(op)) 
  124.             { 
  125.                 Pop(op,temp); 
  126.                 while(temp != '('
  127.                 { 
  128.                     postExp[loop2++] = temp; 
  129.                     Pop(op,temp); 
  130.                 } 
  131.             } 
  132.             c = exp[loop1++]; 
  133.             break
  134.         case '+'
  135.         case '-':                 //当遇到'+','-' 的时候,如有'('则把其之后的符号出栈,放进postExp数组中,但是'('不出栈,  最后把 '+','-'进栈 
  136.             if(!StackEmpty(op))   //如果没有'(' 那么就把全部的符号出栈,放进postExp数组中,最后在把'+','-'进栈 
  137.             {// cout<<"if here is running"<<endl; 
  138.                 Pop(op,temp); 
  139.                 while(temp != '(' ) 
  140.                 {//&& !StackEmpty(op) 
  141.                 //  cout<<"look - or +  value is :"<<temp<<endl; 
  142.                 //  system("pause"); 
  143.                     postExp[loop2++] = temp; 
  144.                     if(!StackEmpty(op)) 
  145.                     {   //cout<<"not empty"<<endl; 
  146.                         Pop(op,temp); 
  147.                     }else 
  148.                     { 
  149.                         break
  150.                     } 
  151.                 } 
  152.                 if(temp == '(') Push(op, '('); 
  153.                 Push(op,c); 
  154.             }else 
  155.             { 
  156.                 Push(op,c); 
  157.             } 
  158.  
  159.             c = exp[loop1++];  
  160.             break
  161.         case '*':                //当遇到'*','/'的时候, 如栈顶的元素是'*','/'的时候则出栈,一直到遇到'(' 或者栈为空为止, 最后通遇到'+','-'一样把'*','/'进栈 
  162.         case '/'
  163.             if(!StackEmpty(op))  //不为空的时候进行操作 
  164.             { 
  165.                 Pop(op, temp); 
  166.                 if(temp != '*' || temp != '/'
  167.                 {   Push(op, temp);} 
  168.                 else 
  169.                 { 
  170.                     while(temp == '*' || temp == '/' ) 
  171.                     {   postExp[loop2++] = temp; 
  172.                         if(StackEmpty(op))  break
  173.                         Pop(op,temp);                    
  174.                     } 
  175.                 //  if(!StackEmpty(op)) Push(op, temp); 
  176.                     Push(op,temp); 
  177.                 } 
  178.             } 
  179.             Push(op,c); 
  180.             c = exp[loop1++]; 
  181.             break
  182.         default :                 //到遇到数字的时候,就一个个取出来,不进栈,而是直接放入到postExp数组中,直到不是数字为止在postExp中加一个'#'以示区别  
  183.             postExp[loop2++] = c; 
  184.             c = exp[loop1++]; 
  185.             while(c <= '9' && c >= '0'
  186.             {   postExp[loop2++] = c; 
  187.                 c = exp[loop1++]; 
  188.             } 
  189.             postExp[loop2++] = '#'
  190.             break
  191.         } 
  192.     } 
  193.     while(!StackEmpty(op))      //如果栈中还有符号元素,则把它们全部取出,放入postExp数组中 
  194.     { 
  195.         Pop(op, temp); 
  196.         postExp[loop2++] = temp; 
  197.     } 
  198.     postExp[loop2] = '\0';   
  199.  
  200. int compvalue(char postExp[], float &value)   //此函数的作用是通过tran求的逆波兰表达式,来计算该表达式的值 
  201.     char c; 
  202.     int loop1 = 0, IntValue = 0; 
  203.     float midValue = 0, tempValue1 = 0, tempValue2 = 0;     //此处定义一个数字栈 
  204.     FSqStack *fst = (FSqStack *)malloc(sizeof(FSqStack)); 
  205.     if(fst == NULL) 
  206.         return -1; 
  207.     InitSqStack(fst); 
  208.     c = postExp[loop1++]; 
  209.     while(c != '\0')           //变量postExp数组 
  210.     { 
  211.         switch(c) 
  212.         { 
  213.         case '+' :         //当遇到'+'的时候,出栈两个数,把出栈的两个数相加,然后入栈 
  214.             Pop(fst,tempValue1); 
  215.             Pop(fst,tempValue2); 
  216.             midValue = tempValue2 + tempValue1; 
  217.             Push(fst, midValue); 
  218.             c = postExp[loop1++]; 
  219.             break
  220.         case '-' :        //当遇到'-'的时候,出栈两个数,把出栈的两个数相减,然后入栈 
  221.             Pop(fst,tempValue1); 
  222.             Pop(fst,tempValue2); 
  223.             midValue = tempValue2 - tempValue1; 
  224.             Push(fst,midValue); 
  225.             c = postExp[loop1++]; 
  226.             break
  227.         case '*' :        //当遇到'*'的时候,出栈两个数,把出栈的两个数相乘,然后入栈 
  228.             Pop(fst,tempValue1); 
  229.             Pop(fst,tempValue2); 
  230.             midValue = tempValue1 * tempValue2; 
  231.             Push(fst,midValue); 
  232.             c = postExp[loop1++]; 
  233.             break
  234.         case '/' :           //当遇到'/'的时候,出栈两个数,把出栈的两个数相除,然后入栈 
  235.             Pop(fst,tempValue1); 
  236.             Pop(fst,tempValue2); 
  237.             if(tempValue2 == 0) {  cout<<"发生除零错误"<<endl; exit(0);} 
  238.             midValue = tempValue2 / tempValue1;          
  239.             Push(fst, midValue); 
  240.             c = postExp[loop1++]; 
  241.             break
  242.         default :        //在此表示遇到了数字, 通过 一定的表达式来求得 该数字的值 ,然后把该数字入栈 
  243.             IntValue = 0; 
  244.             IntValue = c - '0'
  245.             c = postExp[loop1++]; 
  246.             while(c != '#'
  247.             { 
  248.                 IntValue *= 10; 
  249.                 IntValue += (c - '0'); 
  250.                 c = postExp[loop1++]; 
  251.             } 
  252.             Push(fst,(float)IntValue); 
  253.             c = postExp[loop1++]; 
  254.             break
  255.         } 
  256.     } 
  257.     if(!StackEmpty(fst)) 
  258.     {   cout<<"求的值为下:"<<endl; 
  259.         Pop(fst,value); 
  260.     } 
  261.     return 1; 
  262.  
  263. void process(int pos, int path[], int curp)       //此函数中的pos值只能通过恢复到栈原来的环境,来恢复pos的值,本函数中没有直接操作pos值的语句除了递归函数的语句外 
  264. {  
  265.     int m,i,x; 
  266.     if(pos <= total) 
  267.     { 
  268.         Push(pst, pos); 
  269.         process(pos+1,path,curp); 
  270.         Pop(pst,x); 
  271.     }                                          //此递归和回代的过程,只改变pos的值,栈中的数据不变 
  272.     if(!StackEmpty(pst)) 
  273.     { 
  274.         Pop(pst,m); 
  275.         path[curp] = m; 
  276.         curp++; 
  277.         process(pos,path,curp); 
  278.         Push(pst,m); 
  279.     } 
  280.     if(pos>total && StackEmpty(pst)) 
  281.     { 
  282.         cout<<"  "
  283.         for(i=0; i<curp; i++) 
  284.             cout<<path[i]<<"  "
  285.         cout<<endl; 
  286.     } 
  287. }                 //此函数是全排列的一个实现 
  288.  
  289.  
  290. void quanpailie(char str[], int begin, int length) 
  291.     int loop1 = 0, loop2 = 0; 
  292.     char temp; 
  293.     if(begin == length - 1) 
  294.         cout<<str<<endl; 
  295.     for(loop1 = begin; loop1 < length; loop1++) 
  296.     { 
  297.         temp = str[begin]; 
  298.         str[begin] = str[begin + loop2]; 
  299.         str[begin + loop2] = temp; 
  300.         quanpailie(str, begin + 1, length); 
  301.  
  302.         temp = str[begin]; 
  303.         str[begin] = str[begin + loop2]; 
  304.         str[begin + loop2] = temp;                    //以下代码是为了恢复之前的环境 
  305.         loop2++; 
  306.     } 
  307. /* 
  308.     begin表示str开始的位置,length表示字符串的长度 
  309.     此算法的思路是 从第一个字符开始, 第一个字符依次与其本身以及其后面的字符交换,每次交换后进行递归操作,是begin+1, 开始操作下一个字符,当操作到最后一个字符的时候 
  310.     进行输出,    并且在递归调用后进行 恢复环境操作 
  311. */ 
  312. void quanpailie2(char str[], int end)           //此函数的功能与上一个一样 
  313. {  
  314.     int loop1 = 0, loop2 = 0; 
  315.     char temp; 
  316.     if(end == 0) 
  317.         cout<<str<<endl; 
  318.     for(loop1 = 0; loop1 <= end; loop1++) 
  319.     { 
  320.         temp = str[end]; 
  321.         str[end] = str[loop1]; 
  322.         str[loop1] = temp; 
  323.  
  324.         quanpailie2(str, end - 1); 
  325.  
  326.         temp = str[end]; 
  327.         str[end] = str[loop1]; 
  328.         str[loop1] = temp; 
  329.         loop2++; 
  330.     } 
  331. /* 
  332.     此函数的思想是 先把第一个字符与最后一个字符交换, 然后从最后一个字符向前遍历,直到遇到第一个字符,此函数的思想与上一个不同 
  333. */ 
  334.  
  335. void get_command() { 
  336.  cout<<"\n请输入要进行运算的表达式,包括\" +,-,*,/,=,(,)\"和数字,"<<endl 
  337.   <<"例如:\" 3+2*(6-25/4)-8 \"."<<endl 
  338.   <<"注意: 以数字开头,等号结尾,中间括号要匹配."<<endl; 
  339.  
  340.  
  341. int main() 
  342. /*  int path[5]; 
  343.     pst = (SqStack *)malloc(sizeof(SqStack)); 
  344.     InitSqStack(pst); 
  345.     process(1,path,0); 
  346. */   
  347.     char exp[80], postExp[100];  
  348.     float value; 
  349.     while(true
  350.     { 
  351. //      cout<<"输入'q'退出"<<endl<<"输入表达式:"<<endl; 
  352.         get_command(); 
  353.         cin>>exp; 
  354.         strcpy(postExp,"\0"); 
  355.         if(exp[0] == 'q'break
  356.  
  357.         tran(exp, postExp); 
  358.     //  cout<<"fdf"<<endl; 
  359.         cout<<postExp<<endl; 
  360.         compvalue(postExp,value); 
  361.         cout<<value<<endl<<endl; 
  362.     } 
  363.     /* 
  364.     LinkStack *ls = NULL; 
  365.     char c[] = "abcd"; 
  366.     int e; 
  367.     InitLinkStack(ls); 
  368.     Push(ls,1); 
  369.     Push(ls,4); 
  370.     cout<<StackEmpty(ls)<<endl; 
  371.     Pop(ls,e); 
  372.     cout<<e<<endl; 
  373.     DelLinkStack(ls); 
  374. //  cout<<ls<<endl; 
  375.     Pop(ls,e); 
  376. //  cout<<e<<endl; 
  377.      
  378. quanpailie2(c,3 ); 
  379. cout<<endl; 
  380. quanpailie(c,0,4);*/ 
  381.   
  382.     system("pause"); 
  383.     return 1;