时间:2011-06-16 16:08:41

标签: c string

我试图在不使用内置函数的情况下编写自定义strcmp()函数。到目前为止,我的代码感觉有点复杂。基本上我希望字符的顺序是这样的:

  1. 特殊字符(按其出现的顺序)
  2. 数字
  3. 按字母顺序排列字母字符,但首先是大写字母,即“AaBbCcDd”
  4. 如果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. 我的代数运算方法是否适合于确定字母字符的字符顺序。
    3. 这些好方法吗?还有更好的吗?请记住,我正在最大限度地提高效率。

4 个答案:

答案 0 :(得分: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));
}

答案 1 :(得分:0)

我看到的明显问题是以下几行。

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

这不会按预期工作。如果它们相等,则不会返回零。如果string1string2相等,则*string1 == *string2为真,或等效于非零值,因此永远不会等于\0。这个条件应该是

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

不要以这种方式使用三元运算符,因为它们会导致代码的可读性降低。

答案 2 :(得分: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的下一个字符是否为空,在你检查时递增它。如果您运行到字符串的末尾,这会在嵌入快速退出时增加两个指针的效果。它应该非常紧密地装入组件。

这给你一个简化的场景,你只需要确定下一个角色与另一个角色的关系

答案 3 :(得分:0)

这是我的尝试。我实际上复制了strcmp()的正常函数,所以如果字符串不匹配,它将返回每个字符串的第一个元素之间的差异。例如,strcmp(“apple”,“zebra”)返回25,而strcmp(“zebra”,“apple”)返回-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]));
}