新手,自觉的写了一个快速搜索字串的代码,大家给评一下

22 views
Skip to first unread message

Moore

unread,
Nov 18, 2011, 7:34:05 AM11/18/11
to TopLanguage
实际需求例: http get 头里面,有几个串要搜,从一段内存中搜某几个串。

例如搜 GET Referer Host Accept Cookie User-Agent

代码如下:
定义一个结构;
typedef struct HTTPOPT {
char *optname;
int optLeng;
int (*func)(char *,int,DesirInfo *);

} HttpOpt;

申请空间 PRNCHAR 指所有可印的ASCII值
httpOptPtr = (HttpOpt *) calloc(PRNCHAR,sizeof(HttpOpt));
预置没有匹配要求的指向函数空,
for( i = 0; i< PRNCHAR ; i++) {
httpOptPtr[i].func = &doNothing;
httpOptPtr[i].optLeng = 0;
}
将有匹配需求的指向具体函数入口
httpOptPtr['G'].func = &getMatch;
httpOptPtr['G'].optLeng = strlen(GETSTR);

httpOptPtr['H'].func = &hostMatch;
httpOptPtr['H'].optLeng = strlen(HOSTSTR);

httpOptPtr['R'].func = &refererMatch;
httpOptPtr['R'].optLeng = strlen(REFERSTR);

httpOptPtr['C'].func = &cookieMatch;
httpOptPtr['C'].optLeng = strlen(COOKIESTR);

来一个串进行匹配操作的 char *ptr; 串长度外面置好了 resvLen

fbuff = (char *)ptr;
while( i < resvLen) {
ch = (char) fbuff[i] &0x7f;

if( httpOpt[(int)ch].optLeng != 0) {

mReturn = (*httpOpt[(int)ch].func)(fbuff
+i,resvLen,desirInfo);
i += mReturn;

}

i++;

}

匹配串的一个函数:

int hostMatch(char *str,int resvLen,DesirInfo *ds) {

int i = 0;

if(strncmp(str,HOSTSTR,HOSTLEN)==0) {
ds->host = (char *)calloc(resvLen-HOST_DESP,sizeof(char));
while(((char)str[i+HOSTLEN])&&!isspace((char)str[i+HOSTLEN]))
i
++;
i = (i>resvLen)?resvLen:i;
。。。。。。
}

return(i+HOSTLEN);

Milo Yip

unread,
Nov 18, 2011, 9:25:12 AM11/18/11
to pon...@googlegroups.com
通常 compiler 會把 switch-case 變為類似的方式,但使用indirect jmp而不是pointer to
function,該技術稱為jump table。所以這麼做或以足夠:

switch (ch) {
case 'G': GetMatch(); ...
case 'H': hostMatch(); ...
}

另外,literal string的長度,以我記得通常compiler不會把strlen("apple")在compile-time轉換成5。可改用sizeof("apple")
- 1。

以上所說可能有compiler差異,請參考編譯後的assembly code,以及進行實際的性能比較。

--
Milo Yip

http://www.cnblogs.com/miloyip/
http://weibo.com/miloyip/
http://twitter.com/miloyip/

Moore

unread,
Nov 19, 2011, 1:02:48 AM11/19/11
to TopLanguage
不错,好答案。

去看一下assemble.

Reply all
Reply to author
Forward
0 new messages