简体   繁体   English

如何解决河内问题的迭代方法

[英]How Solve Iterative Method For Hanoi Problem

I'm trying to solve the Hanoi problem using an iterative method.我正在尝试使用迭代方法解决河内问题。 I try to do this by using two for nested loops, so as to repeat n - 1 steps in each loop, where n is the number of moves.我尝试通过使用两个 for 嵌套循环来做到这一点,以便在每个循环中重复 n - 1 步,其中 n 是移动次数。 I think I have well posed the problem by using two for, but I don't understand how to change the order of the towers at each pass.我想我已经通过使用两个 for 很好地提出了这个问题,但我不明白如何在每次通过时更改塔的顺序。 Can anyone help me with this task?谁能帮我完成这项任务?

inizio is start, fine is end and supp is support inizio 是开始,fine 是结束,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++;
    
    
}  

  

The number of moves is 2移动次数为 2 −1, so the nested loop you have cannot achieve that, as it will only produce (+1)/2 moves. -1,因此您拥有的嵌套循环无法实现这一点,因为它只会产生 (+1)/2 移动。

The logic for which disc to move is also not as simple as a cycle of 6 distinct moves.棋子移动的逻辑也不像 6 个不同移动的循环那么简单。

There are several ways to implement an iterative solution, some of which are explained onWikipedia .有几种方法可以实现迭代解决方案,其中一些在Wikipedia上进行了解释。 However, the ones that are listed there, require that you maintain the state of each peg (pile), so you can perform checks on what constitutes a valid move.但是,那里列出的那些要求您维护每个钉(桩)的 state,以便您可以检查构成有效移动的内容。

You can also look at the bit-pattern of the move's sequence number and derive from that which is the correct move.您还可以查看移动序列号的位模式,并从中得出正确的移动。

Here is an implementation of that latter idea:这是后一种想法的实现:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM