Advertisement
Guest User

表达式树

a guest
Nov 3rd, 2022
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.50 KB | Source Code | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <fstream>
  7. using namespace std;
  8. typedef int HNODE;
  9. struct BinTreeNode{
  10.     char op;
  11.     double value;
  12.     bool calculated;
  13.     HNODE hNode_left;
  14.     HNODE hNode_right;
  15.     BinTreeNode(char c='\0',double v=0,bool flag=false,HNODE l=0,HNODE r=0):
  16.         op(c),value(v),calculated(flag),hNode_left(l),hNode_right(r){}
  17.     void setValue(double v){
  18.         value=v;
  19.     }
  20.     double getValue(){
  21.         return value;
  22.     }
  23.     void setCalculated(bool setter=true){
  24.         calculated=setter;
  25.     }
  26.     bool isCalculated(){
  27.         return calculated;
  28.     }
  29.     HNODE getHNode_left(){
  30.         return hNode_left;
  31.     }
  32.     HNODE getHNode_right(){
  33.         return hNode_right;
  34.     }
  35.     void setOperator(char c){
  36.         op=c;
  37.     }
  38.     char getOperator(){
  39.         return op;
  40.     }
  41.     friend ostream &operator<<(ostream &os,BinTreeNode &node){
  42.         if(node.op=='\0'){
  43.             os<<"((\""<<"^"<<","<<node.value<<"\"))";
  44.         }
  45.         else
  46.             os<<"((\""<<node.op<<","<<node.value<<"\"))";
  47.         return os;
  48.     }
  49. };
  50.  
  51. struct BinTree{
  52.     HNODE hNode_root;
  53.     vector<BinTreeNode> nodes;
  54.     BinTree(){
  55.  
  56.         hNode_root=newNode(BinTreeNode('\0',0,true,0,0));
  57.     }
  58.     HNODE newNode(const BinTreeNode &node){
  59.         HNODE hNode=nodes.size();
  60.         nodes.push_back(node);
  61.         return hNode;
  62.     }
  63.     void inOrder(HNODE hNode_current){
  64.         if(!hNode_current)return ;
  65.         inOrder(nodes[hNode_current].getHNode_left());
  66.         cout<<hNode_current<<" ";
  67.         inOrder(nodes[hNode_current].getHNode_right());
  68.     }
  69.     void inOrder(){
  70.         inOrder(hNode_root);
  71.     }
  72.     friend ostream &operator<<(ostream &os,BinTree &tree){
  73.         for(HNODE hNode=1;hNode<tree.nodes.size();++hNode){
  74.             os<<hNode<<tree.nodes[hNode]<<endl;
  75.         }
  76.         HNODE hNode_current;
  77.         HNODE hNode_next;
  78.         queue<HNODE>q;
  79.         q.push(tree.hNode_root);
  80.         while(!q.empty()){
  81.             hNode_current=q.front();
  82.             q.pop();
  83.             hNode_next=tree.nodes[hNode_current].getHNode_left();
  84.             if(hNode_next){
  85.                 os<<hNode_current<<"----"<<hNode_next<<endl;
  86.                 q.push(hNode_next);
  87.             }
  88.             hNode_next=tree.nodes[hNode_current].getHNode_right();
  89.             if(hNode_next){
  90.                 os<<hNode_current<<"----"<<hNode_next<<endl;
  91.                 q.push(hNode_next);
  92.             }
  93.         }
  94.         return os;
  95.     }
  96. };
  97. enum Error_Type{
  98.     NONE_ERROR,
  99.     ERR_DIV_ZERO,
  100.     ERR_DISMATCH_RBRACKET,
  101.     ERR_MULTIPLE_DOT
  102.  
  103. };
  104.  
  105. static string SError_Type[]{
  106.     "NONE_ERROR",
  107.     "ERR_DIV_ZERO",
  108.     "ERR_DISMATCH_RBRACKET",
  109.     "ERR_MULTIPLE_DOT"
  110. };
  111.  
  112.  
  113. struct ExpressionTree:public BinTree{
  114.     string expression;
  115.     int pos;
  116.     Error_Type error;
  117.     ExpressionTree(){
  118.         pos=0;
  119.         expression="";
  120.         error=NONE_ERROR;
  121.     }
  122.     double getValue(HNODE hNode_current){
  123.         BinTreeNode &node=nodes[hNode_current];
  124.         if(node.isCalculated()){
  125.             return node.getValue();
  126.         }
  127.         node.setCalculated();
  128.         switch(node.getOperator()){
  129.             case '\0':
  130.                 break;
  131.             case '+':
  132.                 node.setValue(getValue(node.getHNode_left())+getValue(node.getHNode_right()));
  133.                 break;
  134.             case '-':
  135.                 node.setValue(getValue(node.getHNode_left())-getValue(node.getHNode_right()));
  136.                 break;
  137.             case '*':
  138.                 node.setValue(getValue(node.getHNode_left())*getValue(node.getHNode_right()));
  139.                 break;
  140.             case '/':
  141.                 node.setValue(getValue(node.getHNode_left())/getValue(node.getHNode_right()));
  142.                 break;
  143.         }
  144.         return node.getValue();
  145.     }
  146.     double getValue(){
  147.         return getValue(hNode_root);
  148.     }
  149.     double operator()(const string &exp){
  150.         pos=0;
  151.         expression="";
  152.         error=NONE_ERROR;
  153.         nodes.resize(0);
  154.         hNode_root=newNode(BinTreeNode('\0',0,true,0,0));
  155.         expression=filter(exp);
  156.         hNode_root=evalExpression();
  157.         return getValue(hNode_root);
  158.     }
  159.     HNODE evalExpression(){
  160.         HNODE hNode_current;
  161.         HNODE hNode_term;
  162.         HNODE hNode_history;
  163.         char op;
  164.         hNode_term=evalTerm();
  165.         if(error){
  166.             return 0;
  167.         }
  168.         hNode_current=hNode_term;
  169.         while(!end()){
  170.             op=expression[pos];
  171.             if(op!='+'&&op!='-'){
  172.                 return hNode_current;
  173.             }
  174.             ++pos;
  175.             hNode_term=evalTerm();
  176.             if(error){
  177.                 return 0;
  178.             }
  179.             hNode_history=hNode_current;
  180.             hNode_current=newNode(BinTreeNode(op,0,false,hNode_history,hNode_term));
  181.         }
  182.         return hNode_current;
  183.     }
  184.     HNODE evalTerm(){
  185.         HNODE hNode_current;
  186.         HNODE hNode_factor;
  187.         HNODE hNode_history;
  188.         char op;
  189.         hNode_factor=evalFactor();
  190.         if(error){
  191.             return 0;
  192.         }
  193.         hNode_current=hNode_factor;
  194.         while(!end()){
  195.             op=expression[pos];
  196.             if(op!='*'&&op!='/'){
  197.                 return hNode_current;
  198.             }
  199.             ++pos;
  200.             hNode_factor=evalFactor();
  201.             if(error){
  202.                 return 0;
  203.             }
  204.             hNode_history=hNode_current;
  205.             hNode_current=newNode(BinTreeNode(op,0,false,hNode_history,hNode_factor));
  206.         }
  207.         return hNode_current;
  208.     }
  209.     HNODE evalFactor(){
  210.         HNODE hNode_current;
  211.         HNODE hNode_history;
  212.         if(expression[pos]=='('){
  213.             ++pos;
  214.             hNode_current=evalExpression();
  215.             if(error){
  216.                 return 0;
  217.             }
  218.             if(expression[pos]!=')'){
  219.                 error=ERR_DISMATCH_RBRACKET;
  220.                 return 0;
  221.             }
  222.             ++pos;
  223.         }
  224.         else if(expression[pos]=='-'){
  225.             ++pos;
  226.             hNode_history=evalFactor();
  227.             if(error){
  228.                 return 0;
  229.             }
  230.             hNode_current=newNode(BinTreeNode('-',0,false,0,hNode_history));
  231.         }
  232.         else if(isdigit(expression[pos])){
  233.             hNode_current=evalID();
  234.             if(error){
  235.                 return 0;
  236.             }
  237.         }
  238.        
  239.         return hNode_current;
  240.     }
  241.     HNODE evalID(){
  242.         bool dot_flag=false;
  243.         string buffer;
  244.         while(!end()){
  245.             if(expression[pos]!='.'&&!isdigit(expression[pos])){
  246.                 break;
  247.             }
  248.             else if(expression[pos]=='.'){
  249.                 if(dot_flag){
  250.                     error=ERR_MULTIPLE_DOT;
  251.                     return 0;
  252.                 }
  253.             }
  254.             buffer+=expression[pos];
  255.             ++pos;
  256.         }
  257.         return newNode(BinTreeNode('\0',stod(buffer),true,0,0));
  258.     }
  259.     bool end()
  260.     {
  261.         return expression[pos] == '\0';
  262.     }
  263.  
  264.     string filter(const string &exp)
  265.     {
  266.         string text;
  267.         for (auto c : exp)
  268.         {
  269.             if(isdigit(c)||c=='.'||c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')'){//过滤输入,只允许特定的运算符,数字,小数点进入expression
  270.                 text+=c;
  271.             }
  272.         }
  273.         return text;
  274.     }
  275.     void what(){
  276.         if(error){
  277.             cout<<SError_Type[error]<<endl;
  278.         }
  279.         else{
  280.             cout<<"construction complete"<<endl;
  281.         }
  282.     }
  283.     friend ostream &operator<<(ostream &os,ExpressionTree &tree){//打印树的样子
  284.         for(HNODE hNode=1;hNode<tree.nodes.size();++hNode){
  285.             os<<hNode<<tree.nodes[hNode]<<endl;
  286.         }
  287.         HNODE hNode_current;
  288.         HNODE hNode_next;
  289.         queue<HNODE>q;
  290.         q.push(tree.hNode_root);
  291.         while(!q.empty()){
  292.             hNode_current=q.front();
  293.             q.pop();
  294.             hNode_next=tree.nodes[hNode_current].getHNode_left();
  295.             if(hNode_next){
  296.                 os<<hNode_current<<"----"<<hNode_next<<endl;
  297.                 q.push(hNode_next);
  298.             }
  299.             hNode_next=tree.nodes[hNode_current].getHNode_right();
  300.             if(hNode_next){
  301.                 os<<hNode_current<<"----"<<hNode_next<<endl;
  302.                 q.push(hNode_next);
  303.             }
  304.         }
  305.         return os;
  306.     }
  307.     bool outFile(string filepath){//将mermaid作图输出到文件
  308.         ofstream fout(filepath.c_str(),ios::app);//前面的不删除,附加打开
  309.         if(fout.is_open()==false){
  310.             cout<<"error filepath"<<endl;
  311.             return false;
  312.         }
  313.         streambuf *oldcout=cout.rdbuf(fout.rdbuf());
  314.         if(error){
  315.             cout<<SError_Type[error];
  316.            
  317.         }
  318.         else{
  319.             cout<<"## `"<<expression<<"`"<<endl;//给一个二级标题
  320.             cout<<"```mermaid"<<endl;
  321.             cout<<"graph"<<endl<<endl;
  322.             cout<<(*this)<<endl;
  323.             cout<<"```"<<endl;
  324.         }
  325.         // cout.close();
  326.         cout.rdbuf(oldcout);
  327.         fout.close();
  328.         return true;
  329.  
  330.     }
  331. };
  332.  
  333.  
  334. int main(){
  335.     ExpressionTree tree;
  336.     string expression;
  337.     while(true){
  338.         cout<<">";
  339.         cin>>expression;
  340.         if(expression=="q"){
  341.             break;
  342.         }
  343.         cout<<tree(expression)<<endl;
  344.         tree.outFile("tree.md");//本次建树附加到tree.md最后面
  345.  
  346.     }
  347.    
  348.     return 0;
  349. }
  350.  
Tags: 表达式树
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement