使用向量将给定表达式转换为波兰符号时的运行时错误
Posted
技术标签:
【中文标题】使用向量将给定表达式转换为波兰符号时的运行时错误【英文标题】:Run-time error when using vectors to convert given expression into polish notation 【发布时间】:2018-06-21 11:16:01 【问题描述】:我的程序目标是将给定的数学表达式转换为波兰符号。 数学表达式存储在向量中,并使用递归。
编译时出现运行时错误。 使用调试器会显示分段错误 (SIGSEGV)。
假设输入的形式为(a+b),对应的输出为ab+。 (括号必填)
其实是SPOJ的this problem。
我的做法如下——
使用向量来存储表达式
如果表达式大小大于 1
然后使用 pop_back 和 vector::erase 删除总是出现在字符串末尾的括号。
将向量分为三部分——字符串1、运算符和字符串2(字符串1和字符串2是向量)
使用递归将向量字符串 1 和字符串 2 简化为波兰符号
清除传递给函数的原始向量并将字符串 1 、运算符和字符串 2 添加到它。
change() 用于完成所有这些事情
这是我的程序,它将单个语句转换为它的波兰符号。
#include <iostream>
#include <vector>
void convert(std::vector <char> &vect)
if(vect.size()!=1&&vect.size()!=0)
vect.pop_back();
vect.erase(vect.begin());
std::vector<char> str1;
std::vector<char> str2;
char op;
int i=0;
int reqcount = 0;
while(1)
if(vect[i]=='(')
reqcount++ ;
if(vect[i]==')')
reqcount-- ;
str1.push_back(vect[i]);
if(!reqcount)
break;
i++;
op=vect[i];
while((i+1)!=vect.size())
str2.push_back(vect[i+1]);
i++;
vect.clear();
convert(str1);
convert(str2);
for(int i=0; i<str1.size(); i++ )
vect.push_back(str1[i]);
vect.push_back(op);
for(int i=0;i<str2.size();i++)
vect.push_back(str2[i]);
int main( void )
std::vector<char> testinput;;
char c;
std::cin>>std::noskipws;
while(std::cin>>c&&c!='\n')
testinput.push_back(c);
convert(testinput);
for(int i=0;i<testinput.size();i++)
std::cout<<testinput[i];
return 0;
【问题讨论】:
"...编译时出现分段错误。(SIGSEGV)..." 不,您遇到运行时错误,请使用调试器查找。 你忘了处理空的vect
。
对不起。已将分段错误更改为运行时错误。
包括空 vect 的情况,但我认为当 vect 为空时不会出现这种情况,除非输入为空。
【参考方案1】:
您以int i = 0
开头,它将指向整个括号 ()。它会将整个字符串读取为 str1 减去结束的 ')'。如果我没记错的话 op 将是 ')' 并且 str2 将保持为空。
然后你递归地调用'convert(str1)',它没有结束括号,所以你会尝试越过数组的末尾并获取你的 SIGSEGV。
确保您的拆分正常工作,并仔细检查边界条件以防止它发生。
附:您的解决方案是 O(N^2)。你可以做 O(N)。
【讨论】:
实际上,如果从表达式中删除括号,那么我认为拆分会正常工作。 假设表达式为 (a+b)。删除括号后,它将是 a + b 。在字符串 1 中插入 a 后,循环将停止。 其实我真的不知道如何使用调试器调试程序。但是在尝试 i 之后,似乎末尾的括号没有被正确删除,从而导致您提到的问题。 好吧。你是对的,我的分裂是错误的。我在错误的地方增加了 i 的值。它应该在遇到 break 之前增加。否则,如果输入为 (a+b) 导致错误,则字符串 2 将仅以右括号结束。谢谢。以上是关于使用向量将给定表达式转换为波兰符号时的运行时错误的主要内容,如果未能解决你的问题,请参考以下文章