Ladies_Man

Shortest Supastring

Dec 15th, 2013
140
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.58 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX_STRINGS 10
  6.  
  7. //соединяет left с right
  8. //возвращает "цену" пересечения left и right
  9.  
  10. int get_intersection_length(char* left,char* right){
  11.         int i;
  12.     if (strlen(left)>0)
  13.         for (i=0;i!=strlen(left);i++){
  14.             unsigned int right_index = 0;
  15.             unsigned int left_index = i;
  16.             while((left[left_index]==right[right_index])&&
  17.                 (left_index<strlen(left))&&
  18.                 (right_index<strlen(right))){
  19.                     left_index++;
  20.                     right_index++;
  21.             }
  22.             if (left_index==strlen(left)){
  23.                 //есть пересечение длиной (left_index - i)
  24.                 //return strlen(left) - (left_index - i);
  25.                 return left_index - i;
  26.             }
  27.         }
  28.     return 0;
  29. }
  30.  
  31. typedef struct {
  32.     int num;
  33.     int lengths[MAX_STRINGS];
  34. } node, *pnode;
  35.  
  36.  
  37. void calculate_intersections(char** strings,int count, int current_index,pnode pl){
  38.     int i;
  39.     char* current_string = strings[current_index];
  40.     for (i=0;i!=count;i++)
  41.         if (i!=current_index)
  42.             pl->lengths[i] = get_intersection_length(current_string,strings[i]);
  43. }
  44.  
  45. int min_length = 0;
  46. int min_path[MAX_STRINGS];
  47. int total1 = 0;
  48. void get_min_length(
  49.                 pnode current_node,
  50.                 pnode other_nodes,
  51.                 int other_nodes_count,                             
  52.                 int* visited_nodes_nums,
  53.                 int visited_nodes_count,
  54.                 int sum_len){
  55.     //необходимо обойти все узлы из all_nodes
  56.     //кроме current_node и тех, что перечислены в prev_nodes_nums
  57.  
  58.  
  59.  
  60.     if (visited_nodes_count == other_nodes_count - 1){
  61.         total1 ++;
  62.         //больше двигаться некуда.
  63.         if (sum_len>min_length){
  64.             visited_nodes_nums[visited_nodes_count] = current_node->num;
  65.             min_length = sum_len;
  66.             memcpy(min_path,visited_nodes_nums,MAX_STRINGS*sizeof(int));
  67.         }
  68.     } else{
  69.         int i;
  70.         //ищем следующий узел     
  71.         for (i=0;i!=other_nodes_count;i++){
  72.             int k,wf=0;
  73.             pnode pn = &(other_nodes[i]);
  74.             int length_to_pn;
  75.             int _sum, _v_count;
  76.             int _visited_nodes[MAX_STRINGS];
  77.  
  78.             //пропускаем текущий узел
  79.             if (other_nodes[i].num == current_node->num)
  80.                 continue;
  81.  
  82.             //проверяем pn - нет-ли его в пройденном маршруте?
  83.             if (visited_nodes_count)
  84.                 for (k=0;k!=visited_nodes_count;k++)
  85.                     if (pn->num == visited_nodes_nums[k]){
  86.                         wf=1;
  87.                         break;
  88.                     }
  89.                     if (wf)
  90.                         continue;
  91.  
  92.                     //следующий узел - pn
  93.                     length_to_pn = current_node->lengths[pn->num];
  94.                     _sum = sum_len + length_to_pn;
  95.  
  96.                     memset(_visited_nodes,0,MAX_STRINGS*sizeof(int));
  97.                     memcpy(_visited_nodes,visited_nodes_nums,visited_nodes_count*sizeof(int));
  98.                     _visited_nodes[visited_nodes_count] = current_node->num;
  99.                     _v_count = visited_nodes_count + 1;
  100.  
  101.                     get_min_length(pn,other_nodes,other_nodes_count,_visited_nodes,_v_count,_sum);
  102.  
  103.         }
  104.  
  105.     }
  106.  
  107. }
  108.  
  109.  
  110. int get_result_length(char** strings, int* path,node* nodes,int count){
  111.     //считаем длину результ. строки
  112.     int i;
  113.     int res_len = 0;
  114.     for (i=0;i!=count;i++){
  115.         int current_string_index = path[i];
  116.         char* c_string = strings[current_string_index];
  117.         res_len += strlen(c_string);
  118.  
  119.         if (i>0){
  120.             //отнимаем кол-во символов, которое попало в пересечение строк (i+1) и (i)
  121.             //aaaaaaaccc
  122.             //       cccbbbbbb
  123.             int prev_string_index = path[i-1];
  124.             node n = nodes[prev_string_index];
  125.             int intersec_len = n.lengths[current_string_index];
  126.             res_len -= intersec_len;
  127.         }
  128.     }
  129.  
  130.  
  131.     return res_len;
  132. }
  133.  
  134. int main(int argc,char** argv){
  135.     int i;
  136.  
  137.     node ints[MAX_STRINGS];
  138.     pnode plens;
  139.     char *strings[MAX_STRINGS];
  140.     int N;
  141.  
  142.  
  143.     memset(strings,0,MAX_STRINGS*sizeof(char*));
  144.  
  145.     scanf("%d",&N);
  146.     i = 0;
  147.     while(i!=N){
  148.         strings[i] = (char*)malloc(1024); //макс. длина строки в условиях не указана
  149.         scanf("%s",strings[i]);
  150.         i++;
  151.     }
  152.    
  153.    
  154.    
  155.     memset(ints,0,MAX_STRINGS*sizeof(node));
  156.  
  157.     //считаем пересечения строк (каждая с каждой)
  158.     plens = ints;
  159.     for (i=0;i!=N;i++){
  160.         calculate_intersections(strings,N,i,plens);
  161.         plens->num = i;
  162.         plens++;
  163.     }
  164.  
  165.  
  166.     min_length = 0;
  167.     memset(min_path,0,MAX_STRINGS*sizeof(int));
  168.  
  169.     for (i=0;i!=N;i++){
  170.         int visited_nodes[MAX_STRINGS];
  171.         memset(visited_nodes,-1,MAX_STRINGS*sizeof(int));
  172.         get_min_length(&(ints[i]),ints,N,visited_nodes,0,0);
  173.     }
  174.        
  175.  
  176.     min_length = get_result_length(strings,min_path,ints,N);
  177.     printf("%d\n",min_length);
  178.  
  179.    
  180.     for (i=0;i!=N;i++)
  181.         if (strings[i]!=0)
  182.             free(strings[i]);  
  183.     return 0;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment