鉴于两个字符串,我想确定它们是否是彼此的字谜。以下是我提出的解决方案:
# output messages
def anagram
puts "Anagram!"
exit
end
def not_anagram
puts "Not an anagram!"
exit
end
# main method
if __FILE__ == $0
# read two strings from the command line
first, second = gets.chomp, gets.chomp
# special case 1
not_anagram if first.length != second.length
# special case 2
anagram if first == second
# general case
# Two strings must have the exact same number of characters in the
# correct case to be anagrams.
# We can sort both strings and compare the results
if first.chars.sort.join == second.chars.sort.join
anagram
else
not_anagram
end
end
但我认为可能有更好的一个。我分析了这个解决方案的效率,并提出了:
chars
:将字符串拆分为字符数组O(n)
sort
:按字母顺序对字符串进行排序,我不知道如何在Ruby中实现排序,但我假设O(n log n)
,因为这是通常最为人所知的排序效率join
:根据字符数组O(n)
==
:字符串比较本身必须检查字符串的每个字符2*O(n)
鉴于上述情况,我将整个解决方案的效率分类为O(n log n)
,因为排序效率最高。有没有比O(n log n)
更有效的方法呢?
答案 0 :(得分:6)
你的大O应该是O(n*lg(n))
,因为排序是限制功能。如果你尝试使用非常大的字谜,你会发现O(n)
解决方案的性能损失高于预期。
您可以通过比较两个字符映射中的计数来执行O(n)
解决方案=>人物数量。
肯定有其他解决方案具有大致相同的复杂性,但我认为你不能提出比O(n)
答案 1 :(得分:3)
计数示例:
def anagram?(str_a, str_b)
if str_a.length != str_b.length
false
else
counts = Hash.new(0)
str_a.each_char{ |c| counts[c] += 1 }
str_b.chars.none?{ |c| (counts[c] -= 1) < 0 }
end
end
anagram? 'care', 'race'
# => true
anagram? 'cat', 'dog'
# => false
答案 2 :(得分:3)
您可以在O(n+m)
中执行此操作,其中m是字母长度
1.创建一个大小等于输入字母大小的数组。
2.初始化数组中的所有值为“0”。
3.扫描第一个输入字符串,为每个字符增加数组中的相应值(如增量数组[0],如果找到字母表中的第一个字母)。
4.对第二个字符串重复相同的操作,但在这种情况下,数组中的值需要递减。
如果数组中的所有值都是'0',则两个字符串是字谜,否则它们不是。
答案 3 :(得分:1)
我需要一些东西来检查字谜,并想出了这个:
def string_to_array(s)
s.downcase.gsub(/[^a-z]+/, '').split('').sort
end
def is_anagram?(s1, s2)
string_to_array(s1) == string_to_array(s2)
end
puts is_anagram?("Arrigo Boito", "Tobia Gorrio")
puts is_anagram?("Edward Gorey", "Ogdred Weary")
puts is_anagram?("Ogdred Weary", "Regera Dowdy")
puts is_anagram?("Regera Dowdy", "E. G. Deadworry")
puts is_anagram?("Vladimir Nabokov", "Vivian Darkbloom")
puts is_anagram?("Vivian Darkbloom", "Vivian Bloodmark")
puts is_anagram?("Dave Barry", "Ray Adverb")
puts is_anagram?("Glen Duncan", "Declan Gunn")
puts is_anagram?("Damon Albarn", "Dan Abnormal")
puts is_anagram?("Tom Cruise", "So I'm cuter")
puts is_anagram?("Tom Marvolo Riddle", "I am Lord Voldemort")
puts is_anagram?("Torchwood", "Doctor Who")
puts is_anagram?("Hamlet", "Amleth")
puts is_anagram?("Rocket boys", "October Sky")
puts is_anagram?("Imogen Heap", "iMegaphone")