我刚刚完成了河内大厦的迭代版本。
算法就是这样工作的:

我正在试图找到一种删除goto指令的方法。有小费吗?
/**
* 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;
}发布于 2018-03-05 11:39:59
为便于阅读和理解:
content或usage (或者两者都更好)for if else while do...while switch case default )。int main(int argc, char *argv[]),因为两种参数都没有使用,建议使用:int main( void )void print(int STCK[][DM_STCK], int DM_S),因为没有使用'int DM_S‘,要么删除该参数,要么函数正文中的第一行应该是:(void)DM_S;#include <stdlib.h>ODINO_0,并用标签后面的三行代码替换任何“goto”到ODINO_0。对于ODINO_1和ODINO_2也存在类似的考虑DM_S是作为size_t传递的,因此与它一起使用的任何其他变量也应该声明为size_t,而不是int。发布于 2018-03-04 00:09:05
你的代码:
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
}可重写为:
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
https://codereview.stackexchange.com/questions/188717
复制相似问题