【IT168 技术文章】
If you have time and interest in eight queens algorithm, then you can read this article, it is done by ABAP and tested in ECC6.
REPORT z_8queen NO STANDARD PAGE HEADING.
*Store where the queen is
DATA: BEGIN OF row ,
val TYPE i,
END OF row .
DATA: i_row LIKE row OCCURS 0 WITH HEADER LINE .
*How many ways we can achieve
DATA: oktimes TYPE i .
data: queen type i.
*Define the number of queen
CONSTANTS: queenmax TYPE i VALUE 8 .
*Input queen number
PARAMETERS: p_num TYPE i DEFAULT queenmax.
START-OF-SELECTION .
PERFORM main_process .
*&---------------------------------------------------------------------*
*& Form MAIN_PROCESS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM main_process .
DATA: l_num TYPE i . "The first place
DATA: l_s(50) TYPE c . "Output string
DATA: l_time(10) TYPE c.
queen = p_num + 1.
* Init place table
DO queenmax TIMES .
i_row-val = -1 .
APPEND i_row .
ENDDO.
l_num = 1 .
* recursion
PERFORM place_queen USING l_num.
* Get ways of algorithm
l_time = oktimes .
CONDENSE l_time .
CONCATENATE 'Eight Queens have' l_time 'ways to solve it.' INTO l_s
SEPARATED BY space.
WRITE: l_s .
ENDFORM. " MAIN_PROCESS
*&---------------------------------------------------------------------*
*& Form place_queen
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM place_queen USING p_num.
* Local data definition
DATA: l_i TYPE i .
DATA: l_num TYPE i .
* Temp variants
DATA: l_k TYPE i .
DATA: l_t1 TYPE i .
DATA: l_t2 TYPE i .
* Safe place
DATA: BEGIN OF qsave OCCURS 0 ,
val TYPE i ,
END OF qsave .
* Init safe place, make all place be safe
DO queenmax TIMES .
qsave-val = 1 .
APPEND qsave .
ENDDO.
l_i = 1 .
l_num = p_num .
* This loop get the safe place
WHILE l_i < l_num .
READ TABLE i_row INDEX l_i .
READ TABLE qsave INDEX i_row-val .
qsave-val = 0 .
MODIFY qsave INDEX i_row-val.
l_k = l_num - l_i .
l_t1 = i_row-val + l_k .
l_t2 = i_row-val - l_k .
* Mark safe place
* If a queen's place is I_ROW[i]=j, then the unsafe place is row k column j
* and column j+k-i and j-k+i
IF l_t1 >= 1 AND l_t1 < queen .
READ TABLE qsave INDEX l_t1 .
qsave-val = 0 .
MODIFY qsave INDEX l_t1 .
ENDIF.
IF l_t2 >= 1 AND l_t2 < queen .
READ TABLE qsave INDEX l_t2 .
qsave-val = 0 .
MODIFY qsave INDEX l_t2 .
ENDIF.
l_i = l_i + 1 .
ENDWHILE .
l_i = 1 .
* Below loop is to get the queen's place
WHILE l_i < queen .
READ TABLE qsave INDEX l_i .
IF qsave-val = 0 .
* If this place is not safe, then get the next place
l_i = l_i + 1 .
CONTINUE .
ENDIF.
* if not the last place
IF p_num < queenmax.
READ TABLE i_row INDEX p_num .
i_row-val = l_i .
MODIFY i_row INDEX p_num .
l_num = p_num + 1 .
* Get the next queen's place
PERFORM place_queen USING l_num .
ELSE .
* The last queen, give her the last place
READ TABLE i_row INDEX p_num .
i_row-val = l_i .
MODIFY i_row INDEX p_num.
* The ways of place add 1 and output
oktimes = oktimes + 1 .
WRITE: '--------------------------------------------------------------------------------',/.
LOOP AT i_row .
WRITE: i_row-val .
ENDLOOP .
WRITE: / .
ENDIF.
l_i = l_i + 1 .
ENDWHILE .
ENDFORM. " PLACE_QUEEN
*Store where the queen is
DATA: BEGIN OF row ,
val TYPE i,
END OF row .
DATA: i_row LIKE row OCCURS 0 WITH HEADER LINE .
*How many ways we can achieve
DATA: oktimes TYPE i .
data: queen type i.
*Define the number of queen
CONSTANTS: queenmax TYPE i VALUE 8 .
*Input queen number
PARAMETERS: p_num TYPE i DEFAULT queenmax.
START-OF-SELECTION .
PERFORM main_process .
*&---------------------------------------------------------------------*
*& Form MAIN_PROCESS
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM main_process .
DATA: l_num TYPE i . "The first place
DATA: l_s(50) TYPE c . "Output string
DATA: l_time(10) TYPE c.
queen = p_num + 1.
* Init place table
DO queenmax TIMES .
i_row-val = -1 .
APPEND i_row .
ENDDO.
l_num = 1 .
* recursion
PERFORM place_queen USING l_num.
* Get ways of algorithm
l_time = oktimes .
CONDENSE l_time .
CONCATENATE 'Eight Queens have' l_time 'ways to solve it.' INTO l_s
SEPARATED BY space.
WRITE: l_s .
ENDFORM. " MAIN_PROCESS
*&---------------------------------------------------------------------*
*& Form place_queen
*&---------------------------------------------------------------------*
* text
*----------------------------------------------------------------------*
FORM place_queen USING p_num.
* Local data definition
DATA: l_i TYPE i .
DATA: l_num TYPE i .
* Temp variants
DATA: l_k TYPE i .
DATA: l_t1 TYPE i .
DATA: l_t2 TYPE i .
* Safe place
DATA: BEGIN OF qsave OCCURS 0 ,
val TYPE i ,
END OF qsave .
* Init safe place, make all place be safe
DO queenmax TIMES .
qsave-val = 1 .
APPEND qsave .
ENDDO.
l_i = 1 .
l_num = p_num .
* This loop get the safe place
WHILE l_i < l_num .
READ TABLE i_row INDEX l_i .
READ TABLE qsave INDEX i_row-val .
qsave-val = 0 .
MODIFY qsave INDEX i_row-val.
l_k = l_num - l_i .
l_t1 = i_row-val + l_k .
l_t2 = i_row-val - l_k .
* Mark safe place
* If a queen's place is I_ROW[i]=j, then the unsafe place is row k column j
* and column j+k-i and j-k+i
IF l_t1 >= 1 AND l_t1 < queen .
READ TABLE qsave INDEX l_t1 .
qsave-val = 0 .
MODIFY qsave INDEX l_t1 .
ENDIF.
IF l_t2 >= 1 AND l_t2 < queen .
READ TABLE qsave INDEX l_t2 .
qsave-val = 0 .
MODIFY qsave INDEX l_t2 .
ENDIF.
l_i = l_i + 1 .
ENDWHILE .
l_i = 1 .
* Below loop is to get the queen's place
WHILE l_i < queen .
READ TABLE qsave INDEX l_i .
IF qsave-val = 0 .
* If this place is not safe, then get the next place
l_i = l_i + 1 .
CONTINUE .
ENDIF.
* if not the last place
IF p_num < queenmax.
READ TABLE i_row INDEX p_num .
i_row-val = l_i .
MODIFY i_row INDEX p_num .
l_num = p_num + 1 .
* Get the next queen's place
PERFORM place_queen USING l_num .
ELSE .
* The last queen, give her the last place
READ TABLE i_row INDEX p_num .
i_row-val = l_i .
MODIFY i_row INDEX p_num.
* The ways of place add 1 and output
oktimes = oktimes + 1 .
WRITE: '--------------------------------------------------------------------------------',/.
LOOP AT i_row .
WRITE: i_row-val .
ENDLOOP .
WRITE: / .
ENDIF.
l_i = l_i + 1 .
ENDWHILE .
ENDFORM. " PLACE_QUEEN