【数据结构C语言学习打卡-顺序栈(Seqstack)】进制转换/多个字符后缀表达式计算/Hanoi塔

先码下代码,后面跟进分析

运行结果

后缀表达式
在这里插入图片描述
在这里插入图片描述
Hanoi塔
在这里插入图片描述
在这里插入图片描述
进制转化
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX 100
int step = 0,power=0,powerSFX=0;
char suffixEXP[100];
typedef struct seqStack
{
	int data[MAX];
	int top;
};
typedef struct seqStackC
{
	char data[MAX];
	int top;
};

//初始化栈
seqStack* Init_seqStack()
{
	seqStack* s;
	s = (seqStack*)malloc(sizeof(seqStack));
	s->top = -1;
	return s;
}
seqStackC* Init_seqStackC()
{
	seqStackC* s;
	s = (seqStackC*)malloc(sizeof(seqStackC));
	s->top = -1;
	return s;
}

//判断是否是空栈
int isEmpty(seqStack* s)
{
	if (s->top == -1)
		return 1;
	else
	{
		return 0;
	}
}

//进栈
void push_seqStack(seqStack* s, int x)
{
	if (s->top == MAX - 1)
		printf("栈满!\n");
	else
	{
		s->top++;
		s->data[s->top] = x;
	}
}
void push_seqStackC(seqStackC* s, char x)
{
	if (s->top == MAX - 1)
		printf("栈满!\n");
	else
	{
		s->top++;
		s->data[s->top] = x;
	}
}

//出栈
void pop_seqStack(seqStack* s, int* x)
{
	if (s->top == -1)
		printf("栈空!\n");
	else
	{
		*x = s->data[s->top];
		s->top--;
	}
}
void pop_seqStackC(seqStackC* s, char* x)
{
	if (s->top == -1)
		printf("栈空!\n");
	else
	{
		*x = s->data[s->top];
		s->top--;
	}
}

//返回栈顶元素
int top_seqStack(seqStack* s)
{
	if (isEmpty(s))
		printf("栈空!");
	else
	{
		return (s->data[s->top]);
	}
}
char top_seqStackC(seqStackC* s)
{
	if (s->top==-1)
		printf("栈空!");
	else
	{
		return (s->data[s->top]);
	}
}

//依次输出栈内元素
void printSeqStack(seqStack* s)
{
	int i = 0;
	for (i = 0; i <= s->top; i++)
		printf("%d ", s->data[i]);
}
void printSeqStackc(seqStackC* s)
{
	int i = 0;
	for (i = 0; i <= s->top; i++)
		printf("%c ", s->data[i]);
}

//进制转化
void conversionSystem(int N, int r)
{
	seqStack* s;
	int x;
	s = Init_seqStack();
	while (N)
	{
		push_seqStack(s, N % r);
		N = N / r;
	}
	while (s->top != -1)
	{
		pop_seqStack(s, &x);
		printf("%d", x);
	}
}

//计算表达式(一个整数型的和一个字符型的栈,不限大小,整数内计算)
char precede(char in, char out)  //比较读取运算符和栈顶运算符的优先级,()返回等号
{
	if (in == '(' && out == ')')
		return '=';
	int a, b;
	if (in == '(')
		a = 0;
	if (in == '+' || in == '-')
		a = 1;
	if (in == '*' || in == '%' || in == '/')
		a = 2;
	if (in == '^')
		a = 3;
	if (in == ')')
		a = -1;
	if (out == '(')
		b = 4;
	if (out == '+' || out == '-')
		b = 1;
	if (out == '*' || out == '%' || out == '/')
		b = 2;
	if (out == '^')
		b = 3;
	if (out == ')')
		b = -1;

	if (b <= a)
		return '<';
	else 
		return '>';
}
int operate(int a, char opr, int b)   //计算a opr b
{
	if (opr == '-')
		return a - b;
	if (opr == '+')
		return a+b;
	if (opr == '*')
		return a * b;
	if (opr == '/')
		return a / b;
	if (opr == '%')
		return a % b;
	if (opr == '^')
		return pow(a,b);
}
int evaluateExpression()   //计算表达式,返回整数型计算结果
{
	seqStack *OPND;   //整数型栈,存数字
	seqStackC* OPTR;   //字符型栈,存字符
	char c, theta,x;
	int a, b,debug=0;
	OPND = Init_seqStack();
	OPTR = Init_seqStackC();
	push_seqStackC(OPTR, '(');
	c = getchar();
	while (c!='#')
	{
		if (c >= '0' && c <= '9')  
		{
			if (!power)  //读取的初个数字直接存入
			{
				power++;
				push_seqStack(OPND, c - 48);
			}
			else   //连续数字下把之前存入的数字取出,合并成新的整数存入
			{
				int trs;
				pop_seqStack(OPND, &trs);
				trs = trs*10 + c - 48;
				push_seqStack(OPND, trs);
			}
			c = getchar();
		}
		else
		{
			power = 0;
			switch (precede(top_seqStackC(OPTR), c))  //比较读取运算符与栈顶运算符的优先级
			{
			case '>':     //高于直接存入字符栈
				push_seqStackC(OPTR, c);
				c = getchar();
				break;
			case '=':   //()相遇弹出
				pop_seqStackC(OPTR, &x);
				c = getchar();
				break;
			case '<':   //小于从整数栈取出两个数字,取出运算符栈栈顶,进行运算,结果存入整数栈,之后继续比较
				pop_seqStackC(OPTR, &theta);
				pop_seqStack(OPND, &b);
				pop_seqStack(OPND, &a);
				push_seqStack(OPND, operate(a, theta, b));
				break;
			}
		}
		debug++;
		printf("\n第%d部:OPND:", debug);
		printSeqStack(OPND);
		//printf("\n");
		printf("\nOPTR:");
		printSeqStackc(OPTR);
	}
	while (OPTR->top != 0)   //循环结束后运算符栈还有剩余直接依次取出计算直到读到'('
	{
		pop_seqStackC(OPTR, &theta);
		pop_seqStack(OPND, &b);
		pop_seqStack(OPND, &a);
		push_seqStack(OPND, operate(a, theta, b));
	}
	return top_seqStack(OPND);
}

