面试问题:修剪字符串中的多个连续空格

时间:2011-04-06 03:30:23

标签: c++ c string

这是一个面试问题 寻找最佳的最佳解决方案来修剪字符串中的多个空格。此操作应该是就地操作。

input  = "I    Like    StackOverflow a      lot"
output = "I Like StackOverflow a lot"

不允许使用字符串函数,因为这是一个面试问题。寻找问题的算法解决方案。

11 个答案:

答案 0 :(得分:14)

使用<algorithm>是否有资格作为“算法解决方案”?

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
struct BothAre
{
    char c;
    BothAre(char r) : c(r) {}
    bool operator()(char l, char r) const
    {
            return r == c && l == c;
    }
};
int main()
{
    std::string str = "I    Like    StackOverflow a      lot";
    std::string::iterator i = unique(str.begin(), str.end(), BothAre(' '));
    std::copy(str.begin(), i, std::ostream_iterator<char>(std::cout, ""));
    std::cout << '\n';
}

测试运行:https://ideone.com/ITqxB

答案 1 :(得分:11)

c ++ 0x - 使用lambda而不是常规函数对象的解决方案。与Cubbi的解决方案相比。

#include <string>
#include <algorithm>

int main()
{
    std::string str = "I    Like    StackOverflow a      lot";

    str.erase(std::unique(str.begin(), str.end(),
      [](char a, char b) { return a == ' ' && b == ' '; } ), str.end() );  
}

答案 2 :(得分:10)

保留两个索引:下一个可放置字母的位置(例如i),以及您正在检查的当前索引(例如j)。

只需使用j循环遍历所有字符,每当看到一封信时,将其复制到索引i,然后递增i。如果您看到空格前面没有空格,请复制空格。

认为这可以就地工作......

答案 3 :(得分:6)

我只想这样做:

int main(int argc, char* argv[])
{
    char *f, *b, arr[] = "  This        is    a test.                ";
    f = b = arr;

    if (f) do
    {
        while(*f == ' ' && *(f+1) == ' ') f++;
    } while (*b++ = *f++);

    printf("%s", arr);

    return 0;
}

答案 4 :(得分:2)

我建议使用一个小型状态机(只是一个简单的switch语句)。因为如果面试官和我一样,他们要求你做的第一个改进是完全修剪任何领先或尾随空格,以便:

"    leading and    trailing    "

转变为:

"leading and trailing"

而不是:

" leading and trailing "

这是对状态机设计的一个非常简单的修改,对我来说,通常在“直接”编码循环中理解状态机逻辑似乎更容易,即使它需要多几行代码而不是直接循环。

如果你认为对直接循环的修改不会太糟糕(可以合理地论证),那么我(作为采访者)会投入,我也希望数字的前导零是修整。

另一方面,许多采访者可能实际上不喜欢状态机解决方案是“非最佳”。我想这取决于你想要优化的内容。

答案 5 :(得分:0)

这里只使用stdio:

#include <stdio.h>

int main(void){
    char str[] = "I    Like    StackOverflow a      lot";
    int i, j = 0, lastSpace = 0;
    for(i = 0;str[i]; i++){
        if(!lastSpace || str[i] != ' '){
            str[j] = str[i];
            j++;
        }
        lastSpace = (str[i] == ' ');
    }
    str[j] = 0;
    puts(str);
    return 0;
}

答案 6 :(得分:0)

修剪多个空格也意味着空格应始终后跟非空格字符。

int pack = 0;
char str[] = "I    Like    StackOverflow a      lot";
for (int iter = 1; iter < strlen(str); iter++)
{
    if (str[pack] == ' ' && str[iter] == ' ')
        continue;
    str[++pack] = str[iter];
}
str[++pack] = NULL;

答案 7 :(得分:0)

int j = 0;
int k=0;
char str[] = "I    Like    StackOverflow a      lot"; 
int length = strlen(str);
char str2[38];
for (int i = 0; i < length; i++) 
{ 
    if (str[i] == ' ' && str[i+1] == ' ') 
     continue; 
    str2[j] = str[i];
    j++;
} 

str2[j] =NULL;

cout<<str2;

答案 8 :(得分:0)

void trimspaces(char * str){
    int i = 0;
    while(str[i]!='\0'){
        if(str[i]==' '){
            for(int j = i + 1; j<strlen(str);j++){
                if(str[j]!=' '){
                    memmove(str + i + 1, str + j, strlen(str)-j+1);
                    break;
                }
            }
        }
        i++;
    }
}

答案 9 :(得分:0)

Haskell中的功能变体:

import Data.List (intercalate)

trimSpaces :: String -> String
trimSpaces =  intercalate " " . words

下一个算法:

  1. 将字符串分成一个单词列表,这些单词由空格分隔
  2. 连接列表,在列表
  3. 中的每个元素之间插入一个空格

答案 10 :(得分:0)

这是一个非常简单的删除额外空格的实现。

#include <iostream>
std::string trimExtraWhiteSpaces(std::string &str);
int main(){
    std::string str = "  Apple    is a     fruit  and I like     it   .  ";
    str = trimExtraWhiteSpaces(str);
    std::cout<<str;
}
std::string trimExtraWhiteSpaces(std::string &str){
    std::string s;
    bool first = true;
    bool space = false;
    std::string::iterator iter;
    for(iter = str.begin(); iter != str.end(); ++iter){
        if(*iter == ' '){
            if(first == false){
                space = true;
            }
        }else{
            if(*iter != ',' && *iter != '.'){
                if(space){
                    s.push_back(' ');
                }
            }
            s.push_back(*iter);
            space = false;
            first = false;
        }
    }
    return s;
}