0
\$\begingroup\$

The objective is to remove extra spaces from the below string:

" Today it is going to rain. "

so it looks like below

"Today it is going to rain."

Please determine if the code will perform well and if there is a better solution (NO REGEX or LAMBDA).

static string CompactStringPerfect()
{  
    string longString = "   Today   it  is     going    to  rain.     ";  

    StringBuilder sb = new StringBuilder();
    char[] longChars = longString.ToCharArray();

    int spaceCount = 0;

    //Using standard method with no library help
    for (int i = 0; i < longChars.Length; i++)
    {
        //If space then keep a count and move on until nonspace char is found
        if (longChars[i] == 32)
        {
            spaceCount++;
            continue;
        }

        //If more than one space then append a single space  
        if (spaceCount > 1 && sb.Length > 0)
            sb.Append(" ");

        //Append the non space character
        sb.Append(longChars[i]);

        //Reset the space count
        spaceCount = 1;
    }
    return sb.ToString();
}
\$\endgroup\$
4
  • \$\begingroup\$ so msdn.microsoft.com/en-us/library/t97s7bs3%28v=vs.110%29.aspx ? \$\endgroup\$
    – njzk2
    Jan 22, 2015 at 21:51
  • \$\begingroup\$ Minor thought: what about tabs in the string '\t'? \$\endgroup\$
    – dariogriffo
    Jan 23, 2015 at 12:37
  • \$\begingroup\$ There are no tabs in the string \$\endgroup\$
    – Syed Akram
    Jan 23, 2015 at 16:22
  • 1
    \$\begingroup\$ I have to ask... why exactly is it a requirement that possible solutions not use regex or linq? You're excluding possibly good solutions and it's important that we understand why. (Perhaps it's actually more important that you understand why.) \$\endgroup\$
    – RubberDuck
    Feb 13, 2015 at 18:22

4 Answers 4

3
\$\begingroup\$

A few things to point out.

char[] longChars = longString.ToCharArray();

strings in C# are array-like, and can be indexed directly. We don't need to convert it into a char[].

int spaceCount = 0;

We don't really need to keep track of how many spaces so much as whether the last character was a space. Therefore, this can become a boolean flag instead.

if (longChars[i] == 32)

This line has a magic number (32), and that makes it a little harder to understand. I'm guessing it's the Unicode number for the space character, but the fact that I have to guess makes it bad. Better would be: if(longChars[i] == ' '), but best would be: if(Char.IsWhiteSpace(longChars[i])). That catches all potential whitespace characters, and will be more robust. Also, it makes your intention much clearer.

if (spaceCount > 1 && sb.Length > 0)
    sb.Append(" ");

I always recommend using braces in light of goto fail.

//Reset the space count
spaceCount = 1;

This confuses me. You say you are "resetting" the space count, but the original value was 0, not 1, so I might (incorrectly) think this is a bug and try to fix it. The root of this issue lies in how you are tracking spaces.

So incorporating those suggestions, here's what I come up with:

public static string Despace(string longString) {
    StringBuilder sb = new StringBuilder();
    bool lastWasSpace = true; // True to eliminate leading spaces

    for(int i = 0; i < longString.Length; i++) {
        if(Char.IsWhiteSpace(longString[i]) && lastWasSpace) {
            continue;
        }

        lastWasSpace = Char.IsWhiteSpace(longString[i]);

        sb.Append(longString[i]);
    }

    // The last character might be a space
    if(Char.IsWhiteSpace(sb[sb.Length - 1])) {
        sb.Remove(sb.Length - 1, 1);
    }

    return sb.ToString();
}
\$\endgroup\$
0
0
\$\begingroup\$

Use split(), and then go over the String array you got. If some variable is not " ", it's a word like you need.

public class RemoveExtraSpacesFromString {

    public static void main(String[] args) {

        String str = " Today it is going to rain. ";        
        String strResult = "Today it is going to rain.";

        if (compactStringPerfect(str).equals(strResult)){
            System.out.println("Good Job!");
        }
    }

    private static String compactStringPerfect(String spacesStr){

        String newStr = "";
        String currentStr = "";

        for (int i = 0; i < spacesStr.length(); /*no incrementation*/) {
            if (spacesStr.charAt(i) != ' '){
                while (spacesStr.charAt(i) != ' '){
                    currentStr += spacesStr.charAt(i); 
                    i++;
                }               
            }
            else {
                i++;
            }
            if (!currentStr.equals("")){
                newStr += currentStr + " ";
                currentStr = "";
            }
        }

        return newStr.trim();

    }

}
\$\endgroup\$
11
  • \$\begingroup\$ Cannot use any internal string manipulation functions.... \$\endgroup\$
    – Syed Akram
    Jan 22, 2015 at 21:51
  • \$\begingroup\$ So it's only a way of find words with while loop and adding them to a new string separated by spaces \$\endgroup\$
    – Roey Golzarpoor
    Jan 22, 2015 at 21:57
  • 1
    \$\begingroup\$ yes that is correct. \$\endgroup\$
    – Syed Akram
    Jan 22, 2015 at 22:02
  • \$\begingroup\$ I updated my answer with code \$\endgroup\$
    – Roey Golzarpoor
    Jan 23, 2015 at 12:15
  • \$\begingroup\$ Roey, Thanks for the java code. I think splitting the string into words is the optimal way but for some reason the interviewer did not want me to use any library string manipulation functions... \$\endgroup\$
    – Syed Akram
    Jan 23, 2015 at 16:11
0
\$\begingroup\$

You can use regex to remove extra spaces. In Java, it would look something like this:

public static void main(String[] args) {
    String str = "      Today   it  is     going    to  rain.     ";
    String strResult = str.replaceAll("\\s+", " ").trim();

    System.out.println(strResult);
}

Output:

Today it is going to rain.

\$\endgroup\$
0
\$\begingroup\$

Thanks all for sharing your insight. I think using regex is the fastest and optimal solution to this. I believe this was an interview question just to see how one codes and things if no helper functions were to be used.

Another simple way of doing this is

...
char[] WhiteSpace = new char[] { ' ' };
string longString = "   Today   it  is     going    to  rain.     ";
string[] split = longString.Split(WhiteSpace, StringSplitOptions.RemoveEmptyEntries);
string compactedString = string.Join(" ", split);
...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.