How to replace odd/even chars in string with spaces in Java? - java

If given a string like "go to med!" how do I replace just the even characters for example? The problem is that while my code takes care of the first word, the space between the words counts as a character itself and messes up replacements in the second word with the first letter of the second word becoming classified as even.
Here is my attempt
public static void main(String[] args) {
String s = "go to med!";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(s);
for(int i=0; i<s.length(); i++){
char currChar = s.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1)
if (i%2==1)
{
sb.setCharAt(i, '*');
}
}
System.out.println(sb);
}
This gives output "g+ +o m+d!"
(second letter being correctly replaced by + for being even, but the first letter of the second word should not be replaced as "first" is not "even".
How to make the index to ignore white spaces?
Preferably the answer should not contain arrays, only Char and String methods.

You could simply split the input on the space and process each work individually. You could then use a StringJoiner to piece together the result, for example...
String s = "go to med!!";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
String[] words = s.split(" ");
StringJoiner sj = new StringJoiner(" ");
for (String word : words) {
StringBuilder sb = new StringBuilder(word);
for (int i = 0; i < sb.length(); i++) {
char currChar = sb.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1) {
if (i % 2 == 1) {
sb.setCharAt(i, '*');
}
}
}
sj.add(sb.toString());
}
System.out.println(sj.toString());
which outputs
g* t* m*d!!
could this be done without using arrays - just with char and string methods?
Instead of relying on i, you need a separate counter, which tracks which point your up to and which can be used to ignore invalid characters, for example
String s = "go to med!!";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(s);
int counter = 0;
for (int i = 0; i < sb.length(); i++) {
char currChar = sb.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1) {
if (counter % 2 == 1) {
System.out.println("!!");
sb.setCharAt(i, '*');
}
counter++;
}
}
System.out.println(sb.toString());
which still outputs
g* t* m*d!!

this gives: g* t* m*d*
public static void main(String[] args) {
String s = "go to med!";
int realindex=0;
StringBuilder sb = new StringBuilder();
for(int i=0; i<s.length(); i++){
char currChar = s.charAt(i);
if ((currChar != ' '))
{
if (realindex%2==1) {
currChar = '*';
}
realindex++;
}
sb.append(currChar);
}
System.out.println(sb.toString());
}

There are a thousand different ways to accomplish your goal, but assuming you want to keep using your solution, here is what you could do
public static void main(String[] args) {
String s = "go to med!! goodbye cruel world";
String alphabetS = "abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(s);
for (int i = 0,relativePosition=0; i < s.length(); i++,relativePosition++) {
char currChar = s.charAt(i);
if(currChar == ' '){relativePosition=-1;continue;}
int idx = alphabetS.indexOf(currChar);
if (idx != -1)
if (relativePosition % 2 == 1)
sb.setCharAt(i, '*');
}
System.out.println(sb);
}
that prints
g* t* m*d!! g*o*b*e c*u*l w*r*d

What about introducing flag about even state of letter?
boolean isEven=false;
for(int i=0; i<s.length(); i++){
char currChar = s.charAt(i);
int idx = alphabetS.indexOf(currChar);
if (idx != -1)
if(isEven){
isEven=false;
sb.setCharAt(i, '*');
}else {
isEven = true;
}
}
}

Related

A simple decryption in Java

