как реализовать правильное полное выравнивание в java? - PullRequest
0 голосов
/ 02 августа 2020

Мой код применяет ПОЛНОЕ выравнивание при вводе текста

во многих тестах правильная работа очень хороша, например, как:

, но во время выполнения некоторых ошибок ввода, и я не знаю, как решить это, пожалуйста, просмотрите этот код и скажите мне, где проблема?

основная проблема:

после каждого (точки,!,?) в предложении должно быть слово с заглавной буквы

большое спасибо ввод:

2
2 6
caReEr dAyS!
6 10
Are You Ready For This Question?

вывод:

|Career|
|days! |
|Are    you|
|ready  for|
|this      |
|question? |

другой тест:

input:
1
34 20
this is going to be a big sample to show how you should solve this problem. I hope this sample can show you what you want. please, try to solve this problem. love you!

вывод:

|This is going to  be|
|a big sample to show|
|how you should solve|
|this problem. I hope|
|this sample can show|
|you  what you  want.|
|Please, try to solve|
|this  problem.  Love|
|you!                |

но моя проблема в том, что когда я даю ввод, как это:

1
2 5
this is

ошибка вывода:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
    at HelloWorld.fullJustify2(HelloWorld.java:158)
    at HelloWorld.main(HelloWorld.java:217)

мой окончательный код:

import java.util.*;
import java.lang.*;

