대용량 텍스트 단어 수 (문제에 대한 P1308 로스 문제 솔루션 밸리, 자바 언어의 설명)

질문 질문

P1308 주제 링크

그림 삽입 설명 여기
그림 삽입 설명 여기

분석

이 문제 자체가, 다음은 이탈리아, 분석 다음과 같은 성가신입니다.

제목 태그 "고성능"을 선택하고, 데이터 범위에서 폭력 일치 확실한 죽음을 찾습니다. 내가 사용하는 문자를 싫어 [] 천천히 잉크, 자바 우리가 문자열로 이제 문제를 해결하기 위해 노력하고 있으므로, 이것은 매우 성가신 운영! !

두 가지 작업을 수행하려면 : 먼저, 단어가 많은 패턴 텍스트의 단어에 표시되는 횟수를 얻을 , 두 번째는 첫 번째 텍스트에서 단어의 여러 위치에 나타난 패턴 단어를 얻을 .
나는 일치하는 텍스트와 일치하는 단어를 읽어, 말을한다는 말을하지 않는 이유를 이해할 것이다.

경우는 취급이 용이도 같이 IndexOf String 클래스 () 메소드가 아닌 직접 수를 처리 할 수 ​​있지만, 루프 동안을 열 등과 같은 일치하는 문자열입니다.

이 또한 좋은,하지만 불행히도 매우 아픈하려면 없습니다.
그것은 N 단어에 공백 문자로 구분됩니다, 우리는 문제를 해결할 수없는 일반적인 솔루션을 양성하는 단어가 아닌 전체 텍스트 검색을 일치합니다.

우리의 즉각적인 생각이 분할 될 수있다이 경우에는 (), 직접 분리 " “라인에 있지만 수 없습니다.
보기는 하나 개의 테스트 데이터를 묻는 메시지가 오심 것을 때문에, WA는 일단 사실을 발견 공백 문자의 수 는 ......
그래서 정규 표현식을 사용하여 ”\\s+"분할 될 수있다.

그러나 ~ 만 30 점을 지불하도록, 사실, 단순히 잘못된 아이디어, 수집 된 데이터 세트 3 항에있어서, 통계가 같이 IndexOf를 수행 말을하는 것입니다 같이 IndexOf에 시작, 간단한 생각에서이 있어야하고, 그것은 다시 텍스트보다는 일치하는 단어 일치에 갔기 때문에, 불행히도하지 못했습니다 노래 천천히 계산 만한다.

당신이 대머리, 아, 숙고 계속, 우리는 일치를 대체하게 " " + pattern + " "단어에 혼자 있음, 난, 떨어져 다른 단어로 주위를 보장하기 때문에로, 미안 해요, 난 여전히 아, 특별한 문장의 종말의 시작을 무시하고 있기 때문이다.

这一加上对开头结尾的考虑,代码量激增,必须加很多变量去做过程的处理。具体的看最后的AC代码就行啦,为了调整整个不出Bug,比较麻烦,所以这题让人恶心。

比如我们要先用startWith(pattern + " “)做开头的判断,用endWith(” " + pattern)做结尾的判断,过程中怎么处理balabala,过程怎么进行跃进式的indexOf计数,如何保证第一次就是真的第一次,也会漏结尾的情况balabala,看代码就好了,多说无益。

还有那个“超大容量”,看后面我第二次提交的情况吧,那是什么鬼数据啊,我的记事本和Word都快炸了……好在只有测试数据9一个测试用例这样,不然岂不……太惨了吧……

此题比较恶心,不想多说了。

第一次提交——WA

그림 삽입 설명 여기

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String pattern = scanner.nextLine();
        String[] text_array = scanner.nextLine().split(" ");
        int counter = 0, index = -1;
        for (int i = 0; i < text_array.length; i++) {
            String s = text_array[i];
            if (s.equalsIgnoreCase(pattern)) {
                counter++;
                if (index == -1) {
                    index = i;
                }
            }
        }
        if (index == -1) {
            System.out.println(-1);
        } else {
            System.out.println(counter + " " + index);
        }
        scanner.close();
    }
}

