Rekursiv funktion i C#

Tags:    c#

<< < 12 > >>
Jeg er ved at portere noget C kode og er rendt ind i et problem med en rekursiv funktion.

For at illustrere har jeg strikket følgende sammen i C.
Fold kodeboks ind/udKode 

Her udnyttes at man via pointere rekursivt kan kalde samme funktion blot med en ny start adresse i array'et.

Men hvordan kringler jeg den i C#?
Fold kodeboks ind/udKode 


Sidste linie er et 'no go' i C# da pointere er unsafe.

Nogen, som har et fif.



Indlæg senest redigeret d. 12.05.2010 16:53 af Bruger #15897
12 svar postet i denne tråd vises herunder
2 indlæg har modtaget i alt 4 karma
Sorter efter stemmer Sorter efter dato
Du vil gerne have en høj binding i dine klasser. Det betyder at de metoder og properties du har på din klasse skal "hænge sammen" - dvs. din klasse har et klart ansvarsområde som den er ansvarlig for (og kun det). Har du fx. en bil klasse er den kun ansvarlig for alt inden for dens "naturlige" kontekst - og det afgører man ved at betragte de omgivelser den eksisterer i. Det ville ikke give mening for et bil objekt at det har en metode der hedder "beregnRente()" da det hører til i et andet ansvarsområde. Du har gjort det modsatte end at have "for mange" metoder - du har for få. I din ene klasse har du en repræsentation af de data der skal beregnes - de burde jo findes i samme klasse som den der skal beregne på dem. Håber det giver mening.

Jeg ville lave en "Statistik" klasse som skulle være ansvarlig for at indeholde alle data omkring statistik/aflæsninger og så tilbyde metoder der var inden for dette ansvarsområde. På den måde har du en enkelt repræsentation af dine data, de er indkapslet og det giver OOP mening.

du kunne overveje at uddelegere endnu mere - de klasser der indsamler data "xxxCollect" sender dem videre til din data klasse "xxxData", og så er det din data klasse der har ansvaret for at indsamle, holde, og præsentere dine data. Det eneste din collect klasse(r) skal er at indsamle data og være ansvarlig for at sende dem videre til den "rigtige" klasse - det er måske mere en slags utility klasse. Det der således afgører om du skal have en ny klasse er ikke algoritmen, men derimod om du har en funktionalitet der ikke kan placeres i en af de eksisterendes kontekst.

Hvis altid du har behov for kun at returnere data i eet format (fx komma separeret) kan du jo overveje om du ikke skal smide det ned i samme klasse og ikke i 3 forskellige. fx:

Fold kodeboks ind/udKode 


Ideen er at du således indkapsler din algoritme og kan således altid gå til netop denne klasse for at finde ud af hvad der går galt, eller lave ændringer. Worst case ved den anden del er at du skal rundt i alle krogene i din kode for at finde fejl.

Fold kodeboks ind/udKode 


Hvis du har behov for det er det også i denne klasse du kan lave en buffer, der kan holde data hvis de kommer hurtigere end din klasse/algoritme kan følge med.

Håber det giver mening...



Hej
Du kan godt lave det samme som der er i C i C# uden at anvende pointer.

Du laver blot en klasse og opretter et list<int> array (eller hvilke type data der arbejdes på) som property

Derefter opretter du en methode som skal kaldes rekursivt som behandler den globale variabel der er oprettet i klassen.

Herefter kalder du blot denne methode fra klassen konstruktør på samme måde som du kalder denne i C / C++.

Husk at alle array overføres som ref uden anvendelse af ref keyword i C#. Du kan godt release hukommelse i C# ved kald af GC men jeg råder dig ikke til det. Hvis C# CLR`en er god klare denne dette.

Jeg har skrevet meget C- kode og kan godt se dit problem, men det er blot en oversættelse til C# ikke andet.

Håber det gav dig en ide til hvordan du oversætter koden.

Send den rigtige kode eller hvad den skal gøre så kan det være jeg kan oversætte den her.

Med Venlig Hilsen
Janus S. Andersen



Du bliver nok nødt til at give startindex med som parameter. Noget i stil med:

Fold kodeboks ind/udKode 


...sådan ville jeg i hvert fald gør i Java



Indlæg senest redigeret d. 12.05.2010 17:16 af Bruger #2695
Du bliver nok nødt til at give startindex med som parameter. Noget i stil med:

Fold kodeboks ind/udKode 


...sådan ville jeg i hvert fald gør i Java


