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

yang0411 2002-09-05 01:19:06
不需要太复杂,只要含有+、-、*、/、(、)就行
...全文
287 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
  • 打赏
  • 举报
回复
你先告诉我,你的公式里面有没有变量,还是只含常量
知识总结 1 一、整除的性质: 3 二、数的整除特征 3 三、奇偶的性质 4 四、模p运算 4 五、同余的性质 4 六、余数检验 5 七、素数 6 八、素数的检验 7 九、最大公约数 8 十、算术基本定理 9 十一、一些数论的定理 9 十二、二次剩余 9 十三、梅森数 10 十四、完全数 11 十五、费马数 12 十六、完全平方数 12 十七、水仙花数 13 十八、西西弗斯数 13 十九、高度合成数 13 二十、斐波那契数 13 二十一、亲和数 14 二十二、欧拉数 14 二十三、欧拉的其他公式 15 二十四、欧拉方程 15 二十五、勾股数的特点 16 二十六、勾股数系的系和组 17 二十七、勾股数系的性质 17 二十八、二元一次不定方程 18 二十九、中国同余式 18 三十、数列 18 三十一、常识 19 三十二、幻方 19 三十三、克拉茨命题 20 三十三、用牛顿叠代法求高精度倒数 21 三十四、用二分法求解n! 21 三十五、高精度求乘幂 21 三十六、高精度求实数乘幂 22 三十七、高精度求对数 23 三十八、乘法的快速傅立叶转换 23 三十九、FFT 乘法 24 四十、高精度求开方 25 四十一、对原函数进行高精度求解 26 四十二、巴什博奕(Bash Game): 27 四十三、威佐夫博奕(Wythoff Game): 27 四十四、尼姆博奕(Nimm Game): 28 四十五、取火柴游戏 29 四十六、取硬币游戏 30 四十七、分金币 30 四十八、三人行游戏 31 四十九、3个教士和3个土人 31 五十、分酒问题 32 五十一、砝码 33 五十二、杨辉三角 34 五十三、图论的一些定理: 37 五十四、二部图 38 五十五、排列组合问题 39 五十六、计数问题 39 五十七、微积分公式 41 五十八、三角函数公式 43 五十九、空间解析几何和向量代数: 44 六十、多元微积分 44 六十一、多元函数微分法及应用 47 六十二、微分法在几何上的应用: 48 六十三、级数: 49 六十四、微分方程: 52 六十五、数学常用公式 53 六十六、二维图形的周长与面积公式 56 六十七、程序 58

33,027

社区成员

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

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