用栈实现科学计算器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <windows.h>
typedef struct _elem
{
	double Data;
	char Sign;
}elem;
typedef struct _list
{
	elem Elem;
	struct _list *Next;
}list;
typedef list stack;
typedef list suffix;
typedef list listnode;
typedef list stacknode;
void Delete(list *List);
void Add(list *OldList, elem Elm);
void PushStack(stack *SignStack, elem Elm);
void BufToSuffix(char *Buf,suffix *Suffix);
void DealSign(char Sign,stack *SignStack,suffix *Suffix);
bool PriorityGreaterThanStackTop(char Sign, stack *Stack);
double CalculatorSuffix(suffix *Suffix);
elem PopStack(stack *Stack);
int main(void)
{
	char Buf[64] = { 0 };
	double Result = 0;
	suffix *Suffix=NULL;
	Suffix = (suffix*)calloc(1, sizeof(suffix));
	printf("Input:\n");
	scanf("%s", Buf);
	BufToSuffix(Buf,Suffix);
	Result=CalculatorSuffix(Suffix);
	printf("%f\n", Result);
	Delete(Suffix);
	system("pause");
	return 0;
}
void BufToSuffix(char *Buf,suffix *Suffix)
{
	char DataBuf[16] = { 0 };
	int Cou = 0;
	stack *SignStack = NULL;
	elem Elm;
	SignStack = (stack*)calloc(1, sizeof(stack));
	while (*Buf)
	{
		Cou = 0;
		memset(DataBuf, 0, 16 * sizeof(char));
		memset(&Elm, 0, sizeof(elem));
		if (*Buf >= '0' && *Buf <= '9')
		{
			while (1)
			{
				if (!(*Buf >= '0' && *Buf <= '9'))
				{
					break;
				}
				else
				{
					DataBuf[Cou++] = *Buf;
					++Buf;
				}
			}
			Elm.Data = atof(DataBuf);
			Add(Suffix, Elm);
			continue;
		}
		if (*Buf == '+' || *Buf == '-' || *Buf == '*' || *Buf == '/' || *Buf == '(' || *Buf == ')')
		{
			DealSign(*Buf, SignStack, Suffix);
			++Buf;
		}
	}
	while (SignStack->Next)
	{
		Elm = PopStack(SignStack);
		Add(Suffix, Elm);
	}
	Delete(SignStack);
	return;
}
void Add(list *List, elem Elm)
{
	listnode *Tmp = NULL;
	Tmp = (listnode*)calloc(1, sizeof(listnode));
	memcpy(&(Tmp->Elem), &Elm, sizeof(elem));
	while (List->Next)
	{
		List = List->Next;
	}
	List->Next = Tmp;
	return;
}
void DealSign(char Sign,stack *SignStack,suffix *Suffix)
{
	elem Elm;
	memset(&Elm, 0, sizeof(elem));
	switch (Sign)
	{
		case '(':Elm.Sign = '(';
				 PushStack(SignStack, Elm);
				 break;
		case ')':while (1)
				 {
					 Elm = PopStack(SignStack);
					 if (Elm.Sign == '(')
					 {
						 break;
					 }
					 Add(Suffix, Elm);
				 }
				 break;
		case '*':

		case '/':

		case '+':

		case '-':if (PriorityGreaterThanStackTop(Sign, SignStack))
				 {
					 Elm.Sign = Sign;
					 PushStack(SignStack, Elm);
				 }
				 else
				 {
					 while (1)
					 {
						  memset(&Elm, 0, sizeof(elem));
						  if (!PriorityGreaterThanStackTop(Sign, SignStack))
						  {
							  Elm = PopStack(SignStack);
							  Add(Suffix, Elm);
						  }
						  else
						 {
							  Elm.Sign = Sign;
							  PushStack(SignStack, Elm);
							  break;
						  }
					 }
				 }
	}
	return;
}
void Delete(list *List)
{
	list *Tmp = NULL;
	while (List)
	{
		Tmp = List->Next;
		free(List);
		List = Tmp;
	}
	return;
}
void PushStack(stack *SignStack, elem Elm)
{
	stacknode *Tmp = NULL;
	Tmp = (stacknode*)calloc(1, sizeof(stacknode));
	Tmp->Next = NULL;
	memcpy(&(Tmp->Elem), &Elm, sizeof(elem));
	while (SignStack->Next)
	{
		SignStack = SignStack->Next;
	}
	SignStack->Next = Tmp;
	return;
}
elem PopStack(stack *Stack)
{
	elem Elm;
	stacknode *Tmp = NULL;
	while (Stack->Next->Next)
	{
		Stack = Stack->Next;
	}
	Tmp = Stack->Next;
	Stack->Next = NULL;
	memcpy(&Elm, &(Tmp->Elem), sizeof(elem));
	free(Tmp);
	return Elm;
}
bool PriorityGreaterThanStackTop(char Sign, stack *Stack)
{
	elem Top;
	if (Stack->Next == NULL)
	{
		return true;
	}
	Top = PopStack(Stack);
	if (Top.Sign == '(')
	{
		PushStack(Stack, Top);
		return true;
	}
	if (Top.Sign == '*' || Top.Sign == '/')
	{
		if (Sign == '+' || Sign == '-')
		{
			PushStack(Stack, Top);
			return false;
		}
		else if (Sign == '*' || Sign == '/')
		{
			PushStack(Stack, Top);
			return false;
		}
	}
	if (Top.Sign == '+' || Top.Sign == '-')
	{
		if (Sign == '+' || Sign == '-')
		{
			PushStack(Stack, Top);
			return false;
		}
		else if (Sign == '*' || Sign == '/')
		{
			PushStack(Stack, Top);
			return true;
		}
	}
}
double CalculatorSuffix(suffix *Suffix)
{
	stack *Tmp = NULL;
	stacknode TmpNode;
	elem Elm;
	elem Data1;
	elem Data2;
	elem Result;
	Tmp = (stack*)calloc(1, sizeof(stack));
	memset(&TmpNode, 0, sizeof(stacknode));
	Suffix = Suffix->Next;
	while (Suffix)
	{
		memcpy(&Elm, &(Suffix->Elem), sizeof(listnode));
		if (Elm.Sign == 0)
		{
			TmpNode.Elem.Data = Elm.Data;
			PushStack(Tmp, TmpNode.Elem);
		}
		else
		{
			Data2 = PopStack(Tmp);
			Data1 = PopStack(Tmp);
			switch (Elm.Sign)
			{
			case '+':Result.Data = Data1.Data + Data2.Data; break;
			case '-':Result.Data = Data1.Data - Data2.Data; break;
			case '*':Result.Data = Data1.Data*Data2.Data; break;
			case '/':Result.Data = Data1.Data / Data2.Data; break;
			}
			PushStack(Tmp, Result);
		}
		Suffix = Suffix->Next;
	}
	Result = PopStack(Tmp);
	Delete(Tmp);
	return Result.Data;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值