zoukankan      html  css  js  c++  java
  • toj 2806 Replace Words

    2806.   Replace Words
    Time Limit: 1.0 Seconds   Memory Limit: 65536K
    Total Runs: 476   Accepted Runs: 172    Multiple test files



    The text editors such as notepad, Microsoft Word, all have a very useful tool in edit menu, that is "replace", which you can press a shortcut key "ctrl+H" to open. It can help us when we want to replace all of certain set of words with another set of words in our text files.

    Now the task coming to us is to write a program for simulating this "Replace" function.

    Input

    For each test case, the first line contains the word(s) to be replaced (consist of 100 characters at most), the second line contains the new word(s) (consist of 100 characters at most). Please note both lines may contain blank spaces. Then following lines are all text contents till the end of file. For each line, it consists of 1000 characters at most.

    Output

    Output the new text contents after you have replaced all the words. The format of new text contents is the same as text contents shown in input.

    Sample Input

    Tianjin University
    TJU
    Brief Introduction
    --------------------------------------------------------------------------------
    Vision
    Tianjin University aspires to be a world-class, progressive, and multidisciplina
    ry research university.
    Mission
    Tianjin University is committed to
    - Advancing knowledge
    - Bringing knowledge to industry for social development
    - Collaborating with leading institutions and organizations
    - Developing quality education combined with rigorous academic research
    Motto
    Seeking Truth from Facts
    Guideline
    Precise in Learning, Strict in Teaching
    Focus
    Engineering integrated with Science, Liberal Arts, Business, Law, etc.

    Sample Output

    Brief Introduction
    --------------------------------------------------------------------------------
    Vision
    TJU aspires to be a world-class, progressive, and multidisciplina
    ry research university.
    Mission
    TJU is committed to
    - Advancing knowledge
    - Bringing knowledge to industry for social development
    - Collaborating with leading institutions and organizations
    - Developing quality education combined with rigorous academic research
    Motto
    Seeking Truth from Facts
    Guideline
    Precise in Learning, Strict in Teaching
    Focus
    Engineering integrated with Science, Liberal Arts, Business, Law, etc.

    Problem Setter: tashj (blog: http://tashj.yculblog.com)

    Source: TJU Programming Contest 2007 Preliminary


    Submit   List    Runs   Forum   Statistics

    //注意这个KMP是用字符数组,并且它是从字符数组的0下标开始用的
    //638970 2009-05-16 09:36:08 Accepted 2806 C++ 1.3K 0'00.00" 2188K forever4444 
    #include <iostream>
    #include 
    <cstring>
    using namespace std;

    const int N = 1003;
    char str[N][N];
    char red[104], T[104];
    int next[103], Tlen, Slen;

    void get_next()  //计算模式串t的next函数值,存入数组next中
    {
        
    int j, k;

        j 
    = 0; k = -1; next[0= -1;

        
    while(j < Tlen)  //Tlen是要匹配的模式串的长度
            if(k == -1 || T[j] == T[k])
                next[
    ++j] = ++k;
            
    else
                k 
    = next[k];
    }


    int index_KMP(int pos, int cc)  //在目标串S中找模式串T首次出现的位置,若不存在则返回-1
    {
        
    int i, j;
        i 
    = pos ; j = 0;

        
    while(i < Slen && j < Tlen)
            
    if(j == -1 || str[cc][i] == T[j])
            {
                i
    ++; j++;
            }
            
    else
                j 
    = next[j];
        
    if(j == Tlen)   //证明查找成功了
            return i - Tlen;
        
    else   //没有查找成功
            return -1;

    }

    int main()
    {
        
    int cnt = 0;
        
    int i, j, k, kk;
        gets(T);
        gets(red);
        
        Tlen 
    = strlen(T);

        
    while(gets(str[cnt++]));
        get_next();

        
    for(i = 0; i < cnt - 1; i++//对str中每一行进行查找
        {
            Slen 
    = strlen(str[i]);  //求出每一行的长度
            for(j = 0; j < Slen; j++)   //进行模式匹配
            {
                k 
    = index_KMP(j, i);
                
    if(k == -1)   //没有找到
                {
                    printf(
    "%s", str[i] + j);
                      
    break;
                }
                
    else
                {
                    
    for(kk = j; kk < k; kk++)
                        printf(
    "%c", str[i][kk]);
                    printf(
    "%s", red);
                    j 
    = k + Tlen - 1;
                }
            }
            putchar(
    '\n');
        }

        
    return 0;
    }

    //附上我们的KMP省赛模板

    KMP
    假设 主串:s: ‘s(
    1)  s(2)  s(3) ……s(n)’ ;   模式串 :p: ‘p(1)  p(2)  p(3)…..p(m)’
    现在我们假设 主串第i个字符与模式串的第j(j
    <=m)个字符‘失配’后,主串第i个字符与模式串的第k(k<j)个字符继续比较
    此时,s(i)≠p(j),  有
    主串:               S(
    1)……  s(i-j+1)…… s(i-1)   s(i) ………….
                                    
    || (相配)   ||       ≠(失配)
    匹配串:                        P(
    1) …….  p(j-1)   p(j)
    由此,得到关系式
              ‘p(
    1)  p(2)  p(3)…..p(j-1)’   =    ’ s(i-j+1)……s(i-1)’
    由于s(i)≠p(j),接下来s(i)将与p(k)继续比较,则模式串中的前(k
    -1)个字符的子串必须满足下列关系式,并且不可能存在  k’>k  满足下列关系式:(k<j),
              ‘p(
    1)  p(2)  p(3)…..p(k-1)’   =    ’ s(i-k+1)s(i-k+2)……s(i-1)’
    即:
    主串:        S(
    1)……s(i-+1) s(i-+2) ……s(i-1)     s(i) ………….
                            
    || (相配)  ||           ||       ?(有待比较)
    匹配串:                P(
    1)      p(2)    …… p(k-1)    p(k)
    现在把前面总结的关系综合一下
    S(
    1)…s(i-+1)…  s(i-+1) s(i-+2)  ……    s(i-1)     s(i) ……
               
    || (相配)  ||         ||               ||         ≠(失配)
               P(
    1) ……p(j-k+1)   p(j-k+2)  ….   p(j-1)    p(j)
                          
    || (相配)  ||               ||          ?(有待比较)
                          P(
    1)       p(2)    …….    p(k-1)      p(k)

    由上,我们得到关系:
    ‘p(
    1)  p(2)  p(3)…..p(k-1)’   =    ’ s(j-k+1)s(j-k+2)……s(j-1)’
    接下来看“反之,若模式串中存在满足式(
    4-4)。。。。。。。”这一段。看完这一段,如果下面的看不懂就不要看了。直接去看那个next函数的源程序。(伪代码)
    K 是和next有关系的,不过在最初看的时候,你不要太追究k到底是多少,至于next值是怎么求出来的,我教你怎么学会。

    #include 
    <iostream>
    #include 
    <cstring>
    using namespace std;

    const int N = 10004;
    const int M = 1000005;

    char S[N],//主串    
         T[M];//模式串
    int Slen, Tlen;//主串和模式串的长度
    int next[M];

    void Get_next()
    {
        
    int j, k;

        j 
    = 0; k = -1; next[0= -1;

        
    while(j < Tlen)
            
    if(k == -1 || T[j] == T[k])
            {
                next[
    ++j] = ++k;
            }
            
    else
                k 
    = next[k];

    }
    int KMP_Count()
    {
    //此函数用于计算模式串在主串中出现的次数,可以交叉
        int ans = 0;
        
    int i, j = 0;
        Slen 
    = strlen(S);
        Tlen 
    = strlen(T);
        
    if(Slen == 1 && Tlen == 1)  //主串和模式串长度均为1的情况
        {
            
    if(S[0== T[0])
                
    return 1;
            
    else
                
    return 0;
        }
        Get_next();

        
    for(i = 0; i < Tlen; i++)
        {
            
    while(j > 0 && S[j] != T[i])
                j 
    = next[j];
            
    if(S[j] == T[i])
                j
    ++;
            
    if(j == Slen)
            {
                ans
    ++;
                j 
    = next[j];
            }
        }
        
    return ans;
    }

    int KMP_Index()
    {
    //此函数用于返回模式串在主串中第一次出现的位置
     
    //不存在返回-1
        int i, j;
        i 
    = j = 0;

        Slen 
    = strlen(S); Tlen = strlen(T);
        Get_next();

        
    while(i < Slen && j < Tlen)
            
    if(j == -1 || S[i] == T[j])
            {
                i
    ++; j++;
            }
            
    else
                j 
    = next[j];

        
    if(j == Tlen)   //返回第一次出现的位置
            return i - Tlen;
        
    else
            
    return -1;

    }

    int main()
    {
        
    int n;
        scanf(
    "%d"&n);
        getchar();
        
    while(n--)
        {
            scanf(
    "%s%s", S, T);//输入主串和模式串
            printf("%d\n", KMP_Count());
        }
        
    return 0;
    }

  • 相关阅读:
    [题解]luogu_P1627_中位数(排列乱搞
    [题解]luogu_P3313_旅行(树剖
    [题解]luogu_P3201_梦幻布丁(启发式合并
    [题解]luogu_P4127_同类分布(数位dp
    [题解]弹飞绵羊
    [题解]luogu_P3469_BLO(理解tarjan/割点
    [题解]luogu_P3304直径(直径必经边
    [HAOI2015]树上操作(树链剖分)
    [SCOI2005]扫雷(递推)
    洛谷3865 ST表
  • 原文地址:https://www.cnblogs.com/forever4444/p/1458145.html
Copyright © 2011-2022 走看看