转置字符串

时间:2014-06-13 02:32:43

标签: ruby string

给定一个(多行)字符串,其中每一行由"\n"分隔,并且可能不一定具有相同的长度,将其转换为另一个字符串的最佳方法是,如下所示?比最长的线短的线应填充空格(根据原始填充右填充,或根据输出填充底部填充)。对字符串应用两次操作应该是幂等模填充。

输入字符串

abc
def ghi
jk lm no

输出字符串

adj
bek
cf 
  l
 gm
 h 
 in
  o

5 个答案:

答案 0 :(得分:2)

以下是五种方法。 (是的,我有点失望,但我发现试图想出不同的方法来完成同样的任务对于灰色细胞是很好的锻炼。)

<强>#1

一种无趣,蛮力的方法:

a = str.split("\n")
l = a.max_by(&:size).size
puts a.map { |b| b.ljust(l).chars }
      .transpose
      .map { |c| c.join.rstrip }.join("\n")
adj
bek
cf
  l
 gm
 h
 in
  o

<强>#2

此方法及以下所有方法都避免使用ljusttranspose,并利用如果e为空数组,e.shift返回{ {1}}并留下nil一个空数组。 (旁白:我经常找到不存在的方法e。这里可以避免将每一行转换为字符数组。)

String#shift

<强>#3

这个和其余的方法避免了计算最长字符串长度的需要:

a = str.split("\n").map(&:chars)
a.max_by(&:size).size.times.map { a.map { |e| e.shift || ' ' }.join.rstrip }

<强>#4

此方法使用自{2.0}以来可用的Enumerator#lazy

a = str.split("\n").map(&:chars)
a_empty = Array(a.size, [])
[].tap { |b| b << a.map { |e| e.shift || ' ' }.join.rstrip while a != a_empty }

(我最初遇到问题,因为我没有得到输出元素(a = str.split("\n").map(&:chars) (0..Float::INFINITY).lazy.map do |i| a.each { |e| e.shift } if i > 0 a.map { |e| e.first || ' ' }.join.rstrip end.take_while { c = a.any? { |e| !e.empty? } }.to_a )。修复是添加第三行并更改{{1}后面的行我现在所拥有的。我提到这一点是因为在使用" o"时似乎可能是常见的问题。)

<强>#5

最后,使用递归:

a.map { |e| e.shift || ' ' }.join.rstrip

答案 1 :(得分:1)

我会这样写:

def transpose s
  lines = s.split(?\n)
  longest = lines.map { |l| l.length }.max

  (0..longest).map do |index|
    lines.map { |l| l[index] || ' ' }.join
  end * ?\n
end

答案 2 :(得分:0)

这个有效

s = "abc\ndef ghi\njk lm no\n"

s = s.split("\n")
s2 = ''
i = 0
while true
  line = ''
  s.each do |row|
    line += (row[i] or ' ')
  end

  if line.strip == ''
    break
  end

  s2 += line + "\n"
  i += 1
end

puts s2

这个也有效

s = "abc\ndef ghi\njk lm no\n"

s = s.split("\n")
maxlen = s.inject(0) {|m,r| m=[m, r.length].max}
s.map! {|r| r.ljust(maxlen).split(//)}
s = s.transpose.map {|r| r.join('')}.join("\n")

puts s

答案 3 :(得分:0)

关于Chron为早期版本的ruby(例如,1.8.x)所做的事情。 Example 基于显示换行符的原始输入

str="abc\\n
def ghi\\n
jk lm no\\n"


def transpose s
  lines = s.gsub("\\n","").split("\n")
  longest = lines.map { |line| line.length }.max

  (0..longest).map do |char_index|
    lines.map { |line| line.split('')[char_index] || ' ' }.join
  end * "\\n\n"
end

puts transpose(str)

答案 4 :(得分:0)

我会这样写:

def transpose_text(text)
  # split the text into lines
  text = text.split("\n")

  # find the length of the longest line
  max_line_length = text.map(&:size).max

  # pad each line with white space and convert them to character arrays
  text.map! { |line| line.ljust(max_line_length).chars }

  #transpose the character arrays and then join them all into one string
  text.transpose.map(&:join).join("\n")
end