| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 784 人关注过本帖
标题:还是汉诺塔的问题
取消只看楼主 加入收藏
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
结帖率:96.25%
收藏
已结贴  问题点数:20 回复次数:6 
还是汉诺塔的问题
书上例题用Stack这个堆栈类来保存每次移动后三个塔内里的情况,但没写出显示出来的代码。
我记得原来论坛里有人做了一个汉诺塔的游戏,不知道他用的是不是堆栈,保存搜没搜出来。
我尝试写出每次移动后输出塔内里情况,按下面的例子,用5调用TowersOfHanoi第一的输出应该为:
**
***
****
*****
因为第一个塔就出错了,所以来不及考虑其它两个塔的输出,不过暂时也没有思路,在同一排同时输出三个塔里的情况。
我写的输出代码 输出了两次1塔里的情况,也就是移动的第三次出错,不知道是错在哪里了.
去掉输出,运行是不会出错的.
#include <iostream.h>
class NoMem
{
public:
    NoMem(){}
};
void OutOfBounds()
{
    throw NoMem();
}
template <class T>
class Stack
{
    public:
        Stack(int MaxStackSize=10);
        ~Stack(){delete []stack;}
        bool IsEmpty()const {return top==-1;}
        bool IsFull()const {return top==MaxTop;}
        T Top()const;
        Stack<T>& Add(const T& x);
        Stack<T>& Delete(T& x);
        int Length(){return top+1;}
        void Output(ostream& out) const;
        Stack<T>& Divide(Stack<T>& x);
        Stack<T>& Merge(Stack<T>& x);
        friend istream& operator>>(istream& in,Stack<T>& x);
    private:
        int top;
        int MaxTop;
        T *stack;
  
};
template <class T>
Stack<T>& Stack<T>::Merge(Stack<T>& x)
{
    int n=top+x.top+2;
    if (MaxTop<n)
    {
        delete []stack;
        stack=new T[n];
    }
    int xi=0;
    for(int i=top+1;i<n;i++)
    {
        stack[i]=x.stack[xi++];
        top++;
    }
    delete []x.stack;
    x.stack=new T[20];
    x.top=-1;
    return *this;
}
template <class T>
Stack<T>& Stack<T>::Divide(Stack<T>& x)
{
    int n=x.top+1;
    for(int i=0;i<n/2;i++)
        {
        stack[i]=x.stack[i];
        top++;
        }
    x.top=0;
    for( ;i<n;i++)
        {
            x.stack[x.top++]=x.stack[i];
        }
    x.top--;
    return *this;
}
template <class T>
istream& operator>>(istream& in,Stack<T>& x)
{
    T t;
    cin>>t;
    x.Add(t);
    return in;
}
template <class T>
void Stack<T>::Output(ostream& out) const
{
    int n=top+1;
    for(int i=0;i<n;i++)
        out<<stack[i] ;
    cout<<endl;
}
template <class T>
ostream& operator<<(ostream& out,Stack<T>& x)
{
    x.Output(out);
    return out;
}
template <class T>
Stack<T>::Stack(int MaxStackSize)
{
    MaxTop=MaxStackSize-1;
    stack=new T[MaxStackSize];
    top=-1;
}
template <class T>
T Stack<T>::Top()const
{
    if(IsEmpty()) throw OutOfBounds();
    else return stack[top];
}
template <class T>
Stack<T>& Stack<T>::Add(const T& x)
{
 
    stack[++top]=x;
    return *this;
}
template <class T>
Stack<T>& Stack<T>::Delete(T& x)
{
    if(IsEmpty()) throw OutOfBounds();
    x=stack[top--];
    return *this;
}
void TowersOfHanoi(int);
class Hanoi
{
    friend void TowersOfHanoi(int);
public:
    void TowerOfHanoi(int n,int x,int y,int z);
private:
    Stack<int> *S[4];
};
void Hanoi::TowerOfHanoi(int n,int x,int y,int z)
{
    int d;
    if(n>0)
    {
        TowerOfHanoi(n-1,x,z,y);
        S[x]->Delete(d);
        S[y]->Add(d);
     
        int l=S[x]->Length();//    从这里
        int t=S[x]->Top();
        for(int i=0;i<l;i++)
        {
            for(int j=0;j<t;j++)
                cout<<"*";
            cout<<endl;
            t++;
        }
        cout<<endl;
                             //           到这里是我写的输入代码,如果去掉运行还是蛮正常
        TowerOfHanoi(n-1,z,y,x);
    }
}
void TowersOfHanoi(int n)
{
    Hanoi X;
    X.S[1]=new Stack<int> (n);
    X.S[2]=new Stack<int> (n);
    X.S[3]=new Stack<int> (n);
    for(int d=n;d>0;d--)
        X.S[1]->Add(d);
    X.TowerOfHanoi(n,1,2,3);
}
void main()
{
    TowersOfHanoi(5);
}

