c语言版数据结构(奇迹冬瓜)-栈实战(4)表达式求值

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

 

//c语言版数据结构(奇迹冬瓜)-栈实战(4)表达式求值

/*
这个算法难的不是思想,而是尽可能的解决输入格式的问题
这个程序还有两个问题没有解决可以实现输出负数,但是不能输入负数,一旦输入时括号不匹配会发生错误。
主要思想:
利用两个栈,一个存放字符运算符,一个来存放整数.
其中涉及整数的转换和表达式的格式检测及算符之间的优先级.
本算法还很不工整优化.
*/

//-----头文件------

#include<stdio.h>
#include<stdlib.h>

//-----宏定义------

#define INIT_STACKSIZE 100
#define INCREMENTSIZE 10
#define TRUE 1
#define ERROR 0
#define OVERFLOW -2

//-----替换和结构体-----

typedef int Bool;
typedef struct
{
	char *Base,*Top;
	int stacksize;
}SqStackC,*StackC;
typedef struct
{
	int *Base,*Top;
	int stacksize;
}SqStackI,*StackI;

//-------函数列表-------

Bool InitStackC(StackC s);
Bool PopC(StackC s,char *e);
Bool PushC(StackC s,char e);
Bool StackEmptyC(StackC s);
Bool ClearStackC(StackC s);
char GetTopC(StackC s);

Bool InitStackI(StackI s);
Bool PopI(StackI s,int *e);
Bool PushI(StackI s,int e);
Bool StackEmptyI(StackI s);
Bool ClearStackI(StackI s);
int GetTopI(StackI s);

Bool InN(char ch);
void Expression();
Bool Rule(char ch);
char Precede(char c1,char c2);
int Operate(int a,char theta,int b);

//------主函数------

void main()
{
	Expression();
}

//-----其余函数------

void Expression()
{
	SqStackC sq1,*OPTR=&sq1;
	SqStackI sq2,*OPND=&sq2;
	int integer=0,ei,i,flag,startflag,flag1,flag2,flag3,a,b;
	char ec,ch,theta;
	do
	{   flag3=0;
	flag=1;
	flag1=0;
	flag2=0;
	startflag=0;
	InitStackC(OPTR);InitStackI(OPND);
	PushC(OPTR,'#');
	ch=getchar();
	while('#'!=ch||'#'!=GetTopC(OPTR))
	{

		if(!Rule(ch)||(0==startflag&&('+'==ch||'*'==ch||'/'==ch||'-'==ch))||flag1>=2)
		{
			flag=0;
		}
		if(InN(ch))
		{
			flag1=0;
			if(0==integer&&'0'==ch)
			{
				flag=0;
			}
			integer=integer*10+ch-'0';
		}
		else if(('+'==ch||'-'==ch||'*'==ch||'/'==ch||'#'==ch||')'==ch)&&(0==flag2)&&(0!=integer&&'0'!=ch))
		{
			flag1++;
			PushI(OPND,integer);
			integer=0;
		}
		if(Rule(ch)&&(!InN(ch)))
		{
			switch(Precede(GetTopC(OPTR),ch))
			{
			case '<':PushC(OPTR,ch);ch=getchar();flag2=0;break;
			case '=':PopC(OPTR,&ec);ch=getchar();flag2=0;break;
			case '>':PopI(OPND,&b);PopI(OPND,&a);PopC(OPTR,&theta);PushI(OPND,Operate(a,theta,b));flag2=1;break;
			case '@':flag=0;break;
			}
		}
		else
		{
			ch=getchar();
			flag2=0;
		}
		startflag=1;
		flag3++;
		if(flag3>30)
		{
			flag=0;
		}
	}
	if(0==flag)
	{
		printf("表达式格式错误!重新输入.\n");
		getchar();
		ClearStackC(OPTR);
		ClearStackI(OPND);
	}
	}while(0==flag);
	while(!StackEmptyI(OPND))
	{
		PopI(OPND,&ei);
		printf("%d ",ei);
	}
	getchar();
	getchar();
}

Bool InitStackC(StackC s)
{
	if(!(s->Base=(char*)malloc(INIT_STACKSIZE*sizeof(char))))
	{
		exit(OVERFLOW);
	}
	s->Top=s->Base;
	s->stacksize=INIT_STACKSIZE;
	return TRUE;
}

Bool PopC(StackC s,char *e)
{
	if(s->Base==s->Top)
	{
		return ERROR;
	}
	*e=*(--s->Top);
	return TRUE;
}

