C语言数据结构之中缀树转后缀树的实例

对于一个中缀表达式 a+b*c*(d-e/f) 转换成后缀是这样的形式 abc*def/-+

后缀表达式是相当有用处的,转换成后缀表达式后求值会简单很多.那么该如何转换呢?

网上关于这方面的资料一搜一大把,每本数据结构的书中都会提及这个算法,在这个算法中,用到 栈 这个数据结构.

1,关键是比较运算符的优先级,谁的优先级高,谁就出现在前面上面的表达式中,有括号的时候括号优先级最高,*/次之,+-最后. 在上面的表达式中+的优先级不如*的高,因此,在后缀表达式中*出现在+前面,

2,遇到操作数的时候总是直接输出,不做任何比较

3,遇到左括号总是直接入栈,遇到右括号的时候总是弹栈,一直弹到遇到一个左括号

4,遇到操作符的时候就先将这个操作符和它前面的操作符比较优先级,假如高于前面的优先级,先将它压栈,假如低于或等于前面的操作符的优先级,就把前面的优先级比它高的或相等的顺序弹出来, 一直弹到遇到优先级比它还低的或者到了栈顶 ,然后该操作符再压入栈。

知道以上四个规则就可以设计代码实现了,

代码如下:

#include

#include

#include

#include

using namespace std;

void InerStringDevide(string InerStr,string DeviStr[],int &num)

