entrée de traitement du problème pour le juge en ligne
-
06-09-2019 - |
Question
Ceci est lié à mon précédent question
Je suis la résolution de l'étape Editer les échelles de UVA et essayer de faire le juge en ligne conforme à ma réponse.
Je l'ai utilisé la méthode ReadLn () pour adapter mon programme textfile lecture à ceci:
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];
}
}
Je suis censé lire l'ensemble de l'entrée du juge en ligne comme il a été écrit par le clavier, mais quand je lance le programme ci-dessus, je ne peux pas le faire arrêter la lecture. Il va quelque chose comme:
abc
cba
aba
cca
sans être en mesure d'arrêter la lecture de la console. Comment puis-je contourner cela?? Je soupçonne que le problème est dans ma boucle conditionnelle:
String leido=LevenshteinParaElJuez.ReadLn(100);
//System.out.println("lo leido fue "+leido);
while (!leido.equals(" ")){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
J'ai aussi utilisé:
while (!leido.equals(null)){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
et ainsi été immobilisés.
Edit: la déclaration était en fait:
while (leido != null)){
theWords.add(leido);
leido=LevenshteinParaElJuez.ReadLn(100);
}
Je ne comprends pas pourquoi il est défaillant. Je veux que la lecture de l'entrée via le clavier pour arrêter quand la première ligne vide est entrée.
Edit: grâce à la réponse de Rodion, la méthode ReadLn est changé à:
if ((input < 0) || (length == 0)) return null; // eof
au lieu de:
if ((input < 0) && (length == 0)) return null; // eof
Maintenant, il est lu deux espace vide avant de produire la sortie entier. Comment puis-je changer juste pour lire un?
La solution
Le problème est que l'entrée ne sera pas <0 quand il atteint la ligne qui renvoie null, alors faites:
while (leido.length() != 0) {
....
}
Autres conseils
Je ne suis pas vraiment sûr si je comprends bien votre problème. Si vous voulez simplement votre programme pour arrêter la lecture à partir de la console, vous pouvez « fermer » la console en appuyant sur Ctrl + D (Linux) ou Ctrl + Z (Windows). Cela provoque System.in.read () pour renvoyer -1, de sorte que la méthode ReadLn reviendrait nulle.
Vérifier null comme Nathaniel suggéré.
Modifier : (en fonction de votre commentaire)
Le problème est avec cette condition dans le procédé ReadLn
if ((input < 0) && (length == 0)) return null;
Si vous entrez une ligne vide, la longueur sera de 0, l'entrée sera> 0 si (quel que soit votre système utilise pour désigner un saut de ligne). Si vous modifiez à
if ((input < 0) || (length == 0)) return null;
la méthode retourne null si soit le flux d'entrée est fermé ou une ligne vide est entré. Texte fort
Au lieu de !leido.equals(" ")
, utilisez simplement !leido.equals("")
. L'ancien se termine lorsqu'une ligne ne contenant qu'un espace est saisie, celle-ci quand une ligne vide est entré.
Je ne comprends pas votre problème beaucoup, mais juste un suggère de mon côté sera que utiliser votre condition de cette façon
while(!" ".equals(leido)){
//instead of
while (!leido.equals(" ")){
pourquoi, parce que votre code renvoie une exception si votre variable contient nulle, et la condition que je l'ai mentionné ne sera jamais le faire: P