南阳 oj 郁闷的c小加(三) 题目409

/*

表达式树思路

(a+b)*(c*(d+e);

对该树进行后序遍历得到后缀表达式

ab+cde+**;

这里实现的是如何根据一个后缀表达式,构造出其相应的表达式树。

算法思想:其实很简单,主要就是栈的使用。算法时间复杂度是O(n),n是后缀表达式长度。

从前向后依次扫描后缀表达式,如果是操作数就建立一个单节点树,并把其指针压入栈。如果是操作符,则

建立一个以该操作符为根的树,然后从栈中依次弹出两个指针(这2个指针分别指向2个树),作为该树的

左右子树。然后把指向这棵树的指针压入栈。直到扫描完后缀表达式。

最后栈中就会只有一个指针。这个指针指向构造的表达式树的根节点。*/(a+b)*(c*(d+e);

对该树进行后序遍历得到后缀表达式

ab+cde+**;

这里实现的是如何根据一个后缀表达式,构造出其相应的表达式树。

算法思想:其实很简单,主要就是栈的使用。算法时间复杂度是O(n),n是后缀表达式长度。

从前向后依次扫描后缀表达式,如果是操作数就建立一个单节点树,并把其指针压入栈。如果是操作符,则

建立一个以该操作符为根的树,然后从栈中依次弹出两个指针(这2个指针分别指向2个树),作为该树的

左右子树。然后把指向这棵树的指针压入栈。直到扫描完后缀表达式。

最后栈中就会只有一个指针。这个指针指向构造的表达式树的根节点。

#include<stdio.h>

#include<malloc.h>

#include<stdlib.h>

#include<string.h>

#include<stack>

#define N 1000

using namespace std;

char str[N],s[2*N];

typedef struct node//二叉树,节点类型

{

char x[10];

struct node *lchild;

struct node *rchild;

}*linklist;

stack<linklist>ch;//存储节点

stack<char>ca;//存储运算符

stack<double> num;

int top;

int com(char x)

{

switch(x)

{

case ‘+‘ :

case ‘-‘ :return 1;

case ‘*‘ :

case ‘/‘ :return 2;

case ‘(‘ :return 0;

default: return -1;

}

}

void zhuan()

{

while(!ca.empty())

ca.pop();

scanf("%s",str);

top=-1;

int k=strlen(str);

ca.push(‘#‘);

for(int i=0;i<k;i++)

{

if(str[i]>=‘0‘&&str[i]<=‘9‘||str[i]==‘.‘)

{

top++;

s[top]=str[i];

}

else if(str[i]==‘+‘||str[i]==‘-‘||str[i]==‘*‘||str[i]==‘/‘)

{

top++;

s[top]=‘,‘;

if(com(str[i])>com(ca.top())) ca.push(str[i]);

else

{

while(com(ca.top())>=com(str[i]))

{

top++;

s[top]=ca.top();

ca.pop();

top++;

s[top]=‘,‘;

}

ca.push(str[i]);

}

}

else if(str[i]==‘(‘) ca.push(str[i]);

else if(str[i]==‘)‘)

{

while(ca.top()!=‘(‘)

{

top++;

s[top]=‘,‘;

top++;

s[top]=ca.top();

ca.pop();

}

ca.pop();

}

}

while(ca.top()!=‘#‘)

{

top++;

s[top]=‘,‘;

top++;

s[top]=ca.top();

ca.pop();

}

}

linklist cre()//根据后缀式创建二叉树

{

while(!ch.empty())

ch.pop();

for(int i=0;i<=top;i++)

{

if(s[i]==‘+‘||s[i]==‘-‘||s[i]==‘/‘||s[i]==‘*‘)

{

linklist tree;

tree=(linklist)malloc(sizeof(struct node));

tree->x[0]=s[i];

tree->x[1]=‘\0‘;

tree->rchild=ch.top();

ch.pop();

tree->lchild=ch.top();

ch.pop();

ch.push(tree);

i++;

}

else if(s[i]>=‘0‘&&s[i]<=‘9‘)

{

linklist tree;

tree=(linklist)malloc(sizeof(struct node));

tree->lchild=NULL;

tree->rchild=NULL;

int j=0;

char b[10];

while(s[i]!=‘,‘)

{

b[j]=s[i];

j++;

i++;

}

b[j]=‘\0‘;

strcpy(tree->x,b);

ch.push(tree);

}

}

return ch.top();

}

void xtree(linklist head)//前缀式输出

{

if(head)

{

printf("%s ",head->x);

xtree(head->lchild);

xtree(head->rchild);

}

}

void xiao(linklist head)

{

if(head)

{

if(head->lchild) xiao(head->lchild);

if(head->rchild) xiao(head->rchild);

free(head);

}

}

void ji()

{

while(!num.empty())

num.pop();

num.push(‘#‘);

double a1,a2;

char s3[15];

char x;

int k;

for(int i=0;i<=top;i++)

{

x=s[i];

if(x>=‘0‘&&x<=‘9‘)

{

k=0;

while(s[i]!=‘,‘)

{

s3[k]=s[i];

k++;

i++;

}

s3[k]=‘\0‘;

num.push(atof(s3));

}

else

{

switch(x)

{

case ‘+‘:

a1=num.top();

num.pop();

a2=num.top();

num.pop();

num.push(a1+a2);

break;

case ‘-‘:

a1=num.top();

num.pop();

a2=num.top();

num.pop();

num.push(a2-a1);

break;

case ‘*‘:

a1=num.top();

num.pop();

a2=num.top();

num.pop();

num.push(a2*a1);

break;

case ‘/‘:

a1=num.top();

num.pop();

a2=num.top();

num.pop();

num.push(a2/a1);

break;

}

}

}

printf("%.2lf\n",num.top());

}

int main()

{

int m;

scanf("%d",&m);

while(m--)

{

zhuan();

linklist head;

head=cre();

xtree(head);

printf("=\n");

xiao(head);

for(int i=0;i<=top;i++)

{

if(s[i]==‘,‘) printf(" ");

else printf("%c",s[i]);

}

printf(" =\n");

ji();

}

return 0;

}



版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-25 08:41:22

南阳 oj 郁闷的c小加(三) 题目409的相关文章

南阳oj 郁闷的c小加(一) 题目257

 #include<stdio.h> #include <string.h> #include <stack> #define N 1000 using namespace std; stack<char> op;//定义保存运算符的栈 char s1[N],s2[N]; int priority(char ch)//定义运算符的优先级 { int num; switch(ch) { case '+': case '-':return 1; case '

南阳oj 郁闷的c小加(二) 题目267

 #include<stdio.h> #include<stack> #include<string.h> #define N 1000 #include<stdlib.h> using namespace std; stack<char> str;//字符栈  转化为后缀式 stack<double> num;//数字栈  计算值 char s1[N],s2[N],s3[1000000]; int top; int com(ch

郁闷的C小加(一)

郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符在两个操作数之后:num1 num2 operand.ACM队的"C小加"正在郁闷怎样把一个中缀表达式转换为后缀表达式,现在请你设计一个程序,帮助C小加把中缀表达式转换成后缀表达式.为简化问题,操作数均为个

郁闷的C小加(二)

郁闷的C小加(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 聪明的你帮助C小加解决了中缀表达式到后缀表达式的转换(详情请参考"郁闷的C小加(一)"),C小加很高兴.但C小加是个爱思考的人,他又想通过这种方法计算一个表达式的值.即先把表达式转换为后缀表达式,再求值.这时又要考虑操作数是小数和多位数的情况. 输入 第一行输入一个整数T,共有T组测试数据(T<10). 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算

NYOJ 257 郁闷的C小加(一)

郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符在两个操作数之后:num1 num2 operand.ACM队的"C小加"正在郁闷怎样把一个中缀表达式转换为后缀表达式,现在请你设计一个程序,帮助C小加把中缀表达式转换成后缀表达式.为简化问题,操作数均为个

NYOJ257郁闷的C小加(一)

郁闷的C小加(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 我们熟悉的表达式如a+b.a+b*(c+d)等都属于中缀表达式.中缀表达式就是(对于双目运算符来说)操作符在两个操作数中间:num1 operand num2.同理,后缀表达式就是操作符在两个操作数之后:num1 num2 operand.ACM队的"C小加"正在郁闷怎样把一个中缀表达式转换为后缀表达式,现在请你设计一个程序,帮助C小加把中缀表达式转换成后缀表达式.为简化问题,操作数均为个

南阳236--心急的C小加

心急的C小加 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 C小加有一些木棒,它们的长度和质量都已经知道,需要一个机器处理这些木棒,机器开启的时候需要耗费一个单位的时间,如果第i+1个木棒的重量和长度都大于等于第i个处理的木棒,那么将不会耗费时间,否则需要消耗一个单位的时间.因为急着去约会,C小加想在最短的时间内把木棒处理完,你能告诉他应该怎样做吗? 输入 第一行是一个整数T(1<T<1500),表示输入数据一共有T组.每组测试数据的第一行是一个整数N(1<

NYOJ 南阳oj 懒省事的小明 题目55

 /* 懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述       小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.小明决定把所有的果子合成一堆. 因为小明比较懒,为了省力气,小明开始想点子了: 每一次合并,小明可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了.小明在合并果子时总共消耗的体力等于每次合并所耗体力之和. 因

南阳 oj 擅长排列的小明 题目19

 next  以及pre  函数的用法 http://blog.csdn.net/yueloveme/article/details/47164529 #include <stdio.h> #include <string.h> #include <algorithm> char a[10]={'1','2','3','4','5','6','7','8','9','\0'};//给定一个已排列的数组 using namespace std; int main()