从字符串就地删除空格?

时间:2011-10-15 01:18:59

标签: c

我在“面试问题列表”中看到了这一点。让我想知道。

当然,不限于空白,很容易推广为“从字符串中删除某些特定字符,就地”。

我的解决方案是:

void stripChar(char *str, char c = ' ') {
  int x = 0;
  for (int i=0;i<strlen(str);i++) {
    str[i-x]=str[i];
    if (str[i]==c) x++;
  }
  str[strlen(str)-x] = '\0';
}

我怀疑还有一个更高效,但有更优雅的解决方案吗?

修改:完全忘了我离开了strlen,这绝对没有效率

3 个答案:

答案 0 :(得分:17)

C没有默认参数,如果您使用C ++进行编程,则应使用std::string中的remove_if<algorithm>

你绝对可以通过消除对strlen的调用来提高效率,这些调用将O(N)算法转换为O(N 2 )算法,并且完全没有必要 - 你正在扫描字符串,所以只需自己寻找NUL。

通过使用两个指针而不是数组索引,您还可以使这更像C-idiomatic。我会这样做:

void strip_char(char *str, char strip)
{
    char *p, *q;
    for (q = p = str; *p; p++)
        if (*p != strip)
            *q++ = *p;
    *q = '\0';
}

答案 1 :(得分:10)

首先,i<strlen(str)始终是循环字符串的低效习惯用语。正确的循环条件只是str[i],即循环直到str[i]为空终止符。

话虽如此,这是我所知道的最简单/最简洁的算法:

for (size_t i=0, j=0; s[j]=s[i]; j+=!isspace(s[i++]));

注意:我的解决方案是针对主题(空白)而不是正文(特定字符)编写的问题。如果需要,您可以轻松地进行调整。

答案 2 :(得分:-1)

void prepend(char* s,char ch){
    int len = strlen(s);
    memmove(s, s + 1, len - 1);
    s[len - 1] = '\x0';
}


void RemoveWhitespace(char* InStr, char ch){
     int n(0);

if (InStr == NULL){
    return;
}
else if ((*InStr) == '\x0'){
    return;
}   
else if ((*InStr) != ch){
    RemoveWhitespace(InStr + 1,ch);
}
else{
    while ((*InStr) == ch){
        prepend(InStr,InStr[0]);
        n++;
    }
    RemoveWhitespace(InStr + n,ch);
}
}