本代码主要实现的功能是对‘+’、‘-’、‘*’、‘/’、‘()‘这五种运算组成的简单计算。由于本篇代码只作原理讲解并提供参考,所以整篇代码中都使用整型数据,所以不能计算处精确的结果。如果要通过本代码实现对表达式的精确计算,则需要将本源码中的数据类型全改为浮点型数据,同时也需要对本源码中部分相关函数进行修改。
四则运算中括号优先级最高,所以本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;
}
运行结果截图如下: