# hihocoder #1082 : The Marshtomp has seen it all before

标签(空格分隔): hihocoder


题目:#1082 : The Marshtomp has seen it all before

Description

fjxmlhx is fed up with endless marshtomps on the internet. So he turns to you to write a program to change all occurrence of “marshtomp” ( the name is not case-sensitive) to “fjxmlhx”.
此处输入图片的描述

Input

The input contains multiple lines.
Each line is a string which length is no more than 200.
The end of one line don’t connect with the head of the next line.

Output

The output contains multiple lines which are the result after the changes in the description.

Sample Input

The Marshtomp has seen it all before.
marshTomp is beaten by fjxmlhx!
AmarshtompB

Sample Output

The fjxmlhx has seen it all before.
fjxmlhx is beaten by fjxmlhx!
AfjxmlhxB

  这道题目主要是分两步解决,一是找出输入中匹配“marshtomp ”的位置,而是替换这些“marshtomp”字符串为“fjxmlhx”。
字符串匹配可以使用暴力匹配,也可以使用一些优化后的匹配算法,比如KMP算法。
  在匹配的时候,用list或数组保存原始字符串中匹配起始位置(数组需要预估数组大小)。替换可以通过依次添加原始字符串的部分,注意首尾的情况处理。
  KMP算法可以参考博客从头到尾彻底理解KMP。KMP算法的关键在于求解next数组,求解next数组关键在于理解字符串的最长前缀后缀。这个最长前缀后缀不包括字符串本身。next数组的含义就是,第j位字符前面的next[j]个字符,和这个字符串的前next[j]个字符是匹配的,即如果目前匹配串的第j位字符和被匹配串的当前字符不等时,可以将匹配串想右移动j-next[j]位来继续匹配,因为被匹配串的前next[j]个字符是和匹配串第j位的前next[j]个字符相匹配的,即和匹配串的前next[j]位相匹配。
最后代码如下:

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    private static ArrayList<Integer> findStr(String str, String regex) {
        ArrayList<Integer> resIndex = new ArrayList<Integer>();
        int[] next = new int[regex.length()];
        getNext(regex, next);

        int i = 0; 
        int j = 0;
        while (i < str.length() ) {

            if (j == -1 || str.charAt(i) == regex.charAt(j)) {
                i++; j++;
            } else {
                j = next[j];
            }
            if (j == regex.length()) {
                resIndex.add(i - regex.length());
                j = 0;
            }
        }
        return resIndex;
    }

    private static void getNext(String str, int[] next) {
        next[0] = -1;
        int j = -1;
        int i = 0;
        while (i < str.length() - 1) {
            if ( j == -1 || str.charAt(i) == str.charAt(j) ) {
                i++;
                j++;
                next[i] = j;
            } else {
                j = next[j];
            }
        }
    }

    public static void main(String[] args) {

        Scanner sin = new Scanner(System.in);
        while (sin.hasNext()) {
            String tline = sin.nextLine();
            ArrayList<Integer> intervalInt = findStr(tline.toLowerCase(), "marshtomp");

            StringBuilder res = new StringBuilder(); 
            int idxF = 0;
            intervalInt.add(tline.length());

            for (int i = 0; i < intervalInt.size(); i++) {
                res.append(tline.substring(idxF, intervalInt.get(i))).append("fjxmlhx");
                idxF = intervalInt.get(i) + 9;  // 9是marshtomp的长度
            }
            res.delete(res.length()-7, res.length());
            System.out.println(res.toString());
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值