計算四則混合運算表示式(不用棧)
阿新 • • 發佈:2019-02-13
本程式碼主要實現的功能是對‘+’、‘-’、‘*’、‘/’、‘()‘這五種運算組成的簡單計算。由於本篇程式碼只作原理講解並提供參考,所以整篇程式碼中都使用整型資料,所以不能計算處精確的結果。如果要通過本程式碼實現對錶達式的精確計算,則需要將本原始碼中的資料型別全改為浮點型資料,同時也需要對本原始碼中部分相關函式進行修改。 四則運算中括號優先順序最高,所以本Calc函式中先查詢字串中是否有括號,若有則將括號中的內容遞迴呼叫Calc函式。優先順序其次的是乘法和除法,所以在Calc函式中會先對乘號和除號進行查詢,優先計算乘號和除號的結果。優先順序再其次的是加法和減法,在Calc函式中計算完乘除之後,就會開始查詢字串中的加號和減號,並對結果進行計算。優先順序最低的是負號。 由於本實現不使用棧,所以只能在字串中查詢運算子,當找到當前優先順序最高的運算子之後,對其兩端資料進行計算,然後將該處字元全部變為空格符,再將運算後的結果插入其中,然後去掉整個字串中的所有空格符。當計算結果為負數時,為了避免負號與減號的衝突,在運算過程中負數兩端使用<>以示區別,<3> = -3。
/*
*沒有使用棧或佇列實現的對數學表示式進行計算的計算工具
*功能:
*實現對一般的四則混合運算的求解
*
*
*
* Author: StoryMonster
*last change date: 2016/6/27
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int StoreShortExp(char *str,int index,int len); //處理改變後的字串
static int Calc(char *str,int len); //計算
static void BackMove(char *str,int len); //字串向後移動一位
static void InsertDataToString(int data,char *str,int index); //向字串指定位置插入數字
static int ChangeStringToInt(char *str,int len); //把字串轉化為整數
static int DeleteCharactor(char *str,int len,char ch); //在字串中刪除指定字元
static void PreDeal(char *str,int len); //對輸入字串進行預處理
int DeleteCharactor(char *str,int len,char ch)
{
int i,j;
for(i=0;i<len;i++)
{
if(str[i] == ch)
{
for(j=i+1;j<len;j++)
{
str[j-1] = str[j];
}
i--;
str[--len] = '\0';
}
}
return len;
}
int ChangeStringToInt(char *str,int len)
{
int temp = 0,i=0;
while(i<len)
{
temp = temp * 10 + str[i] - '0';
i++;
}
return temp;
}
void InsertDataToString(int data,char *str,int index)
{
int arr[10] = {0},i=0;
int FuShu = 0;
if(data<0)
{
str[index++] = '<';
data*=-1;
FuShu = 1;
}
while(data>0)
{
arr[i++] = data%10;
data/=10;
}
while(i>0)
{
str[index++]=arr[--i] + '0';
}
if(FuShu) str[index++] = '>';
}
int Calc(char *str,int len)
{
int i,j,pp = 0;
int StartIndex = 0, EndIndex = 0;
while(1)
{
pp=0;
for(i=0;i<len;i++)
{
if(str[i] == '(') StartIndex = i;
if(str[i] == ')')
{
pp=1;
EndIndex = i;
char arr[100] ={0};
int n = 0;
for(int k=StartIndex+1;k<=EndIndex-1;k++)
{
arr[n++] = str[k];
}
arr[n] = '\0';
int result = Calc(arr,n);
for(j=StartIndex;j<=EndIndex;j++)
{
str[j] = ' ';
}
InsertDataToString(result,str,StartIndex);
len = DeleteCharactor(str,len,' ');
break;
}
}
if(pp == 0) break;
}
int result = 0;
for(i=0;i<len;i++)
{
if(str[i] == '*'|| str[i] == '/')
{
result = StoreShortExp(str,i,len);
len = DeleteCharactor(str,len,' ');
i = -1;
}
}
for(i=0;i<len;i++)
{
if(str[i] == '+'|| str[i] == '-')
{
result = StoreShortExp(str,i,len);
len = DeleteCharactor(str,len,' ');
i=-1;
}
}
if(str[0] == '<' && str[len-1] == '>')
{
result = ChangeStringToInt(&str[1],len-2);
result *= -1;
for(i=0;i<len;i++)
{
str[i] = ' ';
}
InsertDataToString(result,str,0);
len = DeleteCharactor(str,len,' ');
}
return result;
}
int StoreShortExp(char *str,int index,int len)
{
int i,j,data1=0,data2=0;
char op = str[index];
int StartIndex = 0,EndIndex = 0;
int FuShu = 0;
EndIndex = index-1;
str[index] = ' ';
StartIndex = 0;
if(str[EndIndex] == '>')
{
EndIndex--;
for(j=EndIndex;j>=0;j--)
{
if(str[j] == '<')
{
StartIndex = j+1;
FuShu = 1;
break;
}
}
}
else
{
i = EndIndex;
while(str[i]<='9'&&str[i]>='0') i--;
StartIndex = i+1;
}
if(i != EndIndex)
{
if(FuShu) data1 = (-1)*ChangeStringToInt(&str[StartIndex],EndIndex-StartIndex+1);
else data1 = ChangeStringToInt(&str[StartIndex],EndIndex-StartIndex+1);
if(FuShu) {StartIndex--;EndIndex++;}
for(j=StartIndex;j<=EndIndex;j++)
{
str[j] = ' ';
}
}
int StartStartIndex = StartIndex;
StartIndex = index+1;
EndIndex = len-1;
FuShu = 0;
if(str[StartIndex] == '<')
{
StartIndex++;
FuShu = 1;
for(i = StartIndex;i<len;i++)
{
if(str[i] == '>')
{
EndIndex = i-1;
}
}
}
else
{
i = StartIndex;
while(str[i] <='9'&&str[i]>='0') i++;
EndIndex = i-1;
}
if(i != StartIndex)
{
if(FuShu) data2 = (-1)*ChangeStringToInt(&str[StartIndex],EndIndex-StartIndex+1);
else data2 = ChangeStringToInt(&str[StartIndex],EndIndex-StartIndex+1);
if(FuShu) {StartIndex--;EndIndex++;}
for(j=StartIndex;j<=EndIndex;j++)
{
str[j] = ' ';
}
}
int result = 0;
switch(op)
{
case '+':result = data1+data2;break;
case '-':result = data1-data2;break;
case '*':result = data1*data2;break;
case '/':result = data1/data2;break;
}
InsertDataToString(result,str,StartStartIndex);
return result;
}
void BackMove(char *str,int len)
{
for(int i = len;i>0;i--)
{
str[i] = str[i-1];
}
}
void PreDeal(char *str,int len)
{
int i = 0;
len = DeleteCharactor(str,len,' ');
while(i<len)
{
if(str[i] == '-')
{
if(i == 0)
{
str[i] = '<';
}
else
{
if(str[i-1] > '9' || str[i-1] < '0')
{
str[i] = '<';
}
else
{
i++;
continue;
}
}
for(int j=i+1;j<len;j++)
{
if(str[j] > '9' || str[j] < '0')
{
BackMove(&str[j],len-j);
str[j] = '>';
len++;
break;
}
}
}
i++;
}
}
int main()
{
while(1)
{
char Exp[100] = {0};
printf("input expression:");
gets(Exp);
PreDeal(Exp,strlen(Exp));
printf("the answer is: %d\n",Calc(Exp,strlen(Exp)));
}
return 0;
}
執行結果截圖如下: