zoukankan      html  css  js  c++  java
  • 【思考题】字串的连接最长路径查找

    目标需求:

    输入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]==''){
    			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] = '';
    				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;
    }

    为了提高速度,在进行下一层全排列前判断前面已排序的是否可以进行连接,从而决定是否进行下一层全排列;如果可以连接则进入下一级全排列,否则马上计算连接长度。
     结果演示:

  • 相关阅读:
    如何将Oracle安装为Linux服务
    cp | mv | rm
    scp命令
    【读书笔记】深入理解计算机系统:第一章——计算机系统漫游
    微信小程序笔记(3):小程序的生命周期及其相关函数
    微信小程序笔记(2):wxml相比于html的扩展
    微信小程序笔记(1):小程序的代码构成和目录文件结构
    [C/C++]const限定符总结
    整数的表示与编码
    关于补码的由来和作用
  • 原文地址:https://www.cnblogs.com/xhyzjiji/p/6159372.html
Copyright © 2011-2022 走看看