/*
多项式运算
顺序栈实现
在demo1.cpp基础上增加 弥补异常处理 以及多位数运算缺点
*/
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define OK 1
#define ERROR 2
#define OVERFLOW -1
#define INI_SIZE 100
#define APPEND 10
typedef int Elemtype_int;
typedef char Elemtype_char;
typedef int statue;
typedef struct{
Elemtype_int *pTop_int;
Elemtype_int *pBottom_int;
int stack_int_size;
}stack_int;
typedef struct{
Elemtype_char *pTop_char;
Elemtype_char *pBottom_char;
int stack_char_size;
}stack_char;
statue ini_int(stack_int *stack){//初始化
stack->pBottom_int=(Elemtype_int *)malloc(sizeof(Elemtype_int)*INI_SIZE);
if(stack->pBottom_int==NULL){
printf("内存分配失败\n");
exit(OVERFLOW);
}
stack->pTop_int=stack->pBottom_int;
stack->stack_int_size=INI_SIZE;
return OK;
}
statue ini_char(stack_char *stack){//初始化
stack->pBottom_char=(Elemtype_char *)malloc(sizeof(Elemtype_char)*INI_SIZE);
if(stack->pBottom_char==NULL){
printf("内存分配失败\n");
exit(OVERFLOW);
}
stack->pTop_char=stack->pBottom_char;
stack->stack_char_size=INI_SIZE;
return OK;
}
statue push_int(stack_int *stack,int val){//入栈
if(stack->pTop_int-stack->pBottom_int==stack->stack_int_size){
stack->pBottom_int=(Elemtype_int *)realloc(stack->pBottom_int,stack->stack_int_size+sizeof(Elemtype_int)*APPEND);
if(stack->pBottom_int==NULL){
printf("内存分配失败\n");
exit(OVERFLOW);
}
stack->pTop_int=stack->pBottom_int+stack->stack_int_size;
stack->stack_int_size+=APPEND;
}
*stack->pTop_int=val;
stack->pTop_int++;
return OK;
}
statue push_char(stack_char *stack,char val){//入栈
if(stack->pTop_char-stack->pBottom_char==stack->stack_char_size){
stack->pBottom_char=(Elemtype_char *)realloc(stack->pBottom_char,stack->stack_char_size+sizeof(Elemtype_char)*APPEND);
if(stack->pBottom_char==NULL){
printf("内存分配失败\n");
exit(OVERFLOW);
}
stack->pTop_char=stack->pBottom_char+stack->stack_char_size;
stack->stack_char_size+=APPEND;
}
*stack->pTop_char=val;
stack->pTop_char++;
return OK;
}
statue pop_int(stack_int *stack,int *val){//出栈
if(stack->pBottom_int==stack->pTop_int){
printf("栈为空\n");
return ERROR;
}
stack->pTop_int--;
*val=*stack->pTop_int;
return OK;
}
statue pop_char(stack_char *stack,char *val){//出栈
if(stack->pBottom_char==stack->pTop_char){
printf("栈为空\n");
return ERROR;
}
stack->pTop_char--;
*val=*stack->pTop_char;
return OK;
}
bool In(char val){//判断是否为运算符
if(val>='0'&&val<='9'){
return true;
}else{
return false;
}
}
char getTOP(stack_char stack){
char *p=stack.pTop_char;
p=p-1;
return *p;
}
char precade(char a,char b){
int i,j;
char pre[][7]={
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','=','0'},
{'>','>','>','>','0','>','>'},
{'<','<','<','<','<','0','='}};
switch(a){
case '+':
i=0;
break;
case '-':
i=1;
break;
case '*':
i=2;
break;
case '/':
i=3;
break;
case '(':
i=4;
break;
case ')':
i=5;
break;
case '#':
i=6;
break;
}
switch(b){
case '+':
j=0;
break;
case '-':
j=1;
break;
case '*':
j=2;
break;
case '/':
j=3;
break;
case '(':
j=4;
break;
case ')':
j=5;
break;
case '#':
j=6;
break;
}
return pre[i][j];
}
int operate(int a,char val,int b){
printf("----%d%c%d---\n",a,val,b);
switch(val){
case'+':
return a+b;
case'-':
return a-b;
case'*':
return a*b;
case'/':
return a/b;
}
}
void show(stack_int stack){
Elemtype_int *p=stack.pTop_int-1;
while(p!=stack.pBottom_int-1){
printf("%d ",*p);
p--;
}
printf("\n");
}
void run(char *val){
char *p=val;
stack_int s_int;
stack_char s_char;
int reslute;
ini_int(&s_int);
ini_char(&s_char);
push_char(&s_char,*val);
*val++;//先将#入栈
while(true){
printf("%c\n",*val);
if(In(*val)){//是数字
push_int(&s_int,(*val-48));
}else{//是字符
char flog=precade(getTOP(s_char),*val);
switch(flog){
case'<':
push_char(&s_char,*val);
break;
case'>':
int a,b,myval;
char poer;
show(s_int);//
pop_int(&s_int,&a);
pop_int(&s_int,&b);
pop_char(&s_char,&poer);
myval=operate(b,poer,a);
push_int(&s_int,myval);
val--;
break;
case'=':
char p;
pop_char(&s_char,&p);
break;
}
}
if(*val=='#'){
break;
}
val++;
}
reslute=*(s_int.pTop_int-1);
show(s_int);
printf("结果:%d\n",reslute);
}
bool isChar(char val){//判断是否为 + - * /
if(val=='+'||val=='-'||val=='*'||val=='/'){
return true;
}
return false;
}
bool isKuo(char q){
if(q=='('||q=='<'||q=='{'||q=='['||q==')'||q=='>'||q=='}'||q==']'){
return true;
}
return false;
}
bool isEmpty(stack_char stack){//判断是否为空
if(stack.pTop_char==stack.pBottom_char){
return true;
}
return false;
}
bool judge(char *val){//检查表达式格式
char *p=val,*q=val;
stack_char stack;//存储括号
ini_char(&stack);
//必须以#开头
if(*p!='#'){
printf("ERROR\n");
return false;
}
p++;
//#后面必须为数字
if(!In(*p)){
printf("ERROR\n");
return false;
}
//满足以上条件后开始遍历
while(*val){
if(!In(*val)){
//如果含有其它字符会报错
if(*val=='+'||*val=='-'||*val=='*'||*val=='/'||*val=='('||*val==')'||*val=='#'){
}else{
return false;
}
}
if(isChar(*val)){
*val++;
if(isChar(*val)){
val--;
printf("ERROR++\n");
return false;
}
}
val++;
}
val--;
if(*val!='#'){//必须以#结尾
printf("ERROR\n");
return false;
}
//判断括号是否合法
while(*q){
if(isKuo(*q)){
if(*q=='('||*q=='<'||*q=='{'||*q=='['){
//入栈
push_char(&stack,*q);
q++;
}else{
if(isEmpty(stack)){
printf("括号1不合法\n");
return false;
}
if(*q==')'&&*(stack.pTop_char-1)=='('||*q=='>'&&*(stack.pTop_char-1)=='<'||*q=='}'&&*(stack.pTop_char-1)=='{'||*q==']'&&*(stack.pTop_char-1)=='['){
//出栈
char myval;
pop_char(&stack,&myval);
q++;
}else{
printf("括号2不合法\n");
return false;
}
}
}else{
q++;
}
}
if(isEmpty(stack)){
return true;
}
return true;
}
int main(void){
char asd[100],*p;
p=asd;
printf("请输入表达式 #开头结尾\n");
gets(asd);
if(judge(p)){
run(p);
}else{
printf("格式错误\n");
}
return 0;
}
多项式运算
最新推荐文章于 2020-07-21 18:46:24 发布