//后缀表达式(一个字符型的栈,不限大小整数范围内计算)
void toSuffixExpression()//把中缀表达式转换成后缀表达式,数之间用'|'隔开
{
	seqStackC* OPTR;
	OPTR = Init_seqStackC();
	push_seqStackC(OPTR, '(');
	char c,theta,x;      //c接受输入字符,theta运算符,x剔除多余字符时中介
	int i = 0;           //i数组计数
	c = getchar();
	while (c != '#')    //读到终止符结束
	{
		if (c >= '0' && c <= '9')   //如果是数字
		{
			if (!powerSFX)   //第一个数字前加上'|'用来区分不同数字,再输入数组
			{
				powerSFX++;
				suffixEXP[i] = '|';
				i++;
				suffixEXP[i] = c;
			}
			else            //之后直接输入进数组
				suffixEXP[i] = c;
			i++;
			c = getchar();
		}
		else
		{
			if (powerSFX)   //把是否输入数字的中介清零
			{
				powerSFX = 0;
			}
			switch (precede(top_seqStackC(OPTR), c))  //比较读取运算符的优先级与运算符栈顶优先级高低
			{
			case '>':      //优先级高直接存入运算符的栈
				push_seqStackC(OPTR, c);
				c = getchar();
				break;
			case '=':     //括号相遇清除
				pop_seqStackC(OPTR, &x);
				c = getchar();
				break;
			case '<':     //优先级低把运算符的栈顶输入数组,并继续比较
				pop_seqStackC(OPTR, &theta);
				suffixEXP[i] = theta;
				i++;
				break;
			}
		}
	}
	while (OPTR->top != 0)  //出循环后如果运算符栈还有剩余直接依次输入数组
	{
		pop_seqStackC(OPTR, &theta);
		suffixEXP[i] = theta;
		i++;
	}
}
int calculateSuffixEXP()    //计算后缀表达式,并返回整数型计算结果
{
	seqStackC* sfx;
	int i = 0,a,b,res,pow_=0,mRes;  //i用于存后缀表达式的数组的计次,a b存从栈中取出经过转化后的两个整数
	powerSFX = 0;                    //pow_:两整数计算结果的位数  mRes协助把计算结果依次转化后存入字符栈
	char rt,a_,b_; 
	sfx = Init_seqStackC();
	while (suffixEXP[i]!=NULL)  //数组内为空结束循环
	{
		if ((suffixEXP[i] >= '0' && suffixEXP[i] <= '9')||suffixEXP[i]=='|')  //是数字或者数字区分的符号直接存入栈
		{
			push_seqStackC(sfx, suffixEXP[i]);
			printf("\n栈内现在为:");
			printSeqStackc(sfx);
			i++;
		}
		else   
		{
			a = 0;
			b = 0;                      //以下几步用来把存在字符栈中的数字拼接成完整的整数
			pop_seqStackC(sfx, &a_);     //从栈中读取首个数字       
			printf("\n%c", a_);
			while (a_ != '|')             //读到区别的符号结束
			{
				a = a + (a_-48) * pow(10, powerSFX);  //拼接整数
				powerSFX++;                   
				pop_seqStackC(sfx, &a_);
				printf("\n%c", a_);
			}
			powerSFX = 0;
			pop_seqStackC(sfx, &b_);            //同a的转化
			printf("\n%c", b_);
			while (b_ != '|')
			{
				b = b + (b_ - 48) * pow(10, powerSFX);
				powerSFX++;
				pop_seqStackC(sfx, &b_);
				printf("\n%c", b_);
			}
			powerSFX = 0;
			printf("\n%c", suffixEXP[i]);
			res = operate(b, suffixEXP[i],a);     //把取出的两个整数进行计算,结果赋值给res
			printf("\n计算后%d", res);        //以下几步为把计算的结果转化为字符依次存入栈
			push_seqStackC(sfx, '|');           //先存入区别符号
			while (res / pow(10, pow_ + 1)>=1)    //计算res的位数
				pow_++;
			printf("\npow_%d", pow_);
			for (;pow_>=0; pow_--)     //借助res的位数依次把res各个位数字存入栈
			{
				mRes = res / pow(10, pow_);     //res的最高位赋给mRes
				res = res - mRes * pow(10, pow_);    //res去掉最高位数字
				printf("\nmRes:%d", mRes);
				push_seqStackC(sfx,mRes+48);  //存入
			}
			pow_ = 0;
			printf("\n计算后栈变为:");
			printSeqStackc(sfx);
			i++;
		}
	}
	b = 0;
	pop_seqStackC(sfx, &b_);      //把经过计算只存储了一个整数的字符栈转化为整数,同上a的赋值
	while (b_ != '|')
	{
		b = b + (b_ - 48) * pow(10, powerSFX);
		powerSFX++;
		pop_seqStackC(sfx, &b_);
	}
	powerSFX = 0;
	return b;   //返回就计算结果
}

