对字符串中的字母进行组合

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值