I am having a problem regarding wrapping around the alphabet with my Caesar Cipher Program.
The program works fine with all lowercase letters. Wraps around perfectly and is able to apply positive and negative shifts. When i try to input an uppercase letter, the uppercase letter does not wrap around.
Here is my code:
public static StringBuilder encode(String str, int numShift) { numShift = numShift % 26; //assign each character of the string to a position in the character array char[] strChars = str.toCharArray(); for (int i = 0; i < strChars.length; i++) { //ignore and continue if the character is not within the alphabet if((strChars[i] < 'a' || strChars[i] > 'z') && (strChars[i]<'A' || strChars[i] > 'Z')) continue; //apply the shift to each character strChars[i] += numShift; //wrap around if the shift is beyond Z **if(strChars[i] > 'z') { strChars[i] -= 'z'; strChars[i] += ('a' - 1); }** } StringBuilder encodedStr = new StringBuilder(); encodedStr.append(strChars); return encodedStr; } public static void init(){ Scanner scan = new Scanner(System.in); System.out.println("Please enter the string that you would like to encode:"); String str = scan.nextLine(); System.out.println("Please enter the number of letters you would like to shift:"); int strShift = scan.nextInt(); scan.close(); StringBuilder result = encode(str, strShift); System.out.println(result); } public static void main(String[] args) { init(); }
}
Hints would be much appreciated! Of course, I am not asking anyone to do my work for me but some help would be appreciated! Thank you! 🙂
Edit: here’s the if statement that does the wrap around for lowercase letters only:
if(strChars[i] > 'z') { strChars[i] -= 'z'; strChars[i] += ('a' - 1); }
Advertisement
Answer
Let’s implement a wrap-around function for a single character. This will be used by the other method. When you separate your tasks and sub-tasks wisely, you will observe that your problem becomes easier to solve. Here I have based my solution on the fact that char
variables are represented as numbers, we know the number of letters and we can use that number as a modulo class, to make sure that algebra is aiding us.
private static char wrapChar(char input, int amount) { //assume for now that we have an upper-case letter char start = 'A'; //if the assumption is mistaken... if (('a' <= input) && (input <= 'z')) { //then, if it is lower-case, then use lower-case start = 'a'; } else if (!(('A' <= input) && (input <= 'Z'))) { //target is not letter return input; } //Calculate total offset compared to the first letter of the alphabet //be it lower or upper int offset = ((input - start) + amount) % 26; //If offset happens to be negative, then shift a modulo period of 26 //To get the correct positive offset if (offset < 0) { offset += 26; } //Add the final offset to start and convert it to char return ((char)(start + offset)); }
Now, instead of
//apply the shift to each character strChars[i] += numShift; //wrap around if the shift is beyond Z **if(strChars[i] > 'z') { strChars[i] -= 'z'; strChars[i] += ('a' - 1); }**
You need just:
strChars[i] = wrapChar(strChars[i], numShift);