所有數據都可以用分數來表示,比如整數可以認為分母為1,這樣,所有數據可以這樣保存(數據結構為:)
struct?{
int?z;//分子
int?m;//分母
};
我沒寫過具體的可以計算分數的計算器,下面是加減乘除和括號的計算器源代碼,妳參考壹下,如果看懂了應該不難改,應該是數據結構課程裏堆棧這壹塊的內容。
測試樣例:
輸入:
2*(3+6*(8/2+1))
輸出:
66
#include<stdio.h>#include<string.h>
#include<stdlib.h>
typedef?struct?priority
{
char?symb;
int?pri;
}priority;
priority?kuPriority[7]={{'+',1},{'-',1},{'*',2},{'/',2},{'(',3},{')',3},{'\0',0}};
char?co[100];
char?symbol[100];
int?numb[100];
int?sPoint,nPoint;
int?sHead,nHead;
int?findPri(char?symb)
{
for(int?i=0;i<7;i++)
{
if(kuPriority[i].symb==symb)
return?kuPriority[i].pri;
}
return?-1;
}
int?calc(int?a,int?b,char?symb)
{
switch(symb)
{
case?'+':return?a+b;?
case?'-':return?a-b;
case?'*':return?a*b;?
case?'/':
if(b==0)
{
printf("除數為0\n");
system("pause");
exit(0);
}
else?
{
return?a/b;
}
}
}
void?f()
{
int?len;
int?i,a;
int?flag,negative;
scanf("%s",co);//scanf能解決行末空格問題,gets不行?
len=strlen(co);
sPoint=nPoint=0;
//棧的準備
int?sum=0;
flag=-1;
negative=1;
for(i=0;i<len;i++)
{
if(i==0?&&?co[0]=='-')
{
negative=-1;
continue;
}
if(co[i]<='9'?&&?co[i]>='0')
{
if(i!=0)
{
if(co[i-1]==')')
{
printf("不合法:右括號後面不能是數字\n");
system("pause");
return;
}
}
flag=0;
sum=sum*10+co[i]-'0';
if(i==len-1)
{
numb[nPoint++]=sum*negative;
sum=0;
negative=1;
}
else?if(!(co[i+1]<='9'?&&?co[i+1]>='0'))
{
numb[nPoint++]=sum*negative;
sum=0;
negative=1;
}
}
else?//是運算符?
{
if(co[i]=='('?||co[i]==')')
{
if(co[i]=='('&&flag==0)
{
printf("不合法:左括號前面不能是數字\n");
system("pause");
return;
}
else?if(co[i]==')'&&flag!=0&&co[i-1]!=')')?
{
printf("不合法:右括號前面不能是非右括號運算符\n")?;
system("pause");
return;
}
flag=2;
}
else//不是括號?
{
if(sPoint!=0)
{
if(co[i-1]=='('&&co[i]!='(')//非左括號運算符前面不能是左括號
{
if(co[i]=='-')//負號
{
negative=-1;
continue;?
}?
else?if(co[i]=='+')
{
continue;
}
if(co[i]!='(')
{
printf("不合法:左括號後面不能有非括號運算符\n")?;
system("pause");
return;
?}?
}?
}
if(flag==1)
{
printf("不合法:運算符前後不能有除括號以外的運算符\n")?;
system("pause");
return;
}
flag=1;?
}
symbol[sPoint++]=co[i];
}
}
//棧準備完畢?
a=0;?
for(i=0;i<=sPoint;i++)
{
if(symbol[i]=='(')
{
a++;
}
else?if(symbol[i]==')')
{
a--;
}
if(a==-1)
{
printf("括號符不匹配\n");
system("pause");
return;
}
}
if(a!=0)
{
printf("括號符不匹配\n");
system("pause");
return;
}
//檢查匹配括號完畢?
if(sPoint!=0)
{
sPoint--;
}
if(nPoint!=0)
{
nPoint--;
}
//開始計算
int?formal,current;
sHead=-1;
nHead=0;
if(symbol[0]=='(')
{
nHead--;
}
while(1)
{
sHead++;
if(nPoint==0)
{
printf("%d",numb[0]);
break;
}
if(sHead==0)
{
continue;
}
formal=findPri(symbol[sHead-1]);
current=findPri(symbol[sHead]);
if(formal==-1?||?current==-1)
{
printf("非法字符\n");
system("pause");
return;
}
if(symbol[sHead]!='(')//非左括號
{
nHead++;?
}?
if(current==3)?//括號
{
if(symbol[sHead]=='(')
{
continue;
}
else
{
//消掉括號?
if(symbol[sHead-1]!='(')
{
numb[nHead-1]=calc(numb[nHead-1],numb[nHead],symbol[sHead-1]);
for(a=nHead;a<nPoint;a++)
{
numb[a]=numb[a+1];
}
numb[a]=0;
nPoint--;
for(a=sHead-1;a<sPoint;a++)
{
symbol[a]=symbol[a+1];
}
symbol[sPoint]='\0';
sPoint--;
nHead=0;
sHead=-1;
if(symbol[0]=='(')
{
nHead--;
}
continue;//重新開始?
}
else
{
for(a=sHead-1;a<=sPoint-2;a++)
{
symbol[a]=symbol[a+2];
}
symbol[sPoint-1]=symbol[sPoint]='\0';
sPoint-=2;
sHead=-1;
nHead=0;
if(symbol[0]=='(')
{
nHead--;
}
continue;//重新開始?
}
}
}?
if(formal<current)
{
continue;
}
else?if(formal>=current?&&?formal!=3)//且不是括號?
{
numb[nHead-1]=calc(numb[nHead-1],numb[nHead],symbol[sHead-1]);
for(a=nHead;a<nPoint;a++)
{
numb[a]=numb[a+1];
}
numb[nPoint]=0;
nPoint--;
for(a=sHead-1;a<sPoint;a++)
{
symbol[a]=symbol[a+1];
}
symbol[sPoint]='\0';
sPoint--;
sHead=-1;
nHead=0;
if(symbol[0]=='(')
{
nHead--;
}
continue;?
}
}
}
int?main()
{
while(1)
{
f();
printf("\n");
?}?
}