刚开始想一鼓作气把整个过程全部实现,但白费了那几个小时,调试了半天也没做出来,后来我是通过先实现中缀表达式转化为后缀表达式,然后实现后缀表达式的求值,然后将两块代码进行合成,刚才同学还笑着说:模块化编程。。。
直接在代码中解释。
中缀表达式转后缀表达式:
# include <iostream>
# include <string>
# include <sstream>
# include <cctype> //程序中需使用isdigit()函数,目的在于判别字符是否为数字,将符号和数字区别开来
using namespace std;
struct sign //建立存储符号的结构体
{
char sign;
int level;
struct sign *next_1;
};
class linkstack
{
private:
struct sign *top;
public:
linkstack() { top = NULL; } //无参构造函数,top头指针初始化为零
char push_out(); //将栈顶元素出栈
void push_in(char new_sign); //给栈中添加新元素
char print_top(); //返回栈顶元素中的符号内容
int print_level(); //返回栈顶元素符号的优先级
};
int compare(char compared_sign) //给每个符号赋予优先级
{
int level;
switch (compared_sign) {
case '(':
level = -10; break;
case ')':
level = -10; break;
case '+':
level = 0; break;
case '-':
level = 0; break;
case '*':
level = 1; break;
default: //default要加上
level = 1; break;
}
return level;
}
char linkstack::print_top()
{
char result;
result = top->sign;
return result;
}
int linkstack ::print_level()
{
return top->level;
}
char linkstack::push_out() //删除栈顶元素
{
char char_result;
struct sign *p;
char_result = top->sign;
p = top;
top = top->next_1;
delete p;
return char_result; //删除后需要给sting对象b中追加,所以需要返回
}
void linkstack::push_in(char new_sign)
{
struct sign *s;
s = new struct sign; //添加栈顶元素
s->sign = new_sign;
s->level = compare(new_sign);
s->next_1 = top;
top = s;
}
int main()
{
int count = 0; double m; //count用来记录符号栈中的个数,用top!=NULL也可以
string a,b;
cin >> a; //string对象a是转化前的,b是转换后的
linkstack one;
for (auto c = a.begin(); c != a.end(); c++) { //从a的第一个元素开始扫描
if (isdigit(*c)) {
b.push_back(*c); continue; //如果是数字isdigit(*c)为真,就给b中追加,进行下一个循环
}
else {
if (*c != ')'&&count==0) { //如果栈为空,直接加入栈顶元素
one.push_in(*c);
count++; //记录栈元素的个数
continue; //进行下一个循环
}
if (*c==')') { //进行括号中的运算
while (one.print_top()!= '(') { //一直循环到栈顶元素不等于‘(’
b.push_back(one.print_top()); //将目前栈顶元素追加给b
one.push_out(); count--; //追加完后,删除栈顶元素,个数减一
}
one.push_out(); count--; //最后记得还要把左括号删除,以避免对下一个运算影响
continue;
}
if (compare(*c) <= one.print_level()) { //如果当前符号优先级小于栈顶元素的优先级(即上一个运算符)
b.push_back(one.print_top()); //将栈顶运算符元素追加给b
one.push_out(); //紧跟着删除刚才的栈顶元素
one.push_in(*c); //将当前的运算符号压入栈
continue; //进行下一个循环
}
if (compare(*c)>one.print_level()) { //如果当前运算符优先级大于栈顶元素(即前一个运算符)
one.push_in(*c); count++; //直接压入栈,个数加一,并进行下一个循环
continue;
}
}
}
if (count) { //如果栈不空则还剩余一个符号没有追加给b
b.push_back(one.print_top()); //追加栈中剩余的符号
one.push_out();
}
cout << b << endl;
system("pause");
return 0;
}
后缀表达式求值:
# include <iostream>
# include <string>
# include <sstream> //下边程序中从string类型到double中要用到,具体的用法在以前的博客中我有详细提及
using namespace std;
struct operate
{
double member;
struct operate *next;
};
class new_linkstack
{
public:
new_linkstack() { top = NULL; } //初始化,top为NULL;
void push_in(double x); //将数字压入栈
double push_out(); //删除栈顶元素
void print_result(); //打印运算完后的结果,也就是最后的栈顶元素
private:
struct operate *top;
};
void new_linkstack::push_in(double in_number)
{
struct operate *s;
s = new operate;
s->member = in_number;
s->next = top;
top = s;
}
double new_linkstack::push_out()
{
struct operate *p;
if (top == NULL)throw"下溢";
double out_member;
out_member = top->member; p = top;
top = top->next;
delete p;
return out_member;
}
void new_linkstack::print_result()
{
cout << top->member << endl;
}
int main()
{
double x, y, result,b;
string new_a;
cin >> new_a;
new_linkstack one;
for (auto c = new_a.begin(); c != new_a.end(); c++) { //从头到尾扫描new_a中的元素
if (isdigit(*c)) { //如果当前元素为数字,直接入栈
stringstream sstream;
sstream << *c;
sstream >> b; //string类型到double类型的转换
one.push_in(b);
sstream.clear(); //将stringstream流清空
}
else { //如果当前元素为运算符
x = one.push_out(); //将前两个栈顶的元素取出
y = one.push_out();
switch (*c) //new_a中的运算符不能直接用来做运算
{
case '+':
result = x + y; one.push_in(result); continue;//运算完后,将当前运算结果压入栈,进行下一个循环
case '-':
result = y - x; one.push_in(result); continue;
case '*':
result = x * y; one.push_in(result); continue;
case '/':
result = y / x; one.push_in(result); continue;
}
}
}
one.print_result(); //打印最终结果
system("pause");
return 0;
}
这样就将一个大的问题分成了两个小的问题,下边的代码是我合成之后的:
# include <iostream>
# include <string>
# include <cctype>
# include <sstream>
using namespace std;
struct sign
{
char sign;
int level;
struct sign *next_1;
};
struct operate
{
double member;
struct operate *next;
};
class new_linkstack
{
public:
new_linkstack() { top = NULL; }
void push_in(double x);
double push_out();
void print_result();
private:
struct operate *top;
};
class linkstack
{
private:
struct sign *top;
public:
linkstack() { top = NULL; }
char push_out();
void push_in(char new_sign);
char print_top();
int print_level();
};
int compare(char compared_sign)
{
int level;
switch (compared_sign) {
case '(':
level = -10; break;
case ')':
level = -10; break;
case '+':
level = 0; break;
case '-':
level = 0; break;
case '*':
level = 1; break;
default:
level = 1; break;
}
return level;
}
char linkstack::print_top()
{
char result;
result = top->sign;
return result;
}
int linkstack::print_level()
{
return top->level;
}
char linkstack::push_out()
{
char char_result;
struct sign *p;
char_result = top->sign;
p = top;
top = top->next_1;
delete p;
return char_result;
}
void linkstack::push_in(char new_sign)
{
struct sign *s;
s = new struct sign;
s->sign = new_sign;
s->level = compare(new_sign);
s->next_1 = top;
top = s;
}
void new_linkstack::push_in(double in_number)
{
struct operate *s;
s = new operate;
s->member = in_number;
s->next = top;
top = s;
}
double new_linkstack::push_out()
{
struct operate *p;
if (top == NULL)throw"下溢";
double out_member;
out_member = top->member; p = top;
top = top->next;
delete p;
return out_member;
}
void new_linkstack::print_result()
{
cout << top->member << endl;
}
int main()
{
int count = 0; double m;
string a, b;
cin >> a;
linkstack one;
for (auto c = a.begin(); c != a.end(); c++) {
if (isdigit(*c)) {
b.push_back(*c); continue;
}
else {
if (*c != ')'&&count == 0) {
one.push_in(*c);
count++;
continue;
}
if (*c == ')') {
while (one.print_top() != '(') {
b.push_back(one.print_top());
one.push_out(); count--;
}
one.push_out(); count--;
continue;
}
if (compare(*c) <= one.print_level()) {
b.push_back(one.print_top());
one.push_out();
one.push_in(*c);
continue;
}
if (compare(*c) > one.print_level()) {
one.push_in(*c); count++;
continue;
}
}
}
if (count) {
b.push_back(one.print_top());
one.push_out();
}
double x, y, result, new_b;
string new_a(b);
new_linkstack two;
for (auto c = new_a.begin(); c != new_a.end(); c++) {
if (isdigit(*c)) {
stringstream sstream;
sstream << *c;
sstream >> new_b;
two.push_in(new_b);
sstream.clear();
}
else {
x = two.push_out();
y = two.push_out();
switch (*c)
{
case '+':
result = x + y; two.push_in(result); continue;
case '-':
result = y - x; two.push_in(result); continue;
case '*':
result = x * y; two.push_in(result); continue;
case '/':
result = y / x; two.push_in(result); continue;
}
}
}
two.print_result();
system("pause");
return 0;
}
这也算是个人狭义上的第一次模块化的编程吧。。。。。。