首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >河内大厦练习的迭代版本

河内大厦练习的迭代版本
EN

Code Review用户
提问于 2018-03-03 07:55:19
回答 2查看 293关注 0票数 2

我刚刚完成了河内大厦的迭代版本。

算法就是这样工作的:

我正在试图找到一种删除goto指令的方法。有小费吗?

代码语言:javascript
复制
/**
 * definition of all function: 
 * 
 *  print : just print the state of the array
 *  populate: just fill the array with 0
 *  mov_pl: move the pile from to 
 *  CHK_POS_FROM : check from where come the disk
 *  CHK_POS_TO: check where the disk will go
 *  CHK_STK: check the status of the pile
 **/


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

    // Number if pile
    #define DM_STCK 3

    // Number of disk 
    #define DM_CLMN 10


    void print(int STCK[][DM_STCK], int DM_S);  
    void MOV_PL(int STCK[][DM_STCK], int FROM, int TO, size_t DM_S); 
    int CHK_POS_FROM(int STCK[][DM_STCK], int N_PL, size_t DM_S);
    int CHK_POS_TO(int STCK[][DM_STCK], int N_PL, size_t DM_S);
    int CHK_STK(int STCK[][DM_STCK], int N_PL, size_t DM_S);
    void populate(int STCK[][DM_STCK], int DM_S);

    int main(int argc, char *argv[]){

    // name of each pule

        int PL_1 = 0;
        int PL_2 = 1;
        int PL_3 = 2;

    // check if the disk are odd or even

        if(DM_CLMN % 2 == 0){
            PL_2 = 2;
            PL_3 = 1;
        }


        int stack[DM_CLMN][DM_STCK];

        populate(stack, DM_CLMN);

        long long mosse = (long long)pow(2,DM_CLMN) - 1;

        int RS_1 = 0;
        int RS_2 = 0;

        puts("### START ###");

        print(stack, DM_STCK);

        for(int cnt = 0; cnt < mosse; cnt++){

            RS_1 = 0;
            RS_2 = 0;

            printf("MOSSA NUMERO: %d\n", 1 + cnt);

            if(cnt % 3 == 0){

                    RS_1 = CHK_STK(stack, PL_1, DM_CLMN);
                    RS_2 = CHK_STK(stack, PL_3, DM_CLMN);

                    if(RS_1 > RS_2){
                        if(RS_2 == 0){
                        MOV_PL(stack, PL_1, PL_3, DM_CLMN);
                        print(stack, DM_STCK);

                        //printf("A --> B");
                        } else {
                            ODINO_0:
                            MOV_PL(stack, PL_3, PL_1, DM_CLMN);
                            print(stack, DM_STCK);
                            continue;
                        //printf("B --> A");
                        }
                    } if(RS_1 < RS_2) {
                        if(RS_1 == 0){
    //                      Odino perdonami per questa istruzione
                            goto ODINO_0;
                        }
                        MOV_PL(stack, PL_1, PL_3, DM_CLMN);
                        print(stack, DM_STCK);

                    }

                }

            if(cnt % 3 == 1){

                    RS_1 = CHK_STK(stack, PL_1, DM_CLMN);
                    RS_2 = CHK_STK(stack, PL_2, DM_CLMN);

                    if(RS_1 > RS_2){
                        if(RS_2 == 0){
                        MOV_PL(stack, PL_1, PL_2, DM_CLMN);
                        print(stack, DM_STCK);

                        //printf("A --> B");
                        } else {
    //                  Che odino sia con me
                        ODINO_1:
                        MOV_PL(stack, PL_2, PL_1, DM_CLMN);
                        print(stack, DM_STCK);

                        continue;
                        //printf("B --> A");
                        }
                    } else {
                        if(RS_1 == 0){
    //                      Odino perdonami per questa istruzione
                            goto ODINO_1;
                        }
                        MOV_PL(stack, PL_1, PL_2, DM_CLMN);
                        print(stack, DM_STCK);

                    }
            }

            if(cnt % 3 == 2){

                RS_1 = CHK_STK(stack, PL_2, DM_CLMN);
                RS_2 = CHK_STK(stack, PL_3, DM_CLMN);

                    if(RS_1 > RS_2){
                        if(RS_2 == 0){
                        MOV_PL(stack, PL_2, PL_3, DM_CLMN);
                        print(stack, DM_STCK);

                        //printf("A --> B");
                        } else {
                        ODINO_2:
                        MOV_PL(stack, PL_3, PL_2, DM_CLMN);
                        print(stack, DM_STCK);

                        continue;
                        //printf("B --> A");
                        }
                    } else {
                        if(RS_1 == 0){
    //                      Odino perdonami per questa istruzione
                            goto ODINO_2;
                        }
                        MOV_PL(stack, PL_2, PL_3, DM_CLMN);
                        print(stack, DM_STCK);

                    }
            }

        }

        puts("### END ###");        


        return 0;
    }

    void populate(int STCK[][DM_STCK], int DM_S){

        for(int colonna = 0; colonna < DM_S; colonna++){
            for(int riga = 0; riga < DM_STCK; riga++){
                STCK[colonna][riga] = 0;
            }
        }

        for(int cnt_1 = 0; cnt_1 < DM_S; cnt_1++){
            STCK[cnt_1][0] = cnt_1 + 1;
        }

    }

    // Stampa le 3 torri

    void print(int STCK[][DM_STCK], int DM_S){
        for(int colonne = 0; colonne < DM_CLMN; colonne++){
            for(int righe = 0; righe < DM_STCK; righe++){

                if(STCK[colonne][righe] == 0){
                    printf("|   |");
                }else{
                    printf("| %d |", STCK[colonne][righe]);
                }
            }
            puts("\n");
        }

        puts("\n");
    }

    // Controlla in che direzione muovere il paletto se -> o <-
    // check wich direction to move the pile if left or right

    void MOV_PL(int STCK[][DM_STCK], int FROM, int TO, size_t DM_S){

        int POS_1 = CHK_POS_FROM(STCK, FROM, DM_S);
        int POS_2 = CHK_POS_TO(STCK, TO,DM_S);

        int TMP = STCK[POS_2][TO];
        STCK[POS_2][TO] = STCK[POS_1][FROM];
        STCK[POS_1][FROM] = TMP;

    }

    // Estrae la posizione del numero da posizione
    // Look at the disk position in the array

    int CHK_POS_FROM(int STCK[][DM_STCK], int N_PL, size_t DM_S){

        int POS = DM_S - 1;

        for(int cnt_1 = 0; cnt_1 < DM_S; cnt_1++){
            if(STCK[cnt_1][N_PL] != 0){
               POS = cnt_1;
               break;
          }
        }


        return POS;

    }

    /* 
         Estrae la posizione di dove posizione il numero da posizione e 
        controlla che non sia uno zero, se non è uno zero allora è pos - 1 altrimenti 
        solo pos

        Extract the position, so we can tell in wich position is and check if 
        it's  0, if it's not a 0 pos = pos - 1 otherwise is just pos
    */


    int CHK_POS_TO(int STCK[][DM_STCK], int N_PL, size_t DM_S){

        int POS = DM_S - 1;

        for(int cnt_1 = 0; cnt_1 < DM_S; cnt_1++){
            if(STCK[cnt_1][N_PL] != 0){
               POS = cnt_1 - 1;
               break;
          }
        }


        return POS;

    }

    /*

        Estra il primo anello dallo stack e lo confronta con l'anello del l'altro stack
        per decidere in quale verso spostare l'anello.

        Extract the first disk from the stack and compares with the other disk
        from the pile, to decide in wich way to move the disk left or right

    */ 

    int CHK_STK(int STCK[][DM_STCK], int N_PL, size_t DM_S){

        int FLG = 0;

        for(int cnt = 0; cnt < DM_S; cnt++){
            if(STCK[cnt][N_PL] != 0){
               FLG = STCK[cnt][N_PL];
            break;
          }
        }

     return FLG;

    }
