我正在coderbyte 解决这个问题
使用Ruby语言,让函数NumberSearch(str)接受str参数,搜索字符串中的所有数字,将它们相加,然后返回最终数字。例如:如果str是"88Hello3World!",那么输出应该是91。你必须像上面的例子一样区分个位数和多位数。因此,"55你好"one_answers"5你好5"应该返回两个不同的答案。每个字符串将至少包含一个字母或符号
我第一次尝试解决数字搜索问题的结果是下面的代码。然而,在提交它之后,它不适用于"1 2 3 4 k10"
的情况,这在比较我的代码后是显而易见的。
如果我使用正则表达式并根据非数字字符对其进行拆分,然后在拆分后的数组中添加每个元素,那么解决方案会更优雅,但我想尝试使用长方法进行求解。
如何修复此代码,使其也适用于"1 2 3 4 k10"
的情况?我的代码的目的是搜索字符串中的所有元素,如果它在字符串块中看到更多的数字,就会将字符串相加。如果下一个字符串不是数字,则它重置num_str
。我会得到一个数字字符串的数组,它是num_arr
。
我的原始代码:
def NumberSearch(str)
num_str = "" #store numbers with more than one digit
num_arr = [] #number storage
sum = 0
i = 0
while i<=str.length
if str[i,1].to_i>0
num_str = num_str + str[i,1]
elsif str[i,1].to_i == 0 #str[i].to_i is 0
num_arr << num_str.to_i
num_str = "" #reset string number
end
i += 1
end
num_arr.each do |x|
sum = sum + x
end
return sum
end
编辑:
按照Beartech下面的建议,我更新了代码。我使用字符串.include?
方法而不是数组.include?
方法。方法名称也来自Coderbyte。在方法名称中使用大写字母是不符合规则的。
def NumberSearch(str)
num_str = "" #store numbers with more than one digit
num_arr = [] #number storage
sum = 0
i = 0
#str<<"required!" #add nondigit character for code to work
while i<str.length
if "0123456789".include? str[i,1]
num_str = num_str + str[i,1]
elsif #note the "required" was added earlier because of this section here
num_arr << num_str.to_i
num_str = "" #reset string number
end
i += 1
end
num_arr.each do |x|
sum = sum + x
end
return sum
end
def number_search(check_str)
# do not use capital letter at beginning of name, use "snake case" if you want to do it the ruby way
# initialize empty arrays to hold the number and the group of numbers
num_hold = []
num_arr = []
# split your string into individual characters
y = check_str.split('')
# add an element to the signal the end of the array, use any non-number.
y << "hey!"
#now iterate through your array using `each`.
y.each do |char|
# if the char passed in is a digit then put it in the holder array and go to the next character.
if %w(0 1 2 3 4 5 6 7 8 9).include? char
num_hold << char
# if it's not a digit, then take all of the digits currently in the holder and join them.
# then take the joined string, make it an integer and put it in the array of numbers.
else
num_arr << num_hold.join.to_i
num_hold = [] # be sure and reset the num_hold array to empty
end
end
# now we use another iterator, `inject` to add up all of the numbers in the array.
num_arr.inject {|sum, n| sum + n}
end
我添加了很多评论来帮助你了解自从你说自己是新手以来发生了什么。需要注意的两件事:
1) 需要添加"嘿!",因为如果最后一个数字后面没有非数字,.each
语句中的逻辑将不知道该怎么处理,所以它会丢失。
2) 使用像.each
和.inject
这样的迭代器。如果你要学习Ruby,那么你能为自己做的最好的事情就是去文档中阅读模块Enumerable中所有可用的方法。说真的,现在就去读吧http://ruby-doc.org/core-2.2.1/Enumerable.html
这将为您节省许多while/if/else/until/for语句。Enumerables有巨大的力量。其中许多是由Array和Hash继承的。
inject
是一个有些人很难相处的问题,我知道一开始对我来说并不明显。但它基本上是在列表中迭代,将每个项目传递到循环中,但与每个项目不同的是,它有memo
(这里我使用变量sum
),这只是起始值。你可以将起始值设置为任何值。因此,如果您想将10添加到数组的总数中,您可以设置memo = 10
作为开始。请注意,我没有将sum
设置为任何值。如果不设置它,它将获取数组中的第一个值,并从第二个值开始|n|off。
我会仔细研究这个解决方案,看看你是否可以将其重构为:
str.scan(/d+/).inject(0) {|sum,n| sum + n.to_i}
这是像Ruby这样的语言的核心。它可以让你把你的方法链起来,把复杂的结构做成上面的一行。