数据结构 堆栈(下)

简介: 数据结构 堆栈

4. DS堆栈–迷宫求解


题目描述


给出一个N*N的迷宫矩阵示意图,从起点[0,0]出发,寻找路径到达终点[N-1, N-1]


要求使用堆栈对象来实现,具体算法参考课本3.2.4节51页


输入


第一行输入t,表示有t个迷宫


第二行输入n,表示第一个迷宫有n行n列


第三行起,输入迷宫每一行的每个方格的状态,0表示可通过,1表示不可通过


输入n行


以此类推输入下一个迷宫


输出


逐个输出迷宫的路径


如果迷宫不存在路径,则输出no path并回车


如果迷宫存在路径,将路径中每个方格的x和y坐标输出,从起点到终点,每输出四个方格就换行,最终以单词END结尾,具体格式参考示范数据


输出的代码参考如下:


//path是保存路径的堆栈,堆栈中每个元素都包含x坐标和y坐标,用属性xp和yp表示
//path1是一个临时堆栈,把path的数据倒序输出到path1,使得路径按正序输出
if (!path.empty())//找到路径
{//…若干代码,实现path的数据导入path1
i=0; //以下是输出路径的代码
while (!path1.empty())
{cpos = path1.top();
if ( (++i)%4 == 0 )
cout<<’[’<<cpos.xp<<’,’<<cpos.yp<<’]’<<"–"<<endl;
else
cout<<’[’<<cpos.xp<<’,’<<cpos.yp<<’]’<<"–";
path1.pop();
}
cout<<“END”<<endl;
}
else
cout<<“no path”<<endl; //找不到路径输出no path


输入样例


2

8

0 0 0 1 1 1 1 1

1 0 0 0 1 0 0 1

1 0 0 0 1 0 0 0

1 1 0 0 0 0 0 1

0 0 1 1 0 1 1 0

0 0 0 0 0 0 1 1

1 1 1 1 1 0 0 1

0 0 0 0 1 0 0 0

7

0 0 0 1 1 1 1

1 0 0 1 0 0 1

1 0 0 1 0 0 0

1 1 0 0 0 0 1

0 0 1 1 0 1 0

1 0 0 0 0 1 0

0 0 0 0 1 1 0


输出样例


[0,0]–[0,1]–[0,2]–[1,2]–

[1,3]–[2,3]–[3,3]–[3,4]–

[4,4]–[5,4]–[5,5]–[6,5]–

[6,6]–[7,6]–[7,7]–END

no path


参考代码

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N][N];
int dist[N][N];
bool st[N][N];
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
pair<int, int> pre[N][N];
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n;
        cin >> n;
        memset(a, 0, sizeof a);
        memset(st, false, sizeof st);
        memset(dist, -1, sizeof dist);
        memset(pre, -1, sizeof pre);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) cin >> a[i][j];
        }
        if (a[n - 1][n - 1] == 1) {
            cout << "no path" << endl;
            continue;
        }
        queue<pair<int, int>> q;
        dist[n - 1][n - 1] = 0;
        pre[n - 1][n - 1] = {0, 0};
        st[n - 1][n - 1] = 1;
        q.push({n - 1, n - 1});
        while (q.size()) {
            pair<int, int> t = q.front();
            q.pop();
            for (int i = 0; i < 4; i++) {
                int x = t.first + dx[i], y = t.second + dy[i];
                if (x < 0 || x >= n || y < 0 || y >= n || st[x][y] || a[x][y] == 1) continue;
                if (pre[x][y].first != -1) continue;
                dist[x][y] = dist[t.first][t.second] + 1;
                q.push({x, y});
                st[x][y] = 1;
                pre[x][y] = t;
            }
        }
        if (dist[0][0] == -1) {
            cout << "no path" << endl;
        } else {
            pair<int, int> end = make_pair(0, 0);
            int cnt = 0;
            while (true) {
                printf("[%d,%d]--", end.first, end.second);
                cnt++;
                if (cnt == 4) {
                    cout << endl;
                    cnt = 0;
                }
                if (end.first == n - 1 && end.second == n - 1) {
                    break;
                }
                end = pre[end.first][end.second];
            }
            cout << "END" << endl;
        }
    }
    return 0;
}


