【问题标题】:Writing a clean/cleaner solution to "Valid Anagram" in Elixir在 Elixir 中为“Valid Anagram”编写一个干净/干净的解决方案
【发布时间】:2021-03-20 02:36:36
【问题描述】:

尝试通过使用 Elixir 解决 algo/leetCode 风格的问题来提高我对 Elixir 的理解。

由于我是一个相对较新的程序员(大约一年)并且接受过传统 OOP 语言(如 Ruby 和 JS)的培训,因此我仍然有点难以在函数范式中解决算法问题,尽管我感觉我理解了我在 Elixir/Phoenix 上的 Udemy 课程。

我使用 Elixir 和 Repl 为 the LeetCode "valid anagram" problem 写了一个解决方案,想看看人们是否有任何改进/理解问题的想法,或者是否有解决这个问题的最佳方法。

对于答案,我会接受代码审查、书籍推荐,甚至只是建议我可以做些什么不同的事情。

感谢您抽出宝贵时间,希望这(我在本网站上的第一个问题)很清楚。



###

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")

【问题讨论】:

  • 基本上你需要为每个字符串构建一个频率直方图,然后测试两个直方图模式是否匹配。
  • ["anagram", "nagar AM"] |> Enum.map(& &1 |> String.replace(~r|\W|, "") |> String.downcase() |> to_charlist() |> Enum.sort()) |> Enum.reduce(&Kernel.==/2) ⇐ 这将消除所有非字母,将输入小写,将字符串转换为字符列表,对它们进行排序并比较结果。

标签: functional-programming elixir


【解决方案1】:

新的elixir有Enum.frequencies,它从一个可枚举的对象中生成一个直方图,基本上开箱即用地解决了这个问题:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-26
    • 2010-09-18
    • 1970-01-01
    • 2019-07-02
    • 2023-04-03
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多