conor tighe.
conor tighe.

Reputation: 123

Why do I get an error when populating and assembling my 2d array Matrix?

When Im trying to take a String and throw it into an array by putting the build method inside the print method but when I do I get the following errors:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at polycipher.CipherKey.printMatrix(CipherKey.java:27)
at polycipher.CipherKey.assembleMatrix(CipherKey.java:17)
at polycipher.ApplicationDriver.main(ApplicationDriver.java:23)

I was wondering what I'm doing wrong here? I'm pretty sure you can call a method within a method, is there something wrong with my codes logic? I tryed adding -1 to pretty much everywhere that I thought could cause an array out of bounds but no luck.

import java.util.*;

import polycipher.Matrix;

public class CipherKey {

Scanner write = new Scanner (System.in);
Matrix polyCipher = new Matrix();

private final char[] PHRASE_KEY = { 'J', 'A', 'V', 'A'};
String[][] matrixStore = new String[PHRASE_KEY.length][PHRASE_KEY.length];
public void assembleMatrix()  { 

    matrixFormatter(polyCipher.translation);
    System.out.println(polyCipher.translation);
    printMatrix(buildeMatrix(polyCipher.translation,"|",","));

}


public String printMatrix(String s [][]){
    String keyOut = "  J A V A\n";
    for (int i = 0; i < PHRASE_KEY.length; i++) {
        keyOut += PHRASE_KEY[i] + " ";
        for (int j = 0; j < PHRASE_KEY.length; j++) {
            keyOut += s[i][j] + " ";
        }
        keyOut += "\n";
    }
    return keyOut;
}

public static String [][] buildeMatrix (String translation, String outermarker, String innermarker) {
    // outerdelim may be a group of characters
    String [] sOuter = translation.split ("[" + outermarker + "]"); 
    int size = sOuter.length;
    // one dimension of the array has to be known on declaration:
    String [][] result = new String [size][]; 
    int count = 0;
    for (String line : sOuter)
    {
        result [count] = line.split (innermarker);
        ++count;
    }
    return result;
}

public String matrixFormatter(String x){

     String resultstr = "";
      int i = 0;
      while(i < x.length()) {
        // If end of string: only add character.
        if (i == x.length() - 1) {
          resultstr += x.substring(i, i + 1);
        } else {
          if ( ((i + 1) % 4) == 0) {
            resultstr += x.substring(i, i + 1)  + "|";
          } else {
            resultstr += x.substring(i, i + 1)  + ",";
          }
        }
        i++;
      }
      return resultstr;

}

}

This is how I call the matrix in my main

    CipherKey Key = new CipherKey();
    Key.assembleMatrix();

Here is the class that I take the translation from:

import java.util.Scanner;

public class Matrix {

private final char[] CIPHER_KEY = { 'A', 'D', 'F', 'G', 'V', 'X' }; // static morse array
private final String validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; // characters which can be used
public String translation = ""; // for storing it the translation of the phrase

{ // failsafe, our program will be stuck in an infinite loop if
    // number of valid characters is not at lease the square of CIPHER_KEY
    if(validChars.length() < CIPHER_KEY.length*CIPHER_KEY.length) {
        System.out.println("Error: Not enough valid characters to populate matrix.");
    }

}

private char[][] matrix = new char[CIPHER_KEY.length][CIPHER_KEY.length]; // field for holding the generated matrix
private int[] usedNumbers = new int[validChars.length()]; // field for enforcing unique characters

{ // initiate all array elements to -1 (our "empty" value)
    for (int x = 0; x < usedNumbers.length; x++)
        usedNumbers[x] = -1;
}

public Matrix() { // Matrix default constructor override

    int random; 

    for (int i = 0; i < CIPHER_KEY.length; i++) { // for every row

        for (int j = 0; j < CIPHER_KEY.length; j++) { // for every column

            validation: while (true) { // do this until I break the loop manually

                random = (int) (Math.random() * validChars.length()); // generates a random number from 0 (inclusive) to (36 exclusive)
                for (int k = 0; k < usedNumbers.length; k++) { // check every previously used character

                    if (random == usedNumbers[k]) {
                        continue validation; // if this char used before, skip it
                    } else if (usedNumbers[k] == -1) {

                        usedNumbers[k] = random; // if not previously used, store its value as used
                        break validation; // and break out of this validation loop
                    }
                }
            }
            matrix[i][j] = validChars.split("")[random].charAt(0); // add this character to the matrix
        }
    }
}

public void searchMatrix(){

    Scanner console = new Scanner (System.in);

    String phrase ="";

    System.out.println("\n Enter the message you would like "
            + "to encrypt with the cipher: ");
    phrase = console.nextLine();

    char[] phraseSplit = phrase.toUpperCase().toCharArray();
    for (int k=0; k<phraseSplit.length; k++) {
        for (int i=0; i<matrix.length; i++) {
            for (int j=0; j<matrix[i].length; j++) {
                if (phraseSplit[k] == matrix[i][j]) {
                    System.out.printf("%c has a Array Index %d, %d\n", phraseSplit[k], i, j);
                    if(i == 0){  translation += "A";  }
                    if(i == 1){  translation += "D";  }
                    if(i == 2){  translation += "F";  }
                    if(i == 3){  translation += "G";  }
                    if(i == 4){  translation += "V";  }
                    if(i == 5){  translation += "X";  }
                    if(j == 0){  translation += "A";  }
                    if(j == 1){  translation += "D";  }
                    if(j == 2){  translation += "F";  }
                    if(j == 3){  translation += "G";  }
                    if(j == 4){  translation += "V";  }
                    if(j == 5){  translation += "X";  }

                }//end if
            }//end for j
        }//end for i
    }//end for k
    System.out.println("");




 } //search end

public String toString() { // toString override, useful for debugging, prints out the matrix in a 6x6 table
    String output = "  A D F G V X\n";
    for (int i = 0; i < CIPHER_KEY.length; i++) {
        output += CIPHER_KEY[i] + " ";
        for (int j = 0; j < CIPHER_KEY.length; j++) {
            output += matrix[i][j] + " ";
        }
        output += "\n";
    }
    return output;
}


}

Upvotes: 0

Views: 69

Answers (1)

muued
muued

Reputation: 1676

You perform some split operations on the default value of Matrix.translation and afterwards assume, that the buildeMatrix operation created a 2D array the same size as your matrixStore.

This seems to be a bad idea.

Change the printMatrix mathod in the following way:

public String printMatrix(String s [][]){
    String keyOut = "  J A V A\n";
    for (int i = 0; i < s.length; i++) {
        keyOut += PHRASE_KEY[i] + " ";
        for (int j = 0; j < s[i].length; j++) {
            keyOut += s[i][j] + " ";
        }
        keyOut += "\n";
    }
    return keyOut;
}

and change your assembleMatrix method to eg the following:

public void assembleMatrix()  { 
    polyCipher.translation = matrixFormatter(polyCipher.translation);
    System.out.println(polyCipher.translation);
    System.out.println(printMatrix(buildeMatrix(polyCipher.translation,"|",",")));
}

Upvotes: 1

Related Questions