Bool PushC(StackC s,char e)
{
	if(s->Top-s->Base>=s->stacksize)
	{
		if(!(s->Base=(char*)realloc(s->Base,(INIT_STACKSIZE+INCREMENTSIZE)*sizeof(char))))
		{
			exit(OVERFLOW);
		}
		s->Top=s->Base+s->stacksize;
		s->stacksize+=INIT_STACKSIZE;
	}
	*(s->Top++)=e;
	return TRUE;
}

Bool StackEmptyC(StackC s)
{
	return s->Base==s->Top?TRUE:ERROR;
}

Bool ClearStackC(StackC s)
{
	free(s->Base);
	s->Base=NULL;
	s->Top=NULL;
	return TRUE;
}

char GetTopC(StackC s)
{
	if(!s->stacksize||s->Base==s->Top)
	{
		return ERROR;
	}
	return *(s->Top-1);
}

Bool InitStackI(StackI s)
{
	if(!(s->Base=(int*)malloc(INIT_STACKSIZE*sizeof(int))))
	{
		exit(OVERFLOW);
	}
	s->Top=s->Base;
	s->stacksize=INIT_STACKSIZE;
	return TRUE;
}

Bool PopI(StackI s,int *e)
{
	if(s->Base==s->Top)
	{
		return ERROR;
	}
	*e=*(--s->Top);
	return TRUE;
}

Bool PushI(StackI s,int e)
{
	if(s->Top-s->Base>=s->stacksize)
	{
		if(!(s->Base=(int*)realloc(s->Base,(INIT_STACKSIZE+INCREMENTSIZE)*sizeof(int))))
		{
			exit(OVERFLOW);
		}
		s->Top=s->Base+s->stacksize;
		s->stacksize+=INIT_STACKSIZE;
	}
	*(s->Top++)=e;
	return TRUE;
}

Bool StackEmptyI(StackI s)
{
	return s->Base==s->Top?TRUE:ERROR;
}

Bool ClearStackI(StackI s)
{
	free(s->Base);
	s->Top=s->Base=NULL;
	return TRUE;
}

int GetTopI(StackI s)
{
	if(!s->stacksize||s->Base==s->Top)
	{
		return ERROR;
	}
	return *(s->Top-1);
}

Bool InN(char ch)
{
	return ch>='0'&&ch<='9'?TRUE:ERROR;
}

Bool Rule(char ch)
{
	if(ch>='0'&&ch<='9')
	{
		return TRUE;
	}
	else if('#'==ch||'('==ch||')'==ch||'+'==ch||'-'==ch||'*'==ch||'/'==ch)
	{
		return TRUE;
	}
	return ERROR;
}

char Precede(char c2,char c1)
{
	char opera[8][8]={
		{'@','+','-','*','/','(',')','#'},
		{'+','>','>','<','<','<','>','>'},
		{'-','>','>','<','<','<','>','>'},
		{'*','>','>','>','>','<','>','>'},
		{'/','>','>','>','>','<','>','>'},
		{'(','<','<','<','<','<','=','@'},
		{')','>','>','>','>','@','>','>'},
		{'#','<','<','<','<','<','@','='}};
	int i,j,mark_i=0,mark_j=0;
	for(i=0;i<8;i++)
	{
		if(opera[0][i]==c2)
		{
			mark_i=i;
		}
	}
	for(j=0;j<8;j++)
	{
		if(opera[j][0]==c1)
		{
			mark_j=j;
		}
	}
	return opera[mark_i][mark_j];
}

int Operate(int a,char theta,int b)
{
	int res=0;
	switch(theta)
	{
	    case '+':res=a+b;break;
		case '-':res=a-b;break;
		case '*':res=a*b;break;
		case '/':res=a/b;break;
	}
	return res;
}


 

