Входные данные для обработки задач для онлайн-судьи
-
06-09-2019 - |
Вопрос
Это связано с моим предыдущим вопрос
Я решаю задачи UVA по редактированию Step Ladders и пытаюсь заставить онлайн-судью согласиться с моим ответом.
Я использовал метод ReadLn(), чтобы адаптировать мою программу чтения текстовых файлов к этому:
import java.io.*;
import java.util.*;
class LevenshteinParaElJuez implements Runnable{
static String ReadLn(int maxLength){ // utility function to read from stdin,
// Provided by Programming-challenges, edit for style only
byte line[] = new byte [maxLength];
int length = 0;
int input = -1;
try{
while (length < maxLength){//Read untill maxlength
input = System.in.read();
if ((input < 0) || (input == '\n')) break; //or untill end of line ninput
line [length++] += input;
}
if ((input < 0) && (length == 0)) return null; // eof
return new String(line, 0, length);
}catch (IOException e){
return null;
}
}
public static void main(String args[]) // entry point from OS
{
LevenshteinParaElJuez myWork = new LevenshteinParaElJuez(); // Construct the bootloader
myWork.run(); // execute
}
public void run() {
new myStuff().run();
}
}
class myStuff implements Runnable{
public void run(){
ArrayList<String> theWords = new ArrayList<String>();
try
{
/// PLACE YOUR JAVA CODE HERE
String leido=LevenshteinParaElJuez.ReadLn(100);
//System.out.println("lo leido fue "+leido);
while (!leido.equals(" ")){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
}catch(Exception e){
System.out.println("El programa genero una excepcion");
}
int maxEdit=0;
int actualEdit=0;
int wordsIndex1 =0, wordsIndex2=0;
while (wordsIndex1<= theWords.size())
{
while (wordsIndex2<= theWords.size()-1){
actualEdit=Levenshtein.computeLevenshteinDistance(theWords.get(wordsIndex1),theWords.get(wordsIndex2));
if (actualEdit>maxEdit){maxEdit=actualEdit;}
wordsIndex2++;
}
wordsIndex1++;
}
System.out.println(maxEdit+1);
}
}
class Levenshtein {
private static int minimum(int a, int b, int c) {
if(a<=b && a<=c)
return a;
if(b<=a && b<=c)
return b;
return c;
}
public static int computeLevenshteinDistance(String str1, String str2) {
return computeLevenshteinDistance(str1.toCharArray(),
str2.toCharArray());
}
private static int computeLevenshteinDistance(char [] str1, char [] str2) {
int [][]distance = new int[str1.length+1][str2.length+1];
for(int i=0;i<=str1.length;i++)
distance[i][0]=i;
for(int j=0;j<=str2.length;j++)
distance[0][j]=j;
for(int i=1;i<=str1.length;i++)
for(int j=1;j<=str2.length;j++)
distance[i][j]= minimum(distance[i-1][j]+1,
distance[i][j-1]+1,
distance[i-1][j-1]+
((str1[i-1]==str2[j-1])?0:1));
return distance[str1.length][str2.length];
}
}
Предполагается, что я должен прочитать весь ввод онлайн-судьи в том виде, в каком он был написан с клавиатуры, но когда я запускаю вышеуказанную программу, я не могу заставить ее прекратить чтение.Это звучит примерно так:
abc
cba
aba
cca
не имея возможности остановить чтение с консоли.Как мне обойти это??Я подозреваю, что проблема в условности моего цикла:
String leido=LevenshteinParaElJuez.ReadLn(100);
//System.out.println("lo leido fue "+leido);
while (!leido.equals(" ")){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
Я также использовал:
while (!leido.equals(null)){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
и к тому же застрял.
Редактировать:декларация была на самом деле:
while (leido != null)){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
Я не понимаю, почему это терпит неудачу.Я хочу, чтобы чтение ввода с клавиатуры прекращалось при вводе первой пустой строки.
Редактировать:благодаря ответу родиона метод ReadLn теперь изменен на:
if ((input < 0) || (length == 0)) return null; // eof
вместо того, чтобы:
if ((input < 0) && (length == 0)) return null; // eof
Теперь он считывает два пустых пробела, прежде чем выдавать целочисленный вывод.Как я могу изменить его, чтобы просто прочитать один из них?
Решение
Проблема в том, что входные данные не будут <0, когда он достигнет строки, которая возвращает null, сделайте то же самое:
while (leido.length() != 0) {
....
}
Другие советы
Я не совсем уверен, правильно ли я понимаю вашу проблему.Если вы просто хотите, чтобы ваша программа прекратила чтение с консоли, вы можете "закрыть" консоль, нажав Ctrl + D (Linux) или Ctrl + Z (Windows).Это приводит к тому, что System.in.read() возвращает значение -1, так что метод ReadLn вернет значение null.
Проверьте значение null, как предложил Натаниэль.
Редактировать:(основываясь на вашем комментарии)
Проблема связана с этим условием в методе ReadLn
if ((input < 0) && (length == 0)) return null;
Если вы введете пустую строку, длина будет равна 0, хотя входные данные будут > 0 (независимо от того, что ваша система использует для обозначения новой строки).Если вы измените его на
if ((input < 0) || (length == 0)) return null;
метод вернет значение null, если либо входной поток закрыт, либо введена пустая строка.сильный текст
Вместо того, чтобы !leido.equals(" ")
, просто используйте !leido.equals("")
.Первый завершается при вводе строки, содержащей только пробел, второй - при вводе пустой строки.
Я не очень понимаю вашу проблему, но просто предлагаю с моей стороны использовать ваше состояние таким образом
while(!" ".equals(leido)){
//instead of
while (!leido.equals(" ")){
почему ?, потому что ваш код выдаст исключение, если ваша переменная содержит null, а условие, о котором я упомянул, никогда этого не сделает : P