我不得不使用goto语句编写类似的问题。现在我们被要求在不使用goto语句的情况下重写代码。我不知道如何开始这个程序。我使用goto粘贴以前的程序代码。
// Eight Queens problem using one dimesional array and goto statement
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int q[8];
q[0] = 0;
int c = 0;
int count = 0;
NC: //cout << "Next column\n" << "Column = " << c << endl;
c++;
if (c == 8) goto print;
q[c] = -1;
NR: //cout << "Next row\n" << "Row = " << q[c] << "\nColumn = " << c << endl;
q[c]++;
if (q[c] == 8) goto backtrack;
for(int i = 0; i < c; i++){
if(q[i] == q[c] || abs(q[c] - q[i]) == (c - i))
goto NR;
}
goto NC;
backtrack:
//cout << "Backtrack" << endl;
//cout <<"Column = " << c << endl;
c--;
if(c == -1) return 0;
goto NR;
print:
//cout << "print" << endl;
++count;
cout << count << endl;
for(int i = 0; i <= 7; i++){
cout << q[i];
}
cout << endl;
goto backtrack;
return 0;
}
这个程序是教授为课程发布的一个提示。
#include <iostream>
#include<cstdlib>
#include <cmath>
using namespace std;
bool ok(int q[], int col){
if the configuration is “bad” return false;
else
return true;
}
void backtrack(int &col){
col--;
if(col==-1) exit(1);
}
void print(int q[]){
static int count =0;
print the array q
}
int main(){
int q[8]; q[0]=0;
int c=1;
// from_backtrack keeps track if we need to reset the row to the
// top of the current colum or not.
bool from_backtrack=false;
// The outer loop keeps looking for solutions
// The program terminates from function backtrack
// when we are forced to backtack into column -1
while(1){
while(c<8){ //this loop goes across columns
// if we just returned from backtrack, use current value of row
// otherwise get ready to start at the top of this column
if(!from_backtrack) // we did not just return from backtrack
Code goes here
from_backtrack=false;
while(q[c]<8){ // place queen in this column
q[c]++;
// if row=8, there is no valid square in this column
// so backtrack and continue the loop in the previous column
Code goes here
//if this position is ok, place the queen
// and move on (break) to the next column,
// otherwise keep looking in this column
Code goes here
}
c++; // placed ok, move to the next column
}
// one complete solution found, print it.
print(q); // board completed, print it out
backtrack(c);
from_backtrack=true;
}
}
这是我为完成该计划所做的尝试
// NoGoto.cpp.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
bool attack(int q[], int col){
if(q[i] == q[c] || abs(q[c] - q[i]) == (c - i)) return false;
else
return true;
} // Attack
void backtrack(int & col){
col--;
if(col == -1) exit(1);
} // Backtrack
void print(int q[]){
static int count = 0;
++count;
cout << count << endl;
for(int i = 0; i < 8; i++)
cout << q[i];
cout << endl;
}
int main()
{
int q[8];
q[0] = 0;
int c = 1;
bool from_backtrack = false;
while(1){
while(c < 8){ // this loops across columns
if(!from_backtrack)
attack(q[c],c)
from_backtrack = false;
while(q[c] < 8){ // place queen in this column
q[c]++;
return 0;
}
“我在编写代码时遇到问题。如何[我可以]调用每个函数以使其正确找到解决方案?”
答案 0 :(得分:6)
首先,只需通过剥离其他所有内容并添加显式goto
来执行,通过直线执行到达标签来查看控制流。
NC: if (…) goto print;
goto NR;
NR: if (…) goto backtrack;
if (…) goto NR;
goto NC;
backtrack:
if (…) return;
goto NR;
print:
goto backtrack;
现在,采取无条件的getos并尝试移动块,使它们代表直线执行。
NR: if (…) goto backtrack;
if (…) goto NR;
goto NC;
NC: if (…) goto print;
goto NR;
print:
goto backtrack;
backtrack:
if (…) return;
goto NR;
现在消除直线的结果
NR: if (…) goto backtrack;
if (…) goto NR;
NC: if (…) goto print;
goto NR;
print:
backtrack:
if (…) return;
goto NR;
请注意,包含所有后向gotos的标签是一个循环:
for (;;) {
NR: if (…) goto backtrack;
if (…) continue;
NC: if (…) goto print;
continue;
print:
backtrack:
if (…) return;
}
嗯,我们可以扭转NC: if()
的感觉并消除goto print
。并且goto backtrack
只会跳过某些语句,这相当于另一个语句if
。
for (;;) {
NR: if (! …) {
if (…) continue;
NC: if (! …) continue;
print:
}
backtrack:
if (…) return;
}
循环没有条件,但是backtrack: … if(…) return;
只是退出它,所以将该块和条件移动到循环中。
for (;…; /* backtrack */ …) {
NR: if (! …) {
if (…) continue;
NC: if (! …) continue;
print:
}
}
看起来很不错,没有更多的东西,也没有“可疑”的结构!但是,NC
应该是切入点。
这是盲目,机械,编译器转换失败的地方。我看到三种选择:
goto
更加丑陋。goto NC;
伪装成switch(0)
并将标签NC:
称为case 0:
。老师可能不会接受这种妥协。NC
复制到循环的末尾,并粘贴到循环开头的上方。然后,您可以将它们分解为函数。实际上,这是一种盲目的机械转型。万岁。我还代表NR
和backtrack
作为统一的函数。
NC();
if (…) {
print();
}
while ( backtrack(), … ) { // <- note comma operator
NR();
if (! …) {
if (…) continue;
NC();
if (! …) continue;
print();
}
}
可能有一个更优雅的解决方案,包括查看代码的内容,但这需要较少的思考。