【问题标题】:Ruby: Varying Number of case statemntsRuby:不同数量的case语句
【发布时间】:2020-04-03 05:51:06
【问题描述】:

我目前正在用 Ruby 编写一个自动化的团队组建程序,它可以根据学生的技能来组建异构团队。该技能来自上一年学生的成绩(即 [0;100] 范围内的整数)。我已经实现了等级到技能转换方法的默认版本,其中等级根据以下阈值转换为技能

[0;39] => 1
[40;49] = > 2 
[50;59] = > 3
[60;69] = > 4
[70;79] = > 5
[80;100] = > 6

这是通过 case/when 语句实现的 但是,该程序将被设计为由老师使用,我希望让老师能够提供他自己对如何衡量学生技能的解释(例如,他可能希望拥有更少或更多的技能组或给定技能组的不同阈值)。 我的想法是他将能够以哈希的形式将它们作为命名参数传递,以 2 值数组作为键(等级阈值)和整数作为值(技能),但是我很难思考一种巧妙的方式来实现它。 是否有可能实现可变数量的 when 语句,其中每个语句负责给定的技能(比如将它们置于某种循环中?)。或者你能想出其他可以解决这个问题的方法吗? 非常感谢您的帮助!

【问题讨论】:

  • 提示:find[ range, value ] 成对的数组结构。
  • 蛮力偷懒的方法是用 100 个键创建一个哈希,然后填充所有值。
  • 问题是这是我的硕士最后一年的项目,我正在寻找最聪明的方法来做到这一点,否则,是的,这是一个可能的解决方案
  • “最聪明”和“最有效”一样取决于多种因素。线性扫描将是 O(n) 而散列或数组是 O(1) 更好,但需要更多时间来构建和保留内存。
  • 绝对正确。但是对于这种情况,整个算法具有相当大的时间和空间复杂性,无论它的效率如何,这将是运行时间的一个可以忽略不计的部分。只是不想采用蛮力的方法,而是采用至少看起来整洁的方法。还是谢谢!

标签: ruby switch-statement case-when


【解决方案1】:

给定这样的结构:

values = {
  0..39 => 1,
  40..49 => 2,
  50..59 => 3,
  60..69 => 4,
  70..79 => 5,
  80..100 => 6
}

您可以使用find 获取符合特定条件的第一个条目:(假设范围不重叠并且没有“漏洞”——您可能需要先验证提供的数据)

grade = 52

range, skill = values.find { |r, v| r.cover?(grade) }

range #=> 50..59
skill #=> 3

【讨论】:

  • 请注意,以这种方式遍历哈希并不是最优的。如果您总共只有 100 个条目,您可能希望将其转换为包含所有 100 个 grade => skill 对的“扁平化”哈希。像values.flat_map { |r, v| r.to_a.map { |k| [k, v] } }.to_h 这样的东西应该可以工作。
  • 是的,我想我会这样做,哈希将有 250-300 个条目
【解决方案2】:

使用bsearchfind 性能更高,只要你能保证有序数组——O(log n) vs findO(n)——没有任何额外的内存消耗(堆栈帧除外,呵呵)。此外,由于您的范围(可能)是连续的,它们之间没有任何漏洞,您可以指定阈值。

因此,如果您的索引始终为“1..N”,则此方法有效:

def grade(points, scale)
  scale.bsearch_index { |x| points < x }
end

scale = [0, 40, 50, 60, 70, 80, 101]
grade(39, scale)
# => 1
grade(40, scale)
# => 2

如果没有,那么使用这个:

def grade(points, scale)
  scale.to_a.bsearch { |upto, _| points < upto }.last
end

scale = {40 => 1, 50 => 2, 60 => 3, 70 => 4, 80 => 5, 101 => 6}
grade(39, scale)
# => 1
grade(40, scale)
# => 2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2014-08-24
    相关资源
    最近更新 更多