表达式求解

 

表达式求解问题

第四次数据结构实验:

实验三:表达式求值

 

 

实验目的:

1、掌握顺序栈结点类型的定义

2掌握栈的插入和删除结点操作的特点;

3、熟悉对栈的一些基本操作和具体的函数定义。

代码:

 

 

  1 /* Status.h 各种常量状态、结构体的声明文件*/
  2 #pragma once
  3 #include <malloc.h>
  4 #include <stdlib.h>
  5 
  6 #define TRUE 1
  7 #define FALSE 0
  8 #define OK 1
  9 #define ERROR 0
 10 #define OVERFLOW -2
 11 #define INFEASIBLE -1
 12 
 13 typedef int Status;
 14 
 15 typedef char SElemType;
 16 #define STACK_INIT_SIZE 100
 17 #define STACKINCREMENT  10
 18 struct SqStack{
 19     SElemType *base;
 20     SElemType *top;
 21     int stacksize;
 22 };
 23 
 24 typedef char QElemType;
 25 #define MAXQSIZE 100
 26 struct SqQueue{
 27     QElemType *base;
 28     int front;
 29     int rear;
 30 };
 31 
 32 /* SqStack.h CSqStack类的声明文件*/
 33 #pragma once
 34 #include "Status.h"
 35 
 36 class CSqStack
 37 {
 38 private:
 39     //栈数据结构
 40     SqStack S;
 41 public:
 42     CSqStack(void);
 43     ~CSqStack(void);
 44     //压栈
 45     Status Push(SElemType e);
 46     //出栈
 47     Status Pop(SElemType& e);
 48     //返回栈顶元素,非弹出
 49     char GetTop();
 50     //判断是否为空
 51     bool Empty();
 52 private:
 53     //初始化栈数据结构,放在构造函数里,私有了..
 54     Status InitStack();
 55 };
 56 /* SqStack.h CSqStack类的定义文件*/
 57 #include "SqStack.h"
 58 
 59 CSqStack::CSqStack(void)
 60 {
 61     this->InitStack();
 62 }
 63 
 64 CSqStack::~CSqStack(void)
 65 {
 66     free(this->S.base);
 67 }
 68 
 69 //压栈
 70 Status CSqStack::Push(SElemType e)
 71 {
 72     if (S.top - S.base >= S.stacksize)
 73     {
 74         S.base = (SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
 75         if (!S.base)
 76             exit(OVERFLOW);
 77         S.top = S.base + S.stacksize;
 78         S.stacksize += STACKINCREMENT;
 79     }
 80     *S.top++ = e;
 81     
 82     return OK;
 83 }
 84 
 85 //出栈
 86 Status CSqStack::Pop(SElemType& e)
 87 {
 88     if (S.top == S.base)
 89         return ERROR;
 90     e = *--S.top;
 91 
 92     return OK;
 93 }
 94 
 95 //返回栈顶元素,非弹出
 96 char CSqStack::GetTop()
 97 {
 98     if(S.top == S.base)
 99         return ' ';
100 
101     return *(S.top-1);
102 }
103 
104 //判断是否为空
105 bool CSqStack::Empty()
106 {
107     return S.top == S.base ? TRUE : FALSE ; 
108 }
109 
110 //初始化栈数据结构,放在构造函数里,私有了..
111 Status CSqStack::InitStack()
112 {
113     S.base = (SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
114     if(!S.base)
115         exit(OVERFLOW);
116     S.top = S.base;
117     S.stacksize = STACK_INIT_SIZE;
118 
119     return OK;
120 }
121 
122 /* 
123 ///////////////////////
124 Main.cpp 
125 main函数所在文件
126 0x0o@Live.Cn
127 08.11.05
128 Vista-U + VS2008 下编译通过.
129 ////////////////////////
130 */
131 
132 #include <iostream>
133 #include "Status.h"
134 #include "SqStack.h"
135 using namespace std;
136 
137 char Operate(char a,char ch,char b)
138 {
139     switch (ch)
140     {
141     case '+':
142         return a+b-48;
143     case '-':
144         return a-b+48;
145     case '*':
146         return (a-48)*(b-48)+48;
147     case '/':
148         return (a-48)/(b-48)+48;
149     }
150 }
151 
152 char Precede(char ch1,char ch2)
153 {
154     if (ch1==ch2 && ch2=='#')
155         return '=';
156     if (ch1==ch2 && ch1!='#')
157         return '>';
158     if (ch1 == '#')
159         return '<';
160     if (ch1=='(' && ch2==')')
161         return '=';
162     if (ch1== '(' || ch2=='(')
163         return '<';
164     if (ch2== ')' || ch1==')')
165         return '>';
166     if(ch1=='*' || ch1=='/')
167         return '>';
168     if (ch2=='*' || ch2=='/')
169         return '<';
170     else
171         return '>';
172 }
173 
174 bool IsOpnd(char ch)
175 {
176     if( ch>=48 && ch<=57)
177         return TRUE;
178     else
179         return FALSE;
180 }
181 
182 char EvaluateExpression(CSqStack& OPND,CSqStack& OPTR)
183 {
184     char ch;
185     ch = getchar();
186 
187     while (ch != '#' || OPTR.GetTop() != '#')
188     {
189         if(IsOpnd(ch))
190         {
191             OPND.Push(ch);
192             ch = getchar();
193         }
194         else
195         {
196             switch (Precede(OPTR.GetTop(),ch))
197             {
198             case '<':
199                 OPTR.Push(ch);
200                 ch = getchar();
201                 break;
202             case '=':
203                 char x;
204                 OPTR.Pop(x);
205                 ch = getchar();
206                 break;
207             case '>':
208                 char theta,a,b;
209                 OPTR.Pop(theta);
210                 OPND.Pop(b);OPND.Pop(a);
211                 OPND.Push(Operate(a,theta,b));
212                 break;
213             default:
214                 cout<<"Error!"<<endl;
215             }
216         }
217     }
218     
219     return OPND.GetTop();
220 
221 }
222 
223 int main()
224 {
225     char ch;
226     CSqStack OPTR,OPND;
227     cout<<"Please Input The Expression:"<<endl;
228 
229     OPTR.Push('#');
230 
231     ch = EvaluateExpression(OPND,OPTR);
232 
233     cout<<(int)(ch-48)<<endl;
234 
235 
236     return 0;
237 }
238 

 

 

 

 

以上代码存在问题!

很明显,用char来存输入的数据,如果100*2怎么办?弹出来的是0….太尴尬了

这个问题其实也挺好解决的,例如:堆栈的数据类型是int,然后把字符接收时处理,如果下一个还是数字,就把此数字×10+下一个数字,接受完的时候再存入堆栈即可..

问题是这个代码的其它地方我还没跟踪明白,貌似构造的表达式出现某某现象时,最终结果是一个错误的数字

哎,懒得改了..>

 

今天代码写的有点取巧了,明显用的就是回文序列里面的代码,复用果真很舒服,省了很多时间的说

 

 

 

                                       --------by   0x0o

                                          Time 08.11.05 1541

 

posted @ 2008-11-05 15:44  端木  阅读(716)  评论(0编辑  收藏  举报