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

Prolog中如何合并两个字典并对相同键的值求和?

SWI-Prolog 字典合并谓词实现

你要实现的同标签计数字典合并效果(同键值相加、独有键保留),不需要套用命令式语言的for循环思路——Prolog是声明式语言,你只需要描述清楚合并规则,用内置的列表、字典操作谓词即可实现。

完整实现代码

% 合并两个同标签的计数字典,同键对应数值求和
merge(Dict1, Dict2, Merged) :-
    % 校验两个输入均为字典,且标签一致
    is_dict(Dict1, DictTag),
    is_dict(Dict2, DictTag),
    % 分别提取两个字典的键列表
    dict_keys(Dict1, Keys1),
    dict_keys(Dict2, Keys2),
    % 拼接键列表后去重,得到所有需要保留的键
    append(Keys1, Keys2, DupKeys),
    sort(DupKeys, AllKeys),
    % 对每个键计算合并后的值,生成键值对列表
    maplist(build_kv(Dict1, Dict2), AllKeys, KVPairs),
    % 用原标签和键值对生成最终合并字典
    dict_create(Merged, DictTag, KVPairs).

% 单个键的合并逻辑:键不存在时值按0计算,两个字典的值相加
build_kv(D1, D2, Key, Key-TotalVal) :-
    TotalVal is D1.get(Key, 0) + D2.get(Key, 0).

效果验证

加载上述代码后运行你给出的查询,会得到完全符合预期的结果:

?- merge(counter{a: 1, b: 2}, counter{a: 3, c: 4, d: 5}, Merged).
Merged = counter{a: 4, b: 2, c: 4, d: 5}.

思路说明

你之前用for循环思路失败的核心原因是:逻辑编程没有命令式语言里的可变变量、循环计数器、逐行执行的流程控制,你不需要手动维护临时变量、遍历修改值,只需要明确描述「合并结果满足什么规则」即可:

  • 合并后的字典标签和两个输入字典一致
  • 合并后的字典包含两个输入字典的所有键
  • 每个键对应的值,是两个字典中该键对应值的和,不存在的键按0计数

代码里用到的几个核心内置谓词作用:

  • is_dict/2:校验输入是字典类型,同时提取字典的标签(比如示例里的counter)
  • dict_keys/2:提取字典所有键组成的列表
  • sort/2:对列表排序同时自动去重,刚好得到无重复的完整键列表
  • maplist/3:将单键合并规则应用到整个键列表上,是逻辑编程里替代手动for循环的常用方式
  • dict_create/3:根据标签和键值对列表生成最终的字典结构
  • 字典的.get(Key, Default)语法:读取键对应的值,键不存在时返回指定默认值,刚好适配计数器的求和逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:39:18