【发布时间】:2021-08-05 06:41:23
【问题描述】:
问题
我正在编写一个程序来在控制台中显示标签(字符串),我需要将它们放在特定的宽度内。当它们的总长度太大时,我需要截断一些标签。我正在寻找一种有效的算法来计算要截断的所有字符串的最大大小。
例如,假设我们有 3 个标签要显示,总可用大小为 12 个字符。以下代码块显示了如何将它们放入可用空间中。 (在实际情况中我们还需要它们之间的分隔符,但为简单起见,此处省略。)
The tags:
11111 5 chars wide
2222222 7 chars
333 3 chars
The space:
|------------| 12 chars
Not truncated:
111112222222333 5+7+3 = 15 chars, too long
Truncate every tag to 4 chars:
11112222333 4+4+3 = 11 chars, fits
同样,如果空格长度为 13 个字符,则截断大小为 5 个字符:
|-------------|
1111122222333 5+5+3 = 13 chars, fits
我目前的解决方案
我目前使用一种简单的方法来解决这个问题。这是伪代码:
// the input
tags = [...]
target_width = ...
tag_widths = tags.map(x => x.width).sort()
total_width = tag_width.sum()
truncated_count = 0
truncate_to = tag_widths[0]
// list of items
// v | <- truncation line
// *******|
// ***** |
// *** |
while true {
// find the next group of tags with the same length
//
// |
// ******* <-
// *****|
// *** |
truncated_count += 1
while truncated_count < tags.length
&& tag_widths[truncated_count] == truncate_to {
truncated_count += 1
}
// new_truncate_to is the width of the next group
new_truncate_to = tag_widths[truncated_count] or 0 if truncated_count > tags.length
// calculate the length after truncating all of them
//
// |
// *****|--
// *****|
// *** |
new_total_width = total_width - truncated_count * (new_truncate_to - truncate_to)
if new_total_width <= target_width {
// the target length is between truncate_to and new_truncate_to
// |
// ******|-
// ***** |
// *** |
new_truncate_to += floor((target_width - new_total_width) / truncated_count)
truncate_to = new_truncate_to
break
} else {
// the current truncation is not enough
total_width = new_total_width
truncate_to = new_truncate_to
}
}
// the result
truncate_to
有没有更高效的算法?
【问题讨论】: