c语言实现利用栈的计算器(含大于9的数,小数和负数)

c语言实现利用栈的计算器(含大于9的数,小数和负数)

1、效果
输入数学表达式 输入为数字 和“+ - * / ^(平方) r(根号)s(sin) c(cos) t(tan) l(ln)以及括号",得到算式的答案
2、思路

(1)识别大于9的数,小数和负数
(2)改写为后缀表达式
(3)用后缀表达式进行计算
3.实现
(1)识别大于9的数,小数和负数,
buf为接收输入的字符串
formed为存放后缀表达式的double类型数组

//根据int数组计算实际的值
double cal(int* arr, int flag)
{
	double num = 0;
	int i = 0;
	int j = 0;
	for (i = 0; i < flag; i++)
	{
		if (arr[i] == '.')
			break;
	}
	if (i + 1 == flag)//无小数点
	{
		for (j = 0; j < flag; j++)
			num = num + (arr[j] * pow(10, i--));
	}
	else
	{
		for (j = 0; j < flag; j++)
		{
			if (arr[j] != '.')
				num = num + (arr[j] * pow(10, --i));
		}
	}
	return num;
}
//识别负数并将负号改为后缀‘f'
if (buf[i] == '-' && !(buf[i - 1] > 47 && buf[i - 1] < 58) && buf[i - 1] != ')'&&!(buf[i-1] == '^' || buf[i-1] == 'r' || buf[i-1] == 's' || buf[i-1] == 'c' || buf[i-1] == 'l' || buf[i-1] == 't' || buf[i-1] == 'f'))
					{
						k = strlen(buf + 1) + 1;
						if (buf[i + 1] == '(')
						{
							m = 1;
							for (l = i+2; 1; l++)
							{
								if (buf[l] == ')')
								{
									m--;
								}
								if (buf[l] == '(')
								{
									m++;
								}
								if (m == 0)
									break;
							}

							
							for (k = k; k-1 > l; k--)
							{
								buf[k] = buf[k - 1];
							}
							buf[l + 1] = 'f';
						}
						else
						{
							for(l=i+1;(buf[l] > 47 && buf[l ] < 58)||buf[l]=='.' || buf[l] == 'e' || buf[l] == 'p';l++)
							for (k = k; k-1 > l; k--)
							{
								buf[k] = buf[k - 1];
							}
							buf[l] = 'f';
						}
						continue;
					}
//将buf中的数存放至int数组中,再将int数组代表的数存入formed
//'0'的asc码值为48,'9'为58,'.'为46
           int flag==0;
           for (i = 0; i < max - 1; i++)
			{
				if (buf[i] > 47 && buf[i] < 58)
				{
					arr[flag] = ((int)buf[i] - 48);
					flag++;
				again:
					if (buf[i + 1] > 47 && buf[i + 1] < 58)
					{
						arr[flag] = (int)buf[i + 1] - 48;
						i++;
						flag++;
						goto again;
					}
					else if (buf[i + 1] == 46)
					{
						arr[flag] = buf[i + 1];
						i++;
						flag++;
						goto again;
					}
					else
					{
						formed[f] = cal(arr, flag);
						f++;
						flag = 0;
						memset(arr, 0, sizeof(arr));
					}
				}
		

(2)后缀表达式实现
这里运算符加0.00005的原因是会遇到与运算符asc码值相同的数,加0.00005会避免大多数的bug

typedef struct stack
{
	double data[max];
	int top;
}stack;
void jinzhan(stack* p, char a)
{
	if (p->top < (max - 1))
	{

		p->data[p->top] = a;
		p->top++;
	}
	else
		printf("errorjin\n");
}
double chuzhan(stack* p)
{
	if (p->top > 0)
	{
		p->top--;
		return p->data[p->top];
	}
	else
		printf("errorchu\n");
}


             int f=0;
             int flag=0;
             stack* p = (stack*)malloc(sizeof(stack));
			for (i = 0; i < max - 1; i++)
			{
				if (buf[i] > 47 && buf[i] < 58)
				{
					arr[flag] = ((int)buf[i] - 48);
					flag++;
				again:
					if (buf[i + 1] > 47 && buf[i + 1] < 58)
					{
						arr[flag] = (int)buf[i + 1] - 48;
						i++;
						flag++;
						goto again;
					}
					else if (buf[i + 1] == 46)
					{
						arr[flag] = buf[i + 1];
						i++;
						flag++;
						goto again;
					}
					else
					{
						formed[f] = cal(arr, flag);
						f++;
						flag = 0;
						memset(arr, 0, sizeof(arr));
					}
				}
				else if (buf[i] == 'p')
				{
					formed[f] = 3.141592653589793238;
					f++;
				}
				else if (buf[i] == 'e')
				{
					formed[f] = 2.718281828459;
					f++;
				}
				else if (buf[i] == '(')
				{
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == ')')
				{
					while ((a = chuzhan(p)) != '(' && p->top > 0)
					{
						formed[f] = (a + 0.00005);
						f++;
					}
				}
				else if (buf[i] == '+' || buf[i] == '-')
				{
					while (1)
					{
						if (p->data[p->top - 1] != 40 && p->top > 0)
						{
							formed[f] = chuzhan(p) + 0.00005;
							f++;
						}
						else
							break;
					}
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == '*' || buf[i] == '/')
				{
					while (1)
					{
						if (p->data[p->top - 1] != '+' && p->data[p->top - 1] != '-' && p->top > 0 && p->data[p->top - 1] != '(')
						{
							formed[f] = chuzhan(p) + 0.00005;
							f++;
						}
						else
							break;
					}
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == '^' || buf[i] == 'r' || buf[i] == 's' || buf[i] == 'c' || buf[i] == 'l' || buf[i] == 't')
				{
					while (1)
					{
						if (p->data[p->top - 1] != '+' && p->data[p->top - 1] != '-' && p->top > 0 && p->data[p->top - 1] != '(' && p->data[p->top - 1] != '*' && p->data[p->top - 1] != '/')
						{
							formed[f] = chuzhan(p) + 0.00005;
							f++;
						}
						else
							break;
					}
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == ' ')
					continue;
				else if (buf[i] == '\0')
					continue;
				else
					printf("errorp");
			}
			while (p->top > 0)//将剩余的运算符全部弹出,存入formed
			{
				formed[f] = chuzhan(p) + 0.00005;
				f++;
			}
		}

