Java 如何根据指定的长度格式化带有空格的字符串?
尝试在Java中创建一个方法,通过根据长度拉伸缓冲区的内容(放置适当数量的空白)来格式化字符串。因此,根据给定的特定长度,字符串的第一个字符位于第一个索引中,最后一个字符位于实际的最后一个索引本身Java 如何根据指定的长度格式化带有空格的字符串?,java,string,Java,String,尝试在Java中创建一个方法,通过根据长度拉伸缓冲区的内容(放置适当数量的空白)来格式化字符串。因此,根据给定的特定长度,字符串的第一个字符位于第一个索引中,最后一个字符位于实际的最后一个索引本身 public static String format(String sentence, int length) { if (sentence.length() >= length) { return sentence; } StringBuilder s
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();
}
这里,最大缓冲区大小是:20
使用的字符总数为:10
未使用的字符总数为:10
最终结果(如果打印字符串)为:
小丑中的“n”在索引20处
但是,以下测试存在边缘情况(导致其断裂):
缓冲区大小:50
使用字符总数:25
未使用字符总数:25
空间:3
最终长度:48
最终结果(如果打印字符串)为:
为什么最终指数是48而不是50
“Eclipse”后面的感叹号“!”应该是50而不是48
我怀疑这是因为我的空间计算被关闭了
感谢您抽出时间阅读本测试。
@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,然后您有一个for循环,它不考虑额外的.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;
}
}
"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)
如果空格不会产生所有偶数长度的空格块,则代码倾向于将它们放置在较早出现的空格块中
注意:为了清楚起见,我没有对边缘情况进行编码(单字字符串、零长度输出、空输入、字不适合缓冲区等)。这留给读者作为练习。我猜这是因为在计算空格时使用了int,所以舍入成为一个问题。单词之间的空格不能完全相同。问题在于
int spaces=emptyCharacters/words.length-1代码>。首先,我想你的意思是空字符/(words.length-1)
。其次,正如@SamOrozco所说的,如果它不能平均分配,你将需要不同数量的空格……我很确定这是在美联社上。Sci。去年的考试:根据一个想法,尝试使用Bresenham线算法的一个变体来实现这一点可能是一个有趣的练习,使用(wordcount-1)作为delta y,使用(availableadding)作为delta x,以获得精确的规则空间分布。该算法本质上是将一个给定长度的空间划分为一组长度为n和n+1的重复序列。例如,如果ExpAsACE=0.3333,会发生什么。当你加上其中的三个时,它并不等于每个1。这是一个很好的观察结果。我们应该用双人床吗?或者可以添加一些精度公差?您可以使用一个浮点来计算空格,每次都用分数,然后四舍五入来确定要添加的空格数。同时,用可用的空格数初始化一个int,并减少实际添加的空格数。然后,对于最后一组,只使用剩余空间计数作为插入计数,而不是您一直使用的分数累加器。这应该涵盖所有情况,并给出一个良好的均匀分布和精确的总数。Jason C,感谢您的回复。。。你能提供一些代码作为例子吗?嗨,Basilio German,对不起,它仍然用你的代码打印101,而不是103。尽管如此,还是感谢您提供代码!我放弃了让它正确格式化的尝试。如果有人能修好,谢谢。
@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;
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;
}
}
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);
}
// 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();
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)