EN

回答 2

Code Review用户

发布于 2018-03-05 11:39:59

为便于阅读和理解:

  1. 不断地缩进代码。在每个开口后缩进'{‘。在每个结束大括号'}‘之前不缩进。建议每一缩进水平为4个空格。
  2. 使用有意义的变量和参数名称。名称应该表示contentusage (或者两者都更好)
  3. 用一个空行分隔代码块( for if else while do...while switch case default )。
  4. 用2或3行空白行分隔函数(保持一致)
  5. 最好不要引入随机空白行。
  6. 最好不要引入随机缩进。
  7. 遵循公理:每行只有一条语句,每条语句最多只有一个变量声明。
  8. 将结束括号'}‘视为单独的语句。
  9. 关于:int main(int argc, char *argv[]),因为两种参数都没有使用,建议使用:int main( void )
  10. 关于:void print(int STCK[][DM_STCK], int DM_S),因为没有使用'int DM_S‘,要么删除该参数,要么函数正文中的第一行应该是:(void)DM_S;
  11. 包含未使用内容的头文件是一种错误的编程做法。即建议删除语句:#include <stdlib.h>
  12. 强烈建议删除标签:ODINO_0,并用标签后面的三行代码替换任何“goto”到ODINO_0。对于ODINO_1ODINO_2也存在类似的考虑
  13. 由于DM_S是作为size_t传递的,因此与它一起使用的任何其他变量也应该声明为size_t,而不是int
  14. 为了便于阅读和理解:不要对变量、参数和函数名使用所有的大写。(所有的大写都被认为是“大喊”)对宏名使用所有的大写是合适的。
  15. 为了便于阅读和理解:插入一个(合理的)空格:在parens内部,在方括号内,在逗号后面,在分号后面,在C操作符周围
票数 3
EN

Code Review用户

发布于 2018-03-04 00:09:05

你的代码:

代码语言:javascript
复制
if(RS_1 > RS_2) {
   if(RS_2 == 0) {
      // do A
   } else {
      ODINO_0:
      // do B
   }
} if(RS_1 < RS_2) {
   if(RS_1 == 0) {
      goto ODINO_0;
   }
   // do C
}

可重写为:

代码语言:javascript
复制
if(RS_2 == 0) {
   // do A
} else if(RS_1 > RS_2 || RS_1 == 0) {
   // do B
} else if(RS_1 < RS_2) {
   // do C
}

假设这两个值从来都不是负的。如果它们可能是阴性的,则需要进行一些额外的测试。

我不反对goto,有时它是干净而清晰的。在这种情况下,但是,它是令人困惑的,它需要一段时间来找出它跳到哪里。

关于命名:请使用较长的变量和函数名。3字母全大写名称看起来像Fortran 66代码。很难阅读您的代码,因为变量名称是没有意义的,并且没有注释解释它们的使用。好的变量名使代码易于阅读(如果代码足够好,就不需要注释)。此外,现代IDE做的名字完成,你甚至不必再键入全名。:D

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/188717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档