英文:
how to implement correct full justify in java?
问题
主要问题是:在句子中的每个句点(dot,!,?)之后必须是以大写字母开头的单词。
你的代码似乎是一个Java程序,用于将文本按照指定的宽度进行齐全(justify)。你想要解决的问题是确保在句子中的标点符号后面的单词以大写字母开头。
为了解决这个问题,你可以在以下位置添加代码来检查并修复句子中标点符号后的单词的大小写:
for (int i = 0; i < size; i++) {
String line = "";
if (i == 0) {
line = fullJustify(parts, c).get(i).trim();
// 检查标点符号后的单词
line = fixCapitalization(line);
} else {
line = fullJustify(parts, c).get(i).trim();
// 检查标点符号后的单词
line = fixCapitalization(line);
}
System.out.println(line);
}
// ...
// 添加一个方法来修复标点符号后的单词的大小写
public static String fixCapitalization(String line) {
StringBuilder correctedLine = new StringBuilder();
boolean capitalizeNext = true;
for (char ch : line.toCharArray()) {
if (Character.isLetter(ch)) {
if (capitalizeNext) {
correctedLine.append(Character.toUpperCase(ch));
capitalizeNext = false;
} else {
correctedLine.append(Character.toLowerCase(ch));
}
} else {
correctedLine.append(ch);
if (ch == '.' || ch == '!' || ch == '?') {
capitalizeNext = true; // 标点符号后的单词应以大写字母开头
}
}
}
return correctedLine.toString();
}
以上代码将检查每一行中标点符号后的单词,并确保它们以大写字母开头,同时保留其他字母的小写形式。希望这可以解决你的问题。
英文:
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
答案1
得分: 2
以下是您要翻译的部分:
"处理这种问题的最佳方法是将问题分解成越来越小的部分,然后对每个小部分进行编码和测试,直到您获得一个完整的应用程序。这样做的一个优势是,即使是不完整的应用程序,每个阶段都有一个工作的应用程序。另一个优势是,当遇到问题时,您有一小段代码要检查。
首先,让我们重新阐述问题。
编写一个完全调整文本的应用程序。输入包括以下内容:
整数文本计数
由空格分隔的整数单词计数和列计数
文本输出包括以下内容:
由条形边界限定的调整文本
文本应进行更正,以便句子以大写字母开头,而所有其他字母均为小写。
每行的额外空格遵循一个简单的规则。如果有一个额外的空格,请将其添加到该行的最后一个空格中。如果有两个额外的空格,将第一个额外的空格添加到该行的最后一个空格中,将第二个额外的空格添加到该行的第一个空格中。
您继续在该行的最后一个空格和该行的第一个空格之间交替放置额外的空格,直到到达该行的中央空格。
以下是输入和输出的示例。
2
2 6
caReEr dAyS!
6 10
Are You Ready For This Question?
输出:
|Career|
|days! |
|Are you|
|ready for|
|this |
|question?|
我们可以将问题分解为较小的任务。这样,在编码每个任务时,我们可以运行一个或多个测试来验证我们已经正确编码了任务。
-
输入整数计数和文本。
-
处理文本以进行正确的句子处理。
-
调整已更正的文本。
让我们解决第一个任务。
我们将编写一些代码来读取输入并输出文本。这将验证我们已经使应用程序的主要结构工作。使用 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();
}
}
到目前为止,一切都顺利。现在我们有了一个基础,可以添加更多代码并运行更多测试。
让我们解决第二个任务。
我们可以进一步分解第二个任务,以使其更容易编码。
-
检查输入文本是否包含字符。
-
将文本转换为小写。
-
将文本转换为字符数组,并将第一个字母大写。
-
查找标点符号 (.?!之后的第一个非空白字母,并将该字母大写。
以下是第二个任务的测试结果。再次强调,我们仅输出输入文本,尽管对于此测试,文本应已更正。
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 = a> 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!
>```
希望这有助于解释如何处理任何问题陈述。将问题分解成越来越小的部分,并对每个小部分进行编码和测试。
分而治之。"
<details>
<summary>英文:</summary>
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.
</details>
# 答案2
**得分**: 0
`words[i-1]` 在循环的第一次迭代中总是会抛出异常,当 `i` 为零时... 除非输入的 `maxWidth`(第二行的第二个数字)大于第一个单词的长度,这种情况下 `for` 循环的主体将被完全跳过。
**详情:**
`sb.append(words[i-1].trim());` 引发了异常。异常消息告诉我们 `i-1` 是 -1,这当然不是数组的有效索引。
显然,这意味着 `i` 为零,这意味着这是在 `fullJustify2` 方法的第一次迭代中发生的。
让我们看看 `for` 循环开始的这两行:
count = count + words[i].length();
if (count+i-last>=maxWidth) {
第一个单词 "this" 的长度为 4。`last` 最初为零。所以,`count+i-last` 是 4+0−0,结果为 4。
如果您输入 `2 2` 到您的输入中,就像您最初显示在您编辑之前的问题中一样,那么 `maxWidth` 将为 2。在 `for` 循环的第一次迭代中,`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]` 从未被评估,因此它从未引发异常。
<details>
<summary>英文:</summary>
`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.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论