【问题标题】:Word Count (Ruby)字数(红宝石)
【发布时间】:2015-01-21 14:17:21
【问题描述】:

CoderByte 提供了以下挑战:“使用 Ruby 语言,让函数 WordCount(str) 接受传递的 str 字符串参数并返回字符串包含的单词数(即“从不吃碎小麦”将返回 4 )。单词将由单个空格分隔。"

我解决了,但有没有更简单的解决方案(不使用正则表达式或 .length 以外的方法)?我在for循环内部的for循环内部有一个条件内部。我还在第一个 for 循环的内部和外部将当前变量设置为 false。

这些都是不好的做法吗?有更好的解决方案吗?

def WordCount(string)

    alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    counter = 0
    current = false

    for i in 0...string.length
        prev = current
        current = false
        for j in 0...alphabet.length
            if string[i] == alphabet[j]
                current = true
                if prev == false
                    counter += 1
                end
            end
        end
    end

    return counter

end

WordCount(STDIN.gets)

【问题讨论】:

  • 你应该在CodeReview问这样的问题。
  • 我将在那里发布任何关于最佳实践的未来问题(当然是非一般性的)。谢谢。
  • Code Review 不是关于最佳实践,而是关于改进运行代码。 Software Engineering 是询问最佳实践的地方。

标签: ruby word-count


【解决方案1】:

标点符号显然是个问题。除了在别处提到的撇号之外,老派的人用连字符连接某些词组,例如复合形容词,破折号用于分隔从句,省略号(例如,符号“……”或多个句号)表示继续或改变想法, 斜线提供选择等等。一种处理方法(不使用正则表达式)是首先使用String#tr(或String#gsub)将这些标点符号转换为空格(如果您希望将“不”视为一个单词,请删除' ):

def word_count str
  str.tr("'-/–…\.", ' ').split.size
end

word_count "It was the best of times, it was the worst of times"
  #=> 12 
word_count "I don't think his/her answer is best."
  #=>  9
word_count "Mozart is a much-beloved composer."   # with hyphen
  #=>  6
word_count "I pay the bills–she has all the fun." # with dash
  #=>  9
word_count "I wish you would…oh, forget it."      # with ellipse
  #=>  7
word_count "I wish you would––oh, forget it."     # with dashes
  #=>  7
word_count ""
  #=>  0

在 Mac 上,短划线作为选项输入,连字符;一个椭圆、选项、分号(或“分号”,都可以接受:-))。

现在我们只需要弄清楚如何将带连字符的单词(“state-of-the-art”)计算为一个单词。实际上,我只是触及了这个复杂主题的表面。对不起,如果我走神了。又是什么问题?

【讨论】:

  • 很好的答案。我创建了一个Ruby gem,试图突出所有这些潜在的“字数统计灰色区域”,并允许用户配置她/他希望如何完成计数。
【解决方案2】:
string = ''              => Your string will be stored in this variable
word_count = string.split(' ').count

这应该可以解决。

【讨论】:

    【解决方案3】:

    确实涉及正则表达式,但它是正确的解决方案:

    "Hi there 334".scan(/[[:alpha:]]+/).count # => 2
    

    【讨论】:

    • @daremkd "now's" 是两个词:"now" 和 "is"
    • 我的错,对不起,删除我的评论。
    【解决方案4】:

    我见过的在 Ruby 中查找字数的最优雅的解决方案是:

    words = 'This is a word'
    p words.scan(/\S+/).size #=> 4
    

    为了最方便,猴子补丁字符串:

    class String
      def number_of_words
        self.scan(/\S+/).size
      end
    end
    
    p 'Hi there, how are you?'.number_of_words #=> 5
    

    我看到你的代码的主要问题是你在编码,但你不是在 Ruby(style) 中编码。你很少会看到人们在这里使用 for/in,for例子。如果您知道如何编写惯用的 Ruby,那么在其他语言中需要 10 行代码的代码在这里几乎只有 1 行。

    【讨论】:

    • words = "Never eat shredded wheat 111 _ ?" 将返回7,而不是4,因为\S 计算任何非空白字符,因此它不仅计算单词,而且计算数字和特殊-字符
    • 显然没有完美的方法,就像第一个例子一样,它会输出“now's the time”。这真的取决于,如果作者想把“3rd”算作一个词怎么办?
    • 是的,我同意你的观点,这就是为什么我的第一个建议实际上只是用空格分割单词:) OP 没有提供太多信息
    【解决方案5】:

    嗯,

    s = "Never eat shredded wheat"
    puts s.split.count
    # => 4
    

    如果您不想计算下划线和数字:

    s = "Never eat shredded wheat 1 _ ?"
    puts s.split.reject { |w| w =~ /(\W|_|\d)/ }.count
    # => 4
    

    更高级的正则表达式:

    s = "Never __ 111 ?? eat shredded wheat. _Word?"
    p s.split.reject { |w| w !~ /([a-zA-Z]+(_[a-zA-Z]+)*)/ }
    # => ["Never", "eat", "shredded", "wheat.", "_Word?"]
    

    【讨论】:

    • 但是@Agis,试试你的解决方案,它也会把数字算作单词:) 因为\w Any word character (letter, number(!), underscore)
    • split 假设有一个空格,如果你只是做了s.split.count 你会得到同样的东西。
    猜你喜欢
    • 2019-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多