題目:輸入一個字串,輸出該字串中字元的所有組合。舉個例子,如果輸入abc,它的組合有a、b、c、ab、ac、bc、abc。
開始我的思路 是遞迴,但是具體如何作,沒想出來。
後面看濤哥日誌中一個網友回複,將字串看成01組成數字串,為1則有字母,這樣就是判斷從1到2^n的數字裡面哪些位為1,則對應為字串
代碼簡單:
#include "stdio.h"#include "math.h"#include "string.h"int main(){int len ;int i,j;int number;char str[1024];scanf("%s",&str);len = strlen(str);number = pow(2,len);for(i=1;i<number;i++){for(j=0;j<len;j++){if((i>>j)&1){printf("%c",str[j]);}}printf(" ");}return 0;}
參考海濤的遞迴解法
看海濤的部落格眼前一亮,太妙了。思路是這樣的
從長度為n的字串中,取出m個字元。如何取呢。 1 取第一個字元,然後在餘下n-1個串中,取剩下m-1個字元
2 不取第一個字元,然後在餘下的n個字串中,去m個字元
當然遞迴返回是需要條件的,就是當字串結束,或是取到長度n時結束
代碼如下:
#include "stdio.h"#include "stdlib.h"#include "math.h"#include "string.h"#define MAX 1024typedef struct node{char data;struct node *next;}MyNode;typedef struct queue{ MyNode *tail; MyNode *top; int size;}lineQueue;void push( lineQueue *q,char data){ MyNode *p = ( MyNode *)malloc(sizeof( MyNode));p->data = data;p->next = NULL;if(q->tail != NULL){(q->tail)->next = p;}q->tail = p;if(q->top == NULL){q->top = p;}q->size +=1;}void pop( lineQueue *q,char *data){MyNode *p;if(q->top == NULL)return;p = q->top;if(q->top == q->tail) /*這裡代碼之前出現了問題 ,就是因為沒有考慮到隊列中只有一個節點的情況下,還需要處理尾指標*/{q->tail = NULL;}*data = q->top->data;q->top = q->top->next;free(p);q->size-=1;}void initQueue(lineQueue **q){if(*q == NULL){*q = (lineQueue *)malloc(sizeof(lineQueue));}(*q)->top = NULL;(*q)->tail = NULL;(*q)->size = 0;}void traverse(lineQueue *q){MyNode *p = NULL;p = q->top;while(p!=NULL){printf("%c",p->data);p= p->next;}}void combineLine(char *str,int num,lineQueue *q){int i =0;char data;if(num == 0){traverse(q);printf(" ");return;}if(*str == '\0'){return;}push(q,*str);combineLine(str+1,num-1,q);pop(q,&data);combineLine(str+1,num,q);}void combine(char *str,lineQueue *q){int i = 0;int len = strlen(str);for(i=1;i<=len;i++){combineLine(str,i,q);}}int main(){ lineQueue *q=NULL;int num=5;int i;char str[1024];initQueue(&q);scanf("%s",str);combine(str,q);return 0;}