计算表达式(50分)

  • 主题发起人 主题发起人 mao-jin
  • 开始时间 开始时间
M

mao-jin

Unregistered / Unconfirmed
GUEST, unregistred user!
字符串: ' 1+5*10/20+11 '

如何把这个字符串计算表达式计算出数值来,要快的!
 
采用递归
 
看看数据结构的书吧!
首先要将你的计算表达式转换成中缀式,然后计算。
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1307891
 
下面有你要的:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2513942
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=7357
下午刚做的,肯定能满足你的要求。
 
先转成postfix,要用stack.去网上搜索或者看看书吧。
 
yostgxf,给个能运行的代码我试试
 
你把我笔记上的代码拷贝过去就行了.
刚才少了uses StrUtils,我加进去了
调用函数function CalcText(InStr :String) :String;
 
还有,我没有'/'符号,当成特殊符号了,除用‘/’
 
一个择自《编译原理及实践》上的例子,用递归方法实现了整数的+ - * ( ) 的处理。是我至今见到最简练的例子了。 :)

/* Simple integer arithmetic calculator
according to the EBNF:

<exp> -> <term> { <addop> <term> }
<addop> -> +|-
<term> -> <factor> { <mulop> <factor>}
<mulop> -> *
<factor> -> ( <exp> | Number )

Input a line of text from stdin
Outputs "Error" or the result.
*/

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

char token
/*global token variable*/

/* function prototypes for recursive calls */
int exp(void);
int term(void);
int factor(void);

void error(void)
{ fprintf(stderr, "Error/n");
exit(1);
}

void match (char expectedToken)
{ if (token == expectedToken) token = getchar();
else error();
}

main ()
{
int result;
token = getchar()
/*load token with first character for lookahead */
result = exp();
if (token =='/n') /* check for end of line */
printf("Result = %d/n",result);
else error()
/* extraneous chars on line */
return 0;
}

int exp(void)
{ int temp = term();
while ((token=='+') || (token=='-'))
switch (token) {
case '+': match('+');
temp += term();
break;
case '-': match('-');
temp -= term();
break;
}
return temp;
}

int term(void)
{ int temp = factor();
while (token == '*') {
match('*');
temp *= factor();
}
return temp;
}

int factor(void)
{ int temp;
if (token == '(') {
match('(');
temp = exp();
match(')');
}
else if (isdigit(token)) {
ungetc(token, stdin);
scanf("%d", &amp;temp);
token = getchar();
}
else error();
return temp;
}
 
以下是我读程序时做的逐行注释,enjoy :-)

/* 简易整数算法计算器
根据EBNF以下写成

<exp> -> <term> {<addop> <term>} <表达式> -> <因式> { <加符> <因式> } //{}表示内容可以重复多次
<addop> -> +|- <加符> -> +或-
<term> -> <factor> {<mulop> <factor>} <因式> -> <因子> {<乘符> <因子>}
<mulop> -> * <乘符> -> *
<factor> -> (<exp> | Number) <因子> -> ( <表达式> 或 数字 ) //注意(与)是实际的左右括号
*/

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

char token
/*全局token变量*/

/* 递归函数前置定义 */
int exp(void);
int term(void);
int factor(void);

void error(void)
//出错处理
{ fprintf(stderr, "Error/n");
exit(1);
}

void match (char expectedToken)
//判断当前token是否正确,并取下一个token
{ if (token == expectedToken) token = getchar();
else error();
}

main ()
{
int result;
token = getchar()
/*取第一个字符作为token, 启动运算 */
result = exp()
/*把整个算式作为一个 <表达式> 处理 */
if (token =='/n') /* 检查结束标志 */
printf("Result = %d/n",result)
/*输出结果*/
else error()
/* 算式尾部有多余字符 */
return 0;
}

int exp(void)
//计算一个表达式
//根据:<exp> -> <term> {<addop> <term>}
// <表达式> -> <因式> { <加符> <因式> }

{ int temp = term()
/* 计算最左边因式 */
while ((token=='+') || (token=='-')) /* 循环处理 {} 中的部分 */
switch (token) { /* 分别处理+与- */
case '+': match('+')
/* 检查加符并取下一字符 */
temp += term()
/* 处理算符右边的因式 */
break;
case '-': match('-');
temp -= term();
break;
}
return temp;
}

int term(void)
//计算一个因式
//根据:<term> -> <factor> {<mulop> <factor>}
// <因式> -> <因子> {<乘符> <因子>}

{ int temp = factor()
/* 计算最左边因子 */
while (token == '*') { /* 循环处理{}中的部分 */
match('*')
/* 检查乘符并取下一字符 */
temp *= factor()
/* 计算乘符右边的因子 */
}
return temp;
}

int factor(void)
//计算一个因子
//根据:<factor> -> (<exp> | Number)
<因子> -> ( <表达式> 或 数字 )

{ int temp;
if (token == '(') { /* 处理子表达式 */
match('(')
/* 检查左括号并取下一字符 */
temp = exp()
/* 计算括号中的表达式 */
match(')')
/* 检查右括号并取下一字符 */
}
else if (isdigit(token)) { /* 处理数字 */
ungetc(token, stdin)
/* 如果已经取得的字符是数字,则把读入指针后退一个字符,以便下面的scanf读入*/
scanf("%d", &amp;temp)
/* 取一个整数 */
token = getchar()
/* 取下一个字符以便继续处理)
}
else error()
/* 若非子表达式,非数字,(应该是因子的地方不是因子),则出错 */
return temp;
}
 
多人接受答案了。
 
后退
顶部