【问题标题】:Towers of Hanoi C++ Implementation with StacksTowers of Hanoi C++ 使用栈实现
【发布时间】:2018-08-20 02:49:18
【问题描述】:

我为带有堆栈的递归 ToH 算法编写了以下代码,但无法弄清楚它失败的原因。没有编译错误,但是一旦程序真正开始运行,它会“思考”一点然后崩溃。有什么想法吗?

相关代码:

void algoritmoDeTorres(int numDiscos, pila &origen, pila &aux, pila &meta)
{
    GotoXY(0,0);
    if(numDiscos==1)
    {
        int item;
        item = origen.pop(); //crashes in this function
        lista laux;
        laux.insertaInicio(item);
        meta.push(item);
        return;
    }
    algoritmoDeTorres(numDiscos - 1, origen, aux, meta);
    origen.imprimePila();
    cout << endl;
    aux.imprimePila();
    cout << endl;
    meta.imprimePila();
    algoritmoDeTorres(numDiscos -1, aux, meta, origen);
}


class pila
{
    private:
        lista lisst;
    public:
        int pop()
        {
            int tam;
            tam = lisst.regresaItem();
            lisst.borraInicio();
            return tam;
        }        
    };

class lista
{
private:
    nodo *cabeza;
public:
    lista()
    {
        cabeza = NULL;
    }
    void borraInicio()
    {
        nodo * aux;
        aux = cabeza->next; 
        delete cabeza;
        cabeza = aux;
    }
    int regresaItem()
    {
        return cabeza->item; //crashes here specifically
    }
};

class nodo
{
public:
    int item;
    nodo* next;

    nodo(int a,nodo * siguiente)
    {
        item = a;
        next = siguiente;
    }
};

int main()
{
    pila ORIGEN,AUX,META;
    ORIGEN.push(3);
    ORIGEN.push(2);
    ORIGEN.push(1);

    algoritmoDeTorres(ORIGEN.Size(),ORIGEN,AUX,META);

    ORIGEN.destruirPila();
    AUX.destruirPila();
    META.destruirPila();
    return 0;
}

PS:对不起,西班牙语,我的课是西班牙语,但许多想法仍然用英语提出,因此是时髦的语言。

必要时提供重要的翻译:

aloritmoDeTorres - 塔算法

迪斯科 - 磁盘

pila - 堆栈

起源 - 起源

元 - 目的地/目标

InsertaInicio - 插入(在)开始

印记 - 打印

Regresa - 返回

Borra - 擦除/删除

Nodo - 节点

Cabeza - 头

Siguiente - 下一个

【问题讨论】:

  • 谢谢你,我对不恰当的帖子很不好,不知道,我现在知道了。
  • 这段代码,确切地,正如所呈现的那样,不可能编译,更不用说运行到故障点了。缺少的成员函数个数、函数和类的顺序等
  • @WhozCraig 在调试手表之后我发现代码失败的地方(分段错误),它发生在提供的代码中,我没有包括其余部分,因为它与失败无关(我不认为)。 pop 函数在直接应用于 main 时实际上可以工作,所以我认为在提供的代码中从一个类传递到另一个类时会发生错误(我只是不确定为什么)。
  • aux-&gt;item = ... 看看那个aux 变量。 aux 指向 nothing 确定。事实上,它已在上面的行中声明,并且从未设置为指向 anything。你幸运它崩溃了,因为至少你可以看到问题出在哪里。仅供参考,这个问题至少在另一个地方重复出现。这是您需要检查指针如何工作的标志。

标签: c++ algorithm recursion stack towers-of-hanoi


【解决方案1】:

主要是重新安排课程,并填补空白:

#include <iostream>

using namespace std;

class nodo
{
public:
    int item;
    nodo* next;

    nodo(int a,nodo * siguiente)
    {
        item = a;
        next = siguiente;
    }
};

class lista
{
private:
    nodo* cabeza;
    nodo* p;
public:
    lista()
    {
        cabeza = NULL;
        p = NULL;
    }
    void insertaInicio(int n)
    {
        //create a new node
        cabeza = new nodo(n, p);
        //set next pointer to head
        p = cabeza;

    }
    void borraInicio()
    {
        nodo * aux;
        aux = cabeza->next; 
        delete cabeza;
        cabeza = aux;
    }
    int regresaItem()
    {
        return cabeza->item;
    }
};

class pila
{
private:
    //sz (with getters and setters) used to keep track of the size of the stack
    //(incremented in push, decremented in pop)
    int sz;
    lista lisst;
public:
    pila()
    {
        sz = 0;
    }
    int size()
    {
        return sz;
    }
    void setsize(int size)
    {
        sz = size;
    }
    void push(int n)
    {
        lisst.insertaInicio(n);
        sz++;

    }
    int pop()
    {
        int tam;
        tam = lisst.regresaItem();
        lisst.borraInicio();
        sz--;
        return tam;
    }
    void imprimePila()
    {
        //a lengthy way to print the stack
        //was abit unusual as the pop function
        //was removing elements from the stack,
        //when all that was necessary was to print them.
        //this was a workaround that just copied the stack,
        //printed (and removed) elements from original stack,
        //but set the empty to stack to the copy,
        //to leave it unchanged.
        //feel free to find a better way for this
        lista copy;
        cout << '[';
        int lsize = this->size();
        int arr[3] = {};
        int ind = 2;
        while (this->size() != 0){
            int item = this->pop();
            arr[ind] = item;
            cout<< item;
            cout << ',';
            ind--;
        }
        for (int i = ind; i < 3; i++){
            copy.insertaInicio(arr[i]);
        }
        cout <<  ']';
        lisst = copy;
        this->setsize(lsize);
    }
};
//the stacks are instantiated globally so they can be printed at every
//recursive step from algoritmoDeTorres()
pila ORIGEN, AUX, META;

void algoritmoDeTorres(int numDiscos, pila &origen, pila &aux, pila &meta)
{
    //if statement used to rearrange discs ONLY if there are any (if numdiscos is more than 0)
    if (numDiscos > 0){
        //move (numDiscos - 1) discs from origen to aux, so they are out of the way
        algoritmoDeTorres(numDiscos - 1, origen, meta, aux);

        //move the exposed disc from origen to meta
        int item;
        item = origen.pop();
        //lista laux;
        //laux.insertaInicio(item);
        //commented this list out since the item
        //is added to the list of stack its being added to in the push call
        meta.push(item);

        ORIGEN.imprimePila();
        AUX.imprimePila();
        META.imprimePila();
        cout << endl;

        //now move the (numDiscos - 1) discs that we left on aux onto meta
        algoritmoDeTorres(numDiscos - 1, aux, origen, meta);
    }
}

int main()
{
    ORIGEN.push(3);
    ORIGEN.push(2);
    ORIGEN.push(1);

    ORIGEN.imprimePila();
    AUX.imprimePila();
    META.imprimePila();
    cout << endl;

    algoritmoDeTorres(ORIGEN.size(), ORIGEN, AUX, META);
    //objects not allocated with 'new' don't need to be explicitly destroyed
    //ORIGEN.destruirPila();
    //AUX.destruirPila();
    //META.destruirPila();

    return 0;
}

【讨论】:

  • 谢谢!实际上我今天让它工作了,在你改变的一些事情中,导致整个代码爆炸的主要原因是我没有构造函数将新列表设置为 NULL。当我尝试为该过程设置动画时,这让我很伤心,但它现在可以工作了:) 再次感谢!
猜你喜欢
  • 1970-01-01
  • 2018-03-26
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 2010-11-27
相关资源
最近更新 更多