简体   繁体   English

for循环中的二维数组超出范围的异常

[英]2d array out of bound exception in for-loop

I'm working on keyword columnar cipher and I keep getting array out of bound exception, I have tried debugging the code and try and catch to understand the problem but I couldn't! 我正在使用关键字列密码,并且不断使数组超出绑定异常,我尝试调试代码并尝试捕获以了解问题,但我做不到!

public Decryption (String cipherText, String keyWord) {

      cipherText = cipherText.replaceAll("\\s+","");
      cipherText = cipherText.toUpperCase();
      cipherText = cipherText.trim();

      keyWord = keyWord.toUpperCase();

      int column = keyWord.length();

      int row = (cipherText.length() / keyWord.length());
        if (cipherText.length() % keyWord.length() != 0)
          row += 1;

      char [][] matrix = new char [row][column];

      int re = cipherText.length() % keyWord.length();
       for (int i = 0; i < keyWord.length() - re; i++)
         matrix[row - 1][keyWord.length() - 1 - i] = '*';

      char[] sorted_key = keyWord.toCharArray();
      Arrays.sort(sorted_key); 

      int p = 0, count = 0; 
      char[] cipher_array = cipherText.toCharArray();

      Map<Character,Integer> indices = new HashMap<>();

      for(int i = 0; i < column; i++){

       int last = indices.computeIfAbsent(sorted_key[i], c->-1);
        p = keyWord.indexOf(sorted_key[i], last+1);
          indices.put(sorted_key[i], p);

           for(int j = 0; j < row; j++){
            if (matrix[j][p] != '*') 
            matrix[j][p] = cipher_array[count];
                    count++; 
                }}
}

I'm getting the exception in: 我在以下地方遇到异常:

matrix[j][p] = cipher_array[count];

there is a problem with the loop, if I start with j = 1 it doesn't give me the exception but I don't get the correct results (It doesn't print the last row) 循环存在问题,如果我以j = 1开头,它不会给我异常,但不会得到正确的结果(它不会显示最后一行)

The cipher text that I'm trying to decrypt: 我要解密的密文:

YARUEDCAUOADGRYHOBBNDERPUSTKNTTTGLORWUNGEFUOLNDRDEYGOOAOJRUCKESPY YARUEDCAUOADGRYHOBBNDERPUSTKNTTTGLORWUNGEFUOLNDRDEYGOOAOJRUCKESPY

Keyword: 关键词:

YOURSELF 你自己

The result I get when I start the loop with 1: 我从1开始循环时得到的结果:

JUDGE YOURSELF ABOUT YOUR BACKGROUND KNOWLEDGE TO UNDERSTAND CRYP 判断自己关于了解密码的背景知识

What I'm supposed to get: 我应该得到的是:

JUDGE YOURSELF ABOUT YOUR BACKGROUND KNOWLEDGE TO UNDERSTAND CRYPTOGRAPHY 判断自己的背景知识,以了解密码学

I'm not precisely sure, because your code doesnt allow me to validate this (there is no easy way to check the output of the algorithm without digging in), so... I assume that solution is: 我不确定,因为您的代码不允许我对此进行验证(没有简单的方法就无需深入研究即可检查算法的输出),所以...我认为解决方案是:

for (int j = 0; j < row; j++) {
            if (matrix[j][p] != '*'){
                matrix[j][p] = cipher_array[count];
                count++;
            }
        }

instead of: 代替:

for (int j = 0; j < row; j++) {
                if (matrix[j][p] != '*')
                    matrix[j][p] = cipher_array[count];
                    count++;

            }

I think that the strategy of appending '*' to the string in this case is not the way to go - like what you did. 我认为,在这种情况下,将'*'附加到字符串的策略不是解决之道-就像您所做的那样。 Better to append some character when you are building the grid. 在构建网格时最好追加一些字符。

Following this approach here is a fixed version of your code (check the comments in the code for the changed parts): 按照这种方法,这里是代码的固定版本(请检查代码中的注释以了解已更改的部分):

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class Decryption {

    private final String result;

    public Decryption(String cipherText, String keyWord) {

        cipherText = cipherText.replaceAll("\\s+", "");
        cipherText = cipherText.toUpperCase();
        cipherText = cipherText.trim();

        keyWord = keyWord.toUpperCase();

        int column = keyWord.length();

        int row = (cipherText.length() / keyWord.length());
        if (cipherText.length() % keyWord.length() != 0)
            row += 1;

        int[][] matrix = new int[row][column];

        // Changed to calculate the irregular columns
        int re = column - (row * column - cipherText.length());

        char[] sorted_key = keyWord.toCharArray();
        Arrays.sort(sorted_key);

        int p, count = 0;
        char[] cipher_array = cipherText.toCharArray();

        Map<Character, Integer> indices = new HashMap<>();

        for (int i = 0; i < column; i++) {

            int last = indices.computeIfAbsent(sorted_key[i], c -> -1);
            p = keyWord.indexOf(sorted_key[i], last + 1);
            indices.put(sorted_key[i], p);

            // Changed: Detects the need of an extra character and fills it in case of need
            boolean needsExtraChar = p > re - 1;
            for (int j = 0; j < row - (needsExtraChar ? 1 : 0); j++) {
                matrix[j][p] = cipher_array[count];
                count++;
            }
            if(needsExtraChar) {
                matrix[row - 1][p] = '-';
            }
        }

        result = buildString(matrix);
    }

    public static void main(String[] args) {
        System.out.println(new Decryption("EVLNE ACDTK ESEAQ ROFOJ DEECU WIREE", "ZEBRAS").result);
        System.out.println(new Decryption("EVLNA CDTES EAROF ODEEC WIREE", "ZEBRAS").result);
        System.out.println(new Decryption("YARUEDCAUOADGRYHOBBNDERPUSTKNTTTGLORWUNGEFUOLNDRDEYGOOAOJRUCKESPY", "YOURSELF").result);
    }

    private String buildString(int[][] grid) {
        return Arrays.stream(grid).collect(StringBuilder::new, (stringBuilder, ints) -> Arrays.stream(ints).forEach(t -> {
            stringBuilder.append((char) t);
        }), (stringBuilder, ints) -> {
        }).toString().replace("-", "");
    }
}

If you run this, this will print: 如果运行此命令,则将打印:

WEAREDISCOVEREDFLEEATONCEQKJEU
WEAREDISCOVEREDFLEEATONCE
JUDGEYOURSELFABOUTYOURBACKGROUNDKNOWLEDGETOUNDERSTANDCRYPTOGRAPHY

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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