首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

:一天内结帖! 一个字符串内存放着一个算术表达式(只有加减乘除),例如:怎样求出值

2012-03-16 
紧急求助:一天内结帖!一个字符串内存放着一个算术表达式(只有加减乘除),例如:,怎样求出值紧急求助:一天内

紧急求助:一天内结帖! 一个字符串内存放着一个算术表达式(只有加减乘除),例如:,怎样求出值
紧急求助:一天内结帖!

一个字符串内存放着一个算术表达式(只有加减乘除),例如:
"1234+(433*1.1+212)+4322*1.7 "

怎样求出值?
一定要用正则表达式的方法来做吗,感觉蛮复杂的,

求最简单的实现方法!


[解决办法]
先转化成二叉树中缀表示法,貌似容易解决了。
[解决办法]
用栈实现,读到数字就往栈里放,* /取出栈中top的数据,立马就算,+ -栈中数据多于一个,就把栈里最靠近top的第一个式子取出算掉,再把结果压入栈中,再把刚才的+或-也压入栈中,遇到(,压入栈中,遇到),取出最靠近top的第一个式子算掉,把结果压入栈中。读完一个串,如果表达式正确的话,栈中应该就一个数据了,取出就是结果!!
记得我们以前就是这么做的
[解决办法]
最快的方法 lex & yacc
最扎实的方法 找数据结构课本里面和后波兰表达式相关的内容

[解决办法]
前些时候写的,不妨一看
http://blog.csdn.net/happytree/archive/2006/12/29/1467933.aspx
[解决办法]
javascript里有个
eval();

[解决办法]
简单点用栈,复杂点用2叉树。
更简单点,去找《the C++ program language》,上面有一个半成品的例子。
[解决办法]
编译原理 后缀表达式 有穷状态机 正则表达式 语法分析器
其实不用表达式求值的

譬如

1+(2 + 3* 4)
变为1234*++
然后
1 进栈 2进栈 3 进 4进 然后* 然后弹 3 4 出来相乘 然后结果12进 然后+ 然后弹 2 12 然后进结果14 然后+ 然后弹 1 14 然后进15 然后终止符 然后 15就是结果了

说得有些乱 自己理解一下就明白了 很简单的

[解决办法]
词法分析编译系统:FLEX
LALR(1)语法编译系统:YACC
[解决办法]
用程序bc求解,管道

echo "1234+(433*1.1+212)+4322*1.7 "|bc
[解决办法]
CString Domatch(CString str)//计算主函数,返回结果的字符串
{
char* stopstring;
CString strt,st;
bool bIsFu = false;
int pos=0,post=0,posright;
float code[50],sum = 0,f;
if(str.IsEmpty()) {sumend = 0; return "0 ";}
if(str.GetAt(0) == '* ') return "ERROR_含有多余的乘号 ";
if(str.GetAt(0) == '/ ') return "ERROR_含有多余的除号 ";
do
{

switch(str.GetAt(0))
{
case '0 ' :
case '1 ' :
case '2 ' :
case '3 ' :
case '4 ' :
case '5 ' :
case '6 ' :
case '7 ' :
case '8 ' :
case '9 ' :
if(bIsFu) //是否为负数
code[pos] =-(float) strtod(str, &stopstring);//取字符串的数值
else code[pos] =(float) strtod(str, &stopstring);
pos++;
str.Delete(0,str.Find(*stopstring));
bIsFu = false;
break;
case '+ ' : //+
str.Delete(0);
post++;
break;
case '- ' : //-
str.Delete(0);
post++;
bIsFu = true;
break;
case '* ' : //*
pos--;
str.Delete(0);
if(str.GetAt(0) == '( '){
str.Delete(0);
posright = Findtheright(str);
strt = str.Left(posright);
code[pos] =code[pos] * strtod(Domatch(strt, f),&stopstring);
str.Delete(0,posright+1);;
}
else{
code[pos] =float( code[pos] * strtod(str, &stopstring));
str.Delete(0,str.Find(*stopstring));
}
pos++;
break;
case '/ ' : // /
pos--;
str.Delete(0);
if(str.GetAt(0) == '0 ')


return "ERROR_被除数不能为O ";
if(str.GetAt(0) == '( '){
str.Delete(0);
posright = Findtheright(str);
strt = str.Left(posright);
if(strtod(Domatch(strt, sumend),&stopstring) == 0)
return "ERROR_被除数不能为O ";
code[pos] =code[pos] / strtod(Domatch(strt, f),&stopstring);
str.Delete(0,posright+1);;
}
else {
code[pos] =(float) code[pos] / strtod(str, &stopstring);
str.Delete(0,str.Find(*stopstring));
}
pos++;
break;
case '% ' : // %
pos--;
str.Delete(0);
if(str.GetAt(0) == '( '){
str.Delete(0);
posright = Findtheright(str);
strt = str.Left(posright);
code[pos] =float((int)code[pos] % (int)strtod(Domatch(strt, f),&stopstring));
str.Delete(0,posright+1);;
}
else{
code[pos] =float((int) code[pos] % (int)strtod(str, &stopstring));
str.Delete(0,str.Find(*stopstring));
}
pos++;
break;
case '^ ' : // ^
pos--;
str.Delete(0);
code[pos] =float( pow(code[pos], strtod(str, &stopstring)));
str.Delete(0,str.Find(*stopstring));
pos++;
break;
case '! ' : // ^ ~_~
pos--;
str.Delete(0);
if(code[pos] <0)
code[pos] = -NN(-(int)code[pos]);
else
code[pos] = NN((int)code[pos]);
str.Delete(0,str.Find(*stopstring));
pos++;
break;
case '( ' : // ^ ~_~
str.Delete(0);
posright = Findtheright(str);
strt = str.Left(posright);
st = Domatch(strt, sumend);
if(st.Find( "ERROR ") != -1) return st;
if(bIsFu)
code[pos] = -strtod(Domatch(strt, sumend),&stopstring);
else code[pos] = strtod(Domatch(strt, sumend),&stopstring);
str.Delete(0,posright+1);
pos++;
bIsFu = false;
break;
default :
return "ERROR_含有非法字符 ";
}
if(pos > = 50) return "ERROR_表达式太长 ";
}while(!str.IsEmpty());

for( pos--; pos> =0; pos--)
{
sum +=code[pos];
}

strt.Format( "%g ", sum);
return strt;//返回结果的字符串,如果想返回float 则return sum;

}刚好以前写过..

热点排行