5. DS堆栈–表达式计算


题目描述


计算一个表达式的运算结果


使用C++自带stack堆栈对象来实现


参考课本的算法伪代码P53-54


例如


Push (OPTR, ‘#’);表示把字符#压入堆栈OPTR中,转换成c++代码就是OPTR.push(’#’);


Pop(OPND, a); 表示弹出栈OPND的栈顶元素,并把栈顶元素放入变量a中。因此改成c++代码是两个操作:

a = OPND.top();

OPND.pop();


a = GetTop(OPND)表示获取栈OPND的栈顶元素,转成c++代码就是: a = OPND.top();


884df6147b6341e38acab68f3b9e9e5d.png


08c07f165f3f41a18d4e8ad8816c5781.png

33c752a5947c473684d7a76bc936f9a1.png


输入


第一个输入t,表示有t个实例


第二行起,每行输入一个表达式,每个表达式末尾带#表示结束


输入t行


输出


每行输出一个表达式的计算结果,计算结果用浮点数(含4位小数)的格式表示


用cout控制浮点数输出的小数位数,需要增加一个库文件,并使用fixed和setprecision函数,代码如下:


#include
#include
using namespace std;
int main()
{ double temp = 12.34
cout<<fixed<<setprecision(4)<<temp<<endl;
}


输出结果为12.3400


输入样例


2

1+2*3-4/5#

(66+(((11+22)*2-33)/3+6)*2)-45.6789#



输出样例


6.2000

54.3211


参考代码

#include <iostream>
#include <stack>
#include <string>
#include <cstdlib>
#include <iomanip>
#include <cstring>
using namespace std;
#define ok 0
#define error -1
#define overflow -1
#define opsetsize 7
typedef int Status;
char Prior[7][7] = {
  '>',
  '>',
  '<',
  '<',
  '<',
  '>',
  '>',
  '>',
  '>',
  '<',
  '<',
  '<',
  '>',
  '>',
  '>',
  '>',
  '>',
  '>',
  '<',
  '>',
  '>',
  '>',
  '>',
  '>',
  '>',
  '<',
  '>',
  '>',
  '<',
  '<',
  '<',
  '<',
  '<',
  '=',
  ' ',
  '>',
  '>',
  '>',
  '>',
  ' ',
  '>',
  '>',
  '<',
  '<',
  '<',
  '<',
  '<',
  ' ',
  '=',
};
float Operate(float a, unsigned char theta, float b)
{
  if (theta == '+')
    return a + b;
  else if (theta == '-')
    return a - b;
  else if (theta == '*')
    return a * b;
  else if (theta == '/')
    return a / b;
}
char OPSET[opsetsize] = {'+', '-', '*', '/', '(', ')', '#'};
Status In(char Test, char *TestOp)
{
  for (int i = 0; i < opsetsize; i++)
  {
    if (Test == TestOp[i])
      return 1;
  }
  return ok;
}
char precede(char Aop, char Bop)
{
  int i, j;
  for (i = 0; i < opsetsize; i++)
  {
    if (OPSET[i] == Aop)
      break;
  }
  for (j = 0; j < opsetsize; j++)
  {
    if (OPSET[j] == Bop)
      break;
  }
  return Prior[i][j];
}
float EvaluateExpression(string MyExp)
{
  stack<char> OPTR;
  stack<double> OPND;
  char TempData[20];
  double Data, a, b, r;
  char theta, Dr[2];
  char c;
  int i = 0;
  OPTR.push('#');
  c = MyExp[0];
  strcpy(TempData, "\0");
  while (c != '#' || OPTR.top() != '#')
  {
    if (!In(c, OPSET))
    {
      Dr[0] = c;
      Dr[1] = '\0';
      strcat(TempData, Dr);
      c = MyExp[++i];
      if (In(c, OPSET))
      {
        Data = (float)atof(TempData);
        OPND.push(Data);
        strcpy(TempData, "\0");
      }
    }
    else
    {
      switch (precede(OPTR.top(), c))
      {
      case '<':
        OPTR.push(c);
        c = MyExp[++i];
        break;
      case '=':
        OPTR.pop();
        c = MyExp[++i];
        break;
      case '>':
        double a = OPND.top();
        OPND.pop();
        double b = OPND.top();
        OPND.pop();
        theta = OPTR.top();
        OPTR.pop();
        OPND.push(Operate(b, theta, a));
        break;
      }
    }
  }
  return OPND.top();
}
int main()
{
  string Exp;
  int t;
  double result;
  cin >> t;
  while (t--)
  {
    cin >> Exp;
    result = EvaluateExpression(Exp);
    cout << fixed << setprecision(4) << result << endl;
  }
  return 0;
}
相关文章
|
算法 编译器
数据结构堆栈(中缀到后缀)
数据结构堆栈(中缀到后缀)
56 0
|
存储 算法 C++
堆栈数据结构(介绍与程序)
堆栈数据结构(介绍与程序)
99 0
|
IDE 开发工具 Windows
数据结构——堆栈
时间过的真快呀,上次发文章还是在2月,上学之后很忙,现在肯定要将数据结构的内容尽快的更新完成,早日拿到专家博主。Stack叫栈,或者叫堆栈,这是一个很重点的概念,我将在这篇文章中举出很多的例子,让你能在生活中,windows系统发现那些叫做栈。
152 0
数据结构——堆栈
|
存储 Java 索引
21.从入门到精通:Python数据结构 列表 将列表当做堆栈使用 将列表当作队列使用 列表推导式 嵌套列表解析 del 语句
21.从入门到精通:Python数据结构 列表 将列表当做堆栈使用 将列表当作队列使用 列表推导式 嵌套列表解析 del 语句
|
存储 Java
数据结构(1)线性结构——数组、链表、堆栈、队列(介绍和JAVA代码实现)
1.1.线性表 线性表是指由同种元素构成的有序且线性的一种数据结构,由于其有序且线性的特点,可以抽象出对其的一个操作集:
104 0
|
算法 数据可视化 C语言
数据结构 | 后缀表达式【深入剖析堆栈原理】
数据结构之堆栈的应用中的后缀表达式讲解,层层递进,由浅入深,带你深刻理解后缀表达式
372 0
数据结构 | 后缀表达式【深入剖析堆栈原理】
数据结构 | 队列探究与学习、对比堆栈、队列存储实现
前言:上一篇我们讲解了堆栈相关的知识点,今天我们就对队列详细讲讲,并在此文中将其与堆栈进行适当对比,队列最主要的两个操作是什么呢,我们一起往下看吧 队列(Queue) 概念: 具有一定操作约束的线性表,插入和删除操作,只能在一端插入,而在另一端删除 堆栈也是受限的线性表,但它的插入和删除只在一端进行 数据插入:入队列(AddQ) 数据删除:出队列(DeleteQ) 先来先服务,先进先出(FIFO) 堆栈——先进后出 队列抽象数据类型描述 数据对象集:
|
存储 算法 C语言
C语言数据结构 | 堆栈顺序、链式存储及表达式求值
从计算机对表达式求值引入算数表达式在求值时若无优先级,那么从左到右运算就很容易,但算术表达式由两类对象构成一个是一个是+-*/······不同的运算符号优先级也不一样此时运算就比较困难 ,无法判断运算符后一个运算数是否参与这次运算。
C语言数据结构 | 堆栈顺序、链式存储及表达式求值
|
存储 算法 C++
【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++
简单来说,数据结构是一种辅助程序设计并且进行优化的方法论,它不仅讨论数据的存储与处理的方法,同时也考虑到了数据彼此之间的关系与运算,从而极大程度的提高程序执行的效率,减少对内存空间的占用等。不同种类的数据结构适用于不同的程序应用,选择合适正确的数据结构,可以让算法发挥出更大的性能,给设计的程序带来更高效率的算法。
156 0

热门文章

最新文章