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();
}
-
\$\begingroup\$ so msdn.microsoft.com/en-us/library/t97s7bs3%28v=vs.110%29.aspx ? \$\endgroup\$njzk2– njzk22015年01月22日 21:51:30 +00:00Commented Jan 22, 2015 at 21:51
-
\$\begingroup\$ Minor thought: what about tabs in the string '\t'? \$\endgroup\$dariogriffo– dariogriffo2015年01月23日 12:37:15 +00:00Commented Jan 23, 2015 at 12:37
-
\$\begingroup\$ There are no tabs in the string \$\endgroup\$Syed Akram– Syed Akram2015年01月23日 16:22:47 +00:00Commented 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– RubberDuck2015年02月13日 18:22:44 +00:00Commented Feb 13, 2015 at 18:22
4 Answers 4
A few things to point out.
char[] longChars = longString.ToCharArray();
string
s 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();
}
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();
}
}
-
\$\begingroup\$ Cannot use any internal string manipulation functions.... \$\endgroup\$Syed Akram– Syed Akram2015年01月22日 21:51:59 +00:00Commented 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– Roey Golzarpoor2015年01月22日 21:57:55 +00:00Commented Jan 22, 2015 at 21:57
-
1\$\begingroup\$ yes that is correct. \$\endgroup\$Syed Akram– Syed Akram2015年01月22日 22:02:12 +00:00Commented Jan 22, 2015 at 22:02
-
\$\begingroup\$ I updated my answer with code \$\endgroup\$Roey Golzarpoor– Roey Golzarpoor2015年01月23日 12:15:16 +00:00Commented 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– Syed Akram2015年01月23日 16:11:09 +00:00Commented Jan 23, 2015 at 16:11
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.
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);
...