【问题标题】:Ruby: How to count the number of times a string appears in another string?Ruby:如何计算一个字符串在另一个字符串中出现的次数?
【发布时间】:2014-11-14 07:33:21
【问题描述】:

我正在尝试计算一个字符串在另一个字符串中出现的次数。

我知道你可以计算一个字母在一个字符串中出现的次数:

string = "aabbccddbb"
string.count('a')
=> 2

但是如果我搜索 'aa' 在这个字符串中出现了多少次,我也会得到两次。

string.count('aa')
=> 2

我不明白这一点。我将值放在引号中,因此我正在搜索确切字符串出现的次数,而不仅仅是字母。

【问题讨论】:

  • 请澄清(有编辑):'aa' 是否在字符串'aaa' 中出现一次或两次。
  • 在这种情况下可能应该是两次。位置 0 和 1 && 位置 1 和 2
  • 当然,你是一个优秀的海报。我奖励了你 Cary Swoveland。
  • 非常感谢,约翰逊。

标签: ruby string count


【解决方案1】:

尝试使用 string.split('a').count - 1

【讨论】:

  • 欢迎来到 StackOverflow。您能否详细说明一下您的答案?如果您能解释您的解决方案背后的逻辑,它将帮助将来可能有同样问题的其他人!
  • "a".split('a').count == 0; "ba".split('a').count == 1; "bad".split('a').count == 2;
【解决方案2】:

这里有几种方法可以计算给定子字符串在字符串中出现的次数(第一种是我的偏好)。注意(由 OP 确认)子字符串 'aa' 在字符串 'aaa' 中出现两次,因此在:

string="aaabbccaaaaddbb"

#1

String#scan 与正则表达式一起使用,该正则表达式包含寻找子字符串的正向前瞻:

def count_em(string, substring)
  string.scan(/(?=#{substring})/).count
end

count_em(string,"aa")
 #=> 5

注意:

"aaabbccaaaaddbb".scan(/(?=aa)/)
  #=> ["", "", "", "", ""]

积极的回溯会产生相同的结果:

"aaabbccaaaaddbb".scan(/(?<=aa)/)
  #=> ["", "", "", "", ""]

同样,String#scan 可以替换为 String#gsub

#2

转换为数组,应用Enumerable#each_cons,然后加入并计数:

def count_em(string, substring)
  string.each_char.each_cons(substring.size).map(&:join).count(substring)
end

count_em(string,"aa")
  #=> 5

我们有:

enum0 = "aaabbccaaaaddbb".each_char
  #=> #<Enumerator: "aaabbccaaaaddbb":each_char>

我们可以通过将枚举器转换为数组来查看将生成的元素:

enum0.to_a
  #=> ["a", "a", "a", "b", "b", "c", "c", "a", "a", "a",
  #    "a", "d", "d", "b", "b"]

enum1 = enum0.each_cons("aa".size)
  #=> #<Enumerator: #<Enumerator: "aaabbccaaaaddbb":each_char>:each_cons(2)> 

enum1 转换为数组,看看枚举器将传递给map 的值是什么:

enum1.to_a
  #=> [["a", "a"], ["a", "a"], ["a", "b"], ["b", "b"], ["b", "c"],
  #    ["c", "c"], ["c", "a"], ["a", "a"], ["a", "a"], ["a", "a"], 
  #    ["a", "d"], ["d", "d"], ["d", "b"], ["b", "b"]]

c = enum1.map(&:join)
  #=> ["aa", "aa", "ab", "bb", "bc", "cc", "ca",
  #    "aa", "aa", "aa", "ad", "dd", "db", "bb"]
c.count("aa")
  #=> 5

【讨论】:

    【解决方案3】:

    这是因为count 计算字符,而不是字符串实例。在这种情况下,'aa''a' 的含义相同,它被视为一组要计数的字符。

    统计aa在字符串中出现的次数:

    string = "aabbccddbb"
    string.scan(/aa/).length
    # => 1
    string.scan(/bb/).length
    # => 2
    string.scan(/ff/).length
    # => 0
    

    【讨论】:

    • 我明白了,要找到实际字符串的计数,您使用扫描方法而不是计数方法。谢谢。
    • 是的,scan 接受像 /aa/ 这样的正则表达式,或者如果你愿意的话甚至是像 "aa" 这样的字符串,并返回匹配项。 length 告诉你有多少匹配,如果你不在乎匹配是什么。
    • 你也可以用count或size代替length
    • 在这个例子中没有理由使用正则表达式而不是字符串。
    猜你喜欢
    • 1970-01-01
    • 2011-07-01
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-26
    • 2017-02-01
    • 2018-06-06
    • 1970-01-01
    相关资源
    最近更新 更多