I am writing a method to decrypt a input string. The encryption is straight forward. Any repeating character in the string is replaced by the character followed by the number of times it appears in the string. So, hello is encrypted as hel2o. Below is the decryption logic I have so far. It works but is so imperative and involves multiple loops. How can this be improved?
String input = "hel2o";
String[] inarr = input.split("\\s+");
StringBuilder sb = new StringBuilder();
for(int i = 0; i < inarr.length; i++) {
String s = inarr[i];
char[] c = s.toCharArray();
for(int j = 0; j < c.length; j++) {
if(Character.isDigit(c[j])) {
for(int x = 0; x < Character.getNumericValue(c[j])-1; x++) {
sb.append(c[j-1]);
}
} else {
sb.append(c[j]);
}
}
}
System.out.printl(sb.toString());
You pretty much asked for a solution but I had fun doing it so I'll share.
You can do it with one loop, by doing some clever appending. Also, unlike yours, my solution will work with multi digit numbers e.g.
Hel23o will convert to helllllllllllllllllllllllo with 23 l's.
String input = "hel23o";
StringBuilder builder = new StringBuilder();
char previousChar = ' ';
StringBuilder number = new StringBuilder();
for (char c : input.toCharArray()) {
if (Character.isDigit(c)) {
number.append(c);
continue;
}
if (number.length() > 0 ) {
int count = Integer.parseInt(number.toString());
count = count > 1 ? count - 1 : 0;
builder.append(String.join("", Collections.nCopies(count, String.valueOf(previousChar))));
}
builder.append(c);
previousChar = c;
number.setLength(0);
}
Alternatively without the multi digit number support:
String input = "hel3o";
StringBuilder builder = new StringBuilder();
char previousChar = ' ';
for (char c : input.toCharArray()) {
if (Character.isDigit(c)) {
builder.append(String.join("", Collections.nCopies(Character.getNumericValue(c) - 1, String.valueOf(previousChar))));
continue;
}
builder.append(c);
previousChar = c;
}

why does this method take off the last letter in the string?

This is part of a java project, we have to take in a sentence that has multiple spaces between the world (a sentence like this) and convert it into a character array, then print out the sentence without all the extra spaces. It works, but it prints out the sentence missing the last letter.
Sentence Class:
public class sentences {
String sentence;
int length;
private char[] ch;
public sentences(String sentence, int length) {
this.sentence = sentence;
this.length = length;
char [] ch;
}
/**method that takes a string and turns it into an array then prints out the array
* makes an empty string and fills it with the char, takes out empty spaces
*
*/
public char[] makesentenceanarray(String sentence, int length) {
char[] ch = new char[sentence.length()];
//String noWhite = "";
StringBuilder s = new StringBuilder();
char prevchar = ' ';
for (int i = 0; i < sentence.length(); i++) {
ch[i] = sentence.charAt(i);
}
for(int j = 0; j < sentence.length(); j++) {
char currentchar = ch[j];
if( !(prevchar == ' ' && currentchar == prevchar)) {
s.append(prevchar);
}
prevchar = currentchar;
}
s.deleteCharAt(0);
System.out.println(ch);
System.out.print(s);
return ch;
}
}
Tester class:
import java.util.Scanner;
public class tester {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
System.out.print("enter your sentence: ");
String a = scan.nextLine();
sentences s1 = new sentences(a, a.length());
s1.makesentenceanarray(a, a.length());
}
}
********************************************************************************
heres what I end up with:
enter your sentence: this is my sentence
this is my sentence
this is my sentenc
any help is appreciated thanks!
After the loop, append prevchar. Also, use StringBuilder.
You’re appending the previous character. Think instead about the circumstances under which you would append the current character. In you loop you will look at every current character, but for the very last character, the previous will be the second to last character and then the loop stops. Make sense?
sentence.length() starts counting at 1. (Yes I know it's inconsistent :D)Therefore you need to start counting at 1 and compare with <= at the first for loop.
public char[] makesentenceanarray(String sentence, int length) {
char[] ch = new char[sentence.length()];
//String noWhite = "";
StringBuilder s = new StringBuilder();
char prevchar = ' ';
for (int i = 1; i <= sentence.length(); i++) {
//you should do this now bc of the change of the for loop:
//ch[i - 1] = sentence.charAt(i - 1);
ch[i] = sentence.charAt(i);
}
for(int j = 0; j < sentence.length(); j++) {
char currentchar = ch[j];
if( !(prevchar == ' ' && currentchar == prevchar)) {
s.append(prevchar);
}
prevchar = currentchar;
}
//Now you should be able to delete this
//s.deleteCharAt(0);
System.out.println(ch);
System.out.print(s);
return ch;
}
}

How to make alternate characters in a string to uppercase?

