文章目錄
-
- 1. 題目 1
-
- 1.1 示例
- 1.2 解題思路
- 1.3 代碼實作
- 2. 題目 2
-
- 2.1 示例
- 2.2 解題思路
- 2.3 代碼實作
- 3. 題目 3
-
- 3.1 解題思路
- 3.2 代碼實作
1. 題目 1
輸入一個字元串,列印出該字元串中字元的所有排列。例如,輸入字元串 abc,則列印出由字元a、b、c所能排列出來的所有字元串abc、acb、bac、bca、cab和cba。
1.1 示例
輸入:
abc
輸出:
abc
acb
bac
bca
cba
cab
1.2 解題思路
可以把一個字元串看成由兩部分組成:第一部分是它的第一個字元;第二部分是後面的所有字元。求整個字元串的排列,可以看成兩步。
1.求所有可能出現在第一個位置的字元。
2.固定第一個字元,求後面所有字元的排列。這時仍把後面所有字元分成兩部分:後面字元的第一個字元,以及這個字元之後的所有字元。
1.3 代碼實作
#include <stdio.h>
void Permutation(char* string, char* strBegin);
void Permutation(char* string)
{
if (string == NULL) {
return;
}
Permutation(string, string);
}
void swap(char* strA, char* strB)
{
char temp = *strA;
*strA = *strB;
*strB = temp;
}
void Permutation(char* string, char* strBegin)
{
if (*strBegin == '\0') {
printf("%s\n", string);
} else {
for (char* strCh = strBegin; *strCh != '\0'; ++strCh) {
// 有重複字元時,跳過
if ((*strCh == *strBegin) && (strCh != strBegin)) {
continue;
}
swap(strCh, strBegin);
Permutation(string, strBegin + 1);
swap(strCh, strBegin);
}
}
}
int main(void)
{
char string[] = "abc";
Permutation(string);
return 0;
}
2. 題目 2
如果不是求字元的所有排列,而是求字元的所有組合,應該怎麼辦呢?還是輸入三個字元 a、b、c,則它們的組合有 a、b、c、ab、ac、bc、abc。當交換字元串中的兩個字元時,雖然能得到兩個不同的排列,但卻是同一個組合。比如 ab 和 ba 是不同的排列,但隻算一個組合。
2.1 示例
輸入:
abc
輸出:
a
b
c
ab
ac
bc
abc
2.2 解題思路
可以把這 n 個字元分成兩部分:第一個字元和其餘的所有字元。如果組合裡包含第一個字元,則下一步在剩餘的字元裡選取 m-1個字 符:如果組合裡不包含第一個字元,則下一步在剩餘的 n-1 個字元裡選取 m 個字元。也就是說,我們可以把求 n 個字元組成長度為 m 的組合的問題分解成兩個子問題。
1.求 n-1 個字元串中長度為 m-1 的組合。
2.求 n-1 個字元的長度為 m 的組合。
2.3 代碼實作
#include <cstdio>
#include <cstring>
#include <vector>
void Combination(char* string, int number, std::vector<char>& result);
void Combination(char* string)
{
if (string == nullptr) {
return;
}
std::vector<char> result;
for (int i = 1; i <= strlen(string); ++i) {
Combination(string, i, result);
}
}
void Combination(char* string, int number, std::vector<char>& result)
{
if (number == 0) {
std::vector<char>::iterator iter = result.begin();
for (; iter < result.end(); ++iter) {
printf("%c", *iter);
}
printf("\n");
return;
}
if (*string == '\0') {
return;
}
result.push_back(*string);
Combination(string + 1, number - 1, result);
result.pop_back();
Combination(string + 1, number, result);
}
int main(void)
{
char string[] = "abc";
Combination(string);
return 0;
}
3. 題目 3
輸入一個含有 8 個數字的數組,判斷有沒有可能把這8個數字分别放到正方體的8個頂點上,使得正方體上三組相對的面上的4個頂點的和都相等。
3.1 解題思路
相當于先得到a1、a2、a3、a4、a5、a6、a7和a8這 8 個數字的排列,然後判斷有沒有某一個排列符合題目給定的條件,即 a1+a2+a3+a4 == a5+a6+a7+a8,a1+a3+a5+a7 == a2+a4+a6+a8,并且a1+a2+a5+a6 == a3+a4+a7+a8。
3.2 代碼實作
#include <stdio.h>
#include <stdbool.h>
void swap(int* a, int*b)
{
int temp = *a;
*a = *b;
*b = temp;
}
bool CubVertex(int* A, int length, int begin)
{
if ((A == NULL) || (length != 8)) {
return false;
}
bool result = false;
int i = 0;
if (begin == length - 1) {
if ((A[0] + A[1] + A[2] + A[3] ==A[4] + A[5] + A[6] + A[7]) &&
(A[0] + A[2] + A[4] + A[6] == A[1] + A[3] + A[5] + A[7]) &&
(A[0] + A[1] + A[4] + A[5] == A[2] + A[3] + A[6] + A[7])) {
for (i = 0; i < length; ++i) {
printf("%d ", A[i]);
}
printf("\n");
result = true;
}
} else {
for (i = begin; i < length; ++i) {
swap(&A[begin], &A[i]);
result = CubVertex(A, length, begin + 1);
if (result) {
break;
}
swap(&A[begin], &A[i]);
}
}
return result;
}
int main(void)
{
int A[8] = {1, 2, 3, 1, 2, 3, 2, 2};
int B[8] = {1, 2, 3, 1, 8, 3, 2, 2};
if (CubVertex(A, 8, 0)) {
printf("Yes!\n");
} else {
printf("No!\n");
}
if (CubVertex(B, 8, 0)) {
printf("Yes!\n");
} else {
printf("No!\n");
}
return 0;
}
/* 運作結果
* 1 2 3 2 3 2 1 2
* Yes!
* No!
*/
個人部落格:
www.codeapes.cn