ich hab da mal was vorbereitet...



  • aber guter pseudocode :>

    finix:
    recht hast du.
    wollte mir das map und apply in C ersparen.
    und das andere zip ist ein wenig kaputt:

    > (zip '(1 2 3) '(4 5 6))
    ((1 . 4) (2 . 5) (3 . 6))
    

    ausserdem ist dieses zip hier ein anderes.
    es werden 2 listen zusammengebracht
    edit: hab ich wohl nen unpassenden namen uebernommen... naja.

    zu meinem code:
    der hat immernoch bugs. ich bin noch am basteln.



  • FALSCHES FORUM schrieb:

    🙄 DAS IST KEIN ANSI C 🙄

    Es geht um den Algorithmus in c.rackwitz' ANSI C Programm, und dafür ist die kürzere, lesbarere Darstellung doch wohl angebracht.



  • c.rackwitz schrieb:

    und das andere zip ist ein wenig kaputt:

    > (zip '(1 2 3) '(4 5 6))
    ((1 . 4) (2 . 5) (3 . 6))
    

    Nah, das war schon so beabsichtigt. Könnte man natürlich "reparieren" indem man das zweite cons durch ein list ersetzt.



  • ja. die funktionen sind trotzdem nur namensverwandt 🙂

    hier mal verbessert: http://paste.lisp.org/display/43224



  • finix schrieb:

    Es geht um den Algorithmus in c.rackwitz' ANSI C Programm, und dafür ist die kürzere, lesbarere Darstellung doch wohl angebracht.

    OH OH WENN DAS EIN MOD SIEHT !!!
    ooohoooohhh... !!!



  • FALSCHES FORUM schrieb:

    OH OH WENN DAS EIN MOD SIEHT !!!
    ooohoooohhh... !!!

    was glaubst du, warum ich mir die muehe gemacht hab, diesen wunderhuebschen scheme lisp code nach C zu bringen?
    weil die leute den algorithmus vor lauter pointern nicht mehr sehen.
    weil "pseudocode" scheinbar in prosa geschrieben sein muss und nicht ausfuehrbar sein darf.

    aja, ich find das unheimlich amuesant, wie sich leute mit pointern abmuehen.
    es schult vorstellung und logisches denken, zugegeben.
    den leuten wird aber keine moeglichkeit gezeigt, wie man mit dem kram ohne viel nachdenken klarkommt.
    von selbst drauf kommen kann keiner erwarten. anfaenger koennen nicht wissen, dass es auch einfacher geht.

    es geht einfacher:
    algorithmus verstehen.
    schrittfolge in pseudocode festhalten.
    pseudocode in grossen oder kleinen schritten nach unten uebersetzen.

    listen A und B zippen:
    * neue liste
    * A[0] anfuegen, B[0] anfuegen (beides jeweils wenn die liste nicht leer ist)
    * rester von A und B zippen, ergebnis auch anfuegen (wenn von A oder B noch was uebrig ist)

    anders ausgedrueckt (rekursiv, funktional):
    zip(A, B):
    A leer? -> B
    nur B leer? -> A
    sonst (nichts leer) -> A[0] + B[0] + zip(rest von A, rest von 😎

    natuerlich muss man dafuer schon mal von rekursion gehoert haben

    spontan kommt mir in den sinn:
    * ne verkettete liste mit pointern auf anfang und ende

    res = leere verkettete liste;
    while (a || b)
    {
        if (a) {
            append(res, a->value);
            a = a->next;
        }
        if (b) {
            append(res, b->value);
            b = b->next;
        }
    }
    

    dazu muss man sich natuerlich vorher verkettete listen mit pointer auf anfang und ende basteln... und das ist einfach!
    man braucht:
    * ein struct Liste {pointer auf erstes und letztes element}
    * struct Element { pointer auf naechstes; eigentlicher wert}

    anfuegen:
    * N = neues element, wert sei was man will
    * leere liste (kein erstes)? liste.erstes = N;
    * sonst? liste.letztes.next = N;
    * liste.letztes = N

    das ist die ganze magie.
    ist nicht schwer zu verstehen. muss einem nur einer sagen.



  • und weils so viel spass macht, daten zu zerstoeren, hier destruktives zip:

    A:  1  2  3  4
    B:  1  2  3  4  5  6  7
    
    A:  1  2  3  4  5  6  7
    B:  1  2  3  4
    
    Node *zip(Node *a, Node *a) {
        Node *res;
        Node *an, *bn;
    
        if (!a) return b;
        if (!b) return 0;
    
        res = a;
    
        while (a && b) {
            an = a->next;
            bn = b->next;
    
            a->next = b;
    
            if (an)
                b->next = an;
            else
                break; // a zu ende. wir auch.
    
            a = an;
            b = bn;
        }
        return res;
    }
    

    http://img514.imageshack.us/img514/9912/pointersct9.png



  • stringzip:

    void strzip (char *a, char *b, char *out)
    {
       while (*a || *b)
       {
          if (*a)
             *out++ = *a++;
          if (*b)
             *out++ = *b++;
       }   
       *out = 0;
    }
    

    🙂



  • kannst du auch ein unzip?
    nicht nur fuer strings, sondern auch fuer verkettete listen?
    konstruktiv und destruktiv?

    probiers mal mit cons() 🙂



  • c.rackwitz schrieb:

    kannst du auch ein unzip?
    nicht nur fuer strings, sondern auch fuer verkettete listen?

    unzip müsste etwa so aussehen:

    void strunzip (char *in, char *a, char *b)
    {
       while (*in)
       {
          *a++ = *in++;
          if (*in == 0)
             break;
          *b++ = *in++;
       }
       *a = *b = 0;
    }
    

    für listen alle '*x++' links vom '=' mit 'add_head' und rechts davon mit 'remove_head' (oder tail) und die abfragen auf '0' mit 'is_empty' ersetzen.
    das anhängen der nullen am ende kann man sich bei listen ja sparen...
    🙂


Anmelden zum Antworten