其实字符串全排列问题是8皇后问题的一个小问题,先说说8皇后问题吧!
八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种方法可以解决此问题。
根据8皇后摆放位置的要求,可以看出就是一个字符串重排的问题。可以将8*8象棋格子认为是2个包含8个元素的数组。其中一个数组表示水平方向的位置,而另外一个表示竖直方向上的位置。而将行看成不变的数组来标记皇后放的位置,因此对其中一个数组进行全排列就能够保证任意两个皇后肯定不同行不同列。接下来,我们只需要判断得到的每一个排列对应的八个皇后是不是在同一对角斜线上,也就是数组的两个下标i和j,是不是i-j==ColumnIndex[i]-Column[j]或者j-i==ColumnIndex[i]-ColumnIndex[j]。 下面是代码实现:
首先修改全排列的函数实现:
- int number = 0;//记录满足要求八皇后排列次数
- void Permutation(int ColumnIndex[], int index, int length=8)
- {
- if(index == length)//如果排列完成,就检测数组是否满足要求
- {
- if(CheckQueen(ColumnIndex, length))
- {
- ++ number;
- PrintQueen(ColumnIndex, length);//打印出符合要求的八皇后数组排列
- }
- }
- else
- {
- for(int i = index; i < length; ++ i)
- {
- int temp = ColumnIndex[i];
- ColumnIndex[i] = ColumnIndex[index];
- ColumnIndex[index] = temp;
-
- Permutation(ColumnIndex, index + 1, length);
-
- temp = ColumnIndex[index];
- ColumnIndex[index] = ColumnIndex[i];
- ColumnIndex[i] = temp;
- }
- }
- }
- //检查是否符合八皇后的位置要求
- bool CheckQueen(int ColumnIndex[], int length)
- {
- for(int i = 0; i < length; ++ i)
- {
- for(int j = i + 1; j < length; ++ j)
- {
- if((i - j == ColumnIndex[i] - ColumnIndex[j])
- || (j - i == ColumnIndex[i] - ColumnIndex[j]))
- return false;
- }
- }
-
- return true;
- }
-
- void PrintQueen(int ColumnIndex[], int length)
- {
- printf("满足八皇后的第%d个摆放位置为:\n", number);
-
- for(int i = 0; i < length; ++i)
- printf("%d\t", ColumnIndex[i]);
- printf("\n");
- }
- void EightQueen()
- {
- const int queens = 8;
- int ColumnIndex[queens];
- for(int i = 0; i < queens; ++ i)
- ColumnIndex[i] = i;//初始化皇后在每一列的位置
- Permutation(ColumnIndex, 0, queens);
- }