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

OCaml无命令式函数实现两个列表乘积的技术问询

用OCaml函数式风格实现列表笛卡尔积

先把你目前写的代码贴出来方便分析:

let stringlister = function(mystring, newlist) -> List.append newlist mystring;;
let rec append_func = function([listleft;listright], anslist, i, j) -> 
  if (j == (List.length listright)) then anslist 
  else begin 
    append_func([listleft;listright], anslist, i, j + 1); 
    List.appe...

能看出来你现在的思路有点偏命令式了——用i、j这种索引变量来遍历列表,这可不是函数式编程的路子哦~而且stringlister里直接把字符串和列表append会报错,因为OCaml里字符串不是列表类型,得先转成字符列表才行。

咱们换个纯函数式的思路来实现两个列表的笛卡尔积(也就是你说的“两个单元格的列表乘积”),全程只用递归,不用任何命令式工具:

第一步:实现单个元素与列表的配对

先写个辅助函数,把左边列表里的单个元素,和右边列表的每个元素一一配对:

let rec pair_with_one left_elem right_list =
  match right_list with
  | [] -> []
  | r :: rs -> (left_elem, r) :: pair_with_one left_elem rs

比如pair_with_one 1 [2;3]会返回[(1,2); (1,3)],很直观对吧?

第二步:遍历左列表生成完整乘积

再写主函数,遍历左列表的每个元素,把每个元素和右列表的配对结果拼接起来:

let rec list_product left_list right_list =
  match left_list with
  | [] -> []
  | l :: ls -> List.append (pair_with_one l right_list) (list_product ls right_list)

测试一下:list_product [1;2] [3;4]会返回[(1,3); (1,4); (2,3); (2,4)],完美符合需求。

关于字符串转列表的补充

你原来的stringlister如果是想把字符串转成字符列表,OCaml 4.13+有现成的String.to_list,要是用旧版本的话,自己写个递归函数也很简单:

let rec string_to_char_list s =
  match s with
  | "" -> []
  | _ -> s.[0] :: string_to_char_list (String.sub s 1 (String.length s - 1))

这样整个实现就完全是函数式风格了,没有用任何命令式的索引或者List.mem这类你不想用的函数,刚好适配CYK表的学习需求~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:51:47