以下是引用__c__在2011-1-10 23:39:44的发言:
2楼的方法好.按2楼的方法的一种实现
int
is_match (const char *s1, const char *s2)
{
signed int *pi;
/* count用来记录各个字符的个数,是s1中的字符则加1,s2中的字符则减1.
* 如果匹配成功,那么各个字符的数目应该是0。对于普通字符而言,只要
* 数组有128个元素就可以了,分配129个元素并把第129个元素count[128]
* 初始化为-1,这个元素起着哨兵的作用,在检查各个元素的数目是不是
* 为0的时候,可以少一个if条件语句,可以少量提高效率。 */
signed int count[129] = { [128]=-1 };
for ( ; ; )
{
/* */
++ count[ (int)(*s1) ];
-- count[ (int)(*s2) ];
++ s1, ++ s2; //如果有一个串是空串,这里始终会越过下标
/* 使用&位运算 是为了尽可能的避免 && || if ?: 等语句引起的分支
* 预测而降低效率 。
* (*s1!=0) & (*s2!=0) 为1(真)时,表示s1和s2都没有到达字符串尾部。
* (*s1==0) & (*s2==0) 为1(真)时, 表示s1和s2都刚好到达字符串尾部,
* 这种情况表示s1和s2的长度是一样长,则退出循环, 进入下一步检验。
* 如果上面2个if语句都不满足,则s1和s2的长度不一样,返回不匹配。 */
if ((*s1!=0) & (*s2!=0)) continue;
if ((*s1==0) & (*s2==0)) break;
return 0;
}
/* 如果count数组的某个元素不为0,则退出for循环。当然这绝不会是死循环。
* 不管s1和s2是不是能匹配,count[128]一定不为0(count[128]==-1)。
* 如果s1和s2能匹配, 那么 pi 一定是因为指向了count[128]而退出了循环。
* 也可以这样说,如果 pi没有因指向了count[128]而退出了循环, 则不匹配。
* 这样 count[128]这个元素起到了哨兵的作用,这样可以少一个if 语句。 */
for (pi = count; *++pi == 0; ) { }
/* 如果pi指向了 count[128](等价于pi-count==128)
* 那么返回匹配成功; 否则失败。 */
return ((unsigned int)(pi - count) == 128);
}
这段代码不能处理空字符串。
如果s1和s2有一个是"\0" 则会出错。
程序代码:
signed int count[129] = { [128]=-1 };
if ( !( *s1&&*s2 ) ) return !( *s1^*s2 ) ; /* 加这样一句 可以处理其中一个是空串的问题吗? 没有试过不知道,觉得好像可以 */
for ( ; ; )
[
本帖最后由 日的起烟烟 于 2011-1-17 19:34 编辑 ]