2

I have two strings, a and b, in Ruby.

a="scar"
b="cars"

What is the easiest way in Ruby to find whether a and b contain the same characters?

UPDATE
I am building an Anagram game ,so scar is an anagram of cars.So i want a way to compare a and b and come to conclusion that its an anagram
So c="carcass" should not be a match

Stormvirux
  • 879
  • 3
  • 17
  • 34
  • 4
    How do you want to deal with repeated characters? e.g. `c = "carcass"`, is that a match to a and b? In fact, do you want a `true/false` response at all, or the intersection. Could you give example output in code rather than the ambiguous "it should say"? – Neil Slater Jul 23 '13 at 13:53
  • Possible duplicate of http://stackoverflow.com/q/9646995/1301972 or http://stackoverflow.com/q/16631961/1301972, or answered by one of their answers. – Todd A. Jacobs Jul 23 '13 at 14:14
  • 1
    @CodeGnome Exactly what I was looking for.Actually I was trying manually create hash when group_by was already there. Ruby roxx!! – Stormvirux Jul 23 '13 at 14:26
  • Should `a` and `b` is always same size? Can `a` can contain duplicate characters? in that case what result you would expect? – Arup Rakshit Jul 23 '13 at 14:27

4 Answers4

11

You could do like this:

a = 'scar'
b = 'cars'
a.chars.sort == b.chars.sort
# => true

a = 'cars'
b = 'carcass'
a.chars.sort == b.chars.sort
# => false
toro2k
  • 19,020
  • 7
  • 64
  • 71
  • I think `a.chars.sort.join == b.chars.sort.join` is better because comparation of arrays is more time consuming than comparation of strings. Just a note ;) – Yevgeniy Anfilofyev Jul 23 '13 at 14:01
  • 3
    @YevgeniyAnfilofyev But this is not inequality; it is equality. The moment the two arrays include different elements, the comparison will terminate. And `join` is an extra operation. Do you have numerical basis for your claim? – sawa Jul 23 '13 at 14:04
9

Just for testing arrays vs string vs delete comparation. Assuming we compare strings with equal length.

In the real anagram search you need to sort first word a once. And then compare it to bunch of b's.

a="scar"
b="cars"

require 'benchmark'

n = 1000000
Benchmark.bm do |x|
  x.report('string') { a = a.chars.sort.join; n.times do ; a == b.chars.sort.join ; end }
  x.report('arrays') { a = a.chars.sort; n.times do ; a == b.chars.sort ; end }
end

The result:

          user     system      total        real
string  6.030000   0.010000   6.040000 (  6.061088)
arrays  6.420000   0.010000   6.430000 (  6.473158)

But, if you sort a each time (for delete we don't need to sort any word):

x.report('string') { n.times do ; a.chars.sort.join == b.chars.sort.join ; end }
x.report('arrays') { n.times do ; a.chars.sort == b.chars.sort ; end }
x.report('delete') { n.times do ; a.delete(b).empty? ; end }

The result is:

          user     system      total        real
string 11.800000   0.020000  11.820000 ( 11.989071)
arrays 11.210000   0.020000  11.230000 ( 11.263627)
delete  1.680000   0.000000   1.680000 (  1.673979)
Yevgeniy Anfilofyev
  • 4,827
  • 25
  • 27
3

What is the easiest way in Ruby to find whether a and b contain the same characters?

As per the definitions of Anagram the below written code should work :

a="scar"
b="cars"
a.size == b.size && a.delete(b).empty?
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
1

require 'set'
Set.new(a.chars) == Set.new(b.chars)

updated to take into account comment from sawa

ilan berci
  • 3,883
  • 1
  • 16
  • 21
  • 1
    When your answer depends on a library, do not omit that. – sawa Jul 23 '13 at 14:01
  • 4
    This will not handle words with duplicated letters, since a set would discard them. – Todd A. Jacobs Jul 23 '13 at 14:10
  • 1
    @CodeGnome That requirement was added after this answer was posted. The original question mentioned (and the present one still mentions) "whether `a` and `b` contain the same characters". – sawa Jul 23 '13 at 14:12