数据结构之算符优先法学习笔记()

今天长沙天气特别冷,一下课就坐车回宿舍了。还是做自己的数据结构……看到堆栈那节,看到算符优先法就想动手编下,再联想到上次看到一题目是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;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值