2013-07-22 41 views
0

下面的說明都來自問題4:「調整文本」,從Programming Olympiad 2012: Round 1Java中,控制檯精確的文字間距話

編寫一個程序,將採取提供的文本,並打印出來在 指定寬度的一列(就像在報紙上一樣)。在 處結尾的一行會超出指定的長度,必須將 移到下一行。必須在單詞之間添加空格,以便每行都精確指定寬度,並且空格儘量均勻地分佈在行上。如果一行中只有一個單詞適合 ,則該單詞必須左對齊。列的寬度將始終大於或等於9。使用下面的文字:「A 偉大的發現解決了一個大問題,但有 發現的任何問題的解決方案糧」

我使用的方法是設置的位數使用量例如寬度設置。寬度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--; 
      } 
     } 
    } 
} 
+0

聽起來就像你一次尋找各種事情的建議。你所問的一個具體問題似乎與字母寬度有關,這只是你的控制檯字體問題,而不是你的代碼。 –

回答

4
  1. 所有的代碼都擠在public static void main中。用直觀的名稱創建至少兩個方法,解釋他們如何使其更具可讀性。這樣我可以瀏覽一下,看看你在做什麼的主要主題。

  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 loop減去一行,並使其更具可讀性。

    for(String words : wordsOfLine) { 
        //access words via: 'words' 
    } 
    
  6. 遞減i-- INSIDE一個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. 

它不是完美的,因爲單詞之間的間距被確定爲號碼的字數除以需要多少額外空間才能填補空白,所以右行不是完全合理的。但比以前更合理。