C语言数据结构算法——简单表达式求值(支持计算小数及负数 文章目录样例输入输出中缀表达式转后缀表达式后缀表达式求值运行示例 样例输入输出 输入为一段简单表达式(中缀),表达式中的数据可以是小数以及整数,负数前后都有括号分隔,以下是一段输入样例: 4.5*(3.8-0.9*2)+2.5*(9.6/(-2.4)) 输出为计算结果即 -1。 中缀表达式转后缀表达式 代码如下,算法思路在注释里了,改进了算法加入了对小数以及负数的支持: /* 以下为中缀表达式转后缀表达式: while (从exp读取字符ch,ch!='\0') { ch为数字: 阅读详情

相关推荐

表达式求值的应用(C语言

无语死了,好在终于弄出来了。 题目:利用编写表达式求值程序:输入含有“+”、“-”、“*”、“/”四则运算的表达式,其中负数要用(0-正数)表示,并以=结束。要输出表达式(两运算符号的有限关系见教材《数据结构》表3.1)。 测试样式: 【第一组自测数据】 【键盘输入】 3*(9-7)#↙ 【正确输出】 6 【第二组自测数据】 【键盘输入】 (0-

永远的第一天 3957

数据结构——的应用(表达式求值)(C语言

char Precede(char t1, char t2)函数用于输出t1,t2两个运算符的优先级(t1为先出现的运算符(已经压入OPTR中),t2为后出现的运算符)char Precede(char t1, char t2){ int i,j; char pre[][7]={ //运算符之间的优先级制作成一张表格 {'>

Sup_klz的博客 2万+

C语言网 题目 1683: 数据结构-表达式求值

C语言顺序表实现表达式求值,我很笨,这一题写了半天,理了好久的思路,目前想到的就是使用大量的条件判断语句来实现(┬┬﹏┬┬)(┬┬﹏┬┬)(┬┬﹏┬┬)题目描述算数四则运算的规则是1)先乘除,后加减;2)从左算到右;3)先括号内,后括号外。由此,算式4+2*3-10/5的计算顺序为4+2*3-10/5=4+6-10/5=4+6-2=8。给定一个以“#”作为结束符的算式,出算式的结果。给出严蔚敏《数据结构(C语言)》中的一段算法描述以作参考:图1:表达式求值算法图2:表达式求值算法(续)

qq_62109928的博客 886

C++实现计算器,运用,输出后缀表达式,有负数、小数处理

#include <iostream> #include <stack> #include <vector> #include <string> using namespace std; enum Member_type{ NUM, SIGN }; struct member { member(double n) { m_type = NUM; num = n; } member(char n) { m_type = SIGN; si.

qq_35436635的博客 2283

c语言数据结构迷宫算法,c语言版数据结构奇迹冬瓜-实战(1)解迷宫<迷宫算法>...

//c语言版数据结构(奇迹冬瓜)-实战(1)解迷宫//题目:解迷宫//---------头文件---------#include#include//---------宏定义---------#define TRUE 1#define ERROR 0#define OVERFLOW -2//------替换和结构体-------typedef int Status;typedef str...

weixin_42357916的博客 263

c语言版数据结构奇迹冬瓜-实战(3)括号匹配的检测

//c语言版数据结构奇迹冬瓜-实战(3)括号匹配的检测 /* 初始化 初始化标志位 循环标志位不为1 { 输入一个字符并判断是否为括号 如果是<[{(则进 如果是>]})则出 { 判断出的字符和输入的字符是否相等 { 相等则继续 否则标志位为0 } } 判断空否 { 空则标志位

runner2012的专栏 1469

c语言版数据结构奇迹冬瓜-实战(1)解迷宫<迷宫算法>

//c语言版数据结构奇迹冬瓜-实战(1)解迷宫 //题目:解迷宫 //---------头文件--------- #include #include //---------宏定义--------- #define TRUE 1 #define ERROR 0 #define OVERFLOW -2 //------替换和结构体------- typedef int Stat

runner2012的专栏 1703

aub的c语言线性代码,c语言版数据结构奇迹冬瓜-链表实战(1)A=AUB

//c语言版数据结构(奇迹冬瓜)-链表实战(1)A=AUB//题目:假设利用两个线性表LA和LB分别表示两个集合A和B,现要一个新的集合A=A∪B//思想:/*主函数:初始化集合A和集合B给A和B集合输入元素当集合B中的元素不到最后一个元素时{取出B中的元素和A中的元素比较if(A没有B有){插入A的集合里面}}输出合并后的集合*//*void main(){List *A=InitL();L...

weixin_39950083的博客 474

数据结构多项式乘法c语言,c语言版数据结构奇迹冬瓜-链表实战4)双链表解一元多项式相乘...

//c语言版数据结构(奇迹冬瓜)-链表实战(4)双链表解一元多项式相乘/*主要函数思想:初始化一元多项式A初始化一元多项式B初始化一元多项式C给一元多项式A赋入数据给一元多项式B赋入数据(指数升序)把AB各项累乘放入C中用双指针的模式消除合并累加最后得到结果输出*///---------头文件----------#include#include//---------宏定义----------#...

weixin_35466750的博客 205

c语言版数据结构奇迹冬瓜-链表实战4)双链表解一元多项式相乘

//c语言版数据结构奇迹冬瓜-链表实战4)双链表解一元多项式相乘 /* 主要函数思想: 初始化一元多项式A 初始化一元多项式B 初始化一元多项式C 给一元多项式A赋入数据 给一元多项式B赋入数据(指数升序) 把AB各项累乘放入C中 用双指针的模式消除合并累加最后得到结果 输出 */ //---------头文件---------- #include #include //-------

runner2012的专栏 3440

c语言版数据结构奇迹冬瓜-链表实战(2)合并两有序线性表

