比较Ruby中的三个字符串

比较Ruby中的三个字符串,ruby,Ruby,我想比较三个字符串,并根据哪些字符串相同而采取不同的操作 在我看来,有5种不同的结果: 它们都是一样的 他们都不一样 其中两个是相同的A=B、B=C或C=A 我正在努力编写一段高效的Ruby代码,以获得5种不同的结果。比较字符串似乎是一个相当昂贵的操作,我不想重复比较相同的字符串 这段代码将在一个循环中运行,因此进行一些优化似乎是个好主意。这不是我的计算机科学作业,这是一个现实世界的问题:- [编辑] 对Sergio的代码进行进一步优化,可以得到更好的结果。我们可以将第三个字符串比较延迟到if…

我想比较三个字符串,并根据哪些字符串相同而采取不同的操作

在我看来,有5种不同的结果:

它们都是一样的 他们都不一样 其中两个是相同的A=B、B=C或C=A
我正在努力编写一段高效的Ruby代码,以获得5种不同的结果。比较字符串似乎是一个相当昂贵的操作,我不想重复比较相同的字符串

这段代码将在一个循环中运行,因此进行一些优化似乎是个好主意。这不是我的计算机科学作业,这是一个现实世界的问题:-

[编辑] 对Sergio的代码进行进一步优化,可以得到更好的结果。我们可以将第三个字符串比较延迟到if…then语句,如下所示:

def compare a, b, c
  ab = a == b
  ac = a == c

  if ab && ac
    1
  elsif ab
    2
  elsif ac
    3
  elsif b == c
    4
  else
    5
  end
end
[编辑] 今天给出的解决方案的基准,包括我的Sergios代码版本:

                   user     system      total        real
sawa1:         0.620000   0.000000   0.620000 (  0.625677)
izomorphius:   0.030000   0.000000   0.030000 (  0.025314)
sergio1:       0.020000   0.000000   0.020000 (  0.018039)
sergio2:       0.030000   0.000000   0.030000 (  0.030210)
dominic:       0.010000   0.000000   0.010000 (  0.015450)
我将1024个字符串进行了10000次比较,并将结果减少到1-5范围内的数字,以表示对5种可能结果中的每一种采取不同操作的原始要求

[编辑]这里有基准测试代码


现在,您已经执行了尽可能少的字符串比较操作。在获得ab、bc和ca变量后,使用它们。就这样。在性能方面,您不可能做得更好,但代码风格当然会受到影响。

以下是我的尝试。它最多执行3个字符串比较,至少执行:

def compare a, b, c
  ab = a == b
  ac = a == c
  bc = b == c

  if ab && ac
    "a == b == c"
  elsif ab
    'a == b'
  elsif ac
    'a == c'
  elsif bc
    'b == c'
  else
    'a != b != c'
  end
end

compare '1', '2', '3' # => "a != b != c"
compare '1', '2', '2' # => "b == c"
compare '2', '2', '3' # => "a == b"
compare '1', '2', '1' # => "a == c"
compare '1', '1', '1' # => "a == b == c"
使现代化 这里有另一个聪明的方法,现在涉及位掩码。它会返回可能结果的代码

def compare a, b, c
  res = 0
  res |= (a == b ? 1 : 0)
  res |= ((a == c ? 1 : 0) << 1)
  res |= ((b == c ? 1 : 0) << 2) if res == 0
  res
end

compare '1', '2', '3' # => 0
compare '2', '2', '3' # => 1
compare '1', '2', '1' # => 2
compare '1', '1', '1' # => 3
compare '1', '2', '2' # => 4
或者


这似乎是一个相当昂贵的操作-您是否对其进行了基准测试?你必须每秒比较数百万个字符串吗?我将对一些方法进行基准测试,并在这里发布我的最佳尝试。我认为比较字符串似乎是一种常识,除非Ruby为每个可以比较的字符串而不是字符串本身持有某种哈希值,否则比较字符串是昂贵的。这在我看来是过早的优化。我想这是一种惰性优化,因为我在问StackOverflow:-如果你不必要地投入一些资源,那就太早了。我希望这是一个众所周知的问题,有一个只有我自己不知道的众所周知的解决方案。我将接受Sergio的答案,因为它在我的基准测试中运行得更快。谢谢,您的代码似乎可以确定哪一对是相等的。我需要它做的是告诉我我需要采取的5个行动中的哪一个。要做到这一点,我现在需要反复比较ba、ca和bc值,这比比较字符串更有效,但仍然没有我想要的那么优雅。@DominicSayers你的问题不清楚。您应该指定一个示例输入和脚本的预期输出,就像编程问题一样。@sawa谢谢您的建议。我本来想发布一些示例代码,但你们都抢先一步。非常感谢所有的贡献。即使在随后的测试中检查了3个布尔值,这也几乎和最快的解决方案一样快。我想保持它的直截了当通常是最好的。我相信我的解决方案在a==b==cThanks-Sergio的情况下会更快33%。这当然符合我的要求。我希望在a=b或a=c的情况下避免第三个字符串比较,但不能同时进行,因为在这种情况下,b不能等于c。不管怎样,正如你所建议的,我将对它进行基准测试,并用任何有趣的结果更新它。我喜欢第二个选项的外观。再次感谢。第一个选项在我的基准测试中运行得最快,特别是当修改为推迟第三个字符串比较时,请参见编辑到原始问题我无法使用第二个选项,因为哈希包含原始值,因此我再次比较包含原始字符串的内容。第一个选项非常简洁,但似乎比其他不太优雅的解决方案运行得慢一些。
def compare a, b, c
  res = 0
  res |= (a == b ? 1 : 0)
  res |= ((a == c ? 1 : 0) << 1)
  res |= ((b == c ? 1 : 0) << 2) if res == 0
  res
end

compare '1', '2', '3' # => 0
compare '2', '2', '3' # => 1
compare '1', '2', '1' # => 2
compare '1', '1', '1' # => 3
compare '1', '2', '2' # => 4
h = {a: "foo", b: "boo", c: "foo"}

h.group_by(&:last).values.map{|a| a.map(&:first)}
# => [[:a, :c], [:b]]
h.group_by(&:last)
# => {"foo"=>[[:a, "foo"], [:c, "foo"]], "boo"=>[[:b, "boo"]]}
[string, string, string].uniq.count == 1