Alex Cabo
Alex Cabo

Reputation: 39

How do I shift letters down in a loop

I'm trying to create a loop which only returns letters. In my code, I get symbols that I don't want. How do I fix my loop so that when my integer is +3, it only gives me letters?

public static String caesarDecrypt(String encoded, int shift){
    String decrypted = "";

    for (int i = 0; i < encoded.length(); i++) {
        char t = encoded.charAt(i);

        if ((t <= 'a') && (t >= 'z')) {
            t -= shift;
        }

        if (t > 'z') {
            t += 26;
        } else if ((t >= 'A') && (t <= 'Z')) {
            t -= shift;

            if (t > 'Z') 
                t += 26;
        } else {

        }

        decrypted = decrypted + t;
    }
}

Upvotes: 0

Views: 1442

Answers (4)

brimborium
brimborium

Reputation: 9512

As you are naming your method caesarDecrypt (I assume you mean encrypt), I think you want a shift in the alphabet including wrapping around.

This code will do that for you:

public class Snippet {
    public static void main(String[] args) {
        System.out.println(caesarShift("This is a Fizzy test.", 5));
        System.out.println(caesarShift("Ymnx nx f Kneed yjxy.", -5));
    }

    public static String caesarShift(String input, int shift) {
        // making sure that shift is positive so that modulo works correctly
        while (shift < 0)
            shift += 26;

        int l = input.length();
        StringBuffer output = new StringBuffer();

        for (int i = 0; i < l; i++) {
            char c = input.charAt(i);
            char newLetter = c;

            if (c >= 'a' && c <= 'z') { // lowercase
                newLetter = (char) ((c - 'a' + shift) % 26 + 'a'); // shift, wrap it and convert it back to char
            } else if (c >= 'A' && c <= 'Z') { // uppercase
                newLetter = (char) ((c - 'A' + shift) % 26 + 'A'); // shift, wrap it and convert it back to char
            }

            output.append(newLetter);
        }

        return output.toString();
    }
}

This will handle lowercase and uppercase letters. Everything else will be left as it is (like spaces, punctuations, etc).

Please take some time to look at this code to understand how it works. I have put some comments to make it clearer. From your code I think you were a bit confused, so it is important that you understand this code very well. If you have questions, feel free to ask them.


This code

String start = "abcdefghijklmnopqrstuvwxyz";
String encrypted = caesarShift(start, 3);
String decrypted = caesarShift(encrypted, -3);
System.out.println("Start     : " + start);
System.out.println("Encrypted : " + encrypted);
System.out.println("Decrypted : " + decrypted);

will give this result

Start     : abcdefghijklmnopqrstuvwxyz
Encrypted : defghijklmnopqrstuvwxyzabc
Decrypted : abcdefghijklmnopqrstuvwxyz

Upvotes: 0

Clashsoft
Clashsoft

Reputation: 11882

You are subtracting the shift value from the letters. Therefore, the new letter can never be > 'z'. You should check if the it is < 'a' (or 'A', respectively).

StringBuilder decrypted = new StringBuilder(encoded.length());
for (int i = 0; i < encoded.length(); i++)
{
    char t = encoded.charAt(i);
    if ((t >= 'a') && (t <= 'z'))
    {
        t -= shift;
        while (t < 'a')
        {
            t += 26;
        }
    }
    else if ((t >= 'A') && (t <= 'Z'))
    {
        t -= shift;
        while (t < 'A')
        {
            t += 26;
        }
    }

    decrypted.append(t);
}
return decrypted.toString();

Also, you shouldn't be using String concatenation to generate the result. Learn about StringBuilder instead.

EDIT: To make sure the new letter is in the range 'a' .. 'z' for an arbitrary (positive) shift, you should use while instead of if.

Upvotes: 1

user2069105
user2069105

Reputation: 621

Something like this? (Warning, untested)

public static String caesarDecrypt(String encoded, int shift) {
    String decrypted = "";
    for (int i = 0; i < encoded.length(); i++) {
        char t = encoded.charAt(i).ToUpper();

        decrypted = decrypted + decode(t, shift);
    }
}


// call with uppercase ASCII letters, and a positive shift
function decode(char n, int shift)
{
   if ((n < 'A') || (n > 'Z')) return ('-');

   var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   var s = str.charAt(((n - 'A') + shift)%26);
   return(s);
}

Upvotes: 0

Osmani
Osmani

Reputation: 729

I am not giving you exact code. But I can help you in logic:

  1. Check whether you are reaching end points (a, A, z, Z) due to the shift.
  2. If you exceed the end points either way, then compute the distance between end points and shifted t. Add/subtract/modulus (based on the end point) this distance to the other endpoint to get the exact letter.

Upvotes: 0

Related Questions