怎样求一字符串表达式的值(不用栈结构)。

hproof 2001-08-10 05:32:04
加精
但可以递归。其实,我只是看不惯书上的那一套,那套麻烦的要死,还要构造什么优先及表什么的,而且,意思很难理解。
...全文
268 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
hproof 2001-08-20
  • 打赏
  • 举报
回复
天哪,真是够简洁的。最近不上网了,大家都有分吧。
tarkey 2001-08-14
  • 打赏
  • 举报
回复
最简洁的办法。
以下是伪代码
string a = "1+2*(3+4)";
main()
{
write_file("c:\temp.c","main(){ return "+a+";}");
call_other("c:\temp.c");
return;
}
呵呵,够简单了吧。
不过这是伪代码,提供一种思路。
jucee 2001-08-14
  • 打赏
  • 举报
回复
气氛很浓,可惜以我静不下心来了
hproof 2001-08-12
  • 打赏
  • 举报
回复
服了版主了,比我的短多了。看我的.

对于任何合法的表达式串,如"1+2*3/(4-6)=",可分解为:
"数据+操作+.....+操作+数据="
的形式,只要把'('及')'看作"递归数据"的标志,这样,可定义3类操作:

1,float GetAnswer(int);
//得到一个字符串的值.它调用函数2和函数3.
2,int GetOpt();
//得到一个新的操作符,返回起代码值.
3,float GetData();
//得到一个数据,当遇到'('时,它调用函数1.
4,全局变量:
char buf[256];
char *pch;
//pch指向下一个将处理的字符.
enum{
ADD=100,
SUB=101,
MUL=200,
DIV=201
};
//数值不是随意的,MUL-ADD=100>50 表示MUL比ADD有更高的优先及.
5,源代码:
//"1+2="

char buf[256];
char *pch;

enum{
ADD=100,
SUB=101,
MUL=200,
DIV=201
};

int GetOpt();
float GetData();
float GetAnswer(int);

main()
{
float n;
scanf("%s",buf);
pch=buf;
n=GetAnswer(0);
printf("%f\n",n);
}

int GetOpt()
{
char ch=*pch++;
int opt=0;
switch(ch)
{
case '+':opt=ADD;break;
case '-':opt=SUB;break;
case '*':opt=MUL;break;
case '/':opt=DIV;break;
}
return opt;
}

float GetData()
{
float ret=0;
char ch=*pch++;
if(ch<='9'&&ch>='0')
ret=ch-'0'; //ASSERT(*pch==操作)
else //ASSERT(ch=='(')
{
ret=GetAnswer(0); //ASSERT(*pch==')')
pch++; //ASSERT(*pch==操作)

}
return ret; //ASSERT(*pch==操作)
}

float GetAnswer(int op0)
{
float n=GetData();
int op1=GetOpt();
while(op1-op0>50)
{
switch(op1)
{
case ADD:n+=GetAnswer(ADD);break;
case SUB:n-=GetAnswer(SUB);break;
case MUL:n*=GetAnswer(MUL);break;
case DIV:n/=GetAnswer(DIV);break;
}
op1=GetOpt();
}
pch--;
return n;
}

我曾在TurboC2.0下编译通过,不过,这里是凭记忆写出的.如有望包含。
starfish 2001-08-10
  • 打赏
  • 举报
回复
上面的代码在delphi下通过
starfish 2001-08-10
  • 打赏
  • 举报
回复
Sorry, i forgot the getNumber function.

function getNumber(var s:string):extended;
var i,code:integer;
begin
i:=1;
while s[i] in ['0'..'9','.'] do inc(i);
val(copy(s,1,i-1),result,code);
end;
starfish 2001-08-10
  • 打赏
  • 举报
回复
试试看这个:
function expr(var s:string):extended;
//表达式求值 (4+5)*6-8*(1+1) = 38
// (4+5)*6/3-8*(1+4)=-22
//表达式两边要用()括起来
var
flag:boolean;
ch:char;
begin
flag:=false;
case s[1] of
'0'..'9' : result:=getNumber(s);
'(' : begin
delete(s,1,1);
result:=expr(s);
flag:=true;
end;
end;
while (s[1]<>')') do
begin
ch:=s[1];
delete(s,1,1);
case ch of
'+': result:=result+expr(s);
'-': result:=result-expr(s);
'*': if s[1]='('
then result:=result*expr(s)
else result:=result*getNumber(s);
'/': if s[1]='('
then result:=result/expr(s)
else result:=result/getNumber(s);
end; //case ch
end; //while s[1]
if flag then delete(s,1,1);
end;
one_add_one 2001-08-10
  • 打赏
  • 举报
回复
比如这个表达式:
5*7+((1+2)*(3+4*(5+6)))/2-6
我的算法过程为:
5*7+((1+2)*(3+4*11))/2-6 第一次化简
5*7+(3*(3+4*11))/2-6 第二次化简
5*7+(3*47)/2-6 第三次化简
5*7+141/2-6 第四次化简
99.5 第五次化简
one_add_one 2001-08-10
  • 打赏
  • 举报
