【劍指offer】字串的組合
轉載請註明出處:http://blog.csdn.net/ns_code/article/details/26405471
劍指offer上的擴充題目,輸入一個字串,輸出該字串的字元的所有組合,比如輸入字串:abc,輸出a、b、c、ab、ac、bc、abc。
思路:與上一題類似,也可以用遞迴求解。可以考慮求長度為n的字串中m個字元的組合,設為C(n,m)。原問題的解即為C(n, 1), C(n, 2),...C(n, n)的總和。對於求C(n, m),從第一個字元開始掃描,每個字元有兩種情況,要麼被選中,要麼不被選中,如果被選中,遞迴求解C(n-1, m-1)。如果未被選中,遞迴求解C(n-1, m)。不管哪種方式,n的值都會減少,遞迴的終止條件n=0或m=0。
博主是剛開始嘗試用遞迴去寫,寫了一個多小時都沒寫出來,桑心啊!除了操作二叉樹寫遞迴比較順,其他好多地方用遞迴愣是憋不出來,尤其字串操作。
在何海濤部落格下看到有人留言,給了個思路,覺得很不錯,自己把程式碼寫了出來。具體思路如下:
開闢一個於字串對應長度的int陣列(char陣列也可以,而且更節省空間),用該陣列模擬二進位制的加1操作,則該陣列的元素只能為0或1,我們規定如果該陣列某個位置處的元素是1,則字串對應位置處的字元參與組合,如果為0,則字串對應位置處的字元不參與組合,這樣講該int陣列,從全0加到全1,便可得到字串的全部組合。
這裡沒有去除重複子串,也沒按照字典序輸出,如果要求按照字典序輸出,並去掉重複子串的話,可以採取上道題目一樣的辦法,先將所有的字串儲存在字串陣列中,而後通過快排使陣列中的字串按照字典序排列,再在輸出的時候,跳過重複的字串。
實現程式碼如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
/*
模擬二進位制加1操作,當最高位要進位時,說明所有的位都是1,返回false,
用char陣列來模擬比int陣列更省空間,這裡必須傳入陣列長度len,
由於我們CominationAll中將要傳入的字元陣列全部初始化為了'\0',
如果在該函式內部用strlen計算的話,會得到len=0。
*/
bool Increment(char *BindAdd,int len)
{
if(BindAdd == NULL)
return false;
BindAdd[len-1]++;
int i;
for(i=len-1;i>=0;i--)
{
if(BindAdd[i] >= 2)
{
if(i == 0)
{
BindAdd[i]--;
return false;
}
else
{
BindAdd[i] -= 2;
BindAdd[i-1]++;
}
}
else
break;
}
return true;
}
/*
輸出字串的所有組合
*/
void CominationAll(char *str)
{
if(str == NULL)
return;
int len = strlen(str);
char *BindAdd = (char *)malloc(len*sizeof(char));
if(BindAdd == NULL)
exit(EXIT_FAILURE);
memset(BindAdd,0,len*sizeof(char));
while(Increment(BindAdd,len))
{
int i;
for(i=0;i<len;i++)
{
if(BindAdd[i] == 1)
putchar(str[i]);
}
putchar('\n');
}
free(BindAdd);
BindAdd = NULL;
}
int main()
{
char str[10];
while(gets(str))
CominationAll(str);
return 0;
}
測試結果:相關文章
- 【劍指offer】字串的排列字串
- 【劍指offer】【2】字串的空格字串
- 【劍指offer】左旋轉字串字串
- 劍指 Offer 38. 字串的排列字串
- 劍指Offer 表示數值的字串字串
- 【劍指offer】字串轉整數字串
- 《劍指offer》:[54]表示數值的字串字串
- 【劍指offer】替換字串中的空格字串
- 劍指Offer系列之「表示數值的字串」字串
- 劍指offer-字串空格替換為“ ”字串
- 《劍指offer》:[42-1]左旋轉字串字串
- 《劍指offer》:[49]把字串轉化成整數字串
- [劍指offer][第四章][28]字串的排列字串
- 劍指offer(Java版)--將字串轉換為整數Java字串
- 劍指offer——把字串轉換成整數C++字串C++
- 劍指 Offer 48. 最長不含重複字元的子字串字元字串
- 【劍指offer】刪除在另一個字串中出現的字元字串字元
- 劍指offer-JavaScript版JavaScript
- 劍指Offer題解合集
- 劍指offer面試17 合併兩個排序的連結串列面試排序
- 【劍指offer】樹的子結構
- 劍指offer—58_2.左旋轉字串—分析及程式碼(Java)字串Java
- 力扣 - 劍指 Offer 67. 把字串轉換成整數力扣字串
- 劍指 offer(1) -- 陣列篇陣列
- Leetcode劍指offer(八)LeetCode
- 劍指offer刷題記錄
- 劍指offer——包含min函式的棧函式
- 【劍指offer】陣列中的逆序對陣列
- 【劍指offer】包含min函式的棧函式
- leetcode 劍指 Offer 48. 最長不含重複字元的子字串LeetCode字元字串
- 《劍指 Offer》棧實現佇列佇列
- 劍指offer解析-下(Java實現)Java
- 劍指offer解析-上(Java實現)Java
- 劍指offer——重建二叉樹二叉樹
- 【劍指offer】二叉樹深度二叉樹
- 【劍指offer】員工年齡排序排序
- 【劍指offer】10.程式的完整性
- 劍指offer-17:樹的子結構