0

以下说明来自2012 年编程奥林匹克第 1 轮的问题 4:“证明文本” :

编写一个程序,将提供的文本打印在指定宽度的列中(就像在报纸上一样)。行尾超出指定长度的单词必须移至下一行。必须在单词之间添加空格,以使每行都具有指定的宽度,并且空格尽可能均匀地分布在行上。如果一行中只有一个单词,则该单词必须左对齐。一列的宽度总是大于或等于九。使用以下文本:“一个伟大的发现解决了一个伟大的问题,但在任何问题的解决方案中都有一个发现”</p>

我使用的方法是将要使用的位数设置为宽度集,例如。宽度 20 = 20 位。每个数字都可以用文本中的字母或空格填充。这种方法效果不佳,因为某些字母的长度比其他字母长。

你相信我的方法是允许的吗?如何使用不同的算法产生更好的结果?我该如何改进下面的代码?

这是我的解决方案:

public class main {

    public static void main(String[] args) {
        String text = "A great discovery solves a great problem but there is a grain of discovery in the solution of any problem";
        int input = Integer.valueOf(JOptionPane.showInputDialog("Input: "));

        String[] words = text.split(" ");
        int amDigits = 0;
        ArrayList<String> wordsOfLine = new ArrayList<String>();
        String line = "";

        for(int i = 0; i < words.length; i++) {
            if(amDigits < input) {
                amDigits += words[i].length() + 1;
                wordsOfLine.add(words[i]);

            }
            else {
            //  System.out.println("Words: " + wordsOfLine);

                int totalWhiteSpace = 0;
                for(int a = 0; a < wordsOfLine.size(); a++) {
                    totalWhiteSpace = input - wordsOfLine.get(a).length();

                }
                int singleWhiteSpace = Math.round((float) totalWhiteSpace/(float) wordsOfLine.size() - 1);
                System.out.println(singleWhiteSpace);

                for(int b = 0; b < wordsOfLine.size(); b++) {
                    line += wordsOfLine.get(b);
                    for(int c = 0; c < singleWhiteSpace; c++) {
                        line += " ";

                    }

                }

                System.out.println(line);

                amDigits = 0;
                line = "";
                wordsOfLine = new ArrayList<String>();
                i--;
            }
        }
    }
}
4

2 回答 2

4
  1. 所有代码都挤在公共静态无效主体中。创建至少两个具有直观名称的方法,以解释它们如何使其更具可读性。这样我就可以浏览一下,看看你在做什么的主要主题。

  2. 您的 for 循环在循环的每次迭代中检查数组的大小。每次迭代都重新扫描阵列是浪费处理器时间。

  3. 不要将类称为“main”,而是给它一个名称来说明它的作用。像“SetFormattedSpacingWidth”或捕捉到它的本质的东西。

  4. 有一个三重嵌套的 for 循环。三重嵌套的 for 循环通常可以以多态方式重写为只有一个或最多两个 for 循环。

  5. 您正在使用 for 循环的旧方式,而不是这样:

    for(int b = 0; b < wordsOfLine.size(); b++) {
        line += wordsOfLine.get(b);
        //access words via: wordsOfLine.get(b);
    }
    

    使用新的java foreach 循环减去一行并使其更具可读性。

    for(String words : wordsOfLine) {
        //access words via: 'words'
    }
    
  6. i--在递增 i 的 for 循环内递减?这真是令人困惑。

  7. 可能会发生除以零异常。你甚至不需要抓住那些。它们应该是不可能发生的。

这是我对这个有趣问题的尝试:

import java.io.IOException;
import java.util.ArrayList;

public class DoFormattedColumnWidth {

