算法规则:
1.先通过控制台输入字符串,如果遇到’#‘结尾,就代表输入完毕。
2.一边解析出字符串中的“+”,“-”,“*”,“/”, "(", ')' ,数字,一边参与运算
如果遇到“+”,“-”, "(",就直接放入字符栈q2;
如果遇到“*”,“/”,首先字符串要解析出它后面的数字a1(他后面一定会为数字,根据四则运算的规律),其次还要从数字栈q1中获取顶端数字a2,并弹出,sum=a1*a2或者(sum=a2/a1),再将sum放入数字栈;
如果遇到“)” 时,要循环弹出q2中的符号,直到弹出的符号是“(” 才停止弹出,弹出一个符号为“+”,就要从q1中弹出两个数字,进行运算,再将运算的结果存入到q1中,如果为'-',则要注意连减(6-2-2)的问题,不能采用和’+‘一样的算法(这里我也犯了错,分析了一下后,给它重新设计了出栈进栈算法)。
如果字符串都遍历了,先判断字符栈q2是否为空,如果为空,将q1中的数字弹出来,这就是最终结果,如果不为空,要先将q2中的符号弹出来,符号为“+”,q1中弹出两个数字,进行运算,结果存入q1中,如果为'-',则要注意连减(6-2-2)的问题,不能采用和’+‘一样的算法(这里我也犯了错,分析了一下后,给它重新设计了出栈进栈算法)。直至q2为空,再将q1的结果弹出。
自定义的栈:
#pragma once
#include<iostream>
using namespace std;
template<class T>
class mystack {
private:
//定义了一个数组
T* data;
//顶点元素的索引,为空时,指向-1;
int ding;
//栈的容量
int capacity;
public:
mystack(int cap=100) {
//栈的容量
capacity = cap;
//初始化数组
data = new T[capacity];
//顶点索引先置于-1
ding = -1;
}
//进栈
void push(T d) {
if (full()) {
cout << "栈满了" << endl;
}
else {
data[++ding] = d;
}
}
//出栈
void pop() {
if (empty()) {
cout << "栈中的元素为空" << endl;
}
else {
ding--;
}
}
//返回顶点元素
T top() {
if (empty()) {
cout << "栈中的元素为空" << endl;
}
else {
return data[ding];
}
}
//判断站是否为空
bool empty() {
if (ding == -1) {
return true;
}
else {
return false;
}
}
//判断栈是否满了
bool full() {
if (ding == capacity - 1) {
return true;
}
else {
return false;
}
}
};
经过多次测试后修改的代码:
#include<iostream>
#include "mystack.h"
using namespace std;
//创建一个栈用来存储数字
mystack<int> q1 = mystack<int>();
//创建一个栈来存储字符
mystack<char> q2 = mystack<char>();
struct node {
int number;
int i;
};
void cinStr(char* str, int& len);
node* parseInt(char* str, int i, int len);
int main() {
//1.输入字符串,确定结束标记为#
char* str = new char[200];
int len=0;
cinStr(str,len);
int i = 0;
int a = 0;
node* data = new node();
int result = 0;
//2.一边读取字符串,一边解析出运算符号和数字,将他们存入到栈中,并进行相关的运算
while (true) {
if (i >= len) {
char ch;
int sum = 0;
while (!q2.empty()) {
//根据算法的规律推出字符栈只会有 '+','-','('
ch = q2.top();
if (ch == '+') {
q2.pop();
int a1 = q1.top();
q1.pop();
int a2 = q1.top();
q1.pop();
sum = a1 + a2;
}
else if (ch == '-') {
//中间存在连续相减的问题 (6-3-2)*5
//创建一个数组
int data01[10];
int len = 0;
while (ch == '-') {
q2.pop();
int a1 = q1.top();
data01[len++] = a1;
q1.pop();
if (!q2.empty()) {
ch = q2.top();
}
else {
break;
}
}
sum=q1.top();
q1.pop();
for (int j = 0; j < len;j++) {
sum = sum - data01[j];
}
}
q1.push(sum);
}
result=q1.top();
break;
}
else if (str[i] == '+') {
q2.push(str[i]);
i++;
}
else if (str[i] == '-') {
q2.push(str[i]);
i++;
}
else if (str[i] == '*') {
//下一位一定是数字,将下一位数字进行解析出来
data=parseInt(str, i+1, len);
if (!q1.empty()) {
a=q1.top();
q1.pop();
a = data->number * a;
q1.push(a);
}
i = data->i;
}
else if (str[i] == '/') {
data = parseInt(str, i + 1, len);
if (!q1.empty()) {
a = q1.top();
q1.pop();
a = a/data->number;
q1.push(a);
}
i = data->i;
}
else if (str[i] == '(') {
q2.push(str[i]);
i++;
}
else if (str[i] == ')') {
char ch;
int sum = 0;
while ((ch = q2.top()) != '(') {
//根据算法的规律推出字符栈只会有 '+','-','('
//要将字符栈弹出来
/*q2.pop();
int a1 = q1.top();
q1.pop();
int a2 = q1.top();
q1.pop();
if (ch == '+') {
sum = a1 + a2;
}
else if (ch == '-') {
//这里会出现连减的错误
sum = a2 - a1;
}*/
if (ch == '+') {
q2.pop();
int a1 = q1.top();
q1.pop();
int a2 = q1.top();
q1.pop();
sum = a1 + a2;
}
else if (ch == '-') {
//中间存在连续相减的问题 (6-3-2)*5
//创建一个数组
int data01[10];
int len = 0;
while (ch == '-') {
q2.pop();
int a1 = q1.top();
data01[len++] = a1;
q1.pop();
if (!q2.empty()) {
ch = q2.top();
}
else {
break;
}
}
sum = q1.top();
q1.pop();
for (int j = 0; j < len; j++) {
sum = sum - data01[j];
}
}
q1.push(sum);
}
q2.pop();
i++;
}
else if (str[i] >= '0' && str[i] <= '9') {
data = parseInt(str, i, len);
q1.push(data->number);
i = data->i;
}
}
cout << result << endl;
//3.确定运算规则
}
void cinStr(char *str,int& len) {
char ch;
while (true) {
cin >> ch;
if (ch == '#') {
break;
}
str[len++] = ch;
}
}
node* parseInt(char *str, int i, int len) {
int number = 0;
node* n =new node();
while (true) {
if (i >= len) {
break;
}
else if (str[i] >= '0' && str[i] <= '9') {
number = number * 10 + (str[i] - '0');
i++;
}
else {
break;
}
}
n->i = i;
n->number = number;
return n;
}