在 Elixir 中为 "Valid Anagram" 编写 clean/cleaner 解决方案
Writing a clean/cleaner solution to "Valid Anagram" in Elixir
尝试通过使用 Elixir 做 algo/leetCode 式问题来提高我对 Elixir 的理解。
由于我是一个相对较新的程序员(大约一年)并且接受过 Ruby 和 JS 等传统 OOP 语言的培训,所以我仍然有点难以全神贯注地解决算法问题一个功能范例,尽管我觉得我理解我参加的 Udemy 课程 Elixir/Phoenix。
我使用 Elixir 和 Repl 编写了 the LeetCode "valid anagram" problem 的解决方案,想看看人们是否对 improving/understanding 这个问题有任何想法,或者是否有解决这个问题的最佳方法。
为了获得答案,我会进行代码审查、书籍推荐,甚至只是建议我可以做些什么。
感谢您抽出时间,希望这个(我在本网站上的第一个问题)是清楚的。
###
Given two strings s and t , write a function to determine if t is an anagram of s.
Example 1:
Input: s = "anagram", t = "nagaram"
Output: true
Example 2:
Input: s = "rat", t = "car"
Output: false
Note:
You may assume the string contains only lowercase alphabets.
###
defmodule Algos do
def is_anagram(str1, str2) do
case String.length(str1) == String.length(str2) do
false ->
IO.puts(false)
true ->
both_trackers(str1, str2)
|> check_trackers
|> IO.puts
end
end
def both_trackers(str1, str2) do
t1 = make_tracker(str1)
t2 = make_tracker(str2)
{t1, t2}
end
def check_trackers({t1, t2}) do
Map.keys(t1)
|> Enum.reduce_while(true, fn x, acc ->
if t1[x] == t2[x], do: {:cont, acc}, else: {:halt, false}
end)
end
def make_tracker(str) do
tracker = String.split(str, "", trim: true)
|> Enum.reduce(%{},
fn x,acc -> Map.merge(acc,
case !!acc[x] do
false ->
%{x => 1}
true ->
%{x => acc[x] + 1}
end
)
end
)
tracker
end
end
Algos.is_anagram("sloop ", "pools")
新的elixir有Enum.frequencies
,它从一个enumerable生成直方图,基本上开箱即用地解决了这个问题:
defmodule Algos do
def anagram?(a, b) do
Enum.frequencies(to_charlist(a)) == Enum.frequencies(to_charlist(b))
end
end
Algos.anagram?("a gentleman", "elegant man") # => true
Algos.anagram?("alice", "bob") # => false
尝试通过使用 Elixir 做 algo/leetCode 式问题来提高我对 Elixir 的理解。
由于我是一个相对较新的程序员(大约一年)并且接受过 Ruby 和 JS 等传统 OOP 语言的培训,所以我仍然有点难以全神贯注地解决算法问题一个功能范例,尽管我觉得我理解我参加的 Udemy 课程 Elixir/Phoenix。
我使用 Elixir 和 Repl 编写了 the LeetCode "valid anagram" problem 的解决方案,想看看人们是否对 improving/understanding 这个问题有任何想法,或者是否有解决这个问题的最佳方法。
为了获得答案,我会进行代码审查、书籍推荐,甚至只是建议我可以做些什么。
感谢您抽出时间,希望这个(我在本网站上的第一个问题)是清楚的。
###
Given two strings s and t , write a function to determine if t is an anagram of s.
Example 1:
Input: s = "anagram", t = "nagaram"
Output: true
Example 2:
Input: s = "rat", t = "car"
Output: false
Note:
You may assume the string contains only lowercase alphabets.
###
defmodule Algos do
def is_anagram(str1, str2) do
case String.length(str1) == String.length(str2) do
false ->
IO.puts(false)
true ->
both_trackers(str1, str2)
|> check_trackers
|> IO.puts
end
end
def both_trackers(str1, str2) do
t1 = make_tracker(str1)
t2 = make_tracker(str2)
{t1, t2}
end
def check_trackers({t1, t2}) do
Map.keys(t1)
|> Enum.reduce_while(true, fn x, acc ->
if t1[x] == t2[x], do: {:cont, acc}, else: {:halt, false}
end)
end
def make_tracker(str) do
tracker = String.split(str, "", trim: true)
|> Enum.reduce(%{},
fn x,acc -> Map.merge(acc,
case !!acc[x] do
false ->
%{x => 1}
true ->
%{x => acc[x] + 1}
end
)
end
)
tracker
end
end
Algos.is_anagram("sloop ", "pools")
新的elixir有Enum.frequencies
,它从一个enumerable生成直方图,基本上开箱即用地解决了这个问题:
defmodule Algos do
def anagram?(a, b) do
Enum.frequencies(to_charlist(a)) == Enum.frequencies(to_charlist(b))
end
end
Algos.anagram?("a gentleman", "elegant man") # => true
Algos.anagram?("alice", "bob") # => false