0

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

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

  • 它们都是一样的(A=B=C)
  • 他们都是不同的
  • 其中两个相同(A=B、B=C 或 C=A)

我正在努力编写一段高效的 Ruby 代码来给我 5 种不同的结果。比较字符串似乎是一项相当昂贵的操作,我不想重复比较相同的字符串。

此代码将在循环内运行,因此进行一些优化似乎是个好主意。这不是我的 Comp Sci 作业,这是一个现实世界的问题 :-)

[编辑] 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 个字符串,每个字符串 10,000 次,并将结果缩减为 1-5 范围内的数字,以表示对 5 种可能结果中的每一种采取不同操作的原始要求。

[编辑] 基准代码在这里https://gist.github.com/3871698

4

4 回答 4

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"]]}
于 2012-10-10T13:06:06.340 回答
3
ba=false
ca=false
bc=false
if b == a
  ba = true
  if b == c
    bc = true
    ca = true
  end
elsif c == a
  ca = true
elsif c == b
  bc = true
end

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

于 2012-10-10T12:49:30.737 回答
3

这是我的尝试。它最多执行 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
于 2012-10-10T12:59:50.887 回答
1
[string, string, string].uniq.count == 1
于 2015-09-17T12:52:46.413 回答