Fandt en måde
Fold kodeboks ind/udKode 


Men det er ikke så elegant. Hvis jeg kunne kopiere en del af array'et 'by reference', ville jeg slippe for at skulle kopiere tilbage.



Du kan godt gøre brug af reference henvisninger i C# med ref keywordet: http://msdn.microsoft.com/en-us/library/14akc2c7.aspx



"Bør" man ikke lave det således at man ikke arbejder i en "fælles" struktur, men har en mere funktionel tilgang til det? Således at din rekursive metode returnerer det array i stedet for at arbejde på et "fælles" array. Uden at være stærk udi C, virker det lidt "farligt" at bruge det på den måde - jeg foretrækker at lade den rekursive metode returnere data for at mindske bindingen mellem metoderne og de data de skal arbejde på..

Giver det mening?



Jeg synes måden det gøres på i C er ret elegant, især fordi det sparer hukommelse. For embeddede systemer hvor man har begrænset ram er det vel 'måden' at gøre det på.

Der må være en måde at kopiere et (sub)array uden at lave et value-to-value kopiering. Jeg lurer lidt på ArrayList's getRange().

Se her http://www.codeproject.com/KB/dotnet/arrays.aspx under afsnittet "Array Subranges"




Nailed it! Her er en måde at gøre det på ArrayList.GetRange var min redning.
Fold kodeboks ind/udKode 




Jeg synes måden det gøres på i C er ret elegant, især fordi det sparer hukommelse. For embeddede systemer hvor man har begrænset ram er det vel 'måden' at gøre det på.

Der må være en måde at kopiere et (sub)array uden at lave et value-to-value kopiering. Jeg lurer lidt på ArrayList's getRange().

Se her http://www.codeproject.com/KB/dotnet/arrays.aspx under afsnittet "Array Subranges"


Men nu laver du jo ikke embeddede systemer (jeg ved ikke omman kan lave embeddede systemer i C#)!
Problemet er at du er hoppet i med begge ben i en af de klassiske fejl omkring lav kobling/høj binding. Dit problem er (og derfor at din kode er "forkert") at du har skabt en dyb afhængighed mellem to klasser i dit system. Du har i din ene klasse "Program" et array som du sender til en anden klasse "recursive" for at få behandlet (din metode). Det kaldes en høj kobling mellem de to klasser, da din "program" klasse er hårdt bundet til din "recursive" klasse. Det er det første man lærer på de fleste softwareuddannelser at man skal undgå dette (en lille sviner :-) håber du kan tage det). Du har, i stedet for at lave lav kobling, kodet en høj kobling - det er jo ikke fordi det ikke vil fungere - men jeg ville i den situation nok vægte arkitekturen, kodeprincipper, vedligehold, læsbarhed osv. højere end at du sparer på ram/cpu osv.

Jeg tror ikke på at man kan tage og oversætte C til C# instruktion for instruktion og specielt ikke fra embedded til windows. Det er et andet paradigme og en anden teknologi man arbejder med!

Det kan jo compile og køre, og det er jo nogle gange "godt nok".



Indlæg senest redigeret d. 15.05.2010 20:37 af Bruger #2730

Men nu laver du jo ikke embeddede systemer (jeg ved ikke omman kan lave embeddede systemer i C#)!

Jo, det kan man da. http://www.tinyclr.com/ Og det er faktisk noget embedded kode jeg porterer.

Det er det første man lærer på de fleste softwareuddannelser at man skal undgå dette (en lille sviner :-) håber du kan tage det).

Hermed afsløret at jeg ikke er SW uddannet.


Jeg tror ikke på at man kan tage og oversætte C til C# instruktion for instruktion og specielt ikke fra embedded til windows. Det er et andet paradigme og en anden teknologi man arbejder med!.

Her bliver du så nødt til at følge lidt op på din "sviner". Hvordan vil du så gøre det på den rigtige måde? Jeg er godt klar over, at det er mit OOP paradigme, der ikke helt er på plads her. Jeg lytter gerne for at lære af dem som kan.

For at uddybe. Array'et repræsenterer noget måledata. Den recursive metode er en del af en algoritme, som behandler data. Mit hovedprogram vil gøre brug af flere klasser. Et som indsamler data (fx en data acquisition class), nogle data processeringsklasser (fx min recursive class) og sikkert også nogle som præsenterer det endelige resultat.



Indlæg senest redigeret d. 15.05.2010 22:40 af Bruger #15897
<< < 12 > >>
t