关于 Ruby 中数组的简单问题 - 创建时和使用数组数据时的额外数组元素
Simply Question on Arrays in Ruby - Extra Array Element Upon Creation and When Working With Array Data
# For example, the base [1, 4, 6] gives us the following pyramid
# 15
# 5 10
# 1 4 6
def pyramid_sum(base)
pyramid = [base]
new_level = []
prev_level = []
base.length.times { |x|
prev_level = pyramid[0]
new_level = build(prev_level)
pyramid.unshift(new_level)
}
return pyramid
end
def build(level)
new_level = []
level.each_with_index { |num, index|
if index < level.length-1
new_level <<level[index] + level[index+1]
end
}
return new_level
end
print pyramid_sum([1, 4, 6]) #=> [[15], [5, 10], [1, 4, 6]]
puts
print pyramid_sum([3, 7, 2, 11]) #=> [[41], [19, 22], [10, 9, 13], [3, 7, 2, 11]]
puts
输出:
**
[[], [15], [5, 10], [1, 4, 6]]
[[], [41], [19, 22], [10, 9, 13], [3, 7, 2, 11]]
**
为什么二维数组前面总是多出一个[](空数组)?我在 Ruby 中的数组结果中多次看到这种情况,虽然它很简单,但我似乎无法弄清楚为什么那个额外烦人的数组总是存在?我知道这很简单,如果有必要,我可能会删除这个问题,但为什么我的数组前面有一个额外的数组元素?似乎只是创建一个数组,它总是有一个额外的元素,我不能“真正地”修改它,因为 Ruby 中的所有内容都是一个对象。
之所以在开始时得到额外的空数组,是因为您告诉 pyramid_sum
函数向基础添加 base.length
个更多级别。
以这种方式组成的金字塔的层数与其底部的项目数相同。
所以这意味着当你写 base.length.times { |x| ... }
时,你实际上是在说你将在基础之上添加 base.length
新的 extra 级别等级.
对于您的第一个示例,[1, 4, 6]
,这意味着您说在此基础层之上,您将再添加三层:
- 首先,您将分段总结基础层,添加
[5, 10]
- 其次,您将分部分总结新的第二层,添加
[15]
- 最后,您将尝试总结第三层的部分,这将导致
[]
原因是当您尝试对第三层求和时,其中没有足够的项目来添加下一层的任意两个数字。因此,您最终将添加未修改的空 new_layer = []
。
如果你想解决这个问题,你可以 运行 迭代 (base.length - 1).times
,或者你可以添加一个 if
语句作为保护,不添加任何生成的空层:
new_level = build(prev_layer)
if new_level.length > 0
pyramid.unshift(new_level)
end
作为第一步,我稍微重新格式化了您的代码并删除了一些无用的代码。 (例如,在 pyramid_sum
中对 new_level
和 prev_level
的赋值是无用的,因为它们会立即在块中重新赋值。)
def pyramid_sum(base)
pyramid = [base]
base.length.times do
prev_level = pyramid.first
new_level = build(prev_level)
pyramid.unshift(new_level)
end
pyramid
end
def build(level)
new_level = []
level.each_index do |index|
if index < level.length - 1
new_level << level[index] + level[index + 1]
end
end
new_level
end
删除那些无用的赋值后,产生问题的两行就在彼此的下面,问题几乎已经跳出来了:
- 金字塔的高度应始终与底部的宽度相同。
- 你预先初始化结果变量,将原始基作为金字塔的第一层。
- 但是然后你重复
build
方法 base.length
次,即 除了 你已经预初始化的一层,你 添加另一个base.length
关卡……结果,你最终得到的关卡太多了:你根据需要构建了尽可能多的关卡,但你已经在结果中加入了另一个关卡。
解决方法很简单:迭代 base.length - 1
次:
def pyramid_sum(base)
pyramid = [base]
(base.length-1).times do
prev_level = pyramid.first
new_level = build(prev_level)
pyramid.unshift(new_level)
end
pyramid
end
def build(level)
new_level = []
level.each_index do |index|
if index < level.length - 1
new_level << level[index] + level[index + 1]
end
end
new_level
end
请注意,此问题几乎 尖叫 递归。像这样:
def pyramid_sum(*base) = pyramid_rec([base]).reverse
def pyramid_rec(pyramid)
return pyramid if pyramid.last.size <= 1
pyramid_rec(pyramid << pyramid.last.each_cons(2).map(&:sum))
end
puts pyramid_sum(1, 4, 6)
puts pyramid_sum(3, 7, 2, 11)
# For example, the base [1, 4, 6] gives us the following pyramid
# 15
# 5 10
# 1 4 6
def pyramid_sum(base)
pyramid = [base]
new_level = []
prev_level = []
base.length.times { |x|
prev_level = pyramid[0]
new_level = build(prev_level)
pyramid.unshift(new_level)
}
return pyramid
end
def build(level)
new_level = []
level.each_with_index { |num, index|
if index < level.length-1
new_level <<level[index] + level[index+1]
end
}
return new_level
end
print pyramid_sum([1, 4, 6]) #=> [[15], [5, 10], [1, 4, 6]]
puts
print pyramid_sum([3, 7, 2, 11]) #=> [[41], [19, 22], [10, 9, 13], [3, 7, 2, 11]]
puts
输出: ** [[], [15], [5, 10], [1, 4, 6]] [[], [41], [19, 22], [10, 9, 13], [3, 7, 2, 11]] **
为什么二维数组前面总是多出一个[](空数组)?我在 Ruby 中的数组结果中多次看到这种情况,虽然它很简单,但我似乎无法弄清楚为什么那个额外烦人的数组总是存在?我知道这很简单,如果有必要,我可能会删除这个问题,但为什么我的数组前面有一个额外的数组元素?似乎只是创建一个数组,它总是有一个额外的元素,我不能“真正地”修改它,因为 Ruby 中的所有内容都是一个对象。
之所以在开始时得到额外的空数组,是因为您告诉 pyramid_sum
函数向基础添加 base.length
个更多级别。
以这种方式组成的金字塔的层数与其底部的项目数相同。
所以这意味着当你写 base.length.times { |x| ... }
时,你实际上是在说你将在基础之上添加 base.length
新的 extra 级别等级.
对于您的第一个示例,[1, 4, 6]
,这意味着您说在此基础层之上,您将再添加三层:
- 首先,您将分段总结基础层,添加
[5, 10]
- 其次,您将分部分总结新的第二层,添加
[15]
- 最后,您将尝试总结第三层的部分,这将导致
[]
原因是当您尝试对第三层求和时,其中没有足够的项目来添加下一层的任意两个数字。因此,您最终将添加未修改的空 new_layer = []
。
如果你想解决这个问题,你可以 运行 迭代 (base.length - 1).times
,或者你可以添加一个 if
语句作为保护,不添加任何生成的空层:
new_level = build(prev_layer)
if new_level.length > 0
pyramid.unshift(new_level)
end
作为第一步,我稍微重新格式化了您的代码并删除了一些无用的代码。 (例如,在 pyramid_sum
中对 new_level
和 prev_level
的赋值是无用的,因为它们会立即在块中重新赋值。)
def pyramid_sum(base)
pyramid = [base]
base.length.times do
prev_level = pyramid.first
new_level = build(prev_level)
pyramid.unshift(new_level)
end
pyramid
end
def build(level)
new_level = []
level.each_index do |index|
if index < level.length - 1
new_level << level[index] + level[index + 1]
end
end
new_level
end
删除那些无用的赋值后,产生问题的两行就在彼此的下面,问题几乎已经跳出来了:
- 金字塔的高度应始终与底部的宽度相同。
- 你预先初始化结果变量,将原始基作为金字塔的第一层。
- 但是然后你重复
build
方法base.length
次,即 除了 你已经预初始化的一层,你 添加另一个base.length
关卡……结果,你最终得到的关卡太多了:你根据需要构建了尽可能多的关卡,但你已经在结果中加入了另一个关卡。
解决方法很简单:迭代 base.length - 1
次:
def pyramid_sum(base)
pyramid = [base]
(base.length-1).times do
prev_level = pyramid.first
new_level = build(prev_level)
pyramid.unshift(new_level)
end
pyramid
end
def build(level)
new_level = []
level.each_index do |index|
if index < level.length - 1
new_level << level[index] + level[index + 1]
end
end
new_level
end
请注意,此问题几乎 尖叫 递归。像这样:
def pyramid_sum(*base) = pyramid_rec([base]).reverse
def pyramid_rec(pyramid)
return pyramid if pyramid.last.size <= 1
pyramid_rec(pyramid << pyramid.last.each_cons(2).map(&:sum))
end
puts pyramid_sum(1, 4, 6)
puts pyramid_sum(3, 7, 2, 11)