栈的一些小小应用

原创 2016年06月01日 19:01:23

昨天刚实现了栈的一些基本操作,今天就来实现一点栈的应用把!


首先,写一点比较简单的:

1.逆波兰表达式的计算。

    在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。逆波兰表达式也称为后缀表达式。比如:

  wKiom1cLyhbhgnQiAAAt4UnxwWk442.png  两种表达式如果在程序中运行时,后缀表达式不需要考虑符号优先级的问题。

现在通过一个程序去计算一个简单的后缀表达式:

#pragma once

#include <iostream>
#include <assert.h>
#include <stack>
using namespace std;

enum Type
{
	OP_NUM,//数字
	OP_SYMBOL,//运算符
};

enum SYMBOL
{
	ADD,
	SUB,
	MUL,
	DIV,
};

struct Cell
{
	Type _type;//类型(1.数字 2.运算符)
	int _value;
};

int CountSymbol(Cell a[], size_t size)
{
	assert(a);
	stack<int> s;

	for (size_t i = 0; i < size; i++)//依次读取每个数据
	{
		if (a[i]._type == OP_NUM)
		{
			s.push(a[i]._value);
		}
		else
		{
			//取出运算符前面的两个数字进行计算
			int right = s.top();
			s.pop();//栈的特性,只能pop一个后去下一个数
			int left = s.top();
			s.pop();

			switch (a[i]._value)
			{
				//把计算结果压入栈中
			case ADD:
				s.push(left + right);
				break;
			case SUB:
				s.push(left - right);
				break;
			case MUL:
				s.push(left * right);
				break;
			case DIV:
				s.push(left / right);
				break;
			}
		}
	}
	return s.top();
}

void TestSymbol()
{
	//12*(3+4)-6+8/2 = 82
	//12 3 4 + * 6 - 8 2 / +   逆波兰表达式
	Cell a[] =
	{
		{OP_NUM,12},
		{OP_NUM, 3},
		{OP_NUM,4},
		{OP_SYMBOL,ADD},
		{OP_SYMBOL,MUL},
		{OP_NUM,6},
		{OP_SYMBOL,SUB},
		{OP_NUM,8},
		{OP_NUM,2},
		{OP_SYMBOL,DIV},
		{OP_SYMBOL,ADD},
	};
	int ret = CountSymbol(a, sizeof(a) / sizeof(a[0]));
	cout << "ret=" << ret << endl;
}

wKioL1cL1AzDQoxPAAABmMPUvjQ560.png

在这个程序中可以看到应用了栈的一个重要特性,“后进先出”

2.迷宫是一个很长久的话题,今天我就用代码来实现它。

迷宫问题有一个很重要的点,就是“回溯”,顾名思义,就是沿着走过的路依次往回走。

为了简单起见,直接写一个迷宫,定义为“Maze.txt”文件

wKioL1cLzo3RFZUBAAAVdnv7-m8522.png               

                              (0表示通路,1表示墙)

把走过的路的坐标保存在一个栈中,当无路可走的时候,从栈中依次pop出的坐标回溯,直到找到正确的路或者没有通路为止!

代码实现如下:

#pragma once

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1

#define N 10

#include <iostream>
#include <stack>
#include <assert.h>

using namespace std;

struct Pos//记录坐标
{
	int _row;//行
	int _col;//列
};

void GetMaze(int * a, int n)//读取迷宫
{
	FILE * fout = fopen("Maze.txt", "r");
	assert(fout);

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; )
		{
			char ch = fgetc(fout);
			if (ch == '0' || ch == '1')
			{
				a[i*n + j] = ch - '0';
				j++;//有数据时,才往二维数组中存,所以j++放在这里
			}
			else
			{
				continue;
			}
		}
	}
	fclose(fout);
}

void printMaze(int * a, int n)//输出迷宫
{
	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < n; j++)
		{
			cout << a[i*n + j] << " ";
		}
		cout << endl;
	}
}

bool CheckIsAccess(int * a, int n, Pos next)//检查是否通行
{
	assert(a);
	if (next._row >= 0 && next._row < n&&
		next._col >= 0 && next._col < n&&
		a[next._row*n + next._col] == 0)// 0 表示可以通行
	{
		return true;
	}
	else
	{
		return false;
	}
}


bool MazePath(int *a, int n, const Pos & entry, stack<Pos>& path)
{
	Pos cur = entry;
	path.push(cur);

	while (!path.empty())//栈空的时候返回起点
	{
		a[cur._row*n + cur._col] = 2;//走过的路标记为2

		if (cur._row == n - 1)//判断是否到出口
		{
			return true;
		}
		//向上
		Pos next = cur;
		next._row--;
		if (CheckIsAccess(a, n, next))//判断
		{
			cur = next;
			path.push(cur);//走过的坐标push进栈
			continue;
		}
		//向下
		next = cur;//每次判断的时候重新赋值给next
		next._row++;
		if (CheckIsAccess(a, n, next))
		{
			cur = next;
			path.push(cur);
			continue;
		}
		//向左
		next = cur;
		next._col--;
		if (CheckIsAccess(a, n, next))
		{
			cur = next;
			path.push(cur);
			continue;
		}
		//向右
		next = cur;
		next._col++;
		if (CheckIsAccess(a, n, next))
		{
			cur = next;
			path.push(cur);
			continue;
		}
		//无路可走
		a[cur._row*n + cur._col] = 3;
		path.pop();
		if (!path.empty())
		{
			cur = path.top();
		}
	}

	return false;
}

