Ruby - While循环

时间:2018-03-23 21:18:58

标签: ruby while-loop

如何在阅读单词"结束"?后,对我的程序说出输入数字的总和? 像这样:

    a=gets.to_s
    b="end"
    n=0
    while a=a.to_s
      n=a.to_i+n                             
      if a.to_s==b 
      #If I enter "end" the while loop stop and It prints the sum of the numbers typed until now
        break
        puts n
      end
    end

我是新来的,抱歉我的英语,但我还在学习。

1 个答案:

答案 0 :(得分:0)

首先使用Kernel#gets从用户那里获取字符串。

str = gets

假设这导致str的以下值。

str #=> "One tends 99 to end 23 cats 4 dogs -9\n"

gets返回一个字符串,因此无需将其转换为字符串(就像您所做的那样)。 str将以换行符("\n")结尾。在某些不需要的应用程序中,使用String#chompstr = gets.chomp)将其删除。在这里,换行的存在无关紧要,因此无需删除它。

接下来,我们需要将字符串"end"的第一个实例定位为字符串中的偏移量。为此,我们使用方法String#index

idx = str.index('end')
  #=> 5

"e""tends"的索引。

如果str不包含子字符串"end",则idx将等于nil。由于idx不是nil,我们需要在"end"后面的子字符串中对整数的字符串表示求和。

 s = str[idx+"end".size..-1]
   #=> "s 99 to end 23 cats 4 dogs -9\n"

我们可以使用方法String#scan提取整数的字符串表示形式,使用正则表达式。

arr = s.scan(/-?\d+/)
  #=> ["99", "23", "4", "-9"]

正则表达式读取,"可选(问号)匹配减号后跟一个或多个(加号)数字"。

然后我们可以将它们转换为整数并使用方法Array#sum添加它们,这在Ruby v2.4中首次亮相。

arr.sum { |ss| ss.to_i }
  #=> 117

我们可以更紧凑地写下这个。

arr.sum(&:to_i)
  #=> 117

为了支持早于2.4的Ruby版本,我们可以使用Enumerable#reduce(又名inject)。

arr.reduce(0) { |tot, st| tot + st.to_i }
  #=> 117

我们可以把所有这些放在一个方法中。

def total_after_first_end(str)
  idx = str.index('end')
  return nil if idx.nil?
  str[idx+"end".size..-1].scan(/-?\d+/).sum(&:to_i)
end

str = gets
  #=> "One tends 99 to end 23 cats 4 dogs -9\n"
total_after_first_end(str)
  #=> 117

现在让我们假设它不是标记总和开头的第一个子串"end",但它是第一个单词"end"。要进行调整,我们只需稍微更改正则表达式。

idx = str.index(/\bend\b/)
  #=> 16

"\b"word boundary(搜索"字边界")。

s = str[idx+"end".size..-1]
  #=> " 23 cats 4 dogs -9\n"
arr = s.scan(/-?\d+/)
  #=> ["23", "4", "-9"]
arr.sum(&:to_i)
  #=> 18