c++ - Rewriting a program without using goto statements -
i had program similar problem using goto statements. asked rewrite our code without using goto statement. don't know how begin doing program. paste in previous program code using goto.
// 8 queens problem using 1 dimesional array , 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 = 0; < 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 = 0; <= 7; i++){ cout << q[i]; } cout << endl; goto backtrack; return 0; }
this program hint professor posted class use.
#include <iostream> #include<cstdlib> #include <cmath> using namespace std; bool ok(int q[], int col){ if configuration “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 array q } int main(){ int q[8]; q[0]=0; int c=1; // from_backtrack keeps track if need reset row // top of current colum or not. bool from_backtrack=false; // outer loop keeps looking solutions // program terminates function backtrack // when forced backtack column -1 while(1){ while(c<8){ //this loop goes across columns // if returned backtrack, use current value of row // otherwise ready start @ top of column if(!from_backtrack) // did not return backtrack code goes here from_backtrack=false; while(q[c]<8){ // place queen in column q[c]++; // if row=8, there no valid square in column // backtrack , continue loop in previous column code goes here //if position ok, place queen // , move on (break) next column, // otherwise keep looking in column code goes here } c++; // placed ok, move next column } // 1 complete solution found, print it. print(q); // board completed, print out backtrack(c); from_backtrack=true; } }
and attempted i've made completed program
// nogoto.cpp.cpp : defines entry point 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 = 0; < 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){ // loops across columns if(!from_backtrack) attack(q[c],c) from_backtrack = false; while(q[c] < 8){ // place queen in column q[c]++; return 0; }
"i'm having problem writing code. how [can i] call each function make correctly find solutions?"
first, @ control flow stripping else , adding explicit goto
s execution reaches label straight-line execution.
nc: if (…) goto print; goto nr; nr: if (…) goto backtrack; if (…) goto nr; goto nc; backtrack: if (…) return; goto nr; print: goto backtrack;
now, take unconditional gotos , try move blocks represent straight-line execution.
nr: if (…) goto backtrack; if (…) goto nr; goto nc; nc: if (…) goto print; goto nr; print: goto backtrack; backtrack: if (…) return; goto nr;
now eliminate straight-line gotos
nr: if (…) goto backtrack; if (…) goto nr; nc: if (…) goto print; goto nr; print: backtrack: if (…) return; goto nr;
note label backward-going gotos loop:
for (;;) { nr: if (…) goto backtrack; if (…) continue; nc: if (…) goto print; continue; print: backtrack: if (…) return; }
hmm, can reverse sense of nc: if()
, eliminate goto print
. , goto backtrack
jumps on statements, equivalent reversed if
.
for (;;) { nr: if (! …) { if (…) continue; nc: if (! …) continue; print: } backtrack: if (…) return; }
the loop has no condition, backtrack: … if(…) return;
exits it, move block , condition loop.
for (;…; /* backtrack */ …) { nr: if (! …) { if (…) continue; nc: if (! …) continue; print: } }
looking pretty good, no more gotos , no "suspicious" structure! however, nc
supposed entry point.
this blind, mechanistic, compiler-ish transformations fail. see 3 alternatives:
- introduce variables force execution there first loop iteration. uglier
goto
, in opinion. - disguise
goto nc;
switch(0)
, call labelnc:
case 0:
. teacher not accept compromise. - copy blocks
nc
end of loop , paste above beginning of loop. can factor them out functions. actually, blind, mechanistic transformation. hooray. i'll representnr
,backtrack
functions uniformity.
.
nc(); if (…) { print(); } while ( backtrack(), … ) { // <- note comma operator nr(); if (! …) { if (…) continue; nc(); if (! …) continue; print(); } }
there more elegant solution involves looking @ contents of code, takes less thinking.
Comments
Post a Comment