Google Interview Question
Software Engineer / DevelopersCountry: Israel
Interview Type: In-Person
It seems a easy question if we can use java regex I dont know if we can use it or not.
The code would be :
String s="_ _ _Hello _ _ _ World_ _ _Hello_World_ _ _ _ _ _ _ _ ";
s=s.replaceAll("\\s+",\\s);
in google projects you need to develop these kind of tools / API's to implement new features or test the products. so you need to implement this function /API that shows your logic / programming capabilities, but NOT to use existing system functions
Using library function is not appropriate.
Use 2 pointers - Initially both point to the beginning of the array. The first pointer keeps track of a space and the second pointer is advanced to find a non-space character.
Upon finding the non-space character, it is copied to the location of the first pointer and then both the first and second pointers are advanced. The second pointer has to deal with a boundary condition that it has to treat the first space character after the word boundary as part of the word.
public String removeSpace (String text){
char [] chs = text.toCharArray() ;
int i = 0 ;
int j = i ;
boolean head = false ;
boolean isSpace = false ;
for (i = 0 ; i < chs.length ; ++i) {
if (!head && chs[i] == ' ') {
continue ;
}
head = true ;
if (chs[i] != ' ') {
chs[j++] = chs[i] ;
isSpace = false ;
} else {
if (!isSpace) {
chs[j++] = chs[i] ;
}
isSpace = true ;
}
}
return new String(chs, 0 , j) ;
}
Did it on JS in O(n), dunno if its the best way though haha.
var strToTrim = " HELLO WORLD ";
trim(strToTrim);
//result -> 'HELLO WORLD '
function trim(str){
var strArray = str.split('');
var placeHolder = 0;
var prevChar = null;
for(var i = 0;i < strArray.length;i++){
if(strArray[i] === ' '){
if(prevChar !== ' ' && placeHolder > 0){
placeHolder++;
}
} else {
strArray[placeHolder] = strArray[i];
placeHolder++;
}
prevChar = strArray[i];
strArray[i] = ' ';
}
return strArray.join('');
}
#include <stdio.h>
#include <string.h>
void trim(char *p);
main()
{
char msg[] = "hi this is test message";
trim(msg);
printf("%s",msg);
}
void trim(char *p)
{
char *m,*n;
m = n = p;
int space = 1;
while(*p != '\0')
{
if(isspace(*p) && (space == 1))
{
*m = *p;
space = 0;
m++;
}
if(isalnum(*p))
{
*m = *p;
m++;
space = 1;
}
p++;
}
*m = '\0';
p = n;
}
/*
Given a string with multiple spaces write a function to in-place trim all spaces
leaving a single space between words
*/
string trimSpaces(string target) {
bool extraSpace = false;
string::iterator reader = target.begin();
string::iterator writer = target.begin();
// rewrite string overwriting extra spaces
while (reader != target.end()) {
if (*reader == ' ') {
// check for extra space
if (extraSpace) {
reader++;
} else {
extraSpace = true;
*writer = *reader;
reader++;
writer++;
}
} else {
extraSpace = false;
*writer = *reader;
reader++;
writer++;
}
}
// truncate string up to last written character
target.erase(writer, target.end());
return target;
}
Here is the code in C:)
Remember this is an in place algorithm that is you do not have to create an extra array or extra memory.
The basic algorithm is done here and of course we can do it with the help of already built in functions Like Java but we have to built in our own functions when asked about these questions. So
1. Count the number of words and spaces. If the spaces=words-1 then it is all correct but if its not then
2. Traverse thorough the string and count the number of words and spaces. Then you have to take a variable any variable make it 0 and then whenever there is a letter then put that letter in the variable you first initialized while you also have to take an another variable that is doing the normal traversal
3. Whenever there is an end of a word then put a space after that word and countine with the next word
4. At last put all the spaces n the end. My algo allows to end spaces-1 in the end as it already places an extra space after the last word.
Hope it helps:)
#include <stdio.h>
#include <conio.h>
#include <string.h>
int words=0;
int countWordsAndLetters(char *str)
{
int wo=0;
for(int i=0;i<strlen(str);)
{
if(str[i]!=' ')
{
while(str[i]!=' ')
{
i++;
wo++;
}
words++;
}
else
i++;
}
return wo;
}
int countSpaces(char *str)
{
int co=0;
for(int i=0;i<strlen(str);)
{
if(str[i]==' ')
{ while(str[i]==' ')
{
co++;
i++;
}
}
else
i++;
}
return co;
}
int main()
{
char str[]="Hello World ";
int prevLength=strlen(str);
int space=countSpaces(str);
int letters=countWordsAndLetters(str);
if(space+1==words)
printf("The entered string is correct ");
else
{
int newLength=letters+words+space;
int j=0;
for(int i=0;i<prevLength;i++)
{
if(str[i]!=' ')
{
str[j]=str[i];
j=j+1;
}
if(str[i+1]==' '&&str[i]!=' ')
{
str[j]=' ';
j=j+1;
}
}
int s=space-1;
while(s!=0)
{
str[j]=' ';
j=j+1;
s--;
}
str[j]='\0';
for(int i=0;str[i]!='\0';i++)
{
if(str[i]==' ')
printf("_");
else
printf("%c",str[i]);
}
}
}
Here's one implementation:
public class TrimMultipleSpaces {
public String trim(String word) {
char[] p = word.toCharArray();
tr(p);
return new String(p);
}
private void tr(char[] word) {
boolean flag = false;
for (int i = 0; i < word.length; i++) {
if (word[i] == ' ' && flag) {
bringInFront(word, i);
} else if (word[i] == ' ' && !flag) {
bringInFront(word, i);
flag = true;
} else {
flag = false;
}
}
}
private void bringInFront(char[] word, int l) {
for (int i = l; i < word.length; i++) {
if (i + 1 < word.length - 1) {
word[i] = word[i + 1];
}
}
}
public static void main(String[] args) {
TrimMultipleSpaces obj = new TrimMultipleSpaces();
System.out.println(obj.trim(" Hello World "));
}
}
public static String trimSpace(String input) {
char[] charsInString = input.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < charsInString.length; i++) {
char c = charsInString[i];
if (c == ' ') {
if (i != 0)
sb.append(c);
while (i < charsInString.length - 1
&& charsInString[i + 1] == ' ')
i++;
} else
sb.append(c);
}
if (sb.charAt(sb.length() - 1) == ' ')
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
public static String trimSpaces(String s) {
char[] chars = s.toCharArray();
int spaceCounter = 0;
int curIndex = 0;
int curLength = chars.length;
while (curIndex < curLength) {
// count spaces
while (curIndex < curLength && chars[curIndex] == ' ') {
spaceCounter++;
curIndex++;
}
if (spaceCounter > 0) {
// calculate shift
int shift = spaceCounter - 1;
if (curIndex - spaceCounter == 0) { // beginning of string
shift++;
} else if (curIndex - curLength == 0) { // end of string
shift++;
}
// do shifting
if (shift > 0) {
for (int i = curIndex - shift; i < curLength - shift; i++) {
chars[i] = chars[i + shift];
}
curLength = curLength - shift;
}
}
if (spaceCounter == 0) {
curIndex++;
} else {
spaceCounter = 0;
}
}
String trimmed = new String(chars);
return trimmed.substring(0, curLength);
}
Here is an implementation in 0(n) time complexity:
//replacing All extra spaces between words
#include<iostream>
#include<vector>
#include<map>
#include<list>
#include<cstdio>
#include<climits>
#include<algorithm>
#include<string>
#include<cmath>
#include<cstdlib>
#include<string.h>
#include<string>
using namespace std;
void RemoveExtraSpaces(char s[]){
int i=0,j=0,len=strlen(s),k;
while(j<len && s[j]==' ')
j++;
while(j<len){
while(j<len && s[j]!=' '){
s[i++]=s[j++];
}
k=j;
while(k<len && s[k]==' ')
k++;
if(k<len && k!=j){
s[i++]=' ';
}
j=k;
}
s[i]='\0';
}
int main(){
char a[]=" hello hello hello hello ";
cout<<a<<endl;
RemoveExtraSpaces(a);
cout<<a<<endl;
return 0;
}
void trimExcessSpace(string &orig) {
if (orig.length() == 0)
return;
int sIdx = 0, counter = 0;
bool hasSpace = false;
for (int i = 0; i < orig.length(); i++) {
if (orig[i] != ' ') {
counter++;
orig[sIdx++] = orig[i];
hasSpace = false;
} else if (!hasSpace) {
counter++;
orig[sIdx++] = orig[i];
hasSpace = true;
}
}
orig = orig.substr(0, counter);
}
//in-placing removing duplicated spaces from string
#include <iostream>
#include <string>
bool isSpace(char ch) {
return ch == ' ' || ch == '\t'; //TODO: more space-like character?
}
void removeDuplicatedSpaces(std::string& s) {
std::string::iterator reader;
std::string::iterator writer = s.begin();
if( s.size() == 0 )
return;
bool isNoSpace = false;
for( reader = s.begin(); reader != s.end(); ++reader) {
if( isSpace(*reader)) {
if( isNoSpace ) {
*writer++ = *reader;
}
isNoSpace = false;
continue;
}
isNoSpace = true;
*writer++ = *reader;
}
s.erase(writer-1, reader);
std::cout << std::endl;
}
int main() {
std::string s = " there are many space ";
std::cout << s << std::endl;
removeDuplicatedSpaces(s);
std::cout
<< "'"
<< s
<< "'"
<< " size=" << s.size()
<< std::endl;
return 0;
}
//inplace remove duplicated spaces from string
#include <iostream>
#include <string>
bool isSpace(char ch) {
return ch == ' ' || ch == '\t'; //TODO: more space-like character?
}
void removeDuplicatedSpaces(std::string& s) {
std::string::iterator reader;
std::string::iterator writer = s.begin();
if( s.size() == 0 )
return;
bool isNoSpace = false;
for( reader = s.begin(); reader != s.end(); ++reader) {
if( isSpace(*reader)) {
if( isNoSpace ) {
*writer++ = *reader;
}
isNoSpace = false;
continue;
}
isNoSpace = true;
*writer++ = *reader;
}
s.erase(writer-1, reader);
std::cout << std::endl;
}
int main() {
std::string s = " there are many space ";
std::cout << s << std::endl;
removeDuplicatedSpaces(s);
std::cout
<< "'"
<< s
<< "'"
<< " size=" << s.size()
<< std::endl;
return 0;
}
#include<string>
#include<iostream>
using namespace std;
void in_place_trim(string& sentence) {
int space_count = 0;
bool previous_was_space = true;
for (int i = 0, end = sentence.size(); i != end; ++i) {
if (sentence[i] == ' ') {
if (previous_was_space) {
++space_count;
}
previous_was_space = true;
}
else {
previous_was_space = false;
}
if (space_count != 0) {
sentence[i - space_count] = sentence[i];
sentence[i] = ' ';
}
}
}
int main() {
string str(" This is a test!");
in_place_trim(str);
cout << str << "\n";
}
While j is less than length of the char array keep advancing as long as there are whitespaces. Once we find non space character, shift them back to the ith location. Finally convert this to a string and return. It is O(n) solution where n is the length of the string.
public static String trimSpaces(String input) {
char[] inputChars = input.toCharArray();
int length = input.length();
int i = 0, j = 0;
while (j < length) {
while (j < length && inputChars[j] == ' ') {
j++;
}
while (j < length && inputChars[j] != ' ') {
inputChars[i++] = inputChars[j++];
}
inputChars[i++] = ' ';
}
while (i < length && inputChars[i] != ' ') {
inputChars[i++] = '\0';
}
String output = new String(inputChars);
return output;
}
public class TestProgram {
static String string = " Hello World ";
public static void main(String[] args) {
boolean isWordCompleted = true;
String spaces = "";
String lines = "";
for (int i = 0; i < string.length(); i++) {
if (string.charAt(i) != ' ') {
isWordCompleted = false;
lines = lines + string.charAt(i);
} else if (!isWordCompleted && string.charAt(i) == ' ') {
lines = lines + string.charAt(i);
isWordCompleted = true;
} else if (isWordCompleted && string.charAt(i) == ' ') {
spaces = spaces + ' ';
}
}
System.out.print(lines + spaces);
}
}
package google;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class RemoveWhitespaces {
@Test
public void test() {
assertEquals(" a b c dd ", removeWhitespaces(" a b c dd "));
}
public static String removeWhitespaces(String s) {
if (s.length() <= 1) return s;
char[] symbols = s.toCharArray();
int j = 1;
for (int i = 1; i < symbols.length; i++) {
if (symbols[i] != ' ' || symbols[i - 1] != ' ') {
symbols[j++] = symbols[i];
}
}
return new String(symbols, 0, j);
}
}
#include<cstdlib>
#include<iostream>
using namespace std;
void esp_rm(char* arr)
{
int i=0,j=0,count=0,pos=0;
bool flag=false;
while(arr[i]!='\0')
{
if(arr[i]==' ')
{
j=i;
while(arr[i]==' ')
{
i++;
}
if(i!=j+1)
{
pos=j;
while(arr[i]!='\0')
{
arr[j+1]=arr[i];
arr[i]=' ';
i++;
j++;
flag=true;
}
}
}
if(flag==true)
{
i=pos;
flag=false;
}
i++;
}
int k=0;
while(arr[k]!='\0')
{
cout<<arr[k];
k++;
}
}
int main() {
char arr[]="Hello World The";
esp_rm(arr);
system("Pause");
return 0;
}
#include<cstdlib>
#include<iostream>
using namespace std;
void esp_rm(char* arr)
{
int i=0,j=0,count=0,pos=0;
bool flag=false;
while(arr[i]!='\0')
{
if(arr[i]==' ')
{
j=i;
while(arr[i]==' ')
{
i++;
}
if(i!=j+1)
{
pos=j;
while(arr[i]!='\0')
{
arr[j+1]=arr[i];
arr[i]=' ';
i++;
j++;
flag=true;
}
}
}
if(flag==true)
{
i=pos;
flag=false;
}
i++;
}
int k=0;
while(arr[k]!='\0')
{
cout<<arr[k];
k++;
}
}
int main() {
char arr[]="Hello World The";
esp_rm(arr);
system("Pause");
return 0;
}
Yay! I failed because I didnt do an in-place replace
String input = " Hello World Hello World ";
StringBuilder output = new StringBuilder();
boolean lastWasChar = false;
boolean wordSeen = false;
for ( int index = 0; index < input.length(); index++ ) {
char charAt = input.charAt(index);
if ( charAt != ' ' ) {
if ( ! lastWasChar && wordSeen ) {
output.append(' ');
}
output.append(charAt);
lastWasChar = true;
wordSeen = true;
} else {
lastWasChar = false;
}
}
System.out.println(output);
void TrimStr(char *_str)
{
unsigned int length = strlen(_str);
char *str_ptr1 = _str;
char *str_ptr2;
while(*str_ptr1 != 0x00)
{
str_ptr2 = str_ptr1;
while(*str_ptr2 == '_') str_ptr2++;
if(str_ptr2 - str_ptr1 > 0)
{
if(str_ptr1 != _str && *str_ptr2 != '\x00') str_ptr1++;
length -= str_ptr2 - str_ptr1;
memmove(str_ptr1, str_ptr2, length + 1);
}
str_ptr1++;
}
}
void Spacify(char* input)
{
if (!input)
return;
int writeIndex = 0;
int len = strlen(input);
char currChar = '\0';
for (int i = 0; i < len; i++)
{
currChar = input[i];
// check for starting of a word
if (!isspace(currChar))
{
// copy the whole word
while (i < len && !isspace(currChar))
{
char temp = input[writeIndex];
input[writeIndex] = currChar;
input[i] = temp;
writeIndex++;
i++;
currChar = input[i];
}
if (writeIndex < len)
{
input[writeIndex] = ' ';
writeIndex++;
}
}
}
}
Any one interested this Java in-place solution, less lines
public static String removeSpaces(String str){
if(str == null){
return str;
}
char[] chars = str.toCharArray();
int retIdx = 0;
boolean space = true;//ignore leading spaces
for (char c : chars) {
if(c == ' ' && !space){
chars[retIdx++] = c;
space = true;
}else if(c != ' '){
chars[retIdx++]=c;
space = false;
}
}
if(space){
chars[--retIdx]=0;//trim last space
}
return new String(Arrays.copyOf(chars, retIdx));
}
<pre class="lang-cs pretyprint prettyprinted">
<code>
public static void TrimSpaces(string s1)
{
StringBuilder s = new StringBuilder(s1);
List<string> listOfWords = new List<string>();
List<char> word = new List<char>();
int j = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] != ' ')
{
word.Add(s[i]);
}
else if (word.Count() > 0)
{
listOfWords.Add(string.Concat(word));
word.Clear();
}
}
int l = 0;
for (int k = 0; k < listOfWords.Count(); k++)
{
foreach (char c in listOfWords[k])
{
s[l++] = c;
}
if (k == listOfWords.Count() - 1)
{
s[l] = '\0';
s.Length = l;
}
else
s[l++] = ' ';
}
Console.WriteLine(s);
}
</code>
</pre>
<pre class="lang-cs pretyprint prettyprinted">
<code>
public static void TrimSpaces(string s1)
{
StringBuilder s = new StringBuilder(s1);
List<string> listOfWords = new List<string>();
List<char> word = new List<char>();
int j = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] != ' ')
{
word.Add(s[i]);
}
else if (word.Count() > 0)
{
listOfWords.Add(string.Concat(word));
word.Clear();
}
}
int l = 0;
for (int k = 0; k < listOfWords.Count(); k++)
{
foreach (char c in listOfWords[k])
{
s[l++] = c;
}
if (k == listOfWords.Count() - 1)
{
s[l] = '\0';
s.Length = l;
}
else
s[l++] = ' ';
}
Console.WriteLine(s);
}
</code>
</pre>
// java solution
public static String trimLeft(String s)
{
char[] caracters = s.toCharArray();
char previous = ' ';
char current;
int pos = 0;
for (int i = 0; i < caracters.length; i++) {
current = caracters[i];
if ((current != ' ') || (current == ' ' && previous != current))
caracters[pos++] = current;
previous = current;
}
for (int i = pos; i < caracters.length; i++) // filling the remaining entries
caracters[i] = ' ';
return new String(caracters);
}
void trimrecurse(char[] array, int start, int count) {
int tempCount = 0;
for(int i=start; i < array.length; i++) {
if(array[i] == ' ')
tempCount++;
else if(tempCount > 1) trimrecurse(array, start, count + tempCount - 1);
else {
array[i-count] = array[i];
array[i] = ' ';
}
}
}
void trim(char array[]) {
int count = 0;
int start = 0;
while(array[start++] == ' ') {
count++;
}
trimrecurse(array, start, count);
}
public static void main(String args[])
{
String input = "_ _ _ Hello _ _ _ World _ _ _ ";
int _isString = 0;
int put_string = 0;
String new_string = "";
for(int i=0; i< input.length();i++)
{
char idv_char = input.charAt(i);
if(Character.isLetter(idv_char))
{
new_string = new_string + Character.toString(idv_char);
if(i+1 < input.length())
{
if(!Character.isLetter(input.charAt(i+1)))
{
put_string = put_string + 1;
new_string = new_string +"_";
}
}
else
{
_isString = _isString+1;
}
}
}
int check =_isString + put_string ;
for (int i = 1 ; i <= check ; i++)
{
new_string = new_string+"_";
}
System.out.println(new_string);
}
}
Short C++ solution (O(n))
#include <string>
using namespace std;
void TrimSpaces(string &s) {
int write_idx = 0;
int read_idx = 0;
bool do_trim = true; // trim at start
while (read_idx < s.size()) {
if (s[read_idx] != ' ' || !do_trim)
s[write_idx++] = s[read_idx];
do_trim = (s[read_idx++] == ' ');
}
// fill up with spaces (or trunc string to write_idx length)
while (write_idx < s.size())
s[write_idx++] = ' ';
}
This is a java solution that does exactly as asked for, using a char array
/**
* @param strToShift
* @param cursor
* @return
*/
static char[] shiftBack(char[] strToShift, int cursor) {
for(int i = cursor; i < strToShift.length-1; i++) {
strToShift[i] = strToShift[i+1];
}
return strToShift;
}
/**
* @param strToTrim
* @param trimThis
* @return
*/
static char[] trimExtraChars(char[] strToTrim, char trimThis) {
int cursor = 0;
int skip = 0;
while(cursor + skip < strToTrim.length) {
while(strToTrim[cursor] != trimThis) {
cursor++;
}
if(strToTrim[cursor] == trimThis && strToTrim[cursor+1] == trimThis) {
strToTrim = shiftBack(strToTrim, cursor);
skip++;
} else {
cursor++;
}
}
if(strToTrim[0] == trimThis) {
strToTrim = shiftBack(strToTrim, 0);
}
return strToTrim;
}
public static void main(String[] args) {
char[] strToTrim = new char[] {' ',' ',' ','H','e','l','l','o',' ',' ',' ','W','o','r','l','d',' ',' ',' '};
char trimThis = '.';
char[] trimmmedString = trimExtraChars(strToTrim, trimThis);
}
#include<bits/stdc++.h>
using namespace std;
string temp;
int main(){
cin>>temp;
int state = 0;
int inc = 0;
int j = 0;
for(int inp=0;inp<temp.size();inp++){
if(state==0){
if(temp[inp]=='_')
state = 1;
else
{
temp[j] = temp[inp];
j++;
state = 2;
}
}
else if(state==1){
if(temp[inp]!='_')
{
state = 2;
temp[j] = temp[inp];
j++;
}
}
else if(state==2){
if(temp[inp]=='_')
{
temp[j] = temp[inp];
state = 3;
j++;
}
else{
temp[j] = temp[inp];
state = 2;
j++;
}
}
else{
if(temp[inp]=='_')
state = 1;
else{
temp[j] = temp[inp];
j++;
state = 2;
}
}
}
cout<<temp.substr(0,j)<<endl;
return 0;
}
In Python:
I decided to :
Step 1: Split the string to get the spaces
Step 2: Take only the non space characters and place into a new array
Step 3: Concatenate the elements of the array using a single space
def removeInnerSpace(value):
return " ".join([x for x in value.split(" ") if (x!='' and x!=' ')])
HOWEVER,
If functions such as join and split are not allowed:
def removeInnerSpace(value):
result = ""
'find the start and end of where the text begins : O(n)'
start = -1
end = -1
for i in range(0,len(value)):
start=i if (start<0 and value[i]!=' ') else start
end = len(value)-1-i if (end<0 and value[len(value)-1-i]!=' ') else end
if (start > 0 and end > 0):
break;
'cater for single character'
if (start==end and start>0):
return value[start]
elif(start<0 and end<0):
'cater for all white spaces'
return None
'copy string: O(n)'
for i in range(start,end+1):
'Criteria: When x is blank, the next must not be blank'
'otherwise just copy of the values that are not blank'
result +=value[i] if (value[i]==' ' and i+1 < end+1 and value[i+1]!=' ') or value[i]!=' ' else ''
'Roughly: O(2n) for large values still O(n)'
return result
static String trimSpaces(char[] inp)
{
boolean firstSpaces=true;
int k=0;
for(int i=0; i < inp.length;i++)
{
if(inp[i]==' ' && firstSpaces)
{
inp[k]=' ';
k++;firstSpaces=false;
}else if(inp[i]!=' ')
{
firstSpaces=true;
inp[k]=inp[i];
k++;
}
}
String output=new String(inp);
return output.substring(0,k);
}
- (void)trimmingSpaces
{
char string[] = " Hello World, this is a big space and I'm adding few more spaces to this";
int wordCount = 0;
int charCount = 0;
int spaceCount = 0;
bool shouldIncrementWordCount = false;
int i =0;
for (i =0; string[i]!='\0'; i++)
{
if (string[i] == ' ') {
if (shouldIncrementWordCount) {
wordCount++;
}
spaceCount++;
shouldIncrementWordCount = false;
}
else
{
if (spaceCount==0 || spaceCount==wordCount) {
charCount++;
shouldIncrementWordCount = true;
continue;
}
if (wordCount>0) {
if (!shouldIncrementWordCount) {
string[i-spaceCount+wordCount+1] = ' ';
}
string[(i-spaceCount)+wordCount] = string[i];
}
else
{
string[i-spaceCount] = string[i];
}
string[i] = ' ';
charCount++;
shouldIncrementWordCount = true;
}
}
string[charCount+wordCount] = '\0';
}
Scott's code looked fine to me. Did you try mine? There is only bug but that's an easy fix.
I haven't tried yours, but all the solutions need to make sure the string length does not change and ater moving the chars forward, make sure the original locations are filled with spaces. Both Scot's and Dinesh's code did not take care of that
This was what I had wrote
static void TrimSpecial(char[] str) {
int src = 0, dest = 0;
while (src < str.Length) {
while (src < str.Length && char.IsWhiteSpace(str[src]))
++src;
while (src < str.Length && !char.IsWhiteSpace(str[src]))
str[dest++] = str[src++];
if (src < str.Length && char.IsWhiteSpace(str[src]))
str[dest++] = str[src++];
}
while (dest < str.Length)
str[dest++] = ' ';
}
This is Fixed version of Scott's
static void TrimSpecial2(char[] str) {
bool head = true, inSpace = false;
int j = 0, k = 0;
for (int i = 0; i < str.Length; ++i) {
if (head && char.IsWhiteSpace(str[i]))
continue;
head = false;
if (!char.IsWhiteSpace(str[i])) {
inSpace = false;
str[j++] = str[i];
k = i;
} else {
if (!inSpace)
str[j++] = str[i];
inSpace = true;
}
}
while (j <= k)
str[j++] = ' ';
}
This is the calling code
static void Main(string[] args) {
string s = " Hello World ";
char[] str = s.ToCharArray();
Console.WriteLine("Original = [{0}]", new string(str));
TrimSpecial2(str);
Console.WriteLine("XFormed = [{0}]", new string(str));
}
void MoveWord(char *str, int & sourceIndex, int & destIndex)
{
while (str[sourceIndex] != '\0' && str[sourceIndex] != ' ')
{
str[destIndex] = str[sourceIndex];
destIndex++;
sourceIndex++;
}
str[destIndex++] = ' ';
}
int findWordFirstWord(char *str, int index)
{
while (str[index] != '\0' && str[index] == ' ')
{
index++;
}
if (str[index] == '\0')
{
return -1;
}
return index;
}
void trimFunc(char *str)
{
int length = strlen(str);
if ( length <= 0 )
return;
int begin = 0;
int tail = 0;
tail = findWordFirstWord(str, tail);
while (tail > 0)
{
MoveWord(str, tail, begin);
tail = findWordFirstWord(str, tail);
}
str[begin] = '\0';
}
This is kind of crude but it works well. Tell me if it needs any improvements. Thanks !
public static char[] trimString(char [] arr) {
int temp = 0;
for (int i = 0; i < arr.length;) {
if (arr[i] == ' ') {
if (i != 0) { // checking if the first char is a space, if it is
// a space then no need to include that in final
// array
arr[temp] = arr[i]; // if it is a space between words
// incorporate that space in the array !
temp++;
i++;
}
while (arr[i] == ' ')
i++;
}
if (i < arr.length && arr[i] != ' ') {
while (i < arr.length && arr[i] != ' ') {
arr[temp] = arr[i];
if (temp != i)
arr[i] = ' ';
temp++;
i++;
}
}
}
return arr;
}
public void trim() {
String s = " Hello World ";
Scanner sc = new Scanner(s);
sc.useDelimiter("\\s+");
boolean flag;
while (sc.hasNext()) {
String str=sc.next();
System.out.print(str);
if (sc.hasNext())
System.out.print(" ");
}
}
public String trim(String s){
String finalStr = "";
char[] chr = s.toCharArray();
boolean wordCaptured = false;
for(int i=0; i<chr.length; i++){
if(chr[i] != ' '){
wordCaptured = true;
}else if(wordCaptured && chr[i] == ' '){
wordCaptured = false;
}else{
wordCaptured = false;
continue;
}
if(wordCaptured || (!wordCaptured && chr[i] == ' ')){
finalStr = finalStr + chr[i];
}
}
return finalStr;
}
/*
Given a string with multiple spaces write a function to in-place trim all spaces
leaving a single space between words
*/
string trimSpaces(string target) {
string::iterator reader = target.begin();
string::iterator writer = target.begin();
// rewrite all non-space characters
while (reader != target.end()) {
if (*reader == ' ') {
reader++;
} else {
*writer = *reader;
reader++;
writer++;
}
}
// truncate string up to last written character
target.erase(writer, target.end());
return target;
}
Simple Java
private static String stripSpaces(String input) {
String output = "";
if (input == null || input.isEmpty()) {
return output;
}
for (int i = 0; i < input.length(); i++) {
if (input.charAt(i) == ' ' && i + 1 < input.length() && input.charAt(i+1) == ' ') {
continue;
}
output += input.charAt(i);
}
return output;
}
The logic seems to be good but it is an in-place solution? though string in immutable, I think you have to use same string input object back and not use a new output object to store updated string contents.
- Simple Java implementation June 21, 2014