问题描述
中缀表达式就是我们通常所书写的数学表达式,后缀表达式也称为逆波兰表达式,在编译程序对我们书写的程序中的表达式进行语法检查时,往往就可以通过逆波兰表达式进行。我们所要设计并实现的程序就是将中缀表示的算术表达式转换成后缀表示,例如,将中缀表达式
(A 一 (B*C 十 D)*E) / (F 十 G )
转换为后缀表示为:ABC*D十E*--FG十/
注意:为了简化编程实现,假定变量名均为单个字母,运算符只有+,-,*,/ 和^(指数运算,要注意运算符的结合性),可以处理圆括号 (),并假定输入的算术表达式正确。
要求:使用栈数据结构实现 ,输入的中缀表达式以#号结束
输入
整数N。表示下面有N个中缀表达式
N个由单个字母和运算符构成的表达式
输出
N个后缀表达式。
我的第一种思路是获取可能得到的最大的指数max,然后从I等于0开始遍历到max,把i分为可以相加得到它的两个值,再在链表里去找这两个值
/* PRESET CODE BEGIN - NEVER TOUCH CODE BELOW */
#include <stdio.h>
#include <stdlib.h>
/*
<1,0>,<2,1>,<1,2>,
<1,0>,<1,1>,
<-1,0>,<1,1>,
<1,0>,<1,1>,
<0,0>,
<0,0>,
*/
typedef struct node
{ int coef, exp;
struct node *next;
} NODE;
void multiplication( NODE *, NODE * , NODE * );
void input( NODE * );
void output( NODE * );
void input( NODE * head )
{ int flag, sign, sum, x;
char c;
NODE * p = head;
while ( (c=getchar()) !='\n' )
{
if ( c == '<' )
{ sum = 0;
sign = 1;
flag = 1;
}
else if ( c =='-' )
sign = -1;
else if( c >='0'&& c <='9' )
{ sum = sum*10 + c - '0';
}
else if ( c == ',' )
{ if ( flag == 1 )
{ x = sign * sum;
sum = 0;
flag = 2;
sign = 1;
}
}
else if ( c == '>' )
{ p->next = ( NODE * ) malloc( sizeof(NODE) );
p->next->coef = x;
p->next->exp = sign * sum;
p = p->next;
p->next = NULL;
flag = 0;
}
}
}
void output( NODE * head )
{
while ( head->next != NULL )
{ head = head->next;
printf("<%d,%d>,", head->coef, head->exp );
}
printf("\n");
}
int main()
{ NODE * head1, * head2, * head3;
head1 = ( NODE * ) malloc( sizeof(NODE) );
input( head1 );
head2 = ( NODE * ) malloc( sizeof(NODE) );
input( head2 );
head3 = ( NODE * ) malloc( sizeof(NODE) );
head3->next = NULL;
multiplication( head1, head2, head3 );
output( head3 );
return 0;
}
void multiplication( NODE *head1, NODE * head2, NODE * head3){
int max1=-1,max2=-1;
NODE * p=head1->next;
NODE * q=head2->next;
while(p!=NULL){
if(p->exp>max1){
max1=p->exp;
}
p=p->next;
}
while(q!=NULL){
if(q->exp>max2){
max2=q->exp;
}
q=q->next;
}
int max=max1+max2;
//printf("%d",max);//max是能得到的最大指数
NODE *r=head3;
for(int i=0;i<max+1;i++){//找出结果中系数为i的
NODE *m;
m = ( NODE * ) malloc( sizeof(NODE) );
m->exp=i;
int xishu=0;
int flag=0;
for(int j=0;j<=i;j++){//得到i的每一项
NODE *s=head1->next;
flag=0;
int k;
for( k=0;s->exp!=j&&k<max1;k++){
s=s->next;
}
if(s->exp!=j){
flag=1;
}//printf("flag=%d j=%d exp=%dcoef=%d\n",flag,j,s->exp,s->coef);
NODE *t=head2->next;
for( k=0;t->exp!=i-j&&k<max2;k++){
t=t->next;//printf("mad\n");
}
if(t->exp!=i-j){
flag=1;
}//printf("flag=%d j=%d exp=%dcoef=%d\n",flag,j,t->exp,t->coef);
if(flag==0){
xishu+=(t->coef)*(s->coef);
}
//printf("xishu=%d i=%d flag=%d\n",xishu,i,flag);
//printf("%d\n",xishu);
}
if(xishu!=0){
m->coef=xishu;
r->next=m;
r=m;
}
}
r->next=NULL;
}
/* PRESET CODE END - NEVER TOUCH CODE ABOVE */
这个做法可以把所有的非隐藏案例过了,但是隐藏案例显示内存RE了,所以我尝试另一种方法,先建一个数组将每一项依次相乘,将得到的答案先存入数组中,再利用数组建表。
但是面对的第一个问题就是数组只能做到自然数,负数没有位子。所以要再建一个数组处理负数的
int zhengshu[10010],fushu[10010];
void multiplication( NODE *head1, NODE * head2, NODE * head3){
int max1=-1,max2=-1;
NODE * p=head1->next;
NODE * q=head2->next;
while(p!=NULL){
if(p->exp>max1){
max1=p->exp;
}
p=p->next;
}
while(q!=NULL){
if(q->exp>max2){
max2=q->exp;
}
q=q->next;
}
int max=max1+max2;
//printf("%d",max);//max是能得到的最大指数
memset(zhengshu,0,sizeof(zhengshu));
memset(fushu,0,sizeof(fushu));
p=head1;
q=head2;
while(p->next!=NULL){
p=p->next;
q=head2;
while(q->next!=NULL){//1个p找n个q相乘
q=q->next;
int xishu=p->coef*q->coef;
int zhishu=p->exp+q->exp;
if(zhishu>=0){
zhengshu[zhishu]+=xishu;
}
else{
fushu[-1*zhishu]+=xishu;
}
}}
int fu=0;
for(int i=0;i<10010;i++){
if(fushu[i]!=0){
fu=i;
}
}
if(fu!=0){//有负数部分
NODE *r=head3;
for(int i=fu;i>0;i--){
if(fushu[i]!=0){
NODE *m;
m = ( NODE * ) malloc( sizeof(NODE) );
m->exp=i*-1;
m->coef=fushu[i];
r->next=m;
r=m;
}
}
for(int i=0;i<=max;i++){
if(zhengshu[i]!=0){
NODE *m;
m = ( NODE * ) malloc( sizeof(NODE) );
m->exp=i;
m->coef=zhengshu[i];
r->next=m;
r=m;
}
}
r->next=NULL;
}
if(fu==0){
NODE *r=head3;
for(int i=0;i<=max;i++){
if(zhengshu[i]!=0){
NODE *m;
m = ( NODE * ) malloc( sizeof(NODE) );
m->exp=i;
m->coef=zhengshu[i];
r->next=m;
r=m;
}
}
r->next=NULL;
}
}
/* PRESET CODE END - NEVER TOUCH CODE ABOVE */
然而还是过不了
两个WA,两个RE
考虑了00输出之后,就两个RE了
把10010改为102399后就最后一个RE了
所以题目的意思是让我们的到系数了就直接建表
void multiplication(NODE *head1, NODE *head2, NODE *head3)
{
NODE *p, *q, *r;
p = q = r = head3;
NODE *h1 = head1->next, *h2 = head2->next;
int coef = 0, exp = 0;
while(h1 != NULL)
{
while(h2 != NULL)
{
coef = h1->coef * h2->coef;
if (coef == 0)
{
h2 = h2->next;
continue;
}
exp = h1->exp + h2->exp;
if (p->next == NULL)
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = coef;
s->exp = exp;
s->next = NULL;
p->next = s;
}
else
{
if(r->next != NULL && exp > r->next->exp)
{
q = r;
while(q->next != NULL && exp > q->next->exp)
{
q = q->next;
r = q;
}
}
else
{
while(q->next != NULL && exp > q->next->exp)
{
q = q->next;
r = q;
}
}
NODE *temp = q->next;
if(q->next == NULL)
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = coef;
s->exp = exp;
s->next = NULL;
q->next = s;
}
else if(temp->exp == exp)
{
temp->coef += coef;
if(temp->coef == 0)
{
NODE *dele = temp->next;
q->next = dele;
free(temp);
}
}
else if(temp->exp > exp)
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = coef;
s->exp = exp;
q->next = s;
s->next = temp;
}
}
h2 = h2->next;
q = head3;
}
h2 = head2->next;
h1 = h1->next;
}
if(head3->next == NULL)
{
NODE *s = (NODE*)malloc(sizeof(NODE));
s->coef = 0;
s->exp = 0;
s->next = NULL;
head3->next = s;
}
return;
}