表达式建树

简介:

//用数组实现树
#include<iostream> 
#include<ctype.h>
#include<cstring>
#define N 10000
#define optd 1
#define optr 2
using namespace std;
int treeL[N], treeR[N];
class node
{
public:
   int flag;//区分当前节点是操作符还是操作数 
   double k;
   char ch;
};

node opt[N];
int nodeN; 
char formula[1000];

int buildTree(int ld, int rd)
{
   int i;
   for(i=ld; i<rd; ++i)
     if(!isdigit(formula[i])) 
       break;
   if(i>=rd)//最后全部为数字的时候 
   {
       ++nodeN;
       opt[nodeN].flag=optd;
       sscanf(formula+ld, "%lf", &opt[nodeN].k);
       treeL[nodeN]=treeR[nodeN]=0;//末端节点没有左右孩子 
       return nodeN;//返回当前所建节点编号 
   }
   int pAS=-1, pMD=-1;//分别表示加减号, 乘除号所在的位置 
   int paren=0;//记录左括弧相对于右括弧出现的数目 
   for(i=ld; i<rd; ++i)
   {
      switch(formula[i])
      {
         case '(': ++paren;  break;
         case ')': --paren;  break;

         //最后计算的运算符一定是在括弧的外边,不会包含在括弧里边 
         case '+':
         case '-': 
                   if(paren==0)   pAS=i;
                   break;
         case '*':
         case '/': 
               if(paren==0) pMD=i;
                   break;
      }
   }
   if(pAS<0)  pAS=pMD;
   if(pAS<0) //说明没有找到括弧外边的运算符,则脱掉一对括弧重新寻找 
     return buildTree(ld+1, rd-1);
   int u=++nodeN;
   opt[u].flag=optr;//表示存储操作符
   opt[u].ch=formula[pAS];
   treeL[u]=buildTree(ld, pAS);
   treeR[u]=buildTree(pAS+1, rd);
   return u;
}

void printTree(int cur)//中序输出表达式树 
{
   if(cur)//非末端节点 
   {
      printTree(treeL[cur]);
      if(opt[cur].flag==optd)
        cout<<opt[cur].k<<" ";
      else 
        cout<<opt[cur].ch<<" ";
      printTree(treeR[cur]);
   }
} 

int main()
{
   while(cin>>formula)
   {
      buildTree(0, strlen(formula));
      printTree(1);
   }
   return 0;
} 

 //用链表实现树
#include<iostream> 
#include<ctype.h>
#include<cstring>
#define N 10000
#define optd 1
#define optr 2
using namespace std;

class node
{
public:
   node *lchild, *rchild;
   int flag;//区分当前节点是操作符还是操作数 
   double k;
   char ch;
};

char formula[1000];

void buildTree(node* &T, int ld, int rd)
{
   int i;
   for(i=ld; i<rd; ++i)
     if(!isdigit(formula[i])) 
       break;
   if(i>=rd)//最后全部为数字的时候 
   {
       T=new node();
       T->flag=optd;
       sscanf(formula+ld, "%lf", &T->k);
       return ; 
   }
   int pAS=-1, pMD=-1;//分别表示加减号, 乘除号所在的位置 
   int paren=0;//记录左括弧相对于右括弧出现的数目 
   for(i=ld; i<rd; ++i)
   {
      switch(formula[i])
      {
         case '(': ++paren;  break;
         case ')': --paren;  break;

         //最后计算的运算符一定是在括弧的外边,不会包含在括弧里边 
         case '+':
         case '-': 
                   if(paren==0)   pAS=i;
                   break;
         case '*':
         case '/': 
               if(paren==0) pMD=i;
                   break;
      }
   }
   if(pAS<0)  pAS=pMD;
   if(pAS<0) //说明没有找到括弧外边的运算符,则脱掉一对括弧重新寻找 
     return buildTree(T, ld+1, rd-1);
   T=new node();
   T->flag=optr;//表示存储操作符
   T->ch=formula[pAS];
   buildTree(T->lchild, ld, pAS);
   buildTree(T->rchild, pAS+1, rd);
}

void printTree(node *T)//中序输出表达式树 
{
   if(T)//非末端节点 
   {
      printTree(T->lchild);
      if(T->flag==optd)
        cout<<T->k<<" ";
      else 
        cout<<T->ch<<" ";
      printTree(T->rchild);
   }
} 

int main()
{
   while(cin>>formula)
   {
      node *T=NULL; 
      buildTree(T, 0, strlen(formula));
      printTree(T);
   }
   return 0;
}

目录
相关文章
|
6月前
|
测试技术
【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数
【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数
【编译原理】语法分析:从顶向下、最左推导
【编译原理】语法分析:从顶向下、最左推导
|
26天前
|
存储 算法 Java
数据结构与算法学习八:前缀(波兰)表达式、中缀表达式、后缀(逆波兰)表达式的学习,中缀转后缀的两个方法,逆波兰计算器的实现
前缀(波兰)表达式、中缀表达式和后缀(逆波兰)表达式的基本概念、计算机求值方法,以及如何将中缀表达式转换为后缀表达式,并提供了相应的Java代码实现和测试结果。
28 0
数据结构与算法学习八:前缀(波兰)表达式、中缀表达式、后缀(逆波兰)表达式的学习,中缀转后缀的两个方法,逆波兰计算器的实现
|
3月前
|
算法
【算法】栈算法——逆波兰表达式求值
【算法】栈算法——逆波兰表达式求值
|
6月前
|
C# 数据库
关系代数表达式练习(针对难题)
关系代数表达式练习(针对难题)
52 0
Leecode 1111. 有效括号的嵌套深度
Leecode 1111. 有效括号的嵌套深度
47 0
|
存储 算法
头歌打印二叉树(递归里自增自减陷阱)
头歌打印二叉树(递归里自增自减陷阱)
中缀表达转后缀表达式小技巧+通过后缀表达式求值
在考研中,经常会考中缀表达转后缀表达式,那什么是中缀表达?什么是后缀表达式?我举两个例子大家一个就清楚了
中缀表达转后缀表达式小技巧+通过后缀表达式求值
|
算法
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
128 0
基础算法练习200题08、百鸡问题(循环+逻辑判断+穷举)
|
自然语言处理 索引
一种快速的复杂逻辑表达式求取方法
背景最简单的逻辑表达式求取方法是求取所有每个子表达式的值,然后再带入复杂逻辑表达式依次计算得到最终结果,时间复杂度较高。简单的“或运算”和“与运算”,以短路方式实现,不需要计算所有的子表达式的值,计算效率较高。但是,以“或运算”、“与运算”、“否运算”和“嵌套运算”等子表达式组成的复杂逻辑表达式,不能简单的套用短路运算。本专利,通过“构建逻辑表达式树”及“逐级向上触发树节点”的方式,实现了一种快速
一种快速的复杂逻辑表达式求取方法