F#函数查找列表的所有旋转

KPA*_*KPA 5 recursion f# list rotation

我在这里有一些F#代码用于递归函数,它将列表向左旋转n.我是F#的新手,我正在寻找一种修改此代码的方法,不仅可以按n位置输出一次旋转,还可以输出所有可能的旋转.

例如,假设我有列表:

let list1 = [1; 2; 3; 4]
Run Code Online (Sandbox Code Playgroud)

我想在此列表上调用rotate,以便输出为:

[ [1; 2; 3; 4]; [2; 3; 4; 1]; [3; 4; 1; 2]; [4; 1; 2; 3] ]
Run Code Online (Sandbox Code Playgroud)

我有左移n的代码是:

let rec rotate xs k = 
    match xs, k with
        |[], _ -> []
        |xs, 0 -> xs
        |x::xs, k when k > 0 -> rotate(xs @ [x])(k-1)
        |xs, k -> rotate xs (List.length xs + k)
Run Code Online (Sandbox Code Playgroud)

我不知道如何编辑它来执行上面列出的步骤.任何帮助或资源将不胜感激.我应该补充一点,我真的希望函数是递归的.谢谢.

Mar*_*ann 7

如果我正确理解了这个问题,你也可以使用内置函数编写List.permute函数:

let rotate xs =
    let length = xs |> List.length
    let perm n = xs |> List.permute (fun index -> (index + n) % length) 
    [1 .. length] |> List.rev |> List.map perm
Run Code Online (Sandbox Code Playgroud)

示例输出(稍微格式化以提高可读性):

> [1 .. 4] |> rotate;;
val it : int list list =
  [[1; 2; 3; 4];
   [2; 3; 4; 1];
   [3; 4; 1; 2];
   [4; 1; 2; 3]]
Run Code Online (Sandbox Code Playgroud)


KPA*_*KPA 1

因为我想使用递归和匹配来解决这个具体问题,所以我设法弄清楚了,这就是我想到的:

let rotate xs =
    let n = List.length xs
    let rec rotation xs n = 
        match xs, n with
        |[], _ -> []
        |xs, 0 -> xs
        |x::xs, n -> rotation (xs @ [x]) (n-1)

    let rec rotateList xs n = //we are compiling a list of different rotations
        match xs, n with
        |xs, 0 -> [] 
        |xs, n -> (rotation xs ((List.length xs)-n))::rotateList xs (n-1)
    rotateList xs n 
Run Code Online (Sandbox Code Playgroud)

我还特别想要一个输入参数,即列表