目标需求:
输入n个字符串,如果一个字符串末尾有k个字符与另一个字符串头k个字符相同,则这两个字符串可以连接,比如
abcdef cdefgh这两个字符串可以连接成abcdefgh
从这n个字符串中,寻找可以连接成最长字串的方案。
//样例输入:
//ABCC ABCD BCCE BCDE CCEF BCCE CCEG CEGF
//样例输出:
//ABCCEGF
思路:
1.对所有字符串做编号1,2,3,4,5,.......;
2.对编号进行全排列;
3.对一次排列结果按排列编号进行连接,并记录最大连接长度方案。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int chongdie(char *s1, char *s2){
int s1len, s2len;
int k1, k2;
int chongdie_cnt;
s1len = strlen(s1); s2len = strlen(s2);
for(k1=0, k2=0, chongdie_cnt=0; k1<s1len; k1++){
if(s1[k1]==s2[k2]){
k2++;
chongdie_cnt++;
}
else{
if(chongdie_cnt>0)
k1--;
k2=0;
chongdie_cnt = 0;
}
}
return chongdie_cnt;
}
int *ans;
int max=0;
char **ss;
//全排列判断
void swap(int *a, int *b){
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void quanpailie(int *data, int p, int n){
int k;
int i;
int *data_backup;
int ch_cnt=0;
int temp;
if(p>=n){
for(k=1; k<n; k++){
if((temp=chongdie(ss[data[k-1]], ss[data[k]]))==0){
break;
}
else{
if(k==1)
ch_cnt += strlen(ss[data[k-1]])+strlen(ss[data[k]])-temp;
else
ch_cnt += strlen(ss[data[k]])-temp;
}
}
if(ch_cnt>max){
max = ch_cnt;
memcpy(ans, data, sizeof(int)*n);
}
return;
}
data_backup = (int*)malloc(sizeof(int)*n);
memcpy(data_backup, data, sizeof(int)*n);
for(i=0; i+p<n; i++){
swap(data_backup+p, data_backup+p+i);
quanpailie(data_backup, p+1, n);
}
//free(data_backup);
}
//ABCC ABCD BCCE BCDE CCEF BCCE CCEG CEGF
int main(void){
char **s;
int s_num=20, s_size=0, sk;
char temp[1000];
char *stemp;
int templen, ktemp, kptemp, k;
int *used;
int *data;
s = (char**)malloc(sizeof(char*)*s_num);
gets(temp);
templen = strlen(temp);
for(ktemp=0, kptemp=0; ktemp<=templen; ktemp++){
if(temp[ktemp]==' '||temp[ktemp]=='\0'){
if(ktemp<=kptemp)
kptemp = ktemp+1;
else{
stemp = (char*)malloc(sizeof(char)*(ktemp-kptemp+1));
memcpy(stemp, temp+kptemp, sizeof(char)*(ktemp-kptemp));
stemp[ktemp-kptemp] = '\0';
s[s_size++] = stemp;
if(s_size==s_num){
s_num += 20;
*s = (char*)realloc(*s, sizeof(char*)*s_num);
}
kptemp = ktemp+1;
}
}
}
ans = (int*)malloc(sizeof(int)*s_size);
ss = s;
data = (int*)malloc(sizeof(int)*s_size);
for(k=0; k<s_size; k++){
*(data+k) = k;
}
memcpy(ans, data, sizeof(int)*s_size);
//c++就用map,java就用hash,c呢?
quanpailie(data, 0, s_size);
for(k=1; k<s_size; k++){
if((ktemp=chongdie(ss[ans[k-1]], ss[ans[k]]))==0){
break;
}
else{
if(k==1){
printf("%s", ss[ans[k-1]]);
printf("%s", ss[ans[k]]+ktemp);
}
else
printf("%s", ss[ans[k]]+ktemp);
}
}
system("pause");
return 0;
}
为了提高速度,在进行下一层全排列前判断前面已排序的是否可以进行连接,从而决定是否进行下一层全排列;如果可以连接则进入下一级全排列,否则马上计算连接长度。
结果演示: