如何用栈设计个C语言计算器,高手请跟我说说算法,特别是那些括号和乘法的实现,谢谢

能给些算法加程序那个更好
2025-02-26 18:04:33
推荐回答(5个)
回答1:

支持 加减乘除括号负数开根乘方
#include
#include
#include

double jisuan(char a[])
{
int i=1,j,k,m,cnt=0,t1=0,t2=0,t3=0;
char nibo[50],zhan2[50];
double x,n,l,z=0,zhan3[50];
typedef struct
{
double d1;

int d2;
}dd;
typedef struct
{
dd data[50];
int top;
}zhan1;
zhan1 *shu;
shu=(zhan1 *)malloc(sizeof(zhan1));
shu->top=0;
while(a[i]!='\0')
{
if(a[i]>='0'&&a[i]<='9')
{
z=0;
j=i+1;
while(a[j]>='0'&&a[j]<='9')
{j++;}
j--;
for(k=i;k<=j;k++)
{
z=z*10+a[k]-'0';
}
j=j+1;
x=z;
if(a[j]=='.')
{
l=1;
i=j+1;
j=i+1;
while(a[j]>='0'&&a[j]<='9')
{j++;}
j--;
for(k=i;k<=j;k++)
{
n=pow(0.1,l);
l=l+1;
x=x+n*(a[k]-'0');
}
i=j+1;
}
else i=j;
shu->data[++shu->top].d1=x;
shu->data[shu->top].d2=++cnt;
nibo[++t1]='0'+shu->data[shu->top].d2;
nibo[t1+1]='\0';
}
else if(a[i]=='(')
{
zhan2[++t2]=a[i];
i++;
}
else if(a[i]==')')
{
j=t2;
while(zhan2[j]!='(')
{
nibo[++t1]=zhan2[j];
nibo[t1+1]='\0';
j--;
}
t2=j-1;
i++;
}
else if(a[i]=='+')
{
while(t2>0&&zhan2[t2]!='(')
{
nibo[++t1]=zhan2[t2];
nibo[t1+1]='\0';
t2--;
}
zhan2[++t2]=a[i];
i++;
}
else if(a[i]=='-')
{
if(a[i-1]=='$')
{
a[0]='0';
i=0;
}
else if(a[i-1]=='(')
{
a[i-1]='0';
a[i-2]='(';
i=i-2;
t2--;
}
else
{
while(t2>0&&zhan2[t2]!='(')
{
nibo[++t1]=zhan2[t2];
nibo[t1+1]='\0';
t2--;
}
zhan2[++t2]=a[i];
i++;
}
}
else if(a[i]=='*'||a[i]=='/')
{
while(zhan2[t2]=='*'||zhan2[t2]=='/'||zhan2[t2]=='^'||zhan2[t2]=='#')
{
nibo[++t1]=zhan2[t2];
nibo[t1+1]='\0';
t2--;
}
zhan2[++t2]=a[i];
i++;
}
else if(a[i]=='^'||a[i]=='#')
{
while(zhan2[t2]=='^'||zhan2[t2]=='#')
{
nibo[++t1]=zhan2[t2];
nibo[t1+1]='\0';
t2--;
}
zhan2[++t2]=a[i];
i++;
}
}
while(t2>0)
{
nibo[++t1]=zhan2[t2];
nibo[t1+1]='\0';
t2--;
}

j=1;t3=0;
while(j<=t1)
{
if(nibo[j]>='0'&&nibo[j]!='^'&&nibo[j]!='#')//
{
for(i=1;i<=shu->top;i++)
{
if((int)(nibo[j]-'0')==shu->data[i].d2)
{
m=i;
break;
}
}
zhan3[++t3]=shu->data[m].d1;

}
else if(nibo[j]=='+')
{
zhan3[t3-1]=zhan3[t3-1]+zhan3[t3];
t3--;

}
else if(nibo[j]=='-')
{
zhan3[t3-1]=zhan3[t3-1]-zhan3[t3];
t3--;
}
else if(nibo[j]=='*')
{
zhan3[t3-1]=zhan3[t3-1]*zhan3[t3];
t3--;
}
else if(nibo[j]=='/')
{
zhan3[t3-1]=zhan3[t3-1]/zhan3[t3];
t3--;
}
else if(nibo[j]=='^')
{
zhan3[t3-1]=pow(zhan3[t3-1],zhan3[t3]);
t3--;
}
else if(nibo[j]=='#')
{
zhan3[t3]=sqrt(zhan3[t3]);
}
j++;

}

return zhan3[t3];

}
void main()
{
for(;;)
{
char x,a[50];
double jieguo;
int i=0;
a[0]='$';
printf("#表示开方,^表示乘方(支持负数)\n");
printf("请输入表达式,退出请输入q:\n\n");
scanf("%c",&x);
if(x=='q') break;
while(x!='\n')
{
a[++i]=x;
scanf("%c",&x);
}
a[i+1]='\0';
jieguo=jisuan(a);
printf("\n");
printf("结果为:%lf",jieguo);
printf("\n\n\n\n\n");
}
}

回答2:

一般来说的话,涉及到括号匹配的问题,用两个栈,一个接收数字,一个接受运算符号,之前定义运算符号的优先级
然后边读入边判断优先级,考虑是否要压栈还是如栈...

回答3:

一个完整的表达式计算程序,用栈数据结构实现表达式求值
能够计算:加、减、乘、除、括号

要求表达式以 #结束

#define N 200
#include
#include

