• [学习笔记]基础字符串算法


    这里使用“基础”仅代表整合一些篇幅小的算法与后续几篇大的字符串算法文章区别。

    留给自己补科技树的时间越来越短了。

    字符串哈希

    容易实现,可以快速比对两个串是否相等。

    一般可以使用自然溢出\(Hash\)

    注意使用非自然溢出时,应当把膜数取比字符串数量高一个数量级的质数。

    最小循环表示法

    考虑有\(SAM\)构建的做法。

    我们这里有一个简单做法,定义两个指针\(i = 1,j = 2\)

    两个指针不断向后匹配,直到两个字符不相等,假设前面相等的长度为\(k\),如果\(s[i + k] < s[j + k]\),则\(j = j + k + 1\),否则\(i = i + k + 1\),如果上述操作之后两个数相等,则强制一个向后移动。
    具体实现则是:

    点击查看代码
    	scanf("%lld",&n);
    	for(int i = 1;i <= n;++i)
    	scanf("%lld",&a[i]);
    	for(int i = n + 1;i <= 2 * n;++i)
    	a[i] = a[i - n];
    	int j = 1,i = 2,k,tmp;
    	while(i <= n){
    		k = 0;
    		while(a[i + k] == a[j + k])
    		k += 1;
    		if(a[i + k] < a[j + k])
    		tmp = i,i = std::max(i + 1,j + k + 1),j = tmp;
    		else
    		i = i + k + 1;
    	}
    	for(int l = 1;l <= n;++l)
    	std::cout<<a[j + l - 1]<<" ";
    }
    

    KMP 算法

    现在看KMP就觉得有新的理解。
    我们现在发现求出的\(next\)实际是最长的border。

    AC自动机

    考虑实际上是在\(Trie\)上构建最长border树。

    有三类题目:
    首先是直接在自动机上匹配的问题。
    第二类是在\(AC\)自动机上dp,这类问题是强制不能出现或者一定出现的题,可以直接在Trie图上跑,并记录状态即可。
    第三类题目即使用\(fail\)树,其关键性质是所有有\(S\)作为子串的串都在其子树内,有意思的题即我前几天写的Salieri

  • 相关阅读:
    循环的其他用法
    if和switch
    Activity and Task Design
    Accessing Resource学习
    Ctrl 和Alt 快捷键设置的原则
    Android代码没有错误,但是运行出错
    Android读取txt文本文档在手机上显示乱码解决方法
    ImageButton介绍及两种透明方案
    Android 的 Button 按钮实现的两种方式
    resdrawable-hdpi ew.png:0: error: invalid symbol: 'new'错误原因是new是关键词呀
  • 原文地址:https://www.cnblogs.com/dixiao/p/15918429.html
Copyright © 2020-2023  润新知