C - return problema [megoldva]

 ( Tomi87 | 2013. március 22., péntek - 8:47 )

Ami eleg kiakaszto. Lassuk a kodot:

//works w/ linked list

int find(Nodepointer node, int number)
{
    if(node != NULL)
    {
        if(node->value == number)
        {
            //nemi kod

            return temp_rec_counter; //local var
        }
        else
        {
            //nemi kod

            node = node->next;
            find(node, number);
        }
    }
    return -1;
}

Eljut a return temp_rec_counter; sorig, ott viszont nem adja vissza az erteket main()-nak, hanem a function-t zaro zarojelre ugrik, onnan
a find(node, taxi_number); rekurziv sorra, majd vegigmegy a vegen es -1-et ad vissza.

Na most hat szoval... wtf??? A return nem azt kene, hogy csinalja, hogy azonnal visszaadja az iranyitast es esetleg valami erteket az azt hivo-nak? Nem ertem, valaki felhomalyosithatna. Koszonom.

Szerk.: Ha a keresett (number-rel megegyezo) ertek az elso node-ban van akkor az elvarasoknak megfeleloen mukodik, ha a masodikban, akkor akkor azt, amit leirtam.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Szerintem ez a sor:

find(node, number);

ez akart lenni:
return find(node, number);

A return az jol mukodik. Visszaadja az eredmenyt a hivonak. Visztont ha find meghivja onmagat, akkor ott a hivo find fogja visszakapni az eredmenyt.


"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series

Koszonom szepen, teljesen ertheto amit mondasz. Megfeledkeztem rola, hogy ha a masodik node-ot vizsgalom, a find() hivoja nem a main() hanem maga a find().

Legyszives ilyenkor, ha megvan a problemad megoldasa, tegyel ki egy [Megoldva] vagy [Solved]elotagot a topik cimebe, ez a szokas a HUP-on.

Megjegyzés: Az a 'local var' igazából 'global var' és használata súlyosan ellenjavalt. Egy lehetőség helyette:

int find (const Node *node, int number)
{
    int i, found;

    for (i= 0, found= -1; node && found==-1; ++i, node= node->next) {
        if (node->value == number) {
            //nemi kod (vagy némi kód)
            found=i;

        } else {
            //nemi kod
        }
    }
    return found;
}

Minek kene a found valtozo?
Masreszt mivel node valtozot const, ezert a node = node->next ertekadas szerintem nem mukodik.

int find (const Node *node, int number)
{
    int i = 0;
    Node* current = node;
    while(current != NULL) {
        if(current->value == number) {
            return i;
        }
        i++;
        current = current->next;
    }
    return -1;
}

A pointereket/referenciakat jobbrol balra kell olvasni, tehat ez: const Node *node
pointer const Node-ra, tehat magat a pointer-t piszkalhatod.


"If you must mount the gallows, give a jest to the crowd, a coin to the hangman, and make the drop with a smile on your lips" The Wheel of Time series

Ok thx, egy Javas embert ez megvezet. Igy viszont mar tenyleg nem kell a current valtozo sem.

Ha mar optimalizalunk, a current se kell. :)

---
pontscho / fresh!mindworkz

En azert argumentumnak nem szoktam erteket adni - hacsak nem ez a cel. Az a +1 pointer mar nem oszt-nem szoroz. Foleg ha nem hasznalom rajta ezeket a muveleteket :-)
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

Ebben nagy igazság van; ha mondjuk debuggolni/logolni kell, nagyon hasznos, ha nem rontottuk el az eredeti paramétereket.

> Minek kene a found valtozo?

Mert nem szeretek függvény közepéből (pláne ciklus közepéből) return-ölni.

Akkor meg breakelj.

De ha mar megoldottad a problemat (azaz megtalaltad a keresett elemet), akkor minek vegigmenni a cikluson?

Mondjuk ha a listaban az utolso olyan elem kell, amire igaz a feltetel, akkor vegig kell menni.
Igy meg az elso megfelelo elemet talalod meg. Hiszen elofordulhatnak, hogy ket vagy tobb elemre is igaz a feltete.

Szerk. Bocs, nem mesz vegig, jogos. Beneztem, my bad.

