Reputation: 57
I am working on a project and the problem asks me to switch specific letters in an array. For example, a goes to z, b to y, c to x etc...
I wrote this:
import java.util.Scanner;
public class Project1
{
public static void main( String [] args )
{
System.out.println("This program helps to encode or decode some text, the concept is that an A turns into a Z, B into a Y etc.");
Scanner reader = new Scanner ( System.in );
System.out.print("What is your message (encoded or not): ");
String Sentence = reader.nextLine();
System.out.println();
System.out.print("Press 1 to encode and 2 to decode: ");
int Number = reader.nextInt();
if ( Number == 1)
{
Encode (Sentence);
}
else if ( Number == 2)
{
Decode (Sentence);
}
else
{
System.out.println("The number has to be 1 or 2.");
}
}
public static void Encode (String a)
{
a = a.replace( 'a' , 'z' );
a = a.replace( 'b' , 'y' );
a = a.replace( 'c' , 'x' );
a = a.replace( 'd' , 'w' );
a = a.replace( 'e' , 'v' );
a = a.replace( 'f' , 'u' );
a = a.replace( 'g' , 't' );
a = a.replace( 'h' , 's' );
a = a.replace( 'i' , 'r' );
a = a.replace( 'j' , 'q' );
a = a.replace( 'k' , 'p' );
a = a.replace( 'l' , 'o' );
a = a.replace( 'm' , 'n' );
a = a.replace( 'n' , 'm' );
a = a.replace( 'o' , 'l' );
a = a.replace( 'p' , 'k' );
a = a.replace( 'q' , 'j' );
a = a.replace( 'r' , 'i' );
a = a.replace( 's' , 'h' );
a = a.replace( 't' , 'g' );
a = a.replace( 'u' , 'f' );
a = a.replace( 'v' , 'e' );
a = a.replace( 'w' , 'd' );
a = a.replace( 'x' , 'c' );
a = a.replace( 'y' , 'b' );
a = a.replace( 'z' , 'a' );
System.out.println("Encoded message is: " + a);
}
public static void Decode ( String s)
{
s = s.replace( 'z' , 'a' );
s = s.replace( 'y' , 'b' );
System.out.println("Decoded message is: " + s);
}
}
However, when I put in a word with an a it is turned into a z and then back into and a again. I was wondering if there was any other way to switch from one letter to another like this so that the problem does not happen again.
Upvotes: 4
Views: 1080
Reputation: 243
This probably not the best solution but at least there is no duplication.
public static String encode(String input) {
char [] listChar = input.toCharArray();
for(int i = 0; i <listChar.length; i++) {
switch(listChar[i]) {
case 'a' : listChar[i] = 'z';
break;
/** ToDo */
}
}
input = String.valueOf(listChar);
return input;
}
Upvotes: 0
Reputation: 201439
You don't need the various tables you are currently using, instead you can calculate the correct offset as an integral value from the character 'a' when you encode/decode. And, it's easier to test if you return the value you have encoded/decoded. So use a StringBuilder
(it's mutable, unlike String
). Like,
public static String encode(String s) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length(); i++) {
char ch = sb.charAt(i);
int d = ch - 'a';
sb.setCharAt(i, (char) ('z' - d));
}
return sb.toString();
}
public static String decode(String s) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length(); i++) {
char ch = sb.charAt(i);
int d = ch - 'a';
sb.setCharAt(i, (char) ('z' - d));
}
return sb.toString();
}
And then to test it
String e = encode("hello");
System.out.printf("%s = %s%n", e, decode(e));
I get
svool = hello
Upvotes: 0
Reputation: 79828
I think the easiest way is to iterate through your String
, changing each character individually. It may be easiest to do this in a char[]
, which you can convert back into a String
at the end.
Also, you don't need separate encode
and decode
methods, since encoding and decoding a String
is exactly the same transformation.
public String encode(String toEncode) {
char[] characters = toEncode.toCharArray();
for (int index = 0; index < characters.length; index++) {
if (characters[index] >= 'a' && characters[index] <= 'z') {
characters[index] = (char)('a' + 'z' - characters[index]);
}
}
return new String(characters);
}
Notice the char
arithmetic in the middle there, which will translate a
to z
, b
to y
and so on. The if
condition ensures that you don't replace any characters that aren't lower case letters.
Upvotes: 7
Reputation: 11100
So the trouble is that that if you run the replaces one at a time you end up replacing the results of the previous edits with subsequent changes. I would recommend traversing the string and swapping our each character as needed.
import java.util.HashMap;
public char hotSwap(char c){
Map<Character, Character> swaps = new HashMap<Character, Character>();
// add all the chars to the map...
if(swaps.containsKey(c)){
return(swaps.get(c));
}else{
return(c);
}
}
String myString = "what ever the string needs to be...";
for(int k = 0 ; k < myString.length; k++){
myString.setCharAt(k, hotSwap(myString.charAt(k));
}
Upvotes: 0
Reputation: 86232
Convert the string to a char
array or a StringBuilder
. Iterate over the chars. For each char, perform the necessary substitution, then proceed to the next char. In this way you are sure that no substitution is substituted back to what it originally was.
Upvotes: 4