[ 本帖最后由 mfkblue 于 2009-9-3 00:27 编辑 ]
搜索更多相关主题的帖子: 汉诺塔 
2009-09-03 00:24
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
是想不通为什么会错了,想输出图形出来。
如改那段输出代码改为:
    int xl=S[x]->Length();
        int yl=S[y]->Length();
        int zl=S[z]->Length();
        cout<<"x="<<xl<<" ";
        cout<<"y="<<yl<<" ";
        cout<<"z="<<zl<<" ";
        cout<<endl;
运行是很正常的。
2009-09-03 14:35
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
有点想通了,stack空了,我还在取栈顶的值,估计就错这里了.
2009-09-03 15:48
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
有点想通了,stack空了,我还在取栈顶的值,估计就错这里了.
2009-09-03 15:48
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
问题解决:
输出不是很满意,想不到有什么办法可以同一行显示三个塔的状态。
不过有另一个思路就是在栈里保存*号的字符串,然后打印时就不会为了打多少空格和多少*而头痛了,偷懒不写了,做下题去.
下面是改过的输出代码,还是有个问题,怪不得2楼输出在文本文档里,原来输出行数太多,dos框里显示不了前面的.
int xl=S[x]->Length();
        int yl=S[y]->Length();
        int zl=S[z]->Length();
        int xt=0,yt=0,zt=0,i,j,k,t;
        if(!S[x]->IsEmpty())
        {
            cout<<"1:"<<endl;
            xt=S[x]->Top();
            for(i=0;i<xl;i++)
            {
                for(j=0;j<xt;j++)
                    cout<<"*";
                xt++;
                cout<<endl;
            }
            cout<<endl;
        }
        if(!S[y]->IsEmpty())
        {
            cout<<"2:"<<endl;
            yt=S[y]->Top();
            for(i=0;i<yl;i++)
            {
                for(j=0;j<yt;j++)
                    cout<<"*";
                yt++;
                cout<<endl;
            }
            cout<<endl;
        }
        if(!S[z]->IsEmpty())
        {
            cout<<"3:"<<endl;
            zt=S[z]->Top();
            for(i=0;i<zl;i++)
            {
                for(j=0;j<zt;j++)
                    cout<<"*";
                zt++;
                cout<<endl;
            }
            cout<<endl;
        }
        
2009-09-03 16:45
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
其实汉诺塔的递归原理我还没想通,我都不想做这道题了,你倒是做挺起劲
2009-09-04 14:27
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
没事做又改写了一次,这次倒是同一行输出了,可惜输出的顺序又错了,原因是还没搞懂这题的递归原理,不过这次真的不做了,去做火车进站去.
#include <iostream>
#include <string>
using namespace std;


class Hanoi;

template <class T>
class LinkedStack;

template <class T>
class Node
{
    friend Hanoi;
    friend LinkedStack<T>;
    public:
        T data;
        Node<T> *link;
};

template <class T>
class LinkedStack
{
    public:
        LinkedStack(){top=0;}
        ~LinkedStack();
        bool IsEmpty()const {return top==0;}
        bool IsFull() const;
        T Top() const;
        LinkedStack<T>& Add(const T& x);
        LinkedStack<T>& Delete(T& x);
        int Length();
        void Output(ostream& out) const;
        friend istream& operator>>(istream& in,LinkedStack<T>& x);
        LinkedStack<T>& Divide(LinkedStack& x);
        LinkedStack<T>& Merge(LinkedStack& x);
        Node<T>* First()const;
    private:
        Node<T> *top;
};

template <class T>
Node<T>* LinkedStack<T>::First()const
{
    return top;
}

template <class T>
LinkedStack<T>& LinkedStack<T>::Merge(LinkedStack& x)
{
    T t;
    int n=x.Length();
    for(int i=0;i<n;i++)
    {
        x.Delete(t);
        Add(t);
    }
    return *this;
}

