Reputation: 3
I am trying to eventually replace a sentence with another set of String. But I hit a roadblock while trying to replace a char in a String with another character of another String.
Here's what I have so far.
String letters = "abcdefghijklmnopqrstuvwxyz";
String encode = "kngcadsxbvfhjtiumylzqropwe";
// the sentence that I want to encode
String sentence = "hello, nice to meet you!";
//swapping each char of 'sentence' with the chars in 'encode'
for (int i = 0; i < sentence.length(); i++) {
int indexForEncode = letters.indexOf(sentence.charAt(i));
sentence.replace(sentence.charAt(i), encode.charAt(indexForEncode));
}
System.out.println(sentence);
This way of replacing characters doesn't work. Can someone help me?
Upvotes: 0
Views: 819
Reputation:
You can use codePoints
method to iterate over the characters of this string and replace them with characters from another string, if any.
public static void main(String[] args) {
String letters = "abcdefghijklmnopqrstuvwxyz";
String encode = "kngcadsxbvfhjtiumylzqropwe";
String sentence = "hello, nice to meet you!";
String encoded = replaceCharacters(sentence, letters, encode);
String decoded = replaceCharacters(encoded, encode, letters);
System.out.println(encoded); // xahhi, tbga zi jaaz wiq!
System.out.println(decoded); // hello, nice to meet you!
}
public static String replaceCharacters(String text, String from, String to) {
// wrong cipher, return unencrypted string
if (from.length() != to.length()) return text;
// IntStream over the codepoints of this text string
return text.codePoints()
// Stream<Character>
.mapToObj(ch -> (char) ch)
// encrypt characters
.map(ch -> {
// index of this character
int i = from.indexOf(ch);
// if not present, then leave it as it is,
// otherwise replace this character
return i < 0 ? ch : to.charAt(i);
}) // Stream<String>
.map(String::valueOf)
// concatenate into a single string
.collect(Collectors.joining());
}
See also: Implementation of the Caesar cipher
Upvotes: 0
Reputation: 40057
I would use a character array as follows. Make the changes to a character array and then use String.valueOf
to get the new version of the string.
String letters = "abcdefghijklmnopqrstuvwxyz";
String encode = "kngcadsxbvfhjtiumylzqropwe";
// the sentence that I want to encode
String sentence = "hello, nice to meet you!";
char[] chars = sentence.toCharArray();
for (int i = 0; i < chars.length; i++){
int indexForEncode = letters.indexOf(sentence.charAt(i));
// if index is < 0, use original character, otherwise, encode.
chars[i] = indexForEncode < 0 ? chars[i] : encode.charAt(indexForEncode);
}
System.out.println(String.valueOf(chars));
Prints
xahhi, tbga zi jaaz wiq!
Upvotes: 0
Reputation: 4592
The reason
sentence.replace(sentence.charAt(i), encode.charAt(indexForEncode));
doesn't work is that String
s are immutable (i.e., they never change).
So, sentence.replace(...)
doesn't actually change sentence
; rather, it returns a new String
. You would need to write sentence = sentence.replace(...)
to capture that result back in sentence
.
OK, Strings 101: class dismissed (;->).
Now with all that said, you really don't want want to keep reassigning your partially encoded sentence
back to itself, because you will, almost certainly, find yourself re-encoding characters of sentence
that you already encoded. Best to leave sentence
in its original form while building up the encoded string one character at a time like this:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < sentence.length(); i++){
int indexForEncode = letters.indexOf(sentence.charAt(i));
sb.append(indexForEncode != -1
? encode.charAt(indexForEncode)
: sentence.charAt(i)
);
}
sentence = sb.toString();
Upvotes: 4