数据结构小结 (四) 串
2015-12-20 16:00
399 查看
第四章 串 及其一些算法
前言
其实字符串这里感觉就没有什么数据结构,应要说的话,KMP ,BF ,FF 这些其实是算法的范畴,但是国内的一些数据结构书非要把C 标准库的一些string 中的函数拿出来硬是凑出了数据结构串这章节的内容,也是够了。之前说过,这篇文档主要是小结一些东西,能应对学校考试,了解一些其他没有学过的数据结构, 能和面试对接这才是我们需要的。精研算法的童鞋请绕路。 遂决定这章以下面的路线杂谈 1.概念(考试用,选择填空题) 2.面试小技巧 3.KMP
概念
串
串是由零个或多个字符组成的有限序列。
长度
串中字符的数目n 称为串的长度。
空串
零个字符的串称为空串。
子串
串中任意个连续的字符组成的子序列称为该串的子串。
主串
包含子串的串相应地称之为主串。
相等
称两个串相等,当且仅当这两个串的值相等。
空格串
由一个或多个空格组成的串称之为字符串。
求子串的个数
n(n + 1)/2 + 1 n:串中字符的个数,再加上一个空串,空串是任何字符串的字串。
这个头文件中的函数基本用法需要知道,因为这是C语言的内容,所以此不再赘述。
面试小技巧
很多面试题都有实现一个strcmp,strcat,strcpy等等这些函数。其实,实现并不难,考察的是 编程习惯。 我这里使用glibc的源码来说明一些问题,以strcpy 为例。
char * strcpy(char * dest,const char *src){ char c ; char *s = (char *)src; const ptrdiff_t off = dest -s -1; do{ c = *s++ ; s[off] = c; }while(c != '\0); return dest; } libc_hidden_builtin_def (strcpy)
这就是strcpy 的源码,是不是很难看懂?没事有我在,可以给你解释清楚,包括后边我们发现就算是glibc 库也有一些不尽人意的地方。
想看懂这段代码,需要一些你曾经不知道的东西。 首先注意const 的使用,这很关键。我们防止不小心修改我们的源信息,还是使用const 比较好。
其次注意类型转换,然后注意这个类型,估计很多程序猿都不知道这个类型,普及下,这是两个指针相减的结果类型,主要是求出两个指针的相对偏移量,unisgned long int 类型,接着看着两条语句:
c = *S++; /* 首先将S 的值赋给 C*/ S[off] = c; /*然后将C 的值赋给S[off] 完成给dest头指针的赋值*/ /*注意每次循环以后S的值其实改变了,所以一直都在给dest赋值*/
这段代码还是很精致的,但是我为什么说还有缺陷呢?有点鸡蛋里挑骨头了,既然是让我们写,我们还必须考虑到判空的情况,所以增加两条判断是否有NULL 还是很出彩的。
例如:
if(!dest || !src){ return NULL; }
再看一个strcat
/* Append SRC on the end of DEST. */ char * strcat (dest, src) char *dest; const char *src; { char *s1 = dest; const char *s2 = src; char c; /* Find the end of the string. */ do c = *s1++; while (c != '\0'); /* Make S1 point before the next character, so we can increment it while memory is read (wins on pipelined cpus). */ /*这里检查了下一个字符是否可读,如果不可读直接就在这里发生错误终止程序, 防止即使写了入了字符串,后边却不可读出的情况*/ s1 -= 2; do { c = *s2++; *++s1 = c; } while (c != '\0'); return dest; }
下来说下KMP
KMP 暂时只说两种思路吧,一种是学校老师教偏经验的用法,另一种是更为通用的更一般的用法。 考试的形式主要以选择题,完成题为主。 KMP 相信大家上数据结构课的时候都学习过了,确实不容易理解,复杂的证明就不说了。 我们从几个方面来谈谈这个KMP。 以下所有都以父串:a c a b a a b a a b c a c a a b c
1 2 3 4 5 6 7 8
子串:a b a a b c a c
为例。
KMP 干了什么?
首先给你两个字符串,A 与 B ,需要你判断A 是不是 在B中,如果是返回A的位置,如果我们无脑的使用循环比较,复杂读为O(lenth(A)*lenth(B)) ,使用KMP是O(lenth(A) + lenth(B)) .确实减少了时间复杂度。 KMP 就干了一件这事。KMP 的两种用法
KMP 的两种用法就是根据我们使用计算next 的值的方法不同,使用next 的值的不同来区分的。首先说下求next的广泛使用方式
next 值就是为了减少重复比较的一种预处理方式。对于每一个字符元素求其之前包括自己在 内的前缀串与后缀串的最长的公有元素的长度。 由上边假设的题目条件: 字符 next值 next标号 a 0 1 ab 0 2 aba 1 3 abaa 1 4 abaab 2 5 abaabc 0 6 abaabca 1 7 abaabcac 1 8 这种算法使用公式: 移动位数 = 已匹配的字符数 - 对应的部分匹配值 所以这种算法出来的next 就是0011201 第一趟 a c a b a a b a a b c a c a a b c a b a a b c a c 偏移 = 1 - next[1] = 1 第二趟 a c a b a a b a a b c a c a a b c a b a a b c a c 没有匹配到,偏移= 1 第三趟 a c a b a a b a a b c a c a a b c a b a a b c a c 偏移 = 5 - next[5] = 3; 第四趟 a c a b a a b a a b c a c a a b c a b a a b c a c 完成匹配
求next值的代码:
void get_next(int *next,char *p){ int i ,n ,k; n = strlen(p) next[1] = next[0] = 0; k = 0; for(i = 2;i <= n;i++){ for(; k != 0 && p[k] != p[i-1];k = next[k]){ if(p[k] == p[i-1]) k++; } next[i] = k; } }
以上就是使用比较广泛的一种用法,下来说学校学的一种方法。
KMP 的快速使用方式
学校教授的方法一种可以快速求出next值的方法,当然需要它自己的比较方法。个人感觉这个方法有点“暴力”。
a b a a b c a c
0 1 1 2 2 3 1 2
next next值 元素 1 0 a 2 1 b 前边两个都是直接写 0 1 3 1 a 比较前一个字符与next[2] 不相等1 4 2 a 比较前一个字符与next[3] 相等+1 = 2 5 2 b 同上不等接着比较S[next[2]] 相等+1 = 2 6 3 c 同上比较相等 +1 = 3 7 1 a 同上比较 不相等为1 8 2 c 同上比较 相等+1 = 2
得出next 值后进行匹配
第一趟
a c a b a a b a a b c a c a a b c a b a a b c a c 偏移: c != b next[2] = 1;
第二趟
a c a b a a b a a b c a c a a b c a b a a b c a c 偏移: a != c next[1] = 0;偏移为0 向后偏移1
第三趟
a c a b a a b a a b c a c a a b c a b a a b c a c 偏移: a != c next[6] = 3 ;
第四趟
a c a b a a b a a b c a c a a b c a b a a b c a c 匹配完成。!!!
总的来说想要精研算法的还是去看算法导论吧。
查看原文:http://zmrlinux.com/2015/12/20/%e6%95%b0%e6%8d%ae%e7%bb%93%e6%9e%84%e5%b0%8f%e7%bb%93-%ef%bc%88%e5%9b%9b%ef%bc%89-%e4%b8%b2/
相关文章推荐
- 数据结构小结 (三)栈与队列
- 数据结构小结 (二)链表
- 数据结构小结 (一)总论
- <LeetCode OJ> 66. Plus One
- 最全顺序表函数(打印,初始化,后插,后删,前插,前删……)
- 数据结构期末总结
- 数据结构 — 堆排序
- 《挑战程序设计竞赛》2.4 数据结构-并查集 POJ1182 2236 1703 AOJ2170
- C++ 数据结构 *** 广义表的部分实现
- 数据结构面试题(1)--用两个队列实现一栈和用两个栈实现一个队列
- 二分法解决最大值最小化问题
- 数据结构之计算器的实现(JAVA)(四)
- 数据结构学期期末总结
- 数据结构与算法 LeetCode编程练习--Search in Rotated array
- 【《数据结构》2015-2016学年上学期总结】
- 学习数据结构半年来的总结
- 【数据结构】快速排序
- 数据结构与算法 LeetCode编程练习--Search and Inserted in sorted array
- MYSQL 设计数据结构需注意问题
- 数据结构-图