Elixir中running_total变量为何重置?如何修复?
Elixir罗马数字转整数:解决不可变变量的累加问题
你的问题核心在于**Enum.each无法维护跨迭代的状态**。Elixir的不可变性意味着,你在each的匿名函数里对running_total和max_value的赋值,都是创建了局部的新变量,完全不会影响外部定义的初始值——所以最后函数返回的永远是初始的0。
要解决这类需要累积状态的问题,应该用Enum.reduce,它专门用来在遍历过程中传递并更新状态。下面是修改后的代码:
defmodule Solution do @spec roman_to_int(s :: String.t()) :: integer() def roman_to_int(s) do roman_map = %{ "I" => 1, "V" => 5, "X" => 10, "L" => 50, "C" => 100, "D" => 500, "M" => 1000 } s |> String.reverse() |> String.graphemes() |> Enum.reduce({0, -100}, fn char, {running_total, max_value} -> curr_val = roman_map[char] # 根据当前值与最大值的关系更新累加值 new_total = if curr_val >= max_value do running_total + curr_val else running_total - curr_val end # 更新最大值(仅当当前值更大时) new_max = if curr_val > max_value, do: curr_val, else: max_value # 返回新的状态,供下一次迭代使用 {new_total, new_max} end) # 从最终状态中提取累加结果 |> elem(0) end end IO.puts(Solution.roman_to_int("XIV")) # 输出14
关键说明:
Enum.reduce的第二个参数{0, -100}是初始状态,包含了初始的累加值和最大值。- 每次迭代的匿名函数接收当前字符和当前状态,计算出新的累加值和新的最大值,然后返回这个新状态。
- 遍历结束后,
reduce会返回最终的状态元组,我们用elem(0)取出累加的结果即可。 - 全程没有“修改”任何变量,而是通过返回新状态的方式传递数据,完全符合Elixir不可变的设计思想。
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

