比较Ruby中的三个字符串

时间:2012-10-10 12:44:40

标签: ruby

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

在我看来,有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 个答案:

答案 0 :(得分: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"]]}

答案 1 :(得分: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变量之后使用它们。而已。在性能方面你不可能更好(但当然代码风格也会受到影响)。

答案 2 :(得分: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

答案 3 :(得分:0)

[string, string, string].uniq.count == 1