回溯法的一个习题

  题目如下:按照原理,编程实现1□2□3□4□5□6□7□8□9□10=100。在□中插入+或-,不插入则表示连接,使得最终运算结果等100

  做这个题,自己用了栈+回溯法。题目虽然挺简单,但是实现起来,还是出了不少错误。不多说,附代码:

 

  1 #include <iostream>
  2 using namespace std; 
  3 
  4 #define add 30 //加法     
  5 #define sub 31 //减法 
  6 #define blank 32 //连接 
  7 #define ex 33 //在运算符栈中最先压的元素,优先级最低 
  8 
  9 char youxianji[4][4]={{'>','<','<','>'},{'>','<','<','>'},{'>','>','<','>'},{
 10     '<','<','<','='}};//定义优先级 
 11 
 12 typedef struct{//定义栈结构 
 13     int bas,top;
 14     int num[15];
 15 }stack;
 16 stack opnd,optr;//分别为数字栈和运算符栈 
 17 
 18 int j;
 19 
 20 int bb[10]={
 21     33,33,33,33,33,33,33,33,33,33
 22 };//运算符初始化 
 23 //表达式用数组表示,将运算符数组和1到10数字组合即可 
 24 int exp[25]={1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10,33,1,1,1,1,1}; 
 25 
 26 int allsum;//总的结果 
 27 
 28 int intial_exp(){ //初始化表达式 
 29     j=0;
 30     while(j<9) {
 31     exp[2*j+1]=bb[j];//即将运算符数组赋值到表达式中 
 32     j++;
 33     }
 34     return 0;
 35 }
 36 
 37 int push(stack &s,int n){//压栈 
 38     s.num[s.top]=n;
 39     s.top++;
 40     return 0;
 41 }
 42 
 43 int pop(stack &s,int &n){//出栈 
 44     n=s.num[--s.top];
 45     return 0;
 46 }
 47 
 48 int getop(stack &s){//得到栈顶 
 49     int n=s.num[--s.top];
 50     s.top++;
 51     return n;
 52 }
 53 
 54 int oprate(int op1,int opd,int op2){//运算 
 55     int sum;
 56     switch(opd){
 57     case 30:
 58       sum=op1+op2;
 59       break;
 60     case 31:
 61       sum=op1-op2;
 62       break;
 63     case 32://这点也要注意,注意10的不同之处 
 64       if(op2==10) sum=op1*100+op2;
 65       else sum=op1*10+op2;
 66       break;
 67     }
 68     return sum;    
 69 }
 70 //这个计算过程不和单单求表达式的值一样,需要多次计算表达式的值
 71 //因此,再计算完一次后,需要将数字栈与运算符栈清空(特别注意) 
 72 int compute(){//计算过程 
 73     int a;
 74     int b,c;
 75     int theta;
 76     intial_exp(); 
 77     j=0;//每一次计算,都要将j初始化为0 
 78     push(optr,ex);//第一步要在运算符栈中压入优先级最低的运算符ex 
 79     while(getop(optr)!=33||exp[j]!=33){
 80      if(exp[j]<30) push(opnd,exp[j++]);
 81      else 
 82        switch(youxianji[exp[j]-30][getop(optr)-30])
 83        {case '>':
 84           push(optr,exp[j++]);
 85           break;
 86           case '<':
 87           pop(optr,theta);
 88           pop(opnd,b);pop(opnd,c);
 89           push(opnd,oprate(c,theta,b));
 90           break;
 91         }
 92     }
 93         pop(opnd,allsum); 
 94         pop(optr,a); //清空栈 
 95     return allsum;
 96 }
 97 int print(){//输出结果 
 98     for(int i=0;i<19;i++){
 99         if(exp[i]<30) cout<<exp[i];
100         else if(exp[i]==30) cout<<'+';
101         else if(exp[i]==31) cout<<'-';
102     }
103     cout<<"=100"<<endl;
104 }
105 int backtrack(int dep){//递归回溯 
106     if(dep==9) {
107      compute();
108      if(allsum==100) {
109       print();
110       return 0;
111     }
112      else dep--;//回溯 
113  }
114     else{
115     bb[dep]=add;backtrack(dep+1);
116     bb[dep]=sub;backtrack(dep+1);
117     bb[dep]=blank;backtrack(dep+1);
118  }
119     return 0;    
120 }
121 int main()
122 {
123     backtrack(0);
124     return 0;
125 }

  附上结果:

posted @ 2013-03-06 17:58  简单地快乐  阅读(551)  评论(0编辑  收藏  举报