I wrote the following code but similar characters are always in the same case. What's wrong in this code and How can this problem be solved??
private void genBTActionPerformed(java.awt.event.ActionEvent evt) {
String str = new String(strTF.getText());
int n = str.length();
char ch;
int i;
for(i = 0; i < n; i++) {
if(i % 2 == 0) {
ch = Character.toLowerCase(str.charAt(i));
str = str.replace(str.charAt(i), ch);
} else {
ch = Character.toUpperCase(str.charAt(i));
str = str.replace(str.charAt(i), ch);
}
}
jumTF.setText(str);
}
Unlike what its name says, .replace() replaces characters/CharSequences in the whole input. The difference with .replaceAll() is that it takes literals as arguments and not regexes/regex replacements strings (and that it has an overload taking two chars as arguments). That is the second worst misnamed method of the String class after matches().
Moreover you create a new String on each character you replace, so you have n+1 strings for a n character long string. Do it like this instead:
final char[] chars = str.toCharArray();
final int len = chars.length;
char c;
for (int i = 0; i < len; i++) {
c = chars[i];
chars[i] = i % 2 == 0
? Character.toLowerCase(c)
: Character.toUpperCase(c);
}
jumTF.setText(new String(chars));
In your program you were using replace() which replaces characters/CharSequences in the whole input what you need to do is
Put the string into an array.
Iterate over said array.
convert that array back into string
private void genBTActionPerformed(java.awt.event.ActionEvent evt) {
String str = new String(strTF.getText());
char [] chr= str.toCharArray();
int n = chr.length;
char ch;
int i;
for(i = 0; i < n; i++) {
if(i % 2 == 0) {
ch = Character.toLowerCase(chr[i]);
chr[i]=ch;
} else {
ch = Character.toUpperCase(chr[i]);
chr[i]=ch;
}
}
jumTF.setText(new String(chr)); }
hope this will help you :)
Since String are immutable in java , you can use StringBuilder or StringBuffer to solve this problem
StringBuilder str=new StringBuilder(inputString);
You can use your own logic just with slight change instead of using
str = str.replace(str.charAt(i), ch);//since it replaces in whole string
Use
str.setCharAt(i,ch);
So your final Program looks like this :
for(i = 0; i < n; i++) {
if(i % 2 == 0) {
ch = Character.toLowerCase(str.charAt(i));
str.setCharAt(i,ch);
} else {
ch = Character.toUpperCase(str.charAt(i));
str.setCharAt(i,ch);
}
}
Suppose InputString is : stackoverflow
then output is : sTaCkOvErFlOw

Splitting string into an array

I am attempting to split the components of a string into an array, so that they can be accessed more easily.
For example: 4+5= should become ['4','+','5','='].
Edit: -
I would need consecutive numbers to be joined together, and whitespaces can be ignored. Thanks again!
You can solve it with regex lookaround mechanism.
String str = "10 * 10 - 40 + 100/2 = 110";
//but first lets remove white spaces (it will makes regex easier)
String strWithoutSpaces=str.replaceAll("\\s+", "");
String[] tokens = strWithoutSpaces.split("(?<=[-+*/=])|(?=[-+*/=])");
for (String t:tokens)
System.out.print(t+",");
Output:
10,*,10,-,40,+,100,/,2,=,110,
You can use
String str = "4+5=";
String[] tokens = str.split("(?!^)");
for (String s : tokens) {
System.out.println(s);
}
This will output
4
+
5
=
You could use toCharArray() method
String s ="4+5=";
char [] stArr = s.toCharArray();
for(char ss: stArr){
System.out.println(ss);
}
Out put
4
+
5
=
You could do something like this:
public static void main(String args[]) {
String str = "45+5-26";
String strArr[] = new String[str.length()];
StringBuffer sb = new StringBuffer();
int cnt = 0;
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if (ch != '\0') {
if (ch == ' ') {
continue;
}
if (ch >= 48 && ch <= 57) {
sb.append(ch);
continue;
} else {
strArr[cnt++] = sb.toString();
sb = new StringBuffer();
// sb.append(ch);
}
strArr[cnt++] = ch + "";
sb = new StringBuffer();
}
}
strArr[cnt++] = sb.toString();
sb = new StringBuffer();
System.out.println("strArray: ");
for (int i = 0; i < strArr.length; i++) {
if (strArr[i] == null)
break;
System.out.println(strArr[i]);
}
}
If you have only operators as the separator between the numbers this would be more easy to get the string tokens.
You can modify as below if you want the tokens separated by a comma:
for (int i = 0; i < strArr.length; i++) {
if (strArr[i] == null)
break;
// System.out.println(strArr[i]);
if(i!=0)
sbResult.append(",");
sbResult.append(strArr[i]);
}
System.out.println("sbResult: "+sbResult.toString());

