1. 程式人生 > >計算四則混合運算表示式(不用棧)

計算四則混合運算表示式(不用棧)

本程式碼主要實現的功能是對‘+’、‘-’、‘*’、‘/’、‘()‘這五種運算組成的簡單計算。由於本篇程式碼只作原理講解並提供參考,所以整篇程式碼中都使用整型資料,所以不能計算處精確的結果。如果要通過本程式碼實現對錶達式的精確計算,則需要將本原始碼中的資料型別全改為浮點型資料,同時也需要對本原始碼中部分相關函式進行修改。
四則運算中括號優先順序最高,所以本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; }

執行結果截圖如下:
執行結果