关于给定栈求出所有合法栈的思考
来源:互联网 发布:淘宝高仿运动鞋店推荐 编辑:程序博客网 时间:2024/06/04 01:08
关于给定栈求出所有合法栈的思考
前几天看到一篇关于给定几个元素,给一个出栈的顺序,判断出栈的顺序是否合法,我们也可以通过给定的元素顺序求出所有的合法的出栈顺序,困扰我的问题是如何求出给定元素的所有的排列问题,之前有篇博文也有求三个数的全序列的,但采用的是三个for循环,实在是too young too simple,效率低不说,而且没有一点实用性,总不能几个数几个for循环,这也太傻了()。
对于判断出栈的合法性问题,我先把思想写出来,至于代码实现需要过两天,求所有的合法出栈顺序有两种思路。
方案1:一种是将所有元素的排列求出来,然后将每种都带入到判断栈的合法性的函数中,从而将合法的选出来。
方案2:第二种思路是利用之前括号匹配的思想,压栈为0,出栈为1,出栈的前提是0的个数大于1的个数,然后将所有的可能保存下来,就是所有的合法出栈顺序。
很明显方案2效率高,但博主对于第二中方案的实现实在有压力,先把第一种简单实现下,第二中方案的实现尽快补上()
方案一代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
using namespace std;
#pragma once
#include<iostream>
#include<stack>
using namespace std;
bool Check_Push_Pop(int* pPush, int* pPop, int length)
{
if (length <= 0 || pPush == NULL || pPop == NULL)
{
return false;
}
int in = 0;
int out = 0;
stack<int> s;
//s.push(pPush[0]);
int index = 0; //压入元素的个数
for (out = 0; out < length; out++)
//(1)for循环控制什么,记录弹出了几个元素
{
for (in = index; in <= length; in++)
//pPush[1,2,3,4,5] pPop[4,5,3,2,1] 控制压入了几个元素
{
if ((s.empty()) || s.top() != pPop[out])
//(2)为什么要进行判空 当栈中为空时必须进行压栈操作
{
if (in == length)
//(3)此时所有元素已经压栈但并没找到出栈的元素,证明出栈的元素不合法
{
return false;
}
s.push(pPush[in]);
++index;
}
else //栈顶的元素和弹出的元素相等,直接弹出
{
s.pop();
break; //跳出这层for循环,使它遍历下一个出栈元素
}
}
}
return true;
}
void SWAP(int *a, int *b) //交换数组中的两个元素
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void perm(int *list, int i, int n,int& count,int* push)
{
int j = 0;
if (i == n)
{
if (Check_Push_Pop(push, list, n))
{
for (j = 0; j < n; j++)
{
cout << list[j];
cout << " ";
}
count++;
cout << endl; //加
}
}
else
{
for (j = i; j < n; j++)
{
SWAP(list + i, list + j);
perm(list, i + 1, n,count,push);
SWAP(list + i, list + j);
}
}
}
int main()
{
int list[4] = { 1, 2, 3, 4}; //入栈的元素
int push[4] = { 1, 2, 3, 4};
cout << "Please input a number!" << endl;
int n = 0;
int count = 0;
cin >> n;
perm(list, 0, n,count,push);
cout << count << endl;
system("pause");
return 0;
}
方案1的实现的难点主要在于递归的使用,实现的思想是将数组中的每一元素放在第一位,然后递归将第二位当做第一位继续递归,直至i等于n,打印出来随后的过程是从后向前逐个交换,从而实现全排列。全排列的数组传到断 Check_Push_Pop()函数中判断,若合法则打印,否则不打印。
方案2随后奉上
博主学识尚欠,若有理解错误的地方,请大神指出错误,,博主一定认真分析,尽快修改。
本文出自 “qin-wang” 博客,请务必保留此出处http://10810196.blog.51cto.com/10800196/1763997
- 关于给定栈求出所有合法栈的思考
- 求出数组中满足给定和的所有元素组合
- 求出对应N的所有合法匹配括号 (DFS)---小米笔试题
- 【递归】输出给定的n对括号对的所有合法序列
- 每日一题:给定n, 求出小于n的所有数中1的位数
- 求出一个给定数字的所有因子(6 = 2 * 3)
- 给定一段连续的整数,求出他们中所有偶数的平方和以及所有奇数的立方和。
- 给定有序序列 a,b,求出所有a[i]+b[j]中所的第k小的数
- 给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数
- 给定一个十进制整数N,求出从1到N的所有整数中出现”1”的个数。
- 卡特兰数(Catalan)应用:输出所有N对合法括号序列和输出所有已知进栈序列的合法出栈序列
- 给定一个数组,数组中有正负数,求出所有字数组中和值最大的值。
- 求出范围内所有的素数
- 关于栈的小思考
- 给定入栈顺序,输出所有可能出栈情况及所有情况的总数
- 给定一个序列,输出所有满足栈规则的所有情况
- 练习题目18. 给定一段连续的整数,求出他们中所有偶数的平方和以及所有奇数的立方和。
- 栈的合法输出序列
- 在数组中快速找到只出现一次的数
- 模拟实现string类
- c++中的动态内存管理
- 一个数组实现两个栈
- C++ map的基本使用方法
- 关于给定栈求出所有合法栈的思考
- Linux下的 文件的三个时间参数
- Linux的下的文件查找命令find
- Linux配置vim ctags g++ IDE GDB
- Linux shell 指令
- 通过实现Linux下的进度条引发的一系列问题
- js 获取外部变量 setInterval 一定要 匿名函数调用
- Linux下Makefile
- 操作系统常见的调度算法