C++栈类火车调度问题MFC栈类

Posted bcbobo21cn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++栈类火车调度问题MFC栈类相关的知识,希望对你有一定的参考价值。

先看一下C++基本栈类的使用;

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

int _tmain(int argc, _TCHAR* argv[])

	stack<int> s;

	s.push(0);
	s.push(303);
	s.push(909);
	s.pop();

	cout << s.top() << endl;

    return 0;

 

然后看火车调度问题;

这题大概是ACM里的基础题;题目描述如下;

设有编号为1,2,3,4,5,6~~~n的n辆列车,顺序进入一个栈式结构的站台。列出这n辆车的所有可能出站的顺序。 
Input:
输入列车辆数和编号
Output:
输入所有列车出站的序列用空格隔开车编号


Sample Input:
3
1 2 3
Sample OutPut:
1   2   3 
1   3   2 
2   3   1 
2   1   3 
3   2   1

栈和车是如下示意的;

可以全部开进栈,再往B端出;或先进去3个、2个、1个,再调度往B端出;

某些排列是不可能的;

编程实现起来用栈比较方便;

网上找到一个程序,它的样例输入输出如下;

Input

5 2
1 2 3 5 4

Output

push
pop
push
pop
push
pop
push
push
pop
pop

第一行输入2个整数:车数量,先进到栈里的车数量;

第二行输入一种排列;

如果排列可行,则输出操作序列,如果排列不可行,则输出no;

代码如下;

// hcddtest.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include <stack>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])

	int a[50], c[50];
    bool operation[50];

    int i = 0;
    int t, t1, m, m1 = 0, n, i1 = 0;

    cin >> t;
    for (t1 = 0; t1 < t; t1++) 
        cin >> n >> m;
        for (i = 0; i < n; i++) 
            cin >> a[i];
        
        int step = 0, b = 1;
        stack<int>s;
        s.push(0);
        for (i = 0; i < n; i++) 
            while (s.top() < a[i]) 
                s.push(b++);
                operation[step++] = true;
            
            if (s.size()>m + 1) 
                cout << "no\\n";
                i1 = 1;
                break;
            
            if (s.top() == a[i]) 
                s.pop();
                operation[step++] = false;
            

        
        if (i1 != 1) 
            if (s.size() == 1 && s.top() == 0)
                for (i = 0; i < step; i++) 
                    if (operation[i] == true) cout << "push\\n";
                    else cout << "pop\\n";
                
            else cout << "no\\n";
        
    

    return 0;

但是程序还有点小问题;目前没时间看;输出有些问题,

 

 总之要理解题目、数据结构栈才能做;

然后看一下MFC里面,可能没有栈类;网上找到一个栈类;

#pragma once

#ifndef STACK_H_
#define STACK_H_
#include<iostream>
//结点结构体,双向栈
template<class T>
struct StackNode

	T _tData;                                  //数据域
	StackNode<T>* _pNext;                      //指针域,指向下一结点
	StackNode<T>* _pLast;                      //指针域,指向上一结点(为了行编辑器函数的实现)
	StackNode(StackNode<T>* next = nullptr, 
		StackNode<T>* last = nullptr)         //用指针构造函数
		this->_pNext = nullptr;
		this->_pLast = nullptr;
	
	StackNode(T data, StackNode<T>* next = nullptr, 
		StackNode<T>* last = nullptr)         //用指针构造函数
		this->_tData = data;
		this->_pNext = next;
		this->_pLast = last;
	
;

template<class T>
class Stack 
private:
	StackNode<T>* _pTop;                             //栈顶指针
	StackNode<T>* _pBottom;                          //栈底指针,为了方便行编辑器使用
	int _iConuntOfElement;                           //结点数量
public:
	Stack();                                         //构造函数
	Stack(Stack<T>& copy);                           //构造函数
	~Stack();                                        //析构函数
	bool IsEmpty();                                  //判断栈是否为空
	void MakeEmpty();                                //将栈中的元素全部删除
	void Put(const T data);                          //顶端插入数据
	int Size()  return _iConuntOfElement;          //返回栈中的结点数
	void GetTop(T& data);                            //获取顶端结点
	void Pop(T& data);                               //顶端弹出结点,并将元素传至参数中
	void Traverse();                                 //逆序栈中的结点
	void DisPlay(bool forward = true);               //输出函数,默认正向输出
;

//构造函数,为栈顶和栈底分配内存
template<class T>
Stack<T>::Stack() 
	_pTop = _pBottom = nullptr;
	this->_iConuntOfElement = 0;


//拷贝构造函数
//缺少此函数,在传参与析构的时候容易出问题
template<class T>
Stack<T>::Stack(Stack<T>& copy) 
	StackNode<T>* pCur = this->_pTop;            //建立指针,用于遍历本对象中的结点
	while (pCur)                                //遍历本对象的结点
		T data = pCur->_tData;                   //依此取出结点值
		copy.Put(data);                          //插入到copy栈中
		pCur = pCur->_pNext;
	
                          

//析构函数
template<class T>
Stack<T>::~Stack() 
	MakeEmpty();                               //释放结点内存
	this->_pTop  = this->_pBottom = nullptr;   //将指针指向空,避免出现野指针



//判断栈是否为空
template<class T>
bool Stack<T>::IsEmpty() 
	if (!this->_pTop)                           //如果栈对象没有头节点,那么栈就为空
		return true;
	return false;


