"Programming Thinking and Practice" 1039. Character Combination

"Programming Thinking and Practice" 1039. Character Combination

topic

insert image description here
insert image description here

train of thought

First deduplicate + sort the strings (to ensure that the characters in each combination are in lexicographical order), then enumerate all the combinations, and finally perform lexicographical sorting.

Among them, the de-reordering of strings can use ASCII code values ​​or strchr for bucket sorting. The key is how to enumerate all combinations.

There are two possibilities for each position (select or not), but at least one must be selected, so there are a total of 2 n − 1 2^{n}-12n1 (minus the case of neither option) possibility.

You might as well record the selection as 1, and the non-selection as 0, then this just corresponds to the binary:

Taking all combinations of abc as an example,

000 means neither abc, 001 corresponds to c, 010 corresponds to b, 011 corresponds to bc, 100 corresponds to a, 101 corresponds to ac, 110 corresponds to ab, 111 corresponds to abc.

the code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int cmp(const void* a,const void* b)   //字典序排序
{
    
    
	char* m=(char*)a;
	char* n=(char*)b;
	return strcmp(m,n);
} 

int main()
{
    
    
	int T;
	scanf("%d",&T);
	for(int i=0;i<T;i++)
	{
    
    
		char s[17];  //长度不超过16
		scanf("%s",s);
		char differ[17]={
    
    '\0'};   //桶
        int count=0;
		for(int j=0;j<strlen(s);j++)
		{
    
    
			if(strchr(differ,s[j])==NULL)
            {
    
    
                differ[count++]=s[j];
            }
		}
        differ[count]='\0';
        qsort(differ,count,sizeof(char),cmp);
		
        int temp=(1<<count)-1;   //所有组合结果数
        char result[temp][17];   //所有组合情形
		int possible[count];   //二进制枚举  
        memset(possible,0,sizeof(possible));
		for(int j=0;j<temp;j++)   //每位依此加1
		{
    
    
			possible[0]++;
            for(int k=0;k<count-1;k++)
            {
    
    
                if(possible[k]==2)  //进位
                {
    
    
                    possible[k]=0;
                    possible[k+1]++;
                }
            }
			int t=0;
			for(int k=0;k<count;k++)  
			{
    
    
				if(possible[k])
				{
    
    
					result[j][t++]=differ[k];
				}
			}
			result[j][t]='\0';
		}
		
		qsort(result,temp,sizeof(result[0]),cmp); //排序
		printf("case #%d:\n",i);
		for(int j=0;j<temp;j++)
		{
    
    
			printf("%s\n",result[j]);
		}
	}
	return 0; 
}

Guess you like

Origin blog.csdn.net/boxueyuki/article/details/130402730