在Ruby中创建一个方形乘法表

时间:2016-12-09 05:40:10

标签: ruby

我在接受采访时得到了这个问题并得到了答案,但最后一部分却陷入困境。例如,如果我想获取5的乘法表,我想让输出格式如下:

1, 2, 3, 4, 5
2, 4, 6, 8, 10
3, 6, 9, 12, 15
4, 8, 12, 16, 20
5, 10, 15, 20, 25

我对此的回答是:

def make_table(n)
  s = ""
  1.upto(n).each do |i|
    1.upto(n).each do |j|
      s += (i*j).to_s
    end
    s += "\n"
  end
  p s
end

但是make_table(5)的输出是:

"12345\n246810\n3691215\n48121620\n510152025\n"

我尝试使用数组进行变换,但我得到了类似的输出。

我错过了什么或者我应该如何看待问题的最后部分?

5 个答案:

答案 0 :(得分:2)

图之间没有空格,结果确实不可读。看一下%运算符,它会格式化字符串和数字。而不是

s += (i*j).to_s
你可以写

s += '%3d' % (i*j)

如果你真的想要按照你在帖子中解释的方式(找不到那么多的可读性)来格式化输出,你可以做一个

s += "#{i*j}, "

这会在行的末尾留下两个额外的字符,您必须删除它们。另一种方法是使用数组。而不是内循环,你会有像

这样的东西
s += 1.upto(n).to_a.map {|j| i*j}.join(', ') + "\n"

答案 1 :(得分:2)

如果您只对打印表格感兴趣而不返回表格(作为字符串),则不需要构造字符串。

(1..n).each do |a|
  (1..n-1).each { |b| print "#{a * b}, " }
  puts a * n
end

答案 2 :(得分:2)

您可以使用map和join在一行中获取String:

n = 5 
puts (1..n).map { |x| (1..n).map { |y| x * y }.join(', ') }.join("\n")

迭代行(x = 1,x = 2,...)。对于每一行,它迭代单元格(y = 1,y = 2,...)并计算x*y。它使用,连接一行中的每个单元格,并使用换行符连接表格中的每一行:

1, 2, 3, 4, 5
2, 4, 6, 8, 10
3, 6, 9, 12, 15
4, 8, 12, 16, 20
5, 10, 15, 20, 25

如果您想保持逗号对齐,可以使用rjust:

puts (1..n).map { |x| (1..n).map { |y| (x * y).to_s.rjust(3) }.join(',') }.join("\n")

输出:

  1,  2,  3,  4,  5
  2,  4,  6,  8, 10
  3,  6,  9, 12, 15
  4,  8, 12, 16, 20
  5, 10, 15, 20, 25

在对齐逗号之前,您甚至可以想象并计算n**2的宽度:

n = 11
width = Math.log10(n**2).ceil + 1
puts (1..n).map { |x| (1..n).map { |y| (x * y).to_s.rjust(width) }.join(',') }.join("\n")

输出:

   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11
   2,   4,   6,   8,  10,  12,  14,  16,  18,  20,  22
   3,   6,   9,  12,  15,  18,  21,  24,  27,  30,  33
   4,   8,  12,  16,  20,  24,  28,  32,  36,  40,  44
   5,  10,  15,  20,  25,  30,  35,  40,  45,  50,  55
   6,  12,  18,  24,  30,  36,  42,  48,  54,  60,  66
   7,  14,  21,  28,  35,  42,  49,  56,  63,  70,  77
   8,  16,  24,  32,  40,  48,  56,  64,  72,  80,  88
   9,  18,  27,  36,  45,  54,  63,  72,  81,  90,  99
  10,  20,  30,  40,  50,  60,  70,  80,  90, 100, 110
  11,  22,  33,  44,  55,  66,  77,  88,  99, 110, 121

答案 3 :(得分:1)

我就是这样做的。

require 'matrix'

n = 5

puts Matrix.build(n) { |i,j| (i+1)*(j+1) }.to_a.map { |row| row.join(', ') }
1, 2, 3, 4, 5
2, 4, 6, 8, 10
3, 6, 9, 12, 15
4, 8, 12, 16, 20
5, 10, 15, 20, 25

请参阅Matrix::build

答案 4 :(得分:0)

您可以使其更短,但这是我的版本。

range = Array(1..12)
range.each do |element|
  range.map { |item| print "#{element * item} " } && puts
end