www.jammni.de

Logo - Kleiner Drache
Login
Username:

Passwort:

Daten merken
Auto-Login
Registrieren
 
Online
niemand
 
Forumsuche
Suche nach:

Logo - DracheHaskell-Forum

  1 2 nächste Seite

lordofblh

Gepostet:
15.11.2008 21:09

Eine Liste zu zwei Listen  
Ich habe anfangsschwierigkeiten in haskell, insbesondere bei listn.

ich möchte irgenteine list (x:xs) aufteiln in die ersten 5 elemente und den rest.
nehmn wir mal als bsp: [1 .. 10],
gefunden hab ich da die internen funtionen take und drop. nun möchte ich die ergebnisse nur temporär als jeweils extra liste,
also einmal take 5 = [1,2,3,4,5]} und drop 5 [6,7,8,9,10]
damit ich sie mit meiner hilfsfunktion die 2listen braucht bearbeiten kann.--->

testmischen :: [a] -> [a]
nun meine listen aufspaltung in anfang und ende und das zwischenspiechern derer. ich hab keine ahnung wie ich das mache aber erstmal meine fantasie
take 5 = (y: ys)
drop 5 = (z: zs)


zusammen nehm durch eine funktion die 2listn zu einer baut.
hilfsfunktion (y: ys) (z: zs) = y: z: hilfsfunktion ys zs
ergebnis müsste sein: [y, z, .. , ys, zs]


das komplette ergebnis sollte also sein: [1,6,2,7,3,8,4,9,5,10]


hoffe mein anliegen ist klar :|
Zum Seitenanfang    
 
Siracusa

Gepostet:
15.11.2008 22:03

   
Hallo,

du brauchst deine Hilfsfunktion ja nur mit den beiden Teillisten aufrufen: testmischen xs = hilfsfunktion (take 5 xs) (drop 5 xs). Bei der Hilfsfunktion fehlen noch die Fälle, falls jeweils eine der Listen leer ist.


Viele Grüße,

Siracusa
Zum Seitenanfang    
 
lordofblh

Gepostet:
15.11.2008 22:54

   
1.danke
2.hilfsfunktion wurde kurz angerissen damit man etwa weiß was ich wollte ;) ja es fehlt noch x _ = bzw _ y = , is im orginal gereglt.
3.gut an diesen aufruf hatte ich gar nicht gedacht


dann frage ich mal anders, in z.bsp. java kann ich ja ganz einfach neue variablen definieren.
in haskell ist mir das (bis jetzt) nicht gelungen. eigentlich dachte ich über eine solche umsetztung nach. Wie bekomm ich also aus einer liste zwei neue definiert. [a] = [c]

Zum Seitenanfang    
 
Siracusa

Gepostet:
16.11.2008 01:14

   
Du kannst dir lokal Variablen einführen:
testmischen xs = hilfsfunktion anfang ende
where
anfang = (take 5 xs)
ende = (drop 5 xs)
Oder das gleichwertige:
testmischen xs = let
anfang = (take 5 xs)
ende = (drop 5 xs)
in hilfsfunktion anfang ende

Dies sind allerdings kein echten Variablen wie in Java, die gibt es in Haskell nicht. Es sind mehr nullstellige Funktionen, die ihren Wert nie ändern. Du kannst einer Variablen also später nicht nochmal einen neuen Wert zuweisen.
Zum Seitenanfang    
 
lordofblh

Gepostet:
16.11.2008 10:18

   
testmischen xs = let
anfang = (take 5 xs)
ende = (drop 5 xs)
in hilfsfunktion anfang ende
1. wofür steht das "let", bzw warum kann ich das auch so schreiben? die alternative schreibweise erschließt sich mir nicht so.

2. ich habs jetzt so allgemein forumliert.
shuffle :: [a] -> [a]
shuffle (x:xs) = hilfsfunktion anfang ende
where
anfang = take(length(x: xs) `div` 2) (x: xs)
ende = drop(length(x: xs) `div` 2) (x: xs)

3. es läuft darauf hinaus das ich eine funktion brauche:
shuffleursprung :: Int -> Int
also ich mische eine liste mit xs-elementen solange bis sie ihren alten zustand wieder bekommt, aber mindestens 1mal. also ->
eingabe : wie viele elemente die liste hat. ausgabe: wie oft man mischen musste, um den ausgangszustand zu bekommen.
ich dachte mir das so das ich die eingabe in eine liste packe also shuffleursprung n = [1 .. n]
nun das aussehen dieser liste speichere, um sie zu mischen bis sie wieder dieses aussehen hat (also vergleich der gespeicherten mit der gemischten liste)
in einer variable wiederum wollte ich spiechern wie oft er schon gemischt hat und diesen wert am ende ausgeben lassen.

nur fehlt mir dazu das "know how".
Zum Seitenanfang    
 
Siracusa

Gepostet:
16.11.2008 14:46

   
zu 1.) Die Haskell-Syntax ist stark an mathematische Formelsprache angelehnt. Wenn du deine Haskell-Funktion als mathematische Formel betrachtest, gibt es z.B. folgende zwei Möglichkeiten verwendete Hilfsvariablen/-funktionen zu beschreiben:
  Es gilt 1 + 1 = x, wobei x = 2, oder
  Sei x = 2, dann gilt 1 + 1 = x.

In Haskell kannst du genau diese beiden Varianten als Syntax benutzen:
  1 + 1 == x where x = 2, oder
  let x = 2 in 1 + 1 == x.

Das 'in' ist beim 'let' notwendig, damit man auch weiß, wo die Funktionsdefinition anfängt und wo die lokalen Variablen enden.

zu 3.) Das Prinzip ist schon ok. Man müßte mal überlegen, ob die gemischte Liste auch wirklich immer irgendwann wieder die Ausgangsform annimmt, sonst gerätst du wohlmöglich noch in eine Endlosrekursion. Und die Anzahl der schon durchlaufenen Schritte solltest du als Parameter (in veränderter Form) immer wieder an die rekursiven Aufrufe der Funktion weitergeben, da du Variablen ja wie gesagt nicht nachträglich verändern kannst. Deine Test-Funktion könnte dann etwa folgenden Typ haben:

teste :: [Int] -> [Int] -> Int -> Int
test orig neu anz = ...

wobei orig die unveränderte Liste, neu die aktuelle gemischte Liste und anz die Anzahl der schon durchlaufenen Schritte ist.
Zum Seitenanfang    
 
lordofblh

Gepostet:
16.11.2008 16:01

   
ja bei dieser art des mischverfahrens kehrt es immer wieder zur ausgangsposition zurück (recht schnell ~ [1 .. 52] = 8 durchläufe für orgi liste), Vorraussetztung: gerade anzahl an listeninhalt hat.


ich habe keine ahnung wie ich irgentetwas weitergebe, oder bei der orgi. liste behalten kann das das das orginal ist.
parameter hab ich bisher nur etwas gehabt bei filtern aber sonst ... :?


daraus resultiert auch, das ich hier zum ersten mal listen vergleichen werde. reicht hier ein
[liste a] == [liste] ?


{- das wissen wie mans machen kann ist nicht so schwer, sondern ehr wie kann ich mit meinen mitteln das machen-}
_______________________________________________

hab zwar keine idee ob sowas geht aber so in etwa sollte es sein.

shufflezaehler :: [Int] -> [Int] -> Int -> Int
shufflezaehler n == m [n] soll gleich [m] sein, da ich ihm keine 2listen übergeben will/kann

k (der zähler) muss beim ersten zählen, immer 0 beginn wie weiß haskell das?

shufflezaehler [1 .. n] [1 .. m] k = shuffle[1 .. m] k+ 1 if [n] == [m]
then return k
else shoufflezaehler [m]

Problem: also wenn ich das jetzt richtig raus lese, würde er am anfang [n] [m] immer gleich setzt sodass ich sie immer daur mischn würde.
Zum Seitenanfang    
 
Siracusa

Gepostet:
16.11.2008 17:35

   
Da es in Haskell keine Schleifen wie in Java oder C gibt, bildet man sich welche durch rekursive Aufrufe einer Funktion nach. Hier ist mal ein einfaches Beispiel für eine Funktion, die sich selbst wieder mit einem modifizierten Zählerwert aufruft und immer den aktuellen Zählerwert hinten an die Ergebnisliste anfügt:
f :: Int -> [Int]
f 0 = []
f n = (f (n-1)) ++ [n]

-- Aufruf:
> f 5
[1,2,3,4,5]

Wenn du nun noch andere Werte an die Funktion weiterreichen willst, fügst du einfach einen weiteren Parameter der Funktion hinzu. Die Funktion soll jetzt z.B. an eine vorgegebene Liste die Zahlen hinten anhängen:
f :: [Int] -> Int -> [Int]
f orig 0 = orig
f orig n = (f orig (n-1)) ++ [n]

-- Aufruf:
> f [7,8,9] 5
[7,8,9,1,2,3,4,5]
Die Original-Liste wird also imemr weiter "durchgereicht", bis man sie erst ganz am Ende der Rekursion tatsächlich für das Ergebnis benutzt.

Listen vergleichen ist in Haskell ganz einfach, nämlich genau mit dem == Operator: liste1 == liste2

Zum Seitenanfang    
 
lordofblh

Gepostet:
16.11.2008 18:39

   
f :: Int -> [Int]
f 0 = []
f n = (f (n-1)) ++ [n]

also zu der leeren liste rechne ich immer das n eins runter und füge 1 element der liste hinzu.

f :: [Int] -> Int -> [Int]
f orig 0 = orig
f orig n = (f orig (n-1)) ++ [n]

hier ist orig eine liste. und 0 = n
also hab ich "orig 3" dann kommt am ende eine liste mit [orig,1,2,3] raus??

ich seh nur nicht wie mir das weiterhelfen soll. ähm...
wenn ich eine liste habe: [1,2,3,4,5] jetzt addiere ich zu diesen zahlen immer 1hinzu zum bsp: f ... = map (1+) [1 .. 5] ist gleich [2,3,4,5,6]
das ruf ich jetzt rekursiv auf.
f ... = f ( map (1+) [1 .. 5])
wie krieg ich da den zähler rein? ich kann ja schlecht der leiste elemente hinzufügen.

Zum Seitenanfang    
 
Siracusa

Gepostet:
16.11.2008 20:45

   
> also zu der leeren liste rechne ich immer das n eins runter und füge 1 element der liste hinzu
Du machst aus dem aktuellen Zählerwert n eine Liste, und hängst die rekursiv berechnete Liste mit (n-1) davor. Irgendwann kommst du bei 0 an und gibst dann die leere Liste als Ergebnis zurück.

> hier ist orig eine liste. und 0 = n
> also hab ich "orig 3" dann kommt am ende eine liste mit [orig,1,2,3] raus??
Es kommt (orig ++ [1,2,3]) raus, weil orig ja auch eine Liste ist.

> wie krieg ich da den zähler rein? ich kann ja schlecht der leiste elemente hinzufügen
Wieso sollst du das nicht können? Hab ich doch bei meinen zwei Funktionen auch gemacht. (x:xs) fügt x vorne an xs an, (xs ++ [x]) fügt x hinten an xs an.
Zum Seitenanfang    
 

  1 2 nächste Seite