用递归来实现带括号的C语言实数四则运算

系本人原创,转载请注明地址https://blog.csdn.net/coder_what/article/details/82682366

本人大一菜鸡一枚,借着老师课程设计的机会,用C语言写了一个四则运算

(即输入一个字符串,返回它计算的结果)

实现的功能或者难点有以下几个:

1. 连续运算

2. 识别数字和运算符以及括号

3. 乘法/除法和括号优先级的问题

4. 把带小数的字符串转换成数字

对于第一个问题:

用一个while循环,当字符串到结尾时结束循环就OK了

对于第二个问题:

这里用的是if和for语句,注意一定要加单引号,如:

	for(;s[i]<='9'&&s[i]>='0';i++)

对于第三个问题:

先算乘法和除法,把算完的结果储存在一个float类型的数组里面,把遇到的加号和减号放在一个字符数组里,最后再算加减法。当遇到括号时,运用递归的思想,先算出最里面的括号,依次算外面的,再进行下一组运算

这里其实还有一个问题,就是如何找到最里面的括号,又如何准确的识别并保存括号里面的数呢?当出现括号内出现多个平级括号又该怎么处理呢?

我用的方法就是用count_r和count_l计算左右两边括号的数目,从左边第一个括号开始,当右边的括号大于左边的括号时,就证明已经把里面的括号遍历完毕,就可以愉快的计算啦。

对于第四个问题:

计算小数点前的数时:

for(;s[i]<='9'&&s[i]>='0';i++)
	x=(s[i]-'0')+x*10;

计算小数点后面的数时:

if(s[i]=='.')
	for(i++;s[i]<='9'&&s[i]>='0';i++)
	{
		y=(s[i]-'0')*0.1*tem_y+y;
		tem_y*=0.1;
	}

最后结果就是x+y了。

需要注意的是x和y在每次计算前必须重新赋值为零,且tem_y必须重新赋值为1

先放上头文件和全局变量

//头文件 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//全局变量
int i,n,x,sum,y;
char s[80];
char s1[80];
char s2[80];

逐步实现功能,先放一个连续整数加法的源码:

	x=0,sum=0,i=0;
	printf("\n\t\tPlease input the numbers which you want to calculate:");
	scanf("%s",s);
	while(s[i]!='\0')
	{
		for(;s[i]<='9'&&s[i]>='0';i++)
			x=(s[i]-'0')+x*10;
		if(s[i]=='+'||s[i]=='\0')
		{
			i++;
			sum+=x;
			x=0;
		}
		else
		{
			printf("\n\t\tThe operator is error!\n");
			system("pause");
			return;
		}
	}
	printf("\t\t\t %s = %d\n",&s,sum);

当进行除法时,要考虑除数为零的问题,并且必须要先计算第一个数,放一个连续整数除法的源码:

	float sum,x=0;
	i=0;
	printf("\n\t\tPlease input the numbers which you want to calculate:");
	scanf("%s",s);
	for(i=0;s[i]<='9'&&s[i]>='0';i++)
		x=(s[i]-'0')+x*10;
	sum=x;
	while(1)
	{
		x=0;
		if(s[i]=='\0')
			break;
		if(s[i]!='/')
		{
			printf("\n\t\tThe operator is error!\n");
			system("pause");
			return;
		}
		i++;
		for(;s[i]<='9'&&s[i]>='0';i++)
			x=(s[i]-'0')+x*10;
		if(x!=0)
			sum=sum/x;
		else
		{
			printf("\n\t\tThe operator is error!\n");
			system("pause");
			return;
		}
	}
	printf("\t\t%s = %.2lf\n",&s,sum);

现在可以试试整数不带括号的四则运算了:

	float number[80],x;
	int len,j=0,k=0;
	char operat[80];
	printf("\n\t\tPlease input the numbers which you want to calculate:");
	scanf("%s",s);
	len=strlen(s);
	for(i=0;s[i]<='9'&&s[i]>='0';i++)
		x=(s[i]-'0')+x*10;
	number[j]=x;
	j++;
	for(;i<len;)
	{
		if(s[i]=='*')
		{ 
			x=0;
			for(i++;s[i]<='9'&&s[i]>='0';i++)
				x=(s[i]-'0')+x*10;
			number[j]=x;
			number[j-1]=number[j-1]*number[j];
		}
		if(s[i]=='/')
		{ 
			x=0;
			for(i++;s[i]<='9'&&s[i]>='0';i++)
				x=(s[i]-'0')+x*10;
			number[j]=x;
			if(number[j]==0)
			{
				printf("\n\t\tThe operator is error!\n");
				system("pause");
				return;
			}
			number[j-1]=number[j-1]/number[j];
		}	
		if(s[i]=='+'||s[i]=='-')
		{
			operat[k]=s[i];
			k++;
			x=0;
			for(i++;s[i]<='9'&&s[i]>='0';i++)
				x=(s[i]-'0')+x*10;
			number[j]=x;
			j++;
		}
	}
	for(i=0;i<k+j;i++)
	{		
		if(operat[i] == '+')
		{
			number[0] += number[i+1];
			continue;

		}
		if(operat[i]=='-')
		{
			number[0] -= number[i+1];
			continue;
		}
	}
	printf("\t\t\t %s = %.2f\n",&s,number[0]);

