背景:刚学完栈,实现栈的应用—表达式求值。
栗子:
中缀:(20 + 5 + 1*3)/ 14
后缀: 20 5 + 1 3 * + 14 /
出现的问题:
- 强制转换出现问题 将指向其他类型数据的指针赋值给void类型指针的时候,该内存中存放数据仍是最开始的数据类型。
- 对操作数进行计算后,会覆盖原来的结果。例如先将20+5的结果25入栈,后将1*3的结果3压入栈,会覆盖之前的25。
解决方法:
- 如果强制将string *类型通过(int *)进行转换则会出错,使用stoi()函数;反之,使用to_string()函数。
- 两次使用的变量(就是一个变量)共用同一段内存(该变量为局部变量,生存期内未释放空间),动态申请空间即可。
#include <vector>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
typedef struct StackNode {
void *data;
struct StackNode* next;
}Snode;
class LinkStack {
public:
struct StackNode *top;
LinkStack();
~LinkStack();
void Push(void* x);
int Pop();
void* GetTop();
};
LinkStack::LinkStack()
{
cout << "构造函数成功" << endl;
top = NULL;
}
LinkStack::~LinkStack()
{
cout << "析构成功" << endl;
delete top;
}
void LinkStack::Push(void* x)
{
Snode* p = new Snode;
p->data = x;
p->next = top;
top = p;
p = NULL;
}
int LinkStack::Pop()
{
StackNode *p;
assert(top);
p = top;
if (!top->next)
top = NULL;
else
top = top->next;
delete p;
return 0;
}
void * LinkStack::GetTop()
{
return top->data;
}
int Cal(void* b, void* a,string s) {
if (s == "+")
return stoi(*(string *)a) + stoi(*(string *)b);
if (s == "*")
return stoi(*(string *)a) * stoi(*(string *)b);
if (s == "-")
return stoi(*(string *)a) - stoi(*(string *)b);
if (s == "/")
return stoi(*(string *)a) / stoi(*(string *)b);
}
void* Res(LinkStack *s, vector<string> a) {
//if num push
//else pop two num
//final return Top->data
for (vector<string>::iterator it = a.begin(); it != a.end(); ++it) {
if (*it !="+" && *it != "-" && *it != "*" && *it != "/") {
s->Push(&(*it));//使用迭代器iterator遍历向量中的string数据时,入栈时要先解引用it中的值,再对该值取地址。
cout << "push.data:" << stoi(*(string *)(s->GetTop())) << endl;
}
else {
void* num1 = s->GetTop();
cout << "num1:"<<*(string *)num1 << endl;
s->Pop();
void* num2 = s->GetTop();
cout << "num2:" << *(string *)num2 << endl;
s->Pop();
/*
* void * num3 = (void *)Cal(num1,num2,*it) erro
* use to_string() or stoi() instead of forcibly cast
*/
string *num3 = new string;
*num3 = to_string(Cal(num1, num2, *it));
cout << "num3:" << *num3 <<" &num3:"<<num3<< endl;
s->Push(num3);
cout << "push.data:" << stoi(*(string *)(s->GetTop())) << endl;
}
cout << "s:";
for (Snode *p = s->top; p != NULL; p = p->next) {
cout << *(string *)(p->data)<<"->";
if (!p->next)
break;
}
cout << "NULL"<<endl;
}
return s->GetTop();
}
int main(){
LinkStack *s = new LinkStack();
vector<string> a = { "5","20","+","1","3","*","+","14", "/" };
cout << "Res is " << *(string *)Res(s, a) << endl;
delete s;
system("pause");
}