错因前面分析了,就不说了,一看就知道的。

分享一下测试数据3:
in
u
tIXHUguyz PZYAJL BIv NAPoemaJ aTF LOvhV m s LSa n xDn mQnO T ettIq T AL fG B Xme t fct U tQ d

out
1 92

第二次提交——MLE

그림 삽입 설명 여기

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String pattern = scanner.nextLine().toUpperCase(), text = scanner.nextLine().toUpperCase();
        int length = pattern.length(), counter = 0, firstIndex = -1, tempIndex = -1;
        boolean endFlag = false;
        if (text.startsWith(pattern + " ")) {
            counter++;
            firstIndex = 0;
            pattern = " " + pattern + " ";
            tempIndex = text.indexOf(pattern);
        }
        if (text.endsWith(" " + pattern)) {
            counter++;
            endFlag = true;
        }
        pattern = " " + pattern + " ";
        if (counter == 0) {
            firstIndex = tempIndex = text.indexOf(pattern);
        }
        while (tempIndex != -1) {
            text = text.substring(tempIndex + length);
            tempIndex = text.indexOf(pattern);
            counter++;
        }
        if (firstIndex == -1) {
            if (endFlag) {
                System.out.println(1 + " " + (text.length()-1));
            } else {
                System.out.println(-1);
            }
        } else {
            System.out.println(counter + " " + (firstIndex+1));
        }
        scanner.close();
    }
}

这个测试数据9……我真没法Share,太大了,这就是我说的超大容量……
这样吧,我把文本数据导进了Word,我先进的电脑卡爆了,加载的数据:
그림 삽입 설명 여기

当然这在现在的海量文本数据里面微乎其微,但你要知道这只是一个简单的OJ题啊,这么大的数据量,用Java不得炸裂!!

但我们转而思考自身可能引发超时超内存的问题:数组!!
我们没开数组啊??但String本身不就有数组吗!!!
恍然大悟,我们开了太多substring()了啊,删去就好,换一个indexOf()的重载方法就好!!!

乌拉乌拉乌拉!!!

第三次提交——AC

그림 삽입 설명 여기

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String pattern = scanner.nextLine().toUpperCase(), text = scanner.nextLine().toUpperCase();
        int length = pattern.length(), counter = 0, firstIndex = -1, tempIndex = -1;
        boolean endFlag = false;
        if (text.startsWith(pattern + " ")) {
            counter++;
            firstIndex = 0;
            pattern = " " + pattern + " ";
            tempIndex = text.indexOf(pattern);
        }
        if (text.endsWith(" " + pattern)) {
            counter++;
            endFlag = true;
        }
        pattern = " " + pattern + " ";
        if (counter == 0) {
            firstIndex = tempIndex = text.indexOf(pattern);
        }
        while (tempIndex != -1) {
            tempIndex = text.indexOf(pattern, tempIndex+length);
            counter++;
        }
        if (firstIndex == -1) {
            if (endFlag) {
                System.out.println(1 + " " + (text.length()-1));
            } else {
                System.out.println(-1);
            }
        } else {
            System.out.println(counter + " " + (firstIndex+1));
        }
        scanner.close();
    }
}

总结

  • 在处理一个问题的时候,其实稍加变换解决思路就能大有改观。
  • 解决问题就是根据已知,不断转化转化再转化,直到转化出我们需要的条件,再求解。
  • Java的API博大精深,不断研究,总会有新收获呢。

不知道大家可有收获?今年是大年初一,新春快乐@All !!!

게시 된 367 개 원래 기사 · 원 찬양 (626) ·은 40000 +를 볼

추천

출처blog.csdn.net/weixin_43896318/article/details/104084512