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

如何在Coq中将带空行的字符串解析为嵌套整数列表?

解决Coq中解析含空行的字符串为嵌套整数列表的问题

你的代码无法得到预期结果的核心原因是:Coq的记号解析器会将所有空白字符(包括单个换行和多个换行)视为相同分隔符,无法区分单换行和双换行来划分不同分组,因此原代码会把所有数字解析成一个扁平列表,而非嵌套列表。

针对可变长度分组(每组元素数量不固定)的场景,更合适的方案是先将字符串解析为包含可选数字的列表,再通过辅助函数将连续的有效数字分组为子列表。以下是完整实现:

From Coq Require Export String List NArith.
From Coq Require Import Ascii.

#[global] Open Scope string_scope.
#[global] Open Scope N.
Import ListNotations.

(* 将字符串按换行符分割为行列表 *)
Fixpoint split_lines (s : string) : list string :=
  match s with
  | EmptyString => [EmptyString]
  | String c s' =>
    if c = Ascii.ascii_of_nat 10 then (* 匹配换行符ASCII码 *)
      EmptyString :: split_lines s'
    else
      match split_lines s' with
      | [] => [String c EmptyString]
      | h :: t => (String c h) :: t
      end
  end.

(* 将单行字符串转换为可选自然数(空行或无效数字返回None) *)
Definition string_to_opt_N (s : string) : option N :=
  N.of_string_opt s.

(* 将行列表转换为可选自然数列表 *)
Definition lines_to_opt_Ns (lines : list string) : list (option N) :=
  map string_to_opt_N lines.

(* 分割列表:提取满足条件的前缀和剩余部分 *)
Fixpoint split_prefix {A} (P : A -> bool) (l : list A) : (list A) * (list A) :=
  match l with
  | [] => ([], [])
  | h :: t =>
    if P h then
      let (prefix, suffix) := split_prefix P t in
      (h :: prefix, suffix)
    else
      ([], l)
  end.

(* 将可选自然数列表分组为嵌套列表:连续的有效数字组成子列表,空行分隔不同子列表 *)
Fixpoint group_opt (l : list (option N)) : list (list N) :=
  match l with
  | [] => []
  | None :: t => group_opt t (* 跳过空行或无效数字 *)
  | Some n :: t =>
    let (group, rest) := split_prefix (fun x => match x with Some _ => True | None => False end) t in
    let full_group := n :: map (fun x => match x with Some m => m end) group in
    full_group :: group_opt rest
  end.

(* 主解析函数:从字符串得到嵌套整数列表 *)
Definition parse_input (s : string) : list (list N) :=
  group_opt (lines_to_opt_Ns (split_lines s)).

(* 示例输入 *)
Definition example_str := "1
2

3
4
5
".

(* 解析示例 *)
Definition example := parse_input example_str.

(* 查看结果 *)
Print example.

代码说明

  1. split_lines: 将输入字符串按换行符分割为单个行的列表,保留空行。
  2. string_to_opt_N: 使用N.of_string_opt将单行字符串转换为option N,空行或非数字字符串会返回None。
  3. group_opt: 遍历可选数字列表,将连续的Some n元素组合为子列表,遇到None则切换到下一个分组。
  4. parse_input: 串联所有步骤,从原始字符串得到最终的嵌套列表。

运行Print example.后,你会得到预期的[[1; 2]; [3; 4; 5]]。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:42:48