字符串中的字串问题,两种算法了解。以及自己这两天看到的些东西的总结

原创 2008年10月03日 04:50:00

  问题描述我就不说了,就说其实就是JAVA里面String.indexOf().

  第一种是关于KMP算法的,甘草上半年的时候让我去看的,好像现在想想也没有忘记

  其实啊,我觉得这个算法的主要思想很简单,也很好:对子字符串进行分析先,得到一个从子字符串生成的数组,作用呢?呵呵,我先卖个关子,看具体的字符串的时候就知道有什么用了。

  首先我来说说最简单的吧,比如hellhello,我要匹配的子字符串是hello.怎么匹配呢?

  h   e   l    l  h  e  l    l  o

  |     |    |    |   |

  h   e    l   l  o

 这里出现了不匹配,那我们就应该rollback对吧,那从哪里开始呢?从hellhello(第2位)开始?不是吧,这样的话,我们假设原 字符串是N,子串是M,算法复杂度就应该是O(M*N);但是明明不对啊,我们应该是从hellhello开始查啊,前面都不合适啊,明明都查过了啊。这样快多了嘛。。。。

   但是请考虑这样的情况:eeel------eel这样的情况,我们怎么在rollback以后重新开始新的查找呢?

   这个时候我们应该想起原来说的需要分析子串生成的那个数组了,也就是我需要去跳跃前面查找过的字符,但是到底跳跃多少呢?其实是由子串决定的,至于具体这个数组的生成规范呢,我就不说了,其实是留给自己的思考,让自己以后回来看的时候能够好好思考,而不是只看。

    顺便说下,KMP的算法复杂度是在O(N+M),即便是在最坏情况下

  

 

 

    第2种是我翻阅源代码的,JAVA,没技术含量多了。。。。

    for循环里找子串的第一个字符,找到以后再匹配剩下来的字段,不过原理和感情上都比较容易接受。但是感觉最坏情况下算法复杂度还是O(N*M),但是平均复杂度是一定优于第一直觉的。平均的情况我没有去算,因为平均的算起来真是麻烦。。哈哈,大家体谅啊。。。

 

 

   其实KMP算法的这样一种思想在算法中间还是很常见的,比如今天看到的一个问题的解答就是:给你一个dictionary(文件形式),给你一个单词,让你找出他们一系列的单词(形容词不会翻译,勉强理解意思吧),pots跟stop,tops是属于一个系列的(他们由完全一样的字母形成)。当单一的一个单词的时候,也许遍历是不错的选择,但是当面临一次性N多,或者说是网络情境下使用的时候,我们就会发现,效率在急剧下降。算法复杂度为O(N*M)(N为字典中总单词数,M为输入的单词数目);而资料给出的方案就是一次遍历dictionary,将所有的单词贴上一个标签。这个标签是将组成这个单词的字母按字典顺序排列起来,比如pots的标签是opst,同样stop的标签也是opst。全部打完标签以后,对标签排序,这样所有的组成字母相同的单词就排列在一起了。最后我们查找的时候就可以利用二分法查找了。 这样的算法复杂度呢不大会算了,哈哈,总时间是N+Nlog(N)+M*log2(N)。这样的时间随着M的增大,与每次都进行遍历的方法间的优势将越来越大。 

   这个时候我们将需要一个trade off。代价和收益问题。让我想起了最近总是想进百度的事情,所以总是在看百度以前的笔试题目,有一道题目是这样的:93=78+7+8;我们给98这样的数取名叫OOXX数,然后让你输入0-1000内一个数,编程判断这个数字是不是OOXX数。

   ^_^,我的第一想法是99乘法表。。怎么说呢,既然说清楚只在0-1000内,那我就应该利用这个限制条件,生成一个1000的数组,做一次遍历,从1开始,比如2=1+1;11=10+1;所有被得到的数字,直接用INDEX方法把他标记为1,不然就是0;然后你输入多少就可以用数组访问,直接知道咯。简单,问花费多少时间代价呢?2000(其中1000是用来初始化数组的)

  这样的做法的灵感来自于小时候乘法表总是背不出来,^_^,不要鄙视我哦~~~~。优点嘛,当你需要查询的数字很多的时候每个数字都只需要1就可以直接访问到,有没有点HASH的味道在里面呢?

    但是要是我只查一次呢,建这么大一个OOXX数字表是不是就太夸张了点,或者,当我需要1-1000000间的时候,是不是我也建这么大一张表,而其实我只要查询一次呢?

   感觉被耍了。。。再往小时候想想,这个时候怎么办?还能怎么办,老老实实算啊,但是怎么算啊?很显然是个特征数,那就吧特征写出来吧。。。我写写我看出来的特征吧,大家也可以写自己的特征:

                                                 一个OOXX数

                                                                            N=XYY+X+Y+Z=101X+11Y+2Z(如果他是一个3位数处理得到的话)

    有点意思了吧,为什么呢?11Y+2Z是不是有取值范围?多少?0-117,那就简单了,X=N/100,或者X=N/100-1,X=N/100-2,这样范围就减少多了,然后呢?2Z的取值范围是多少?0-18啊,那Y的取值呢?还是3种情况,Z是不是就呼之欲出了。

  好嘛,那我的这个算法的算法复杂度是多少呢?3^(lgN-1),根据输入数的位数决定,3位就是9次尝试,4位就是27次尝试。

   算法出来以后的第一感觉是,1000以内也没什么,但是随着数位的增加,我总觉得不是特别好,lgN是可以接受的,但是作为3的指数,就有些让人接受不了。那怎么办啊,^_^,不要着急,再想想办法呢。把式子改变下呢。

                                                                         N=XYY+X+Y+Z         -----》   N-XYZ=X+Y+Z;

   这意味着什么呢?我靠,那就是说N和XYZ的差值一定小于等于27呢?想想,对啊,而且,我们还可以把范围缩小,怎么缩小,想想看吧,X是不是一定小于等于N/100,对啊,那我们就可以把尝试的范围缩小到N-1到N-N/100-18,这几个数字之间了。

  现在的算法复杂度是多少呢?O(9*lgN)啊。

  这样的复杂度,对我而言,可以安心了。毕竟已经从一个指数型变成了底数型了。。。

  这就是我这两天看到的东西吧,还有些没有完全写出来,不过先就这样吧,回笼觉去了。。。哈哈

