在C中优化此Remove()方法

时间:2013-12-31 05:57:41

标签: c arrays string

这是一种用于从char数组中删除'key'的方法。

版本1:

/* remove character key by two loop */
char *Remove(char *str, const char key)
{
    int len = strlen(str);
    for (int i = 0; i < len; i++)
        if (str[i] == key)
        {
            for (int j = i--; j <= len; j++)
                str[j] = str[j + 1];
        }
    return str;
}

第2版:

/* remove character key by one loop */
char *Remove(char *str, const char key)
{
    char *p1, *p2;

    p1 = p2 = str;
    while (*p2)
    {
        if (*p1 == *p2 && *p1 != key)
                p1++;
        else if (*p2 != key)
            *p1++ = *p2;
        p2++;
    }
    *p1 = *p2;  // assign '\0' to *p1
    return str;
}

我想优化版本2,任何机构都有任何想法吗?

2 个答案:

答案 0 :(得分:3)

为什么不使用,

p1 = p2 = s;
do
  {
    while (*p2 == key) p2++;
    *p1++ = *p2++;
  }
while (p2[-1]);

我知道有很多大写错误;我目前受黑莓自动纠正的支配。

答案 1 :(得分:3)

我恭敬地建议这个循环更简单。与问题中的函数相比,它是O(N)时间,而如果出现key字符,则问题中第一个函数的代码是O(N * N)。第二个是O(N),但是循环体非常复杂。

char *Remove(char *str, char key)
{
    char *dst = str;
    for (char *src = str; *src != '\0'; src++)
    {
        if (*src != key)
            *dst++ = *src;
    }
    *dst = '\0';
    return dst;  // Or src, but knowing the end is more useful!
}

显然,如果您没有C99编译器,可以将src的声明置于循环之外。


我使用以下代码来确保randomusernameanswer中的代码现在正确(并生成与我的代码相同的答案):

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

static char *Remove2(char *s, char key)
{
    char *p1, *p2;
    p1 = p2 = s;
    do
    {
        while (*p2 == key)
            p2++;
        *p1++ = *p2++;
    }
    while (p2[-1]);
    return p2 - 1;
}

static char *Remove1(char *str, char key)
{
    char *dst = str;
    for (char *src = str; *src != '\0'; src++)
    {
        if (*src != key)
            *dst++ = *src;
    }
    *dst = '\0';
    return dst;  // Or src, but knowing the end is more useful!
}

int main(void)
{
    char data1[32] = "AB=CD==EF===GHI\0AAAAA";
    char data2[32] = "AB=CD==EF===GHI===\0AAAAA";
    char data[32];
    char *end;

    memmove(data, data1, sizeof(data));
    end = Remove1(data, '=');
    printf("[%s] => [%s] (%d)\n", data1, data, (int)(end - data));

    memmove(data, data1, sizeof(data));
    Remove2(data, '=');
    printf("[%s] => [%s] (%d)\n", data1, data, (int)(end - data));

    memmove(data, data2, sizeof(data));
    Remove1(data, '=');
    printf("[%s] => [%s] (%d)\n", data2, data, (int)(end - data));

    memmove(data, data2, sizeof(data));
    Remove2(data, '=');
    printf("[%s] => [%s] (%d)\n", data2, data, (int)(end - data));

    return 0;
}

输出:

[AB=CD==EF===GHI] => [ABCDEFGHI] (9)
[AB=CD==EF===GHI] => [ABCDEFGHI] (9)
[AB=CD==EF===GHI===] => [ABCDEFGHI] (9)
[AB=CD==EF===GHI===] => [ABCDEFGHI] (9)