课程设计 动态表达式求值

题目:

动态表达式求值 功能:

(1) 输入并保存公式到文件。(公式中的操作数用字母代替,计算时给出具体值)

(2) 将公式载入到表达式二叉树

(3) 输入操作数的具体值,计算结果

 

需求分析:

  1. 本演示程序中,表达式变量限制为26个英文字母,大小写均可。运算符支持“+,-,*,/,^”,允许括号。
  2. 演示程序以用户和计算机对话方式执行,即在计算机终端上显示提示信息之后,用户按格式输入数据,计算结果显示在其后,公式部分会保存在与程序同目录的文件“data.txt”中。

使用说明:

  1. 执行过程:输入一行公式,创建二叉树,输入'数据组数n'和每组数据'变量个数m',之后每组数据输入m行,每行为变量名,空格,变量值的形式。计算并输出结果。
  2. 测试数据:
  1.  

a^b+c/(d-e)

3 5

a 2

b 3

c 43

d 5

e -3

a 1.1

b 2

c 1

d 143

e 334

a 3.4

b 2

c 10

d 5

e 0.1

n

结果:

13.375

1.20475

13.6008

概要设计:

 

顺序栈存储结构

Struct {

  Type_a  sta[MAXX];

  Int top_a;//记录栈顶

}

 

二叉树存储结构:

struct Data {

char val;

struct Data *lch,*rch;

}

 

TNode new_Node(char val)

    操作结果:创建并返回值为val的数树节点

void build(*s,len)

操作结果:根据公式s,创建表达式二叉树

double Tra(t)

    操作结果:根据带入数据计算表达式树的值 

 

详细设计

 

Part1 建树

参照通过栈求表达式值的算法。

之前数字栈的操作与二叉树操作一一对应。

比如取出数字栈顶两个数3,5,求3+5 = 8放进数字栈

这次栈中存二叉树节点

对应取出栈顶两个值为3,5的子树的根a,b,新建节点值为‘+’左儿子a,右儿子b.放回栈中

 

例子

3*(4-1)

 

 

数字3 4 1

符号 *(-

 

 

数字3 3

符号*

课程设计 动态表达式求值_第1张图片

 

数字9

符号

课程设计 动态表达式求值_第2张图片

 

 

 

 

 

Part2 计算

 

double char_to_val[257];

char_to_val[‘a’]代表变量a的值

 

通过递归求解

如果某个节点是变量x,返回char_to_val[x];

否则该点的值是操作R(+-*/^)是 左子树的值R右子树的值。

 

 

程序:

#include 

#include 

#include 

#include 

#include 



#define MAXX 10000



char sta[MAXX];int top_a;

double char_to_val[257];



typedef struct Data {

char val;

struct Data *lch,*rch;

}Node,*TNode;



TNode new_Node(char val) {

    TNode tp = (TNode)malloc(sizeof(Node));

    tp->lch = tp->rch = NULL;

    tp->val = val;

    return tp;

}



TNode stt[MAXX];

int top_t;



int Level(char c) {

return  (c=='^')*2 + (c=='*'||c=='/')*1 + (c=='+'||c=='-')*0;

}



void Out() {

char c = sta[top_a--];

TNode tmp = new_Node(c);

tmp->lch = stt[top_t-1];

tmp->rch = stt[top_t];

stt[--top_t] = tmp;

}



void build(char *s,int len) {

int i;

for (i = 0; i < len; i++) {

char c = s[i];

if (isalpha(c)) {

stt[++top_t] = new_Node(c);

} else if (c == ')') {

while(sta[top_a] != '(') Out();

top_a--;

} else if (c == '(') {

sta[++top_a] = c;

} else {

while(top_a && sta[top_a]!='(' && Level(sta[top_a])>=Level(c)) Out();

sta[++top_a] = c;

}

}

while(top_a) Out();

}





double calc(double a,char opt,double b) {

if (opt == '^') return pow(a,b);

if (opt == '+') return a+b;

if (opt == '-') return a-b;

if (opt == '*') return a*b;

if (opt == '/') return a/b;

return 0;

}



double Tra(TNode t) {

if (isalpha(t->val)) return char_to_val[(int)t->val];

return calc(Tra(t->lch),t->val,Tra(t->rch));

}



int main() {

FILE *fp = fopen("data.txt","w");

char s[MAXX];    

char tmp;

    int t,i;

while(1) {

   printf("请输入表达式:\n");

   scanf("%s",s);

   fprintf(fp,"%s\n",s);//保存公式到文件

   top_a = top_t = 0;

   build(s,strlen(s));//将公式载入到表达式二叉树

       char val_x; double val_n;

   int cas,tot;

   printf("请输入'数据组数'和每组数据'变量个数':\n");

   scanf("%d%d",&cas,&tot);//输入操作数的具体值,计算结果

   for (t = 1; t <= cas; t++) {

  for (i = 1; i <= tot; i++) {

    scanf("%*c%c%lf",&val_x,&val_n);

  char_to_val[(int)val_x] = val_n;

  }

      printf("%g\n",Tra(stt[top_t]));

   }

   printf("继续?y/n\n");

   scanf("%*c%c",&tmp);

   if (tmp == 'n') break;

}

fclose(fp);

return 0;

}

调试分析:

 

课程设计 动态表达式求值_第3张图片

 

 

你可能感兴趣的:(杂类文章,算法/数据结构)