template <class T>
LinkedStack<T>& LinkedStack<T>::Divide(LinkedStack& x)
{
    int n=x.Length();
    T t;
    for(int i=0;i<n/2;i++)
    {
        x.Delete(t);
        Add(t);
    }
    return *this;
}

template <class T>
int LinkedStack<T>::Length()
{
    Node<T> *p=top;
    int i=0;
    while(p)
    {
        
        p=p->link;
        i++;
    }
    return i;
}

template <class T>
void LinkedStack<T>::Output(ostream& out) const
{
    Node<T> *p=top;   
    while(p)
    {
        out<<p->data<<" ";
        p=p->link;
    }
    cout<<endl;
}

template <class T>
ostream& operator<<(ostream& out,LinkedStack<T>& x)
{
    x.Output(out);
    return out;
}

template <class T>
LinkedStack<T>::~LinkedStack()
{
    Node<T> *next;
    while(top)
    {
        next=top->link;
        delete top;
        top=next;
    }
}

template <class T>
bool LinkedStack<T>::IsFull()const
{
    try
    {
        Node<T> *p=new Node<T>;
        delete p;
        return false;
    }
    catch(NoMem){return true;}
}

template <class T>
T LinkedStack<T>::Top()const
{
    return top->data;
}

template <class T>
LinkedStack<T>& LinkedStack<T>::Add(const T& x)
{
    Node<T> *p=new Node<T>;
    p->data=x;
    p->link=top;
    top=p;
    return *this;
}

template <class T>
LinkedStack<T>& LinkedStack<T>::Delete(T& x)
{
    x=top->data;
    Node<T> *p=top;
    top=top->link;
    delete p;
    return *this;
}




class Hanoi
{
public:
    Hanoi(int n);
    void Hanoi::TowerOfHanoi(int n,int x,int y,int z);
    LinkedStack<string> S[4];
};

Hanoi::Hanoi(int n)
{
    string a="*",b="",c="";
    int i,j,k;
    for(i=0;i<n;i++)
    {
        for(j=i;j<n;j++)
            b=b+a;
        for(k=0;k<i;k++)
        c=c+" ";
        c=c+b;
        S[1].Add(c);
        b="";
        c=b;
    }
}

void Hanoi::TowerOfHanoi(int n,int x,int y,int z)
{
    string a;
    if(n>0)
    {
        TowerOfHanoi(n-1,x,z,y);
        S[x].Delete(a);
        S[y].Add(a);
        Node<string> *t1,*t2,*t3;
        int i,j,k,s,m;
        i=S[1].Length();
        j=S[2].Length();
        k=S[3].Length();
        if(!S[1].IsEmpty())
            t1=S[1].First();
        if(!S[2].IsEmpty())
            t2=S[2].First();
        if(!S[3].IsEmpty())
            t3=S[3].First();
        for(m=0;m<4;m++)
        {
            if(i<4-m&&j<4-m&&k<4-m)
            {   
                cout<<endl;
                continue;
            }
        
        
            if(!S[1].IsEmpty())
            {
                if(i<4-m)
                for(s=0;s<24;s++)
                        cout<<" ";
                else
                {
                    cout<<t1->data;
                    for(s=0;s<20;s++)
                        cout<<" ";
                    t1=t1->link;
                    i--;
                }
            
            }
            
            if(!S[2].IsEmpty())
            {
                if(j<4-m)
                for(s=0;s<24;s++)
                        cout<<" ";
                else
                {
                    cout<<t2->data;
                    for(s=0;s<20;s++)
                        cout<<" ";
                    t2=t2->link;
                    
                }
            
            }

            if(!S[3].IsEmpty())
            {
                if(k<4-m)
                for(s=0;s<24;s++)
                        cout<<" ";
                else
                {
                    cout<<t3->data;
                    for(s=0;s<20;s++)
                        cout<<" ";
                    t3=t3->link;
                    
                }
            
            }
        
            cout<<endl;
            
        }
        cout<<"  "<<1<<"                        "<<2<<"                      "<<3<<endl;
     TowerOfHanoi(n-1,z,y,x);   
        
    }
}

void main()
{
    Hanoi h(4);
    h.TowerOfHanoi(4,1,2,3);
}
2009-09-05 16:58
快速回复:还是汉诺塔的问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018754 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved