You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 01:24:56