【思考题】字串的连接最长路径查找
目标需求:
输入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; }
为了提高速度,在进行下一层全排列前判断前面已排序的是否可以进行连接,从而决定是否进行下一层全排列;如果可以连接则进入下一级全排列,否则马上计算连接长度。
结果演示: