Я пытаюсь реализовать этот алгоритм переноса слов в Java. Моя программа принимает количество абзацев для обертывания, максимальную длину строки и текст ввода. Например:
1
5
This is a test.
Однако после того, как он принимает текст ввода и запускает алгоритм, я получаю следующую ошибку времени выполнения:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1
at DynamicProgramming.main(DynamicProgramming.java:74)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Возможно ли, что у меня есть опечатка от перевода вышеуказанного кода с C++ на Java или есть ли какая-то ошибка в этой логике, которая вызвала бы это исключение? Благодарю.
import java.util.Scanner;
public class DynamicProgramming {
static int P;
static int M;
static String[] inputLine;
public static void printNeatly(int M, int[] inputLineLengths) {
int n = inputLineLengths.length;
double[][] extraSpaces = new double[n][n];
double[][] lineCost = new double[n][n];
double[] optimalTotalCost = new double[n];
int[] optimizedLengths = new int[n];
for (int i=1; i <= n; i++) {
extraSpaces[i][i] = M - inputLineLengths[i-1];
for (int j=i+1; j <= n; j++) {
extraSpaces[i][j] = extraSpaces[i][j-1] - inputLineLengths[j-1] -1;
}
}
for (int i=1; i<= n; i++) {
for (int j=i; j <=n; j++) {
if (extraSpaces[i][j] < 0) {
lineCost[i][j] = Double.POSITIVE_INFINITY;
}
else if (j == n && extraSpaces[i][j] >= 0) {
lineCost[i][j] = 0;
}
else {
lineCost[i][j] = extraSpaces[i][j]*extraSpaces[i][j];
}
}
}
optimalTotalCost[0] = 0;
for (int j=1; j <= n; j++) {
optimalTotalCost[j] = Double.POSITIVE_INFINITY;
for (int i=0; i <= j; i++) {
if (optimalTotalCost[i-1] != Double.POSITIVE_INFINITY && lineCost[i][j] != Double.POSITIVE_INFINITY &&
(optimalTotalCost[i-1] + lineCost[i][j] < optimalTotalCost[j])) {
optimalTotalCost[j] = optimalTotalCost[i-1] + lineCost[i][j];
optimizedLengths[j] = i;
}
}
}
}
public int printOutput(int[] optimizedLengths, int n) {
int k;
if (optimizedLengths[n] == 1) {
k = 1;
}
else {
k = printOutput(optimizedLengths, optimizedLengths[n]-1);
}
System.out.println(optimizedLengths[n]);
return k;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
P = Integer.parseInt(scanner.nextLine());
int[] inputLineLengths = new int[]{};
for (int i=1; i <= P; i++) {
M = Integer.parseInt(scanner.nextLine());
inputLine = scanner.nextLine().split("[ ]+");
inputLineLengths[i] = inputLine.length;
printNeatly(M, inputLineLengths);
}
}
}
Просто взглянув на метод printNeatly
:
Вы получаете длину массива следующим образом:
int n = inputLineLengths.length;
Но в ваших циклах вы поднимаетесь и включаете n
:
for (int i=1; i <= n; i++) {
Вам нужно остановиться раньше, потому что массивы (на Java) индексируются от 0
до n-1
(поэтому также очень вероятно, что вы хотите запустить свои массивы с 0
, а не 1
)
for (int i=1; i < n; i++) {
[i-1]
которые, очевидно, не будут работать, когда i=0
, поэтому, похоже, мне придется провести некоторую реструктуризацию.
[i-1]
не так уж важно, особенно если учесть, что вы целенаправленно начали с i=1
; но как только i=n
и вы попытаетесь прочитать этот индекс массива, вы получите ошибки.
Во-первых, ваш массив inputLineLengths
инициализируется длиной 0
, поэтому вы не можете помещать что-либо в массив.
Сначала инициализируйте его до длины P
int[] inputLineLengths = new int[P];
Во-вторых, цикл for
должен располагаться над допустимыми значениями индекса, которые от 0
до array length - 1
. Измените цикл for
на:
for (int i = 0; i < P; i++) {
У вас есть другие for
петель вне main
которые необходимо изменить аналогичным образом.