自己独立设计的字符串加密算法

自己独立设计的字符串加密算法 作者:成晓旭这是本人自行设计的第一个数据加密算法,当初是想设计成分组的对称加密算法,但后来工作一忙,就没有实现,就草草完成便开始应用起来了。但是目前的混淆度已经能够满足绝...
  • CXXSoft
  • CXXSoft
  • 2006年08月23日 18:12
  • 7316

[LeetCode-14] Longest Common Prefix(多个字符串公共字符子串查找)

【分析】找出输入的多个字符串的公有前序,简单的逻辑遍历查找就好。 算法流程: 1、判断输入的字符串数量,小于2时候做出相应返回。 2、获取最短字符串的长度。 3、设定标记 same_flag,控制跳出...
  • xy010902100449
  • xy010902100449
  • 2015年09月09日 16:37
  • 357

算法练习 - 字符串包含

这个题目不难,July和他伙伴们在《程序员编程艺术:面试和算法心得》中也分析的非常透彻,从最容易想但是效率最低的循环遍历,到逐渐优化先排序再轮询,再到更为优化的素数乘除法,直到最后的位操作。逐渐进阶,...
  • beggar200
  • beggar200
  • 2015年12月08日 11:24
  • 843

获取两个字符串所有公共的子串算法

应用场景: 获取两个字符串所有公共的子串。 思路: 1. 先获取两个子串的交集              2. 遍历交集子串,从最短子串到最长子串 public static List ...
  • chndata
  • chndata
  • 2015年07月01日 17:38
  • 1927

【字符串处理算法】字符串包含的算法设计及C代码实现

一、需求描述给定一个长字符串和一个短字符串,编写程序判断短字符串中的所有字符是否都在长字符串中。如果是,则长字符串包含短字符串;反之,不包含。为了尽量包含大多数情况,字符串中可以包含大小写英文字母、数...
  • zhouzxi
  • zhouzxi
  • 2016年02月17日 12:01
  • 1972

字符串中查找包含字串的次数的算法

·鄙人在深入学习String时遇到一个问题:如何查找一个字符串中包含某个子字符串的次数 我想到了一个新算法(可能不新了,已经被别人用过了也有可能),就是:把原字符串后面拼接一个非要查找的字串后用Str...
  • baidu2030
  • baidu2030
  • 2014年03月10日 10:57
  • 1094

无意在网上看到这篇《大牛讲解信号与系统以及数字信号处理》看的时候眼泪奔涌而出,现在我才知道大学读的专业的干吗的!

无意在网上看到这篇《大牛讲解信号与系统以及数字信号处理》看的时候眼泪奔涌而出,现在我才知道大学读的专业的干吗的! 第一课 什么是卷积 卷积有什么用 什么是傅利叶变换 什么是拉普拉斯变换 ...
  • hopedengxiwang
  • hopedengxiwang
  • 2013年10月12日 21:19
  • 1799

定义单链表存储结构,用头插法和尾插法建立单链表,并显示建立好以后的结果。

问题及代码: /* *Copyright(c) 2015,烟台大学计算机与控制工程学院 *All rights reserved. *文件名称:test.cpp *作 者:刘磊...
  • DDraven
  • DDraven
  • 2015年09月21日 17:08
  • 441

[算法]两种字符串匹配算法(索引法,KMP算法)对比,C语言实现

今天做了个一个简单的字符对比程序,功能是实现从A串删除包含B最多的字符的操作,比如A=“aaaaabbbbbbabababa” B=“aaccbaab”,应当删除“aab”的,不是aa,相信知道搜索引...
  • yctccg
  • yctccg
  • 2016年08月16日 10:38
  • 828

北京航空航天大学online judge:2014第一次练习*L题

 L题:回文数问题   题目描述 小小的大只没做中秋节热身赛,这两天看到那道回文数的题目颇为有趣。她决定进行修改。 输入格式: 题目有多组数据 每行两个数a,...
  • yujifan0326
  • yujifan0326
  • 2014年10月23日 15:55
  • 1410
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:字符串中的字串问题,两种算法了解。以及自己这两天看到的些东西的总结
举报原因:
原因补充:

(最多只允许输入30个字)