2016-09-20 116 views
4

嘗試在Java中創建方法時,通過基於長度擴展緩衝區的內容(通過放入適當數量的空白)來格式化字符串。因此,根據給定的特定長度,字符串的第一個字符位於第一個索引中,而最後一個字符位於實際的最後一個索引本身。如何使用基於指定長度的空格來格式化字符串?

public static String format(String sentence, int length) { 
    if (sentence.length() >= length) { 
     return sentence; 
    } 
    StringBuilder sb = new StringBuilder(); 

    String[] words = sentence.split("\\s+"); 

    int usedCharacters = 0; 

    for (String word : words) { 
     usedCharacters += word.length(); 
    } 

    int emptyCharacters = length - usedCharacters; 
    int spaces = emptyCharacters/words.length - 1; 

    for (String word : words) { 
     sb.append(word); 
     for (int i = 0; i <= spaces; i++) { 
      sb.append(" "); 
     } 
    } 
    return sb.toString(); 
} 

對於這個單元測試,這工作:

@Test 
public void isCorrectLength() { 
    String value = StringUtils.format("brown clown", 20); 
    assert(value.length() == 20); 
} 

所以,在這裏,最大緩衝器大小是:20

的使用的字符總數爲:10

總未使用字符的數量爲:10

最終結果(如果您打印字符串)是:

brown  clown 

在小丑的 「n」 是在索引20 ...

然而,存在邊緣的情況下使用以下測試(這會導致它打破):

@Test 
public void isCorrectLengthWithLongerSentence() { 
    String value = StringUtils.format("Love programming Java using Eclipse!", 50); 
    assert(value.length() == 50); 
} 

緩衝區大小:50個

總使用的字符:25個 總計未使用的字符:25

個空間:3

最終長度:48

最終的結果(如果打印字符串)是:

Love  programming Java using Eclipse! 

爲什麼最終指數48,而不是50?

感嘆號「!」在「Eclipse」之後,應該是50而不是48 ...

我懷疑它是由於我的空間計算關閉了。

感謝您花時間閱讀本文。

+1

我猜測這是因爲你正在爲你的空間計算使用一個int,所以四捨五入成爲一個問題。單詞之間的空格不能相同。 –

+0

問題出在'int spaces = emptyCharacters/words.length - 1;'。首先,我認爲你的意思是'emptyCharacters /(words.length - 1)'。其次,正如@SamOrozco所說,如果它不能均勻分配,您將需要不同數量的空格... – qxz

+0

我很確定這是在AP Comp上。科學。去年考試:D – qxz

回答

2

對於此測試

@Test 
public void isCorrectLength() { 
    String value = StringUtils.format("Went to the slope and snowboarded for hours., 103); 
    assert(value.length() == 103); 
} 

這是因爲你正在分裂:

int spaces = emptyCharacters/words.length - 1; 

這導致(66/8) - 1)= 7.25,然後有一個循環,這沒有考慮到額外的.25這意味着你不會填充所需的緩衝區長度。

此外,由於您將它聲明爲int,所以您不會得到額外的0.25,因此您應該將其更改爲double,並將其他值轉換爲double值。

然後您可以計算單詞並檢查額外的0.25乘以計數器是否達到1,您添加一個空格並重置計數器。

double spaces = (double)emptyCharacters/(double)words.length - 1.0; 

    double extraSpace = spaces % 1; 
    double counter = 0; 
    for (String word : words) { 
     counter++; 

     sb.append(word); 
     for (int i = 0; i <= spaces; i++) { 
      sb.append(" "); 
     } 

     if ((counter * extraSpace) >= 1) { 
      sb.append(" "); // This is the extra space. 
      counter = 0; 
     } 
    } 

就是這樣。問題在於,並非所有單詞都可以具有相同數量的空格。爲了適應靜態緩衝區的長度,一些會有更多,有些會少些。這也是一種特殊情況,因爲餘數是0.25,並且會產生正好2個空格,您仍然需要適應其餘的餘數。 (如果它沒有達到1,並且你還有一個字)

下面的代碼彌補了這一點。

double spaces = (double)emptyCharacters/(double)words.length - 1.0; 

    double extraSpace = spaces % 1; 
    double counter = 0; 
    int wordIndex = 0; 
    for (String word : words) { 
     counter++; 
     wordIndex++; 

     sb.append(word); 
     for (int i = 0; i <= spaces; i++) { 
      sb.append(" "); 
     } 

     if ((counter * extraSpace) >= 1) { 
      sb.append(" "); // This is the extra space. 
      counter = 0; 
     } 

     if ((wordIndex == words.length - 1) && (counter * extraSpace) > 0) { 
      sb.append(" "); // This accounts for remainder. 
     } 
    } 

