数据结构:栈的应用——数值转换、括号匹配、行编辑程序(C++实现)

这里是闲话:在上一篇文章(详见https://blog.csdn.net/jokerCe/article/details/114139123)中,我们已经实现了栈的最基本操作,那么在本篇文章中,我们便可以用已实现的数据结构来完成一些小应用,包括数值转换、括号匹配、行编辑程序,并给出必要的实验结果。

在下文内容中,我们应着重思考栈的特性——“后进先出”(FILO)在这几个应用中起到的作用,以下内容仅供参考~

这里是目录:

一、数值转换

二、括号匹配

三、行编辑程序


一、数值转换

    1、 算法思想:

求进制转化使一般从高位到低位进行,恰好和计算过程相反。该算法可以使十进制整数转化为N进制整数(N∈(1,10)),每次取余之后把余数入栈保存,保存N进制整数最后从栈顶输出。

例如:将10进制的18转化为3进制

             18/3=6..........0

             6/3=2............0

             2/3=0............2

∴10进制的18用3进制表示为:200

    2、代码实现:

//对于输入的任意一个非负十进制整数,打印输出与其等值的N进制数(N<10)
void concersion_10toN() {
	SqStack S;
	InitStack(S);
	int a, N;

	cout << "请输入一个非负十进制整数:" << endl;
	while (cin >> a && a < 0)
		cout << "请输入非负十进制整数!" << endl;
	cout << "你要转化为几进制?(1<N<10)" << endl;
	while (cin >> N && (N <= 1 || N >= 10))
		cout << "进制N应在以下范围:(1,10)!" << endl;
	while (a) {
		Push(S, a % N);
		a /= N;
	}
	for (int i = S.top - 1; i >= 0; i--)
		cout << S.elem[i];
	cout << endl;
}

 

二、括号匹配

1、算法思想:

括号匹配要求表达式中允许包含两种括号:圆括号和方括号,嵌套的格式随意但必须匹配,例如 [()[]] 为正确格式。因此可以用“期待的急迫程度”来描述括号匹配的优先级。该算法可根据以下原则(左)列出解决方法(右):

①表达式中可以连续接收多个左括号,且越后接受的括号急迫程度越高→用栈的数据来接受左括号元素(先进后出,以保证最后的括号先匹配)

②计算机接受右括号时,必须有最急迫对应左括号与其匹配→判断括号是否匹配,若匹配成功则将左括号出栈

2、代码实现:

bool ParenthesisMatch(char str[]) {
	SqStack S;
	InitStack(S);
	bool flag;
	for (int i = 0; i < strlen(str); i++) {
		SElemType e;
		if (str[i] == '(' || str[i] == '{' || str[i] == '[')
			Push(S, str[i]);
		else if ((str[i] == ')' && Top(S) == '(')
			|| (str[i] == '}' && Top(S) == '{')
			|| (str[i] == ']' && Top(S) == '['))
			Pop(S, e);
		else {
			flag = false;
			break;
		}
	}
	if (StackLength(S) == 0) flag = true;
	else flag = false;
	ClearStack(S);
	return flag;
}

3、运行结果及检验:

①检验问题:输入[()[]]、[(][]]

②理论结果:OK!、ERROR!

③实际结果:

 

经检验,实际结果符合理论。

 

三、行编辑程序

1、算法思想:

问题的关键在于设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区,同时这个缓冲区允许输入有误是进行当前行的更正。因此可以设这个输入缓存区为一个栈结构,每当终端接受一个字符后可以做如下判断和操作:

①如果它不是退格符也不是退行符,该字符进栈;

②如果它是退格符,字符栈出栈;

③如果它是退行符,字符栈清为空栈。

2、代码实现:

void LineEdit() {
	//利用字符栈S,从终端接收一行并传送只调用过程的数据区。
	SqStack S;
	InitStack(S);//构建并初始化栈S
	char ch;
	ch = cin.get();//从终端读入单个字符ch
	SElemType e;
	while (ch != EOF) {//EOF为全文结束符
		while (ch != EOF && ch != '\n') {
			switch (ch) {
			case '#': Pop(S, e); break;
			case '@': ClearStack(S); break;
			default: Push(S, ch);
			}
			ch = cin.get();
		}
		//输出语句进行验证
		for (int i = 0; i < S.top; i++)
			cout << S.elem[i];
		cout << endl;
		ClearStack(S);
		if (ch != EOF) ch = cin.get();
	}
}

3、运行结果及检验:

①检验问题:终端接受以下两行字符

Whli##ile#e(s#*s)

outcha@putchar(*s=#++);

②理论结果:

While(*s)

putchar(*s++);

③实际结果:

经检验,实际结果符合理论。


这里还是闲话:有关栈的三种简单应用就此结束啦,思路其实不难。下一篇文章是关于栈的另外两个应用——迷宫求解和表达式求值,有兴趣的伙伴可以继续浏览噢~

这里是链接:https://blog.csdn.net/jokerCe/article/details/114144322

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值