{

int count,i;

int numbe=InerStr.size();

for(i=0;i

DeviStr[i][0]='\0';

count=0;

for(i=0;i

{

if(InerStr[i]=='+'||InerStr[i]=='-'||InerStr[i]=='*'||

InerStr[i]=='/'||InerStr[i]=='%'||InerStr[i]=='^'

||InerStr[i]=='('||InerStr[i]==')')

{

DeviStr[count].push_back(InerStr[i]);

count++;

i++;

}

else

{

while(InerStr[i]!='+'&&InerStr[i]!='-'&&InerStr[i]!='*'&&

InerStr[i]!='/'&&InerStr[i]!='%'&&InerStr[i]!='^'

&&InerStr[i]!='('&&InerStr[i]!=')')

{

DeviStr[count].push_back(InerStr[i]);

i++;

if(i>=numbe)

break;

}

count++;

}

}

num=count;

}

void InerTreeToPostTree(string InerStr,string &PostStr)

{

PostStr[0]='\0';

mapOpC;

typedef map::value_type ValType;

OpC.insert(ValType('+',1));

OpC.insert(ValType('-',1));

OpC.insert(ValType('*',2));

OpC.insert(ValType('/',2));

OpC.insert(ValType('%',2));

OpC.insert(ValType('^',3));

OpC.insert(ValType('(',-1));

OpC.insert(ValType(')',0));

int num,i,j,StrNum;

num=InerStr.size();

string *DevedeStr=new string[num];

InerStringDevide(InerStr,DevedeStr,StrNum);

stack ChStack;

int count=0;

for(int i=0;i

{

//如果输入的字符串是操作符

if(DevedeStr[i][0]=='+'||DevedeStr[i][0]=='-'||DevedeStr[i][0]=='*'||

DevedeStr[i][0]=='/'||DevedeStr[i][0]=='%'||DevedeStr[i][0]=='^'

||DevedeStr[i][0]=='('||DevedeStr[i][0]==')')

{

//如果操作符栈中为空可以直接将操作符入栈

if(ChStack.empty())

{

ChStack.push(DevedeStr[i][0]);

}

//如果非空要根据操作符的优先级及其类别进行判断并分类入栈

else

{

char TopCh=ChStack.top();

//如果是(则直接入栈

if(OpC[DevedeStr[i][0]]==-1)

{

ChStack.push(DevedeStr[i][0]);

}

//如果操作符优先级大于栈中当前操作符直接入栈

else if(OpC[TopCh]

{

ChStack.push(DevedeStr[i][0]);

}

//否则按操作符的类别有区别的处理

else

{

//如果遇到)则操作符出栈并入字符串

if(OpC[DevedeStr[i][0]]==0)

{

TopCh=ChStack.top();

while(OpC[TopCh]!=-1)

{

if(!PostStr.empty())

{

PostStr.push_back(' ');

}

PostStr.push_back(TopCh);

ChStack.pop();

TopCh=ChStack.top();

}

ChStack.pop();

TopCh=ChStack.top();

}

else

{

while(OpC[TopCh]>=OpC[DevedeStr[i][0]]&&OpC[TopCh]!=-1)

{

if(!PostStr.empty())

{

PostStr.push_back(' ');

}

PostStr.push_back(TopCh);

ChStack.pop();

if(!ChStack.empty())

TopCh=ChStack.top();

else

break;

}

ChStack.push(DevedeStr[i][0]);

}

}

}

}

//如果输入的字符串是数字

else

{

int DevideSize=DevedeStr[i].size();

if(!PostStr.empty())

{

PostStr.push_back(' ');

}

for(int j=0;j

{

PostStr.push_back(DevedeStr[i][j]);

}

}

}

while(!ChStack.empty())

{

if(!PostStr.empty())

{

PostStr.push_back(' ');

}

PostStr.push_back(ChStack.top());

ChStack.pop();

}

}

以上为头文件InerTreeToPostTree.h。该文件的 作用是输入中缀字符串,输出后缀字符串,其中中缀字符串不带空格,而后缀字符串带空格。头文件中的另一个函数是将字符串分为字符串数组,该数组中存储数字和运算符。

#include

#include

#include

using namespace std;

void StringDevide(string str,int &num,string st1[])

{

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

st1[i][0]='\0';

int n=str.size();

int j=0,count=0;

for(int i=0;i

{

if(str[i]!=' ')

{

st1[count].push_back(str[i]);

}

else

{

count++;

}

}

num=count+1;

}

void StringToNum(string str,int &num)

{

num=0;

int n=str.size();

for(int i=0;i

{

num=num*10;

num+=str[i]-'0';

}

}

class InterTreeComputer

{

private:

//要计算的表达式

string m_expresion;

//将数字存储到栈中

stack m_num;

public:

InterTreeComputer(string expression):m_expresion(expression)

{}

//判定某一操作符是否是运算符

bool IsOperator(char ch)const;

//获取要计算的两个运算数

void GetOperands(int &left,int &right);

//对获取的两个数按照符号ch进行计算

int computer(int left,int right,char ch)const;

//获取表达式

string GetPostoperation()const;

void SetPostoperator();

//计算表达式并返回结果

int Evaluate();

};

bool InterTreeComputer::IsOperator(char ch)const

{

switch(ch)

{

case '+':

case '-':

case '*':

case '/':

case '%':

case '^':

return 1;

default:

return 0;

}

}

void InterTreeComputer::GetOperands(int &left,int &right)

{

if(m_num.empty())

{

cout<

return ;

}

right=m_num.top();

m_num.pop();

if(m_num.empty())

{

cout<

return ;

}

left=m_num.top();

m_num.pop();

}

int InterTreeComputer::computer(int left,int right,char ch)const

{

switch(ch)

{

case '+':

return left+right;

break;

case '-':

return left-right;

break;

case '*':

return left*right;

break;

case '/':

if(right==0)

{

cout<

return -1;

}

return left/right;

break;

case '%':

return left%right;

break;

case '^':

if(left==0&&right==0)

{

cout<

return -1;

}

int value=1;

while(right>0)

{

value*=left;

right--;

}

return value;

break;

}

}

string InterTreeComputer::GetPostoperation()const

{

return m_expresion;

}

void InterTreeComputer::SetPostoperator()

{}

int InterTreeComputer::Evaluate()

{

string *str=new string[100];

int num;

StringDevide(m_expresion,num,str);

for(int i=0;i

{

if(str[i][0]=='+'||str[i][0]=='-'||str[i][0]=='*'||str[i][0]=='/'

||str[i][0]=='%'||str[i][0]=='^')

{

char ch=str[i][0];

int left,right;

GetOperands(left,right);

int number=computer(left,right,ch);

m_num.push(number);

}

else

{

int numb=0;

StringToNum(str[i],numb);

m_num.push(numb);

}

}

return m_num.top();

}

以上代码为InerTreeComputer.h头文件,该头文件的作用是输入后缀表达式并计算该表达式的值。

#include

using namespace std;

#include

#include

#include"InterTreeComputer.h"

#include"InerTreeToPostTree.h"

int main()

{

string str="3*(4-2^5)+6";

string st1="2 3 ^ 1 +";

string st2="2 2 3 ^ ^ 4 /";

string StrRe;

InerTreeToPostTree(str,StrRe);

InterTreeComputer Comp(StrRe);

cout<

cout<

return 0;

}

测试文件对以上两个头文件进行了测试。

以上就是数据结构C语言数据结构之中缀树转后缀树的实例,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持,大家共同进步!

后缀树c语言算法,C语言数据结构之中缀树转后缀树的实例相关推荐

  1. 数据结构实验——中缀表达式转为后缀表达式

    一.实验内容: 编写程序,实现中缀表达式化为后缀式输出. 已知中缀表达式中操作数全部用小写英文字母表示,运算符只含有+, -, *, /四种,定界符只有( )以及结束符#. 二.程序源代码: 运行示例 ...

  2. 数据结构——栈——中缀表达式和后缀表达式

    什么是中缀表达式,什么是后缀表达式 我们一般看见的多项式计算都是中缀表达式构成的:1+2*3+4/3 类似这种,为什么说是中缀呢?因为它的计算符号都是在两个数中间的. 那么自然而然的明白了后缀表达式是 ...

  3. Java数据结构之中缀表达式转后缀表达式

    简介 通过数组模拟栈进行中缀表达式转后缀表达式,再进行计算 不说废话,请看代码. package com.atguigu.Stack;import java.util.ArrayList; impor ...

  4. 学校门口的树C语言算法,C语言校园导游程序设计汇报.doc

    C语言校园导游程序设计汇报 <应用程序设计 课程设计>报告 班级: 学号: 姓名: 指导教师: 成绩评定: 目录 题目: 设计一个校园导游程序,为来访的客人提供各种信息查询服务 一.需求分 ...

  5. 冒泡法排序c语言算法步骤,冒泡排序 - 数据结构与算法教程 - C语言网

    1.复杂度与稳定性 算法时间复杂度 最坏情况:O(n^2) 最好情况:O(n) 平均情况:O(n^2) 空间复杂度:S(n)=O(1) 稳定性:稳定排序 2.过程介绍(以顺序为例) 1.从第一个元素开 ...

  6. 必背C语言算法 C语言小写转大写

    算法思想 在计算机中,大小写字母的ASCII值差32,字符a的ASCII值为97,字符A的ASCII值为65. 程序代码 #include <stdio.h> int main() {ch ...

  7. 加法接力赛C语言算法,C语言循环结构

    <C语言循环结构>由会员分享,可在线阅读,更多相关<C语言循环结构(47页珍藏版)>请在人人文库网上搜索. 1.UML和需求建模,第六章,循环控制,UML和需求建模,主要内容, ...

  8. 输出每行坐标的的c语言算法,C语言输出空心菱形的实现

    http://www.cnblogs.com/liutogo/archive/2013/05/31/3110394.html 输出空心菱形是c语言初学者经常遇到的问题,由于涉及c语言的基础知识较多,也 ...

  9. mm1模型的c语言算法,C语言动画程序源码(1).pdf

    C 语言动画程序 #include #include #include #include #define pi 3.1415926535 double ca3mm1(double m1,double ...

  10. 田忌赛马c语言算法,C语言里关于田忌赛马的问题

    C语言里关于田忌赛马的问题0 limmettle2014.10.24浏览83次分享举报 这是题目 题目描述 赛马是一古老的游戏,早在公元前四世纪的中国,处在诸侯割据的状态,历史上称为"战国时 ...

最新文章

  1. linux小脚本批量添加/删除用户
  2. 【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal
  3. dbms_metadata遇到ORA-31603的解决方案
  4. 日志打印的8种级别(很详细)
  5. 不能比较或排序text、ntext和image数据类型,除非使用IS NULL 或 LIKE 运算符。
  6. leetcode mysql 排名_GitHub - nimphy/leetcode-Mysql
  7. android教程1009无标题,Android ActionBarActivity设置全屏无标题实现方法总结_Android_脚本之家...
  8. consule服务注册和发现 安装 部署
  9. vegan稀释曲线 基因丰度_R语言 vegan包计算物种累计曲线
  10. oracle:触发器,自治事务,instead of trigger,trigger
  11. 教你如何构建异步服务器和客户端的 Kotlin 框架 Ktor
  12. k-d Tree及其Java实现
  13. Alex 的 Hadoop 菜鸟教程: 第20课 工作流引擎 Oozie
  14. uchar t 单片机C语言的注释是什么,uchar(单片机中uchar是什么意思)
  15. UI设计初学者应该如何入门?
  16. oracle用升序索引去降序查询,Oracle工作札记
  17. 出租车不需要司机了?带你体验无人驾驶出租车!|『智能产品家』第三期
  18. 解决禅道(ZenTao)Mysql启动不了的问题
  19. 2019届互联网校招高薪清单
  20. 315维权大数据报告:手机爆炸事件仍在发生,国民安全受到严重威胁!

热门文章

  1. Android真机调试时LogCat不显示日志信息
  2. 内蒙古工业大学计算机好调剂吗,内蒙古工业大学信息工程学院2017硕士研究生第三次调剂公告...
  3. redis命令行技术文档。命令教程
  4. CSRF与XSS攻击的原理与防范
  5. Wyn Enterprise 核心功能:易用至极的自助式BI和数据分析工具
  6. logrotate日志转储
  7. webpack 生产环境下插件用途
  8. 《软件定义网络:基于OpenFlow的SDN》一一3.4 本章总结
  9. 侧滑面板(对viewGroup的自定义)
  10. [译]C#控制管理VisualSVN Server