java - 如何在java中实现正确的完全对齐?
问题描述
我的代码在文本输入上应用 FULL justify
在许多测试中,正确的工作非常好,例如:
但是在某些输入抛出错误运行时,我不知道如何解决这个问题,请查看此代码并告诉我问题出在哪里?
主要问题是:
在句子中的每个(点,!,?)之后必须是带有大写字符的单词
非常感谢输入:
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();
}
}
主要问题是:
在句子中的每个(点,!,?)之后必须是带有大写字符的单词
请帮我
解决方案
解决此类问题的最佳方法是将问题分解为越来越小的部分,然后编写代码并测试每个小部分,直到您拥有完整的应用程序。这样做的一个好处是您在每个阶段都有一个工作应用程序,即使它是一个不完整的应用程序。另一个优点是当您遇到问题时,您只需检查一小段代码。
首先,让我们重述问题。
编写一个应用程序来完全证明文本。输入包括以下内容:
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? |
我们可以将问题分解为更小的任务。这样,当我们对每个任务进行编码时,我们可以运行一个或多个测试来验证我们是否正确地对任务进行了编码。
输入整数计数和文本。
处理文本以造出正确的句子。
证明更正的文本。
让我们处理第一个任务。
我们将编写一些代码来读取输入和输出文本。这将验证我们的应用程序的主要结构是否正常工作。使用 aScanner
可能很棘手。如果您使用该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 = 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;
}
}
在本次迭代中更容易看出我们正在使用方法并保持每个方法的内容相对较短。同样,这使得发现问题变得更加容易。我们已经对此代码进行了至少六次测试。在这一点上,我们相当确定输入被正确读取并且文本被正确转换。
这段代码并不是这些任务可以被编码的唯一方式。还有其他方法,有些方法比其他方法更有效。我的目标是提供易于理解的代码。
有了这个坚实的基础,您现在可以专注于第三个任务。我将把这项任务作为 OP 的练习,因为这是他任务的主要部分。我希望这个答案有助于教授如何处理任何问题陈述。
将问题分解成越来越小的部分并编写代码并测试每个小部分,直到您拥有完整的应用程序。
分而治之。
编辑添加
OP 给出的第三个示例隐藏了一个非常难以解决的要求。我将要求添加到问题描述中。
示例输入
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! |
附加要求定义了在何处添加额外空格以完全证明文本。
“This will be”这一行有 4 个地方可以放置额外的空间。在该示例中,将一个额外的空格添加到该行的第 4 个空格。
“你想要什么”这句话。有3个地方可以放置两个额外的空间。在示例中,一个额外的空格被添加到第三个空格,另一个额外的空格被添加到第一个空格。
从这些有限的信息中,我推断出额外空间以交替模式分布的要求,从最后一个空间开始,然后是第一个空间,然后是倒数第二个空间,然后是第二个空间,直到到达中心空间。
推荐阅读
- sql - 如何将 clob 附加到特定位置的 clob?
- c++ - Clang 10 无法在 macOS 10.12 上将 C++ 应用程序与 CMake 链接起来
- python - 我有一个从 .OptionMenu(command=argument) 获取参数的函数,在我分配数据框的函数内部
- sql - 如何计算表示按另一列分组的比例的比率?
- c# - 正则表达式获取大括号之间的文本,包括其他大括号
- java - 使用 OpenGLES 2 在 android(java) 中渲染 3D 对象时缺少某些部分
- microsoft-graph-api - 如何通过 C# Microsoft.Graph SDK 向日历添加或更新多个事件?
- python-3.x - 如何在python中从包含(或完全匹配)字符串(例如“Agg”或“Aggressive”)的目录中查找文件夹名称(不是文件名)
- c# - 如何在字符串“Regression”C#中找到隐藏的特殊字符
- python - 我的嵌套 for 循环在计算词频时花费了很多时间