【记录】【C++】【栈】【数据结构实验】(四)

一、实验作业相关要求

实验四 栈和队列

1、实验目的与要求

1)熟悉栈、队列的类型定义和基本操作;
2)灵活应用栈、队列解决具体应用问题。

2、实验内容

1.判断回文数,回文是指正读反读均相同的字符序列,如“1221”和“12321”均是回文,但“1234”不是回文。
请写一个算法判定给定的字符向量是否为回文。
(提示:将一半字符入栈)。

2.输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。
假设压入栈的所有数字均不相等。
例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。
示例 1:
输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
示例 2:
输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
输出:false
解释:1 不能在 2 之前弹出。
提示:
0 <= pushed.length == popped.length <= 1000
0 <= pushed[i], popped[i] < 1000
pushed 是 popped 的排列

3、实验结果

1)请将调试通过的主要源代码、输出结果粘贴在下面

2)简述算法步骤,格式如下:
S1:
S2:
S3:

3)请分析算法的时间复杂度。

二、源代码

将其写在同一项目

在这里插入图片描述

主函数源代码(submit.cpp)如下:

#include <iostream>
#include<string>
#include<vector>
#include "SeqStack.h"
#include "Solution.h"
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */


int main(int argc, char** argv) {
	string inp;
	cout<<"请输入字符串判断是否回文:\n";
	cin>>inp;
	cout<<"此字符串"<<(Solution().judgePalindrome(inp)==1?"是":"不是")<<"回文字符串!\n"<<endl;
	cout<<"请输入整数序列的长度:\n";
	int length;
	cin>>length;
	vector<int>  pushed(length);
	vector<int>  popped(length);
	cout<<"请输入入栈序列:\n";
	for(int i=0;i<length;i++){
		cin>>pushed[i];
	}
	cout<<"请输入可能的出栈序列:\n";
	for(int i=0;i<length;i++){
		cin>>popped[i];
	}
	cout<<"第二个序列"<<(Solution().judgePoppedByPushed(pushed,popped)==1?"是":"不是")<<"该栈的弹出顺序!\n"<<endl;
	return 0;
}

定义栈的头文件(SeqStack.h)如下:

#include<iostream>
using namespace std;

template<class T>
class Stack{
public:
	Stack(){};
	virtual void Push(T x) = 0;
	virtual bool Pop() = 0;
	virtual T Top() const = 0;
	virtual bool Empty() const = 0;
	virtual bool Full() const = 0;
	virtual int Size() const = 0;
};

template<class T>
class SeqStack: public Stack<T>{
public:
	SeqStack(int size = 50);
	~SeqStack() {delete []elems;};
	void Push(T x);
	bool Pop();
	T Top()const;
	bool Empty()const {return top == -1;};
	bool Full()const {return top == maxsize-1;};
	int Size()const {return top+1;};
	void makeEmpty() {top = -1;}
private:
	T* elems;
	int top;
	int maxsize;
	void overflow()const;
};

template<class T>
SeqStack<T>::SeqStack(int size){
	if(size <= 0){
		this->overflow();
	}
	elems = new T[size];
	if(!elems){
		this->overflow();
	}
	maxsize = size;
	top = -1;
}

template<class T>
void SeqStack<T>::Push(T x){
	if(this->Full()){
		this->overflow();
	}
	elems[++top] = x;
}

template<class T>
bool SeqStack<T>::Pop(){
	if(this->Empty()){
		return false;
	}
	top--;
	return true;
}

template<class T>
T SeqStack<T>::Top()const{
	if(this->Empty()){
		this->overflow();
	}
	return elems[top];
}

template<class T>
void SeqStack<T>::overflow()const{
	cerr<<"overflow!!!"<<endl;
	exit(-1);
}

方法类的头文件(Solution.h)如下:

#include<iostream>
//#include "SeqStack.h"
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

class Solution{
public:
	bool judgePalindrome(string inp);
	bool judgePoppedByPushed(vector<int>& pushed,vector<int>& popped);
};


bool Solution::judgePalindrome(string inp){
	if(inp.size()<=1){
		return true;
	}
	Stack<char>* store=new SeqStack<char>(inp.size()/2);
	for(int i=0;i<=inp.size()-1;i++){
		if(inp.size()%2==0){
			if(i<=inp.size()/2-1){
				store->Push(inp[i]);
			}else{
				if(store->Top()!=inp[i]){
					return false;
				}else{
					store->Pop();					
				}
			}
		}else{
			if(i<inp.size()/2){
				store->Push(inp[i]);
			}else if(i==inp.size()/2){
				continue;
			}else{
				if(store->Top()!=inp[i]){
					return false;
				}else{
					store->Pop();					
				}
			}
		}
	}
	delete store;
	return true;
}
bool Solution::judgePoppedByPushed(vector<int>& pushed,vector<int>& popped){
	if(pushed.size()<=1){
        return true;
    }
    Stack<int>* store=new SeqStack<int>(pushed.size());
    store->Push(pushed[0]);
    int i=1,j=0;
    while(true){
        if(!store->Empty()&&j<popped.size()&&store->Top()==popped[j]){
            store->Pop();
            j++;
        }else if(i<pushed.size()){
            store->Push(pushed[i]);
            i++;
        }else{
            if(!store->Empty()){
                return false;
            }else{
                break;
            } 
        } 
    }
	delete store;
    return true;
}

执行效果:
在这里插入图片描述

三、作业提交的文档内容

1)请将调试通过的主要源代码粘贴在下面

如上

2)简述算法步骤:

第一题

S1:判断字符串是奇数长度还是偶数长度,确认前一半的长度

S2:遍历字符串,前一半字符逐个入栈,后一半字符与逐个出栈的元素进行比对,若字符串回文,将是一一相等的

S3:比对过程中一旦碰到不相等的情况,中止返回flase;而若正常结束循环,返回true

第二题

S1:我们先假设弹出序列可以得到,模拟一遍入栈、弹出的过程,定义两个指针 i 与 j ,分别指向两序列,定义一个栈来存储。

S2:在一层循环中,每次进行一系列判断,若栈中存在元素且 j 指向的元素正好等于栈顶元素,便弹出栈顶,指针 j 向后移动一次;若栈为空或栈顶元素不等于 j 所指向元素,便将 i 指向的元素入栈,指针 i 向后移动;而若入栈序列已然遍历完且无法继续按照出栈序列弹出栈顶,循环结束。

S3:此时判断栈是否为空,若栈非空,则表明栈无法按照出栈序列弹出所有元素,返回false;若栈空,则表明栈按照出栈序列弹出所有元素,返回true。

3)请分析算法的时间复杂度。

第一题

只需循环一遍,入栈前一半,出栈后一半,所以时间复杂度为O(n)

第二题

一层循环的最坏情况下,入栈n次,出栈n次,总共遍历2n次,此时正是能按弹出序列弹出的情况;而其余的情况下,未能出栈n次,遍历次数小于2n次。
综上,时间复杂度为O(n)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值