[算法系列之十二]字符串匹配之蛮力匹配

引言

字符串匹配是数据库开发和文字处理软件的关键。幸运的是所有现代编程语言和字符串库函数,帮助我们的日常工作。不过理解他们的原理还是比较重要的。

字符串算法主要可以分为几类。字符串匹配就是其中之一。当我们提到字符串匹配算法,最基本的方法就是所谓的蛮力解法,这意味着我们需要检查每一个文本串中的字符是否和匹配串相匹配。一般来说我们有文本串和一个匹配串(通常匹配串短于文本串)。我们需要做的就是回答这个匹配串是否出现在文本串中。

概述

字符串蛮力匹配法的原理非常简单。我们必须检查匹配串的第一个字符与文本串的第一个字符是否相匹配,就如下图片所述。

我们通过比较文本串的和匹配串的第一个字符来开始

如果他们不匹配我们移向文本串的第二个字符。现在我们比较匹配串的第一个字符和文本串第二个字符。如果他们不匹配我们继续向前移动,直到我们遇到一个相匹配的或直到我们到达文本串的最后。

因为文本串第一个字符和匹配串的第一个字符不匹配,我们向前移动到文本串的的第二个字符。现在我们比较文本串的第二个字符和匹配串的第一个字符!

假设第一个字符匹配,我们移向匹配串的第二个字符去和文本串的下一个字符比较。如下面图片所示。

如果文本串的一个字符和匹配串的第一个字符相匹配,我们向前移动到匹配串第二个字符和文本串的下一个字符做匹配

如果仅仅是因为匹配串的第一个字符与文本串的某个字符相匹配,那并不意味着这个匹配串出现在文本串中,也仅仅是第一个字符出现在文本串中,其他说明不了。我们必须向前移动匹配串,看看完整的匹配串是否包含在文本文本串中。

匹配串相匹配

代码

/*--------------------------------
*   日期:2015-02-05
*   作者:SJF0115
*   题目: 字符串匹配之蛮力匹配
*   博客:
------------------------------------*/
#include <iostream>
using namespace std;

int SubString(string text,string pattern){
    int m = text.size();
    int n = pattern.size();
    // 蛮力匹配
    for(int i = 0;i < m - n;++i){
        int j = 0;
        while(j < n && text[i+j] == pattern[j]){
            ++j;
        }//while
        // match
        if(j == n){
            return i;
        }//if
    }//for
    return -1;
}

int main(){
    string text("hello world!");
    string pattern("o wo");
    int result = SubString(text,pattern);
    cout<<"下标位置->"<<result<<endl;
    return 0;
}

复杂度

就像我说的这个算法是缓慢的。实际上每一个算法,只要在它的名字中包含“蛮力”二字,这个算法都是很缓慢的,其时间复杂度是O(n*m)。这里m是文本串的长度,而n是匹配串的长度。

原文连接

Computer Algorithms: Brute Force String Matching

时间: 2024-11-15 20:12:06

[算法系列之十二]字符串匹配之蛮力匹配的相关文章

[算法系列之十四]字符串匹配之Morris-Pratt字符串搜索算法

前言 我们前面已经看到,蛮力字符串匹配算法和Rabin-Karp字符串匹配算法均非有效算法.不过,为了改进某种算法,首先需要详细理解其基本原理.我们已经知道,暴力字符串匹配的速度缓慢,并已尝试使用Rabin-Karp中的一个散列函数对其进行改进.问题是,Rabin-Karp的复杂度与强力字符串匹配相同,均为O(mn). 我们显然需要采用一种不同方法,但为了提出这种不同方法,先来看看暴力字符串匹配有什么不妥之处.事实上,再深入地研究一下它的基本原理,就能找到问题的答案了. 在暴力匹配算法中,需要检

算法系列(十二)散列

概述 Hash,一般翻译做"散列",也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值.这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值.简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数. HASH主要用于信息安全领域中加密算法,它把一些不同长度的信息转化成杂乱的128位的编码

[算法系列之二十六]字符串匹配之KMP算法

一 简介 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此人们称它为克努特-莫里斯-普拉特操作(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的. 二 基于部分匹配表的KMP算法 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含搜索串"ABCDABD"? 步骤1:字符串"BBC ABC

[算法系列之十八]海量数据处理之BitMap

一:简介 所谓的BitMap就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了bit为单位来存储数据,因此在存储空间方面,可以大大节省. 二:基本思想 我们用一个具体的例子来讲解,假设我们要对0-7内的5个元素(4,7,2,5,3)排序(这里假设这些元素没有重复).那么我们就可以采用BitMap的方法来达到排序的目的.要表示8个数,我们就只需要8个bit(1Bytes). (1)首先我们开辟1字节(8bit)的空间,将这些空间的所有bit位都置为0,如下图: (2

hbase源码系列(十二)Get、Scan在服务端是如何处理?

继上一篇讲了Put和Delete之后,这一篇我们讲Get和Scan, 因为我发现这两个操作几乎是一样的过程,就像之前的Put和Delete一样,上一篇我本来只打算写Put的,结果发现Delete也可以走这个过程,所以就一起写了. Get 我们打开HRegionServer找到get方法.Get的方法处理分两种,设置了ClosestRowBefore和没有设置的,一般来讲,我们都是知道了明确的rowkey,不太会设置这个参数,它默认是false的. if (get.hasClosestRowBef

C++语言笔记系列之十二——C++的继承

C++的继承 1.继承方式 public(公有继承) 派生类中的成员可以访问基类的public成员和protected成员,但不能访问基类的private成员. 派生类的对象只能访问基类的public成员. protected(保护继承),private(私有继承) 派生类中的成员可以访问基类的public成员和protected成员,但不能访问基类的private成员. 派生类的对象不能访问基类的任何成员. 2.例子 example 1: #include <iostream.h> clas

quick-cocos2d-x 学习系列之十二 关于websocket

quick-cocos2d-x 学习系列之十二 关于websocket 1.  概念 百度百科:WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex). 在浏览器中通过http仅能实现单向的通信,comet可以一定程度上模拟双向通信,但效率较低,并需要服务器有较好的支持; flash中的socket和xmlsocket可以实现真正的双向通信,通过 flex ajax bridge,可以在javascript中使用这两项功能. 可

算法导论第十二章__二叉搜索数

package I第12章__二叉搜索树; //普通二叉树 public class BinaryTree<T> { // -----------------------数据结构--------------------------------- private int height = 0; private Node<T> rootNode; class Node<T> { T t; int key; Node left; Node right; public Node

【算法】利用有限自动机进行字符串匹配

1102. Strange Dialog Time Limit: 1.0 second Memory Limit: 16 MB One entity named "one" tells with his friend "puton" and their conversation is interesting. "One" can say words "out" and "output", besides h