• [Aizu] ALDS1_14_B: String Search


    题目

    传送门: ALDS1_14_B: String Search

    描述

    寻找字符串P在一个文本T中出现的位置, 输出所有在T中找到的P的索引, T的索引从0开始.

    输入

    第一行, 给出一个文本T, 在第二行, 给出一个字符串P

    输出

    每行输出一个在T中找到的P的下标, 以升序输出

    限制条件

    • (1 leq length of T leq 1000000)
    • (1 leq length of P leq 10000)
    • 输入由字母字符和数字组成

    样例输入1

    aabaaa
    aa
    

    样例输出1

    0
    3
    4
    

    样例输入2

    xyzz
    yz
    

    样例输出2

    1
    

    样例输入3

    abc
    xyz
    

    样例输出3

     
    

    求解

    分析

    尝试了普通的查找, 从T开始遍历, 如果第一次匹配了, 然后将当前位置给k, 然后k遍历T, j遍历P, 如果有不同则退出, 如果全部相同则输出, 之后继续之前T的遍历
    但是结果是时间超时, 完全没有更好的思路, 只能查看别人的代码
    tk4114的代码
    根据他的思路, 只需要用i遍历一遍T就行, 中间不需要在匹配或者不匹配时往回退一段.
    根据待查找的字符串, 可能会存在一部分重复的情况, 比如说: P = aaab, 在T = aaaab中查找时, i遍历T, j遍历P, 前3个a匹配完毕, 到了第四个a的时候, 前面是b, 所以不能匹配, 但是由于之前有3个a已经匹配过了, 我们不需要将i退回到第2个a的位置, 并将j退回到第一个a的位置, 而只需要将j退回到第3个a的位置, 然后重新进行比较就可以了, 相当于在P中前两个a已经比较过了. 从而减少比较的次数

    设计

    还是感觉有点不理解, 直接贴代码了

    编码

    // 参考了用户 tk4114 的代码
    #include <bits/stdc++.h>
    using namespace std;
    
    int main(void) {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    
    	char T[1000005], P[10005];
    	cin.getline(T, 1000005);
    	int Tl = cin.gcount() - 1;
    	cin.getline(P, 10005);
    	int Pl = cin.gcount() - 1;
    	if (Pl > Tl) return 0;
    
    	int jmp[10005];
    	jmp[1] = 0;
    	int i = 2, j = 0;
    	while (i <= Pl) {
    		if (P[i - 1] == P[j]) {
    			i++;
    			j++;
    			jmp[i - 1] = j;
    		} else if (j > 0) {
    			j = jmp[j];
    		} else {
    			jmp[i] = 0;
    			i++;
    		}
    	}
    
    	i = 0;
    	j = 0;
    	while (i < Tl) {
    		if (T[i] == P[j]) {
    			i++;
    			j++;
    			if (j == Pl) {
    				cout << i - Pl << endl;
    				j = jmp[j];
    			}
    		} else if (j > 0) {
    			j = jmp[j];
    		} else {
    			i++;
    		}
    	}
    }
    

    结果

    由于是几乎照搬别人的代码, 就不截图了

    总结

    可能几天内暂时不做其他题了, 专心研究这一块

  • 相关阅读:
    爬虫伪装头部
    selenium的简单使用
    selenium 安装与 chromedriver安装
    python多线程和线程池
    分析微信好友列表信息(json)
    BeautifulSoup简介
    Java泛型中extends和super的理解
    java 泛型--桥方法
    java 资源文件的读取
    java 清单文件
  • 原文地址:https://www.cnblogs.com/by-sknight/p/10944961.html
Copyright © 2020-2023  润新知