查找列表中的每个第k个元素

时间:2017-11-02 08:30:49

标签: haskell

我正在尝试在Haskell函数中编写一个函数,该函数将保留列表中的每个第k个元素。

      class1.class  
      class2.class

我已尝试过以下功能,但输出显示不一致。我希望列表为[3,6],但它会以[1,5,9]

显示
> keepl 2 [3,4,5,6,7,8,9]
[4,6,8]

4 个答案:

答案 0 :(得分:0)

不是一个完整的答案,因为这听起来像是一个家庭作业问题。但是这里有一个提示:如果你let (y:ys) = drop (k-1) xsy是要添加到列表中的下一个元素,你可以递归调用该函数,kys为争论,以获得其余的。终止递归的基本情况将是length xs < k

通过编写递归函数,你有了正确的想法。您不希望结果的第一个元素成为列表的第一个元素,而是k,因此不要在drop之前添加输入列表的头部。< / p>

还有其他可能的方法,但递归最简单(也可能是最有效的)。一些更聪明的人:map last . unfoldr (\xs -> if length xs < k then Nothing else Just (splitAt k xs))。对unfoldr的调用反复调用辅助函数,该函数将列表拆分为长度为k的块,丢弃任何剩余部分。然后map获取每个块的最后一个元素。或者生成索引列表并将!!映射到每个索引上。

答案 1 :(得分:0)

如果您想使用图书馆,这项工作

+(void)saveText:(NSString *)textTobeSaved atPath:(NSString*)fileName
{
    NSString *filePath = [NSString stringWithFormat:@"%@.text",fileName];

    NSString *path = [[self getDocumentsDirectoryPath].path
                      stringByAppendingPathComponent:filePath];
    NSFileHandle *fileHandler = [NSFileHandle fileHandleForWritingAtPath:path];
    if(fileHandler == nil) {
        [[NSFileManager defaultManager] createFileAtPath:path contents:nil attributes:nil];
        fileHandler = [NSFileHandle fileHandleForWritingAtPath:path];
    } else {
        textTobeSaved = [NSString stringWithFormat:@"\n-----------------------\n %@",textTobeSaved];
        [fileHandler seekToEndOfFile];
    }

    [fileHandler writeData:[textTobeSaved dataUsingEncoding:NSUTF8StringEncoding]];
    [fileHandler closeFile];
}

否则,如果这是学习haskell的练习,并且你想重建轮子,这将有效:

import Data.List.Split
let keepl k x = map last $ chunksOf k x

答案 2 :(得分:0)

好吧,你的函数确实给了每个 k -th元素(实际上,每个 k +第1个元素,因为你删除 k 并保持一个... ...只是,它从头部开始,即采用元素[0, k ,2· k +1,3· ķ 2 ...]。这是因为keepl k (x:xs) = x : ...子句在结果前面加x,无论如何。

如果您只想在删除一些元素之后取元素,请写出来:

keepl k xs = case drop k xs of
    ...

答案 3 :(得分:0)

您可以使用splitAt将原始列表拆分为长度为k的子列表:

splitlists :: Int -> [a] -> [[a]]
splitlists _ [] = []
splitlists k xs = first : (splitlists k rest)
    where
        (first, rest) = splitAt k xs

所以打电话如:

splitlists 2 [3,4,5,6,7,8,9]

会导致:

[[3,4],[5,6],[7,8],[9]]

然后取每个长度为k的子列表的最后一个元素,并将它们添加到新列表中:

keepl :: Int -> [a] -> [a]
keepl _ [] = []
keepl k xs = [last x | x <- splitlists k xs, length x == k]

示例电话:

> keepl 2 [3,4,5,6,7,8,9]
[4,6,8]
> keepl 3 [3,2,1,4,5,6,9,8,7,10]
[1,6,7]