功能描述:
实现计算器混合运算基本功能,包括:( )、+、-、*、/。
功能很简单,但实现起来还是有一定逻辑难度,因为,混合运算需要考虑优先级。
优先级最高的为:()
其次,*、/
最后,+、-
所以在每次运算时,需要排查,先计算优先级高的部分。
为了便于编程,输入的混合表达式,都采用字符串形式,便于处理,不然数值输入更难以处理,区分优先级计算。最后的结果以浮点型输出。
代码如下:
主函数:
void main()
{
char str[100] = "";
gets(str);
printf("result = %f\n",calc(charProcess(str)));
}
计算函数:
double calc(char * str)
{
int i,j=0,k=0,l=0;
char op[100] = "";//符号字符串
char aq[100] = "";//数字字符串
double num[100] = {0};//数字
double res=0;//结果
for(i=0;str[i]!='\0';i++)
{
if(str[i]>='0'&&str[i]<='9'||str[i]=='.')
{
aq[j++]=str[i];
}//将输入的字符串中的数字提取出来
else
{
num[l++]=atof(aq);//数字存入double类型
memset(aq,0,sizeof(aq));//清空aq
op[k++]=str[i];//符号存入op
j=0;
}
}
num[l++]=atof(aq);
op[k]='\0';
//puts(op);
//for(i=0;num[i]!='\0';i++)
//{
// printf("%.2lf\t",num[i]);
//}
//printf("\n");
for(i=0;op[i]!='\0';i++)
{
if(op[i]=='*')
{
for(j=i;op[j]!='\0';j++)
{
op[j]=op[j+1];//符号递进
}
num[i]=num[i]*num[i+1];
for(j=i+1;num[j]!='\0';j++)
{
num[j]=num[j+1];//数字递进
}
i--; //符号前进i要退一
}//乘法运算
if(op[i]=='/')
{
for(j=i;op[j]!='\0';j++)
{
op[j]=op[j+1];
}
num[i]=num[i]/num[i+1];
for(j=i+1;num[j]!='\0';j++)
{
num[j]=num[j+1];
}
i--;
}//除法运算
}
res=num[0];
for(i=0;op[i]!='\0';i++)
{
if(op[i]=='+')
{
res=res+num[i+1];
}
if(op[i]=='-')
{
res=res-num[i+1];//进行加减运算
}
}
//printf("%.2lf\n",res); // 输出结果
return res;
}
核心子函数:
/****************************************************
***函数名称:char* charProcess(char str[])
***函数参数:char* charProcess(char str[]) 输入字符串,返回值为结果
***函数功能:判断混合运算中是否有括号(),如没有不做任何处理,
*** 如有则先将括号中内容处理完后再进行混合运算
***
***
***
****************************************************/
char* charProcess(char str[]) //
{
char flag = 0;
char strTemp[20] = "";
char strTemp2[20] = "";
char strTemp3[100] = "-";
char strTempDes[20] = "";
char strResult[100] = "";
char flagChar = 0;
char flagChar2 = 0;
int i = 0; // 循环变量
int j = 0;
int k = 0;
int n = 0;
int cnt = 0;
int index = 0;
int index1 = 0; // 记录(出现的位置(坐标)
int index2 = 0; // 记录)出现的位置(坐标)
for(i = 0; i<(int)strlen(str); i++)
{
if('(' == str[i])
{
cnt++;
flag++;
}
}
printf("cnt = %d\n",cnt);
if(flag >= 1)
{
for(i=0; i<cnt; i++)
{
for(j = 0; j<(int)strlen(str); j++)
{
if('(' == str[j])
{
index1 = j; // ( 出现的位置记录 取最后一个
}
}
for(j = 0; j<(int)strlen(str); j++)
{
if(')' == str[j])
{
index2 = j; // ) 出现的位置记录 取最后一个
if(index2>index1)
{
break;
}
}
}
for(k = index1+1; k<index2;k++)
{
strTemp[n] = str[k];
n++;
}
strTemp[n] = '\0';
n = 0;
sprintf(strTemp2,"%.2f",calc(strTemp));
puts(strTemp2);
for(k = index1; k<=index2;k++)
{
strTempDes[n] = str[k];
n++;
}
strTempDes[n] = '\0';
n = 0;
str_replace(strResult,str,strTempDes,strTemp2);
strcpy(str,strResult);
puts(str);
memset(strTemp,0,sizeof(strTemp));
memset(strTempDes,0,sizeof(strTempDes));
memset(strTemp2,0,sizeof(strTemp2));
memset(strResult,0,sizeof(strResult));
}
/// 增加处理
str_replace(strResult,str,"+-","-");
strcpy(str,strResult);
str_replace(strResult,str,"--","+");
strcpy(str,strResult);
for(i=0;i<(int)strlen(str)-1;i++)
{
if('*' == str[i] && '-' == str[i+1])
{
flagChar2 = 1;
index = i;
for(j=index;j>=0;j--)
{
if('+' == str[j])
{
str[j] = '-';
break;
}
if('-' == str[j])
{
str[j] = '+';
break;
}
}
continue;
}
if('/' == str[i] && '-' == str[i+1])
{
flagChar2 = 1;
index = i;
for(j=index;j>=0;j--)
{
if('+' == str[j])
{
str[j] = '-';
break;
}
if('-' == str[j])
{
str[j] = '+';
break;
}
}
continue;
}
}
for(i=0;i<(int)strlen(str)-1;i++)
{
if('*' == str[i] && '-' == str[i+1])
{
index = i;
for(j=index;j>=0;j--)
{
if('+' == str[j])
{
flagChar++;
}
if('-' == str[j])
{
flagChar++;
}
}
break;
}
if('/' == str[i] && '-' == str[i+1])
{
index = i;
for(j=index;j>=0;j--)
{
if('+' == str[j])
{
flagChar++;
}
if('-' == str[j])
{
flagChar++;
}
}
break;
}
}
if(0 == flagChar && 0 != flagChar2)
{
strcat(strTemp3,str);
strcpy(str,strTemp3);
}
str_replace(strResult,str,"*-","*");
strcpy(str,strResult);
str_replace(strResult,str,"/-","/");
strcpy(str,strResult);
puts(str);
return str; // 输入字符串有括号
}
else
{
return str; // 字符串中没有括号
}
}
运行效果:
代码如下: