谁有数学运算公式的解析算法,最好是C语言的?

yang0411 2002-09-05 01:19:06
不需要太复杂,只要含有+、-、*、/、(、)就行
...全文
231 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
qingqingtimes 2002-10-09
  • 打赏
  • 举报
回复
来晚了,没赶上,
怎么就没有人,提出使用bison呢?有感兴趣的请和我联系。nci_yht2000@sina.com
yang0411 2002-09-06
  • 打赏
  • 举报
回复
我很菜,看不懂C++程序,你能改成c语言的吗?
熊主任 2002-09-06
  • 打赏
  • 举报
回复
把C++的改成C语言很复杂吗?我用的是STL,你找本数据结构的书,自己写个int和char的stack,不就OK了?
dcyu 2002-09-06
  • 打赏
  • 举报
回复
这是我以前下载的一个:
// ExpressTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "string.h"
#include "math.h"

#define ADD 1 //运算符
#define SUB 2
#define MUL 3
#define DIV 4
#define POW 5
#define FACT 6
#define LEFT 7
#define ADDLEVEL 1 //运算优先级别
#define SUBLEVEL 1
#define MULLEVEL 2
#define DIVLEVEL 2
#define POWLEVEL 3
#define FACTLEVEL 4
#define LEFTLEVEL 5

char string[1001];
int STRLEN;
typedef struct stack
{
float num;//数字
char opsign;//运算符
int bracket;//所处括号层
struct stack * pnext;//链表
}stack;

float getnumber();//得到数字
float fact(int n);//阶乘
int getlevel(int opsign);//得到运算符的优先级别
char getnextopsign();//得到下一个运算符,包括'('
void push(char opsign);//压入堆栈
void pop();//从堆栈拉出
bool check();//检查表达式是否合法
stack * getstack(int n);//得到某堆栈指针

stack firststack;//动态堆栈首
int point;//表达式指针
int stacknum;//堆栈数目
char repeat='y';
float result;
int bracket;//当前层次深度


void main()
{
bool error=0;
while(1){
point=0;bracket=0;stacknum=0;error=0;
printf("请输入1000字符内的计算式('q'退出):\n");
scanf("%s",string);
if(string[0]=='q' || string[0]=='Q') return;
STRLEN=strlen(string);
if(!check()) continue;//合法?
result=getnumber();
while(point<=STRLEN-1){
switch(string[point++]){//哪个运算符?
case '+':
if(getnextopsign()>ADDLEVEL){
push(ADD);
result=getnumber();
}
else result+=getnumber();
break;
case '-':
if(getnextopsign()>SUBLEVEL){
push(SUB);
result=getnumber();
}
else result-=getnumber();
break;
case '*':
if(getnextopsign()>MULLEVEL){
push(MUL);
result=getnumber();
}
else
{
result*=getnumber();
if(stacknum>0 && getnextopsign()<MULLEVEL && getstack(stacknum)->bracket>=bracket)
pop();
}
break;
case '/':
if(getnextopsign()>DIVLEVEL){
push(DIV);
result=getnumber();
}
else
{
result/=getnumber();
if(stacknum>0 && getnextopsign()<DIVLEVEL && getstack(stacknum)->bracket>=bracket)
pop();
}
break;
case ')'://右括号
--bracket;
if(getstack(stacknum)->opsign==0){//括号前面为空
pop();
break;
}
while(stacknum>0 && getnextopsign()<getlevel(getstack(stacknum)->opsign)
&& getstack(stacknum)->bracket>=bracket && getstack(stacknum)->opsign!=0)
//将本层括号内可以pop的都pop
pop();
break;
case '^':
if(getnextopsign()>POWLEVEL){
push(POW);
result=getnumber();
}
else
{
result=(float)pow((double)result,(double)getnumber());
while(stacknum>0 && getnextopsign()<getlevel(getstack(stacknum)->opsign)
&& getstack(stacknum)->bracket>=bracket) pop();
}
break;
case '!':
if(getnextopsign()>FACTLEVEL){
push(FACT);
result=getnumber();
}
else
{
result=fact((long)result);
while(stacknum>0 && getnextopsign()<getlevel(getstack(stacknum)->opsign)
&& getstack(stacknum)->bracket>=bracket) pop();
}
break;
}
}
if(!error) printf("计算结果:%g\n",result);
}
}
float getnumber()
{
if(point>STRLEN-1) return 0;
char strnum[20];
int n=0;
if(string[point]=='-'){//一开始就是负号
return 0;
}
while(string[point]=='('){
if(string[point+1]=='-'){//负号
point++;
return 0;
}
else if(string[point+1]=='(') push(0);
else break;
}
while((string[point]<'0' || string[point]>'9') && string[point]!='.') point++;
while((string[point]>='0' && string[point]<='9') || string[point]=='.'){
strnum[n++]=string[point++];
if(point>STRLEN-1) break;
}
strnum[n]='\0';
return (float)atof(strnum);
}
char getnextopsign()
{
int p=point;
while(p<=STRLEN-1){
switch(string[p++]){
case '+':
return ADDLEVEL;
case '-':
return SUBLEVEL;
case '*':
return MULLEVEL;
case '/':
return DIVLEVEL;
case '(':
return LEFTLEVEL;
case '^':
return POWLEVEL;
case '!':
return FACT;
case ')':
return 0;
}
}
return 0;
}
void push(char opsign)
{
stack *p=getstack(stacknum);
if(stacknum>0) p=(p->pnext=new stack);
p->bracket=bracket;
if(string[point]=='('){
++bracket;
point++;
}
p->num=result;
p->opsign=opsign;
stacknum++;
}
void pop()
{
stack *p=getstack(stacknum);
switch(p->opsign){
case ADD:
result+=p->num;
break;
case SUB:
result=p->num-result;
break;
case MUL:
result*=p->num;
break;
case DIV:
result=p->num/result;
break;
case POW:
result=(float)pow(p->num,result);
break;
case FACT:
result=fact((long)result);
break;
case 0:
break;
}
if(stacknum>1) delete p;
stacknum--;
}

