相关疑难解决方法(0)

foldl与具有无限列表的foldr行为

此问题中 myAny函数的代码使用foldr.当谓词满足时,它会停止处理无限列表.

我用foldl重写了它:

myAny :: (a -> Bool) -> [a] -> Bool
myAny p list = foldl step False list
   where
      step acc item = p item || acc
Run Code Online (Sandbox Code Playgroud)

(请注意,步骤函数的参数已正确反转.)

但是,它不再停止处理无限列表.

我试图在Apocalisp的答案中跟踪函数的执行情况:

myAny even [1..]
foldl step False [1..]
step (foldl step False [2..]) 1
even 1 || (foldl step False [2..])
False  || (foldl step False [2..])
foldl step False [2..]
step (foldl step False [3..]) 2
even 2 || (foldl step False [3..])
True   || (foldl …
Run Code Online (Sandbox Code Playgroud)

haskell combinators lazy-evaluation fold

115
推荐指数
3
解决办法
2万
查看次数

用于查找给定字符串的下一个更大排列的算法

我想要一个有效的算法来找到给定字符串的下一个更大的排列.

algorithm

55
推荐指数
4
解决办法
5万
查看次数

为什么Python的itertools.permutations包含重复项?(当原始列表有重复时)

普遍认为n个不同符号的列表有n!排列.然而,当符号不明显时,在数学和其他地方最常见的惯例似乎只计算不同的排列.因此,列表的排列[1, 1, 2]通常被认为是
[1, 1, 2], [1, 2, 1], [2, 1, 1].实际上,以下C++代码正好打印出这三个:

int a[] = {1, 1, 2};
do {
    cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
} while(next_permutation(a,a+3));
Run Code Online (Sandbox Code Playgroud)

另一方面,Python itertools.permutations似乎打印其他东西:

import itertools
for a in itertools.permutations([1, 1, 2]):
    print a
Run Code Online (Sandbox Code Playgroud)

这打印

(1, 1, 2)
(1, 2, 1)
(1, 1, 2)
(1, 2, 1)
(2, 1, 1)
(2, 1, 1)
Run Code Online (Sandbox Code Playgroud)

正如用户Artsiom Rudzenka在一个答案中指出的那样,Python文档说:

元素根据其位置而不是其价值被视为唯一元素.

我的问题:为什么做出这个设计决定?

似乎遵循通常的惯例会给出更有用的结果(事实上它通常正是我想要的)......或者是否存在一些我缺少的Python行为应用?

[或者是一些实施问题?这里的算法next_permutation- 例如在StackOverflow上解释(由我)在这里显示为O(1)摊销 - 在Python中似乎是高效和可实现的,但是Python做了更有效的事情,因为它不保证基于词典顺序价值?如果是这样,效率的提高是否值得呢?]

python algorithm language-design permutation

49
推荐指数
3
解决办法
1万
查看次数

你如何迭代地计算0到N的所有可能的排列?

我需要迭代地计算排列.方法签名如下:

int[][] permute(int n)

为了n = 3例如,返回值将是:

[[0,1,2],
 [0,2,1],
 [1,0,2],
 [1,2,0],
 [2,0,1],
 [2,1,0]]
Run Code Online (Sandbox Code Playgroud)

您将如何以最有效的方式迭代地执行此操作?我可以递归地执行此操作,但我有兴趣看到许多替代方法来迭代地执行此操作.

language-agnostic math permutation

30
推荐指数
3
解决办法
2万
查看次数

没有递归函数调用的排列

要求:生成集合的所有可能组合的算法,无需重复,或递归调用函数以返回结果.

大多数,如果不是所有的答案都在JavaScript中的Permutations提供从循环或其他函数中递归调用函数以返回结果.

循环内的递归函数调用示例

function p(a, b, res) {
  var b = b || [], res = res || [], len = a.length;
  if (!len) 
    res.push(b)
  else 
    for (var i = 0; i < len 
         // recursive call to `p` here
       ; p(a.slice(0, i).concat(a.slice(i + 1, len)), b.concat(a[i]), res)
       , i++
    );
  return res
}

p(["a", "b", "c"]);
Run Code Online (Sandbox Code Playgroud)

当前的问题试图在线性过程中创建给定的排列,依赖于先前的排列.

例如,给定一个数组

var arr = ["a", "b", "c"];
Run Code Online (Sandbox Code Playgroud)

确定可能的排列总数

for (var len = 1, i = k …
Run Code Online (Sandbox Code Playgroud)

javascript algorithm permutation

29
推荐指数
6
解决办法
4479
查看次数

我应该如何为中国邮递员问题生成分区/对?

我正在研究一个涉及解决中国邮递员问题的课程.我们的任务只要求我们编写一个程序来解决它的硬编码图,但我试图在我自己的一般情况下解决它.

给我带来麻烦的部分是为奇数顶点生成配对分区.

例如,如果我在图中有以下标记的奇数顶点:

1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)

我需要找到我可以用这些顶点做出的所有可能的配对/分区.

我发现我会i给出分配:

  n = num of odd verticies  
  k = n / 2  
  i = ((2k)(2k-1)(2k-2)...(k+1))/2^n
Run Code Online (Sandbox Code Playgroud)

因此,考虑到上面的6个奇数顶点,我们将知道我们需要生成i = 15分区.

15个部分看起来像:

1 2   3 4   5 6
1 2   3 5   4 6
1 2   3 6   4 5
...
1 6   ...
Run Code Online (Sandbox Code Playgroud)

然后,对于每个分区,我取每对,找到它们之间的最短距离,并为该分区求和.选择其对之间具有最小总距离的分区,然后我将奇数顶点之间的最短路径(在所选分区中找到)之间的所有边加倍.

这些代表邮递员必须走两次的边缘.

起初我以为我已经制定了适当的算法来生成这些分区:

  1. 从按升序排序的所有奇数顶点开始

    12 34 56

  2. 选择当前具有最大顶点的对后面的对

    12 [34] 56

  3. 将此对中的第二个数字增加1.将所选对的左侧所有内容保持相同,并使所选对中右侧的所有数字与集合中的其余数字一致,按递增顺序排序.

    12 35 46

  4. 重复

但是,这是有缺陷的.例如,我意识到当我到达最后并且选择对位于最左侧位置(即)时:

[16] .. ..

我计算出来的算法在这种情况下会停止,而不会生成其余开始的对[16],因为它的左边没有对可以改变.

所以,它又回到了绘图板.

之前有没有研究过这个问题的人是否有任何提示可以帮助我指出正确的方向来生成这些分区?

algorithm

15
推荐指数
1
解决办法
1597
查看次数

计算F#中的排列

受这个问题答案的启发,如何在F#中创建通用排列算法?谷歌没有给出任何有用的答案.

编辑:我在下面提供了我最好的答案,但我怀疑Tomas的更好(当然更短!)

algorithm f# permutation

14
推荐指数
2
解决办法
5394
查看次数

列出1 ... n之间k个整数的所有可能组合(n选择k)

出于特殊的原因,我决定寻找一种算法,该算法产生1 ... n之间k个整数的所有可能选择,其中k整数中的顺序无关紧要(n选择k thingy).

从完全相同的原因,这是没有理由的,我也用C#实现了它.我的问题是:

你在我的算法或代码中看到任何错误吗?而且,更重要的是,你能建议一个更好的算法吗?

请注意算法而不是代码本身.这不是我写过的最漂亮的代码,虽然可以告诉你是否看到了错误.

编辑: Alogirthm解释 -

  • 我们持有k指数.
  • 这会创建k个嵌套for循环,其中循环i的索引是indices [i].
  • 它模拟k for for循环,其中indices [i + 1]属于嵌套在indices [i]循环中的循环.
  • indices [i]从索引[i-1] + 1到n-k + i + 1运行.

码:

public class AllPossibleCombination
{
    int n, k;
    int[] indices;
    List<int[]> combinations = null;

    public AllPossibleCombination(int n_, int k_)
    {
        if (n_ <= 0)
        {
            throw new ArgumentException("n_ must be in N+");
        }
        if (k_ <= 0)
        {
            throw new ArgumentException("k_ must be in N+");
        }
        if (k_ …
Run Code Online (Sandbox Code Playgroud)

c# algorithm math combinatorics

11
推荐指数
2
解决办法
1万
查看次数

Lisp Style问题标签是否有本地功能?

我想知道是否有关于在Lisp中使用标签的标准做法.我一直在讨论第一个答案中描述的算法的Lisp实现这里懒惰地生成排列 我当前版本使用标签来突破部分功能.

(defun next-permutation (pmute)
  (declare (vector pmute))
  (let ((len (length pmute)))
    (if (> len 2)
        (labels ((get-pivot ()
                   (do ((pivot (1- len) (1- pivot)))
                       ((or (= pivot 0)
                            (< (aref pmute (1- pivot))
                               (aref pmute pivot)))
                        pivot)))
                 (get-swap (pivot)
                   (let ((swp (1- len)))
                     (loop for i from (1- len) downto pivot do
                           (if (or (and (> (aref pmute i)
                                           (aref pmute (1- pivot)))
                                        (< (aref pmute i) (aref pmute swp)))
                                   (< (aref pmute swp) (aref pmute (1- pivot)))) …
Run Code Online (Sandbox Code Playgroud)

lisp coding-style common-lisp

10
推荐指数
1
解决办法
738
查看次数

sbcl在第二次调用函数时永远运行

功能:

给定列表lst返回列表的内容的所有排列,其长度为k,如果未提供,则默认为列表的长度.

(defun permute (lst &optional (k (length lst)))
  (if (= k 1)
   (mapcar #'list lst)
   (loop for item in lst nconcing
     (mapcar (lambda (x) (cons item x)) 
             (permute (remove-if (lambda (x) (eq x item)) lst) 
                      (1- k))))))
Run Code Online (Sandbox Code Playgroud)

问题:我在连接到sbcl的emacs中使用SLIME,我还没有做太多的自定义.该功能在较小的输入上工作正常,例如lst ='(1 2 3 4 5 6 7 8)k = 3,这在实践中主要用于它.但是,当我连续两次使用大输入调用它时,第二个调用永远不会返回,而sbcl甚至不会显示在顶部.这些是REPL的结果:

CL-USER> (time (nth (1- 1000000) (permute '(0 1 2 3 4 5 6 7 8 9))))
Evaluation took:
12.263 seconds of real time
12.166150 seconds of total run time (10.705372 user, …
Run Code Online (Sandbox Code Playgroud)

lisp recursion sbcl common-lisp slime

6
推荐指数
1
解决办法
594
查看次数

懒惰的随机算法

我有一个很大的元素列表,我想以随机顺序迭代.但是,我无法修改列表,我也不想创建它的副本,因为1)它很大,2)可以预期迭代会提前取消.

List<T> data = ...;
Iterator<T> shuffled = shuffle(data);
while (shuffled.hasNext()) {
    T t = shuffled.next();
    if (System.console().readLine("Do you want %s?", t).startsWith("y")) {
        return t;
    }
}
System.out.println("That's all");
return t;
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个算法,上面的代码将运行O(n)(并且最好只需要O(log n)空格),因此缓存之前生成的元素不是一个选项.我不在乎算法是否有偏差(只要它不明显).

(我在我的问题中使用伪Java,但如果你愿意,你可以使用其他语言)

这是我到目前为止最好的.

Iterator<T> shuffle(final List<T> data) {
    int p = data.size();
    while ((data.size() % p) == 0) p = randomPrime();
    return new Iterator<T>() {
        final int prime = p;
        int n = 0, i = 0;
        public boolean hasNext() { return i < …
Run Code Online (Sandbox Code Playgroud)

language-agnostic algorithm shuffle lazy-evaluation

6
推荐指数
1
解决办法
841
查看次数

N的C++算法!排序

我有一个N项目列表,我想知道如何循环列表以获得每个组合.没有双打,所以我需要得到全部N!排序.额外的内存没有问题,我正在考虑最简单的算法,但我遇到了麻烦.

c++ permutation factorial

5
推荐指数
2
解决办法
1566
查看次数