【问题标题】:Printing the Tower of Hanoi Linearly线性打印河内塔
【发布时间】:2014-12-08 21:54:15
【问题描述】:

我无法在 C 中打印河内塔。

我的猜测是,造成这种情况的原因是算法正在递归运行。并且变量 pegSource、pegSpare 和 pegDest 正在切换。导致打印不正确。

输入为 3 时我当前的输出是:

| | | | | | | | | | | | | | | +|+ | | ++|++ | | +++|+++ | | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | ++|++ | | +++|+++ | +|+ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | | +|+ ++|++ +++|+++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | +|+ +++|+++ | ++|++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | +|+ | | ++|++ | +++|+++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | | ++|++ +++|+++ +|+ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | ++|++ | +|+ +++|+++ | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | +|+ | | ++|++ | | +++|+++ | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX

所需的输出是:

| | | | | | | | | | | | | | | +|+ | | ++|++ | | +++|+++ | | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | ++|++ | | +++|+++ +|+ | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | | +++|+++ +|+ ++|++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | +|+ +++|+++ | ++|++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | +|+ | +++|+++ ++|++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | | | +|+ +++|+++ ++|++ XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | | | | ++|++ | +|+ +++|+++ | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX | | | | | | | | | | | | | | | | +|+ | | ++|++ | | +++|+++ | XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXX

这是我的 C 代码:
我尝试将PrintPegs(pegSource, pegDest, pegSpare); 行放在 TOH 函数和 MoveDisk 函数的多个位置。当然没有一个成功。 如果可能的话,我希望能够在上面打印所需的输出而不是我当前的输出。

#include <stdio.h>
#include <stdlib.h>

void PrintPegLine(int layer, int peg[]){
    switch (peg[layer]){
        case 0:
            printf("          |          ");
            break;
        case 1:
            printf("         +|+         ");
            break;
        case 2:
            printf("        ++|++        ");
            break;
        case 3:
            printf("       +++|+++       ");
            break;
        case 4:
            printf("      ++++|++++      ");
            break;
        case 5:
            printf("     +++++|+++++     ");
            break;
        case 6:
            printf("    ++++++|++++++    ");
            break;
        case 7:
            printf("   +++++++|+++++++   ");
            break;
        case 8:
            printf("  ++++++++|++++++++  ");
            break;
        default:
            printf(" XXXXXXXXXXXXXXXXXXX ");
            break;

    }
}

void PrintPegs(int pegSource[], int pegDest[], int pegSpare[]) {
    int layer;
    for (layer=0; layer<9; layer++){
        PrintPegLine(layer, pegSource);
        PrintPegLine(layer, pegDest);
        PrintPegLine(layer, pegSpare);
        printf("\n");
      }
}

void MoveDisk(int pegSource[], int pegDest[]){
    int i,j;
    int temp;

    for (i=0; i<9; i++){
        if (pegSource[i] != 0){
            temp = pegSource[i];
            pegSource[i]=0;
            break;
        }
    }

    for (j=0; j<9; j++){
        if (pegDest[j] != 0){
            pegDest[j-1]=temp;
            break;
        }
    }
}

void TOH(int n, int pegSource[], int pegDest[], int pegSpare[]) {
   if (n > 0) {
      TOH(n - 1, pegSource, pegSpare, pegDest);
      PrintPegs(pegSource, pegDest, pegSpare);
      MoveDisk(pegSource, pegDest);
      TOH(n - 1, pegSpare, pegDest, pegSource);
   }
}



int main(int argc, char **argv)
{
    int n = atoi(argv[1]);
    if (n>8 || n<2){
        printf("invalid input\n");
        exit(0);
    }
    int pegSource[9] = {0,0,0,0,0,0,0,0,9};
    int pegDest[9] = {0,0,0,0,0,0,0,0,9};
    int pegSpare[9] = {0,0,0,0,0,0,0,0,9};
    int i;
    int j = 1;
    for (i=8-n; i<8; i++){
        pegSource[i]=j;
        j++;
    }
      TOH(n, pegSource, pegDest, pegSpare);
      PrintPegs(pegSource, pegDest, pegSpare);
      printf("DONE\n");
    return 0;
}

谢谢

【问题讨论】:

  • 不,递归实际上是解决这类问题的好方法。您的代码中的某处可能存在逻辑错误。我什至无法编译您提供的代码,函数的顺序无效。
  • 对不起代码,我已经更新了它,在我忽略函数顺序警告之前,它编译得很好。我明白这个问题是要递归解决的,这也是我所做的。 (见我的 TOH 功能)。我只是在这里打印有问题。

标签: c recursion printing towers-of-hanoi


【解决方案1】:

您解决河内塔的算法很好。问题在于您如何称呼PrintPegs()。当您递归时,您正确地排列了pegSourcepegSparepegDest 的顺序——但这也会排列它们的打印顺序,这是您不想要的。

一个快速的解决方法是两次传递数组,一次被置换,一次被打印,如下所示:

void TOH(int n, int pegSource[], int pegDest[], int pegSpare[], int print1 [], int print2 [], int print3[]) {
   if (n > 0) {
      TOH(n - 1, pegSource, pegSpare, pegDest, print1, print2, print3);
      PrintPegs(print1, print2, print3);
      MoveDisk(pegSource, pegDest);
      TOH(n - 1, pegSpare, pegDest, pegSource, print1, print2, print3);
   }
}

int main(int argc, char **argv)
{
    int n = atoi(argv[1]);
    int pegSource[9] = {0,0,0,0,0,0,0,0,9};
    int pegDest[9] = {0,0,0,0,0,0,0,0,9};
    int pegSpare[9] = {0,0,0,0,0,0,0,0,9};
    int i;
    int j = 1;

    if (n>8 || n<2){
        printf("invalid input\n");
        exit(0);
    }
    for (i=8-n; i<8; i++){
        pegSource[i]=j;
        j++;
    }

    TOH(n, pegSource, pegDest, pegSpare, pegSource, pegDest, pegSpare);
    PrintPegs(pegSource, pegDest, pegSpare);
    printf("DONE\n");
    return 0;
}

这样做,我得到了输出:

          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
         +|+                   |                    |
        ++|++                  |                    |
       +++|+++                 |                    |
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
        ++|++                  |                    |
       +++|+++                +|+                   |
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
       +++|+++                +|+                 ++|++
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                   +|+
       +++|+++                 |                  ++|++
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                   +|+
          |                 +++|+++               ++|++
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
         +|+                +++|+++               ++|++
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                  ++|++                  |
         +|+                +++|+++                 |
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                    |                    |
          |                   +|+                   |
          |                  ++|++                  |
          |                 +++|+++                 |
 XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX  XXXXXXXXXXXXXXXXXXX

【讨论】:

  • 谢谢!这也是我认为导致问题的原因,您的解决方案非常有效!
【解决方案2】:

我不确定是否可以按照您的意愿编写它.. 因为每当你调用递归时,你实际上必须在挂钩之间切换,而不是你永远不会把它切换回来。所以对于大多数递归调用来说,它实际上是这样的

编辑:实际上我开始认为如果您将另一个函数用于河内塔递归的最后部分,您可以做到这一点

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    相关资源
    最近更新 更多