Hlavní navigace

Vlákno názorů k článku Paralelní přepisování řetězců v L-systémech od lob - Mel bych par pripominek k funkci applyRules, ktera...

  • Článek je starý, nové názory již nelze přidávat.
  • 7. 11. 2006 17:12

    lob (neregistrovaný)
    Mel bych par pripominek k funkci applyRules, ktera ma provadet paralelni aplikaci pravidel na axiom. V prvni rade se axiom vubec nepouziva, tato vada je pro Sierpinskeho trojuhelnik kompenzovana prevzetim rozvinute prave strany 2. pravidla (Y=...) a doplnenim F, coz da axiom YF, pro Hilbertovu krivku se tak axiomem vlastne stava Y misto X. Navic pouzity zpusob prepisovani pravych stran pravidel misto klasickeho nahrazovani znaku v axiomu zpusobuje, ze zadana maximalni iterace vede na obrazec s iteraci 2^maxiter (priklad pro Kochovu krivku: F=F+F--F+F, 1. F=F+F--F+F+F+F--F+F--F+F--F+F+F--F+F 2. F=F+F--F+F+F+F--F+F--F+F--F+F+F--F+F+
    F+F--F+F+F+F--F+F--F+F--F+F+F--F+F--
    F+F--F+F+F+F--F+F--F+F--F+F+F--F+F+
    F+F--F+F+F+F--F+F--F+F--F+F+F--F+F).
  • 8. 11. 2006 9:08

    Pavel Tišnovský
    Mate pravdu, tu funkci jsem "bastlil" na posledni chvili (puvodne byla napsana uplne jinak, ale potom jsem objevil jednu chybu, ktera by se sice na dnesnich gramatikach neprojevila, ale pro jina pravidla uz ano).

    Mel jsem dojem, ze takto udelane prepisovani je rychlejsi, protoze dochazi k mene kopiim novych retezcu do retezcu starych (samotne nahrazovani urychlit moc nejde, ale porad je implementovano lip, nez napr. nahrazovanim znaku ala Java). Zkusite navrhnout korektni reseni? (myslim, ze postacuje zmenit "prostredni" smycku tak, aby brala v uvahu i axiom).
  • 8. 11. 2006 10:55

    Pavel Tišnovský

    Zdravim, pokusil jsem se narychlo funkci applyRules() upravit do korektni podoby a vysledek vypada nasledovne (kontrolni vypisy jsou zakomentovane):

    //-----------------------------------------------------------------------------
    // Aplikace prepisovacich pravidel na retezec
    //-----------------------------------------------------------------------------
    void applyRules(
            char *rules[],                          // pole prepisovacich pravidel
            char *axiom,                            // axiom - prvotni naplneni retezce
            char *ret,                              // retezec, do ktereho se ma ulozit vysledek
            int maxiters)                           // maximalni pocet iteraci (aplikaci pravidel)
    {
        int rulesCount;                             // pocet pravidel
        char *leftSide;                             // pole levych casti prepisovacich pravidel
        char **rightSideSrc;                        // pole pravych casti prepisovacich pravidel
        int i, j, k, iter;                          // pocitadla smycek a indexy znaku
        char src[MAX_LENGTH];
    
        // zjistit celkovy pocet prepisovacich pravidel
        for (rulesCount=0; rules[rulesCount]; rulesCount++)
            ;
        // nyni mame v promenne rulesCount ulozen pocet prepisovacich pravidel
        printf("celkovy pocet pravidel=%d\n", rulesCount);
    
        // alokace pameti pro levou stranu prepisovacich pravidel
        // a inicializace pole znaku
        leftSide=(char *)malloc(rulesCount*sizeof(char));
        for (i=0; i<rulesCount; i++)
            leftSide[i]=rules[i][0];
    
        // alokace pameti pro pravou stranu prepisovacich pravidel
        // a inicializace pravych stran
        rightSideSrc=(char **)malloc(rulesCount*sizeof(char *));
        for (i=0; i<rulesCount; i++) {
            rightSideSrc[i]=(char *)malloc(MAX_LENGTH);
            strcpy(rightSideSrc[i], rules[i]+2); // podretezec za znakem '='
        }
    
        // nastaveni axiomu
        strcpy(ret, axiom);
    
        // hlavni iteracni smycka
        for (iter=0; iter<=maxiters; iter++) {
            j=0;
            printf("iteration=%d\n", iter);
            strcpy(src, ret);
            puts(src);
            char *ch;
            // projit celym retezcem
            for (ch=src; *ch; ch++) {
                int left;
                int found=0;
                // pro kazdy znak zjistit, zda pro nej neexistuje prepisovaci pravidlo
                // a pokud ano, provest prepis
                for (left=0; left<rulesCount; left++) {
                    if (leftSide[left]==*ch) {
                        //printf("%c -- %s\n", *ch, rightSideSrc[left]);
                        for (k=0; rightSideSrc[left][k]; k++, j++)          // provest prepis
                            ret[j]=rightSideSrc[left][k];
                        found=1;
                    }
                }
                // zadne pravidlo pro dany znak jsme nenasli, proto se znak
                // pouze zkopiruje
                if (!found) {
                    //printf("%c -- %c\n", *ch, *ch);
                    ret[j]=*ch;
                    j++;
                }
            }
            ret[j]=0;
        }
    }