void TestMaze()
{
	int a[N][N] = {};
	GetMaze((int *)a, N);
	printMaze((int *)a, N);

	stack<Pos> path;
	Pos entry = { 2,0 };

	MazePath((int *)a, N, entry, path);
	cout << "结果" << endl;
	printMaze((int *)a, N);

}

输出的结果是:

wKiom1cOQg7yRMSjAAAK4TkA22g363.png

数字“2”表示通路。


欢迎各位大神吐槽。

本文出自 “不断进步的空间” 博客,请务必保留此出处http://10824050.blog.51cto.com/10814050/1762816

版权声明:本文为博主原创文章,未经博主允许不得转载。

栈和队列的实际应用

在信息处理领域,栈和队列的身影随处可见。许多程序语言本身就是建立于栈结构之上,无论 PostScript 或者 Java,其实时运行环境(Realtime Runtime Environment)都是...
  • lanchunhui
  • lanchunhui
  • 2016年06月14日 13:11
  • 2601

数据结构学习之路-第三章:栈的应用

【 声明:版权所有,转载请标明出处,请勿用于商业用途。  联系信箱:libin493073668@sina.com】 前言: 前面已经介绍过栈的相关操作的具体实现,那么现在就按...
  • libin1105
  • libin1105
  • 2015年09月08日 19:15
  • 1331

栈的经典应用

前言                    前面的一文中,说明了什么是栈,以及栈的两种实现方式。接下来我们简单看看栈的经典的               应用。         栈的应用举例 ...
  • kiritor
  • kiritor
  • 2013年04月29日 21:28
  • 4456

关于栈及其应用示例

栈和线性表类似,也是有两种存储结构,分别为顺序结构和链式结构。大部分情况下,栈使用前者,这和它的使用场景有关,因为通常情况下我们不会对栈进行频繁地,随机地插入,删除操作。下面是我用顺序结构实现的栈,这...
  • pony_maggie
  • pony_maggie
  • 2014年06月14日 21:38
  • 10041

小小输入法使用小记

从网上得知,适合自定义、折腾的输入法非Rime和小小输入法了,前段时间接触了rime,也集成了小鹤双拼(音形方案),把其余不用的输入方式统统删除了,也罢整个界面调整为简体了,除了不能修改的之外。 以前...
  • liming0931
  • liming0931
  • 2016年12月04日 19:11
  • 3408

致第一次安装(yong)小小输入法的你

致第一次安装(yong)小小输入法的你目录致第一次安装yong小小输入法的你目录强大全开放的外挂内置输入平台 支持各种编码 方便的词库维护功能 最温情的输入法 本文的题目就参考了百度贴吧「致第一次安装...
  • liming0931
  • liming0931
  • 2016年12月07日 20:55
  • 6706

[数据结构与算法分析]栈的应用-学习笔记

平时我们很少接触到一个栈的使用,但是今天看了如下三个例子后感触颇深,对于栈应用的情况理解更深了。分享如下: 1、平衡符号 平衡是个动词,意思就是用来平衡符号的,例如关于方法里{}左右大括号的匹配问...
  • u014629433
  • u014629433
  • 2016年06月06日 09:04
  • 655

【小小决斗】我看你不顺眼很久了,快来和我一决高下!

为了世界友谊与和平,开发者做了这样一个微信小程序 ,有仇报仇、有怨报怨,大家都来『小决斗』吧!! ​​​​ 这款小程序,乍看之下有点无聊,细玩之后觉得:这个小程序,有毒啊。...
  • rolan1993
  • rolan1993
  • 2017年07月25日 15:57
  • 180

栈的应用——四则表达式求值

栈的应用有很多,四则运算是一个比较常见的应用。对于四则运算,括号内的要先运算,而且还要先乘除后加减,又要涉及到负数和浮点数,看上去简简单单的式子,其实暗藏杀机。        常用的方法是利用后缀表达...
  • hcx25909
  • hcx25909
  • 2014年07月15日 15:31
  • 5131

Docker-搭建简单的应用栈

系统环境操作系统版本$ cat /etc/issue Debian GNU/Linux 8 \n \l 内核版本$ uname -r 3.16.0-4-amd64 Docker版本 docker ve...
  • u012066426
  • u012066426
  • 2016年09月20日 19:33
  • 2133
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:栈的一些小小应用
举报原因:
原因补充:

(最多只允许输入30个字)