//汉诺塔
void move(int n, char o, char p)
{
	step++;
	printf("第%d步:将编号为%d的圆盘从%c移动到%c\n", step,n, o, p);
}
void Hanoi(int n, char x, char y, char z)
{
	if (n == 1)
		move(n, x, z);
	else
	{
		Hanoi(n - 1, x, z, y);
		move(n, x, z);
		Hanoi(n - 1, y, x, z);
	}
}

int main()
{
	//进制转换
	/*int n, r;
	printf("输入十进制数n和r进制\n");
	scanf_s("%d %d", &n, &r);
	printf("十进制%d转化成为%d进制数为\n", n, r);
	conversionSystem(n, r);
	getchar();*/
	//表达式计算
	/*int result;
	printf("\n输入表达式,输入#结束\n");
	result = evaluateExpression();
	printf("结果为%d\n", result);
	getchar();*/
	//后缀表达式
	int j = 0;
	printf("\n输入表达式,输入#结束\n");
	toSuffixExpression();
	while (suffixEXP[j]!=NULL)
	{
		printf("%c", suffixEXP[j]);
		j++;
	}
	printf("\n结果为%d", calculateSuffixEXP());
	getchar();
	//Hanoi塔
	/*int n2=0;
	char x = 'x', y = 'y', z = 'z'; 
	printf("输入圆盘数目:\n");
	scanf_s("%d", &n2);
	Hanoi(n2, x, y, z);
	printf("步骤:%d", step);
	getchar();*/
	

	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
顺序栈是一种基于数组实现的,它的特点是具有随机存取的特性。顺序栈的基本运算包括进、出和查看顶元素。进操作将元素插入到顶,出操作将顶元素删除并返回,查看顶元素操作返回顶的元素值,但不修改的状态。 在C语言中,顺序栈的存储结构可以使用一个一维数组来存放中的元素,同时使用一个指示器top来指示顶的位置。在进行进和出操作时,需要更新top的值,使其指向顶元素。 下面是一种常见的顺序栈的定义和基本操作的示例代码: ```c // 定义中元素的数据类型 typedef int StackElementType; // 定义顺序栈的存储结构 #define Stack_Size 100 // 的最大容量 typedef struct { StackElementType elem[Stack_Size]; // 用数组存放中元素 int top; // 顶指针 } SeqStack; // 初始化顺序栈 void Init_SeqStack(SeqStack *S) { S->top = -1; // 初始时为空,顶指针置为-1 } // 进操作 void Push_SeqStack(SeqStack *S, StackElementType x) { if (S->top == Stack_Size - 1) { printf("已满,无法进"); return; } S->top++; // 顶指针加1 S->elem[S->top] = x; // 将新元素放入顶位置 } // 出操作 StackElementType Pop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空,无法出"); return -1; // 返回一个特殊值表示出错 } StackElementType x = S->elem[S->top]; // 获取顶元素的值 S->top--; // 顶指针减1 return x; // 返回顶元素的值 } // 查看顶元素 StackElementType GetTop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("为空"); return -1; // 返回一个特殊值表示出错 } return S->elem[S->top]; // 返回顶元素的值 } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值