简体   繁体   中英

Java while loop not working

The program allows the user to enter a phrase and converts it to ROT13, where each English letter entered, becomes the letter 13 places after it(A becomes N). My current code works when 1 character is entered, however I need it to run through the code the number of times there are characters. I've tried to put in a while loop at the beginning, but it doesn't seem to be working. Why is this?

import java.io.*;

public class J4_1_EncryptionErasetestCNewTry
{

    public static void main (String [] args) throws IOException
    {
        BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));// Buffered Reader reads the number inputed 

        String key [] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
        String keyA [] = {"N","O","P","Q","R","S","T","U","V","W","X","Y","Z","A","B","C","D","E","F","G","H","I","J","K","L","M"};

        System.out.println("Enter a phrase: ");
        String phrase = myInput.readLine();

        int length = phrase.length();
        int y = 0, i = 0, num = 0;

        while (y <= length) {
            String letter = Character.toString(phrase.charAt(y));
            y++;
            while(!(letter.equals(key[i]))){
                i++;
            }
            num = i;
            System.out.println(keyA[num]);
            y++;
        }
    }
}

See comments on code.

public static void main(String[] args) {

        BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));// Buffered Reader reads the number inputed 

        String key [] = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"};
        String keyA [] = {"N","O","P","Q","R","S","T","U","V","W","X","Y","Z","A","B","C","D","E","F","G","H","I","J","K","L","M"};

        System.out.println("Enter a phrase: ");
        String phrase = "";

        try {
            phrase = myInput.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        }

        int length = phrase.length();
        int y = 0, i = 0, num = 0;

        while (y < length) { // This should be y < length. Otherwise, it would throw a StringIndexOutOfBoundsException.
            i=0; // Re-initialize
            String letter = Character.toString(phrase.charAt(y));
//            y++; // Unecessary incremental
            while(!(letter.equalsIgnoreCase(key[i]))){
                i++;
            }
            num = i;
            System.out.print(keyA[num]);
            y++;
        }

    }

Although this doesn't answer your problem, it answers your intention:

public static String rot13(String s) {
    String r = "";
    for (byte b : s.getBytes())
        r += (char)((b + 13 - 'A') % 26 + 'A');
    return r;
}

Your code is far too complicated for what it's doing. Really, all the work can be done in one line. Use byte arithmetic rather than array lookups etc. Simple/less code is always the best approach.

Please no comments about inefficiencies etc. This is a basic implementation that works (tested). The reader is free to improve on it as an exercise.

I have implemented it in a different way, but it works as you expect, only for uppercase as in your example:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

public class WhileLoopIssue {

    public static void main( String[] args ) throws IOException {
        BufferedReader myInput = new BufferedReader( new InputStreamReader(
                System.in ) );// Buffered Reader reads the
                              // number inputed

        final List<String> letterList = Arrays.asList( "A", "B", "C", "D", "E",
                "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
                "R", "S", "T", "U", "V", "W", "X", "Y", "Z" );

        System.out.println( "Enter a phrase: " );
        String phrase = myInput.readLine();

        final String[] letters = phrase.split( "" );     // Split input phrase
        final StringBuffer buffer = new StringBuffer();  // Variable to save letters. Could be a String as well.
        for ( int i = 0; i < letters.length; i++ ) {
            final int letterIndex = letterList.indexOf( letters[i] );  // Get the numeric value of the letter
            if ( letterIndex < 0 )  // Skip iteration if not found. Maybe a lowercase, or an empty String
                continue;

            final int nextLetterIndex = 13 + letterIndex;   // Actual value of the letter + 13
            if ( nextLetterIndex > letterList.size() ) {
                buffer.append( nextLetterIndex % letterList.size() );  // Actual value greater than the total number of letters in the alphabet, so we get the modulus for the letter
            } else {
                buffer.append( letterList.get( nextLetterIndex ) );  // Letter in the range, get it
            }
        }
        System.out.println( buffer.toString() );
    }
}

You're code will most likely break in your inner while loop as you are not resetting the value of i . By not doing so your gonna hit StringIndexOutOfBounds. I would recommend initialising i in your outer while loop or better yet just move int i = 0; inside the outer while loop.

You need to reset i in each iteration. It may happen that first letter found toward the end of the array "key". Your code will find next input char there onward, I guess this is not what you want, and will not find that char and will throw SIOBException. I have changed the while loop, removed twice increment in variable y as well. Have a look

    while (y < length) {
        i = 0; //Every Time you want to search from start of the array 
                //so just reset the i.
        String letter = Character.toString(phrase.charAt(y));
        while(!(letter.equals(key[i]))){
            i++;
        }
        num = i;
        System.out.println(keyA[num]);
        y++;
    }

I am assuming what ever you enter as input is a phrase of ONLY upper-case alphabets, else you will come across the SIOBException as you you will not be able to locate that letter in your array.

Just on side note, instead of those arrays you should use some other data structures which are efficient for searching like hashmap. Your linear search across the array is not optimized.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM