• 沒有找到結果。

temp叫 硎

在文檔中 数据结构基础 (頁 89-95)

(al初始化

temp叫 硎

( b ) s t r n c p y ( t e m p , s , i ) f t t f f Z f ,

temp

( c ) s t r c a t ( t e m p , tl l\ttjZ)G

teIn

(d) strcat(temp` s+土 ) 书 戈 彳∫歹L丿 斤

图 2,10字 符 中插 入举例

稆序 2.12把 一个字符 串插 入 另一个,通 常的 str⊥ng.h中 无此函数。冈为两个串都有可 能是空 串,程 序考虑 了这种情况 。注意 ,str土 ngs(s`匕 `0)与 strcat(t`s)功 能等价 。程序 2.12仅 是标准 串函数 的用法举例 ,读 者在实际 l∶作中不应该用这个函数 ,它 的时间需求和空

间需求都不 讲究 ,temp实 际不需耍 ,改 动稆序可 以去掉这个变 鞋。 □

§2.7.3 模 式 匹配

本小 i∷要讨论一个非常精妙的字符 串算法 。给定两个 串 pa匕、string,要 在 str土ng中 杏找模式 串 pat,最 简单的方法是调用 内部函数 strstr。 给定 以 卜语句 :

char pat[MAX_SIZE]` str土 ng[MAX~SIZE]` ★ t`

71

a u t o \0

72 第 2章 数组和结构

v o i d s t r i n g s ( c h a r * s , c h a r * t , i n t i )

I / . , . i n a a r t - n f r i n r t f i n f o a i n i r t - ^ . S i t i O n i * t

\ / * L I l S e I L b L L L t t g L L l t u v D L L L J T V D a L P v

c h a r s t r i n g I M A X S I Z E ] , * t e m p = s t r i n g ;

i f ( i < 0 & & i > s t r l e n ( s ) ) {

f n r ; n f f ( q i r T a r r n p n q i f . i o n i s o r t f o f h n r r n d q \ n r r ) :

! } / ! I I r U ! \ o u q u ! ! , u f V I l u I D u V U U u v ! u v v s r r s ' u \ r r I I

C X i t ( E X I T _ F A I L U R E ) ; i

)

i f ( ! s t r l e n ( s ) ) s t r c p y ( s , t ) ; e l s e i f ( s t r l e n ( t ) ) i

s t r n c p y ( t e m p , s , a ) ; s t r c a t ( t e m p , t ) ; s t r c a t ( t e m p , ( s + i ) ) ; s t r c p y ( s , t e m p ) ; Il

])

程序 2,12字 符 串插入 函数

卜面一段程序在 串 string中 杏找 串 pat:

土 £ (t=strstr(str主 ng` pat))

