计算器

利用双栈实现基本计算器功能:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#define STACK_SIZE_FIRST 100
#define STACK_SIZE_INCREASE 20
struct Expression{
    char sign;
    struct Expression *next;
};
typedef struct{
    char *top;
	char *bottom;
	int stack_size;
}Stack;
struct Expression *GetExp();
int StackCreate(Stack *s);
int PUSH(Stack *s, char c);
int POP(Stack *s, char c);
char GetTop(Stack *s);
int Calculate(struct Expression *exp);
int Count(char num1, char sign, char num2);
int IsOpOrNum(char c);
char JudgeLevel(char c1, char c2);
void PrintResult(struct Expression *exp,int result);
int IsExpresiion(struct Expression *exp);
int main() {
    struct Expression *head;
    int Result = 0;
	int temp = 0;
    char select;
    while(temp == 0) {
	    head = GetExp();
        if(IsExpresiion(head) == 0 || head == NULL) {
		    printf("error!please re-enter");
			getch();
			system("cls");
		} else {
		    Result = Calculate(head);
            PrintResult(head,Result);
            printf("whether to continue to calculate??y??n\n");
            select = getch();
			if(select == 'n' || select == 'N')
			    temp = 1;
			else
			    system("cls");
		}
	}
	system("pause");
	return 0;
}
struct Expression *GetExp() {
    printf("\tthe bracketed arithmetic expression evaluation\n");
	printf("please enter an arithmetic expression that needs to be calculated:('='to the end)\n");
	char c;
    int number = 0;
    struct Expression *head = NULL,*p1,*p2,*first = NULL;
	head = (struct Expression *)malloc(sizeof(struct Expression));
	while((c = getchar()) != '\n') {
	    if(c != '?') {
		    p1 = (struct Expression *)malloc(sizeof(struct Expression));
			if(c == '=')
			    c = '#';
			p1->sign = c;
		    if(first == NULL)
			    first = p1;
            else
                p2->next = p1;
		    p2 = p1;
			number++;
		}
	}
	if(p2->sign != '#') {
	    p1 = (struct Expression *)malloc(sizeof(struct Expression));
		p1->sign = '#';
		p2->next = p1;
		p2 = p1;
		number++;
	}
	head->next = first;
	head->sign = number + '0';
	if(head->next != NULL)
	    p2->next = NULL;
	return head;
}
int StackCreate(Stack *s) {
    s->bottom = (char *)malloc(STACK_SIZE_FIRST * sizeof(char));
	if (s->bottom == NULL) {
	    printf("stack initialization failed!\n");
		exit(0);
	} else {
	    s->top = s->bottom;
		s->stack_size = STACK_SIZE_FIRST;
	}
	return 1;
}
int PUSH(Stack *s, char c) {
    if(s->top - s->bottom >= STACK_SIZE_FIRST) {
	    s->bottom = (char *)realloc(s->bottom,(STACK_SIZE_FIRST+STACK_SIZE_INCREASE) * sizeof(char));
		if(s->bottom == NULL) {
		    printf("increase stack space failed!\n");
			exit(0);
		}
		s->stack_size = s->stack_size + STACK_SIZE_INCREASE;
	}
	*(s->top) = c;
	s->top ++;
    return 1;
}
int POP(Stack *s, char c) {
    if(s->top == s->bottom) {
	    printf("stack is empty!stack failure!\n");
		exit(0);
	} else {
	    c = *(s->top);
		s->top --;
	}
	return 1;
}
char GetTop(Stack *s) {
    char c;
	if(s->top == s->bottom)
	    printf("stack is empty,unable to get the top element of the stack!\n");
	else {
	    c = * (s->top - 1);
	}
	return c;
}
int Calculate(struct Expression *exp) {
    exp = exp->next;
	char OpSign ='?';
	char NumSign1='?',NumSign2= '?';
	char result;
    char temp = '?';
	Stack s_operator, s_number;
	StackCreate(&s_operator);
	StackCreate(&s_number);
	PUSH(&s_operator,'#');
    printf("\nthe calculation procedure is as follows:\n");
    while(exp->sign != '#' || GetTop(&s_operator) != '#') {
	    if(IsOpOrNum(exp->sign) == 0) {
		    PUSH(&s_number,exp->sign);
			exp = exp->next;
		} else if(IsOpOrNum(exp->sign) == 1) {
            OpSign = GetTop(&s_operator);
            switch(JudgeLevel(OpSign,exp->sign)) {
			    case '<':PUSH(&s_operator,exp->sign);
				         exp = exp->next;
				         break;
				case '=':POP(&s_operator,OpSign);
				         exp = exp->next;
						 break;
				case '>':POP(&s_operator,OpSign);
				         NumSign1 = GetTop(&s_number);
						 POP(&s_number,temp);
						 NumSign2 = GetTop(&s_number);
						 POP(&s_number,temp);
						 result = Count(NumSign2,OpSign,NumSign1);
						 PUSH(&s_number,result);
						 break;
				default: break;
			}
		}
	}
	result = GetTop(&s_number);
	return result - '0';
}
char JudgeLevel(char c1, char c2) {
    switch(c1) {
	    case '+':switch(c2) {
		    case '*':
			case '/':
			case '(':
			         return '<';
					 break;
			default: return '>';
			         break;
		}
		break;
		case '-':switch(c2) {
		    case '*':
			case '/':
			case '(':
			         return '<';
					 break;
			default: return '>';
			         break;
		}
		break;
		case '*':switch(c2) {
		    case '(':return '<';
			         break;
			default: return '>';
			         break;
		}
		break;
		case '/':switch(c2) {
		    case '(':return '<';
			         break;
			default: return '>';
			         break;
        }
        break;
		case '(':switch(c2) {
            case ')':return '=';
			         break;
			default: return '<';
			         break;
		}
		break;
		case ')':switch(c2) {
		    case '+':return '>';
			         break;
			default: return '>';
			         break;
		}
		break;
		case '#':switch(c2) {
		    case '#':return '=';
			         break;
			default: return '<';
			         break;
		}
		break;
		default:return '<';
		break;
	}
}
int Count(char num1, char sign, char num2) {
    int a=0,b=0;
	a = num1 - '0';
	b = num2 - '0';
	int result = 0;
	switch(sign) {
	    case '+':result = a+b;
		         break;
		case '-':result = a-b;
		         break;
		case '*':result = a*b;
		         break;
		case '/':result = a/b;
		         break;
		default: break;
	}
	printf("%d  %c  %d = %d\n",a,sign,b,result);
	return result + '0';
}
int IsOpOrNum(char c) {
    switch(c) {
	    case '+':
		case '-':
		case '*':
		case '/':
		case '(':
		case ')':
		case '#':
		         return 1;
		         break;
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
		return 0;
		         break;
		default: return -1;
		break;
	}
}
void PrintResult(struct Expression *exp,int result) {
    printf("\nthe final calculation results are:\n");
	exp = exp->next;
	while(exp != NULL) {
	    if( exp->sign == '#')
		    exp->sign = '=';
		printf(" %c",exp->sign);
		exp = exp->next;
	}
	printf(" %d\n",result);
}
int IsExpresiion(struct Expression *exp) {
    int parameter = 1;
    int i=0,j=0;
    if(exp->sign - '0' < 4)
	    parameter = 0;
	exp = exp->next;
	while((parameter == 1) && (exp != NULL)) {
	    switch(IsOpOrNum(exp->sign)) {
		    case 0:exp = exp->next;
			       if(IsOpOrNum(exp->sign) != 1 || exp->sign == '(')
				       parameter = 0;
				   break;
			case 1:switch(exp->sign) {
			           case ')':i++;
					            exp = exp->next;
								if(IsOpOrNum(exp->sign) != 1)
								    parameter = 0;
								if(IsOpOrNum(exp->sign) == 1)
								    if(exp->sign == '(') {
									    printf("11111\n");
										parameter = 0;
									}
								break;
						case '+':
						case '-':
						case '*':
						         exp = exp->next;
								 if(exp->sign == '(')
								     parameter = 1;
								 else if(IsOpOrNum(exp->sign) == 0)
								     parameter = 1;
								 else
								     parameter = 0;
								 break;
						case '/':
						         exp = exp->next;
								 if(exp->sign == '(')
								     parameter = 1;
								 else if(IsOpOrNum(exp->sign) == 0) {
								     if(exp->sign == '0') {
									     printf("cannot divide into 0\n");
										 parameter = 0;
									 }
								 }
								 else
								     parameter = 0;
								 break;
						case '(':
						         j++;
								 exp = exp->next;
								 if(IsOpOrNum(exp->sign) != 0)
								     if(exp->sign != '(')
									     parameter = 0;
								 break;
						case '#':
						         if(exp->next != NULL)
								     parameter = 0;
								 exp = exp->next;
								 break;
				    }
					break;
			case -1:
					parameter = 0;
					break;
		}
	}
    if(i != j)
		parameter = 0;
	return parameter;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值