Ruby:改变方法参数(整数与数组)
Ruby: Mutating method parameters (integer vs. array)
在下面的代码中,我的初衷是将计数器变量传递给递归运行的辅助方法,沿途更新它,然后 return 当辅助函数完成时 运行.
计数器 return 为零,我想弄清楚为什么会这样。我知道这种方法在您传入数组时有效,我相信这是因为对数组的每个引用都指向内存中的同一个对象,例如,当您使用 shovel 运算符时,您正在改变该对象。
然而,在这种情况下,情况并非如此,计数器变量被重新分配给内存中的新值(无论生成的整数指向何处)。
这是我的问题 --> 这里的问题是计数器变量被正确地重新分配,但仅在其定义的范围内?所以 return 'counter +=1' 没有做任何事情来保留对计数器变量的更改,因为在该函数的范围内(并且仅在函数的范围内)计数器变量被重新分配?很难彻底理解这一点。以下是感兴趣的人的问题陈述:
给定一个包含所有正数且无重复的整数数组,找出加起来达到正整数目标的可能组合的数量。
Example:
nums = [1, 2, 3]
target = 4
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.
Therefore the output is 7.
这是我的代码:
# @param {Integer[]} nums
# @param {Integer} target
# @return {Integer}
def combination_sum4(nums, target)
nums.sort! # n log n
generate_combinations(nums, target, counter = 0)
counter
end
def generate_combinations(nums, target, counter)
return counter += 1 if target == 0
(1...nums.length).each do |num|
break if num > target
generate_combinations(nums, target - num, counter)
end
counter
end
这是范围问题。您传递给 generate_combinations
的局部变量 counter
与其中的 counter
不同。方法中定义的局部变量的范围仅限于该方法。当您将它们传递给另一个方法时,您传递的是变量的值,而不是变量本身。在 combination_sum4
中,counter
永远不会改变其原始值 0
。
解决方案
1) 使用一个实例变量@counter
,只要它们定义在同一上下文中,或在同一class 或模块中,这些方法就可以共享该实例变量。如果您稍后需要在后续方法调用期间访问相同的值,这将很有帮助。
2) 不要在combination_sum4
的末尾returncounter
。将 generate_combinations
作为方法的最后一行。 return 也将被 combination_sum4
编辑 return。
def combination_sum4(nums, target)
nums.sort! # n log n
generate_combinations(nums, target)
end
def generate_combinations(nums, target, counter = 0) # `counter` is now an optional argument with a default value of `0`
return counter + 1 if target.zero?
nums.each do |num| # use inclusive range (..) rather than exclusive range (...)
break if num > target
counter = generate_combinations(nums, target - num, counter) # reassign `counter` to the return value of the recursion
end
counter
end
@m-simon-borg 已经完美地解释了你的问题:你有范围问题。
但是,我建议使用 inject
的 "rubyest" 方法(@see:https://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-reduce):
def combination_sum4(nums, target)
generate_combinations(nums.sort, target, 0)
end
def generate_combinations(nums, target, counter)
return counter += 1 if target == 0
(1..nums.length).inject(counter) do |counter, num|
num > target ?
counter :
generate_combinations(nums, target - num, counter)
end
end
nums = [1, 2, 3]
target = 4
combination_sum4(nums, target) # 7
在下面的代码中,我的初衷是将计数器变量传递给递归运行的辅助方法,沿途更新它,然后 return 当辅助函数完成时 运行.
计数器 return 为零,我想弄清楚为什么会这样。我知道这种方法在您传入数组时有效,我相信这是因为对数组的每个引用都指向内存中的同一个对象,例如,当您使用 shovel 运算符时,您正在改变该对象。
然而,在这种情况下,情况并非如此,计数器变量被重新分配给内存中的新值(无论生成的整数指向何处)。
这是我的问题 --> 这里的问题是计数器变量被正确地重新分配,但仅在其定义的范围内?所以 return 'counter +=1' 没有做任何事情来保留对计数器变量的更改,因为在该函数的范围内(并且仅在函数的范围内)计数器变量被重新分配?很难彻底理解这一点。以下是感兴趣的人的问题陈述:
给定一个包含所有正数且无重复的整数数组,找出加起来达到正整数目标的可能组合的数量。
Example:
nums = [1, 2, 3]
target = 4
The possible combination ways are:
(1, 1, 1, 1)
(1, 1, 2)
(1, 2, 1)
(1, 3)
(2, 1, 1)
(2, 2)
(3, 1)
Note that different sequences are counted as different combinations.
Therefore the output is 7.
这是我的代码:
# @param {Integer[]} nums
# @param {Integer} target
# @return {Integer}
def combination_sum4(nums, target)
nums.sort! # n log n
generate_combinations(nums, target, counter = 0)
counter
end
def generate_combinations(nums, target, counter)
return counter += 1 if target == 0
(1...nums.length).each do |num|
break if num > target
generate_combinations(nums, target - num, counter)
end
counter
end
这是范围问题。您传递给 generate_combinations
的局部变量 counter
与其中的 counter
不同。方法中定义的局部变量的范围仅限于该方法。当您将它们传递给另一个方法时,您传递的是变量的值,而不是变量本身。在 combination_sum4
中,counter
永远不会改变其原始值 0
。
解决方案
1) 使用一个实例变量@counter
,只要它们定义在同一上下文中,或在同一class 或模块中,这些方法就可以共享该实例变量。如果您稍后需要在后续方法调用期间访问相同的值,这将很有帮助。
2) 不要在combination_sum4
的末尾returncounter
。将 generate_combinations
作为方法的最后一行。 return 也将被 combination_sum4
编辑 return。
def combination_sum4(nums, target)
nums.sort! # n log n
generate_combinations(nums, target)
end
def generate_combinations(nums, target, counter = 0) # `counter` is now an optional argument with a default value of `0`
return counter + 1 if target.zero?
nums.each do |num| # use inclusive range (..) rather than exclusive range (...)
break if num > target
counter = generate_combinations(nums, target - num, counter) # reassign `counter` to the return value of the recursion
end
counter
end
@m-simon-borg 已经完美地解释了你的问题:你有范围问题。
但是,我建议使用 inject
的 "rubyest" 方法(@see:https://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-reduce):
def combination_sum4(nums, target)
generate_combinations(nums.sort, target, 0)
end
def generate_combinations(nums, target, counter)
return counter += 1 if target == 0
(1..nums.length).inject(counter) do |counter, num|
num > target ?
counter :
generate_combinations(nums, target - num, counter)
end
end
nums = [1, 2, 3]
target = 4
combination_sum4(nums, target) # 7