回复
我看我的哪个程序最顺眼,思想就是不断化简,没有用后缀!
hproof 2001-08-10
  • 打赏
  • 举报
回复
下了,不在了。2天后回来。
frman 2001-08-10
  • 打赏
  • 举报
回复
俺觉得后缀挺好的啊,嘿嘿。。。不说了不说了,吃饭去了哦:))))
hproof 2001-08-10
  • 打赏
  • 举报
回复
分数不够我可以加啊,望大家多多费脑,就当是锻炼吧.
不需要源程序,只要算法原理就可以了。
one_add_one 2001-08-10
  • 打赏
  • 举报
回复
后缀表达式难理解,编程复杂,看起也不顺眼!
frman 2001-08-10
  • 打赏
  • 举报
回复
哈哈~~~~大家发言时间这么近,都在线上啊:)
frman 2001-08-10
  • 打赏
  • 举报
回复
嘿嘿。。。one_add_one,真好玩:)

我的发言插到你的发言中间来了:)))
hproof 2001-08-10
  • 打赏
  • 举报
回复
哦,,,后缀的?有没有更好的呢。
one_add_one 2001-08-10
  • 打赏
  • 举报
回复
以上程序的思想是:不断化简表达式,最后化为一个数字!
frman 2001-08-10
  • 打赏
  • 举报
回复
你的意思是不是不要转换成后缀表达式啊?:)
我觉得那方法挺好啊,起码比我下面说的这个好:)

不用后缀表达式,俺觉得比较笨的方法是一级一级的扫描字串,对没有括号的式子先找到其中优先级最高的运算符,对其两边的数运算啊,也说不上什么算法,就是一般人去计算一个式子所用的呗,对有括号的式子,先找最里面的括号去做呗,

其实这样编起来又麻烦效率还低,为什么不用后缀表达式呢?
one_add_one 2001-08-10
  • 打赏
  • 举报
回复
这是我原来用QBASIC写的一个求表达示值的程序!
数据结构只有字符串!

DEFINT A-Z
DECLARE FUNCTION kh$ (x$)
DECLARE FUNCTION zl$ (x$)
DECLARE FUNCTION js$ (x$)
DECLARE FUNCTION lg$ (x$, a, n)
LINE INPUT "Please Input A Express:", x$
FOR a = 1 TO LEN(x$)
IF MID$(x$, a, 1) = "-" THEN MID$(x$, a, 1) = "_"
NEXT: PRINT "Result="; kh$(x$)

FUNCTION js$ (x$)
x$ = zl$(x$)
FOR a = 1 TO LEN(x$)
i$ = MID$(x$, a, 1)
IF i$ = "*" OR i$ = "/" THEN IF i$ = "*" THEN x$ = lg$(x$, a, 3) ELSE x$ = lg$(x$, a, 4)
NEXT
x$ = zl(x$)
FOR a = 1 TO LEN(x$)
i$ = MID$(x$, a, 1)
IF i$ = "+" OR i$ = "_" THEN IF i$ = "+" THEN x$ = lg$(x$, a, 1) ELSE x$ = lg$(x$, a, 2)
NEXT: js$ = x$
END FUNCTION

FUNCTION kh$ (x$)
FOR x = 1 TO LEN(x$)
i$ = MID$(x$, x, 1)
IF i$ = "(" THEN
k = k + 1: IF k = 1 THEN a = x
ELSEIF i$ = ")" THEN
k = k - 1
IF k = 0 THEN
b$ = MID$(x$, a + 1, x - a - 1)
MID$(x$, a, x - a + 1) = STRING$(x - a + 1, 32)
MID$(x$, a, x - a + 1) = kh$(b$)
END IF
END IF
NEXT: kh$ = js$(x$)
END FUNCTION

FUNCTION lg$ (x$, a, n)
DIM p AS DOUBLE, q AS DOUBLE
FOR x = a - 1 TO 1 STEP -1
s = ASC(MID$(x$, x, 1))
IF s = 42 OR s = 43 OR s = 95 OR s = 47 THEN EXIT FOR
NEXT
FOR y = a + 1 TO LEN(x$)
s = ASC(MID$(x$, y, 1))
IF s = 42 OR s = 43 OR s = 95 OR s = 47 THEN EXIT FOR
NEXT
p = VAL(MID$(x$, x + 1, a - 1)): q = VAL(MID$(x$, a + 1, y - 1))
IF n = 3 THEN
b$ = LTRIM$(STR$(p * q))
ELSEIF n = 4 THEN
b$ = LTRIM$(STR$(p / q))
ELSEIF n = 1 THEN
b$ = LTRIM$(STR$(p + q))
ELSEIF n = 2 THEN
b$ = LTRIM$(STR$(p - q))
END IF
MID$(x$, x + 1, y - 1) = STRING$(y - x - 1, 32)
MID$(x$, x + 1, y - 1) = b$: lg$ = x$
END FUNCTION

FUNCTION zl$ (x$)
FOR a = 1 TO LEN(x$)
IF MID$(x$, a, 1) <> " " THEN b$ = b$ + MID$(x$, a, 1)
NEXT: zl$ = b$
END FUNCTION

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