【问题标题】:How Solve Iterative Method For Hanoi Problem如何解决河内问题的迭代方法
【发布时间】:2021-12-30 12:01:37
【问题描述】:

我正在尝试使用迭代方法解决河内问题。 我尝试通过使用两个 for 嵌套循环来做到这一点,以便在每个循环中重复 n - 1 步,其中 n 是移动次数。我想我已经通过使用两个 for 很好地提出了这个问题,但我不明白如何在每次通过时更改塔的顺序。 谁能帮我完成这项任务?

inizio 是开始, 好的是结束和 supp是支持

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

void tower_Organizer(int *inizio, int *fine, int *supp);
void hanoi_Iter(int n, int inizio, int fine, int supp);

int main(void){
    
    int n;
    
    printf("%s\n" ,"inserisci un nuero positivo");
    scanf("%d", &n);
    
    hanoi_Iter(n, 1, 2, 3);
    
    return 0;
    
}


void hanoi_Iter(int n, int inizio, int fine, int supp){
    
    for(int i = 1 ; i <= n ; i++){
        
        for(int j = 1 ; j <= i - 1 ; j++){
            
            printf("%d -> %d\n", inizio, fine);
            tower_Organizer(&inizio, &fine, &supp);

                
        }
        
        printf("%d -> %d\n", inizio, fine);
        tower_Organizer(&inizio, &fine, &supp);

    }       
        
}


void tower_Organizer(int *inizio, int *fine, int *supp){
    
    static int count = 1;
    
    int c = count % 6;
    
    switch( c ){
        
        case 0:
            *inizio = 1;
            *fine = 2;
            *supp = 3;
            break;
        case 1:
            *inizio = 1;
            *fine = 3;
            *supp = 2;
            break;
        case 2:
            *inizio = 2;
            *fine = 3;
            *supp = 1;
            break;
        case 3:
            *inizio = 1;
            *fine = 2;
            *supp = 3;
            break;
        case 4:
            *inizio = 3;
            *fine = 1;
            *supp = 2;
            break;
        case 5:
            *inizio = 3;
            *fine = 2;
            *supp = 1;
            break;
        
    }
    
    count++;
    
    
}  

  

【问题讨论】:

  • 两个循环适用于O(n^2) 解决方案...河内是O(2^n) 问题
  • 建议:规范的 C 循环往往从 0 开始,一直到 排除 n (for (int i = 0; i &lt; n; i++))。如果您没有充分的理由不这样做,请以规范的方式进行。
  • @pmg ,所以我不能用两个循环来解决它?
  • 不是有两个计数循环,但for 循环只是编写while 循环的另一种方式;我相信你可以用一个while(或for)循环来解决河内问题...while (!solved()) { step_closer(); }或等效for (; !solved(); ) { step_closer(); }
  • @pmg 好的,我试试,谢谢

标签: c algorithm towers-of-hanoi


【解决方案1】:

移动次数为 2?-1,因此您拥有的嵌套循环无法实现,因为它只会产生 ?(?+1)/2 次移动。

移动哪张棋子的逻辑也不像一个循环 6 次不同的移动那么简单。

有几种方法可以实现迭代解决方案,其中一些在Wikipedia 上进行了解释。但是,那里列出的那些要求您维护每个钉子(桩)的状态,以便您可以检查构成有效移动的内容。

您还可以查看移动序列号的位模式并从中得出正确的移动。

这是后一种想法的实现:

void hanoi(int n, int start, int end, int helper) {
    // Create a converter for a pile index (0, 1 or 2) to the identifiers 
    //    that are given as arguments:
    int map[] = {start, end, helper};
    // Perform as many iterations as there are moves to perform:
    for (int last = 1<<n, i = 1; i < last; i++) {
        // Use bit pattern of i to determine the source peg.
        // First remove and count the trailing 0 bits in i:
        int j = i;
        int zeroCount = 0;
        while (j % 2 == 0) {
            j >>= 1;
            zeroCount++;
        }
        // Derive the source pile from that zero-stripped number
        int source = (j >> 1) % 3;
        // Get next pile as destination
        int target = (source + 1) % 3;
        // Depending on parity, the source/target pile should be mirrored
        if ((n + zeroCount) % 2 == 0) {
            source = (3 - source) % 3;
            target = (3 - target) % 3;
        }
        printf("Move from %d to %d\n", map[source], map[target]);
    }
}

int main(void) {
    int n;
    printf("%s\n" ,"Enter a positive number (of discs)");
    scanf("%d", &n);
    hanoi(n, 1, 2, 3);
    return 0;
}

【讨论】:

    猜你喜欢
    • 2016-03-19
    • 2021-11-12
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多