字串-----輸出字串所有組合
阿新 • • 發佈:2019-02-19
方法一:遞迴,遍歷字串,每個字元只能取或者不取;取該字元的話,就把字元放入到結果字串中,遍歷完畢後,輸出結果字串;
#include <stdio.h> #include <string.h> #define MAXSIZE 1024 #define MAXLENGTH 64 void CombineRecursiveImpl(const char *str, char *begin, char *end) { if (*str == 0) { *end = 0; if (begin != end) printf("%s ", begin); return; } CombineRecursiveImpl(str + 1, begin, end); *end = *str; CombineRecursiveImpl(str + 1, begin, end + 1); } void CombineRecursive(const char str[]) { if (str == NULL) return; char result[MAXLENGTH]; CombineRecursiveImpl(str, result, result); } int main() { char str[MAXSIZE]; gets(str); CombineRecursive(str); return 0; }
方法二:當N很大時,遞迴效率很差,因為棧呼叫次數約為2^n,尾遞迴優化後有2^(n-1);為了提高效率,可以構造一個長度為n 的01字串(或二進位制數)表示輸出結果中是否包含某個字元。例如,'001'表示輸出中不含字元a,b,只有c,而'101'表示輸出結果為ac,即題意為輸出'001'~'111'的2^n-1個組合對應的字串
#include<stdio.h> #include<string.h> #define MAXLENGTH 64 void Combine(const char str[]) { if (str == NULL || *str == 0) return; int len = strlen(str); bool used[MAXLENGTH] = { 0 }; char cache[MAXLENGTH]; char *result = cache + len; *result = 0; while (1) { int index = 0; while (used[index]) { used[index] = false; ++result; if (++index == len) return; } used[index] = true; *--result = str[index]; printf("%s ", result); } } int main() { Combine("abc"); printf("\n"); return 0; }