我已经编写了一个程序,使用UBUNTU中的C语言将中缀转换为后缀...但是我的程序无法正常工作可以帮助吗? 我的计划如下:
#include<stdio.h>
#include<stdlib.h>
char op[50];
struct node
{
char data;
struct node *next;
} *l1=NULL;
void push(char x) // pushes char into the linkedlist
{
if(l1==NULL)
{
l1=(struct node *)malloc(sizeof(struct node));
l1->data=x;
l1->next=NULL;
}
else
{
struct node *p;
p=(struct node *)malloc(sizeof(struct node));
p->data=x;
p->next=l1;
l1=p;
}
}
char pop() // pops char outof linkedlist
{
char c;
struct node *p;
if (l1==NULL)
{
printf("the stack is empty\n");
// exit(1);
}
else
{
c=l1->data;
p=l1->next;
free (l1);
l1=p;
}
return c;
}
void display(struct node *start)
{
{
int i=0;
struct node *p;
p=start;
if(p==NULL)
printf("Empty list");
else
{
while(p!=NULL)
{
printf("%c->",p->data);
p=p->next;
}
printf("NULL\n");
}
}
}
int prior(char s, char c)
{
if ( c=='^' && s=='+' || s=='-' ||s=='/' || s=='*')
return 1;
else if( c=='*' || c=='/')
{
if(s=='+' || s=='-' )
return 1;
else
return 0;
}
else if( c=='+' || c=='-' )
return 0;
}
void cnvrt(char s[], int n) // convert infix to postfix
{
char g;
int i,j,x;
for(i=0,j=0;i<n;i++)
{
if (s[i]>='0'&&s[i]<='9' || s[i]>='a' && s[i]<='z'|| s[i]>='A' && s[i]<='Z')
{
op[j]=s[i];
j++;
}
else if(s[i]=='(')
{
push(s[i]);
}
else if (s[i]=='+' || s[i]=='/' || s[i]=='-' || s[i]=='*' || s[i]=='^')
{
if( l1==NULL)
push(s[i]);
else if(l1->data=='(')
push(s[i]);
else if(prior(l1->data, s[i] )!=1)
push(s[i]);
else
{ op[j]=pop();
j++;
push(s[i]);
}
}
else if(s[i]==')')
{
while(l1!=NULL && l1->data!='(')
{
op[j]=pop();
j++;
}
g=pop();
}
}
while(l1!=NULL)
{
op[j]=pop();
j++;
l1=l1->next;
}
}
void main()
{
int i,n;
char c[50];
printf(" enter the no of characters in infix string\n ");
scanf("%d",&n);
printf(" enter the infix string\n");
//for(i=0;i<n;i++)
scanf("%s",c);
cnvrt(c,n);
printf("the postfix string is \n");
for(i=0;i<n;i++)
{
printf("%c",op[i]);
}
}
答案中始终缺少其中一个运算符...而且它有时会将CORE DUMPED作为输出,如果infix包含'('ot')'那么它会在堆栈为空时给出输出...... 请帮助我,我是一名学生,所以他们可能在我的课程中出错。
答案 0 :(得分:4)
此代码中存在许多问题,一些是次要问题,一些主要。
MAJOR: pop()
如果列表为空,将返回一个不确定的字符(即未定义的行为)。
MINOR:display()
MINOR:i
display()
MAJOR:在prior()
开头if
条款错误。它看起来像这样:
if ( c=='^' && s=='+' || s=='-' ||s=='/' || s=='*')
它应该是这样的:
if ( c=='^' && (s=='+' || s=='-' ||s=='/' || s=='*'))
MAJOR :在prior()
中存在一个没有建立返回值的控制路径,因此该函数具有未定义的行为。见下文
int prior(char s, char c)
{
if ( c=='^' && (s=='+' || s=='-' ||s=='/' || s=='*'))
return 1;
else if( c=='*' || c=='/')
{
if(s=='+' || s=='-' )
return 1;
else
return 0;
}
else if( c=='+' || c=='-' )
return 0;
// ELSE NO RETURN VALUE SET; UNDEFINED BEHAVIOR
}
MINOR:在cnvrt()
中,第一个if
子句接近加密要理解。它看起来像这样:
(s[i]>='0'&&s[i]<='9' || s[i]>='a' && s[i]<='z'|| s[i]>='A' && s[i]<='Z')
考虑将其更新为:
((s[i]>='0'&&s[i]<='9') || (s[i]>='a' && s[i]<='z') || (s[i]>='A' && s[i]<='Z'))
并感谢@cHao对运算符优先级的轻推。
MINOR:cnvrt()
变量x
未使用。
非标准: void
不是main()
的有效返回类型。根据标准,main()
必须返回int
。虽然这可能适用于您的平台,但它不符合标准。
这些只是我在阅读代码时发现的内容,我猜测修复它们将极大地帮助修复程序,尤其是标记为 MAJOR 的项目。如上所述,我不能这样做,所以我只能希望是这种情况。
答案 1 :(得分:3)
以下是工作修改:
#include<stdio.h>
#include<stdlib.h>
char op[50];
struct node
{
char data;
struct node *next;
} *l1=NULL;
void push(char x) // pushes char into the linkedlist
{
if(l1==NULL)
{
l1=(struct node *)malloc(sizeof(struct node));
l1->data=x;
l1->next=NULL;
}
else
{
struct node *p;
p=(struct node *)malloc(sizeof(struct node));
p->data=x;
p->next=l1;
l1=p;
}
}
char pop() // pops char outof linkedlist
{
char c;
struct node *p;
if (l1==NULL)
{
printf("the stack is empty\n");
// exit(1);
}
else
{
c=l1->data;
p=l1->next;
free (l1);
l1=p;
}
return c;
}
void display(struct node *start)
{
{
//int i=0;
struct node *p;
p=start;
if(p==NULL)
printf("Empty list");
else
{
while(p!=NULL)
{
printf("%c->",p->data);
p=p->next;
}
printf("NULL\n");
}
}
}
int prior(char s, char c)
{
if ( (c=='^' && s=='+') || s=='-' ||s=='/' || s=='*')
return 1;
else if( c=='*' || c=='/')
{
if(s=='+' || s=='-' )
return 1;
else
return 0;
}
else if( c=='+' || c=='-' )
return 0;
return -1;
}
void cnvrt(char s[], int n) // convert infix to postfix
{
//char g;
int i,j;//,x;
for(i=0,j=0;i<n;i++)
{
if ((s[i]>='0'&&s[i]<='9') || (s[i]>='a' && s[i]<='z')|| (s[i]>='A' && s[i]<='Z'))
{
op[j]=s[i];
j++;
}
else if(s[i]=='(')
{
push(s[i]);
}
else if (s[i]=='+' || s[i]=='/' || s[i]=='-' || s[i]=='*' || s[i]=='^')
{
if( l1==NULL)
push(s[i]);
else if(l1->data=='(')
push(s[i]);
else if(prior(l1->data, s[i] )!=1)
push(s[i]);
else
{ op[j]=pop();
j++;
push(s[i]);
}
}
else if(s[i]==')')
{
while(l1!=NULL && l1->data!='(')
{
op[j]=pop();
j++;
}
pop();
}
}
while(l1!=NULL)
{
op[j]=pop();
j++;
}
}
int main()
{
int i,n;
char c[50];
printf(" enter the no of characters in infix string\n ");
scanf("%d",&n);
printf(" enter the infix string\n");
//for(i=0;i<n;i++)
scanf("%s",c);
cnvrt(c,n);
printf("the postfix string is \n");
for(i=0;i<n;i++)
{
printf("%c",op[i]);
}
return 0;
}
您可以diff代码并查找修改,或查看@WhozCraig答案。那里有一些小错误,但导致内存错误的错误就是这个部分:
//127-132
while(l1!=NULL)
{
op[j]=pop();
j++;
l1=l1->next;
}
调试器中的:
> gcc code.c -Wall -g
> gdb -q a.exe
Reading symbols from a.exe...done.
(gdb) run
Starting program: a.exe
[New Thread 4000.0x524]
enter the no of characters in infix string
3
enter the infix string
1+2
Program received signal SIGSEGV, Segmentation fault.
0x004016f9 in cnvrt (s=0x22fee6 "1+2", n=3) at code.c:131
131 l1=l1->next;
(gdb)
(gdb) p l1
$1 = (struct node *) 0x0
(gdb)
l1
为NULL
,因此l1->next
将失败。你需要做到:
while(l1!=NULL)
{
op[j]=pop();
j++;
}
pop()
负责更改l1
的指针,然后当它从最后一项完成时,它将指向NULL
,然后访问l1->next
将失败。
现在几乎没有测试:
> a.exe
enter the no of characters in infix string
3
enter the infix string
1+2
the postfix string is
12+
> a.exe
enter the no of characters in infix string
7
enter the infix string
(1+3)*4
the postfix string is
13+4*
>