0 1背包问题
先把字符串去重,并记录每个字母相应的个数.
设组合的结果为comb(s,strCount,idx,aux) ,s表示去重的字符串,strCount表示对应的个数,idx表示当前位置,aux表示当前位置取了几个数那么
comb(s,strCount,idx,aux)= 当aux[idx]分别为0...n时comb(s,strCount,idx+1) ;
/*
============================================================================
Name : strCombination.c
Author :
Version :
Copyright :
Description : 对字符串中的每个字母进行组合 如输入aba 输出:a b ab aa aab
============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void pr_arrByAux(const char *s, int len,const int *aux)
{
int i = 0, k = 0;
for (i = 0; i < len; ++i)
{
for (k = 0; k < aux[i]; ++k)
printf("%c", s[i]);
}
printf("\n");
}
void pr_arr(const int *a,int len)
{
int i=0;
for(i=0;i<len;i++)
{
printf("%d ",a[i]);
}
printf("\n");
}
//去有序字符串中重复的字母,并保存每个字母相应的个数
//如 s="aabbccd"
//得 s="abcd"
//strCount为2,2,2,1
void delRepeatAndCount(char *s,int *strCount)
{
char *pre,*p;
int i=0;
if(s==NULL || strlen(s) <= 1) return;
pre=s,p=s+1;
for(i=0;i<strlen(s);i++)
{
strCount[i]=1;
}
i=0;
while(*p != '\0')
{
if(*p != *pre)
{
*(++pre)=*p++;
++i;
}
else
{
++p;
strCount[i]++;
}
}
*(pre+1)='\0';
/* pr_arr(strCount,strlen(s));
puts(s);*/
}
int comp(const void *pa,const void *pb)
{
return *(char*)pa - *(char*)pb;
}
//s表示去重复的字母集合,strCount表示 相应字母的个数
void strCombination(const char *s, int len, int *strCount, int idx, int *aux)
{
int i = 0;
if (len < 1 || idx > len) return;
if (idx == len)
{
pr_arrByAux(s, len, aux);
return;
}
aux[idx] = 0;
for (i = 0; i <= strCount[idx]; ++i)
{
aux[idx] = i;
strCombination(s, len, strCount, idx + 1, aux);
}
aux[idx] = 0;//还原
}
//对字符串的字母进行组合
void strComb(const char *s)
{
//strCount 保存字母相应的个数
int *aux,*strCount ,len;
char *str; //源字符串的副本,并删除其中重复的字母
if(s==NULL || strlen(s) < 1) return;
//init
len=strlen(s);
aux=(int*)malloc(sizeof(int)*len);
strCount=(int*)malloc(sizeof(int)*len);
str=(char*)malloc(sizeof(char)*(len+1));
strcpy(str,s);
//kernel
qsort(str,len,sizeof(char),comp); //变成有序字符串
delRepeatAndCount(str,strCount); //去重,并计数
strCombination(str,strlen(str),strCount,0,aux);//组合
//free
free(str);
free(strCount);
free(aux);
}
int main(void)
{
strComb("abaa");
return 0;
}