计算具有两个以上操作数的后缀表达式时出现问题
Problems Calculating a Postfix Expression with More Than Two Operands
我需要创建一个RPN(后缀符号(计算器,它可以进行简单的操作(+,-,*,/(,同时使用链表来维护堆栈。 我已经完成了大部分工作,但遇到了一些问题。 我可以用一个操作数计算任意两个数字(例如:5 5 + = 10(,但不能做更多的事情。 我在网上做了一些研究,并观看了一些YouTube视频来达到我现在的位置,但大多数人使用堆栈引用来做到这一点。 我尝试结合这方面的教程,以及如何制作自己的堆栈。
我对此很陌生,并且对如何计算更大的表达式(例如:5 5 5 + + = 15(非常迷茫,我还需要检查错误,我已经完成了一些错误,但我正在努力解决的是"运算符太多"和"操作数太多"。 对于太多的运算符,我认为它与无法弹出值有关,因为那里没有值,但这是我所能得到的(如果它是正确的,仍然不太确定如何实现它(。 任何关于这 3 件事的帮助,或者您能在这里看到的任何其他内容,将不胜感激。
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
class SLLNode
{
double data;
SLLNode *top;
SLLNode *ptr;
public:
SLLNode()
{
top = NULL;
ptr = NULL;
}
void pushVal(double val)
{
SLLNode *next = new SLLNode;
next -> data = val;
next -> ptr = top;
top = next;
}
double popVal()
{
SLLNode *next = new SLLNode;
next = top;
top = top -> ptr;
next -> ptr = NULL;
return next -> data;
delete next;
}
void print()
{
SLLNode *next = new SLLNode;
next = top;
cout << "= " << next -> data << endl << ">>";
next = next -> ptr;
delete next;
}
};
bool isOperator(const string& input)
{
string ops[] = {"+", "-", "*", "/"};
for(int i = 0; i < 4; i++)
{
if(input == ops[i])
{
return true;
}
}
return false;
}
void performOp(const string& input, SLLNode& stack)
{
double fVal, sVal;
int result = 0;
sVal = stack.popVal();
fVal = stack.popVal();
if(input == "+")
{
stack.pushVal(fVal + sVal);
}
else if(input == "-")
{
stack.pushVal(fVal - sVal);
}
else if(input == "*")
{
stack.pushVal(fVal*+ sVal);
}
else if(input == "/" && sVal != 0)
{
stack.pushVal(fVal / sVal);
}
if(input == "/" && sVal == 0)
{
cout << "Error: Division by zero" << endl;
result = 1;
}
if(result == 0)
{
stack.print();
}
}
int main()
{
string input;
SLLNode stack;
cout << "::::::::::::::::RPN CALCULATOR:::::::::::::::::" << endl;
cout << "::TYPE IN A POSTFIX EXPRESSION OR 'q' TO QUIT::" << endl;
cout << ":::::::::::::::::::::::::::::::::::::::::::::::" << endl << endl;
cout << ">>";
while(true)
{
cin >> input;
double num;
if(istringstream(input) >> num)
{
stack.pushVal(num);
}
else if (isOperator(input))
{
performOp(input, stack);
}
else if (input == "q")
{
return 0;
}
else
{
cout << "Error: Invalid input" << endl;
}
}
}
我建议您使用std::map<double>
而不是滚动自己的链表,除非是为了学习目的。
主要问题在于SLLNode::popVal()
和SLLNode::print()
,事情变得有点混乱。
以下是您需要更改以修复它的内容:
double popVal()
{
SLLNode *next = top -> ptr;
double ret = top -> data;
delete top;
top = next;
return ret;
}
void print()
{
cout << "= " << top -> data << endl << ">>";
}
在代码中还有许多其他可以改进的地方,但这应该可以回答你的问题。
中有两个运算符"*"和"+"来计算乘法。 我添加并重新安排了一些错误检查,
int
performOp(const string& input, SLLNode& stack)
{
double fVal, sVal;
int result = 0;
if( stack.size < 2 )
{
cout << "Error: too few operands" << end;
stack.print();
return 1;
}
sVal = stack.popVal();
fVal = stack.popVal();
if(input == "+")
{
stack.pushVal(fVal + sVal);
}
else if(input == "-")
{
stack.pushVal(fVal - sVal);
}
else if(input == "*")
{
stack.pushVal(fVal * sVal); //problem was here
}
else if(input == "/" )
{
if(sVal == 0)
{
cout << "Error: Division by zero" << endl;
stack.print();
return 1;
}
stack.pushVal(fVal / sVal);
}
return 0;
}
定义一个包含头部/尾部的列表节点,并计算堆栈中的元素,
#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>
using namespace std;
class SLLNode //single link list
{
public:
SLLNode *next;
double data;
SLLNode()
{
next = NULL;
data = 0;
}
void print()
{
SLLNode *node = NULL;
cout << "= " << data << endl << ">>";
}
};
您的堆栈实现会泄漏内存,分配不必要的节点,并且缺少一些有用的堆栈操作来帮助您解决一些问题。 您需要一个析构函数来清空列表,以防您忘记清空它,并且打印整个列表会有所帮助。 无论如何
class SLList //single link list
{
SLLNode *head;
SLLNode *tail;
int _count;
public:
SLList()
{
head = NULL;
tail = NULL;
_count = 0;
}
~SLList()
{
while( !empty() ) { pop(); }
}
int size() { return _count; }
bool empty() { return (!head); return false; }
void push(double val)
{
SLLNode *node = new SLLNode;
node->data = val;
node->next = head;
++_count;
if(!tail) tail = node;
head = node;
}
double pop()
{
SLLNode *node = NULL;
if(!head) return 0;
node = head;
double val = node->data;
head = node->next;
--_count;
if(!head) tail = NULL;
delete node;
return val;
}
double tip()
{
SLLNode *node = NULL;
if(!head) return 0;
node = head;
double val = node->data;
return val;
}
void print()
{
SLLNode *node = NULL;
if(!head) return;
for( node=head; node; node=node->next )
node->print();
}
};
您可能希望添加更多运算符,提取它,
bool isOperator(const string& input);
int performOp(const string& input, SLList& stack);
static string BINOPS[] = {"+", "-", "*", "/"};
bool
isOperator(const string& input)
{
for(int i = 0; i < 4; i++) //should get size of BINOPS
{
if(input == BINOPS[i])
{
return true;
}
}
return false;
}
在从堆栈中提取项目之前检查堆栈大小,
int
performOp(const string& input, SLList& stack)
{
double fVal, sVal;
int result = 0;
if( stack.size() < 2 )
{
cout<<"Error: too few operands"<<endl;
stack.print();
return 1;
}
sVal = stack.pop();
fVal = stack.pop();
if(input == "+")
{
stack.push(fVal + sVal);
}
else if(input == "-")
{
stack.push(fVal - sVal);
}
else if(input == "*")
{
stack.push(fVal * sVal);
}
else if(input == "/" )
{
if(sVal == 0)
{
cout << "Error: Division by zero" << endl;
stack.print();
return 1;
}
stack.push(fVal / sVal);
}
return 0;
}
您需要某种方法来打印列表。 第四种语言使用".",所以在这里我添加了一个案例来使用"."打印列表,
int
main()
{
string input;
SLList stack;
cout<<"::::::::::::::::RPN CALCULATOR:::::::::::::::::"<<endl;
cout<<"::TYPE IN A POSTFIX EXPRESSION OR 'q' TO QUIT::"<<endl;
cout<<":::::::::::::::::::::::::::::::::::::::::::::::"<<endl<<endl;
double num;
while(true)
{
cout << ">>";
cin >> input;
if(istringstream(input) >> num)
{
stack.push(num);
}
else if (isOperator(input))
{
performOp(input, stack);
}
else if (input == ".")
{
stack.print();
double val = stack.tip();
cout << "= " << val << endl << ">>";
}
else if (input == "q")
{
return 0;
}
else
{
cout << "Error: Invalid input" << endl;
}
}
}
我还清理了其他几个错误。
- 增量运算符与后缀混淆
- 控制允许动态运行c++的并发操作数
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 错误 C2679:二进制"<<":未找到采用类型 'std::string_view' 的右侧操作数的运算符(或者没有可接受的转换)
- C++ 带有向量的 IF 计算操作数
- 是否所有C++运算符都接受操作数?
- 如何在OpenSSL库的名称中添加后缀'd'?
- 一元*运算符的操作数是否期望一个 prvalue
- 与'operator='不匹配(操作数类型'String'且"void")
- 不正确的操作数类型 MSVC
- C++17 十六进制浮点文字单精度后缀冲突?
- C2678 二进制 '==':未找到采用 'Card' 类型左操作数的运算符(或者没有可接受的转换)
- 错误:类型"double()"和"double()"的操作数无效到二进制&quo
- 我的运算符重载是否有效<<(流插入)左操作数不是 ostream
- 没有运算符"="与这些操作数匹配,JUCE 窗口演示应用程序
- 如果我在指针中使用 ++ 操作数,我的值就会出错
- 二进制表达式的操作数无效 - 使用 for 和迭代器
- 使用带有链表的堆栈数据结构将中缀转换为后缀
- 计算具有两个以上操作数的后缀表达式时出现问题
- c++后缀计算器不能处理一行中的两个操作数