字符全排列

  1. 输入一个字符串, 打印出该字符串中字符的所有排列。举个例子,123的全排列有123、132、213、231、312、321这六种。
  2. 字符串全排列扩展----八皇后问题

1、思路:

  递归思路:全排列就是从第一个数起每一个数分别和他后面数做交换。当数组中有出现重复数字时,当出现之前交换过的数字就跳过,只交换不重复的数字。

Permutation
 1 #include <iostream>
 2 #include <assert.h>
 3 
 4 using namespace std;
 5 
 6 
 7 //从第一个数开始,分别与后面的数交换
 8 void Permutation1(char* pStr, char* pBegin)
 9 {
10     assert(pStr && pBegin);
11 
12     if (*pBegin == '\0')
13         printf("%s\n", pStr);
14     else
15     {
16         for (char* pCh = pBegin; *pCh != '\0'; pCh++)
17         {
18             swap(*pBegin, *pCh);
19             Permutation1(pStr, pBegin + 1);
20             swap(*pBegin, *pCh);
21         }
22     }
23 }
24 
25 /**************************************************/
26 
27 /*如果字符串中有重复的字符则上面的方法有误*/
28 //从第一个数开始,分别与后面非重复的数交换
29 bool IsSwap(char* pBegin, char* pEnd)
30 {
31     for (char* p = pBegin; p < pEnd; p++)
32     {
33         if (*p == *pEnd)
34             return false;
35     }
36     return true;
37 }
38 
39 void Permutation2(char* pStr, char* pBegin)
40 {
41     assert(pStr && pBegin);
42     if (*pBegin == '\0')
43     {
44         static int num = 1;
45         printf("第%d个排列:%s\n", num++, pStr);
46     }
47     else
48     {
49         for (char* pCh = pBegin; *pCh != '\0'; pCh++)
50         {
51             if (IsSwap(pBegin, pCh))
52             {
53                 swap(*pBegin, *pCh);
54                 Permutation2(pStr, pBegin + 1);
55                 swap(*pBegin, *pCh);
56             }
57         }
58     }
59 }
60 
61 int main()
62 {
63     char test[] = "abb";
64     Permutation2(test, test);
65 }

  字典序排列:52431 -> 53421 -> 53124,首先自右向左定位第一个比右侧数小的数2,再从该位置右侧开始遍历最后一个比2大的数字3,然后2和3互换,从该位置右侧一个数字开始逆序,这样就可以得到52431的下一个数字就是53124。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <assert.h>
 4 #include <stdlib.h>
 5 
 6 #define N 4
 7 
 8 int Cmp(const void *a, const void *b)
 9 {
10     return *(char*)a - *(char*)b;
11 }
12 
13 void Swp(char *m, char *n)
14 {
15     char tmp = *m;
16     *m = *n;
17     *n = tmp;
18 }
19 
20 void Rev(char *str, int m, int n)
21 {
22     while (m < n)
23     {
24         Swp(str + m, str + n);
25         m++;
26         n--;
27     }
28 }
29 
30 int Fac(int n)
31 {
32     assert(n > 0);
33     int result = 1, i = 2;
34     while (i <= n)
35     {
36         result *= i;
37         i++;
38     }
39     return result;
40 }
41 
42 void Out(char* str, int len)
43 {
44     for (int i = 0; i < len; i++)
45         printf("%c ", str[i]);
46     printf("\n");
47 }
48 
49 void Per(char* str)
50 {
51     int index1, index2;
52     int n = Fac(N);
53     for (int i = 1; i < n; i++)
54     {
55         for (index1 = N - 2; index1 >= 0; index1--)
56         {
57             if (str[index1] < str[index1 + 1])
58                 break;
59         }
60         int min = 32767;
61         for (int j = index1 + 1; j < N; j++)
62         {
63             if (str[j] > str[index1])
64             {
65                 if (str[j] < min)
66                 {
67                     min = str[j];
68                     index2 = j;
69                 }
70             }
71             else break;
72         }
73         Swp(str + index1, str + index2);
74         Rev(str, index1 + 1, N - 1);
75         Out(str, N);
76     }
77 }
78         
79 void main()
80 {
81     char str[N] = {'1', '2', '4', '3'};
82     qsort(str, N, sizeof(char), Cmp);
83     Out(str, N);
84     Per(str);
85 }
Perm

 

2、思路:

  行固定,列为全排列问题。保证斜对角的数字符合题目要求就行,所以在打印全排列的时候需要做一个判断。

EightQueen
 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int g_number = 0;
 6 
 7 void PrintArray(int* data, int length)
 8 {
 9     printf("第%d个方案:", g_number);
10     for (int i = 0; i < length; i++)
11         printf("%d ", data[i]);
12     printf("\n");
13 }
14 
15 bool Check(int* cols, int rows)
16 {
17     for (int i = 0; i < rows; i++)
18     {
19         for (int j = i + 1; j < rows; j++)
20         {
21             if (i - j == cols[i] - cols[j] || j - i == cols[i] - cols[j])
22                 return false;
23         }
24     }
25     return true;
26 }
27 
28 void Permutation(int* cols, int rows, int index)
29 {
30     if (index == rows)
31     {
32         if (Check(cols, rows))
33         {
34             g_number++;
35             PrintArray(cols, rows);
36         }
37     }
38     else
39     {
40         for (int i = index; i < rows; i++)
41         {
42             swap(cols[index], cols[i]);
43             Permutation(cols, rows, index + 1);
44             swap(cols[index], cols[i]);
45         }
46     }
47 }
48 
49 void EightQueen()
50 {
51     const int rows = 8;
52     int cols[rows];
53     for (int i = 0; i < rows; i++)
54         cols[i] = i;
55     Permutation(cols, rows, 0);
56 }
57 
58 int main()
59 {
60     EightQueen();
61     return 0;
62 }

 

posted on 2013-03-28 17:23  月moon鸟  阅读(328)  评论(0编辑  收藏  举报

导航