我想构建简单的解析树/但它不起作用。我认为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();
}
答案 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。