2016-12-26 135 views
0

需要做的理由对于给定的字符串与所述给定长度,对齐字符串红宝石

ss = "There is an example to make Justify the text us" 

Total length = 50 

需要的输出:

ss = "There is an example to make Justify the text us" 

这里串的长度与50字符调节之后加入间距第一个字符“There”,最后一个字符“us”,“text”。

都试过了,

qw = "" 
string.split(" ").each_with_index do |x,i| 
qw = qw + " " + x 

end 

,但不能能够增加空间

+1

这是非常不清楚你问我害怕。这些空间的目的是什么?它们应该放置在什么地方? – Iceman

+0

我需要在红宝石中对整个段落进行论证(每行50个字符),我做了50或50个字符以上的分割,并且没有打破文字。现在我需要添加行距小于50个字符的行。 –

回答

0

假设你想先添加空间最后一个字,然后在第一,然后到倒数第二等:

def justify(str, length) 
    words = str.split(/\s+/) 
    cnt = words.size - 1 
    return str if cnt < 1 
    return str if str.size >= length 

    diff = length - str.size 
    base = diff/cnt + 1 
    rest = diff % cnt 

    cnt.times.each.with_index do |word, i| 
    r = [i + 1, cnt - i - 1].min * 2 <= rest && rest > 0 ? 1 : 0 
    rest -= r 
    words[i] << " " * (base + r) 
    end 
    words.join 
end 

justify("There is an example to make Justify the text us", 50) 
#=> "There is an example to make Justify the text us" 

justify("One more example", 50) 
#=> "One     more     example" 

justify("Or this", 50) 
#=> "Or           this" 

justify("Example", 50) 
#=> "Example" 

justify("There is an example to make Justify the very long text us", 50) 
#=> "There is an example to make Justify the very long text us" 
+0

看起来不错,您的输出完全符合我的要求。谢谢 –

0

您的示例代码是不工作的原因是split消耗的分隔符。

'a b c'.split.to_a #=> ['a', 'b', 'c'] 

当您手动重装你的字符串,你加入,你消耗的界定空间,导致相同的字符串一个空格()。

正如评论所建议的那样,您尚未向我们提供足够的信息来说明您想如何处理此问题。如果只有一个字会发生什么?如果我们有更多的字符而不是线条应该是什么?你想如何称重空间?你需要考虑文本的渲染宽度吗?这很快成为一个更复杂的项目。

但是,请注意,大多数视图(无论是移动设备,网页还是外壳)都有方法来验证您可以利用的文本的效果。

这一切都表示,这里是一种工作示例中忽略的边缘情况:

input = "There is an example to make Justify the text us" 
words = input.split 
spaces_needed = 50 - input.scan(/[^ ]/).length 
spaces_per_word = Float(spaces_needed)/(words.count - 1) 

words.each_with_index.map do |word, i| 
    word += ' ' if (spaces_per_word * (i + 1)) % 1 == 0 
    word 
end.join(' ') 
1

试试这个,

str = 'There is an example to make Justify the text us' 

words = str.split 
width, remainder = (50 - words.map(&:length).inject(:+)).divmod(words.length - 1) 
width, remainder = 1, 0 if width.zero? # take care of long lines 
words.take(words.length - 1).each { |word| width.times { word << 32 }} 
words.take(words.length - 1).shuffle.take(remainder).each { |word| word << 32 } 
p words.join 

这是如何工作的?

  • 分割字符串成字
  • 计算的空间宽度和余k
  • 附加空间宽度到所有的话,但最后一个
  • 追加一个空间的k
+0

啊哈。尼斯。我从来没见过'string << 32'。 PS:这可能只是一个个人的观点,但我觉得每个人都是混淆的变数名称。 –

+0

可能不是最易读的,但可避免创建临时字符串。鉴于Ruby的坏垃圾收集,这是生产代码的好习惯。 – akuhn

+0

关于“每个”的好处,已更新。 – akuhn

0
随机样本

这里有一个合理可读的方式来做到这一点:

def padString (str,width) 
    words = str.split.map{|s|s+" "}  # words single spaced 
    padding = width-words.join.length+1 # how much needs adding? 
    locations = words.size - 1   # places space can be added 
    return str if padding<0 or words==[] # abort if string too long or empty 
    padding.times { 
     words[rand(locations)] += " " # append space to random location 
    } 
    words.join.strip!     # reconstitute the string 
end 

它随机添加填充,所以你得到不同的线通过每个时间:

padString("There is an example to make Justify the text us",50) 
=> "There is an example to make Justify the text us" 

padString("There is an example to make Justify the text us",50) 
=> "There is an example to make Justify the text us" 

padString("hey you",50) 
=> "hey           you" 

padString("hey",50) 
=> "hey"