表达式建树

//用数组实现树
#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;
}
时间: 2024-12-21 18:03:24

表达式建树的相关文章

Java EL系列-3.1.JUEL表达式工厂

inkfish翻译,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).本文是我学习JUEL同时,对原网站进行的简单的翻译,原网站地址:http://juel.sourceforge.net/guide/basic/factory.html .说实话,这篇翻译的的确不怎样. 表达式工厂(Expression Factory) 如果要使用EL ,就必须要有一个javax.el.ExpressionFactory 的实例.表达式工厂用于创建多种类型的表达式

PostgreSQL 索引虚拟列 - 表达式索引 - JOIN提速

标签 PostgreSQL , join , 表达式索引 , 虚拟列索引 , 静态数据 , immutable函数 背景 CASE: 使用虚拟索引,响应时间从2.3秒下降到0.3毫秒 业务系统在设计时,为了减少数据冗余,提升可读性,通常需要将不同的数据放到不同的表. 在查询时,通过多表JOIN来补齐需要查询或在过滤的内容. 比如这样的例子: 有两张表,分别有1千万和100万数据,当用户查询时,需要补齐那100万表中的某个字段进行过滤. create table a (id int, bid in

jsp-JSP中编写JS代码过程中,调用了一个JSP表达式,发现一个问题,麻烦各位大神解答

问题描述 JSP中编写JS代码过程中,调用了一个JSP表达式,发现一个问题,麻烦各位大神解答 背景: 楼主使用Myelipse新建了一个Web项目,在编写一个JSP文件的时候遇到一个问题,首先是使用了img,并且写了一个事件,代码如下: <imgclass="poke" src="poke/back.jpg" title="hit" id="play_id_3" onClick="change_pic()&qu

表达式-/ 100 + 3 * - 2 4 / 20 10

问题描述 / 100 + 3 * - 2 4 / 20 10 已知一个表达式的后缀形式是/ 100 + 3 * - 2 4 / 20 10求它的前缀形式? 解决方案 这就是前缀吧中缀是 100/(3+((2-4)*20/10))后缀 100 3 2 4 - 20 * 10 / + /

select-link能不能直接调用方法?还是只能写表达式?

问题描述 link能不能直接调用方法?还是只能写表达式? link能不能直接调用方法?还是只能写表达式? int[] array = { 1, 2, 3, 4, 5, 6, 7, 8 }; var query = from x in array where Predicate select x; foreach (int item in query) Console.WriteLine(item); bool Predicate(int n) { if (n % 2 == 0) return t

表达式计算器

1+2/3*(4-6)*6/8+9*2 = ? #include <stdio.h> #include <stdlib.h> #define MAXSIZE 32 typedef struct{ int data[MAXSIZE];//数据段 int top;//栈指针 }sqstack; sqstack *sqstack_create() { sqstack *sq; sq = malloc(sizeof(*sq)); if(sq == NULL ) { return NULL;

vc++2010创建项目失败,无法计算xxx处的属性表达式的值

问题描述 vc++2010创建项目失败,无法计算xxx处的属性表达式的值 vc++2010创建项目失败,报错如下图,求教高手提点. 解决方案 是新建的项目的话,建议重装下vs,再不行重装下系统.

话说模式匹配(5) for表达式中的模式匹配

在for表达式中 for(x <- collection) { balabala } 直觉上以为 x 就是个用于迭代每一个元素的局部变量. 我们看一些例子: scala> for(i <- List(1,2,3) ) {println(i)} // 看看语法树 scala> tb.parse("for(i <- List(1,2,3) ) {println(i)}") res2: tb.u.Tree = List(1, 2, 3).foreach(((i)

Swift使用闭包表达式

Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in    语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是后面有in关键字.Swift提供了多种闭包简化写法,这一节我们将介绍几种不同的形式.1.类型推断简化类型推断是Swift的强项,Swift可以根据上下文环境推断出参数类型和返回值类型.以下代码是标准形式的闭包:{(a:Int, b:Int) -> Int in    return a + b}Swift