2011-06-16 36 views
2

我正在嘗試在不使用內置函數的情況下編寫自定義strcmp()函數。到目前爲止,我的代碼感覺有些複雜。基本上我想字符的順序是這樣的:沒有strcmp()的字母比較?

  1. 特殊字符(他們的順序出現)
  2. 字母字符,在順序,但首都首,即「AABBCCDD」

如果string1出現在string2之前,則返回1;如果string2出現在string1之前,則返回-1;如果相等,則返回0。

這裏是我的代碼:

int strcmp(char * string1, char * string2) 
{ 
    while((*string1 != '\0') && (*string2 != '\0') && (*string1 == *string2)) 
    { 
     ++string1; 
     ++string2; 
    } 

    //If both are now zero, they are equal 
    if (*string1 == *string2 == '\0') { return 0; } 

    //If string1 is comes before, return 1 
    //If string2 is comes before, return -1 
    int type1 = (isalpha(string1) ? 2 : (isnum(string1) ? 1 : 0)) 
    int type2 = (isalpha(string2) ? 2 : (isnum(string2) ? 1 : 0)) 
    return ((type1 < type2) 1 : ((type2 < type1) -1 : 
     (((*string1 >= 'a') ? (*string1 - 'a')*2+1 : (*string1 - 'a')*2) < 
     ((*string2 >= 'a') ? (*string2 - 'a')*2+1 : (*string2 - 'a')*2) ? 1 : -1))); 
} 

有兩件事情我不知道:

  1. 無論分配「類別」是正確的做法。現在我將類型0分配給特殊字符,將數字鍵入1並將字母鍵入類型2。這樣我可以快速比較類型。
  2. 我的使用代數運算的方法是否適合建立字母順序的字符。

這些好方法嗎?有更好的嗎?請記住我正在爲效率最大化。

+0

爲什麼不是你的因素比較標準了,只是做一個函數'compare_chars( char a,char b)',然後就返回那個?另外不要忘記測試一個字符串比另一個字符串短的情況。 – 2011-06-16 16:14:28

+0

比較(* string1 == * string2 =='\ 0')不正確 - * string1 == * string2的結果將爲0或1,然後將其與零字節進行比較,在所有你想要的。你實際上需要做(* string1 == * string2 && * string1 =='\ 0')。 – chrisdowney 2011-06-16 16:21:32

+0

你應該看看strcmp的一些現有實現。例如glibc或PJ Plauger(前兩個想到的)。還要學習如何實現isalpha()和其他宏。 – 2011-06-16 16:28:03

回答

0

嘗試

int strcmp(const char * string1, const char * string2) 
{ 

while (*string1 == *string2++) 
    if (*string1++ == 0) 
     return (0); 
    // then check for the ordering according to taste 

} 

雖然字符是一樣的,你會增加S2,然後檢查是否S1的下一個字符爲空,增加它作爲你檢查。如果您運行到字符串的末尾,則嵌入快速退出時會產生增加兩個指針的效果。它應該相當緊密地裝入組件。

這給你留下一個簡化的場景,在這裏你只需要確定下一個字符是什麼相對於其他

2

假設8位字符,您可以填充查找表。使用現有的比較代碼對所有可能的char值進行排序,然後爲每個字符創建一個索引編號表。

然後你的內循環只需要查找字符串中每個字符的1個索引號,然後比較整數。

#include <stdio.h> 

static int my_strcmp_order[256]; // you fill this in 

int my_strcmp(const char *s1, const char *s2) 
{ 
     while (*s1 == *s2++) { 
       if (*s1++ == '\0') return 0; 
     } 
     return my_strcmp_order[*(const unsigned char*)s1] 
       - my_strcmp_order[*(const unsigned char*)(s2-1)]; 
} 

int main() 
{ 
     for (int i=0; i<256; i++) { 
       my_strcmp_order[i] = i; // native sort order - you fill it your way 
     } 

     const char *s1 = "Abc"; 
     const char *s2 = "Abcd"; 
     const char *s3 = ""; 
     printf("s1 <=> s2 = %d\n", my_strcmp(s1, s2)); 
     printf("s1 <=> s3 = %d\n", my_strcmp(s1, s3)); 
     printf("s3 <=> s2 = %d\n", my_strcmp(s3, s2)); 
} 
+0

+1 - 但請注意:只有當您的查找表爲每個'char'使用不同的代碼時(否則您可能會停止比較早期的字符轉換爲等效),這將起作用。如果你想要不同的字符進行比較等效(例如執行不區分大小寫比較或者將所有標點符號等同對待),那麼通過轉換表的間接需要在'while'循環比較中發生(簡單修改)。 – 2011-06-16 17:55:51

+0

是的,這對stricmp或爲stricmp準備的查找表是正確的。但是OP想要更多的字典排序。 (MyCo 2011-06-16 18:58:09

+0

我只是希望OP瞭解到複雜性有點複雜,這取決於他可能希望如何分類「MyCo」和「Myca」。 – 2011-06-16 19:11:28

0

我看到的顯而易見的問題是以下行。

if (*string1 == *string2 == '\0') { return 0; } 

這不會按預期工作。如果它們相等,這將不會返回零。如果string1string2相等,則*string1 == *string2爲真,或者等於非零值,因此永遠不會等於\0。這種情況應該是

if ((*string1 == '\0') && (*string2 == '\0')) {} 

而且不要使用三元運算符這種方式,因爲它們導致可讀代碼少。

0

這是我在它的嘗試。我實際上覆制了strcmp()的正常函數,因此如果字符串不匹配,它會返回每個字符串的第一個元素之間的差異。例如,STRCMP(「蘋果」,「斑馬線」)返回25,而STRCMP(「斑馬線」,「蘋果」)返回-25

#include <stdio.h> 
#include <string.h> 

int my_strcmp(char* arg1, char* arg2) { 
    while(arg1++ == arg2++); 
    return (--arg1==--arg2&&strlen(arg1)==strlen(arg2))?0:arg2[0]-arg1[0]; 
} 

int main(int argc, char* argv[]) { 
    printf("%d\n",my_strcmp(argv[1],argv[2])); 
}