【问题标题】:Find the minimun length of a SubList that contains all numbers from 1 to K找到包含从 1 到 K 的所有数字的 SubList 的最小长度
【发布时间】:2019-05-15 17:54:22
【问题描述】:

问题是“查找包含从 1 到 K 的所有数字的列表的最小长度”。 输入 : 列表,K,N 其中 N 是列表的长度


我的算法(显然有点面向 C):

  1. 设置最小值= N+1
  2. 找到第一个包含从 1 到 K 的所有数字的子列表 (FSub)
  3. 如果没有,则 Min=0 并完成
  4. 如果有创建一个列表 C,它包含除第一个长度 (FSub) 元素之外的起始列表的所有元素。

找到最小值的函数(参数:FSub、C、NewList、Min)

  1. 如果 length(Fsub)=K 那么我们不必继续搜索,因为我们找到了 sublist 的最小长度
  2. 如果 FSub 的 Head 在 Fsub 的 Tail 中,那么我们从 FSub 中删除 Head,更新 min 并递归,
  3. 如果不是,那么我们将列表 C(在上面创建)的头部附加到 FSub 并递归。

如果 C 等于空列表,则停止

这个算法看起来很耗时,而且在某些大型列表的情况下,它可能会耗尽堆栈。


asked 关于第一个子列表部分并获得了此代码。

findFirstSubListHavingAllColors( NumList, List ,SubList, Len):-
    once((
         append(SubList, _, List),        % get SubList
         subtract(NumList, SubList, []),  % test whether NumList is contained in SubList
         length(SubList, Len)
  )).

我无法找到解决办法。


示例

列表=[1,3,1,3,1,3,3,2,2,1] , K=3 , N=10

答案应该是 4,因为包含数字 1,2,3 的最小 SubList 是 [1,3,3,2] 或 [3,2,2,1]。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    我认为这行得通:

    sublist(NumList, In, Out):-
        append([_, Out, _], In),
        forall(member(X, NumList), member(X, Out)).
    
    minSubList(NumList, In, Out) :-
        aggregate_all(min(Len, Out1),(sublist(NumList, In, Out1), length(Out1, Len)), Out).
    

    例如:

    ?- minSubList([1,2,3], [1,3,1,3,1,3,3,2,2,1], Out).
    Out = min(4, [1, 3, 3, 2]).
    

    注意我没有尝试过非常大的列表。

    【讨论】:

    • 两个答案似乎都比预期的要慢一些。有没有办法更快地解决这个问题?回溯可能是您提出的方法中的问题吗?
    【解决方案2】:

    这是另一个测试增加长度的子列表(K 到 len(L))的解决方案:

    min_len(L, K, M):-
      length(L, N),
      numlist(1, K, LK),
      once((
        between(K, N, M),
        length(SubL, M),
        append([_, SubL, _], L),
        subset(LK, SubL)
      )).
    

    测试用例:

    ?- min_len([1,3,1,3,1,3,3,2,2,1], 3, Min).
    Min = 4
    

    【讨论】:

    • 对于更大的情况,这似乎工作得更快。非常感谢
    猜你喜欢
    • 2016-09-08
    • 2020-11-08
    • 1970-01-01
    • 2012-10-22
    • 2015-11-08
    • 2019-06-01
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多