typedef struct{
int top;
double array[N];
}NumStack;
typedef struct{
int top;
char array[N];
}OpStack;
int Cint(char mychar){
return (mychar-48);
}
void PushNum(NumStack *numstack,double num){
numstack->top++;
numstack->array[numstack->top-1]=num;
}
void PopNum(NumStack *numstack,double *num){
*num=numstack->array[numstack->top-1];
numstack->top--;
}
void PushOp(OpStack *opstack,char op){
opstack->top++;
opstack->array[opstack->top-1]=op;
}
void PopOp(OpStack *opstack,char *op){
*op=opstack->array[opstack->top-1];
opstack->top--;
}
double Calc(double a,double b,char c){
double result;
switch(c){
case '+':result=a+b;break;
case '-':result=a-b;break;
case '*':result=a*b;break;
case '/':result=a/b;break;
}
return result;
}
char Priority(char y,char x){
char priority='<';
switch(x){
case '+':
case '-':if(y=='(' || y=='#')priority='>';break;
case '*':
case '/':if(y=='(' || y=='#'|| y=='+' || y=='-')priority='>';break;
case '(':priority='>';break;
case ')':if(y=='(')priority='=';break;
case '#':if(y=='#')priority='=';break;
default:priority='E';
}
return priority;
}
void Process(NumStack *numstack,OpStack *opstack,char x){
double a,b;char c;
static double tempnum=0.00000000;static int len=10;static int dot=0,flags=0;
if(isdigit(x) || x=='.'){
if(x=='.')dot=1;
else{
if(dot==0)
tempnum=tempnum*10+Cint(x);
else{
tempnum=tempnum+(double)Cint(x)/len;
len*=10;
}
}
}
else{
if(flags==0 && x!='('){PushNum(numstack,tempnum);tempnum=0.00000000;len=10;dot=0;}
switch(Priority(opstack->array[opstack->top-1],x)){
case '>':PushOp(opstack,x);flags=0;break;
case '<':
PopOp(opstack,&c);
PopNum(numstack,&b);
PopNum(numstack,&a);
PushNum(numstack,Calc(a,b,c));flags=1;
Process(numstack,opstack,x);break;
case '=':PopOp(opstack,&c);flags=1;break;
default:printf("Wrong Express!");exit(0);
}
}
}

int main()
{
NumStack numstack;OpStack opstack;char s[N];int i=0;
numstack.top=0;opstack.top=0;
PushOp(&opstack,'#');
printf("\nEnter your expression and end it with #:");scanf("%s",s);
for(i=0;iProcess(&numstack,&opstack,s[i]);
printf("The result is %f",numstack.array[numstack.top-1]);
}

再送一个检查括号匹配的小函数,只检查 小括号()

int CheckBrackets(const char* szSrc)
{
int i;
int len;
int count;

if (NULL == szSrc)
return 1;

count = 0;
len = strlen(szSrc);
for (i = 0; i < len; i++)
{
if ('(' == szSrc[i])
{
count++;
if (i < len - 1)
{
if (')' == szSrc[i + 1])
{
return 0;
}
}
}
else if (')' == szSrc[i])
{
count--;
}
if (count < 0)
return 0;
}

return (0 == count) ? 1 : 0;
}

回答4:

#define N 200
#include
#include
#include
#include "process.h"
typedef struct{
int top;
double array[N];
}NumStack;
typedef struct{
int top;
char array[N];
}OpStack;
int Cint(char mychar){
return (mychar-48);
}
void PushNum(NumStack *numstack,double num){
numstack->top++;
numstack->array[numstack->top-1]=num;
}
void PopNum(NumStack *numstack,double *num){
*num=numstack->array[numstack->top-1];
numstack->top--;
}
void PushOp(OpStack *opstack,char op){
opstack->top++;
opstack->array[opstack->top-1]=op;
}
void PopOp(OpStack *opstack,char *op){
*op=opstack->array[opstack->top-1];
opstack->top--;
}
double Calc(double a,double b,char c){
double result;
switch(c){
case '+':result=a+b;break;
case '-':result=a-b;break;
case '*':result=a*b;break;
case '/':result=a/b;break;
}
return result;
}
char Priority(char y,char x){
char priority='<';
switch(x){
case '+':
case '-':if(y=='(' || y=='#')priority='>';break;
case '*':
case '/':if(y=='(' || y=='#'|| y=='+' || y=='-')priority='>';break;
case '(':priority='>';break;
case ')':if(y=='(')priority='=';break;
case '#':if(y=='#')priority='=';break;
default:priority='E';
}
return priority;
}
void Process(NumStack *numstack,OpStack *opstack,char x){
double a,b;char c;
static double tempnum=0.00000000;static int len=10;static int dot=0,flags=0;
if(isdigit(x) || x=='.'){
if(x=='.')dot=1;
else{
if(dot==0)
tempnum=tempnum*10+Cint(x);
else{
tempnum=tempnum+(double)Cint(x)/len;
len*=10;
}
}
}
else{
if(flags==0 && x!='('){PushNum(numstack,tempnum);tempnum=0.00000000;len=10;dot=0;}
switch(Priority(opstack->array[opstack->top-1],x)){
case '>':PushOp(opstack,x);flags=0;break;
case '<':
PopOp(opstack,&c);
PopNum(numstack,&b);
PopNum(numstack,&a);
PushNum(numstack,Calc(a,b,c));flags=1;
Process(numstack,opstack,x);break;
case '=':PopOp(opstack,&c);flags=1;break;
default:printf("Wrong Express!");exit(0);
}
}
}

int main()
{
NumStack numstack;OpStack opstack;char s[N];int i=0;
numstack.top=0;opstack.top=0;
PushOp(&opstack,'#');
printf("\nEnter your expression and end it with #:");scanf("%s",s);
for(i=0;iProcess(&numstack,&opstack,s[i]);
printf("The result is %f",numstack.array[numstack.top-1]);
}

回答5:

参考编程原理