hendrahjh
hendrahjh

Reputation: 3

Replacing a character in a string with another character from another string

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

Answers (3)

user15402945
user15402945

Reputation:

You can use codePoints method to iterate over the characters of this string and replace them with characters from another string, if any.

Try it online!

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

WJS
WJS

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

Kevin Anderson
Kevin Anderson

Reputation: 4592

The reason

sentence.replace(sentence.charAt(i), encode.charAt(indexForEncode));

doesn't work is that Strings 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

Related Questions