递归火山软件开发平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 火山 源码 类库
查看: 1956|回复: 4
打印 上一主题 下一主题

[视窗] Boyer-Moore快速查找算法

[复制链接]

86

主题

947

帖子

4884

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
4884
跳转到指定楼层
楼主
发表于 2024-3-14 08:15:24 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 小蜗牛 于 2024-3-14 08:22 编辑

文本快速查找算法,可以不区分大小写~
适用于,查找大文本...或者,输入一个值,查找多个目标...

如果是很短的文本,并且频繁切换要查找的子文本(也就是每一次查找都初始化),不会更快,只会更慢,请熟知!


<火山程序 类型 = "通常" 版本 = 1 />

类 BM查找算法 <注释 = "Boyer-Moore算法" 注释 = "" 注释 = "https://cloud.tencent.com/developer/article/1490414" 折叠>
{
    变量 m_短文本 <类型 = 文本型>
    变量 m_短文本表 <类型 = 整数数组类>
    变量 m_短文本长度 <类型 = 整数>
    变量 m_区分大小写 <类型 = 逻辑型>

    方法 计算字符表 <静态 注释 = "computeBadCharTable" 折叠>
    参数 要计算的文本 <类型 = 文本型>
    参数 返回表 <类型 = 整数数组类>
    {
        变量 i <类型 = 整数>
        变量 当前字符 <类型 = 字符>
        返回表.重置数组 (数值范围.最大字符值 + 1, 假)
        循环 (0, 返回表.取成员数 (), i)
        {
            返回表.置成员值 (i, -1)
        }
        循环 (0, 取文本长度 (要计算的文本), i)
        {
            当前字符 = 取字符 (要计算的文本, i)
            返回表.置成员值 (当前字符, i)
        }
    }

    方法 初始化 <公开 注释 = "一般只需要初始化一次即可" 折叠>
    参数 要查找的子文本 <类型 = 文本型 注释 = "要查找的子文本!~">
    参数 区分大小写 <类型 = 逻辑型>
    {
        m_短文本 = 要查找的子文本
        m_短文本长度 = 取文本长度 (m_短文本)
        m_区分大小写 = 区分大小写
        如果 (m_区分大小写 == 假)
        {
            自身到大写 (m_短文本)
        }
        计算字符表 (m_短文本, m_短文本表)
    }

    方法 查找 <公开 类型 = 整数 注释 = "可以多次查找~">
    参数 长文本指针 <类型 = 变整数 注释 = "UTF-16文本指针">
    参数 长文本长度 <类型 = 整数 注释 = "要查找的长度~">
    {
        变量 短文本索引 <类型 = 整数>
        变量 起始位置 <类型 = 整数>
        变量 短文本地址 <类型 = 变整数>
        变量 短文本表指针 <类型 = 变整数 注释 = "数组地址">
        变量 x <类型 = 整数>
        变量 ""
        变量 j <类型 = 整数>
        变量 i <类型 = 整数>
        变量 max <类型 = 整数>
        变量 区分大小写 <类型 = 逻辑型>
        短文本索引 = m_短文本长度 - 1
        短文本地址 = 取文本指针 (m_短文本)
        短文本表指针 = m_短文本表.取数组指针 ()

        x = 长文本长度 - 短文本索引
        区分大小写 = m_区分大小写

        判断循环 (起始位置 <= x)
        {
            j = 短文本索引
            i = 起始位置 + j
            如果 (区分大小写)
            {
                判断循环 (j >= 0 && 文本指针_取字符 (短文本地址, j) == 文本指针_取字符 (长文本指针, i))
                {
                    j = j - 1
                    i = i - 1
                }
            }
            否则
            {
                判断循环 (j >= 0 && 文本指针_取字符 (短文本地址, j) == 字符_到大写 (文本指针_取字符 (长文本指针, i)))
                {
                    j = j - 1
                    i = i - 1
                }
            }

            如果 (j < 0)
            {
                返回 (起始位置)  // 找到匹配
            }
            否则
            {
                // 坏字符规则
                max = j - 读指针处值 (短文本表指针 + 文本指针_取字符 (长文本指针, i) * 4, 整数)  // 读指针处对象 (短文本表指针, 整数数组类).取成员 (文本指针_取字符 (长文本指针, i))
                如果 (max < 1)
                {
                    max = 1
                }
                起始位置 = 起始位置 + max
            }
        }

        返回 (-1)  // 未找到匹配
    }

    方法 文本指针_取字符 <静态 类型 = 字符 折叠 @嵌入式方法 = "">
    参数 文本指针 <类型 = 变整数>
    参数 索引 <类型 = 整数 注释 = "请确保不会越界~">
    {
        @ *(wchar_t*)(@<文本指针> + @<索引> * 2)

        // 返回 (读指针处值 (文本指针 + 索引 + 索引, 字符))
    }

    方法 字符_到大写 <静态 类型 = 字符 折叠 @视窗.前缀文本 = "inline">
    参数 当前字符 <类型 = 字符>
    {
        如果 (当前字符 >= 'a' && 当前字符 <= 'z')
        {
            当前字符 = 当前字符 - (字符)' '
        }
        返回 (当前字符)
    }
}


回复

使用道具 举报

86

主题

947

帖子

4884

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
4884
5#
 楼主| 发表于 2024-3-14 11:07:28 | 只看该作者
shuimiao 发表于 2024-3-14 09:40
我也有类似算法,不过没有名字,自己想的算法。也是先初始化要查找的目标文本,建一个表,后面大量查找子文 ...

嗯,你这个百倍有点猛啊
回复

使用道具 举报

410

主题

2511

帖子

8281

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
8281
地板
发表于 2024-3-14 09:40:59 来自手机 | 只看该作者
我也有类似算法,不过没有名字,自己想的算法。也是先初始化要查找的目标文本,建一个表,后面大量查找子文本的操作就能提速百倍千倍。而对于每次查找换一个目标文本的场景,这种算法反而更慢。所以是特定用途
回复

使用道具 举报

86

主题

947

帖子

4884

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
4884
板凳
 楼主| 发表于 2024-3-14 09:28:27 | 只看该作者
本帖最后由 小蜗牛 于 2024-3-14 09:29 编辑
aycap 发表于 2024-3-14 09:07
要多长的文本才算大文本?

不管是多次查找,还是单次查找,个人感觉,累计起码10K吧查找十次不同的1K
或者,查找一次10K...

只是个人感觉.没有测试

回复

使用道具 举报

21

主题

263

帖子

3121

积分

核心用户

Rank: 9Rank: 9Rank: 9

积分
3121
沙发
发表于 2024-3-14 09:07:23 | 只看该作者
要多长的文本才算大文本?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|递归火山软件开发平台 ( 鄂ICP备18029190号 )

GMT+8, 2024-11-23 20:45 , Processed in 0.091459 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表