pr土 ntf("The凵 str土 ng凵 fr0m凵 strstr凵 ⊥ S:凵 %s\n"` t)`

e1臼 e

pr土 ntf("The凵 pattern凵 was凵 not凵 f° und凵 w土 th凵 Strstr\n")'

pat不 str土 ng屮 ,(t=strstr(str土 ng`pat))返 Fl空 。 如 pat|ll现 string

中,t指 向 str土ng中 的 pat,然 后打 印 t指 向子串的全部 内容。

尽管 strstr看 起来完全实现 了所需功能,我 们还是决定编写 臼己的模式匹配 函数 ,尝 试各种实现方法 。最简单的一种 ,是 顺序 比较模式 串的每个 字符和主 串的每个字符 ,直 到发 现匹配结束,或 扫描到主 串结束仍 未找到而结束。这种方法虽然简单 ,却 是效率最低 的方法 , 我们把这种方法放到 习题 中讨论 。令 pat的 长度 是 彳,str土 凹 的长度 是 昭,如 果 pat不 出 现在 st土ng中 ,这 种方法 的计算 时间足 O(″ ・彳)。这个结呆并不令人满意 ,以 下方法要好一 此

上述模式匹配 的策略足穷举搜索 ,在 此基础 上,如 果发现 str1en(pat)人 ]=主 串剩 卜的 串长就结束查找 ,可 以减少计算 时问。另外 ,如 呆 pat的 第一个字符和 st ont匹 配 ,马 上 拿 pat的 最后一个字符和 str土ng的 对应位置 比较 ,能 进一步捉高效率 。程序 2.13的 nf土nd 是这两种改进 的实现 。

2.3m血 d运 )假 pat="aab"、 str土 ng="ababbaabaa",图 2.11是 nf主 nd比

pat与 str土 ng的 1asts、 1astp分 str土 ng、 pat的 。 首 ,nf土 nd比

str土 ng[endmatch]不 冂 pat[1astp],如 j呆 ,nf土 nd移 土 、 j继 ,直

,如 start用 土 。 □

§2.7字 符串 73

i n t n f i n d ( c h a r * s t r i n g , c h a r * P a t )

| / - n = r n h r h e l _ a s t c h a r a c t e r o f p a t t e r n f i r s t , a n d t h e n m a t c h f r o m

\ / * I l l a e g J t L . l r E

t h e b e g i n n i n g . * / i n t L , j , s t a r t = O ;

i n t l a s t s = s t r l e n ( s t r i n g ) - 1 ; i n t l a s t p = s l r l e n ( P a t ) - 1 ; i n t e n d m a t c h = 1 a s t P ;

f o r ( i = O ; e n d m a t c h < = l a s t s ; e n d m a t c h + + , s t a r t + + ) { i f ( s t r i n g [ e n d m a t c h ] = = p a t I l a s t p ] )

f o r ( j = 0 , i = s L a r t ;

j < l a s t p & & s t r i n g ; i l = = P a t [ j J ; 1 + + , j + + )

t

i f ( j = = l a s t p ) r e t u r n s t a r t ; / * s u c c e s s f u f * /

])

r e t u r n - 1 ;

程序 2.13先 比较模 式 串末尾字符的模 式 匹配

町 彳歹分析 以 str⊥ng="aa.… a"、 pat="a.… ab"为 例,n£ 土nd的 计算时间是 o(昭 ),昭 是 str1ng的 长度,这 个复杂度足线性的,显 然远远优 J=顺i伶 找方法。虽然该方法足顺序杏找 方法的改进,它 的最并情形复杂度依然楚糟糕的 O(冫9御)。 □

我们 的理想是构造最优算法 ,使 时问复杂度达到 O(str1en(str主 ng)+str△ en(pat))。

这个复杂度之所 以最优 ,是 冈为模式Vε配算法在最 厍怙 形,必 须扫描主串!J模式 中的所有字 符至少一次。在扫描过稆 ,如 呆失配 ,我 们不想Fl头 再 么比较主 串中已比较过 的字符 ,而 是 希望利用模式 串的字符信息,以 及模式 申的失配位苴 ,确 定 卜一步应 比较 的主 串和模式串位 置 。这正是 Knuth'Morris'Pra仗 的模式V刂配算法思路 。这个算法 的计算 时间楚线性 的。以 下给 出一个例子 ,假 定

P='伢 抄 c伢 抄 c伢 c伢

令 S=sOs1… ・s解-1是 主 串,要 确定 P足 否在 sf开 始处匹配 。如呆 sj≠ 伢则接 卜来显然耍用

s丿 +1和 伢 比 较 。 同 理 ,若 sJ=伢 s`+1≠ b,则 卜 来 sj+1和 l伢 比 较 。 若 s阝 丿+1=劢

s`妮 ≠c,则 有 以 P清 形:

S P

?表 示我们不关心 S在 该位置的值 。第一个 ?表 示 s∴+2且 sj+2≠ c。这时,我 们知道,下 一次 应该用 P的 第一个字符直接与 s氵ψ 比较,而 不是 l-J sj+1比较,冈 为我们 己经知道,助+1与 P 的第工个字符 抄相等 ,所 以一定有 sf+1≠ 伢。继续比较 卜去,假 定 P的 前四个字符和 S匹 配,

74 第 2章 数组和结构

lastp (⑴ 模J1串

(⑶ 失 四d

start endmatch (θ失 配

lasts

b a b b

a|a|b

a

stort endmatch lasts

(g) Lζ酉J

2.11n丘 nd仿

但 卜一个字符失配 ,即 s`冫 ≠b,这 时的情形是:

仔细观察后 ,我 们发现接 卜来应该用 ss艹 与 P的 第工 个字符 乙相 比,好 像把棋式 串 P 向右滑动 ,使 它 的子 串对准 S的 一个子 串,然 后 让两 个相等 丫串后面 的第一 个字符相 比。通 过观察 ,我 们得 出结论 ,根 据模式 申中的字符信息 ,根 据模式 串失配主 串的字 符位置 ,可 以 确定接下来应该用模式 串的哪个 字符和主 串的当前 失配 宁符继续 比较 ,而 无需冂 去比较主

串的较前位置字符。为确定这个模式 串位置 ,需 要定 义以 卜失配函数 (failure hnction):

_ _

S Ρ

rb)失 配

(dl失 配

endmatch

(el失 配

§2.7字 符串

#def⊥ ne MAX pATTERN sIzE △ 00 土n△ match()氵

vo土 d fa± 1()`

土nt £ 1ure[MAX PATTERN SIZE]`

char string[MAX_pATTERN_sIZE]`

76

re△urn ((j==1enp) ? (i-1enp) : 这条语句检 查是否找到模式 串,如 呆未找到 ,那 么模式 串 卜标

§2.8参 考文献和选读材料

把以上分析综合起来,计 算失配函数和uu配 算法的总体时问足

77

O ( s t r l e n ( p a t ) * s t r l e n ( s t r i n g ) ) .

习 题

1,编 写函数,读 入一个字符 申,统 计字符串中不同字符的出现频率。挑选不 同的数据集测 试这个函数 。

2.编 strnde1,参

s乜 r土 ng和 start、 1ength。 str⊥ ng

册 刂|徐 start/1・ 女f)的 1ength个 ↑讠

:,鼓

丨丨l string。

3.编 strde1,参 string和

冫 符 character。 string屮

character,鼓 str⊥ nq。

4,编 t了 strp。 s△ ,参 str土 ng和 charac匕 er。

,即

str土 ng中

character的 。 如 character不 str土 ng中 ,返 -1。

应 调川 str土ng.hL⒈ JF向s匕rp。 函数,虽 然它 不楚 A∶NSI C的 标准 函数,可 楚仃些 C讠手丨l`^

库捉供这 个函数。

5.编 tJ函 数 strchr△ ,完 成 Ij上 题 strp○ △丬‖{1的 功 能 ,不 过返 「Π值 足指 向 string屮

character第

。 劫 l宋 character不 str土 ng屮 ,返 Fl NuLL。

6.修 改稆序 2.12,不 川临时变 鞋 temp。 分析新稆序时间复杂度并与原不V序 相 比。

7.证 明 n£土nd的 计算时间足 O(彳彳),″ 足主中 κ度,昭 足模式 串 K度 。川具体的主申、模 式 中加 以说 明。

8,计 算 卜列模式 申的失配函数 :

(a) rInrI砑

(b) 日乙伢抄日伢

(C) 伢 D日 伢乙砑砑抄

在文檔中 数据结构基础 (頁 89-95)

相關文件