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

Erlang中lists:filter返回"\n\f"而非列表的问题求助

Erlang中lists:filter返回看似字符串的问题解析与修复

首先明确:你看到的"\n\f"不是字符串,而是Erlang Shell对整数列表的自动格式化显示——当列表中的整数恰好对应可打印ASCII字符时,Shell会将其以字符串形式输出。比如10对应换行符\n,12对应换页符\f,所以整数列表[10,12]就会被显示为"\n\f"。你可以用io:format("~p~n", [Result])打印原始列表,就能看到真实的整数内容。

问题根源:add_matching_numbers逻辑偏离需求

你的核心需求是统计每个数字的出现次数是否为偶数,但当前add_matching_numbers函数的逻辑是对连续相同数字求和,而非统计次数:

  • 比如测试用例Test_2的数字列表排序后是[1,2,3,4,5,5,6,6],经过add_matching_numbers处理后得到[10,12](两个5求和为10,两个6求和为12),这两个数恰好是可打印ASCII码,于是Shell显示成了"\n\f"。
  • 更关键的是,这个求和逻辑完全无法正确反映数字出现的次数(比如三个相同数字会被拆成两次求和,无法体现次数为奇数)。

修复方案:替换为次数统计逻辑

重新实现统计数字出现次数的函数,再检查所有次数是否为偶数:

-module(challenge).
-export([test/0, check_dominos/1]).

extract_numbers([]) -> [];
extract_numbers([{First, Second} | T]) -> [First, Second | extract_numbers(T)]. % 优化列表拼接,用|代替++更高效

% 统计每个数字的出现次数
count_occurrences(List) ->
    count_occurrences(lists:sort(List), #{}).

count_occurrences([], Map) -> Map;
count_occurrences([H|T], Map) ->
    % 拆分出所有连续相同的数字
    {SameGroup, Rest} = lists:splitwith(fun(X) -> X =:= H end, [H|T]),
    % 记录当前数字的出现次数
    count_occurrences(Rest, maps:put(H, length(SameGroup), Map)).

check_dominos(Dominos) -> 
    All_Numbers = extract_numbers(Dominos),
    Occurrence_Map = count_occurrences(All_Numbers),
    % 检查所有次数是否都是偶数
    lists:all(fun(Count) -> Count rem 2 =:= 0 end, maps:values(Occurrence_Map)).

test() ->
    Test_1 = [{1, 3}, {3, 2}, {2, 1}], % Already in order
    Test_2 = [{5, 2}, {5, 6}, {6, 3}, {1, 4}], % Shouldn't work
    Test_3 = [{2, 6}, {3, 5}, {1, 4}, {3, 4}, {6, 1}, {2, 5}], % Should work

    true = check_dominos(Test_1),
    false = check_dominos(Test_2),
    true = check_dominos(Test_3).

额外优化点

  • 将[First] ++ [Second] ++ extract_numbers(T)改为[First, Second | extract_numbers(T)],避免不必要的列表拼接,提升效率。
  • 使用maps存储次数统计,比列表更直观易维护。

内容的提问来源于stack exchange,提问作者Skhoooler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 18:11:09