Local az, de csak a kod relevans reszeit masoltam be. Igaz kellett egy global is amiben eltaroltam az iteraciok szamat. Rekurzivan akartam megoldani mivel plusz pontok jarnak erte igy szukseg volt ra. (A localra pedig azert volt szukseg, mert a global-t 0-ra kell allitani return elott, viszont main()-ben meg a return erteket akartam hasznalni, nem a globalis valtozoet, bar ugyanaz az ertek)

Szerk.: ...vagy megoldhato ez rekurzivan globalis valtozo nelkul is?

"Szerk.: Megoldhato ez rekurzivan globalis valtozo nelkul?"

Naná. :) Az egyik megoldás a static változó használata, persze ezzel nem vagy sokkal előrébb, csak nem globális a változó. A másik megoldás, hogy átadod paraméterben az aktuális elem indexét is. Gondolom a find paraméterezésén nem változtathatsz, vagyis ekkor a tényleges rekurzív keresést egy segédfüggvénnyel kell megoldanod, a find pedig csak továbbhív ebbe a segédfüggvénybe.

"átadod paraméterben az aktuális elem indexét is"

Ugy gondolod, ha a node struct-ba tennek egy index integer-t is? Az mukodhetne, csak van (khmm, lesz) egy remove() is (tulajdonkeppen FIFO amit csinalok) es akkor vegig kene menni az osszes node indexen es megvaltoztatni oket. Elveszne a tomb-ot hasznalo megoldassal szembeni elony. Szoval ha jol latom marad a static valtozo megoldasnak, de azzal C-ben meg nem dolgoztam. Majd ranezek.

Nem.

find(Node*, int what, int index)
Es a find elso meghivasa 0-s indexszel menne, rekurzivan pedig index+1-gyel. Es ha megtalalta a keresett elemet, akkor return index.

Az a gond, hogy a rekurzió normálisan a lusták könnyű eszköze, ezzel szemközt tőled meg kifejezetten azt kérik...

find (const Node*p, int what, int index)
{
    if (!p) return -1;
    else if (p->number==what) return index;
    else return find (p->next, what, index+1);
}

Gondolom arrol van szo, hogy bizonyitsam, ertem a koncepciot, mivel tobb agysejtet kivan a megertese mint ugyanennek a problemanak a nem rekurziv megoldasa. En amugy nem reszesitem elonyben, a nem rekurziv kod, ebben a pillanatban legalabbis, szimpatikusabb/olvashatobb szamomra.

Ezt az index dolgot megint tulbonyolitottam kicsit. Ugy gondoltam mivel a node "tulajdonsaga" az altala elfoglalt hely, logikus a struct-ba tenni, hogy egy helyen legyen az egesz. Ugy tunik ez mar a Java es az objektumorientaltsag kezdeti hatasa :)

Ez Halassy Béla azon példájára emlékeztet, amikor egy cégnél azon ismérv szerint csoportosították az adatokat, hogy azok milyen méretű floppyn érkeztek be (5.25 vagy 3.5)... Szóval nem, az adatnak nem tulajdonsága az, hogy a listában hányadik helyen van.

off, de erdekelne

egy hasonlo problemat Java-ban is igy lenne helyesebb megoldani, vagy Node.setPosition()/Node.getPosition() es private valtozo??
(ami kicsit hasonlit az emlitett node->position elvetett otletre)

Egy objektumhoz általában nem tartozik hozzá, hogy hol a helye az őt tartalmazó konténerben. Akármilyen nyelven írod.

Pedig pofás kis stressztesztelő program jöhetne ki belőle: minden egyes elembeszúráskor végigsétálni az újat követő elemeken, hogy pos attól fogva pos+1 legyen, illetve törléskor pos-1 a törölt után...
Ha az objektum már diszkre lóg, megvolna a helye a kávékortyolgatásnak is.

Mivel egy objektum is tobb kollekcio eleme lehet, nincs ertelme magaban az objektumban tarolni, hogy o melyik kolleckioban hanyadik.

Koszonom mindenkinek a valaszokat.

Szervusz, beírod a téma címe elé, hogy [Megoldva]? Hogy jelezd, hogy további flamere nincs igényed :-).

Beirtam mar, ugy tunik tul hosszu a cim es nem latszik. Roviditek rajta.

Köszönöm.

Protip: ha az elejere irod, mindig latszik :-) Most mar nem erdekes, csak a jovore nezve az.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal

:)