bool check()//检查表达式的合法性
{
int left=0,right=0;
for(int i=0;i<STRLEN;i++){
if(string[i]<='9' && string[i]>='0')
continue;
switch(string[i]){
case '(':
++right;
break;
case ')':
++left;
break;
case '^':
case '!':
case '+':
case '-':
case '*':
case '/':
case '.':
break;
default:
printf("错误:出现非法字符!\n");
return 0;
}
}
if(right!=left){
printf("错误:括号不匹配!\n");
return 0;
}
return 1;
}

float fact(int n)
{
float r=1;
if(n<=1) return 1;
while(n>1){
r*=n;
--n;
}
return r;
}
int getlevel(int opsign)
{
if(opsign<=2) return 1;
if(opsign<=4) return 2;
return opsign-2;
}
stack * getstack(int n)
{
stack *p=NULL;
if(n==0) return &firststack;
for(int i=0;i<n;i++){
if(i==0) p=&firststack;
else p=p->pnext;
}
return p;
}

tomxh0001 2002-09-06
  • 打赏
  • 举报
回复
我正在写这个东西,还支持自定义函数和自定义对象属性
yang0411 2002-09-05
  • 打赏
  • 举报
回复
先来简单的,不含有变量,如果有含变量的就更好了!
注意:我希望是c语言的,不希望是c++
alidiedie 2002-09-05
  • 打赏
  • 举报
回复
顶楼的问题很关键.
熊主任 2002-09-05
  • 打赏
  • 举报
回复
#include <iostream>
#include <strstrea.h>
#include <stack>

using namespace std;

float MathOP(char ch_operator, float op1, float op2)
{
float result;
switch (ch_operator)
{
case '+':
result = op1 + op2;
break;
case '-':
result = op1 - op2;
break;
case '*':
result = op1 * op2;
break;
case '/':
result = op1 / op2;
break;
default: break;
}
return result;
}

int main(void)
{
char *expr = new char[100];
istrstream ins(expr);

stack<float> COperand;
stack<char> COperator;

float x_operand, op1, op2, op_temp;
char ch_operator;
char ch;

std::cin.getline(expr, 99);

ins >> ch;
while (ch != '=')
{
if (isdigit(ch))
{
ins.putback(ch);
ins >> x_operand;
COperand.push(x_operand);
ins >> ch;
}
else
{
switch(ch)
{
case '+':
case '-':
{
if (!COperator.empty())
{
ch_operator = COperator.top();
if (ch_operator == '*' || ch_operator == '/')
{
COperator.pop();
op2 = COperand.top();
COperand.pop();
op1 = COperand.top();
COperand.pop();
op_temp = MathOP(ch_operator, op1, op2);
COperand.push(op_temp);
}
}
COperator.push(ch);
break;
}
case '*':
case '/':
{
COperator.push(ch);
break;
}
case '(':
{
COperator.push(ch);
break;
}
case ')':
{
ch_operator = COperator.top();
while (ch_operator != '(')
{
COperator.pop();
op2 = COperand.top();
COperand.pop();
op1 = COperand.top();
COperand.pop();
op_temp = MathOP(ch_operator, op1, op2);
COperand.push(op_temp);
ch_operator = COperator.top();
}
COperator.pop();
break;
}
default:
break;
}
ins >> ch;
}
}

while (!COperator.empty())
{
ch_operator = COperator.top();
COperator.pop();
op2 = COperand.top();
COperand.pop();
op1 = COperand.top();
COperand.pop();
op_temp = MathOP(ch_operator, op1, op2);
COperand.push(op_temp);
}

std::cout << "Result is " << COperand.top() << endl;
delete[] expr;
return 0;
}
whfhtt 2002-09-05
  • 打赏
  • 举报
回复
你先告诉我,你的公式里面有没有变量,还是只含常量

33,010

社区成员

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

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