php natsort內(nèi)核函數(shù)淺析
/* {{{ compare_right
*/
static int
compare_right(char const **a, char const *aend, char const **b, char const *bend)
{
int bias = 0;
/* The longest run of digits wins. That aside, the greatest
value wins, but we can't know that it will until we've scanned
both numbers to know that they have the same magnitude, so we
remember it in BIAS. */
for(;; (*a)++, (*b)++) {
if ((*a == aend || !isdigit((int)(unsigned char)**a)) &&
(*b == bend || !isdigit((int)(unsigned char)**b)))
return bias;
else if (*a == aend || !isdigit((int)(unsigned char)**a))
return -1;
else if (*b == bend || !isdigit((int)(unsigned char)**b))
return +1;
else if (**a < **b) {
if (!bias)
bias = -1;
} else if (**a > **b) {
if (!bias)
bias = +1;
}
}
return 0;
}
/* }}} */
/* {{{ compare_left
*/
static int
compare_left(char const **a, char const *aend, char const **b, char const *bend)
{
/* Compare two left-aligned numbers: the first to have a
different value wins. */
for(;; (*a)++, (*b)++) {
if ((*a == aend || !isdigit((int)(unsigned char)**a)) &&
(*b == bend || !isdigit((int)(unsigned char)**b)))
return 0;
else if (*a == aend || !isdigit((int)(unsigned char)**a))
return -1;
else if (*b == bend || !isdigit((int)(unsigned char)**b))
return +1;
else if (**a < **b)
return -1;
else if (**a > **b)
return +1;
}
return 0;
}
/* }}} */
/* {{{ strnatcmp_ex
* call in array.c: strnatcmp_ex(Z_STRVAL(first), Z_STRLEN(first), Z_STRVAL(second), Z_STRLEN(second), fold_case);
*/
PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case)
{
char ca, cb;
char const *ap, *bp;
char const *aend = a + a_len,
*bend = b + b_len;
int fractional, result;
if (a_len == 0 || b_len == 0)
return a_len - b_len;
ap = a;
bp = b;
while (1) {
ca = *ap; cb = *bp;
/* skip over leading spaces or zeros */
while (isspace((int)(unsigned char)ca) || (ca == '0' && (ap+1 < aend) && (*(ap+1)!='.')))
ca = *++ap;
while (isspace((int)(unsigned char)cb) || (cb == '0' && (bp+1 < bend) && (*(bp+1)!='.')))
cb = *++bp;
/* process run of digits */
if (isdigit((int)(unsigned char)ca) && isdigit((int)(unsigned char)cb)) {
fractional = (ca == '0' || cb == '0');
if (fractional)
result = compare_left(&ap, aend, &bp, bend);
else
result = compare_right(&ap, aend, &bp, bend);
if (result != 0)
return result;
else if (ap == aend && bp == bend)
/* End of the strings. Let caller sort them out. */
return 0;
else {
/* Keep on comparing from the current point. */
ca = *ap; cb = *bp;
}
}
if (fold_case) {
ca = toupper((int)(unsigned char)ca);
cb = toupper((int)(unsigned char)cb);
}
if (ca < cb)
return -1;
else if (ca > cb)
return +1;
++ap; ++bp;
if (ap >= aend && bp >= bend)
/* The strings compare the same. Perhaps the caller
will want to call strcmp to break the tie. */
return 0;
else if (ap >= aend)
return -1;
else if (bp >= bend)
return 1;
}
}
/* }}} */
從strnatcmp_ex函數(shù)中的:
while (isspace((int)(unsigned char)ca) || (ca == '0' && (ap+1 < aend) && (*(ap+1)!='.')))
ca = *++ap;
while (isspace((int)(unsigned char)cb) || (cb == '0' && (bp+1 < bend) && (*(bp+1)!='.')))
cb = *++bp;
所以,我覺得應(yīng)該字符串(當(dāng)前位置開始)中前面的空字符和數(shù)字前面的‘0'不會(huì)參與比較,比較的結(jié)果應(yīng)該和
http://us.php.net/manual/en/function.natsort.php
http://sourcefrog.net/projects/natsort/example-out.txt
所說的一樣,但是在我的php5.2.9中對(duì)于“0”的處理結(jié)果卻不一樣(例如“img002.png”與“img1.png”,我的理解應(yīng)該是前者大于后者,不過在我的5.2.9中卻是前者小于后者),原因還沒想清楚,可能是5.2.9的一個(gè)bug,也可能是自己還沒有理解清楚源碼的意思。下次配置好環(huán)境再好好測(cè)試,好好消化~~
在array.c中有兩個(gè)重要的數(shù)據(jù)結(jié)構(gòu)很值得我們關(guān)注
- php in_array 函數(shù)使用說明與in_array需要注意的地方說明
- PHP數(shù)組的交集array_intersect(),array_intersect_assoc(),array_inter_key()函數(shù)的小問題
- php array_intersect比array_diff快(附詳細(xì)的使用說明)
- PHP內(nèi)核介紹及擴(kuò)展開發(fā)指南—基礎(chǔ)知識(shí)
- php數(shù)組函數(shù)序列之in_array() 查找數(shù)組值是否存在
- php數(shù)組函數(shù)序列之a(chǎn)rray_combine() - 數(shù)組合并函數(shù)使用說明
- php數(shù)組函數(shù)序列之in_array() - 查找數(shù)組中是否存在指定值
- php數(shù)組函數(shù)序列之a(chǎn)rray_intersect() 返回兩個(gè)或多個(gè)數(shù)組的交集數(shù)組
- 使用js判斷數(shù)組中是否包含某一元素(類似于php中的in_array())
- PHP內(nèi)核探索:變量存儲(chǔ)與類型使用說明
- PHP內(nèi)核探索:變量概述
- php內(nèi)核解析:PHP中的哈希表
- 2個(gè)自定義的PHP in_array 函數(shù),解決大量數(shù)據(jù)判斷in_array的效率問題
- php數(shù)組查找函數(shù)in_array()、array_search()、array_key_exists()使用實(shí)例
- PHP函數(shù)in_array()使用詳解
- php提示W(wǎng)arning:mysql_fetch_array() expects的解決方法
- PHP內(nèi)核探索:哈希表碰撞攻擊原理
- 深入理解PHP內(nèi)核(一)
- 深入理解PHP內(nèi)核(二)之SAPI探究
- 深入php內(nèi)核之php in array
相關(guān)文章
PHP超級(jí)全局變量【$GLOBALS,$_SERVER,$_REQUEST等】用法實(shí)例分析
這篇文章主要介紹了PHP超級(jí)全局變量用法,結(jié)合實(shí)例形式分析了PHP中$GLOBALS,$_SERVER,$_REQUEST等超級(jí)全局變量相關(guān)概念、功能、使用方法及操作注意事項(xiàng),需要的朋友可以參考下2019-12-12PHP動(dòng)態(tài)創(chuàng)建Web站點(diǎn)的方法
在這一篇中我寫了一些動(dòng)態(tài)創(chuàng)建Web站點(diǎn)的一些內(nèi)容,例如黏性表單、發(fā)送電子郵件、日期函數(shù)等。希望能對(duì)大家有所幫助,別忘了好評(píng)哦。2011-08-08PHP實(shí)現(xiàn)的下載遠(yuǎn)程文件類定義與用法示例
這篇文章主要介紹了PHP實(shí)現(xiàn)的下載遠(yuǎn)程文件類定義與用法,結(jié)合具體實(shí)例形式分析了php封裝的下載遠(yuǎn)程文件操作類定義及使用方法,需要的朋友可以參考下2017-07-07php獲取網(wǎng)頁標(biāo)題和內(nèi)容函數(shù)(不包含html標(biāo)簽)
有時(shí)候我們需要獲取網(wǎng)頁的標(biāo)題與內(nèi)容,就是個(gè)采集函數(shù),這里簡(jiǎn)單分享下,方便需要的朋友2014-02-02PHP+MySQL統(tǒng)計(jì)該庫中每個(gè)表的記錄數(shù)并按遞減順序排列的方法
這篇文章主要介紹了PHP+MySQL統(tǒng)計(jì)該庫中每個(gè)表的記錄數(shù)并按遞減順序排列的方法,涉及PHP基于PDO操作MySQL數(shù)據(jù)庫的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2016-02-02PHP類的靜態(tài)(static)方法和靜態(tài)(static)變量使用介紹
PHP類的靜態(tài)(static)方法和靜態(tài)(static)變量使用介紹,學(xué)習(xí)php的朋友可以看下2012-02-02