解析树不起作用

时间:2011-04-16 19:05:39

标签: c++

我想构建简单的解析树/但它不起作用。我认为strlen会返回错误的结果。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

int min(int a ,int b){ return (a>b)?b:a;}

class Node
{
    Node* left;
    Node* right;
    char operation;

public:
    float res;

    Node(char* str)
    {
        char* ch = NULL;
        ch = strrchr2(str);
        if (ch==NULL)
        {
            if(str[0]=='(')
            {
                str = &str[1]; 
                int k = strlen(str);
                char *tmp = new char[k-1];

                strncpy(tmp,str,k-1);
                ch = strrchr2(tmp);

                div(tmp,ch);
            }
            else
                res = atof(str);                
        }
        else
        {
            div(str,ch);
        }
    }

    void div(char* str,char* ch)
    {
            //getting opertion
            strncpy(&operation,ch,1);

            //getting position of operation
            int pos = strlen(str)-strlen(ch);

            //right node creation
            ch = &ch[1];
            right = new Node(ch);

            //left node creation
            char* tmp = new char[pos];
            strncpy(tmp,str,pos);
            left = new Node(tmp);

            //applying opertion to to node's results
            switch( operation )
            {
                case '/':this->res = left->res/right->res;break;
                case '*':this->res = left->res*right->res;break;
                case '+':this->res = left->res+right->res;break;
                case '-':this->res = left->res-right->res;break;
                default:break;
            };
    }

    char* strrchr2(char* s)
    {
        char* str = new char[strlen(s)];
        strcpy(str,s);
        int i = search(str);
        if(i==-1) return NULL;
            else
        if(str[i]=='+' || str[i]=='-') return &str[i];
            else if (str[i] == '*' || str[i]=='/')
            {
                char c = str[i+1];
                if(i+1<strlen(str)-1 && search(&c)!=-1) return strrchr2(&c);
                else return &str[i];
            }
    }

    int search(char* str)
    {
        int cnt1 = 0;
        int cnt2 = 0;
        for(int i=0;i<strlen(str);i++)
        {
            if (str[i]=='(') cnt1++;
            else if (str[i]==')') cnt2++;
            if (cnt1!=0)
            {
               if(cnt1==cnt2)
               {
                  int m = strlen(str);
                  return ((i+1)!=m?i+1:-1);
               }
            }
            else
            {
                if (str[i]=='-' || str[i]=='+' || str[i]=='*' || str[i]=='/') return i;
            }
        }
        char* ch = NULL;
        ch = strchr(str,'-');
        if(ch==NULL) ch = strchr(str,'+');
        if(ch==NULL) ch = strchr(str,'*');
        if(ch==NULL) ch = strchr(str,'/');
        if(ch==NULL)return -1;
        else return strlen(str)-strlen(ch);
    }
};

int main()
{
    char* expr = "(1/2)-(1/2)";
    Node* n = new Node(expr);
    printf("%s = %.3f",expr,n->res);



    _getch();
}

2 个答案:

答案 0 :(得分:5)

看起来你的C语言比C ++更多。 尝试使用{* 1}} char *。这样你就不会遇到任何strlen问题(如果strlen确实是问题),因为字符串有一个std::string函数,并且它可以很好地工作。最重要的是,您可以使用许多正在尝试重新编码的功能。

有关字符串的更多信息:http://www.cplusplus.com/reference/string/string/

M.Dijsktra还创建了一种解析数学表达式并输出AST(抽象语法树)的算法。它将允许您处理更复杂的表达式。它被称为“分流码算法”#。这是维基百科:http://en.wikipedia.org/wiki/Shunting-yard_algorithm

我想你可能想知道已经完成了什么。 :)

答案 1 :(得分:4)

这是你做的。

您确保使用带有集成调试器的良好IDE。您可以单步执行代码并查看变量,这一点至关重要。专家可以在没有这些奢侈品的情况下调试代码,但需要非常多的专业知识。

所以你需要一个调试器。如果您使用的是Windows,则可以免费获得Visual Studio 2010 Express。或者您可能已经有一个调试器。

接下来你要做的是逐行逐步完成代码,并确保它在每一步都完全符合它的要求。这很乏味,但就是这样。

“此代码不起作用”并未删除它。 StackOverflow上唯一可以为您做的事情(没有根据运气发现明显的错误)是将代码加载到自己的调试器中并为您逐步完成。但你真的需要学会自己动手。

P.S。库函数和编译器基本上总是有效。如果你认为你发现了一个错误,你几乎肯定没有。如果您仍然这么认为,请尝试使用几行代码重现该错误。如果确实存在错误,那么它几乎总是可以简化为5行程序。如果你不能将它缩减到一个非常短的程序,那么它几乎肯定是你代码中的一个错误,如果它不是那么你就会知道没有询问StackOverflow。