要注意乘法和除法中的 number[j-1]=number[j-1]*number[j];

因为是直接算出来,所以就代替了前一个数

来试试带一个括号的整数运算,此处需要加一个辅助函数(基于主函数)

int main()
{ 
	float number[80],x=0;
	int len,j=0,k=0,l,tem_j,tem_k,tem_i;
	char operat[80],s1[80];
	printf("\n\t\tPlease input the numbers which you want to calculate:");
	scanf("%s",s);
	len=strlen(s);
	if(s[0]=='(')
	{
		for(i=1,l=0;s[i]!=')';i++,l++)
			s1[l]=s[i];
		s1[l]='\0';
		tem_j=j;tem_k=k;tem_i=i;
		number[tem_j]=mixmodel(s1);
		j=tem_j;
		k=tem_k;
		i=++tem_i;
	} 
	else
	{
		i=0;
		for(;s[i]<='9'&&s[i]>='0';i++)
			x=(s[i]-'0')+x*10;
		number[j]=x;
	}	
	j++;
	for(;i<len;)
	{
		if(s[i]=='*')
		{ 
			if(s[i+1]=='(')	
			{
				for(i+=2,l=0;s[i]!=')';l++,i++)
					s1[l]=s[i];
				s1[i]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=mixmodel(s1);
				i=++tem_i;
				j=tem_j;k=tem_k;			
			}
			else
			{
				x=0;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				number[j]=x;
			}	
			number[j-1]=number[j-1]*number[j];
		}
		if(s[i]=='/')
		{ 
			if(s[i+1]=='(')	
			{
				for(i+=2,l=0;s[i]!=')';i++,l++)
					s1[l]=s[i];
				s1[l]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=mixmodel(s1);
				i=++tem_i;
				j=tem_j;k=tem_k;				
			}
			else
			{
				x=0;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				number[j]=x;
			}
			if(number[j]==0)
			{
				printf("\n\t\tThe operator is error!\n");
				system("pause");
				return 0;
			}
			number[j-1]=number[j-1]/number[j];
		}	
		if(s[i]=='+'||s[i]=='-')
		{
			operat[k]=s[i];
			k++;
			if(s[i+1]=='(')	
			{
				for(i+=2,l=0;s[i]!=')';i++,l++)
					s1[l]=s[i];
				s1[l]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=mixmodel(s1);
				i=++tem_i;
				j=++tem_j;k=tem_k;				
			}
			else
			{
				x=0;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				number[j]=x;
				j++;
			}
		}
	}
	for(i=0;i<j+k;i++)
	{		
		if(operat[i] == '+')
		{
			number[0] += number[i+1];
			continue;

		}
		if(operat[i]=='-')
		{
			number[0] -= number[i+1];
			continue;
		}
	}
	printf("\t\t\t %s = %.2f\n",&s,number[0]);
	return 0;
	
}
float mixmodel(char*s1)
{
	float number[80],x=0;
	int len,j=0,k=0;
	char operat[80];
	len=strlen(s1);
	for(i=0;s1[i]<='9'&&s1[i]>='0';i++)
		x=(s1[i]-'0')+x*10;
	number[j]=x;
	j++;
	for(;i<len;)
	{
		if(s1[i]=='*')
		{ 
			x=0;
			for(i++;s1[i]<='9'&&s1[i]>='0';i++)
				x=(s1[i]-'0')+x*10;
			number[j]=x;
			number[j-1]=number[j-1]*number[j];
		}
		if(s1[i]=='/')
		{ 
			x=0;
			for(i++;s1[i]<='9'&&s1[i]>='0';i++)
				x=(s1[i]-'0')+x*10;
			number[j]=x;
			if(number[j]==0)
			{
				printf("\n\t\tThe operator is error!\n");
				system("pause");
				return 0;
			}
			number[j-1]=number[j-1]/number[j];
		}	
		if(s1[i]=='+'||s1[i]=='-')
		{
			operat[k]=s1[i];
			k++;
			x=0;
			for(i++;s1[i]<='9'&&s1[i]>='0';i++)
				x=(s1[i]-'0')+x*10;
			number[j]=x;
			j++;
		}
	}
	for(i=0;i<k+j;i++)
	{		
		if(operat[i] == '+')
		{
			number[0] += number[i+1];
			continue;

		}
		if(operat[i]=='-')
		{
			number[0] -= number[i+1];
			continue;
		}
	}
	return number[0];

tem_i,tem_j,tem_k分别是用来暂时储存i,j,k的数值的

最后放大招,试试带多级括号的实数四则运算吧:

int main()
{ 
	float number[80],x=0,y=0,tem_y=1;
	int len,i=0,j=0,k=0,l=0,count_r=0,count_l=0,tem_j,tem_k,tem_i;
	char operat[80],s[80],s1[80];
	printf("Please input the numbers which you want to calculate:");
	scanf("%s",s);
	len=strlen(s);
	if(s[0]=='(')
	{
		while(1)
		{
			i++;
			if(s[i]=='(')
				count_l++;
			s1[l]=s[i];			
			l++;
			if(s[i]==')')
				count_r++;
			if(s[i]==')'&&(count_l<count_r||count_l==0))
				break;			
		}
		s1[l-1]='\0';
		tem_j=j;tem_k=k;tem_i=i;
		number[tem_j]=aux(s1);
		j=tem_j;
		k=tem_k;
		i=++tem_i;
	} 
	else
	{
		i=0;
		for(;s[i]<='9'&&s[i]>='0';i++)
			x=(s[i]-'0')+x*10;
		if(s[i]=='.')
			for(i++;s[i]<='9'&&s[i]>='0';i++)
			{
				y=(s[i]-'0')*0.1*tem_y+y;
				tem_y*=0.1;
			}	
		number[j]=x+y;
	}	
	j++;
	for(;i<len;)
	{
		if(s[i]=='*')
		{ 
			if(s[i+1]=='(')	
			{
				i++;
				l=0;
				count_l=count_r=0;
				while(1)
				{
					i++;
					if(s[i]=='(')
						count_l++;
					s1[l]=s[i];			
					l++;
					if(s[i]==')')
						count_r++;
					if(s[i]==')'&&(count_l<count_r||count_l==0))
						break;			
				}
				s1[l-1]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=aux(s1);
				j=tem_j;
				k=tem_k;
				i=++tem_i;			
			}
			else
			{
				x=0;y=0;tem_y=1;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				if(s[i]=='.')
					for(i++;s[i]<='9'&&s[i]>='0';i++)
					{
						y=(s[i]-'0')*0.1*tem_y+y;
						tem_y*=0.1;
					}
				number[j]=x+y;
			}	
			number[j-1]=number[j-1]*number[j];
		}
		if(s[i]=='/')
		{ 
			if(s[i+1]=='(')	
			{
				i++;
				l=0;
				count_l=count_r=0;
				while(1)
				{
					i++;
					if(s[i]=='(')
						count_l++;
					s1[l]=s[i];			
					l++;
					if(s[i]==')')
						count_r++;
					if(s[i]==')'&&(count_l<count_r||count_l==0))
						break;
				}
				s1[l-1]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=aux(s1);
				j=tem_j;
				k=tem_k;
				i=++tem_i;			
			}
			else
			{
				x=0;y=0;tem_y=1;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				if(s[i]=='.')
				for(i++;s[i]<='9'&&s[i]>='0';i++)
				{
					y=(s[i]-'0')*0.1*tem_y+y;
					tem_y*=0.1;
				}
				number[j]=x+y;
			}
			if(number[j]==0)
			{
				printf("\n\t\tThe operator is error!\n");
				system("pause");
				return 0;
			}
			number[j-1]=number[j-1]/number[j];
		}	
		if(s[i]=='+'||s[i]=='-')
		{
			operat[k]=s[i];
			k++;
			if(s[i+1]=='(')	
			{
				i++;
				l=0;
				count_l=count_r=0;
				while(1)
				{
					i++;
					if(s[i]=='(')
						count_l++;
					s1[l]=s[i];			
					l++;
					if(s[i]==')')
						count_r++;
					if(s[i]==')'&&(count_l<count_r||count_l==0))
						break;
				}
				s1[l-1]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=aux(s1);
				j=++tem_j;
				k=tem_k;
				i=++tem_i;			
			}
			else
			{
				x=0;y=0;tem_y=1;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				if(s[i]=='.')
				for(i++;s[i]<='9'&&s[i]>='0';i++)
				{
					y=(s[i]-'0')*0.1*tem_y+y;
					tem_y*=0.1;
				}
				number[j]=x+y;
				j++;
			}
		}
	}
	for(i=0;i<j+k;i++)
	{		
		if(operat[i] == '+')
		{
			number[0] += number[i+1];
			continue;

		}
		if(operat[i]=='-')
		{
			number[0] -= number[i+1];
			continue;
		}
	}
	printf("\t\t\t %s = %.2f\n",&s,number[0]);
	system("pause");
	return 0 ;	
}
float aux(char*s)
{
	float number[80],x=0,y=0,tem_y=1;
	int len,i=0,j=0,k=0,l=0,count_r=0,count_l=0,tem_j,tem_k,tem_i;
	char operat[80],s1[80];
	len=strlen(s);
	if(s[0]=='(')
	{
		while(1)
		{
			i++;
			if(s[i]=='(')
				count_l++;
			s1[l]=s[i];			
			l++;
			if(s[i]==')')
				count_r++;
			if(s[i]==')'&&(count_l<count_r))
				break;
		}
		s1[l-1]='\0';
		tem_j=j;tem_k=k;tem_i=i;
		number[tem_j]=aux(s1);
		j=tem_j;
		k=tem_k;
		i=++tem_i;
	} 
	else
	{
		i=0;
		for(;s[i]<='9'&&s[i]>='0';i++)
			x=(s[i]-'0')+x*10;
		if(s[i]=='.')
			for(i++;s[i]<='9'&&s[i]>='0';i++)
			{
				y=(s[i]-'0')*0.1*tem_y+y;
				tem_y=0.1*tem_y;
			}
		number[j]=x+y;
	}	
	j++;
	for(;i<len;)
	{
		if(s[i]=='*')
		{ 
			if(s[i+1]=='(')	
			{
				i++;
				l=0;
				count_l=count_r=0;
				while(1)
				{
					i++;
					if(s[i]=='(')
						count_l++;
					s1[l]=s[i];			
					l++;
					if(s[i]==')')
						count_r++;
					if(s[i]==')'&&(count_l<count_r||count_l==0))
						break;
				}
				s1[l-1]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=aux(s1);
				j=tem_j;
				k=tem_k;
				i=++tem_i;			
			}
			else
			{
				x=0;y=0;tem_y=1;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				if(s[i]=='.')
				for(i++;s[i]<='9'&&s[i]>='0';i++)
				{
					y=(s[i]-'0')*0.1*tem_y+y;
					tem_y*=0.1;
				}
				number[j]=x+y;
			}	
			number[j-1]=number[j-1]*number[j];
		}
		if(s[i]=='/')
		{ 
			if(s[i+1]=='(')	
			{
				i++;
				l=0;
				count_l=count_r=0;
				while(1)
				{
					i++;
					if(s[i]=='(')
						count_l++;
					s1[l]=s[i];			
					l++;
					if(s[i]==')')
						count_r++;
					if(s[i]==')'&&(count_l<count_r||count_l==0))
						break;
				}
				s1[l-1]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=aux(s1);
				j=tem_j;
				k=tem_k;
				i=++tem_i;			
			}
			else
			{
				x=0;y=0;tem_y=1;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				if(s[i]=='.')
				for(i++;s[i]<='9'&&s[i]>='0';i++)
				{
					y=(s[i]-'0')*0.1*tem_y+y;
					tem_y*=0.1;
				}
					number[j]=x+y;
				}
			if(number[j]==0)
			{
				printf("\n\t\tThe operator is error!\n");
				system("pause");
				return 0;
			}
			number[j-1]=number[j-1]/number[j];
		}	
		if(s[i]=='+'||s[i]=='-')
		{
			operat[k]=s[i];
			k++;
			if(s[i+1]=='(')	
			{
				i++;
				l=0;
				count_l=count_r=0;
				while(1)
				{
					i++;
					if(s[i]=='(')
						count_l++;
					s1[l]=s[i];			
					l++;
					if(s[i]==')')
						count_r++;
					if(s[i]==')'&&(count_l<count_r||count_l==0))
						break;
				}
				s1[l-1]='\0';
				tem_j=j;tem_k=k;tem_i=i;
				number[tem_j]=aux(s1);
				j=++tem_j;
				k=tem_k;
				i=++tem_i;			
			}
			else
			{
				x=0;y=0;tem_y=1;
				for(i++;s[i]<='9'&&s[i]>='0';i++)
					x=(s[i]-'0')+x*10;
				if(s[i]=='.')
				for(i++;s[i]<='9'&&s[i]>='0';i++)
				{
					y=(s[i]-'0')*0.1*tem_y+y;
					tem_y*=0.1;
				}
				number[j]=x+y;
				j++;
			}
		}
	}
	for(i=0;i<j+k;i++)
	{	
		if(operat[i] == '+')
		{
			number[0] += number[i+1];
			continue;

		}
		if(operat[i]=='-')
		{
			number[0] -= number[i+1];
			continue;
		}
	}
	operat[0]=0;
	return number[0];	
}

这种情况下主要加了一个对多级括号的处理,当s1读取括号里的字符串时,如果右面的括号多于左边的括号,则读取字符串完毕,注意在下一次读取时要把运算符数组(operat)和左右括号的计数(count_l,count_r)重新变成0

给大家看一下运行结果啦啦啦啦

猜你喜欢

转载自blog.csdn.net/coder_what/article/details/82682366