火车入栈出栈序列

A stack may be regarded as a railway switching network like the one in the figure.
Cars numbered 1, 2, …, n are on the line at the left, and it is desired to rearrange (permute) the cars as they leave on the right-hand track. A car that is on the spur (stack) can be left there or sent on its way down the right track, but it can never be sent back to the incoming track. For example, if n=3, and we have the cars 1,2,3 on the left track, then 3 first goes to the spur. We could then send 2 to the spur, then on its way to the right, then send 3 on the way, then 1, obtaining the new order 1,3,2.
For general n, find how many permutations can be obtained by using this stack. And output all the permutations by using the switching network in the figure.

分析

三条轨道相应记为left, down, right…显然用递归方法解决此问题很直观,易懂

为简化分析,假设left的数都要经过down,(即使left直接去到right也当成是先到down再到right),且数不能从downright回到left

则有3种情况

  • left中没有数时,此时数都已在downright, 这种情况下,顺序已经确定,无法再更改顺序. right的数依次出栈输出, 然后再将down的数依次出栈输出
  • down中没有数时,此时只能将left中的数出栈, 压到down..
  • 当不属于上述两种情况时,leftdown中都有数时,

此时有两中选择

1.)left中的一个数出栈, down

2.)left中的数不变, down中的一个数出栈,压到right

很显然,left,只需在一端操作, 可以将其设计为stack;

同样,down也只需在一端操作,且具有先进先出特点, 适合设计为stack

right需要在两端操作, 1种情况时,需要在一端将数出栈输出, 而在第3种情况中,将从down中出来的数,要压到right的另一端, 故可将right设计为双端队列deque

由以上分析, 借助C++ STL中的模版类,很容易写出具体实现出来, 代码见文件train.cpp

所有排列输出到文件D:/output.txt


由于此问题所有的排列的总数是Catlan数, 由Catlan数计算公式,写了个函数验证一下上述递归方法解的个数是否正确..

关于catalan数,可见这篇文章

下面是n=4时的所有排列, 输出序列为从左到右
4 3 2 1 (4先出栈,1最后出栈)
4 3 1 2
4 2 3 1
4 2 1 3
4 1 2 3
3 4 2 1
3 4 1 2
3 2 4 1
3 2 1 4
3 1 2 4
2 3 4 1
2 3 1 4
2 1 3 4
1 2 3 4
Total number of all the permutations is 14


//  train.cpp

#include 
< iostream >
#include 
< fstream >
#include 
< stack >
#include 
< queue >

using   namespace  std;


int  counter = 0 ;

long   double  catalan( int  n)
{
    
if(n==0)    return 1;
    
else return (4*n-2)*catalan(n-1)/(n+1);
}



void  recur(stack < int >  left, stack < int >  down, deque < int >  right, ofstream &  fout)
{
    
int left_num=left.size();
    
int down_num=down.size();
    
if(left_num==0)
    
{
        
while(!right.empty())
        
{
            cout
<<right.front()<<" ";
            fout
<<right.front()<<" ";
            right.pop_front();
        }

        
while(!down.empty()){
            cout
<<down.top()<<" ";
            fout
<<down.top()<<" ";
            down.pop();
        }

        fout
<<endl;
        cout
<<endl;
        counter
++;
        
return ;
    }

    
else if(down_num==0)
    
{
        down.push(left.top());
        left.pop();
        recur(left, down, right, fout);
    }
    
    
else {
        
int temp=down.top();
        right.push_back(temp);
        down.pop();
        recur(left, down, right, fout);
        right.pop_back();
        down.push(temp);
        down.push(left.top());
        left.pop();
        recur(left, down, right, fout);
    }

    
return ;    
}


int  main()
{
    
int num;
    ofstream fout;    
    cout
<<"Input a number: ";
    
while(cin>>num)
    
{
        fout.open(
"d:/permutations.txt");
        counter
=0;
        stack
<int> left;
        stack
<int> down;
        deque
<int> right;
        
int i=1;
        
while(i<=num)
        
{
            left.push(i);
            i
++;
        }

        recur(left, down, right, fout);
        cout
<<"Total number of all the permutations is "<<counter<<endl;
        fout
<<"Total number of all the permutations is "<<counter<<endl;
        cout
<<" Input a number: ";
        fout.close();
    }

    
return 0;
}



你可能感兴趣的:(C++,NetWork,iostream,output)