我编写了一个c ++程序,用于将中缀表达式转换为后缀表达式。 每当我运行它,它似乎进入无限循环。 我已经使用堆栈来存储运算符和括号等,并使用一个队列来存储后缀表达式本身。 用户输入整个中缀表达式,程序一次取一个字符,而中缀表达式的其余部分保留在stdin流中。
我无法弄清楚这个程序中的错误,请帮忙!
程序代码:
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
struct LIST
{
char val;
LIST* next;
};
LIST* start_stack=NULL;
LIST* start_post=NULL;
LIST* end_post=NULL;
LIST* np;
int check_char(char a)
{
if(isalnum(a))
return 1;//For operand
else if(a=='^'||a=='*'||a=='/'||a=='+'||a=='-') //For operator
{
if(a=='^')
return 21;
else if(a=='*'||a=='/')
return 22;
else
return 23;
}
else if(a=='('||a=='['||a=='{')//For openeing parenthesis
return 3;
else if(a==')'||a=='}'||a==']')
return 4;
else
return 0;
}
void push(LIST* push_element, int i=1)
{
if(i==1)
{
if(start_stack==NULL)
start_stack=push_element;
else
{
LIST* temp;
temp=start_stack;
start_stack=np;
start_stack->next=temp;
}
}
else
{
if(start_post==NULL)
start_post=end_post=np;
else
{
end_post->next=np;
end_post=np;
}
}
}
void pop(LIST* pop_element)
{
LIST *temp;
temp=pop_element;
pop_element=pop_element->next;
delete temp;
}
void Infix_to_Postfix()
{
char a;
cin>>a;
while(a!='.')
{
if(check_char(a)==1)
{
np=new LIST;
np->val=a;
np->next=NULL;
push(np,2);
}
else if(check_char(a)>20)
{
while(start_stack!=NULL&&check_char(start_stack->val)!=3)
{
if(check_char(a)>=check_char(start_stack->val))
{
np=new LIST;
np->val=start_stack->val;
np->next=NULL;
push(np,2);
pop(start_stack);
}
}
np=new LIST;
np->val=a;
np->next=NULL;
push(np);
}
else if(check_char(a)==3)
{
np=new LIST;
np->val=a;
np->next=NULL;
push(np);
}
else if(check_char(a)==4)
{
while(start_stack!=NULL&&check_char(start_stack->val)!=3)
{
np=new LIST;
np->val=start_stack->val;
np->next=NULL;
push(np,2);
pop(start_stack);
}
pop(start_stack);
}
cin>>a;
}
while(start_stack!=NULL)
{
np=new LIST;
np->val=start_stack->val;
np->next=NULL;
push(np,2);
pop(start_stack);
}
while(start_post!=NULL)
{
cout<<endl;
cout<<start_post->val;
start_post=start_post->next;
}
}
int main()
{
clrscr();
Infix_to_Postfix();
getch();
return 1;
}
答案 0 :(得分:0)
功能中存在问题。
void pop(LIST* pop_element)
弹出的值可以找到,但它不会修改sent in参数。
所以行
pop(start_stack);
删除内存start_stack,但不会更改指针start_stack。 创建引用将解决此问题。
即
void pop(LIST* & pop_element)
{
LIST *temp;
temp=pop_element;
pop_element=pop_element->next;
delete temp;
}
我的调试环境使用了MSVC和调试堆。当第二次释放相同的内存时,它在调试器中破坏并且相对容易解决这个问题。对于linux,你可以在windows上使用valgrind,非MS编译器Application Verifier会发现这个问题。
如果您使用调试器单步执行代码。查看变量的值,并检查它们是否符合您的预期。
在这种情况下(没有调试堆,我可以看到指针start_stack
没有改变值。
提供的代码是列表,堆栈的实现,并将它们一起用于所需的中缀到后缀转换。
尝试单独测试列表行为与较大问题的单元测试。 尝试单独测试堆栈行为与较大问题的单元测试。堆栈溢出需要最小的可验证代码示例(SO : MCVE)。这是为了鼓励您解构您的问题,以找到最不起作用的最小代码。这也应该有助于您专注于如何解决它。
当您实现堆栈和队列时,请尝试与std :: stack和std :: queue行为进行比较,再次帮助您识别失败的单元。
最后,对于堆栈溢出,一个吃stdin的程序很难让人们看到正在发生的事情。确保指定导致行为所需的输入,或提供从其自身获取输入的程序....
void Old()
{
int myVar;
cin > myVar;
}
int main()
{
Old();
}
应该是
void Old( std::istream & stm )
{
int myVar;
stm > myVar;
}
int main()
{
std::stringstream s( "123" ); // test value causes issue.
Old(s );
}