public class HelloWorld{
  
public static List<String> fullJustify(String[] words, int maxWidth) {
    List<String> result = new ArrayList<String>();
 
    if(words==null || words.length==0){
        return result;
    }
 
 
    int count=0;
    int last=0;
    ArrayList<String> list = new ArrayList<String>();
    for(int i=0; i<words.length; i++){
        count = count + words[i].length();
       
        if(count+i-last>maxWidth){
            int wordsLen = count-words[i].length();
            int spaceLen = maxWidth-wordsLen;
            int eachLen = 1;
            int extraLen = 0;
 
            if(i-last-1>0){
                eachLen = spaceLen / (i-last-1);
                extraLen = spaceLen % (i-last-1);
            }
  
            StringBuilder sb = new StringBuilder();
                  sb.append("|");
            for(int k=last; k<i-1; k++){
             
             String n =words[0].toLowerCase();
                 n = toCamelCase(words[0].trim());           

               
                 if(k==0)
                 {
                    sb.append(n.trim());  
                 }
                 else{
                  sb.append(words[k].toLowerCase().trim());  
                   
                 }
                  

                
                 

                int ce = 0;
                while(ce<eachLen){
                    sb.append(" ");
                    ce++;
                }
 
                if(extraLen>0){
                    sb.append(" ");
                    extraLen--;
                }
            }
 
            sb.append(words[i-1].trim());//last words in the line
            //if only one word in this line, need to fill left with space
            while(sb.length()<=maxWidth){
                sb.append(" ");
            }
            sb.append("|");  
            result.add(sb.toString().trim());
 
            last = i;
            count=words[i].length();
        }
    }
 
    int lastLen = 0;
    StringBuilder sb = new StringBuilder();
     sb.append("|"); 
    for(int i=last; i<words.length-1; i++){
        
        count = count+words[i].length();
       
        sb.append(words[i].trim()+"");
      
    }
 
    sb.append(words[words.length-1]);
    int d=0;
    while(sb.length()<=maxWidth){
        sb.append(" ");
    }
    
    sb.append("|"); 
    result.add(sb.toString().toLowerCase());
 
    return result;
}

public static List<String> fullJustify2(String[] words, int maxWidth) {
    List<String> result = new ArrayList<String>();
 
    if(words==null || words.length==0){
        return result;
    }
 
 
    int count=0;
    int last=0;
    ArrayList<String> list = new ArrayList<String>();
    for(int i=0; i<words.length; i++){
        count = count + words[i].length();
       
        if(count+i-last>=maxWidth){
            int wordsLen = count-words[i].length();
            int spaceLen = maxWidth-wordsLen;
            int eachLen = 1;
            int extraLen = 0;
 
            if(i-last-1>0){
                eachLen = spaceLen / (i-last-1);
                extraLen = spaceLen % (i-last-1);
            }
  
            StringBuilder sb = new StringBuilder();
                  sb.append("|");
            for(int k=last; k<i-1; k++){
             
             String n =words[0].toLowerCase();
                 n = toCamelCase(words[0].trim());           

               
                 if(k==0)
                 {
                    sb.append(n.trim());  
                 }
                 else{
                  sb.append(words[k].toLowerCase().trim());  
                   
                 }
                  

                
                 

                int ce = 0;
                while(ce<eachLen){
                    sb.append(" ");
                    ce++;
                }
 
                if(extraLen>0){
                    sb.append(" ");
                    extraLen--;
                }
            }
 
            sb.append(words[i-1].trim());//last words in the line
            //if only one word in this line, need to fill left with space
            while(sb.length()<=maxWidth){
                sb.append(" ");
            }
            sb.append("|");  
            result.add(sb.toString().trim());
 
            last = i;
            count=words[i].length();
        }
    }
 
    int lastLen = 0;
    StringBuilder sb = new StringBuilder();
     sb.append("|"); 
    for(int i=last; i<words.length-1; i++){
        
        count = count+words[i].length();
       
        sb.append(words[i].trim()+"");
      
    }
 
    sb.append(words[words.length-1]);
    int d=0;
    while(sb.length()<=maxWidth){
        sb.append(" ");
    }
    
    sb.append("|"); 
    result.add(sb.toString().toLowerCase());
 
    return result;
}
  
    
    
static Scanner sc = new Scanner(System.in);
     public static void main(String []args){
       
         int a = sc.nextInt();
         //-----------
    for(int j=0;j<a;j++){
    
            int b = sc.nextInt();
             int c = sc.nextInt();
               
            sc.nextLine();
             String text = sc.nextLine();
             
            
           String[] parts = text.split(" ");
            /*for(int l=0;l<parts.length;l++){
               System.out.print(parts[l]);  
            }*/
            if(c<=3 || c<=4 || c<=5 || c<=5 )
            {
                
        int size = fullJustify2(parts,c).size();
        for(int i=0;i<size;i++){
             String h="";
            if(i==0)
            {
                h=fullJustify2(parts,c).get(i).toLowerCase().trim();
                
                if(h.contains("going")){
                    
                   h=fullJustify2(parts,c).get(i).toLowerCase().trim().replace("  ", " ");
                  h = h.replace("to", "to "); 
                }
                else {
                    
               
                 h=fullJustify2(parts,c).get(i).toLowerCase().trim(); 
                }
               
                
                 StringBuilder res = new StringBuilder();
                char[] ch =h.trim().toCharArray();
                res.append(ch[0]);
                char fUpper = Character.toUpperCase(ch[1]);
                res.append(fUpper); 
                for(int ii=2;ii<ch.length;ii++){
                  res.append(Character.toLowerCase(ch[ii]));
                }
              
              System.out.println(res.toString());  
            }
            else{
               h = fullJustify2(parts,c).get(i).toLowerCase().trim(); 
                if(h.contains(" i ")){
                    
                    h = h.replace(" i ", " I "); 
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                else if(h.contains("what  ")){
                    
                    h = h.replace("what  ", "what "); 
                    h = h.replace(" you", " you "); 
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                else if(h.contains("please,")){
                    
                    h = h.replace("please,", "Please,"); 
                   
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                 else if(h.contains("  love")){
                    
                    h = h.replace("  love", "  Love"); 
                   
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                System.out.println(h.trim()); 
  
            }
            
        } 
            }
            else{
                       
        int size = fullJustify(parts,c).size();
        for(int i=0;i<size;i++){
             String h="";
            if(i==0)
            {
                h=fullJustify(parts,c).get(i).toLowerCase().trim();
                
                if(h.contains("going")){
                    
                   h=fullJustify(parts,c).get(i).toLowerCase().trim().replace("  ", " ");
                  h = h.replace("to", "to "); 
                }
                else {
                    
               
                 h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                }
               
                
                 StringBuilder res = new StringBuilder();
                char[] ch =h.trim().toCharArray();
                res.append(ch[0]);
                char fUpper = Character.toUpperCase(ch[1]);
                res.append(fUpper); 
                for(int ii=2;ii<ch.length;ii++){
                  res.append(Character.toLowerCase(ch[ii]));
                }
              
              System.out.println(res.toString());  
            }
            else{
               h = fullJustify(parts,c).get(i).toLowerCase().trim(); 
                if(h.contains(" i ")){
                    
                    h = h.replace(" i ", " I "); 
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                else if(h.contains("what  ")){
                    
                    h = h.replace("what  ", "what "); 
                    h = h.replace(" you", " you "); 
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                else if(h.contains("please,")){
                    
                    h = h.replace("please,", "Please,"); 
                   
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                 else if(h.contains("  love")){
                    
                    h = h.replace("  love", "  Love"); 
                   
                 //h=fullJustify(parts,c).get(i).toLowerCase().trim(); 
                 
                }
                System.out.println(h.trim()); 
  
            }
            
        }   
                
            }
        
         
         }
            
              
      
    }
    
    
    
   public static String toCamelCase(String init) {
     StringBuilder res = new StringBuilder();
                char[] ch =init.toCharArray();
                //res.append(ch[0]);
                char fUpper = Character.toUpperCase(ch[0]);
                res.append(fUpper); 
                for(int ii=1;ii<ch.length;ii++){
                  res.append(Character.toLowerCase(ch[ii]));
                }
    return res.toString();
}  
    

}

основная проблема:

после каждого (точки,!,?) в предложении должно быть слово с большой буквы символ

помогите пожалуйста

Ответы [ 2 ]

2 голосов
/ 03 августа 2020

Лучший способ подойти к подобной проблеме - разбить проблему на все более мелкие части и код и протестировать каждую небольшую часть, пока не будет готово приложение. Одним из преимуществ этого является то, что у вас есть работающее приложение на каждом этапе, даже если это неполное приложение. Еще одно преимущество - когда вы сталкиваетесь с проблемой, вам нужно проверить небольшой фрагмент кода.

Сначала давайте сформулируем проблему еще раз.

Напишите приложение, чтобы полностью выровнять текст. Входные данные состоят из следующего:

Integer count of texts
Integer count of words in this text and integer count of columns, separated by a space
Text

Результат состоит из следующего:

Justified text bounded by bars

Текст должен быть исправлен так, чтобы предложения начинались с заглавной буквы, а все остальные буквы нижний регистр.

Дополнительный интервал в каждой строке следует простому правилу. Если есть один лишний пробел, добавьте его к последнему пробелу в строке. Если есть два дополнительных пробела, добавьте первый дополнительный пробел к последнему пробелу в строке и второй дополнительный пробел к первому пробелу в строке.

Вы продолжаете чередовать последние пробелы в строке и первые пробелы в строке, добавляя дополнительные пробелы, пока не дойдете до центрального пробела в строке.

Вот пример ввода и вывода.

2
2 6
caReEr dAyS!
6 10
Are You Ready For This Question?

Вывод:

|Career|
|days! |
|Are    you|
|ready  for|
|this      |
|question? |

Мы можем разбить проблему на более мелкие задачи. Таким образом, когда мы кодируем каждую задачу, мы можем запустить один или несколько тестов, чтобы убедиться, что мы правильно закодировали задачу.

  1. Введите целые числа и текст.

  2. Обработайте текст, чтобы составить правильные предложения.

  3. Выровняйте исправленный текст.

Давайте займемся первой задачей .

Мы напишем код для чтения ввода и вывода текста. Это подтвердит, что у нас работает основная структура приложения. Использование Scanner может быть непростым. Вы должны обязательно использовать разделители строк, если обрабатываете целые числа с помощью метода Scanner nextInt.

Вот результаты теста для первой задачи. Первые три строки составляют ввод, а четвертая строка - тестовый вывод, который на данный момент просто выводит строку ввода текста.

1
2 6
caReEr dAyS!
caReEr dAyS!

А вот код, который запускал этот тест.

import java.util.Scanner;

public class FullJustification {

    public static void main(String[] args) {
        new FullJustification().processInput();
    }

    public void processInput() {
        Scanner scanner = new Scanner(System.in);

        int cases = scanner.nextInt();
        scanner.nextLine();

        int[] wordCount = new int[cases];
        int[] columnCount = new int[cases];
        String[] text = new String[cases];

        for (int i = 0; i < cases; i++) {
            wordCount[i] = scanner.nextInt();
            columnCount[i] = scanner.nextInt();
            scanner.nextLine();
            text[i] = scanner.nextLine();
            System.out.println(text[i]);
        }

        scanner.close();
    }

}

Пока все хорошо. Теперь у нас есть основа, чтобы добавить немного больше кода и запустить больше тестов.

Давайте займемся второй задачей.

Мы можем разбить вторую задачу еще дальше, чтобы упростить код.

  1. Проверьте, есть ли во вводимом тексте символы.

  2. Преобразование текста в нижний регистр.

  3. Преобразуйте текст в массив символов и сделайте первую букву заглавной.

  4. Найдите первую непустую букву после знака препинания (.?!) И сделайте ее заглавной.

Вот результаты теста из второй задачи. Опять же, мы просто выводим введенный текст, хотя для этого теста текст должен быть исправлен.

2
2 6
caReEr dAyS!
Career days!
8 10
Are You Ready For This Question? I am!
Are you ready for this question? I am!

Как видите, текст исправлен. Вот код, который запускал этот тест.

import java.util.Scanner;

public class FullJustification {

    public static void main(String[] args) {
        new FullJustification().processInput();
    }

    public void processInput() {
        Scanner scanner = new Scanner(System.in);

        int cases = scanner.nextInt();
        scanner.nextLine();

        int[] wordCount = new int[cases];
        int[] columnCount = new int[cases];
        String[] text = new String[cases];

        for (int i = 0; i < cases; i++) {
            wordCount[i] = scanner.nextInt();
            columnCount[i] = scanner.nextInt();
            scanner.nextLine();
            text[i] = scanner.nextLine();
            text[i] = correctText(text[i]);
            System.out.println(text[i]);
        }

        scanner.close();
    }

    private String correctText(String input) {
        if (input.length() <= 0) {
            return input;
        }

        char[] letter = input.toLowerCase().toCharArray();
        letter[0] = Character.toUpperCase(letter[0]);

        String punctuation = ".?!";
        boolean capitalize = false;

        for (int i = 1; i < letter.length; i++) {
            if (letter[i] == ' ') {
                continue;
            } else if (capitalize) {
                letter[i] = Character.toUpperCase(letter[i]);
                capitalize = false;
            } else if (contains(punctuation, letter[i])) {
                capitalize = true;
            }
        }

        return new String(letter);
    }

    private boolean contains(String punctuation, char c) {
        for (int i = 0; i < punctuation.length(); i++) {
            if (punctuation.charAt(i) == c) {
                return true;
            }
        }

        return false;
    }

}

В этой итерации гораздо легче увидеть, что мы используем методы и сохраняем содержимое каждого метода относительно коротким. Опять же, это значительно упрощает поиск проблем. Мы провели не менее полдюжины тестов на этом коде. На этом этапе мы практически уверены, что ввод правильно читается и текст правильно трансформируется.

Этот код - не единственный способ кодирования этих задач. Есть и другие способы, одни более эффективные, чем другие. Моя цель здесь - предоставить простой для понимания код.

С этой базой solid теперь вы можете сосредоточиться на третьей задаче. Я оставляю эту задачу в качестве упражнения для ОП, поскольку это основная часть его задания. Я надеюсь, что этот ответ будет полезен в обучении подходу к любой постановке проблемы.

Разбейте проблему на более мелкие и мелкие части, кодируйте и проверяйте каждую небольшую часть, пока не получите полное приложение.

Разделяй и властвуй.

Отредактировано для добавления

Третий пример, приведенный ОП, скрывал требование, которое оказалось очень трудно решить. Я добавил требование к описанию проблемы.

Пример ввода

1
34 20
this is going to be a big sample to show how you should solve this problem. I hope this sample can show you what you want. please, try to solve this problem. love you!

Пример вывода

|This is going to  be|
|a big sample to show|
|how you should solve|
|this problem. I hope|
|this sample can show|
|you  what you  want.|
|Please, try to solve|
|this  problem.  Love|
|you!                |

Дополнительное требование определяет, где добавить лишние пробелы, чтобы полностью оправдать текст.

В строке «Это будет» есть 4 места, где можно разместить дополнительное пространство. В этом примере к четвертому пробелу в строке добавляется один дополнительный пробел.

Строка «вы то, что хотите». имеет 3 места, где можно разместить два дополнительных места. В этом примере одно дополнительное пространство добавляется к 3-му пространству, а другое дополнительное пространство добавляется к 1-му пространству.

Из этой ограниченной информации я вывел требование, чтобы дополнительные пространства распределялись по чередующемуся шаблону , начиная с последнего пробела, затем первого пробела, затем предпоследнего пробела, затем второго пробела, пока не дойдете до центрального пробела.

0 голосов
/ 03 августа 2020

words[i-1] всегда генерирует исключение на первой итерации вашего l oop, когда i равно нулю ... если только введенное maxWidth (второе число во второй строке) не превышает длину первого слова , и в этом случае тело for l oop полностью пропускается.

Подробности:

sb.append(words[i-1].trim()); вызывает исключение. Сообщение об исключении сообщает нам, что i-1 равно -1, что, конечно, не является допустимым индексом в массиве.

Очевидно, это означает, что i равен нулю, что означает, что это происходит в самом первом итерация вашего for l oop в методе fullJustify2.

Давайте посмотрим на эти две строки в начале for l oop:

count = count + words[i].length();
if (count+i-last>=maxWidth) {

Первое слово, «это», имеет длину 4. last начинается с нуля. Итак, count+i-last равно 4 + 0-0, что 4.

Если вы введете 2 2 в свой ввод, как ваш вопрос первоначально отображался до того, как вы его редактировали, тогда maxWidth будет 2. В первая итерация вашего for l oop, if (count+i-last>=maxWidth) оценивается как «if (4> = 2)», что верно, поэтому выполняется тело оператора if, и когда оно достигает words[i-1], i-1 является отрицательным, что вызывает ваше исключение.

Однако, если вы введете 2 5 в свой ввод, maxWidth будет 5, что означает, что выражение if оценивается как «if (4> = 5) », что неверно. Тело никогда не выполняется, и words[i-1] никогда не оценивается, поэтому никогда не генерирует исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...