//c语言版数据结构奇迹冬瓜-链表实战(2)合并两有序线性表 //题目:已知线性表La和Lb中的数据元素按非递减有序排列,现要将La与Lb一起为一个新的线性表Lc(非递减排列) /* 主要函数思想: 初始化La,Lb,Lc链表头; 输入La,Lb链表数据; 当La链表下一个结点不为空或者Lb链表下一个结点不为空 { 比较La和Lb的结点 { La的结点>=L

runner2012的专栏 2255

c语言队列模拟排队编程,c语言版数据结构奇迹冬瓜-队列实战(1)离散事件模拟(银行排队)...

//c语言版数据结构(奇迹冬瓜)-队列实战(1)离散事件模拟(银行排队)//------头文件---------#include#include#include//-------宏定义---------#define TURE 1#define ERROR 0#define OVERFLOW -2//------替换及结构体------typedef int Bool;typedef st...

weixin_35826751的博客 756

c语言版数据结构奇迹冬瓜-实战(2)整数进制转换<10进制到2,8,16进制>

//c语言版数据结构奇迹冬瓜-实战(2)整数进制转换 /* 初始化 输入要转换的进制并进行判断是否在制定进制内 输入要转换的整数并判断改整数是否大于零 循环当整数不为零的时候 { 先对该整数(选择的进制) 余数进 在对该整数(选择的进制) } 循环当不为空 { 出 } */ //---------头文件---------- #include #

runner2012的专栏 2103

c语言版数据结构奇迹冬瓜-链表实战(1)A=AUB

//c语言版数据结构奇迹冬瓜-链表实战(1)A=AUB //题目:假设利用两个线性表LA和LB分别表示两个集合A和B,现要一个新的集合A=A∪B //思想: /* 主函数: 初始化集合A和集合B 给A和B集合输入元素 当集合B中的元素不到最后一个元素时 { 取出B中的元素 和A中的元素比较 if(A没有B有) { 插入A的集合里面 } } 输出合

runner2012的专栏 2077

c语言版数据结构奇迹冬瓜-队列实战(1)离散事件模拟(银行排队)

//c语言版数据结构奇迹冬瓜-队列实战(1)离散事件模拟(银行排队) //------头文件--------- #include #include #include //-------宏定义--------- #define TURE 1 #define ERROR 0 #define OVERFLOW -2 //------替换及结构体------ typedef int Boo

runner2012的专栏 4853

c语言版数据结构奇迹冬瓜-链表实战(3)解升序排列的一元多项式相加

//c语言版数据结构奇迹冬瓜-链表实战(3)解升序排列的一元多项式相加 /* 主要函数思想: 初始化一元多项式A 初始化一元多项式B 初始化一元多项式C 给一元多项式A赋入数据 给一元多项式B赋入数据(指数升序) 当A的结点或者B的结点项的下一项不为空 { 比较AB的指数 { 定位当前结点A的指数,定位当前结点B的指数. 如果A的结点指数<B的结点指数(C的下一个结

runner2012的专栏 2301

c语言版数据结构奇迹冬瓜-单链式队列

(一)      队列(FIFO)先进先出模式,包含初,毁,清,空,长,得,进,出。八种基本操作。现以两种存储方式为例,来讲解队列的用法。    (二)      单 链式存储结构  //----头文件----- #include #include //-----宏定义----- #define TURE 1 #define ERROR 0 #define OVERFLOW -2

runner2012的专栏 2034

c语言版数据结构奇迹冬瓜-串的匹配模式算法

[一]传统匹配模式 //-----头文件------ #include #include //------宏定义------ #define MAXSTRLEN 255 #define OVERFLOW -2 #define TURE 1 #define ERROR 0 //-------类型名替换-------- typedef unsigned char SString[MAXSTRLE

runner2012的专栏 3061

线性链表的合并C语言源代码,c语言版数据结构奇迹冬瓜-链表实战(2)合并两有序线性表...

//c语言版数据结构(奇迹冬瓜)-链表实战(2)合并两有序线性表//题目:已知线性表La和Lb中的数据元素按非递减有序排列,现要将La与Lb一起为一个新的线性表Lc(非递减排列)/*主要函数思想:初始化La,Lb,Lc链表头;输入La,Lb链表数据;当La链表下一个结点不为空或者Lb链表下一个结点不为空{比较La和Lb的结点{La的结点>=Lb的结点{Lc的结点指向下一个结点为Lb的...

weixin_39678103的博客 200
上一篇: c语言版数据结构(奇迹冬瓜)-栈实战(3)括号匹配的检测
下一篇: c语言版数据结构(奇迹冬瓜)-队列实战(1)离散事件模拟(银行排队)
utral董东东
博客等级 码龄16年 158粉丝 33原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值