Microsoft Interview Question
Software Engineer / DevelopersCountry: United States
there will be one iteration to move i,j to the end of the string. hence your solution can be done only with 2 iterations.
the question clearly says "one" iteration
what i assumed from the question is you have to write a function say moveSpace(char* str) { //ur code goes here }
In this case we do not know the length of the string unless we iterate over it
How about strlen(char*) to find out the end??
i am not sure if thats also counted as one iteration
I am the dumb idiot who thought an iteration means no loop. Sorry english is not my first language! This is simple enough solution.
It can be done without knowing the size of the string length beforehand and even not using strlen.
@unknown: Really can you? Microsoft will be please to announce that strlen() is now a constant time algorithm ^^... Just tell them what you know!
@Praveen: You are right. As with all questions here they are ridiculously under-specified and it is always funny how people just post some random answers to their interpretation, without even stating their interpretation. Microsoft should not hire them lol.
This question can only be solved under the assumption that you possess a pointer to the end of the string or can obtain it in constant time, which is only possible if you know the size of the string, which is not the case for c-style strings.
It is possible. sites.google.com/site/spaceofjameschen/home/string/move-the-spaces-to-the-starting-of-the-string-in-single-iteration---microsoft
@Dumbo: try preserving the sequence.
'Chan' has done as below:
Before processing
H e l l o w o r l d
After processing
e l l o H w o r l d
However i think the question become more tough if you maintain the order such as:
After processing
H e l l ow o r l d
Although it isn't stated, I feel fairly certain that the interviewer would want the non-space sequence to be preserved. Otherwise the question is stupid-easy.
It's akin to the remove algorithm in many libraries, which are required to be stable (i.e. preserve ordering of items not selected for removal).
char str[]=" asdfe sdrfjcz dgrjf ";
int i=0, len=0, count=0;
len = strlen(str);
for(i=len-1; i>=0; i--)
{
if(count ==i)
{
str[i] = ' '; count--;
}
else if(str[i] == ' ')
{
count++; continue;
}
else
{
if(count)
str[i+count] = str[i];
}
}
}
Not working!! This is the output for "H i t h e re! Is t hi s ev en p o s sib le?"-
"H i t h e re! Is t Hithere!Isthisevenpossible?"
char str[]="H i t h e re! Is t hi s ev en p o s sib le?";
int i=0, len=0, count=0, traversed = 0;
len = strlen(str);
for(i=len-1; i>=0; i--)
{
if(count>= 0 && (i == 0) && !traversed)
{
str[i+count] = str[i];
i=count;
traversed = 1;
count--;
}
else if(traversed && i>=0)
{
str[i] = ' ';
count--;
}
else if(str[i] == ' ')
{
count++; continue;
}
else
{
if(count)
str[i+count] = str[i];
}
}
I did in Java, but the technique is very similar. Java code is:
public char[] moveSpaceFront(String data){
int count = 0;
char[] str = data.toCharArray();
int i = str.length - 1;
while(i >= 0){
if(str[i] == ' ')
count++;
else
str[i + count] = str[i];
i--;
}
for(i = 0; i < count; i++)
str[i] = ' ';
return str;
}
public String moveSpacesToFront(String str) {
if (str == null || str.length() < 2) {
return str;
}
char[] chars = str.toCharArray();
int last = chars.length;
for (int i = last - 1; i >= 0; --i)
if (chars[i] != ' ')
chars[--last] = chars[i];
if (last > 0)
Arrays.fill(chars, 0, last, ' ');
return new String(chars);
}
#include<iostream>
#include<conio.h>
#include<string.h>
using namespace std;
void swap(char str[],int i,int j)
{
char temp=str[i];
str[i]=str[j];
str[j]=temp;
}
int main()
{
char str[60];
cout<<"Enter string:";
gets(str);
int len=strlen(str);
int j=len-1;
for(int i=len-1;i>=0;i--)
{
if(str[i]!='_')
{
swap(str,i,j);
j--;
}
}
puts(str);
getch();
return 0;
}
void inlineSpacesMove(char* str, int len, int currLen, int* numSpaces) {
if (*str == '\0')
return;
inlineSpacesMove(str + 1, len, --currLen, numSpaces);
printf("%s\n", str);
if ((currLen + (*numSpaces)) == len) {
*(str) = ' ';
(*numSpaces)--;
} else {
if (*(str - *numSpaces) == ' ')
(*numSpaces)++;
if (*numSpaces > 0 && currLen + (*numSpaces) != len) {
printf("%c \n", *str);
*str = *(str - (*numSpaces));
}
}
}
int main() {
char *str = malloc(500);
int numSpaces = 0;
fgets(str, 500, stdin);
/* Remove trailing newline, if there. */
if ((strlen(str) > 0) && (str[strlen(str) - 1] == '\n'))
str[strlen(str) - 1] = '\0';
printf("%s ", str);
inlineSpacesMove(str, strlen(str), strlen(str), &numSpaces);
printf("%s ", str);
free(str);
return 0;
}
I think its possible in one single pass.
public static void Move()
{
var input = "ab cd e".ToCharArray();
Console.WriteLine(input);
int count = 0;
for (int i = input.Length - 1; i >= 0; i--)
{
if (count != 0 && input[i] != ' ')
{
input[i + count] = input[i];
}
if (input[i] == ' ')
{
count++;
}
}
if (count > 0)
{
for (int j = 0; j < count; j++)
{
input[j] = ' ';
}
}
Console.WriteLine(input);
}
}
#include<stdio.h>
#include<string.h>
int main()
{
char *name = new char(100);
char* name2=new char(100);
int n=0, i=0, spaceC=0, j=0;
strcpy(name, "This is my string");
for(j=i=strlen(name);i>=0;i--,j--){
if(name[i]==' ')
{
i--;
name2[j]=name[i];
name2[spaceC]=' ';
spaceC=spaceC+1;
}
else
name2[j]=name[i];
}
printf("\nthe entered string is '%s'\n", name2);
return 0;
}
#include <stdio.h>
#include <string.h>
main()
{
char a[500] = " i s th i s ev enpos si b l e ";
printf ("%s\n", a);
int i;
int j;
i = j = strlen(a) - 1;
while(i)
{
if ((a[j] >= 'a' && a[j] <= 'z') && ( --i && --j ))
;
else if ( (a[i] == ' ') && --i)
;
else if (( a[i] >= 'a' && a[i] <= 'z' ))
{
a[j] = a[i];
a[i] = ' ';
--i;
--j;
}
}
printf ("%s\n", a);
return 0;
}
I implemented in java, Its very simple.
public static final char S = '-';
public static String moveSpaceToFirst(String data) {
char[] values = data.toCharArray();
int i = values.length-1;
int c = values.length-1;
while(i>= 0){
if(values[i] != S) {
values[c] = values[i];
if(i!=c) values[i]=S;
c--;
}
i--;
}
return new String(values);
}
Implemented in java, its simple.
public static final char S = '-';
public static String moveSpaceToFirst(String data) {
char[] values = data.toCharArray();
int i = values.length-1;
int c = values.length-1;
while(i>= 0){
if(values[i] != S) {
values[c] = values[i];
if(i!=c) values[i]=S;
c--;
}
i--;
}
return new String(values);
}
public static void MoveSpacesToFront(ref char[] input)
{
int lastSpace = -1;
for (int i = input.Length - 1; i >= 0; i--)
{
if (input[i] == ' ')
{
lastSpace = Math.Max(lastSpace, i);
}
else if (lastSpace != -1)
{
Swap(input, i, lastSpace);
lastSpace--;
}
}
}
private static void Swap(char[] input, int i, int j)
{
char temp = input[i];
input[i] = input[j];
input[j] = temp;
}
#include "stdafx.h"
#include <string.h>
int _tmain(int argc, _TCHAR* argv[])
{
//char str[] = {'a',' ','b','c',' ','d'};
char str[] = "H i t h e re! Is t hi s ev en p o s sib le?";
int j=-1;
for(int i= strlen(str) - 1;i>=0;i--)
{
if(str[i] == ' ' && j==-1)
{
j=i;
continue;
}
if(str[i]!=' ' && j!=-1)
{
str[j] = str[i];
str[i] = ' ';
j--;
}
}
printf("%s\n",str);
return 0;
}
This is my resolution, and it takes only one iteration.
#include<string>
#include<iostream>
using namespace std;
void moveSpaceToStart(char* pStr) {
int length = strlen(pStr);
int count = length - 1;
int i = length - 1;
while (i >= 0) {
if (' ' != pStr[i])
pStr[count--] = pStr[i];
i--;
}
while (count >= 0) {
pStr[count--] = ' ';
}
}
int main(int argc, char* argv[]) {
char str[] = "this is a test.";
moveSpaceToStart(str);
cout << str << endl;
cin.get();
return 0;
}
My solution below works well. Not sure if it is qualified for 'one iteration' here as I have a small while loop inside a while loop. However when there are plenty of spaces the small while loop would take trivial time as it marks position to start searching for next non-space character each time.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[]=" Hello I am";
printf("Input: %s\n",str);
char *end = str + strlen(str)-1;
char *next_non_space = NULL;
while(end>=str)
{
if(*end==' ')
{
//Find the next non-space character j from the left substring and move it to end, then set j to space
char *j;
if(next_non_space!=NULL)
{
j = next_non_space;
}
else
{
j = end;
}
while(j>str)
{
j--;
if(*j!= ' ')
{
next_non_space = j; // We found the next non space character at j, next time when we search the 'next' next non space character, we should start from j (j is input but it actually starts at (j-1) in the program)
*end = *j;
*j= ' ';
break;
}
}
}
end--;
}
printf("Output: %s\n",str);
}
My solution below works efficiently. Although I am not sure if it's qualified for 'one iteration' as I have a small while loop inside a while loop. However the small while loop would take trivial time if there are plenty of spaces as it marks the next position to start searching for next non-space character.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char str[]=" Hello I am";
printf("Input: %s\n",str);
char *end = str + strlen(str)-1;
char *next_non_space = NULL;
while(end>=str)
{
if(*end==' ')
{
//Find the next non-space character j from the left substring and move it to end, then set j to space
char *j;
if(next_non_space!=NULL)
{
j = next_non_space;
}
else
{
j = end;
}
while(j>str)
{
j--;
if(*j!= ' ')
{
next_non_space = j; // We found the next non space character at j, next time when we search the 'next' next non space character, we should start from j (j is input but it actually starts at (j-1) in the program)
*end = *j;
*j= ' ';
break;
}
}
}
end--;
}
printf("Output: %s\n",str);
}
#include <iostream>
using namespace std;
void MoveSpaces(string* line){
string input=*line;
int count=input.length();
int pos1=0,pos2=input.length();
char* charAry=new char[input.length()];
strcpy(charAry,input.c_str());
char* charAry2=new char[input.length()];
string space,non_space;
while(count >= 0){
if(charAry[count] == ' '){
space=charAry[count]+space;
}else{
non_space=charAry[count]+non_space;
}
count--;
}
*line=string(space+non_space);
}
int main(){
string input="H i T h e r e!";
MoveSpaces(&input);
cout << " After function iz : " << input << endl;
}
Just use two pointers as explained by Dumbo and replace in the below program '_' with ' '.
'_' is used to see the output clearly.
#include <stdio.h>
void swap(char *s, char *d, int s_c, int d_c){
char temp = s[s_c];
s[s_c] = d[d_c];
d[d_c] = temp;
}
int main()
{
char string[] = {"__algor__rith_m_"};
char *s_p, *d_p; /* s_p is space pointer pointing to space */
/*d_p is data pointer pointing to any non-space */
int i, s_p_c, d_p_c;
/*s_p_c points to the space character which we are working on currently */
/*d_p_c points to the non-space character which we are working on currently */
s_p = string;
d_p = string;
s_p_c = strlen(string)-1;
d_p_c = strlen(string)-1;
while(s_p_c>=0 && d_p_c>=0){
while(s_p_c >= 0 && s_p[s_p_c] != '_'){
s_p_c--;
}
if(s_p_c <= 0)
goto end;
d_p_c = s_p_c-1;
while(d_p[d_p_c] == '_'){
d_p_c--;
}
if(d_p_c <= 0)
goto end;
swap(s_p, d_p, s_p_c, d_p_c);
s_p_c--;
d_p_c--;
}
end:
printf("%s\n", string);
}
#include<stdio.h>
#include<string.h>
int main()
{
char *name = new char(100);
char* name2=new char(100);
int n=0, i=0, spaceC=0, j=0;
strcpy(name, "This is my string");
for(j=i=strlen(name);i>=0;i--,j--){
if(name[i]==' ')
{
i--;
name2[j]=name[i];
name2[spaceC]=' ';
spaceC=spaceC+1;
}
else
name2[j]=name[i];
}
printf("\nthe entered string is '%s'\n", name2);
return 0;
}
void movespace(char str[])
{
int i=0,j=0;
while(str[i]!='\0')
{
if(str[i]!=' ')
++i;
else
{
swap(str[i],str[j]);
++j;
}
}
cout<<str;
}
static void Main()
{
string inputString = "H i t h e re! Is t hi s ev en p o s sib le?";
char[] chars = inputString.ToCharArray();
for (int i = chars.Length - 1; i > 0; i--)
{
while (chars[i] != ' ')
{
i--;
}
int j = i;
while (chars[j] == ' ' && j > 0)
{
j--;
}
chars[i] = chars[j];
chars[j] = ' ';
}
foreach (char c in chars)
Console.Write(c);
Console.ReadKey();
}
void moveSpace(char *str)
{
char *sp_a,*sp_b;
int bFlag = 0;
int walker=0;
int spaceCount = 0;
char c;
sp_a = str;
while(*sp_a)
{
sp_a++;
}
walker=sp_a-str;
if (walker <= 1) return ;
printf("%d",walker);
--sp_a;
while(walker--)
{
if(*sp_a == ' ')
{
if (!spaceCount)
{
sp_b = sp_a;
}
spaceCount++;
sp_a--;
continue;
}
if (spaceCount)
{
c = *sp_a;
sp_b[0] = c;
sp_b--;
}
sp_a--;
}
sp_a++;
sp_b++;
while(sp_a<sp_b)
{
*sp_a = ' ';
sp_a++;
}
}
int main()
{
char str[200];
gets(str);
moveSpace(str);
printf("String ------------>%s<----------------",str);
return 0;
}
This can be done but with recursion.
I hope doing it recursion will count it as one iteration :)
I have used _ in place of space( ) for clarity.
Point me out for any wrong assumptions.
#include "stdio.h"
#include "string.h"
void swap (char *a, char*b)
{
char t;
t = *a;
*a = *b;
*b = t;
}
void moveSpace (char *str, char **lastSpace)
{
if (*str == '\0')
{
return;
}
moveSpace(str+1, lastSpace);
if (*lastSpace != NULL)
{
if (*str != '_')
{
swap (str, *lastSpace);
(*lastSpace)--;
}
}
if (*lastSpace == NULL)
{
if (*str == '_')
*lastSpace = str;
}
}
void printResult (char *tar, const char *src)
{
char *last = NULL;
strcpy (tar, src);
printf ("Original String: \"%s\"\n", tar);
moveSpace (tar, &last);
printf ("New String: \"%s\"\n\n", tar);
}
int main ()
{
char str[20] = {0};
printResult (str, "abc_dce__fg__");
printResult (str, "abc_dce_fg");
}
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str=" this is me, baby^^";
cout<<str<<endl;
int head=0;
for(int i=0; i!=sizeof(str);++i)
{
if (str[i]==' ')
{
for(int j=i;j>0;--j)
{
str[j]=str[j-1];
}
str[head]=' ';
}
}
cout<<str;
return 0;
}
Yes, possible. Start two pointers i & j from the end of the string.
- Murali Mohan June 14, 2013a. Keep copying the character from ith location to the jth location and decrement both i & j
b. When i encounters a space, decrement i, but not j
c Repeat steps a & b until i falls of the beginning of the string.
d. Keep setting 'space' character at jth location and decrement j unitl j falls of the beginning of the string