-1

My code apply FULL justify on text input

in many test correct work very good like as :

but in some input throw error run time and I don't know how to solve this, please review this code and say to me where is problem ?

main problem is :

after each (dot , ! ,? ) in sentence must will be word with capital character

very thanks input:

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

output:

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

another test:

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!

output:

|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!                |

but my problem is this that when time i give input like this:

1
2 5
this is

output show error :

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

my final code is this:

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();
}  
    

}

main problem is :

after each (dot , ! ,? ) in sentence must will be word with capital character

please help me

  • https://stackoverflow.com/questions/8524979/justify-text-in-java – Pitto Aug 02 '20 at 20:21
  • Unless you have a graphics system that does full desktop publishing, your users will probably not like full justification. I don't like it in books but have learned to deal with it. – NomadMaker Aug 02 '20 at 20:32
  • I’m not sure why you changed `2 2` to `2 5` in your sample input. `2 5` does not cause an exception, so there is no reason to ask this question in such a case. `2 2` does, however, produce the exception you describe. – VGR Aug 03 '20 at 01:25
  • @Pitto my problem is : after each (dot , ! ,? ) in sentence must will be word with capital character – mahdi norouzi Aug 03 '20 at 07:15
  • @VGR my problem is: after each (dot , ! ,? ) in sentence must will be word with capital character – mahdi norouzi Aug 03 '20 at 07:16
  • You can use RegEX for such a check, you can start with something similar: [!,?,-\.]\s+[A-Z] – Pitto Aug 03 '20 at 12:19
  • You should adjust the title for the question because the title is very different from your question. – NomadMaker Aug 03 '20 at 21:21

2 Answers2

2

The best way to approach a problem like this is to break the problem down into smaller and smaller pieces and code and test each small piece until you have a complete application. One advantage of doing this is you have a working application at each stage, even if it's an incomplete application. Another advantage is when you encounter a problem, you have a small bit of code to check.

First, let's restate the problem.

Write an application to fully justify text. The input consists of the following:

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

The output consists of the following:

Justified text bounded by bars

The text should be corrected so that sentences start with a capital letter, with all other letters lower case.

The additional spacing in each line follows a simple rule. If there's one extra space, add it to the last space in the line. If there are two extra spaces, add the first extra space to the last space in the line and the second extra space to the first space in the line.

You continue alternating between the last spaces in the line and the first spaces in the line, placing extra spaces, until you reach the center spaces in the line.

Here's an example of the input and output.

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

Output:

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

We can break the problem down into smaller tasks. That way, when we code each task, we can run one or more tests to verify that we've correctly coded the task.

  1. Input the Integer counts and text.

  2. Process the text to make correct sentences.

  3. Justify the corrected text.

Let's tackle the first task.

We'll write some code to read the input and output the text. This will verify that we have the main structure of the application working. Using a Scanner can be tricky. You have to make sure to consume the line separators if you're processing integers with the Scanner nextInt method.

Here are the test results for the first task. The first three lines constitute the input and the fourth line is the test output, which at this point, just outputs the input text line.

1
2 6
caReEr dAyS!
caReEr dAyS!

And here's the code that ran this test.

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();
    }

}

So far, so good. Now we have a basis to add a little more code and run more tests.

Let's tackle the second task.

We can break the second task down even further to make it easier to code.

  1. Check to see if the input text has characters.

  2. Convert the text to lower case.

  3. Convert the text to a character array, and capitalize the first letter.

  4. Find the first non-blank letter after a punctuation mark (.?!) and capitalize the letter.

Here are the test results from the second task. Again, we're merely outputting the input text, although, for this test, the text should be corrected.

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!

As you can see, the text is corrected. Here's the code that ran this test.

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;
    }

}

It's much easier to see in this iteration that we're using methods and keeping the contents of each method relatively short. Again, this makes finding problems much easier. We've run at least half a dozen tests on this code. At this point, we're fairly sure that the input is being read correctly and the text is being transformed correctly.

This code is not the only way that these tasks can be coded. There are other ways, some more efficient than others. My goal here is to provide easy to understand code.

With this solid base, you can now concentrate on the third task. I'm leaving that task as an exercise for the OP since that's the major part of his assignment. I hope this answer is helpful in teaching how to approach any problem statement.

Break the problem down into smaller and smaller pieces and code and test each small piece until you have a complete application.

Divide and conquer.

Edited to add

The third example given by the OP hid a requirement that turned out to be very hard to solve. I added the requirement to the problem description.

Example 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!

Example output

|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!                |

The additional requirement defines where to add the extra spaces to fully justify the text.

The line "This is going to be" has 4 places where the extra space can be placed. In the example, one extra space is added to the 4th space in the line.

The line "you what you want." has 3 places where the two extra spaces can be placed. In the example, one extra space is added to the 3rd space and the other extra space is added to the 1st space.

From this limited information, I deduced the requirement that the extra spaces are distributed in an alternating pattern, starting with the last space, then the first space, then the second to last space, then the second space, until you reach the center space.

Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
  • Magnificent and helpful answer, +1. – Pitto Aug 03 '20 at 12:16
  • very thanks mr dear ! but when time i give liks: |l r.| must be |L space space space space space r.| but not be – mahdi norouzi Aug 05 '20 at 16:42
  • And also your program have not maxword in parameter that depend of that will be show words in sentence – mahdi norouzi Aug 05 '20 at 16:53
  • @mahdi norouzi: I didn't need the word count to solve the problem. I finished the code after posting this answer. It took me a long time to figure out how to distribute the extra spaces. Your comment example has one space between the L and the R (I used upper case to make the letters easier to see), so all the additional spaces go in that one space – Gilbert Le Blanc Aug 05 '20 at 17:45
  • please see to this method : fulljustify(string, maxLength) maxlength is length in each line that put words – mahdi norouzi Aug 05 '20 at 20:34
  • for example maxLength in each line for this is : 19 |This is going to be| – mahdi norouzi Aug 05 '20 at 20:36
  • @mahdi norouzi: I'm not going to give you the complete solution. Based on what you provided in the question, I figured out how to justify the text. See my answer for the explanation. – Gilbert Le Blanc Aug 05 '20 at 20:54
  • please give me complete solution my experience is low – mahdi norouzi Aug 05 '20 at 21:42
0

words[i-1] always throws an exception in the first iteration of your loop, when i is zero… unless the entered maxWidth (the second number on the second line) is larger than the first word’s length, in which case the for loop body is skipped entirely.

Details:

sb.append(words[i-1].trim()); is throwing the exception. The exception’s message tells us that i-1 is -1, which of course is not a valid index in an array.

Obviously, that means i is zero, which means this is happening in the very first iteration of your for loop in the fullJustify2 method.

Let’s look at these two lines at the start of the for loop:

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

The first word, “this”, has a length of 4. last starts out as zero. So, count+i-last is 4+0−0 which 4.

If you enter 2 2 in your input, as your question originally showed before you edited it, then maxWidth will be 2. In the first iteration of your for loop, if (count+i-last>=maxWidth) evaluates to “if (4 >= 2)” which is true, so the body of the if statement executes, and when it gets to words[i-1], i-1 is negative which causes your exception.

However, if you enter 2 5 in your input, maxWidth will be 5, which means the if statements evaluates to “if (4 >= 5)” which is false. The body is never executed, and words[i-1] is never evaluated, so it never throws an exception.

VGR
  • 40,506
  • 4
  • 48
  • 63