有没有办法优化我为String类写的这个字符计数器的代码?

huangapple go评论73阅读模式
英文:

Any way to optimize this character counter i wrote in ruby for String class

问题

# 字符计数器
class String
  def count_lcases
    count(('a'..'z').to_a.join(''))
  end

  def count_upcases
    count(('A'..'Z').to_a.join(''))
  end

  def count_num
    count((0..9).to_a.join(''))
  end

  def count_spl_chars
    length - count_lcases - count_upcases - count_num
  end
end

input = ARGV[0]

if ARGV.empty?
  puts '请提供输入'
  exit
end

puts '小写字符 = %d' % [input.count_lcases]
puts '大写字符 = %d' % [input.count_upcases]
puts '数字字符 = %d' % [input.count_num]
puts '特殊字符 = %d' % [input.count_spl_chars]

对于你提出的优化问题,可以考虑使用正则表达式来一次性匹配并计数不同类型的字符。不过,这个示例中的方法也是有效的。

英文:
# Character Counter
class String
  def count_lcases
    count(('a'..'z').to_a.join(''))
  end

  def count_upcases
    count(('A'..'Z').to_a.join(''))
  end

  def count_num
    count((0..9).to_a.join(''))
  end

  def count_spl_chars
    length - count_lcases - count_upcases - count_num
  end
end

input = ARGV[0]

if ARGV.empty?
  puts 'Please provide an input'
  exit
end

puts 'Lowercase characters = %d' % [input.count_lcases]
puts 'Uppercase characters = %d' % [input.count_upcases]
puts 'Numeric characters = %d' % [input.count_num]
puts 'Special characters = %d' % [input.count_spl_chars]

I used ranges to count characters but count function is called 3 times.

I can always use loops and count it one by one.I was wondering is there any way to optimize this?...

答案1

得分: 3

如果您使用Ruby 2.7,您可以使用tally;字符串的字符只需迭代一次。

def classify_char(c)
  case c
    when /[a-z]/ then :lcase 
    when /[A-Z]/ then :ucase
    when /\d/    then :digit
    else :other
  end
end

p "asg3456  ERTYaeth".chars.map{|c| classify_char(c) }.tally
# => {:lcase=>7, :digit=>4, :other=>2, :ucase=>4}
英文:

If you are using Ruby 2.7 you could use tally; the string's chars are just iterated one time.

def classify_char(c)
  case c
    when /[a-z]/ then :lcase 
    when /[A-Z]/ then :ucase
    when /\d/    then :digit
    else :other
  end
end

p "asg3456  ERTYaeth".chars.map{|c| classify_char(c) }.tally
# => {:lcase=>7, :digit=>4, :other=>2, :ucase=>4}

答案2

得分: 0

如果 Ruby 版本在 2.3 到 2.7 之间,这段代码将有效:

CHAR_CLASSES = {
  lcase: ?a..?z,
  ucase: ?A..?Z,
  digit: ?0..?9,
}

p "asg3456  ERTYaeth".each_char.with_object(Hash.new(0)) { |c, o|
  o[CHAR_CLASSES.find { |label, group| group === c }&.first || :other] += 1
}

对于小于 2.3 的情况,

p "asg3456  ERTYaeth".each_char.with_object(Hash.new(0)) { |c, o|
  p = CHAR_CLASSES.find { |label, group| group === c }
  o[p ? p.first : :other] += 1
}
英文:

If Ruby 2.3...2.7, this will work:

CHAR_CLASSES = {
  lcase: ?a..?z,
  ucase: ?A..?Z,
  digit: ?0..?9,
}

p "asg3456  ERTYaeth".each_char.with_object(Hash.new(0)) { |c, o|
  o[CHAR_CLASSES.find { |label, group| group === c }&.first || :other] += 1
}

For < 2.3,

p &quot;asg3456  ERTYaeth&quot;.each_char.with_object(Hash.new(0)) { |c, o|
  p = CHAR_CLASSES.find { |label, group| group === c }
  o

+= 1 }

huangapple
  • 本文由 发表于 2020年1月6日 20:01:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/59611754.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定