Search code examples
javastringencryptioncaesar-cipher

last character not rotating correctly


I've written a code for Caesar cipher where 1st input is length of string without any spaces, 2nd input is string to be rotated & 3rd is key by which to rotate. My code is working except the last character of string. For that some strange character is coming instead of an alphabet. Please help!!!..I'm at my wits end..just can't figure out! Below is the code:-

    import java.io.*;
    import java.util.*;
    public class Solution {
    public static void main(String[] args) {
    int length,rotate,i,x;
    Scanner scan=new Scanner(System.in);
    String s;
    length=scan.nextInt();
    s=scan.next();
    rotate=scan.nextInt();
    char c[]=s.toCharArray();
    for(i=0;i<length;i++) {
    x=c[i];
    if(((x>65)||(x==65))&&((x==90)||(x<90))) {
    x=x+rotate;
    if(x>90)
    x=x-90;
    }
    else if(((x>97)||(x==97))&&((x==122)||(x<122))) {
    x=x+rotate;
    if(x>122)
    x=x-122;
    }
    c[i]=(char)x;
    }
    System.out.println();
    for(i=0;i<length;i++) 
    System.out.print(c[i]);
    }
    }

input is:-

    11
    middle-Outz
    2

output should be:-

    okffng-Qwvb

but instead my output is coming as:-

    okffng-Qwv

please help!!! please...someone tell whats the mistake in my code!


Solution

  • You don't currently have any logic to handle the case where a letter wraps around to the start of the alphabet if the rotation shift exceed a certain threahhold. Your logic should be to add to the base value (i.e. first letter) the remainder of the initial shift plus the rotation amount divided by the size of the alphabet. Something like this:

    public static void main(String[] args) {
        int length, rotate, i, x;
        Scanner scan = new Scanner(System.in);
        String s;
        // don't input the length of the array, let it tell you what its length is
        //length = Integer.parseInt(scan.nextLine());
        s = scan.nextLine();
        // make sure you really enter a pure integer here, to avoid a crash
        rotate = Integer.parseInt(scan.nextLine());
        char c[] = s.toCharArray();
        for (i=0; i < c.length; i++) {
            x = c[i];
            int base;
            if (x >= 65 && x <= 90) {
                base = 65;
            }
            else if (x >= 97 && x <= 122) {
                base = 97;
            }
            else {
                continue;
            }
            int diff = x - base;
            x = base + (rotate + diff) % 26;
            c[i] = (char)x;
        }
        System.out.println();
        for (i=0; i < c.length; i++) 
            System.out.print(c[i]);
    }
    

    Note that I chose to not modify a character which is not either a lowercase or uppercase English letter. In case of other characters, they would not be rotated.

    Follow the link below for a demo which shows that the input middle-Outz is correctly being transformed to okffng-Qwvb.

    Rextester

    Update:

    As you correctly pointed out, you also had some problems with your Scanner logic. A safe pattern to use it to always read everything in a string line, and then parse/format the input as appropriate. The input mismatch exception you were getting was probably due to incorrect use of the scanner.