赞
踩
串是字符串的简称,串是由零个或多个字符组成的有限序列。
串是一种特殊的线性表,其特殊性体现在ElemType
固定为字符类型。
“ a 1 a 2 a 3 . . . a n ” ( n ≥ 0 ) “a_1a_2a_3...a_n”( n \ge 0 ) “a1a2a3...an”(n≥0)
注意双引号不是串的内容
串中所含字符的个数
含零个字符的串,串长为0,空串可以用希腊字母Φ表示
只包含空格(对应ASCII码为32)的串,空格串有内容有长度
注意空格串和空串的区别
当且仅当两个串的长度相等并且对应位置上的字符都相同时,这两个串才是相等的。
所有的空串都是相等的
一个串中任意个连续字符组成的子序列(含空串)称为该串的子串,例如"abcd"
的子串有
"a"
,"b"
,"c"
,"d"
"ab"
,"bc"
,"cd"
"abc"
,"bcd"
"abcd"
是指不包含自身的所有子串
C语言用\0
字符标记串的结束,在求串长时需要从头开始遍历,时间复杂度为O(n);若单独存储串的长度即可省去遍历操作,时间复杂度为O(1)
给定两个串
s
=
"
a
1
a
2
.
.
.
a
n
"
t
=
"
b
1
b
2
.
.
.
b
m
"
s= "a_1a_2...a_n"\\ t="b_1b_2...b_m"
s="a1a2...an"t="b1b2...bm"
当满足下列条件之一,有s<t
1.
n
<
m
,
且
a
i
=
b
i
(
i
=
1
,
2
,
.
.
.
,
n
)
1.n<m,且a_i = b_i(i = 1,2,...,n)
1.n<m,且ai=bi(i=1,2,...,n)
2.
存
在
某
个
k
≤
min
(
m
,
n
)
,
使
得
a
i
=
b
i
(
i
=
1
,
2
,
.
.
.
,
k
−
1
)
,
a
k
<
b
k
2.存在某个k\le \min(m,n),使得a_i=b_i(i=1,2,...,k-1),a_k<b_k
2.存在某个k≤min(m,n),使得ai=bi(i=1,2,...,k−1),ak<bk
上面这些基本操作,一般的高级语言会提供现成的库函数,不需要程序员自己造轮子。具体内容请查阅标准参考手册。
用一组地址连续的存储单元来存储串中的字符序列。采用定长数组来定义。
#define MAXLEN 100
typedef struct _string{
char ch[MAXLEN];
int len;
}string;
给string
类型的顺序串编写一个比较函数Strcmp
,能够比较两个顺序串大小并返回一个整型值,Strcmp
的行为应与<string.h>
定义的strcmp
函数一致
基本思路:
min_len
,比较两个串在min_len
长度范围内的字符1
-1
min_len
范围内的字符均相同,比较长度0
1
-1
int Strcmp( string *s1, string *s2 ) { int i; int min_len; min_len = s1->len > s2->len ? s2->len : s1->len; for( i = 0; i < min_len; i++ ){ if( s1->ch[i] < s2->ch[i] ){ return 1; }else if( s1->ch[i] > s2->ch[i] ){ return -1; } } if( s1->len == s2->len ){ return 0; }else if( s1->len > s2->len ){ return 1; }else{ return -1; } }
操作顺序串时需警惕数组越界的问题,尤其在对两串进行复制,连接,子串插入,子串替换这几个操作时更要小心。一般的操作步骤是先检查长度,截断多余的部分以保证程序正常运行,显然在截断的过程中造成了数据丢失。对于这种不能事先确定串长的变化范围的问题,一般会使用动态的链式存储结构来存储串。
串的链式存储结构也被称为链串,组织形式和链表相似。
typedef struct _strnode{
char ch;
struct _lstring *next;
}strnode;
如果在一个节点只存储一个字符,会浪费结点3个字节的空间,存储密度为12.5%
为了提高存储密度,我们可以将灰色部分的空间利用起来
typedef struct _strnode{
char ch[4];
struct _lstring *next;
}strnode;
此时存储密度提高到了50%。
在链串1中,串结束的标志是链表尾的NULL
指针。但在链串2中,需要单独设置一个结束标志字符,如#
或\0
链串2的存储密度提高了4倍,付出的代价就是操作变得更复杂了:结点和结点之间是链式结构的操作,结点内部的字符又是顺序结构的操作。所以我们要根据串的某个操作的频度灵活选择合适的数据域大小。
如果串频繁的执行子串插入替换等操作,应该设置单个char以简化操作
如果串频繁执行连接操作,使用第二种结构会更节约空间。
给定一个含子串ab
的串,请将第一个出现的ab
替换为xyz
给出的条件是2换3,如果使用顺序串,要花时间把a后面的字符往后移一位,时间复杂度为O(n)
如果使用链串,只需要将新结点插入到ab中间即可。同时为了简化操作应使用链串1的结构
void replace( strnode *s ) { int exit = FALSE; strnode *p; for( s = s->next; s->next != NULL; s = s->next ){ if( s->ch == 'a' && s->next->ch == 'b' ){ exit = TRUE; break; } } if( exit ){ s->ch = 'x'; s->next->ch = 'z'; p = ( strnode* )malloc( sizeof( strnode ) ); p->ch = 'y'; p->next = s->next; s->next = p; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。