[Java] C++实现简单的表达式类型 →→→→→进入此内容的聊天室

来自 , 2021-01-09, 写在 Java, 查看 123 次.
URL http://www.code666.cn/view/4e477793
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<malloc.h>
  4. #include<string.h>
  5.  
  6. typedef enum
  7. {
  8.         INT, CHAR
  9. } DataType;//CHAR=1表示存贮字符,INT=0表示存储运算数据
  10.  
  11. typedef union
  12. {
  13.          char vchar;
  14.      int num;
  15. } ElemType;
  16.  
  17. //二叉树节点结构体
  18. typedef struct BiTNode
  19. {
  20.         DataType type;//data中存储的数据的类型
  21.         ElemType data;//数据域
  22.         struct BiTNode *lchild, *rchild; //左右孩子指针域
  23. } BiTNode, *BiTree;
  24.  
  25. //全局变量
  26. char preExpr[100];//表达式
  27. int isExist = 0;//表达式是否已经构造
  28. int beCounted = 0;//表达式中的常数运算行为是否发生
  29.  
  30. //顺序栈功能的实现
  31. #define STACK_INIT_SIZE 100 //存储空间初始分配量
  32. #define STACK_INCREMENT 10 //存储空间分配增量
  33. #define SElemType BiTree//元素类型
  34.  
  35. typedef struct
  36. {
  37.         SElemType *base;//栈底指针
  38.         SElemType *top;//栈顶指针
  39.         int stackSize;//当前已分配的存储空间 以元素为单位
  40. } SqStack;
  41.  
  42. //构造一个空栈S
  43. int InitStack(SqStack *S)
  44. {
  45.         (*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
  46.         if(!(*S).base) exit(1);
  47.         (*S).top = (*S).base;
  48.         (*S).stackSize = STACK_INIT_SIZE;
  49.         return 0;
  50. }
  51.  
  52. //若栈不空 则用e返回S的栈顶元素 并返回1 否则返回0
  53. int GetTop(SqStack S,SElemType *e)
  54. {
  55.         if(S.top == S.base) return 0;
  56.         *e = *(S.top - 1);
  57.         return 1;
  58. }
  59.  
  60. //插入元素e为新的栈顶元素
  61. int Push (SqStack *S,SElemType e)
  62. {
  63.         if((*S).top - (*S).base >= (*S).stackSize) {//栈满 追加存储空间
  64.                 (*S).base = (SElemType *)realloc((*S).base,((*S).stackSize + STACK_INCREMENT)*sizeof(SElemType));
  65.                 if(!(*S).base) exit(1);//存储分配失败
  66.                 (*S).top = (*S).base + (*S).stackSize;
  67.                 (*S).stackSize += STACK_INCREMENT;
  68.         }
  69.         *(*S).top++ = e;
  70.         return 1;
  71. }
  72.  
  73. //若栈不空 则删除S的栈顶元素 用e返回其值 并返回1 否则返回0
  74. int Pop(SqStack *S, SElemType *e)
  75. {
  76.         if((*S).top == (*S).base) return 0;
  77.         *e = * --(*S).top;
  78.         return 1;
  79. }
  80.  
  81. //若栈S为空栈,则返回1,否则返回0
  82. int StackEmpty(SqStack S)
  83. {
  84.         if(S.top==S.base)
  85.                 return 1;
  86.         else
  87.                 return 0;
  88. }
  89.  
  90. //函数声明
  91. void list();
  92. int getPreExpr();
  93. void AsNode(BiTree *E,int i);
  94. int ReadExpr(BiTree *E);
  95. int Primary(char a,char b);
  96. void WriteExpr(BiTree E);
  97. void Assign(BiTree *E,char V,int c,int *flag);
  98. int Check_Variable(BiTree E);
  99. float Operate(int a, char ope, int b);
  100. float Value(BiTree E);
  101.  
  102. //主函数
  103. int main()
  104. {
  105.         char choice;
  106.         BiTree E,E2;//二叉树
  107.         float value_result;
  108.         while(1)
  109.         {
  110.                 list();//输出功能列表
  111.                 printf("请输入你的选择:");
  112.                 choice = getch();
  113.                 switch(choice)
  114.                 {
  115.                         case '1':
  116.                                 printf("\n【提示】\n算术表达式内可以含有变量(a~z),常量(0~9)和二元运算符(+, -, *, /)");
  117.                                 fflush(stdin);//清理缓冲区
  118.                                 if(getPreExpr())
  119.                                         if(ReadExpr(&E))
  120.                                         {
  121.                                                 isExist=1;
  122.                                                 printf("表达式构造成功!\n");
  123.                                         }
  124.                                 printf("按任意键返回:");
  125.                                 getch();
  126.                                 break;
  127.  
  128.                         case '2':
  129.                                 if(isExist==1)//检查是否已经构造表达式
  130.                                 {
  131.                                         printf("\n带括弧的中缀表达式为:");
  132.                                         WriteExpr(E);
  133.                                 }
  134.                                 else
  135.                                         printf("\n没有成功构造表达式!");
  136.                                 printf("\n按任意键返回:");
  137.                                 getch();
  138.                                 break;
  139.  
  140.                         case '3':
  141.                                 if(isExist==1)//检查是否已经构造表达式
  142.                                 {
  143.                                         char next;
  144.                                         do
  145.                                         {
  146.                                                 int Assign_flag=0;
  147.                                                 int c;
  148.                                                 char V;
  149.                                                 printf("\n表达式E为:");
  150.                                                 WriteExpr(E);
  151.                                                 fflush(stdin);//清理缓冲区
  152.                                                 //获取输入
  153.                                                 printf("\n请输入需要赋值的变量:");
  154.                                                 V=getchar();
  155.                                                 //判断输入的是不是字符
  156.                                                 if((V>='a' && V<='z') || (V>='A' && V<='Z'))
  157.                                                 {
  158.                                                         printf("");
  159.                                                 }
  160.                                                 else
  161.                                                 {
  162.                                                         printf("请输入字母!");
  163.                                                         next = 'y';
  164.                                                         continue;//从头重新输入
  165.                                                 }
  166.  
  167.                                                 printf("请输入需要赋给该变量的值:",V);
  168.                                                 scanf("%d",&c);
  169.  
  170.                                                 Assign(&E,V,c,&Assign_flag);
  171.                                                 //判断是否赋值成功
  172.                                                 if(Assign_flag)
  173.                                                 {
  174.                                                         printf("赋值成功!\n赋值后的表达式为:");
  175.                                                         WriteExpr(E);
  176.                                                 }
  177.                                                 else
  178.                                                         printf("赋值失败!可能表达式中没有此变量!");
  179.                                                 printf("\n是否继续赋值?<y/n>");
  180.                                                 next = getch();
  181.                                         }while(next=='y' || next=='Y');
  182.                                 }
  183.                                 else
  184.                                 {
  185.                                         printf("\n没有成功构造表达式!");
  186.                                         printf("\n按任意键返回:");
  187.                                         getch();
  188.                                 }
  189.                                 break;
  190.  
  191.                         case '4':
  192.  
  193.                                 if(isExist==1)//检查是否已经构造表达式
  194.                                 {
  195.                                         printf("\n算术表达式为:");
  196.                                         WriteExpr(E);
  197.                                         if(Check_Variable(E))//确保没有未知量
  198.                                         {
  199.                                                 value_result = Value(E);
  200.                                                 printf("\n其值为:");
  201.                                                 printf("%.2f",value_result);
  202.                                         }
  203.                                         else
  204.                                                 printf("\n表达式中仍存在没有赋值的变量!");
  205.                                 }
  206.                                 else
  207.                                         printf("\n没有成功构造表达式!");
  208.                                 printf("\n按任意键返回:");
  209.                                 getch();
  210.                                 break;
  211.  
  212.                         case '0':
  213.                                 printf("\n感谢使用,再见!\n按任意键退出:");
  214.                                 getch();
  215.                                 exit(0);
  216.                                 break;
  217.                 }
  218.                 system("cls");//清屏
  219.         }
  220.  
  221.         return 0;
  222.  
  223. }
  224.  
  225. //功能列表
  226. void list()
  227. {
  228.         printf("------------------表达式类型的实现-----------------\n");
  229.         printf("           1.输入前缀表示式并构造表达式\n");
  230.         printf("           2.用带括弧的中级表示式输出表达式\n");
  231.         printf("           3.对表达式中的变量赋值\n");
  232.         printf("           4.对算术表达式求值\n");
  233.         printf("----------------------------------------------------\n");
  234. }
  235.  
  236. //获取前缀表达式
  237. int getPreExpr()
  238. {
  239.         printf("\n请输入前缀表示式:");
  240.         gets(preExpr);//从键盘输入一串字符串作为前缀表达式
  241.         if(strlen(preExpr) == 1)//输入的表达式字符串长度为1
  242.                 //输入的表达式只有一个运算符
  243.                 if(preExpr[0] == '+' || preExpr[0] == '-' || preExpr[0] == '*' || preExpr[0] == '/')
  244.                 {
  245.                                 printf("输入错误!表达式只有一个运算符!");
  246.                                 return 0;
  247.                 }
  248.                 //输入的表达式只有一个数字或字符
  249.                 else if((preExpr[0] >= '0' && preExpr[0] <= '9') || (preExpr[0] >= 'a' && preExpr[0] <= 'z') || (preExpr[0] >= 'A' && preExpr[0] <= 'Z'))
  250.                 {
  251.                         printf("输入成功!表达式只有一个字符!");
  252.                         return 1;
  253.                 }
  254.                 else
  255.                 {
  256.                         printf("输入错误!输入无法识别");
  257.                         return 0;
  258.                 }
  259.         else
  260.                 return 1;
  261. }
  262.  
  263. //将字符或数字存为二叉树结点
  264. void AsNode(BiTree *E,int i)
  265. {
  266.         if(preExpr[i]>='0' && preExpr[i]<='9')//为数字
  267.         {
  268.                 //将字符型数字转换成字符串以满足atoi函数的参数要求
  269.                 char value[2];
  270.                 value[0] = preExpr[i];
  271.                 value[1] = '\0';
  272.                 //将字符型数字转换成整形数字
  273.                 (*E)->data.num = atoi(value);
  274.                 (*E)->type = INT;
  275.         }
  276.         else//为字符
  277.         {
  278.                 (*E)->data.vchar = preExpr[i];
  279.                 (*E)->type = CHAR;
  280.         }
  281.  
  282. }
  283.  
  284. //以前缀表示式构造表达式
  285. int ReadExpr(BiTree *E)
  286. {
  287.         SqStack S;
  288.         int i,len;//len为表达式的长度
  289.         BiTree p,q;
  290.  
  291.         (*E) = (BiTree)malloc(sizeof(BiTNode));//申请二叉树的根结点的空间
  292.     (*E)->lchild = NULL;
  293.     (*E)->rchild = NULL;
  294.         len = strlen(preExpr); //len赋值为表达式的长度
  295.  
  296.         if(len == 1)//表达式长度为1时,二叉树只有根结点
  297.         {
  298.                 AsNode(E,0);//将第一个输入字符存入二叉树的结点中
  299.         }
  300.         else
  301.         {
  302.                 AsNode(E,0);//将第一个输入字符存入二叉树的结点中
  303.                 InitStack(&S);//初始化栈
  304.                 q=(*E);
  305.                 Push(&S,q);//入栈
  306.                 Push(&S,q);//入栈,根结点入栈两次是为判断先序输入的表达式是不是正确的表达式
  307.  
  308.                 for(i=1; i<len && !StackEmpty(S); i++)
  309.                 {
  310.                                 p=(BiTree)malloc(sizeof(BiTNode));
  311.                                 AsNode(&p,i);//将exprstring[i]存入二叉树的结点中
  312.                                 p->lchild = NULL;
  313.                                 p->rchild = NULL;
  314.  
  315.                                 //为运算符,运算符入栈,根据是否为空来选择成为左孩子还是右孩子
  316.                                 if(preExpr[i]=='+' || preExpr[i]=='-' || preExpr[i]=='*' || preExpr[i]=='/')
  317.                                 {
  318.                                         if(!q->lchild)//左孩子空 成为左孩子
  319.                                         {
  320.                                                 q->lchild=p;
  321.                                                 Push(&S,p);
  322.                                                 q=p;
  323.                                         }
  324.                                         else//右孩子空 成为右孩子
  325.                                         {
  326.                                                 q->rchild=p;
  327.                                                 Push(&S,p);
  328.                                                 q=p;
  329.                                         }
  330.                                 }
  331.                                 else//不是运算符,运算符出栈
  332.                                 {
  333.                                         if(!q->lchild)
  334.                                         {
  335.                                                 q->lchild=p;
  336.                                                 Pop(&S,&q);
  337.                                         }
  338.                                         else
  339.                                         {
  340.                                                 q->rchild=p;
  341.                                                 Pop(&S,&q);
  342.                                         }
  343.                                 }
  344.                 }
  345.  
  346.  
  347.                 //栈空且i>=len,说明输入的表达式是正确的
  348.                 if(StackEmpty(S) && i >= len)
  349.                 {
  350.                         return 1;
  351.                 }
  352.                 else
  353.                 {
  354.                         printf("\n输入的表达式有误!");
  355.                         return 0;
  356.                 }
  357.         }
  358.  
  359. }
  360.  
  361. //如果两个字符是运算符,比较两个运算符的优先级 输出是否a比b优先
  362. int Primary(char a,char b)
  363. {
  364.         //判断是否为运算符
  365.         if((a=='*' || a=='-' || a=='+' || a=='/') && (b=='*' || b=='-' || b=='+' || b=='/'))
  366.         {
  367.                 //a为乘法或除法运算符 优先于加减运算符
  368.                 if(a=='*' || a=='/')
  369.                 {
  370.                         if(b == '*' || b == '/')
  371.                                 return 0;
  372.                         else
  373.                                 return 1;
  374.                 }
  375.                 else
  376.                         return 0;
  377.         }
  378.         else
  379.                 return 0;
  380. }
  381.  
  382. //用带括弧的中缀表达式输出表达式
  383. void WriteExpr(BiTree E)
  384. {
  385.         //树不为空 中序遍历
  386.         if(E)
  387.         {
  388.                 //递归左子树
  389.                 if(E->lchild && E->lchild->type == CHAR)//E的左孩子不为空且为字符
  390.                 {
  391.                         //双亲运算符比孩子运算符优先
  392.                         if(Primary(E->data.vchar,E->lchild->data.vchar))
  393.                         {
  394.                                 //带括弧输出左子树
  395.                                 printf("(");
  396.                                 WriteExpr(E->lchild);
  397.                                 printf(")");
  398.                         }
  399.                         else
  400.                                 WriteExpr(E->lchild);//不带括弧输出左子树
  401.                 }
  402.                 else WriteExpr(E->lchild);//直接输出左子树
  403.  
  404.                 //访问输出根结点的值
  405.                 if(E->type == INT)
  406.                         printf("%d",E->data.num);
  407.                 else
  408.                         printf("%c",E->data.vchar);
  409.  
  410.                 //递归右子树
  411.                 if(E->rchild && E->rchild->type == CHAR)//E的右孩子不为空且为字符
  412.                 {
  413.                         //双亲运算符比孩子运算符优先
  414.                         if(Primary(E->data.vchar,E->rchild->data.vchar))
  415.                         {
  416.                                 //带括弧输出右子树
  417.                                 printf("(");
  418.                                 WriteExpr(E->rchild);
  419.                                 printf(")");
  420.                         }
  421.                         else
  422.                                 WriteExpr(E->rchild);//不带括弧输出右子树
  423.                 }
  424.                 else
  425.                         WriteExpr(E->rchild);//直接输出右子树
  426.         }
  427. }
  428.  
  429. //实现对表达式中的所有变量V的赋值(V=c) 参数flag为表示是否赋值过的标志
  430. void Assign(BiTree *E,char V,int c,int *flag)
  431. {
  432.         //二叉树存在 先序递归遍历
  433.         if(*E)
  434.         {
  435.                 if((*E)->type == CHAR && (*E)->data.vchar == V)//找到要赋值的变量
  436.                 {
  437.                         (*E)->type = INT; //修改元素类型
  438.                         (*E)->data.num = c;
  439.                         *flag = 1;//标志已赋值
  440.                 }
  441.  
  442.                 //递归左子树
  443.                 Assign(&((*E)->lchild),V,c,flag);
  444.  
  445.                 //递归右子树
  446.                 Assign(&((*E)->rchild),V,c,flag);
  447.         }
  448. }
  449.  
  450. //检查表达式是否还存在没有赋值的变量 先序递归遍历
  451. int Check_Variable(BiTree E)
  452. {
  453.         //树不为空且元素为字符型
  454.         if(E && E->type == CHAR)
  455.         {
  456.                 //存在非运算符
  457.                 if(E->data.vchar != '*' && E->data.vchar != '-' && E->data.vchar != '+' && E->data.vchar != '/')
  458.                         return 0;
  459.  
  460.                 //递归左子树
  461.                 if(Check_Variable(E->lchild))
  462.                 {
  463.                         Check_Variable(E->rchild);//递归右子树
  464.                 }
  465.         }
  466.         else
  467.                 return 1;
  468.  
  469.  
  470. }
  471.  
  472. //基本运算求值 ope:运算符
  473. float Operate(int a, char ope, int b)
  474. {
  475.         switch(ope)
  476.         {
  477.                 case '+': return (a+b); break;
  478.                 case '-': return (a-b); break;
  479.                 case '*': return (a*b); break;
  480.                 case '/': return (a/b); break;
  481.         default : return 0;
  482.         }
  483. }
  484.  
  485. //对算术表达式求值
  486. float Value(BiTree E)
  487. {
  488.         if(E)//树不为空
  489.         {
  490.                 //若为叶子结点(即数字)则返回结点的值
  491.                 if(!E->lchild && !E->rchild && E->type == INT)
  492.                         return E->data.num;
  493.  
  494.                 //非叶子结点则继续递归求值
  495.                 return Operate(Value(E->lchild),E->data.vchar,Value(E->rchild));
  496.         }
  497. }
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515. //java/5689

回复 "C++实现简单的表达式类型"

这儿你可以回复上面这条便签

captcha