zoukankan      html  css  js  c++  java
  • hdu

    A + B for you again

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 7687    Accepted Submission(s): 1921


    Problem Description

    Generally speaking, there are a lot of problems about strings processing. Now you encounter another such problem. If you get two strings, such as “asdf” and “sdfg”, the result of the addition between them is “asdfg”, for “sdf” is the tail substring of “asdf” and the head substring of the “sdfg” . However, the result comes as “asdfghjk”, when you have to add “asdf” and “ghjk” and guarantee the shortest string first, then the minimum lexicographic second, the same rules for other additions.

    Input

    For each case, there are two strings (the chars selected just form ‘a’ to ‘z’) for you, and each length of theirs won’t exceed 10^5 and won’t be empty.

    Output

    Print the ultimate string by the book.

     

    Sample Input

    asdf sdfg

    asdf ghjk

     

     

    Sample Output

    asdfg

    asdfghjk

     

    题意概括:

    先确定s1和s2相同的部分并输出s1中相同部分之前的串、相同部分和s2中相同部分之后的串。

    解题分析:

    水题。进行两次KMP,然后读懂题意就可以了。主要就是判断s1的后缀和s2的前缀相等,然后输出s1相同部分之前的字

    符、相同部分和s2相同部分之后的字符。因为在对s1和s2进行KMP时,它俩都可以作为文本串和模板串,所以要进行两

    次KMP。当两次KMP返回的值不相等时,就要用值大的那个(KMP返回的值是两个字符串前后缀相等的长度)。如果两

    个返回值相等再按字母表顺序输出(这里就包含了两个串不相等的情况了)。

    需要注意的是“asdfwedf”, “df” 这组数据如果用一般的KMP是卡不住这组数据的(虽然OJ中没有这组数据)。

    通常KMP中循环的结束是当两个字符串有一个结束就结束循环,然后判断一下文本串是否跑完处理一下返回值就可以了。如下:

    [cpp] view plain copy

     print?

    1. int KMP(char s[], char t[])  
    2. {  
    3.     get_next(t);  
    4.     int i = 0, j = 0, l1, l2;  
    5.     l1 = strlen(s);  
    6.     l2 = strlen(t);  
    7.     while(i < l1 && j < l2){//结束条件  
    8.         if(j == 0 && s[i] != t[j])  
    9.             i++;  
    10. 10.         else if(j > 0 && s[i] != t[j])  
    11. 11.             j = Next[j-1];  
    12. 12.         else{  
    13. 13.             i++;  
    14. 14.             j++;  
    15. 15.         }  
    16. 16.     }  
    17. 17.     if(i == l1)//处理返回值  
    18. 18.         return j;  
    19. 19.     return 0;  

    20. }  

    但是这是卡不住刚才说的数据的,因为它的两次KMP的值都会是0,输出是“asdfwedfdf”,但它的正确输出应该是“asdfwedf”才对。

    其中的原因只要理解了KMP的处理过程就不难想出来了。

    话不多说了直接上代码吧,聪明的你一看就懂。

    AC代码:

    [cpp] view plain copy

     print?

    1. #include<stdio.h>  
    2. #include<string.h>  
    3.   
    4.   
    5. #define N 100010  
    6.   
    7.   
    8. int Next[N];  
    9. char s1[N], s2[N];  
    10. 10.   
    11. 11.   

    12. void get_next(char str[])  

    13. {  

    1. 14.     int i = 1, j = 0, len;  
    2. 15.     len = strlen(str);  
    3. 16.     while(i < len){  
    4. 17.         if(j == 0 && str[i] != str[j]){  
    5. 18.             Next[i] = 0;  
    6. 19.             i++;  
    7. 20.         }  
    8. 21.         else if(j > 0 && str[i] != str[j])  
    9. 22.             j = Next[j-1];  
    10. 23.         else{  
    11. 24.             Next[i] = j+1;  
    12. 25.             i++;  
    13. 26.             j++;  
    14. 27.         }  
    15. 28.     }  

    29. }  

    30. int KMP(char s[], char t[])  

    31. {  

    1. 32.     get_next(t);  
    2. 33.     int i = 0, j = 0, l1, l2;  
    3. 34.     l1 = strlen(s);  
    4. 35.     l2 = strlen(t);  
    5. 36.     while(i < l1){//这里必须要把s串跑完,不然会造成bug,漏掉情况。虽然按一般的形式写也能AC  
    6. 37.         if(j == 0 && s[i] != t[j])  
    7. 38.             i++;  
    8. 39.         else if(j > 0 && s[i] != t[j])  
    9. 40.             j = Next[j-1];  
    10. 41.         else{  
    11. 42.             i++;  
    12. 43.             j++;  
    13. 44.         }  
    14. 45.     }  
    15. 46.     return j;  

    47. }  

    1. 48.   
    2. 49.   

    50. int main()  

    51. {  

    1. 52.     int k, k1, k2;  
    2. 53.     while(~scanf("%s%s", s1, s2)){  
    3. 54.         k1 = KMP(s1, s2);  
    4. 55.         k2 = KMP(s2, s1);  
    5. 56.         if(k1 == k2){  
    6. 57.             if(strcmp(s1, s2) == -1)  
    7. 58.                 printf("%s%s ", s1, s2+k1);  
    8. 59.             else  
    9. 60.                 printf("%s%s ", s2, s1+k1);  
    10. 61.         }  
    11. 62.         else if(k1 > k2)  
    12. 63.             printf("%s%s ", s1, s2+k1);  
    13. 64.         else  
    14. 65.             printf("%s%s ", s2, s1+k2);  
    15. 66.     }  
    16. 67.     return 0;  

    68. }  

  • 相关阅读:
    gradle文件中自定义字段值在java代码中使用
    Kotlin中,lateinit 和 lazy{} 的区别
    AndroidStudio Terminal的使用
    组件化踩过的坑
    MVP
    关于组件化的思考
    AspectJ使用的遇到的坑
    使用AOP思想无侵入式申请权限,解决组件化中权限问题(一)
    小米造最强超分辨率算法 | Fast, Accurate and Lightweight Super-Resolution with Neural Architecture Search
    新型超分辨率方法:用神经网络迁移参照图像纹理
  • 原文地址:https://www.cnblogs.com/didideblog/p/7397782.html
Copyright © 2011-2022 走看看