這不以任何方式,優雅,但它的工作原理,對於以前的測試,例如,對於這個新的:

@Test 
public void isCorrectLength() { 
    String value = StringUtils.format("We went to the giant slope and snowboarded for hours., 103); 
    assert(value.length() == 103); 
} 
+1

我不會爲此使用浮點數,因爲float不精確。例如,考慮如果extraSpace = 0.3333會發生什麼情況。當你添加其中三個時,它不會達到1. –

+0

這是一個很好的觀察。我們應該使用雙?或者,也許增加一些精度寬容? –

+0

你可以做的是使用浮點數來計算空格,分數,隨着時間的推移和每次舍入以確定要添加的空格數。同時用可用空間的數量初始化一個int,並減少要添加的實際空間數量。然後,對於最後一組,只需使用剩餘空間計數作爲插入計數,而不是使用的分數累加器。這應該涵蓋所有情況,並以精確的總數進行良好的均勻分配。 –

1
  1. 拆分串入的話,基於空白。
  2. 查找將單詞填充到所需的字符串長度(字符串的總長度 - 單詞長度)所需的總空格數。
  3. 找出放置在單詞之間的「空格塊」的數量(單詞數量 - 1)。
  4. 通過向每個空間塊反覆添加空格來構建「空間塊」,直到空間用盡(請參閱步驟2)。
  5. 重新組裝通過將字,空間塊,字,等等

    私有靜態字符串formatString的(字符串的句子,INT長度){// 由空格 字符串[]字解析話句子= sentence.split( 「\ S +」);

    // calc the char length of all words 
    int wordsLength = 0; 
    for (String w: words) { 
        wordsLength += w.length(); 
    } 
    
    // find the number of space blocks and initialize them 
    int spacesLength = length - wordsLength; 
    String[] spaceBlocks = new String[words.length - 1]; 
    Arrays.fill(spaceBlocks, ""); 
    
    // distribute spaces as evenly as possible between space blocks 
    int spacesLeft = spacesLength; 
    int k = 0; 
    while (spacesLeft > 0) { 
        spaceBlocks[k++] += " "; 
        if (k == spaceBlocks.length) { 
         k = 0; 
        } 
        spacesLeft--; 
    } 
    
    // assemble the buffer: for each word, print the word, then a spaces block, and so on 
    StringBuilder b = new StringBuilder(); 
    for (int i = 0; i < words.length; i++) { 
        b.append(words[i]); 
        if (i < spaceBlocks.length) { 
         b.append(spaceBlocks[i]); 
        } 
    } 
    return b.toString(); 
    

    }

    公共靜態無效的主要(字串[] args){ 的String; String t;

    s = "Hello, spaces."; 
    t = formatString(s, 50); 
    System.out.println(String.format("\"%s\" (length=%d)", t, t.length())); 
    
    s = "Hello, spaces."; 
    t = formatString(s, 51); 
    System.out.println(String.format("\"%s\" (length=%d)", t, t.length())); 
    
    s = "Good day, spaces."; 
    t = formatString(s, 52); 
    System.out.println(String.format("\"%s\" (length=%d)", t, t.length())); 
    
    s = "The quick brown fox."; 
    t = formatString(s, 53); 
    System.out.println(String.format("\"%s\" (length=%d)", t, t.length())); 
    
    s = "Ask not what your country can do for you."; 
    t = formatString(s, 54); 
    System.out.println(String.format("\"%s\" (length=%d)", t, t.length())); 
    
    s = "Ask not what your country can do for you, Bob."; 
    t = formatString(s, 55); 
    System.out.println(String.format("\"%s\" (length=%d)", t, t.length())); 
    

    }

輸出,

"Hello,          spaces." (length=50) 
"Hello,          spaces." (length=51) 
"Good     day,     spaces." (length=52) 
"The   quick   brown   fox." (length=53) 
"Ask not what your country can do for you." (length=54) 
"Ask not what your country can do for you, Bob." (length=55) 

在情況下的空間不會導致所有偶數長度空白塊,代碼有利於將它們放置在前面 - 發生空間塊。

爲了清楚起見,我沒有編碼邊緣情況(單字串,零長度輸出,空輸入,單詞不適合緩衝區等)。這留給了讀者一個練習。

+0

我放棄了試圖讓SO正確格式化。如果其他人可以修復它,謝謝。 –