用栈实现把前缀变后缀和中缀的原代码

gudaodeai 2011-11-01 08:11:12
给你的是中缀表达式,怎样变成前缀呢?前缀又怎么变成后缀呢,难死我了。急急急。
...全文
359 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
火龙 2011-11-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 gudaodeai 的回复:]

大虾,给你出道题。输入前缀表达式:+*ab*-c/def.编个程序,让其输出是:ab*cde/-f*+(这是后缀表达式)。大虾会不???我急用
[/Quote]

楼主,你这样做已经非常不厚道了,我给的和楼上楼上给的都是关于这个的源码,对于这样代码长度的CSDN论坛一般不会给源码的,而且CSDN以及各种论坛不欢迎找人写作业的,既然你要的其中一种情况已经给出的完整的源码你要是自己思考了一定马上可以举一反三,但是你一再的要求源码,根本不理会别人给思路。如果你坚持要求我们帮你写作业请自行离开,这里不是你找人帮忙写作业的地方。
gudaodeai 2011-11-07
  • 打赏
  • 举报
回复
大虾,给你出道题。输入前缀表达式:+*ab*-c/def.编个程序,让其输出是:ab*cde/-f*+(这是后缀表达式)。大虾会不???我急用
尘缘udbwcso 2011-11-06
  • 打赏
  • 举报
回复

//表达式求值
#include <stdio.h>
#include <malloc.h>
#include <string.h>
/*
*功能:根据运算符计算
*参数:a, b参与运算的数, ch运算符
*返回值:计算结果,操作符错误则返回0
*/
int cal(int a, char ch, int b)
{
switch(ch)
{
case '+':
return a+b;
break;
case '-':
return a-b;
break;
case '*':
return a*b;
break;
case '/':
return a/b;
break;
}
return 0;
}
/*
*功能:计算表达式的值(用数组模拟栈)
*参数:表达式字符串
*返回值:计算结果
*/
int evaluateExpression(char *str)
{
int i = 0, result, numSub = 0, operSub = 0;
int tmp, len = strlen(str);
int *operand = (int*)malloc(sizeof(int)*len);
char *operat = (char*)malloc(sizeof(char)*len);
while(str[i] != '\0')
{
switch(str[i])
{
case '+':
while(operSub > 0 && operat[operSub-1] != '(')
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
operat[operSub++] = '+';
break;
case '-':
while(operSub > 0 && operat[operSub-1] != '(')
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
operat[operSub++] = '-';
break;
case '*':
if(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = 0;
while(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = tmp * 10 + str[i+1] - '0';
++i;
}
--i;
printf("%d * %d = ", operand[numSub-1], tmp);
operand[numSub-1] = cal(operand[numSub-1], '*', tmp);
printf("%d\n", operand[numSub-1]);
++i;
}
else
operat[operSub++] = '*';
break;
case '/':
if(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = 0;
while(str[i+1] >= '0' && str[i+1] <= '9')
{
tmp = tmp * 10 + str[i+1] - '0';
++i;
}
--i;
printf("%d / %d = ", operand[numSub-1], tmp);
operand[numSub-1] = cal(operand[numSub-1], '/', tmp);
printf("%d\n", operand[numSub-1]);
++i;
}
else
operat[operSub++] = '/';
break;
case '(':
operat[operSub++] = '(';
break;
case ')':
while(operat[operSub-1] != '(')
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
--operSub;
break;
default:
tmp = 0;
while(str[i] >= '0' && str[i] <= '9')
{
tmp = tmp * 10 + str[i] - '0';
++i;
}
--i;
operand[numSub++] = tmp;
break;
}
++i;
}
while(numSub > 1 && operSub >= 1)
{
printf("%d %c %d = ", operand[numSub-2], operat[operSub-1], operand[numSub-1]);
operand[numSub-2] = cal(operand[numSub-2], operat[operSub-1], operand[numSub-1]);
printf("%d\n", operand[numSub-2]);
--numSub;
--operSub;
}
result = operand[numSub-1];
free(operand);
free(operat);
return result;
}
int main()
{
char *str = "225/15-20+(4-3)*2";
int result;
printf("计算过程:\n");
result = evaluateExpression(str);
printf("计算结果:result = %d\n", result);
return 0;
}

计算过程:
225 / 15 = 15
15 - 20 = -5
4 - 3 = 1
1 * 2 = 2
-5 + 2 = -3
计算结果:result = -3
gudaodeai 2011-11-06
  • 打赏
  • 举报
回复
好啊,我给你一个前缀。+*ab*-c/def。现在就这个式子,大虾,你能把它变成ab*cde/-f*+吗?记得用栈来实现哦。大虾,你会不?????。
火龙 2011-11-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 gudaodeai 的回复:]

中缀变后缀,我也会,但前缀变后缀呢?我不会,你会不?????
[/Quote]
既然都会前者了后者还不是顺水推舟的事情?你的输出只不过是把顺序调动了一下罢了,如果还是不会那只能说你还没弄懂这个原理,这就跟树的前序中序和后序遍历一样的过程
gudaodeai 2011-11-02
  • 打赏
  • 举报
