strstr 的优化版本(搜索具有恒定长度)

2023-11-21

我的 C 程序有很多 strstr 函数调用。标准库 strstr 已经很快,但在我的例子中,搜索字符串的长度始终为 5 个字符。我用一个特殊版本替换了它以获得一些速度:



int strstr5(const char *cs, const char *ct)
{
    while (cs[4]) {

        if (cs[0] == ct[0] && cs[1] == ct[1] && cs[2] == ct[2] && cs[3] == ct[3] && cs[4] == ct[4])
            return 1;

        cs++;
    }

    return 0;
}
  

该函数返回一个整数,因为它足以知道 ct 是否出现在 cs 中。在这种特殊情况下,我的函数比标准 strstr 更简单、更快,但我很想听听是否有人有一些可以应用的性能改进。即使是很小的改进也是受欢迎的。

Summary:

  • cs 的长度 >=10,但其他方面可能会有所不同。长度之前已知(在我的函数中未使用)。 cs的长度通常为100到200。
  • ct 的长度为 5
  • 字符串的内容可以是任何内容

编辑:感谢您的所有回答和评论。我必须研究和测试想法,看看什么最有效。我将从 MAK 关于后缀 trie 的想法开始。


有几个快的字符串搜索算法。尝试看看博耶-摩尔(正如 Greg Hewgill 已经建议的那样),拉宾-卡普 and KMP算法。

如果您需要在同一大段文本中搜索许多小模式,您还可以尝试实现后缀树 or a 后缀数组。但恕我直言,这些有点难以理解和正确实施。

但要注意,这些技术非常快,但只有在涉及的字符串非常大时才会带来明显的加速。对于长度小于 1000 个字符的字符串,您可能看不到明显的加速。

EDIT:

如果您一遍又一遍地搜索相同的文本(即cs在调用之间总是/经常相同),通过使用后缀特里树(基本上是一个trie后缀)。由于您的文本只有 100 或 200 个字符,因此您可以使用更简单的 O(n^2) 方法来构建 trie,然后对其进行多次快速搜索。每次搜索只需要 5 次比较,而不是通常的 5*200 次。

Edit 2:

正如咖啡馆的评论所提到的,Cstrstr算法取决于实现。 glibc 使用线性时间算法,在实践中该算法应该或多或少与我提到的任何方法一样快。虽然OP的方法渐近较慢(O(N*m)而不是O(n)),但它更快可能是因为n和m(模式和文本的长度)都非常小并且它不必在 glibc 版本中进行任何长时间的预处理。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

