• timus_1002_kmp_dijkstra


    题目描述:

    给定字母与数字的映射关系:

    1 ij    2 abc   3 def

    4 gh    5 kl    6 mn

    7 prs   8 tuv   9 wxy

            0 oqz

    根据输入的数字字符串,和已经存在的字符串词典,求出符合给出的数字字符串的字符串序列,要求这个序列中字符串的个数最少

    输入:

    数字字符串

    字典中包含的字符串个数

    字符串 …

    有多个case输入,数字字符串为-1结束所有的case输入

    7325189087

    5

    it

    your

    reality

    real

    our

    4294967296

    5

    it

    your

    reality

    real

    our

    -1

    输出:

    reality our

    No solution.

    输出满足条件的任意一组字符串序列,如果没有满足条件的,输出No solution.

    解题思路:

    将目标数字串的下标作为图的顶点。对于给定的字典中的每个字符串,根据映射表转化为数字串,通过KMP算法,将这些数字串与输入的目标数字串匹配,获得匹配项的下标s,e,并认为顶点s-1与顶点e是有一条长度为1的边,如果有多条相同的边,取一条就可以了。对于不匹配的字符串直接忽略。题目所求就是找出从顶点0到顶点n-1的最小路径长度(n为目标数字串数字的个数)。

    代码:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 
      5 //数字与字母关系映射表
      6 char table[26] = {'2', '2', '2', '3', '3', '3', '4', '4', '1', '1', '5', '5', '6', '6', '0', '7', '0', '7', '7', '8', '8', '8', '9', '9', '9', '0'};
      7 
      8 //存放输入的数字串
      9 char digital[101]; 
     10 int len_digital;//输入字符串的长度
     11 
     12 //临时存放输入的字符串
     13 char temp_string[51], temp_input[51];
     14 //输入的字母在输入数字串中的位置表示
     15 char *position[100][100];
     16 
     17 //字典中单词的个数
     18 int n;
     19 //最小跳数的路径
     20 int path[100];
     21 //0顶点到其他顶点的距离
     22 int distance[100];
     23 int flag[100];//标记哪些顶点已经找到了最短路径
     24 
     25 #define INFINITE 1000000
     26 //打印答案
     27 void print_ans(int n)
     28 {
     29     if (path[n] == 0)
     30     {
     31         printf("%s ", position[0][n]);
     32         return ;
     33     }
     34     print_ans(path[n]);
     35     printf("%s ", position[path[n] + 1][n]);
     36 }
     37 //dijkstra算法
     38 void dijkstra()
     39 {
     40     int i,j;
     41 
     42     path[0] = -1;
     43     distance[0] = 0;
     44     flag[0] = 1;
     45     //初始化
     46     for (i = 1; i < len_digital; i ++)
     47     {
     48         path[i] = 0;    
     49         if (position[0][i])
     50         {
     51             distance[i]    = 1;
     52         }
     53         else
     54         {
     55             distance[i]    = INFINITE; 
     56         }
     57         flag[i] = 0;
     58     }
     59     //查找最短路径
     60     for (i = 1; i < len_digital; i ++)    
     61     {
     62         int min = INFINITE,k; 
     63         for (j = 1; j < len_digital; j ++) {
     64             if (!flag[j] && distance[j] < min)        
     65             {
     66                 min = distance[j];
     67                 k = j;
     68             }
     69         }
     70         if (min == INFINITE)
     71             break;
     72         flag[k] = 1;
     73         //printf("%d : %d\n", k, distance[k]);
     74         //松弛边
     75         for (j = k + 1; j < len_digital; j ++)
     76         {
     77             if (!flag[j] && position[k + 1][j] && distance[k] + 1 < distance[j])
     78             {
     79                 distance[j]    = distance[k] + 1;
     80                 path[j] = k;
     81             }
     82         }
     83     }
     84 }
     85 //获得最长长度k
     86 void computer_prefix_fuction(int prefix_func[])
     87 {
     88     int k,q;
     89 
     90     k = 0;
     91     prefix_func[0] = 0;
     92     q = 2;
     93     while (temp_string[q - 1])
     94     {
     95         while (k > 0 && temp_string[k] != temp_string[q - 1])    
     96             k = prefix_func[k - 1];
     97         if (temp_string[k] == temp_string[q - 1])
     98             k ++;
     99         prefix_func[q - 1] = k;
    100         q ++;
    101     }
    102 }
    103 //KMP算法
    104 void kmp_matcher()
    105 {
    106     int q,i,prefix_func[51];
    107 
    108     computer_prefix_fuction(prefix_func);
    109     i = 0;//计数
    110     q = 0;//匹配的字符数
    111     while (digital[i])    
    112     {
    113         while (q > 0 && temp_string[q] != digital[i])    
    114             q = prefix_func[q - 1];
    115         if (temp_string[q] == digital[i])
    116             q ++;
    117         if (! temp_string[q])
    118         {
    119             //匹配成功    
    120             if (! position[i - q + 1][i])    
    121             {
    122                 position[i - q + 1][i] = (char *)malloc(sizeof(char) * (q + 1));
    123                 strcpy(position[i - q + 1][i], temp_input);
    124                 //printf("%s:%d ---> %d\n", temp_string, i - q + 1, i);
    125             }
    126             //匹配下一个
    127             i = i - q + 1;
    128             q = 0;
    129         }    
    130         i ++;
    131     }
    132 }
    133 int main(void)
    134 {
    135     int i,j;
    136 
    137     while (1)    
    138     {
    139         //输入数据    
    140         scanf("%s", digital);            
    141         if (digital[0] == '-') 
    142             break;
    143         len_digital = strlen(digital);
    144         scanf("%d", &n);        
    145         //初始化position表
    146         for (i = 0; i < len_digital; i ++)    
    147             for (j = i; j < len_digital; j ++)
    148                 position[i][j] = NULL;
    149         
    150         for (i = 0; i < n; i ++)
    151         {
    152             scanf("%s", temp_input);    
    153             j = 0;
    154             while (temp_input[j])    
    155             {
    156                 temp_string[j] = table[temp_input[j] - 'a'];
    157                 j ++;
    158             }
    159             temp_string[j] = 0;
    160             //获得输入字符串在目标数字串的位置,并将其填入position表中
    161             kmp_matcher();
    162         }    
    163 
    164         //使用dijkstra算法计算从位置0到位置n-1的最小跳数
    165         dijkstra();
    166         if (distance[len_digital - 1] == INFINITE)
    167         {
    168             printf("No solution.\n");    
    169         }
    170         else
    171         {
    172             print_ans(len_digital - 1);    
    173             printf("\n");
    174         }
    175     }
    176     return 0;
    177 }
  • 相关阅读:
    tp3.2和Bootstrap模态框导入excel表格数据
    PHPEXCEL导入导出
    Yar请求数据接口
    php函数
    Linux常用操作命令
    PHP读取excel表格,和导出表格
    PHP 查找二维数组中是否有指定字符串的字段
    下载百度网盘大文件
    thinkPHP写txt日志文件
    PHP接收post请求,不是空数组就是没值,怎么办!
  • 原文地址:https://www.cnblogs.com/chengxuyuancc/p/2867762.html
Copyright © 2020-2023  润新知