    public static void main(String[] args) {

        String msg = "Contrary to popular belief, Lorem Ipsum is not simply " +
        "random text. It has roots in a piece of classical Latin " +
        "literature from 45 BC, making it over 2000 years old. Richard " +
        "McClintock, a Latin professor at Hampden-Sydney College in " +
        "Virginia, looked up one of the more obscure Latin words, " +
        "consectetur, from a Lorem Ipsum passage, and going through the " +
        "cites of the word in classical literature, discovered the " +
        "undoubtable source. Lorem Ipsum comes from sections 1.10.32 and " +
        "1.10.33 of \"de Finibus Bonorum et Malorum\" (The Extremes of Good " +
        "and Evil) by Cicero, written in 45 BC. This book is a treatise on " +
        "the theory of ethics, very popular during the Renaissance. The first " +
        "line of Lorem Ipsum, \"Lorem ipsum dolor sit amet..\", comes from a " +
        "line in section 1.10.32.";
        ArrayList<String> lines = 
                justifyText(msg, 25);

        for(String line : lines){
            System.out.println(line);
        }
    }
    public static ArrayList<String> justifyText(String text, int width){

        ArrayList<String> lines = new ArrayList<String>();

        String[] words = text.split(" ");

        String currentLine = "";
        int currentWord = 0;
        int len = words.length;
        int numberOfWordsThisLine=0;
        while (currentWord < len){      
            if ((currentLine.length() + words[currentWord].length()) <= width || 
                (currentLine.length() + words[currentWord].length()) > width && 
                numberOfWordsThisLine == 0){

                currentLine = currentLine + " " + words[currentWord];
                currentWord++;
                numberOfWordsThisLine++;
                if (currentWord == len)
                    lines.add(currentLine.trim());
            }
            else{
                currentLine = infuseLineWithSpaces(currentLine.trim(), 
                      width - (currentLine.trim().length()));
                lines.add(currentLine.trim());
                currentLine = "";
                numberOfWordsThisLine=0;
            }
        }
        return lines;
    }
    public static String infuseLineWithSpaces(String text, int numSpaces){

        String newText = "";
        if (numSpaces == 0) return text;
        else if (numSpaces == 1) return text + " ";
        else if (numSpaces > 1){
            String[] words = text.split(" ");
            int numberOfWords = words.length;

            int left = (numSpaces + (numberOfWords-1));
            int right = ((words.length-1));

            int numberSpacesToAddEachWord = (int)((double)left / (double)right);

            for(int x = 0; x < numberOfWords; x++){
                if (x == numberOfWords)
                    newText = newText + words[x];
                else
                    newText = newText + words[x] + getSpaces(numberSpacesToAddEachWord);
            }
        }
        else 
            return text;
        return newText;
    }
    public static String getSpaces(int spaces){
        String text = "";
        for(int x = 0; x < spaces; x++){
            text+= " ";
        }
        return text;
    }
}

哪个输出:

Contrary    to    popular
belief,  Lorem  Ipsum  is
not simply random text.
It has roots in a piece
of    classical    Latin
literature  from  45  BC,
making it over 2000 years
old. Richard McClintock,
a  Latin  professor  at
Hampden-Sydney College in
Virginia, looked up one
of the more obscure Latin
words, consectetur, from
a  Lorem  Ipsum  passage,
and  going  through  the
cites  of  the  word  in
classical     literature,
discovered            the
undoubtable source. Lorem
Ipsum comes from sections
1.10.32  and  1.10.33  of
"de  Finibus  Bonorum  et
Malorum" (The Extremes of
Good and Evil) by Cicero,
written in 45 BC. This
book is a treatise on the
theory  of  ethics,  very
popular    during    the
Renaissance.  The  first
line  of  Lorem  Ipsum,
"Lorem  ipsum  dolor  sit
amet..",  comes  from  a
line in section 1.10.32.

这并不完美,因为单词之间的间距是由一行中的单词数除以填补空白所需的额外空格数来确定的,因此正确的行并不完全合理。但这比以前更有道理。

于 2013-07-22T17:25:31.573 回答
0

如果您的控制台使用等宽字体,则不应发生这种情况。

于 2013-07-22T17:19:34.187 回答