今天长沙天气特别冷,一下课就坐车回宿舍了。还是做自己的数据结构……看到堆栈那节,看到算符优先法就想动手编下,再联想到上次看到一题目是X1 ,X2,X3,X4,X5中间放四个算术符,结果等于Y的有多少种符号的集合。正好想到可利用回溯法找出它所的排列来,也不是4的全排列,然后利用算符优先得出其结果,最后判断是否相等即可!同时也复习下堆栈的知识。说真的,刚写完它的时候也小错误大难,在堆栈的出栈还出现了死循环的,冷静的转了半天才算完成,代码够多,但没什么技术含量,只是为自己做一个笔记,同时也纪念下自己写过的算是长程序了吧。。
#include <iostream>
#include <stdlib.h>
#include<vector>
#include<malloc.h>
#define STACK_INIT_SIZE 100
#define LEN 10
vector<char> ss;
char x[LEN];
char h[4]={'+','-','*','/'};
int numsource[5]; 用于输入原始数据
int y;
int sum=0;///用于计算总共有多少种符合要求
void process(vector<char> ss);/在定义之前调用的函数申明
typedef struct{
char ch; /符号
int right;优先级权值
}signal;
signal mm[5]; 用于定义优先级的数组
/*定义数字堆栈*/
typedef struct{
int *base;
int *top;
int stacksize;
}numstack;
/*定义字符堆栈*/
typedef struct{
char *base;
char *top;
int stacksize;
}charstack;
numstack optn; ///定义数据堆栈
charstack optr;///定义字符堆栈
/*数字堆栈的初始化*/
void INitstack(numstack &optn)
{
optn.base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
if(!optn.base) exit(0);
optn.top=optn.base;
optn.stacksize=STACK_INIT_SIZE;
}
/*字符堆栈的初始化*/
void INitstack(charstack &optr)
{
optr.base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
if(!optr.base) exit(0);
optr.top=optr.base;
optr.stacksize=STACK_INIT_SIZE;
}
/*数字堆栈的入栈*/
void push(numstack &optn,int e)
{
if(optn.top-optn.base>=optn.stacksize) exit(0);
*optn.top++=e;
}
/*字符堆栈的入栈*/
void push(charstack &optr,char e)
{
if(optr.top-optr.base>=optr.stacksize) exit(0);
*optr.top++=e;
}
/*数字堆栈的出栈*/
void pop(numstack &optn, int &e)
{
if(optn.top==optn.base) exit(0);
e=*--optn.top;
}
/*字符堆栈的出栈*/
void pop(charstack &optr, char &e)
{
if(optr.top==optr.base) exit(0);
e=*--optr.top;
}
/*取字符堆栈栈顶元素*/
void gettop(charstack optr,char &e)
{
if(optr.top==optr.base) exit(0);
e=*(optr.top-1);
}
/*堆栈过程中的数值符号计算*/
int operater(int num1,char ch,int num2)
{
switch(ch)
{
case '+':return num1+num2;break;
case '-':return num1-num2;break;
case '*':return num1*num2;break;
case '/':return num1/num2;
}
}
/*构造字符数字表达式向量*/
void constructed(vector<char> &ss,char *x, int *y)
{ int i;
for(i=0;i<4;i++)
{
ss.push_back(y[i]+48);
ss.push_back(x[i+1]);
}
ss.push_back(y[i]+48);
ss.push_back('#');
for(i=0;i<11;i++)
cout<<ss[i]<<" ";
cout<<endl;
}//四个符号加五个数字加最后一“#”字符共十个
/*栈顶字符与输入字符的优先级比较*/
int precede(char c1,char c2)
{
int p1,p2;
if(c1==c2) return 0;
for(int i=0;i<5;i++)
{
if(c1==mm[i].ch) p1=mm[i].right;
if(c2==mm[i].ch) p2=mm[i].right;
}
return p1>=p2?2:-2;
}
int fun(char x[],int t, char c)
{/*回溯算法的约束函数*/
int k;
for(k=t-1;k>=1;k--)
if(x[k]==c) return 0;
return 1;
}
/*搜索符号函数*/
void backtrack(int t)
{
if(t>4){
for(int i=1;i<=4;i++)
cout<<x[i]<<" ";
cout<<endl;
constructed( ss,x,numsource);
process(ss);
ss.clear();
}
else
for(int j=0;j<4;j++)
{
x[t]=h[j];
if(fun(x,t,h[j]))
backtrack(t+1); //如满足约束条件,则向下搜索
}
}
/*计算表达式的中间过程*/
void process(vector<char> ss)
{
int i=0,a,b,result,p=0;
char str,theta,mm;///mm用于记录从栈顶取出的符号
str=ss[0];
gettop(optr,mm);
while(str!='#' || mm!='#')
{
if(str>=48&&str<=57)
{ push(optn,str-48); str=ss[++i];}
else
{
switch(precede(str,mm))
{
case 2: push(optr,str); str=ss[++i]; break;栈顶元素小直接入栈
case -2: while(precede(str,mm)<0) ///当栈顶元素大于输入符号时直接出栈计算
{
pop(optn,a);
pop(optn,b);
pop(optr,theta);
result=operater(b,theta,a);
push(optn,result);
gettop(optr,mm);
}
if(precede(str,mm)==0) p=1;
push(optr,str);
str=ss[++i];
}/swith
if(p==1) break;
gettop(optr,mm);
}else
}//while
pop(optn,result);
if(result==y) sum++;
cout<<result<<endl;
cout<<sum<<endl;
}
int main(int argc, char *argv[])
{
int hh;
INitstack(optn);
INitstack(optr);
push(optr,'#');
cout<<"请输入原始数据X1————X5:"<<endl;
for(int i=0;i<5;i++)
cin>>numsource[i];
cout<<"请输入最终表达式应等于的结果Y:"<<endl;
cin>>y;
cout<<"请输入自定义的优先级:"<<endl;
/*自己设定优先级,假如:
‘#’------优先级为1
‘+’和‘-’优先级为2
‘*’和‘/’优先级为3*/
for(int j=0;j<5;j++)
cin>>mm[j].ch>>mm[j].right;
backtrack(1);
system("PAUSE");
return 0;
}