简体   繁体   English

如何格式化基于指定长度的空格?

[英]How to format a String with spaces based on a specified length?

Trying to create a method in Java formats the string by stretching the content (by putting appropriate number of whitespaces) of a buffer, based on the length. 尝试用Java创建方法通过基于长度扩展缓冲区的内容(通过放置适当数量的空格)来格式化字符串。 So, based on a particular length given, the first character of the string is in the first index and the last character is located at the actual last index itself. 因此,基于给定的特定长度,字符串的第一个字符位于第一个索引中,而最后一个字符位于实际的最后一个索引本身。

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();
}

For this unit test, this works: 对于此单元测试,它可以:

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

So, here, the maximum buffer size is: 20 因此,此处的最大缓冲区大小为:20

Total number of used characters is: 10 使用的字符总数为:10

Total number of unused characters is: 10 未使用的字符总数为:10

The end result (if you print the String) is: 最终结果(如果打印字符串)为:

brown     clown

The "n" in clown is at index 20... 小丑中的“ n”在索引20处。

However, there is an edge case with the following test (which causes it to break): 但是,在进行以下测试时会出现边缘情况(这会导致其破裂):

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

Buffer size: 50 缓冲区大小:50

Total Used Characters: 25 Total Unused Characters: 25 已使用的字符总数:25未使用的字符总数:25

Spaces: 3 空间:3

Final Length: 48 最终长度:48

The end result (if you print the String) is: 最终结果(如果打印字符串)为:

Love     programming    Java    using    Eclipse!

Why is the final index 48 instead of 50? 为什么最终指数是48,而不是50?

The exclamation point "!" 感叹号“!” after "Eclipse", should be at 50 instead of 48... 在“ Eclipse”之后,应该是50,而不是48 ...

Am suspecting that its due to my spaces calculation being off. 我怀疑这是由于我的空间计算被关闭了。

Thanks for taking the time to read this. 感谢您抽时间阅读。

For this test 对于这个测试

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

This happens because you are dividing: 发生这种情况是因为您正在划分:

int spaces = emptyCharacters / words.length - 1;

This results in (66 / 8) - 1) = 7.25, and then you have a for loop, which does not account for the extra .25 This means you will not fill the desired buffer length. 这导致(66/8)-1)= 7.25,然后您有了一个for循环,该循环没有考虑额外的.25,这意味着您将无法填充所需的缓冲区长度。

Also, since you declared it as int, you will not get the extra 0.25, so you should change it to double , and cast the others as double as well. 另外,由于您将其声明为int,因此不会获得额外的0.25,因此应将其更改为double ,并将其他类型也强制转换为double。

You then can count the words and check if the extra 0.25 multiplied by the counter reaches 1, you add a space, and reset the counter. 然后,您可以对单词进行计数,并检查额外的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;
        }
    }

Something like this. 这样的事情。 The problem resides in that not all words can have the same number of spaces. 问题在于并非所有单词都可以具有相同数量的空格。 Some will have more, some will have less, in order to accommodate for the static buffer length. 为了适应静态缓冲区的长度,有些会有更多,有些会有更少。 This is also a special case, because the remainder is 0.25, and will produce exactly 2 spaces, You still need to accommodate for the remainder of the remainder. 这也是一种特殊情况,因为余数为0.25,并且将恰好产生2个空格,因此您仍然需要容纳余数。 (In case it does not reach 1 and you still have one more word.) (如果它没有达到1,并且您还有一个字。)

The following code makes up for this. 以下代码弥补了这一点。

    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.
        }
    }

This is not, in any way, elegant, but it works, for the previous test, and for example, for this new one: 无论如何,这都不是很优雅,但是它可以用于先前的测试,例如,对于新的测试:

@Test
public void isCorrectLength() {
    String value = StringUtils.format("We went to the giant slope and snowboarded for hours., 103);
    assert(value.length() == 103);
}
  1. Split the string into words, based on white space. 根据空格将字符串拆分为单词。
  2. Find the number of total spaces needed to pad the words to the desired string length (total length of string - words length). 找到将单词填充到所需字符串长度(字符串的总长度-单词长度)所需的总空格数。
  3. Find the number of "space blocks" to be placed between words (number of words - 1). 找到要在单词之间放置的“空格”的数量(单词数-1)。
  4. Build the "space blocks" by iteratively adding spaces to each space block until we run out of spaces (see step 2). 通过反复向每个空格块中添加空格来构建“空格块”,直到我们用完空格为止(请参见步骤2)。
  5. Re-assemble the sentence by placing word, space block, word, etc. 通过放置单词,空格,单词等来重新组合句子。

    private static String formatString(String sentence, int length) { // parse words by white space String[] words = sentence.split("\\s+"); 私有静态String formatString(String string,int length){//用空格解析单词String [] words = statement.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(); 

    } }

    public static void main(String[] args) { String s; public static void main(String [] args){String s; String t; 字符串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())); 

    } }

Output, 输出,

"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)

In the cases where the spaces don't result in all even-length space blocks, the code favors placing them in the earlier-occurring space blocks. 在空格未包含所有偶数长度的空格的情况下,代码倾向于将其放置在较早出现的空格中。

Note for clarity I did not code edge cases (one-word strings, zero-length output, null inputs, words don't fit in buffer, etc). 为了清楚起见,请注意,我没有对边缘情况进行编码(一个单词的字符串,零长度的输出,空输入,单词不适合缓冲区等)。 That's left as an exercise for the reader. 留给读者练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM