Wie kann ich {2n + 3m + 1 | n, m∈N} im Listenverständnis ausdrücken? N ist die Menge natürlicher Zahlen, einschließlich 0.Wie man {2n + 3m + 1 | n, m∈N} im Listenverständnis ausdrückt? (N ist die Menge natürlicher Zahlen einschließlich 0)
Antwort
[2*n + 3*m +1 | m <- [0..], n <- [0..]]
wird nicht funktionieren, weil es mit m = 0
beginnt und geht durch alle n
, und dann hat m = 1
und geht durch alle n, etc. Aber nur die m = 0
Teil ist unendlich , so werden Sie nie zu m = 1 oder 2 oder 3 usw. gelangen. So ist [2*n + 3*m +1 | m <- [0..], n <- [0..]]
genau dasselbe wie [2*n + 3*0 +1 | n <- [0..]]
.
Um alle von ihnen zu generieren, müssen Sie entweder erkennen, wie Benutzer vartec und Hynek -Pichi- Vychodil, dass die Menge der Zahlen, die Sie wollen, nur die natürlichen Zahlen - {0,2} ist. Oder Sie müssen irgendwie alle Paare (m, n) so aufzählen, dass m, n nichtnegativ sind. Ein Weg, dies zu tun ist, entlang jeder der "Diagonalen" zu gehen, wo m + n
das gleiche ist. Also beginnen wir mit den Zahlen, wo m + n = 0
, und dann die, wo m + n = 1
, etc. Jede dieser Diagonalen hat eine endliche Anzahl von Paaren, so dass Sie immer weiter zum nächsten, und alle Paare (m, n) werden schließlich gezählt werden.
Wenn wir i = m + n
und j = m
lassen, dann wird [(m, n) | m <- [0..], n <- [0..]]
[(j, i - j) | i <- [0..], j <- [0..i]]
Also für Sie, können Sie einfach
tun[2*(i-j) + 3*j +1 | i <- [0..], j <- [0..i]]
(Natürlich wird diese Methode auch Duplikate für Sie produzieren, weil es mehrere sind (m, n) Paare, die die gleiche Zahl in Ihrem Ausdruck erzeugen.)
weiß ich nicht, was ich getrunken habe, als ich diese Antwort gepostet habe: P danke für die Erklärung obwohl :) und ich werde meinen nutzlosen Beitrag löschen – Sujoy
Sie könnten immer 'nub' die Liste, um Dubletten zu beseitigen, obwohl es dann nicht streng eine Liste ist Verständnis nur, und es wird übermäßige Mengen an Speicher verwenden. – ephemient
Die folgende Haskell-Funktion liefert Ihnen alle Paare aus zwei Listen, auch wenn eine oder beide unendlich sind. Jedes Paar genau einmal:
allPairs :: [a] -> [b] -> [(a, b)]
allPairs _ [] = []
allPairs [] _ = []
allPairs (a:as) (b:bs) =
(a, b) : ([(a, b) | b <- bs] `merge`
[(a, b) | a <- as] `merge`
allPairs as bs)
where merge (x:xs) l = x : merge l xs
merge [] l = l
könnten Sie dann Ihre Liste schreiben, wie
[2 * n + 3 * m + 1 | (n,m) <- allPairs [0..] [0..] ]
Um ein Gefühl dafür zu bekommen, wie es funktioniert, eine unendliche Viertel Ebene zeichnen, und Blick auf die Ergebnisse von
take 100 $ allPairs [0..] [0..]
Sie können versuchen, alle Ganzzahlpaare aufzulisten. Dieser Code in der Aufzählung bei University of California Berkeley beschrieben basiert (nicht enthalten 0)
data Pair=Pair Int Int deriving Show
instance Enum Pair where
toEnum n=let l k=truncate (1/2 + sqrt(2.0*fromIntegral k-1))
m k=k-(l k-1)*(l k) `div` 2
in
Pair (m n) (1+(l n)-(m n))
fromEnum (Pair x y)=x+((x+y-1)*(x+y-2)) `div` 2
Aber Sie eine andere Aufzählung verwenden können.
Dann können Sie tun:
[2*n+3*m+1|Pair n m<-map toEnum [1..]]
meine 0,2:
trans = concat [ f n | n <- [1..]]
where
mklst x = (\(a,b) -> a++b).unzip.(take x).repeat
f n | n `mod` 2 == 0 = r:(mklst n (u,l))
| otherwise = u:(mklst n (r,d))
u = \(a,b)->(a,b+1)
d = \(a,b)->(a,b-1)
l = \(a,b)->(a-1,b)
r = \(a,b)->(a+1,b)
mkpairs acc (f:fs) = acc':mkpairs acc' fs
where acc' = f acc
allpairs = (0,0):mkpairs (0,0) trans
result = [2*n + 3*m + 1 | (n,m) <- allpairs]
Dies scheint eine Hausaufgaben Frage zu sein, ist aber nicht als solche gekennzeichnet. Bitte lesen Sie die entsprechenden FAQ: http://stackoverflow.com/questions/230510/homework-on-stackoverflow – nominolo
Dies ist unterspezifiziert.Möchten Sie Semantik (d. H. Keine Duplikate) in Ihrer Antwort festlegen? Besteht Ordnung? –