Algorithm 查找给定点积的列表和另一个列表的算法

Algorithm 查找给定点积的列表和另一个列表的算法,algorithm,functional-programming,sml,Algorithm,Functional Programming,Sml,我需要编写一个函数findL,它获取整数列表L1和所需的点积n,并返回非负整数列表L2,使得L1·L2=n。(我所说的“点积”是指两两乘积之和;例如,[1,2]·[3,4]=1.3+2.4=11。) 因此,例如,findL(11[1,2])可能返回SOME[3,4]。如果没有可能的列表,我将返回NONE 我用的是函数式语言。(特别是标准ML,但确切的语言并不那么重要,我只是想考虑一个FP算法。)到目前为止,我写的是: 假设我有findL(n,L1): 如果L1=[],则返回NONE 如果L1=[

我需要编写一个函数
findL
,它获取整数列表L1和所需的点积n,并返回非负整数列表L2,使得L1·L2=n。(我所说的“点积”是指两两乘积之和;例如,[1,2]·[3,4]=1.3+2.4=11。)

因此,例如,
findL(11[1,2])
可能返回
SOME[3,4]
。如果没有可能的列表,我将返回
NONE

我用的是函数式语言。(特别是标准ML,但确切的语言并不那么重要,我只是想考虑一个FP算法。)到目前为止,我写的是:

假设我有findL(n,L1):

  • 如果L1=[],则返回NONE
  • 如果L1=[x](长度列表1)
    • 如果(n>=0,x>0,n mod x=0),则返回一些[n div x]
    • 否则不返回
  • 如果L1的长度大于1,则我在findL上递归(n,L[1:])。如果它返回一个列表L2,则返回连接到L2的[1]。如果递归调用返回NONE,我对findL(0,L[1:])执行了另一个递归调用,如果结果不是NONE,则在[n div x]前面加上前缀。这对许多输入有效,但对其他输入无效
    我需要修改第三部分,但我不确定我的想法是否正确。如果有任何提示,我将不胜感激

    除非您需要说明输入中的空列表总是不好的(即使列表[]中的n=0),否则我建议根据您是否在末尾达到0(所有内容都已减去)为空列表返回不同的值,然后在接收到任何非空列表而不是一个元素列表时递归

    至于第三步,您需要测试输入列表中第一个元素的每一个可能的正整数倍,直到它们超过n,而不仅仅是第一个和最后一个。您得到的第一个非None值已经足够好了,因此您只需在返回列表中添加乘数(而不是倍数)。如果一切都不给你,你就什么也不回


    我不知道SML,但在Haskell我会这样做:

    import Data.Maybe(isJust,listToMaybe)
    --求正整数的线性组合
    solve::Integer->[Integer]->可能[Integer]
    --如果我们在剩下零的情况下走到了终点,那就太好了!
    解0[]=仅解[]
    --否则,这条路就不行了。
    解[]=无
    --如果输入列表中的一个元素为零,只需将该元素乘以一即可。
    求解n(0:xs)=案例求解n的xs
    无->无
    Just ys->Just(1:ys)
    solve n(x:xs)=listToMaybe——如果存在第一个解,则采用第一个解
    . 映射(\(m,只是ys)->m:ys)--将乘数放在列表的前面
    . 过滤器(isJust.snd)——删除非解决方案
    . zip[1..]--乘法器中的元组
    . 映射(\m->solve(n-m)xs)——使用每个多个
    $[x,x+x..n]--x到n的倍数
    

    .

    False不是一个列表。您的规范有一个类型错误。@melpomene我知道,我实际上没有返回任何类型的错误。如果有结果,我将返回一些结果(基本上使用SML中的选项)。我只是觉得不会有很多人知道SML,所以我没有深入讨论细节,只是寻求算法方面的帮助。如果你用一种特定的编程语言来标记,你的问题可能会得到更多的关注。@melpomene我标记函数式编程,因为“SML”的帖子很少,但为了以防万一,我也标记了它。谢谢。输入列表中的点积或任何值都允许为负数吗?对不起,我仍然感到困惑:/。该算法非常合理,但我不确定如何编写它。我用我的原始解决方案进行了编辑。我需要改变最后一种情况。我知道你不了解SML,但你能再解释一下你在上一个案例中做了什么吗?Haskell和SML似乎有类似的函数(map、filter、zip…),但我不确定如何创建倍数列表(x、x+x…)。在这一行中:map(\m->solve(n-m)xs)$[x,x+x..n],是否使用每个x,x+x等。。代替m?您添加到问题中的代码非常好,只是您需要测试
    x
    的所有倍数,而不仅仅是
    x
    n
    (如果
    n
    x
    的倍数)。你需要
    x
    2*x
    3*x
    ,等等,直到他们爬过
    n
    。是的,
    x
    x+x
    x+x+x
    等用于替换底部
    map
    中的
    m
    。您可以创建第二个函数,使该列表位于底部:
    乘以nx=go nx,其中go nx m=如果m>n,则[]否则m:go nx(m+x)
    。然后,您只需在原始函数中说
    乘以nx