C中的字符串是一个以'\0'结尾的字符数组
python中的字符串对象有内部的PyStringObject表示。
结构:
typedef struct
{
PyObject_VAR_HEAD;
long ob_shash;
int ob_sstate;
char ob_sval[1];
}PyStringObject;
其中ob_shash是字符串的哈希,ob_sval包含大小为ob_size的字符串,以'\0'终止,ob_sval初始大小为1字节
ob_sval[0] = 0。ob_size位于PyObject_VAR_HEAD中,这位于object.h,ob_sstate表示字符串对象是否在待查字典中
s1 = 'abc'会发生什么?
调用内部C函数PyString_FromString,以下是伪代码
argument:stirng object :'abc'
returns :Python string object with ob_sval = 'abc'
PyString_FromString(string):
size = length of string
allocate string object + size for 'abc'.ob_sval will be of size:size+1
copy string to ob_sval
return object
可以看出每次使用新字符串时,都会分配一个新的字符串对象
在变量之间共享小字符串,减少了使用的内存量
小字符串就是大小为0-一个字节能够容纳的字符串,其实也就是字母了
静态全局变量interned是引用这些小字符串的字典,字符数组还引用长度为1字节的字符串,也就是字母
一些常量都在相应的头文件里面,这是用C实现的python
static PyStringObject * characters[UCHAR_MAX+1];
static PyObject *interned;
s2 = 'a'会发生什么?
包含“a”的字符串对象将添加到字典interned中,key是指向字符串对象的指针,值是相同的指针,新的字符串对象在字符数组中偏移量97的地方引用。所以说s3指向key为指向’a'的指针,value也为指向‘a'的指针的字符串对象
s3 = ’a'怎么办呢:
s4 = ‘c'怎么办呢:
字符串搜索
一般我们用find方法,这个方法内部是用Boyer-Moore和Horspool算法的结合版本
我们将搜索字符串称为“ s”,将搜索字符串称为“ p”。s ='adcabcdbdabcabd'和p ='abcab'。“ n”是“ s”的长度,“ m”是“ p”的长度。n = 18且m = 5。
代码中的第一个检查是显而易见的,如果m> n,那么我们知道我们将无法找到索引,因此该函数立即返回-1,如下面的代码所示:
w = n -m;
if (w<0)
return -1;
当m = 1时,代码每次一次通过“ s”一个字符,并在匹配时返回索引。在我们的示例中,mode = FAST_SEARCH,因为我们要查找的是索引中首先找到该字符串的索引,而不是找到该字符串的次数。
if (m <= 1)
{
...
if (mode == FAST_COUNT) {
...
}
else
{
for (i = 0; i < n; i++)
if (s[i] == p[0])
return i;
}
return -1;
}
而对于其他情况,m>1;第一步是创建一个压缩的Boyer-Moore delta 1表,在该步骤中将分配两个变量:“掩码”和“跳过”。
掩码”是一个32位的位掩码,使用字符的5个最低有效位作为关键字。它是使用字符串搜索“ p”生成的。这是一个Bloom筛选器,用于测试此字符串中是否存在字符。这确实非常快
位掩码的生成方式:
mlast = m-1;
for (mask = i = 0;i<mlast;i++)
{
mask |= (1<<(p[i]&0x1f));
}
mask |= (1<<(p[mlast] & 0x1f));
Boyer-Moore算法:链接