编号搜索Coderbyte Ruby

时间:2015-03-21 18:21:46

标签: ruby

我在coderbyte解决了这个问题

使用Ruby语言,让函数NumberSearch(str)取str参数,搜索字符串中的所有数字,将它们加在一起,然后返回最后的数字。例如:如果str是" 88Hello 3World!"输出应为91.您必须区分单个数字和多个数字,如上例所示。所以" 55你好"和" 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

Editted:

根据Beartech的建议,我更新了代码。我使用字符串.include?方法而不是数组.include?方法。方法名称也来自Coderbyte。在方法名称中使用大写字母是非rubyist。

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

1 个答案:

答案 0 :(得分:1)

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)添加&#34;嘿!&#34;是必要的,因为我们的.each语句中的逻辑不知道如果不是最后一个数字,如果它后面没有非数字,那么它就会丢失。

2)使用.each.inject等迭代器。如果您要学习Ruby,那么您可以为自己做的最好的事情是转到文档并阅读Enumerable模块中的所有可用方法。说真的,现在去看看http://ruby-doc.org/core-2.2.1/Enumerable.html

这将在/ if / else / until / for语句中为您节省很多。 Enumerables有巨大的力量。其中许多都是由Array和Hash继承的。

inject是一个人有一段艰难时期,我知道这对我来说似乎并不明显。但它基本上是遍历列表将每个项目传递到循环中,但与每个项目不同,它有memo(这里我使用变量sum),这只是起始值。您可以将起始值设为任何值。因此,如果要在数组总数中添加10,则应将memo = 10设置为开头。请注意,我没有将sum设置为任何内容。如果你没有设置它,它将获得数组中的第一个值并启动| n |关闭第二个值。

我会通过这个解决方案,看看你是否可以将它重构为:

str.scan(/\d+/).inject(0) {|sum,n| sum + n.to_i}

这是像Ruby这样的语言的核心。它允许您链接您的方法,使复杂的结构成为像上面这样的单行。