//将栈中的元素全部删除
template<class T>
void Stack<T>::MakeEmpty()                                  
	StackNode<T>* pDel = nullptr;                 //建立临时结点指针,用于释放结点内存
	while (_pTop)                                //循环依此从顶端删除
		pDel = this->_pTop;
		this->_pTop = _pTop->_pNext;
		delete pDel;
	
	_iConuntOfElement = 0;                         //栈结点数量置零


//顶端插入数据
template<class T>
void Stack<T>::Put(const T data) 
	StackNode<T>* newData = new StackNode<T>(data);  //为新结点分配内存,新结点的并确定结点指针指向
	if (!newData)                                  //如果内存分配错误
		std::cerr << "内存分配错误!" << std::endl;
		exit(-1);
	

	if (this->IsEmpty())                            //如果插入的是第一个结点
		newData->_pLast = nullptr;                   //将这个结点的指向上一下一结点的指针都赋空值
		newData->_pNext = nullptr;
		this->_pTop = newData;                       //将栈顶和栈底指针都指向这个结点
		this->_pBottom = newData;
		++this->_iConuntOfElement;                  //节点数加1
		return;
	                          
		
	this->_pTop->_pLast = newData;                  //栈顶的上一结点指针指向新结点
	newData->_pNext = this->_pTop;                  //将新结点的下一结点指针指向栈顶   
	this->_pTop = newData;                          //新结点作为栈顶
	++this->_iConuntOfElement;


//获取顶端结点
template<class T>
void Stack<T>::GetTop(T& data) 
	if (this->IsEmpty())           //栈为空,直接返回
		return;
	data = this->_pTop->_tData;    //获取栈顶元素,赋值给返回参数
	return;


//顶端弹出元素,并将元素传至参数中
template<class T>
void Stack<T>::Pop(T& data) 
	if (this->IsEmpty())                      //栈为空,直接返回
		return;
	data = this->_pTop->_tData;               //先取出栈顶的值
	StackNode<T>* pDel = this->_pTop;         
	if (this->_pTop->_pNext)                 //如果有后继结点,就将后继结点的上一个指针指向空
		this->_pTop->_pNext->_pLast = nullptr;
		this->_pTop = this->_pTop->_pNext;
		delete pDel;                         //释放原栈顶内存
		--this->_iConuntOfElement;           //栈结点数量递减
		return;
	                    
	delete pDel;                               //如果就只有一个结点,直接释放原栈顶的空间
	this->_pTop = this->_pBottom = nullptr;    //没有后继结点,释放栈顶空间,将指针指向空,避免出现野指针
	--this->_iConuntOfElement;                 //栈结点数量递减
	return;
 

//逆序栈中的结点
template<class T>
void Stack<T>::Traverse() 
	StackNode<T>* pCur = this->_pTop;
	StackNode<T>* pTmp = nullptr;       //临时指针,循环要用
	while (pCur)                       //循环将栈中结点的前驱与后继指针对调
		pTmp = pCur->_pLast;
		pCur->_pLast = pCur->_pNext;
		pCur->_pNext = pTmp;
		pCur = pCur->_pLast;           //这个是很值得细细品味的
	
	//将栈顶与栈顶指针对调
	pTmp = this->_pTop;
	this->_pTop = this->_pBottom;
	this->_pBottom = pTmp;
	return;


//输出函数
template<class T>
void Stack<T>::DisPlay(bool forward = true) 
	StackNode<T>* pCur;
	if(forward == true)
		pCur = this->_pTop;
	else
		pCur = this->_pBottom;
	while (pCur)                              //如果当前指针不为空,就一直循环遍历
		std::cout << pCur->_tData;             //为了照顾
		//if (iCount % 10 == 0)                //每隔十个换一行,以免输出的太长
		//	std::cout << std::endl;
		if (forward == true)
			pCur = pCur->_pNext;
		else
			pCur = pCur->_pLast;
	
	std::cout << std::endl;
     

#endif // !STACK_H_

调用的代码如下;

void CssView::OnDraw(CDC* pDC)

	CssDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	CString str1;
	Stack<CString> mystack;
	mystack.Put(_T("AAA"));
	mystack.Put(_T("BBB"));
	mystack.Put(_T("CCC"));
	mystack.Put(_T("DDD"));
	
	mystack.GetTop(str1);
	pDC->TextOutW(50,50, str1);
	
	str1.Format(_T("%d"), mystack.Size());
	pDC->TextOutW(50,80, str1);

	CString strTopOfInfix = _T("");
	mystack.Pop(strTopOfInfix);
	mystack.GetTop(str1);
	pDC->TextOutW(50,110, str1);	

 输出如下;

看上去这个类可用;下回继续;

以上是关于C++栈类火车调度问题MFC栈类的主要内容,如果未能解决你的问题,请参考以下文章

栈类Stack

基于数组实现Java 自定义Stack栈类及应用

Leetcode练习(Python):栈类:第145题:二叉树的后序遍历:给定一个二叉树,返回它的 后序 遍历。

Leetcode练习(Python):栈类:第145题:二叉树的后序遍历:给定一个二叉树,返回它的 后序 遍历。

Leetcode练习(Python):栈类:第144题:二叉树的前序遍历:给定一个二叉树,返回它的 前序 遍历。

Leetcode练习(Python):栈类:第144题:二叉树的前序遍历:给定一个二叉树,返回它的 前序 遍历。