回复
记得要用栈实现
gudaodeai 2011-11-02
  • 打赏
  • 举报
回复
中缀变后缀,我也会,但前缀变后缀呢?我不会,你会不?????
火龙 2011-11-01
  • 打赏
  • 举报
回复
主函数所在文件:

#include <iostream>
#include "Stack.h"
using namespace std;

int func (char c) //返回栈顶运算符的优先级
{
int top = 0;
switch (c)
{
case '+':
case '-':
top = 1;
break;
case '*':
case '/':
top = 2;
break;
case ')':
top = 3;
break;
case '(':
top = 0;
break;
default:
break;
}

return top;

}

int main ()
{
cout << "请输入中缀表达式:" << endl;
char *string;
Stack<char> str1(1000), str2(1000);
string = new char [1000];
cin >> string;
int i = 0;
int *order;
order = new int [1000];


while (string [i] != '\0') //判定输入表达式内运算符的优先级
{
if (string [i] == '+' || string [i] == '-')
order [i] = 1;
else if (string [i] == '*' || string [i] == '/')
order [i] = 2;
else if (string [i] == ')')
order [i] = 3;
else if (string [i] == '(')
order [i] = 0;
else
{ }
i ++;
}

i = 0;
int top;
char z;

while (string [i] != '\0')
{
if (string [i] == '+' || string [i] == '-'
|| string [i] == '*' || string [i] == '/'
|| string [i] == '(' || string [i] == ')')
{
if (!str2.isEmpty ())
{
if (order [i] <= top)
{
while (order[i] <= top && !str2.isEmpty () && string[i] != '(')
{
str2.pop (z);
str1.push (z);
// str2.push (string [i]);
top = func (str2.getStack());
}
str2.push (string [i]);
}
else
{
str2.push (string [i]);
top = func (str2.getStack ());
}
}
else
{
str2.push (string [i]);
top = func (str2.getStack());
}
}
else
{
str1.push (string [i]);
}

i ++;
}


cout << "\n输出后缀表达式:\n";

while (!str1.isEmpty ())
{
str1.pop (z);
str2.push (z);
}

while (!str2.isEmpty ())
{
str2.pop (z);
if (z != '(' && z != ')')
cout << z;
}

delete [] string;
delete [] order;

cout << endl;

system ("pause");

return 0;
}

火龙 2011-11-01
  • 打赏
  • 举报
回复
栈声明:
文件名是:Stack.h

#ifndef STACK_H
#define STACK_H

template <class T>
class Stack
{
public:
Stack (int = 20);
~Stack () {delete [] stackPtr;}
void push (const T&);
void pop (T&);
int isEmpty () const {return top == -1;}
int isFull () const {return top == size - 1;}
void addTop (int);
void detructTop (int);
int getTop () {return top;}
T getStack () {return stackPtr[top];}
private:
int size;
int top;
T *stackPtr;
};

template <class T>
Stack<T>::Stack (int s)
{
size = s;
top = -1;
stackPtr = new T [size];
}

template <class T>
void Stack<T>::push (const T &item)
{
if (!isFull())
{
stackPtr[++top] = item;
}
else
cout << "ERRO!" << endl;
}

template <class T>
void Stack<T>::pop (T &item)
{
if (!isEmpty ())
{
item = stackPtr [top--];
}
}

template <class T>
void Stack<T>::addTop (int s)
{
top = top + s;
}

template <class T>
void Stack<T>::detructTop (int s)
{
top = top - s;
}

#endif
火龙 2011-11-01
  • 打赏
  • 举报