Write a method to replace all spaces in a string with '%20'

I have a question about a programming problem from the book Cracking The Code Interview by Gayl Laakmann McDowell, 5th Edition.
The problem states: Write a method to replace all spaces in a string with '%20'. Assume string has sufficient space at end of string to hold additional characters, and that you're given a true length of a string. I used the books code, implementing the solution in Java using a character array (given the fact that Java Strings are immutable):
public class Test {
public void replaceSpaces(char[] str, int length) {
int spaceCount = 0, newLength = 0, i = 0;
for(i = 0; i < length; i++) {
if (str[i] == ' ')
spaceCount++;
}
newLength = length + (spaceCount * 2);
str[newLength] = '\0';
for(i = length - 1; i >= 0; i--) {
if (str[i] == ' ') {
str[newLength - 1] = '0';
str[newLength - 2] = '2';
str[newLength - 3] = '%';
newLength = newLength - 3;
}
else {
str[newLength - 1] = str[i];
newLength = newLength - 1;
}
}
System.out.println(str);
}
public static void main(String[] args) {
Test tst = new Test();
char[] ch = {'t', 'h', 'e', ' ', 'd', 'o', 'g', ' ', ' ', ' ', ' ', ' ', ' '};
int length = 6;
tst.replaceSpaces(ch, length);
}
}
The output I am getting from the replaceSpaces() call is: the%20do which is cutting of the last character of the original array. I have been scratching my head over this, can anyone explain to me why the algorithm is doing this?
public String replace(String str) {
String[] words = str.split(" ");
StringBuilder sentence = new StringBuilder(words[0]);
for (int i = 1; i < words.length; ++i) {
sentence.append("%20");
sentence.append(words[i]);
}
return sentence.toString();
}
You are passing the length as 6, which is causing this. Pass length as 7 including space.
Other wise
for(i = length - 1; i >= 0; i--) {
will not consider last char.
With these two changes I got the output: the%20dog
1) Change space count to 2 [since length already includes 1 of the 3 characters you need for %20]
newLength = length + (spaceCount * 2);
2) Loop should start on length
for(i = length; i >= 0; i--) {
Here is my solution. I check for the ascii code 32 then put a %20 instead of it.Time complexity of this solution is O(N)
public String replace(String s) {
char arr[] = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 32)
sb.append("%20");
else
sb.append(arr[i]);
}
return sb.toString();
}
This is my code for this question. Seems like working for me. If you're interested, please have a look. It's written in JAVA
public class ReplaceSpaceInString {
private static char[] replaceSpaceInString(char[] str, int length) {
int spaceCounter = 0;
//First lets calculate number of spaces
for (int i = 0; i < length; i++) {
if (str[i] == ' ')
spaceCounter++;
}
//calculate new size
int newLength = length + 2*spaceCounter;
char[] newArray = new char[newLength+1];
newArray[newLength] = '\0';
int newArrayPosition = 0;
for (int i = 0; i < length; i++) {
if (str[i] == ' ') {
newArray[newArrayPosition] = '%';
newArray[newArrayPosition+1] = '2';
newArray[newArrayPosition+2] = '0';
newArrayPosition = newArrayPosition + 3;
}
else {
newArray[newArrayPosition] = str[i];
newArrayPosition++;
}
}
return newArray;
}
public static void main(String[] args) {
char[] array = {'a','b','c','d',' ','e','f','g',' ','h',' ','j'};
System.out.println(replaceSpaceInString(array, array.length));
}
}
You can also use substring method and the ascii for space (32).
public String replaceSpaceInString(String s){
int i;
for (i=0;i<s.length();i++){
System.out.println("i is "+i);
if (s.charAt(i)==(int)32){
s=s.substring(0, i)+"%20"+s.substring(i+1, s.length());
i=i+2;
}
}
return s;
}
To test:
System.out.println(cc.replaceSpaceInString("mon day "));
Output:
mon%20day%20
You could just do this.
No need to calculate the length or whatever.
Strings are immutable anyways.
import java.util.*;
public class ReplaceString {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
String str=in.nextLine();
String n="";
for(int i=0;i<str.length();i++)
{
if(str.charAt(i)==' ')
n=n+"%20";
else
n=n+str.charAt(i);
}
str=n;
System.out.println(str);
}
}
void Rep_Str(char *str)
{
int j=0,count=0;
int stlen = strlen(str);
for (j = 0; j < stlen; j++)
{
if (str[j]==' ')
{
count++;
}
}
int newlength = stlen+(count*2);
str[newlength--]='\0';
for (j = stlen-1; j >=0 ; j--)
{
if (str[j]==' ')
{
str[newlength--]='0';
str[newlength--]='2';
str[newlength--]='%';
}
else
{
str[newlength--]=str[j];
}
}
}
This code works :)
We can use a regular expression to solve this problem. For example:
public String replaceStringWithSpace(String str){
return str.replaceAll("[\\s]", "%20");
}
This works correctly. However, using a StringBuffer object increases space complexity.
Scanner scn = new Scanner(System.in);
String str = scn.nextLine();
StringBuffer sb = new StringBuffer(str.trim());
for(int i = 0;i<sb.length();i++){
if(32 == (int)sb.charAt(i)){
sb.replace(i,i+1, "%20");
}
}
public static String replaceAllSpaces(String s) {
char[] c = s.toCharArray();
int spaceCount = 0;
int trueLen = s.length();
int index = 0;
for (int i = 0; i < trueLen; i++) {
if (c[i] == ' ') {
spaceCount++;
}
}
index = trueLen + spaceCount * 2;
char[] n = new char[index];
for (int i = trueLen - 1; i >= 0; i--) {
if (c[i] == ' ') {
n[index - 1] = '0';
n[index - 2] = '2';
n[index - 3] = '%';
index = index - 3;
} else {
n[index - 1] = c[i];
index--;
}
}
String x = new String(n);
return x;
}
Another way of doing this.
I am assuming the trailing spaces don't need to be converted to %20 and that the trailing spaces provide enough room for %20s to be stuffed in between
public class Main {
public static void main(String[] args) {
String str = "a sd fghj ";
System.out.println(replacement(str));//a%20sd%20fghj
}
private static String replacement(String str) {
char[] chars = str.toCharArray();
int posOfLastChar = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] != ' ') {
posOfLastChar = i;
}
}
int newCharPosition = chars.length - 1;
//Start moving the characters to th end of the array. Replace spaces by %20
for (int i = posOfLastChar; i >= 0; i--) {
if (chars[i] == ' ') {
chars[newCharPosition] = '0';
chars[--newCharPosition] = '2';
chars[--newCharPosition] = '%';
} else {
chars[newCharPosition] = chars[i];
}
newCharPosition--;
}
return String.valueOf(chars);
}
}
public class ReplaceChar{
public static void main(String []args){
String s = "ab c de ";
System.out.println(replaceChar(s));
}
public static String replaceChar(String s){
boolean found = false;
StringBuilder res = new StringBuilder(50);
String str = rev(s);
for(int i = 0; i <str.length(); i++){
if (str.charAt(i) != ' ') { found = true; }
if (str.charAt(i) == ' '&& found == true) { res.append("%02"); }
else{ res.append(str.charAt(i)); }
}
return rev(res.toString());
}
// Function to reverse a string
public static String rev(String s){
StringBuilder result = new StringBuilder(50);
for(int i = s.length()-1; i>=0; i-- ){
result.append(s.charAt(i));
}
return result.toString();
}}
A simple approach:
Reverse the given string and check where the first character appears.
Using string builder to append "02%" for spaces - since the string is reversed.
Finally reverse the string once again.
Note: We reverse the string so as to prevent an addition of "%20" to the trailing spaces.
Hope that helps!
The question in the book mentions that the replacement should be in place so it is not possible to assign extra arrays, it should use constant space. You should also take into account many edge cases, this is my solution:
public class ReplaceSpaces {
public static void main(String[] args) {
if ( args.length == 0 ) {
throw new IllegalArgumentException("No string");
}
String s = args[0];
char[] characters = s.toCharArray();
replaceSpaces(characters);
System.out.println(characters);
}
static void replaceSpaces(char[] s) {
int i = s.length-1;
//Skipping all spaces in the end until setting `i` to non-space character
while( i >= 0 && s[i] == ' ' ) { i--; }
/* Used later to check there is enough extra space in the end */
int extraSpaceLength = s.length - i - 1;
/*
Used when moving the words right,
instead of finding the first non-space character again
*/
int lastNonSpaceCharacter = i;
/*
Hold the number of spaces in the actual string boundaries
*/
int numSpaces = 0;
/*
Counting num spaces beside the extra spaces
*/
while( i >= 0 ) {
if ( s[i] == ' ' ) { numSpaces++; }
i--;
}
if ( numSpaces == 0 ) {
return;
}
/*
Throw exception if there is not enough space
*/
if ( extraSpaceLength < numSpaces*2 ) {
throw new IllegalArgumentException("Not enough extra space");
}
/*
Now we need to move each word right in order to have space for the
ascii representation
*/
int wordEnd = lastNonSpaceCharacter;
int wordsCounter = 0;
int j = wordEnd - 1;
while( j >= 0 ) {
if ( s[j] == ' ' ){
moveWordRight(s, j+1, wordEnd, (numSpaces-wordsCounter)*2);
wordsCounter++;
wordEnd = j;
}
j--;
}
replaceSpacesWithAscii(s, lastNonSpaceCharacter + numSpaces * 2);
}
/*
Replaces each 3 sequential spaces with %20
char[] s - original character array
int maxIndex - used to tell the method what is the last index it should
try to replace, after that is is all extra spaces not required
*/
static void replaceSpacesWithAscii(char[] s, int maxIndex) {
int i = 0;
while ( i <= maxIndex ) {
if ( s[i] == ' ' ) {
s[i] = '%';
s[i+1] = '2';
s[i+2] = '0';
i+=2;
}
i++;
}
}
/*
Move each word in the characters array by x moves
char[] s - original character array
int startIndex - word first character index
int endIndex - word last character index
int moves - number of moves to the right
*/
static void moveWordRight(char[] s, int startIndex, int endIndex, int moves) {
for(int i=endIndex; i>=startIndex; i--) {
s[i+moves] = s[i];
s[i] = ' ';
}
}
}
Any reason not to use 'replace' method?
public String replaceSpaces(String s){
return s.replace(" ", "%20");}
Hm... I am wondering about this problem as well. Considering what I have seen in here. The book solution does not fit Java because it uses in-place
char []
modification and solutions in here that use char [] or return void don't fit as well because Java does not use pointers.
So I was thinking, the obvious solution would be
private static String encodeSpace(String string) {
return string.replcaceAll(" ", "%20");
}
but this is probably not what your interviewer would like to see :)
// make a function that actually does something
private static String encodeSpace(String string) {
//create a new String
String result = new String();
// replacement
final String encodeSpace = "%20";
for(char c : string.toCharArray()) {
if(c == ' ') result+=encodeString;
else result+=c;
}
return result;
}
this looks fine I thought, and you only need one pass through the string, so the complexity should be O(n), right? Wrong! The problem is in
result += c;
which is the same as
result = result + c;
which actually copies a string and creates a copy of it. In java strings are represented as
private final char value[];
which makes them immutable (for more info I would check java.lang.String and how it works). This fact will bump up the complexity of this algorithm to O(N^2) and a sneaky recruiter can use this fact to fail you :P Thus, I came in with a new low-level solution which you will never use in practice, but which is good in theory :)
private static String encodeSpace(String string) {
final char [] original = string != null? string.toCharArray() : new char[0];
// ASCII encoding
final char mod = 37, two = 50, zero = 48, space = 32;
int spaces = 0, index = 0;
// count spaces
for(char c : original) if(c == space) ++spaces;
// if no spaces - we are done
if(spaces == 0) return string;
// make a new char array (each space now takes +2 spots)
char [] result = new char[string.length()+(2*spaces)];
for(char c : original) {
if(c == space) {
result[index] = mod;
result[++index] = two;
result[++index] = zero;
}
else result[index] = c;
++index;
}
return new String(result);
}
But I wonder what is wrong with following code:
private static String urlify(String originalString) {
String newString = "";
if (originalString.contains(" ")) {
newString = originalString.replace(" ", "%20");
}
return newString;
}
Question : Urlify the spaces with %20
Solution 1 :
public class Solution9 {
public static void main(String[] args) {
String a = "Gini Gina Protijayi";
System.out.println( urlencode(a));
}//main
public static String urlencode(String str) {
str = str.trim();
System.out.println("trim =>" + str);
if (!str.contains(" ")) {
return str;
}
char[] ca = str.toCharArray();
int spaces = 0;
for (char c : ca) {
if (c == ' ') {
spaces++;
}
}
char[] newca = new char[ca.length + 2 * spaces];
// a pointer x has been added
for (int i = 0, x = 0; i < ca.length; i++) {
char c = ca[i];
if (c == ' ') {
newca[x] = '%';
newca[x + 1] = '2';
newca[x + 2] = '0';
x += 3;
} else {
newca[x] = c;
x++;
}
}
return new String(newca);
}
}//urlify
My solution using StringBuilder with time complexity O(n)
public static String url(String string, int length) {
char[] arrays = string.toCharArray();
StringBuilder builder = new StringBuilder(length);
for (int i = 0; i < length; i++) {
if (arrays[i] == ' ') {
builder.append("%20");
} else {
builder.append(arrays[i]);
}
}
return builder.toString();
}
Test case :
#Test
public void testUrl() {
assertEquals("Mr%20John%20Smith", URLify.url("Mr John Smith ", 13));
}
Can you use StringBuilder?
public String replaceSpace(String s)
{
StringBuilder answer = new StringBuilder();
for(int i = 0; i<s.length(); i++)
{
if(s.CharAt(i) == ' ')
{
answer.append("%20");
}
else
{
answer.append(s.CharAt(i));
}
}
return answer.toString();
}
I am also looking at that question in the book. I believe we can just use String.trim() and String.replaceAll(" ", "%20) here
I updated the solution here. http://rextester.com/CWAPCV11970
If we are creating new array and not in-place trasition, then why do we need to walk backwards?
I modified the real solution slightly to walk forward to create target Url-encoded-string.
Time complexity:
O(n) - Walking original string
O(1) - Creating target string incrementally
where 'n' is number of chars in original string
Space complexity:
O(n + m) - Duplicate space to store escaped spaces and string.
where 'n' is number of chars in original string and 'm' is length of escaped spaces
public static string ReplaceAll(string originalString, char findWhat, string replaceWith)
{
var newString = string.Empty;
foreach(var character in originalString)
newString += findWhat == character? replaceWith : character + string.Empty;
return newString;
}
class Program
{
static void Main(string[] args)
{
string name = "Stack Over Flow ";
StringBuilder stringBuilder = new StringBuilder();
char[] array = name.ToCharArray(); ;
for(int i = 0; i < name.Length; i++)
{
if (array[i] == ' ')
{
stringBuilder.Append("%20");
}
else
stringBuilder.Append(array[i]);
}
Console.WriteLine(stringBuilder);
Console.ReadLine();
}
}
public class Sol {
public static void main(String[] args) {
String[] str = "Write a method to replace all spaces in a string with".split(" ");
StringBuffer sb = new StringBuffer();
int count = 0;
for(String s : str){
sb.append(s);
if(str.length-1 != count)
sb.append("%20");
++count;
}
System.out.println(sb.toString());
}
}
public class Test {
public static void replace(String str) {
String[] words = str.split(" ");
StringBuilder sentence = new StringBuilder(words[0]);
for (int i = 1; i < words.length; i++) {
sentence.append("%20");
sentence.append(words[i]);
}
sentence.append("%20");
System.out.println(sentence.toString());
}
public static void main(String[] args) {
replace("Hello World "); **<- Hello<3spaces>World<1space>**
}
}
O/P:: Hello%20%20%20World%20
Remember that you only to want replace ' ' with '%20' when the latter is not a leading or trailing space. Several answers above do not account for this. For what it's worth, I get "index out of bounds error" when I run Laakmann's solution example.
Here's my own solution, which runs O(n) and is implemented in C#:
public static string URLreplace(string str, int n)
{
var len = str.Length;
if (len == n)
return str;
var sb = new StringBuilder();
var i = 0;
while (i < len)
{
char c = str[i];
if (c == ' ')
{
while (i < len && str[i] == ' ')
{
i++; //skip ahead
}
}
else
{
if (sb.Length > 0 && str[i - 1] == ' ')
sb.Append("%20" + c);
else
sb.Append(c);
i++;
}
}
return sb.ToString();
}
Test:
//Arrange
private string _str = " Mr John Smith ";
private string _result = "Mr%20John%20Smith";
private int _int = 13;
[TestMethod]
public void URLified()
{
//Act
var cleaned = URLify.URLreplace(_str, _int);
//Assert
Assert.IsTrue(cleaned == _result);
}
One line code
System.out.println(s.trim().replace(" ","%20"));
// while passing the input make sure you use the .toCharArray method becuase strings are immutable
public static void replaceSpaces(char[] str, int length) {
int spaceCount = 0, newLength = 0, i = 0;
for (i = 0; i < length; i++) {
if (str[i] == ' ')
spaceCount++;
}
newLength = length + (spaceCount * 2);
// str[newLength] = '\0';
for (i = length - 1; i >= 0; i--) {
if (str[i] == ' ') {
str[newLength - 1] = '0';
str[newLength - 2] = '2';
str[newLength - 3] = '%';
newLength = newLength - 3;
} else {
str[newLength - 1] = str[i];
newLength = newLength - 1;
}
}
System.out.println(str);
}
public static void main(String[] args) {
// Test tst = new Test();
char[] ch = "Mr John Smith ".toCharArray();
int length = 13;
replaceSpaces(ch, length);
}
`// Maximum length of string after modifications.
const int MAX = 1000;
// Replaces spaces with %20 in-place and returns
// new length of modified string. It returns -1
// if modified string cannot be stored in str[]
int replaceSpaces(char str[])
{
// count spaces and find current length
int space_count = 0, i;
for (i = 0; str[i]; i++)
if (str[i] == ' ')
space_count++;
// Remove trailing spaces
while (str[i-1] == ' ')
{
space_count--;
i--;
}
// Find new length.
int new_length = i + space_count * 2 + 1;
// New length must be smaller than length
// of string provided.
if (new_length > MAX)
return -1;
// Start filling character from end
int index = new_length - 1;
// Fill string termination.
str[index--] = '\0';
// Fill rest of the string from end
for (int j=i-1; j>=0; j--)
{
// inserts %20 in place of space
if (str[j] == ' ')
{
str[index] = '0';
str[index - 1] = '2';
str[index - 2] = '%';
index = index - 3;
}
else
{
str[index] = str[j];
index--;
}
}
return new_length;
}
// Driver code
int main()
{
char str[MAX] = "Mr John Smith ";
// Prints the replaced string
int new_length = replaceSpaces(str);
for (int i=0; i<new_length; i++)
printf("%c", str[i]);
return 0;
}`

Categories