3

長さが より大きいgetIndex xs y最初のサブリストのインデックスが必要です。xsy

出力は次のとおりです。

[[],[4],[4,3],[3,5,3],[3,5,5,6,1]]
aufgabe6: <<loop>>

なぜgetIndex機能しないのですか?

import Data.List

-- Die Sortierfunktion --
myCompare a b
    | length a < length b = LT
    | otherwise = GT

sortList :: [[a]] -> [[a]]
sortList x = sortBy myCompare x

-- Die Indexfunktion --
getIndex :: [[a]] -> Int -> Int
getIndex [] y = 0
getIndex (x:xs) y
    | length x <= y = 1 + getIndex xs y
    | otherwise = 0
    where (x:xs) = sortList (x:xs)

main = do
    print (sortList [[4],[3,5,3],[4,3],[3,5,5,6,1],[]])
    print (getIndex [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2)
4

3 に答える 3

9

終了させる

問題はこの場合

getIndex (x:xs) y
    | length x <= y = 1 + getIndex xs y
    | otherwise = 0
    where (x:xs) = sortList (x:xs)

どれがどれだか混乱して(x:xs)います。代わりに行う必要があります

getIndex zs y
    | length x <= y = 1 + getIndex xs y
    | otherwise = 0
    where (x:xs) = sortList zs

与える

Main> main
[[],[4],[4,3],[3,5,3],[3,5,5,6,1]]
3
*Main> getIndex [[],[2],[4,5]] 1
2
*Main> getIndex [[],[2],[4,5]] 5
3

これにより、少なくともソートされたリスト内の最初の長さのリストの数が得られます。これは、 「元のリストの長さは最大でいくつですか?」yという質問に実際に答えます。y

どうすれば他の事実を知ることができますか?

元のリストからの位置が必要な場合は、次を使用してエントリに位置をタグ付けできますzip

*Main> zip [1..] [[4],[3,5,3],[4,3],[3,5,5,6,1],[]]
[(1,[4]),(2,[3,5,3]),(3,[4,3]),(4,[3,5,5,6,1]),(5,[])]

それらを操作するためのユーティリティ関数を作成しましょう。

hasLength likeThis (_,xs) = likeThis (length xs)

次のように使用できます。

*Main> hasLength (==4) (1,[1,2,3,4])
True
*Main> filter (hasLength (>=2)) (zip [1..] ["","yo","hi there","?"])
[(2,"yo"),(3,"hi there")]

つまり、 より長い長さの最初のリストのインデックスを与える関数を書くのが簡単になりましたy:

whichIsLongerThan xss y = 
    case filter (hasLength (>y)) (zip [1..] xss) of
         [] -> error "nothing long enough" -- change this to 0 or (length xss + 1) if you prefer
         (x:xs) -> fst x

これにより、

*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2
2
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 3
4
*Main> whichIsLongerThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 0
1

短い?

しかし、同様のトリックを行うことができます:

whichIsShorterThan xss y = 
    case filter (hasLength (<y)) (zip [1..] xss) of
         [] -> error "nothing short enough" -- change this to 0 or (length xss + 1) if you prefer
         (x:xs) -> fst x

だからあなたは得る

*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 2
1
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 1
5
*Main> whichIsShorterThan [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 0
*** Exception: nothing short enough

一般化された

そこで共通のテーマを引き出してみましょう。

whichLength :: (Int -> Bool) -> [[a]] -> Int
whichLength likeThis xss = 
    case filter (hasLength likeThis) (zip [1..] xss) of
         [] -> error "nothing found" -- change this to 0 or (length xss + 1) if you prefer
         (x:xs) -> fst x

私たちができるように

*Main> whichLength (==5) [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 
4
*Main> whichLength (>2) [[4],[3,5,3],[4,3],[3,5,5,6,1],[]] 
2
于 2013-05-20T00:34:27.180 に答える
1

ということindex of the firs sublist with length > yですか?それが目標ではない (そして目標で< yある) 場合は、

length x <= y = 1 + getIndex xs y

する必要があります

length x >= y = 1 + getIndex xs y

また、決して終わらないので、bottom(x:xs) = sortList (x:xs)です。何らかの方法で並べ替えたい場合は、AndrewC のソリューションに従うことができます。

于 2013-05-20T00:34:53.260 に答える