回复
给你一个转后缀的,你自己去写另一个
作为结束符的中缀算术表达式已经保存在s1字符串中,转换后得到的后缀算术表达式拟存于s2字符串中。由中缀表达式转换为后缀表达式的规则可知:转换前后,表达式中的数值项的次序不,而运算符的次序发生了化,由处在两个运算对象的中间为处在两个运算对象的后面,同时去掉了所有的括号。为了使转换正确,必须设定一个运算符栈,并在栈底放入一个特殊算符,假定为’@’字符,让它具有最低的运算符优先级,假定为数值0,此栈用来保存扫描中缀表达式得到的暂不能放入后缀表达式中的运算符,待它的两个运算对象都放入到后缀表达式以后,再令其出栈并写入到后缀表达式中。 把中缀表达式转换为后缀表达式算法的基本思路是从头到尾地扫描中缀表达式中的每个字符,对于不同类型的字符按不情况进行处理。 若遇到的是空格则认为是分隔符,不需要进行处理; 若遇到的是数字或小数点,则直接写入到s2中,并在每个数值的最后写入一个空格; 若遇到的是左括号,则应把它压入到运算符栈中,待以它开始的括号内的表达式转换完毕后再出栈; 若遇到的是右括号,则表明括号内的中缀表达式已经扫描完毕,把从栈底直到保存着的对应左括号之间的运算符依次退栈并写入s2串中; 若遇到的是运算符,当该运算符的优先级大于栈顶运算符的优先级(加减运算符的优先级设定为1,乘除运算符的优先级设定为2,在栈中保存的特殊运算符’@’和’(’的优先级设定为0)时,表明该运算符的后一个运算对象还没有被扫描并放入到s2串中,应把它暂存于运算符栈中,待它的后一个运算对象从s1串中读出并写入到s2串中后,再另其出栈并写入s2串中; 若遇到的运算符的优先级小于等于栈顶运算符的优先级,这表明栈顶运算符的两个运算对象已经被保存到s2串中,应将栈顶运算符退栈并写入到s2串中,对于新的栈顶运算符仍继续进行比较和处理,直到被处理的运算符的优先级大于栈顶运算符的优先级为止,然后另该运算符进栈即可。 按照以上过程扫描到中缀表达式结束符’@’时,把栈中剩余的运算符依次退栈并写入到后缀表达式中,再向s2写入表达式结束符’@’和字符串结束符’{ post.content} ’,整个转换过程就处理完毕,在s2中就得到了转换成的后缀表达式。
强大的计算器 基本操作:输入表达式,按ENTER或单击C按钮。 按ESC清除输入文本。 按UP / DOWN选择历史输入。 单击结果编号以将其输入文本。 数字:默认为十进制。 二进制的前缀0b。 十六进制的前缀0x。 下划线_可以是数字(exp。10_000)。 字符串:单引号/双引号,如'abc'“ str”使用“ \”转义特殊字符,如\'单引号\“双引号\\反向固相线\ /固相线\ n换行符\ t水平制表符\ u? ??? 4个十六进制数字表示一个Unicode字符\ b *退格\ f * formfeed \ r *回车*这些字符未显示在屏幕中注意:实际上,它使用JSON的字符串格式以及其他“ \'”。必须遵循其语法或发生错误。有关更多信息,请访问http://json.org/当前支持的运算符基本:+:加号(+)-:减号(−)*:时间(×)/:除法( ÷)%:扩展的模块:**:电源//:整数除法* /:N-Power的根:a * / b == a **(1 / b)按位(仅整数):〜:按位NOT&:按位与| |:按位OR ^:按位XOR逻辑(真= 1,假= 0):!:逻辑非&&:逻辑与|||:逻辑或关系(真= 1,假= 0):==:等于! =:不等于>:大于<:小于> =:大于或等于<=:小于o r等于任务(懒惰版本):条件? 真值:exp的假值。 1> = 2吗? 10:20 => 20 1吗? 2? 3:4:5? 6:7 = 1? (2?3:4):(5?6:7)操作员订单使用(和)促销订单。 1 ** * / 2 * /%// 3 +-4〜&| ^ 5! && || 6 ==!=> <> = <= 7吗? :量,常量和函数分配量:= a = ... a = b = 3 => a =(b = 3)a = 1 +(b = 2)=> a = 3,b = 2 [*]可以将量分配给功能。 常数:E:2.7182818 ... PI:3.1415926 ...功能:绝对值:绝对值ln:基于E的日志lg lg10 log10:基于10 lg2的日志log2:基于2的日志log:log(number,base)sin ,cos,tan / tg,ctan / ctg:三角函数ord / chr:在char和代码之间转换。 有符号/无符号:将整数转换为有符号/无符号。 中缀/后缀表示法中缀(快捷键Ctrl + I):#{IN:1 + 2}#{IN:9 * 8-7 / 6}后缀(快捷键Ctrl + R):#{RPN:1 2 +}#{ RPN:9 8 * 7 6 /-}混合:#{RPN:1#{IN:2 + 3} +}#{IN:2 +#{RPN:9 8 * 7 6 /-}}后缀表示法语法运算符:一元:〜#{RPN:1〜}! #{RPN:0!}由于冲突因不受支持:+-(应使用0和#{RPN:0 1-}之类的二进制运算符)Binary:全部受支持。 例如#{IN:6 * 7 + 8 /(9-5)}等于#{RPN:6 7 * 8 9 5-/ +}三进制:#{IN:a? b:c}等于#{RPN:abc?}。 无需冒号(:)空格和逗号在没有冲突的情况下,不需要空格。 对于ins。,#{RPN:6 7 * 8 9 5-/ +}可能是#{RPN:6 7 * 8 9 5-/ +}在RPN模式下忽略逗号(,)。 因此,您可以使用它们来代替空格。 例如,#{RPN:6 7 * 8 9 5-/ +}可以是#{RPN:6,7 *,8,9 5,-,/ ,, +}函数调用:fn(args ... )等于(args ... fn),但没有逗号加入到参数中。 例如,#{IN:log(n,b)}等于#{RPN:(nb log)}#{IN:ord(c)}等于#{RPN:(c ord)}#{IN:log(8 ** 4,6-2)}等于#{RPN:(8 4 **,6 2-,log)} 支持语言:English (United States)

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