如何通过Ruby查找字符串中出现的次数

时间:2014-04-29 21:21:57

标签: ruby

我是Ruby的新手并且通过solving IOI questions来学习它。

示例输入文件的第一行是' O'的编号。如果是1则需要找到IOI'如果是2,那么' IOIOI'等

第二个数字13表示第三行中的字符数。问题是找到< IOI'

的出现次数

以下样本应该给出4.

我创建了一个方法并在while循环中使用if语句。但它给出了ioioi.rb:14: syntax error, unexpected keyword_end (SyntaxError)的错误。我在while循环中尝试的是查找前3个字符是否相等以及是否将count增加一个。并删除第一个字符并重复该过程。

示例输入文件

1
13
OOIOIOIOIIOII

输出应为

4

我的班级Ioioi

def self.frequency(file_name)
    file = File.new(file_name, 'r').each_line.map(&:strip)
    count = 0
    o_str = file.shift # '1'
    o_num = o_str.to_i 
    findme = "IO" * o_num + "I"
    length = file.shift # '13'
    input = file.join
    while file.size > 0 do
      if file[0..(2*o_num)].eql?(findme)
        count +=
      end
        file = file[1..-1] # delete the first letter
    end
    count
  end

3 个答案:

答案 0 :(得分:3)

使用正则表达式:

 def countem(n, str)
  str.scan(/I(?=#{'OI' * n})/).size
end

p countem(1, 'OOIOIOIOIIOII')    # => 4
p countem(2, 'OOIOIOIOIIOII')    # => 2
p countem(3, 'OOIOIOIOIIOII')    # => 1
p countem(4, 'OOIOIOIOIIOII')    # => 0

正则表达式查找"我" (并使用它),然后使用正向前瞻匹配字符串的其余部分,以便不消耗它。这使得字符串的其余部分可用于更多匹配。

答案 1 :(得分:2)

@Kyle已回答你的问题。这是一种以类似Ruby的方式实现它的方法。

编辑: @steenslag为我的代码改进提出了两个很好的建议,我很乐意采用。原来我有:

def countem(n, str)
  target = ('IO'*n + 'I').split('')
  str.split('').each_cons(2*n+1).reduce(0) {|tot,e| tot + (e==target ? 1 : 0)}
end

他的主要建议是我使用count而不是reduce,而且还以更直接的方式构建target。这些变化反映在下面。

<强>代码

这里的关键是使用方法Enumerable#each_cons

def countem(n, str)
  target = ['I','O']*n << 'I'
  str.split('').each_cons(2*n+1).count { |e| e==target }
end

示例

str = "OOIOIOIOIIOII"
countem(1, str) #=> 4
countem(2, str) #=> 2
countem(3, str) #=> 1

<强>解释

n = 1
str = "OOIOIOIOIIOII"

target = ['I','O']*n << 'I'
  #=> ["I", "O", "I"]

a = str.split('')
  #=> ["O", "O", "I", "O", "I", "O", "I", "O", "I", "I", "O", "I", "I"]
b = a.each_cons(2*n+1) #=> a.each_cons(3)
  #=> #<Enumerator: ["O", "O", "I", "O", "I", "O", "I", "O",
  #                  "I", "I", "O", "I", "I"]:each_cons(3)>

查看枚举器的内容:

b.to_a
  #=> [["O", "O", "I"], ["O", "I", "O"], ["I", "O", "I"], ["O", "I", "O"],
  #    ["I", "O", "I"], ["O", "I", "O"], ["I", "O", "I"], ["O", "I", "I"],
  #    ["I", "I", "O"], ["I", "O", "I"], ["O", "I", "I"]]

最后,计算b等于target

的元素
b.count { |e| e==target }
  #=> 4

答案 2 :(得分:1)

你错过了+=函数的参数,因此Ruby试图将下一行作为参数读取。相反,它正在获取end块的if - 但count +=语句未完成,因此它还没有为块结束做好准备。