strstr 的优化版本(搜索具有恒定长度) 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 有没有办法让 doxygen 自动处理未记录的 C 代码?

    通常它会忽略未记录的 C 文件 但我想测试 Callgraph 功能 例如 您知道在不更改 C 文件的情况下解决此问题的方法吗 设置变量EXTRACT ALL YES在你的 Doxyfile 中
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 在 Owl Carousel 2 中加载动态内容

    我有一个带有 2 个轮播的网页 我必须根据用户操作在其中显示不同的项目 新数据来自互联网 我使用fetch 将json解析成数组 一切都很好 唯一的问题是我无法让新项目替换旋转木马中的旧项目 举个简单的例子 我尝试过 var carouse
  • 写入具有设备名称的文件

    我遇到了一些奇怪的事情 我有一个反编译器 可以从二进制文件中提取信息 我正在提取一系列需要作为二进制文件单独写入磁盘的对象 这些对象是编译到库中的图形模型 这些对象中嵌入了名称 我需要使用该名称作为文件名 我在用 try Open file
  • 我可以在 cakephp 3 中的 Table 类上设置默认顺序吗

    在 CakePHP 2 x 中有一个属性 order在模型中 所以我使用这个属性来全局排序我的数据 例如 假设我需要在我的视图中显示一个包含国家 地区的选择框Country用于添加行的模型 order Country country DES
  • 在 tkinter 小部件中显示子进程的实时输出

    我的问题和这个几乎一样 显示子进程标准输出的小部件 但更进一步 我有以下代码 python2 7 def btnGoClick p1 params w line get if len params 0 return create child
  • net core 2.0 appsettings.json 保存在 bin 目录下

    我是新来的net core 2 0 我正在连接到数据库 我习惯使用App Config or Web Config设置连接字符串 但在net core 2 0中使用appsettings json文件代替 当我编译 de 应用程序时 app
  • Express.js req.body 未定义

    我将此作为我的 Express 服务器的配置 app use app router app use express cookieParser app use express session secret keyboard cat app s
  • 从列表中删除子列表

    我有 2 个清单 list1 and list2 都是int类型 现在我想删除内容list2 from list1 我怎样才能在 C 中做到这一点 PS 不要使用循环 重要变化 正如评论中指出的那样 Except 内部使用集合 因此任何重复
  • 使用 QListWidgetItem::setData 存储指针

    我有一个QListWidget日历 每个QListWidgetItem在逻辑上与一个实例相关联Calendar 它是属于应用程序模型端的类 我可以使用指针的形式存储这个关联吗QListWidgetItem setData 当我尝试执行此操作
  • 如何在 Azure Web 角色上禁用 RC4 密码

    我有一个托管在 Microsoft Azure Web 角色上的 Web 应用程序 如何禁用 RC4 密码 我使用 Powershell 脚本遇到的问题是需要修改的键包含正斜杠 而 Powershell 将此视为路径分隔符 因此脚本失败 解
  • 日期比较逻辑/液体模板过滤器

    我正在尝试创建一个类似 预购 的机制 其中我的 Shopify Liquid 模板的某些元素仅在当前日期大于或小于元字段中指定的日期时显示 截至目前 这就是我所拥有的 包括逻辑 p Today now date d m Y p p Rele
  • Flex:弄清楚正在运行的 swf 是何时编译的?

    无论如何 在 Flex 应用程序中是否可以 在运行时 确定运行的 swf 何时被编译 我想将其与服务器上 swf 的最新文件版本进行比较 并检测服务器上是否有更新版本 如果有 则强制用户重新加载浏览器以获取新版本 我需要它也可以与缓存中的
  • 节点-gyp。 MSBuild.exe`失败,退出代码:1

    我试图安装 Sharp 模块 这需要 c 编译器 我下载了 Visual Studio 2017 和 Visual C 构建工具 node gyp 安装成功 但是运行 npm install g Sharp 我遇到了很多错误 吉普 错误 堆
  • 如何在 ASP.NET ListBox 中设置多项选择?

    我无法在后面的代码中找到在 ASP NET ListBox 中选择多个项目的方法 这是需要在 Javascript 中完成的事情吗 您必须使用 ListBox 的 FindByValue 方法 foreach string selected
  • Python:如何修改/编辑打印到屏幕的字符串并将其读回?

    我想在 Windows 中将字符串打印到命令行 终端 然后编辑 更改该字符串并将其读回 有人知道该怎么做吗 谢谢 print Hell Hello lt Edit it on the screen s raw input print s H
  • 在IE11中,如何使用console.log?

    尝试使用console log 但总是打印undefined 尝试使用类似的解决方案Console log IE9 问题它也不起作用 In this IE11文档 有如下句子 Last but not least forget about
  • 比较数组是否相等,忽略元素的顺序

    我有一个包含 4 个数组列的表 结果如下 ids signed ids new ids new ids signed 1 2 3 2 1 3 4 5 6 6 5 4 无论如何都要比较ids and signed ids通过忽略元素的顺序 使
  • 重新附加实体图并检测集合更改

    我首先使用实体 框架代码 并通过 WCF REST HTTP 接口公开 Northwind 数据库 我没有公开 OrderDetails 表 订单项 因为创建订单然后通过另一个服务单独添加每个所需的 OrderDetail 是没有意义的 在
  • 在 Rails 中使用带有 has_many 的委托?

    我们有 2 个模型和一个连接模型 app models message rb Class Message lt ActiveRecord Base has many image messages has many images throug
  • 如何对实体的自定义属性进行建模?

    假设我们有一个应用程序应该能够存储所有类型的产品 每个产品至少有一个ID and a Name但所有其他属性都可以由用户自己定义 例如 他可以创建一个产品组Ipods其中将包含属性capacity and 一代 例如 他可以创建一个产品组T
  • strstr 的优化版本(搜索具有恒定长度)

    我的 C 程序有很多 strstr 函数调用 标准库 strstr 已经很快 但在我的例子中 搜索字符串的长度始终为 5 个字符 我用一个特殊版本替换了它以获得一些速度 int strstr5 const char cs const cha