(3)用后缀表达式进行计算

typedef struct stackd
{
	double data[max];
	int top;
}stackd;
void jinzhand(stackd* p, double a)
{
	if (p->top < (max - 1))
	{

		p->data[p->top] = a;
		p->top++;
	}
	else
		printf("errorjind\n");
}
double chuzhand(stackd* p)
{
	if (p->top >0)
	{
		p->top--;
		return p->data[p->top];
	}
	else
		printf("errorchud\n");
}


    stack* pp = (stackd*)malloc(sizeof(stackd));
	for (i = 0; i < max - 1; i++)
		{
			if (formed[i] == '+' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n1 + n2;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '-' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n2 - n1;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '*' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n2 * n1;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '/' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n2 / n1;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '^' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = n1 * n1;
				jinzhand(pp, n1);
			}
			else if (formed[i] == 'r' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = sqrt(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 's' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = sin(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 'c' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = cos(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 'l' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = log(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 't' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = tan(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == ' ' + 0.00005)
				continue;
			else if (formed[i] == '\0' + 0.00005)
				continue;
			else
			{
				jinzhand(pp, formed[i]);
			}

		}

计算结束后,stackd中应只剩data[0],我们

printf("%lf\n", pp->data[0]);

得到最终结果
全部代码

#include
#include
#include
#include
#include
#include
#define max 50
typedef struct stack
{
	double data[max];
	int top;
}stack;
typedef struct stackd
{
	double data[max];
	int top;
}stackd;
void jinzhan(stack* p, char a)
{
	if (p->top < (max - 1))
	{

		p->data[p->top] = a;
		p->top++;
	}
	else
		printf("errorjin\n");
}
double chuzhan(stack* p)
{
	if (p->top > 0)
	{
		p->top--;
		return p->data[p->top];
	}
	else
		printf("errorchu\n");
}
void jinzhand(stackd* p, double a)
{
	if (p->top < (max - 1))
	{

		p->data[p->top] = a;
		p->top++;
	}
	else
		printf("errorjind\n");
}
double chuzhand(stackd* p)
{
	if (p->top >0)
	{
		p->top--;
		return p->data[p->top];
	}
	else
		printf("errorchud\n");
}
double cal(int* arr, int flag)
{
	double num = 0;
	int i = 0;
	int j = 0;
	for (i = 0; i < flag; i++)
	{
		if (arr[i] == '.')
			break;
	}
	if (i + 1 == flag)//wudian
	{
		for (j = 0; j < flag; j++)
			num = num + (arr[j] * pow(10, i--));
	}
	else
	{
		for (j = 0; j < flag; j++)
		{
			if (arr[j] != '.')
				num = num + (arr[j] * pow(10, --i));
		}
	}
	return num;
}
int main()

{
	while (1)
	{
		printf("示例:(ps+pc+pt+el)^-((1+2)*4/3)r=-2\n");
		int flag = 0;
		int flag2 = 0;
		int arr[max];
		memset(arr, 0, sizeof(arr));
		double a;
		int f = 0;
		int m,j,k;
		double formed[max];
		char buf[max];
		int i = 0;
		double n1 = 0;
		double n2 = 0;
		double n3 = 0;
		memset(buf, 0, sizeof(buf));
		memset(formed, 0, sizeof(formed));
		stack* p = (stack*)malloc(sizeof(stack));
		stackd* pp = (stackd*)malloc(sizeof(stackd));
		pp->top = 0;
		memset(p->data, 0, sizeof(p->data));
		memset(pp->data, 0, sizeof(pp->data));
		if (p)
		{
			p->top = 0;
			scanf("%s", buf);
			for (i = 0; i < max - 1; i++)
			{
				if (buf[i] > 47 && buf[i] < 58)
				{
					arr[flag] = ((int)buf[i] - 48);
					flag++;
				again:
					if (buf[i + 1] > 47 && buf[i + 1] < 58)
					{
						arr[flag] = (int)buf[i + 1] - 48;
						i++;
						flag++;
						goto again;
					}
					else if (buf[i + 1] == 46)
					{
						arr[flag] = buf[i + 1];
						i++;
						flag++;
						goto again;
					}
					else
					{
						formed[f] = cal(arr, flag);
						f++;
						flag = 0;
						memset(arr, 0, sizeof(arr));
					}
				}
				else if (buf[i] == 'p')
				{
					formed[f] = 3.141592653589793238;
					f++;
				}
				else if (buf[i] == 'e')
				{
					formed[f] = 2.718281828459;
					f++;
				}
				else if (buf[i] == '(')
				{
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == ')')
				{
					while ((a = chuzhan(p)) != '(' && p->top > 0)
					{
						formed[f] = (a + 0.00005);
						f++;
					}
				}
				else if (buf[i] == '+' || buf[i] == '-')
				{
				  if (buf[i] == '-' && !(buf[i - 1] > 47 && buf[i - 1] < 58) && buf[i - 1] != ')'&&!(buf[i-1] == '^' || buf[i-1] == 'r' || buf[i-1] == 's' || buf[i-1] == 'c' || buf[i-1] == 'l' || buf[i-1] == 't' || buf[i-1] == 'f'))
					{
						k = strlen(buf + 1) + 1;
						if (buf[i + 1] == '(')
						{
							m = 1;
							for (l = i+2; 1; l++)
							{
								if (buf[l] == ')')
								{
									m--;
								}
								if (buf[l] == '(')
								{
									m++;
								}
								if (m == 0)
									break;
							}

							
							for (k = k; k-1 > l; k--)
							{
								buf[k] = buf[k - 1];
							}
							buf[l + 1] = 'f';
						}
						else
						{
							for(l=i+1;(buf[l] > 47 && buf[l ] < 58)||buf[l]=='.' || buf[l] == 'e' || buf[l] == 'p';l++)
							for (k = k; k-1 > l; k--)
							{
								buf[k] = buf[k - 1];
							}
							buf[l] = 'f';
						}
						continue;
					}
					while (1)
					{
						if (p->data[p->top - 1] != 40 && p->top > 0)
						{
							formed[f] = chuzhan(p) + 0.00005;
							f++;
						}
						else
							break;
					}
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == '*' || buf[i] == '/')
				{
					while (1)
					{
						if (p->data[p->top - 1] != '+' && p->data[p->top - 1] != '-' && p->top > 0 && p->data[p->top - 1] != '(')
						{
							formed[f] = chuzhan(p) + 0.00005;
							f++;
						}
						else
							break;
					}
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == '^' || buf[i] == 'r' || buf[i] == 's' || buf[i] == 'c' || buf[i] == 'l' || buf[i] == 't')
				{
					while (1)
					{
						if (p->data[p->top - 1] != '+' && p->data[p->top - 1] != '-' && p->top > 0 && p->data[p->top - 1] != '(' && p->data[p->top - 1] != '*' && p->data[p->top - 1] != '/')
						{
							formed[f] = chuzhan(p) + 0.00005;
							f++;
						}
						else
							break;
					}
					jinzhan(p, buf[i]);
				}
				else if (buf[i] == ' ')
					continue;
				else if (buf[i] == '\0')
					continue;
				else
					printf("errorp");
			}
			while (p->top > 0)
			{
				formed[f] = chuzhan(p) + 0.00005;
				f++;
			}
		}
		for (i = 0; i < max - 1; i++)
		{
			if (formed[i] == '+' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n1 + n2;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '-' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n2 - n1;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '*' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n2 * n1;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '/' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n2 = (double)chuzhand(pp);
				n3 = n2 / n1;
				jinzhand(pp, n3);
			}
			else if (formed[i] == '^' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = n1 * n1;
				jinzhand(pp, n1);
			}
			else if (formed[i] == 'r' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = sqrt(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 's' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = sin(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 'c' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = cos(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 'l' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = log(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == 't' + 0.00005)
			{
				n1 = (double)chuzhand(pp);
				n1 = tan(n1);
				jinzhand(pp, n1);
			}
			else if (formed[i] == ' ' + 0.00005)
				continue;
			else if (formed[i] == '\0' + 0.00005)
				continue;
			else
			{
				jinzhand(pp, formed[i]);
			}

		}

		printf("%lf\n", pp->data[0]);
		system("pause");
	}
	return 0;
}

c语言实现利用栈的计算器(含大于9的数,小数和负数)_第1张图片

你可能感兴趣的:(笔记,c语言,stack)