kath Δημοσ. 10 Ιουλίου 2006 Δημοσ. 10 Ιουλίου 2006 Εχω ενα μικρο προβληματακι, ελπιζω να μπορεσει να βοηθησει καποιος... Στην παρακατω array εχω προσθεσει δεδομενα: var A :array[0..10] of pchar; A[0] := '00001'; A[1] := '00010'; A[2] := '10100'; A[3] := '01000'; A[4] := '10000'; A[5] := '10000'; A[6] := '00001'; A[7] := '10001'; A[8] := '00001'; A[9] := '10001'; Οπως βλεπετε , μερικες θεσεις της array εχουν τις ιδιες τιμες. Πως μπορω να εντοπισω αυτες τις θεσεις προγραμματιστικα ; Σας ευχαριστω.
gtroza Δημοσ. 10 Ιουλίου 2006 Δημοσ. 10 Ιουλίου 2006 σύγκρινε την κάθε τιμή με τις άλλες και σε περίπτωση ισότητας κράτα τις θέσεις
alkisg Δημοσ. 10 Ιουλίου 2006 Δημοσ. 10 Ιουλίου 2006 Γενικά: ταξινομείς τον πίνακα και μετά με ένα μόνο πέρασμα κοιτάς τις συνεχόμενες θέσεις αν έχουν ίδιες τιμές. Στο συγκεκριμένο πρόβλημα: αν οι τιμές pchar είναι αυτής της μορφής (δηλαδή binary αριθμοί μέχρι το 11111), τότε μπορείς να τις μετατρέψεις σε αριθμούς και να τις βάλεις σε έναν πίνακα B[0..31]. Αρχικοποιείς τον B με μηδενικά, και όταν π.χ. βρεις το 00010, αυξάνεις το B[2] κατά 1. Έτσι στο τέλος ο πίνακας B θα είναι η συχνότητα εμφανίσεων. Αν θες και τις θέσεις, μπορείς να τις κρατάς σε κάποιον παράλληλο πίνακα C.
kath Δημοσ. 10 Ιουλίου 2006 Μέλος Δημοσ. 10 Ιουλίου 2006 Χωρις να θελω να σας κουρασω , αλλα ειναι ευκολο να μου δωσετε ενα μικρο παραδειγματακι ; Οχι κατι πολυπλοκο , κατι απλο , να μπω στο νοημα. Ευχαριστω ξανα.
kath Δημοσ. 11 Ιουλίου 2006 Μέλος Δημοσ. 11 Ιουλίου 2006 Δοκιμασα αυτο: > for p:=0 to 9 do begin if strTOinT(A[p]) = strTOinT(A[p]) then begin inc(A[p]); showmessage('bre8hke'+'A['+inttostr(p)+']'); end; end; Αλλα δεν δουλευει
alkisg Δημοσ. 11 Ιουλίου 2006 Δημοσ. 11 Ιουλίου 2006 Δεν μπορείς να το κάνεις με μία μόνο for. Είτε πρέπει πρώτα να ταξινομήσεις τον πίνακα, είτε να βάλεις δύο for, η μία μέσα στην άλλη (όπως είπε ο gtroza). Σπάστο σε κομμάτια και δούλευε καταρχάς με ακέραιους για να το κάνεις πιο εύκολο, και μετά το φτιάχνεις και με strings. Π.χ. έστω ότι έχεις ήδη ταξινομήσει τον πίνακα (το οποίο γίνεται με δύο for), και έστω ότι ο πίνακας είναι ως εξής: Α[0] = 1 Α[1] = 3 Α[2] = 3 Α[3] = 5 κτλ Για να βρεις τα ίδια, κάνεις > lastNumber := A[0]; for i := 1 to 9 do begin if A[i] = lastNumber then ShowMessage('Βρέθηκε ίδιο στοιχείο, το ' + IntToStr(A[i]) + ' στη θέση ' + IntToStr(i)); //εδώ αν θες μετράς και συχνότητα εμφάνισης κτλ else lastNumber := i; end;
gtroza Δημοσ. 11 Ιουλίου 2006 Δημοσ. 11 Ιουλίου 2006 kath δεν είμαι προγραμματιστής ! αν δεν κατάλαβες αυτά που γράφει ο alkisg, μάλλον θέλεις περισσότερη βοήθεια. το θέμα είναι τι θέλεις να κάνεις, δηλαδή να βρείς δυο ίδιες τιμές, να βρείς ομάδες ίδιων τιμών και μετά τί? μάλλον η ταξινόμηση που σου γράφει, είναι απαραίτητο βήμα γιατι μετά χειρίζεσαι τα στοιχεία εύκολα. χρειάζεσαι και ένα πίνακα που θα έχει τις αρχικές θέσεις των ταξινομημένων στοιχείων ________________________________________________________________ Γενικά: ταξινομείς τον πίνακα και μετά με ένα μόνο πέρασμα κοιτάς τις συνεχόμενες θέσεις αν έχουν ίδιες τιμές. .......................... Αν θες και τις θέσεις, μπορείς να τις κρατάς σε κάποιον παράλληλο πίνακα C ________________________________________________________________ για ρ=0 μέχρι πλήθος -1 αν το περιεχόμενο της θέσης ρ=με το περιεχόμενο της θέσης ρ+1 τότε πές "βρήκα ιδια στις θέσεις ρ , ρ+1" ;αύξησε το ρ αν οχι αύξησε το ρ ______ κάπου όμως πρέπει να κρατάς αυτά που βρίσκεις για να τα ξαναεπεξεργαστείς. μάλλον πρέπει να διαβάσουμε λίγο περισσότερο, γιατί θα μας κόψει ο alkisg!
kath Δημοσ. 11 Ιουλίου 2006 Μέλος Δημοσ. 11 Ιουλίου 2006 Σας ευχαριστω παιδια! ελυσα το προβλημα! Να και ο κωδικας: > var lastNumber,i,max:integer; var A :array[0..10] of integer; var B :array[0..10] of string; begin A[0] := 00001; A[1] := 00010; A[2] := 10100; A[3] := 01000; A[4] := 10000; A[5] := 10000; A[6] := 00001; A[7] := 10001; A[8] := 00001; A[9] := 10001; max:=9; i:=0; lastnumber :=A[0]; for i := 0 to max do begin if (A[i] = lastNumber)then ShowMessage('Βρέθηκε ίδιο στοιχείο, το ' + inttostr(A[i]) + ' στη θέση ' + IntToStr(i)) else if not((A[i] = lastnumber)and(lastnumber<max+1)) then lastnumber:=A[i+1]; if ((A[i] = lastnumber)) then A[i]:=1; end; B[0]:='Αποτελέσματα ελέγχου:'+#13+''; i:=0; for i:=0 to max do begin if (A[i] =1) then B[0]:=B[0]+inttostr(i+1)+')Διεγράφει'+#13 else B[0]:=B[0]+inttostr(i+1)+')'+inttostr(A[i])+#13; end; Yπαρχουν περιθωρια βελτιωσης ;
kath Δημοσ. 11 Ιουλίου 2006 Μέλος Δημοσ. 11 Ιουλίου 2006 Δεν εμφανιζεται σωστα..το ξανα δημοσιευω , εδω: > var lastNumber,i,max:integer; var A :array[0..10] of integer; var B :array[0..10] of string; begin A[0] := 00001; A[1] := 00010; A[2] := 10100; A[3] := 01000; A[4] := 10000; A[5] := 10000; A[6] := 00001; A[7] := 10001; A[8] := 00001; A[9] := 10001; max:=9; i:=0; lastnumber :=A[0]; for i := 0 to max do begin if (A[i] = lastNumber)then ShowMessage('brethhke idio stoixeio, to ' + inttostr(A[i]) + ' sth thesh ' + IntToStr(i)) else if not((A[i] = lastnumber)and(lastnumber<max+1)) then lastnumber:=A[i+1] else if ((A[i] = lastnumber)) then A[i]:=1; end; B[0]:='Apotelesmata:'+#13+''; i:=0; for i:=0 to max do begin if (A[i] =1) then B[0]:=B[0]+inttostr(i+1)+')Diegrafhke'+#13 else B[0]:=B[0]+inttostr(i+1)+')'+inttostr(A[i])+#13; end; Showmessage(b[0]); //ektypwsh pinaka end; Τωρα ομως υπαρχει αλλο προβλημα. Σε καποιες θεσεις του πινακα , μερικα ψηφια αφαιρουνται. Γιατι;
gtroza Δημοσ. 11 Ιουλίου 2006 Δημοσ. 11 Ιουλίου 2006 Σε καποιες θεσεις του πινακα , μερικα ψηφια αφαιρουνται. σε ποιό πίνακα? τι ψηφία? γράψε ένα αποτέλεσμα >> Showmessage(b[0]) νομίζω μπερδεύεις τον μετρητή με το περιεχόμενο της θέσης του πίνακα πχ )and(lastnumber<max+1) _____________ if (A = lastNumber)then <<<<@@@ ShowMessage('brethhke idio stoixeio, to ' + inttostr(A) + ' sth thesh ' + IntToStr(i)) else if not((A = lastnumber)and(lastnumber<max+1)) then lastnumber:=A[i+1] else if ((A = lastnumber)) then A:=1;<<<<γιατί δεν είναι στη θέση @@@ ? έχεις διπλές (( μάλλον μονές ( ____________ μη βιάζεσαι !
kath Δημοσ. 11 Ιουλίου 2006 Μέλος Δημοσ. 11 Ιουλίου 2006 Να το αποτελεσμα: @gtroza : Α. Τα "(( ))" , δεν νομιζω να δημιουργουν προβλημα........ Β. Σε αυτο το κομματι : > if not((A[i] = lastnumber)and(lastnumber<max+1)) then lastnumber:=A[i+1] Αλλαζει το περιεχομενο του "lastnumber" , και παιρνει την τιμη της αμεσως επομενης θεσης του πινακα Α. Γ. Θα δοκιμασω να μετατρεψω τον πινακα σε string , να δουμε αν υπαρχει προβλημα με τους ακεραιους.
kath Δημοσ. 11 Ιουλίου 2006 Μέλος Δημοσ. 11 Ιουλίου 2006 Δοκιμασα να μετατρεψω ολους τους ακεραιους σε strings , ομως δεν μου εντοπιζει 2 ιδιες τιμες. Και ο νεος κωδικας: > var lastNumber:string; var i,max:integer; var A :array[0..10] of STRING; var B :array[0..10] of string; begin A[0] := '00101'; A[1] := '10101'; A[2] := '10100'; A[3] := '01000'; A[4] := '10000'; A[5] := '10000'; A[6] := '00001'; A[7] := '10001'; A[8] := '00001'; A[9] := '10001'; i:=0; max:=9; B[1]:='Arxikes times'#13+''; for i:=0 to max do begin B[1] := B[1]+A[i]+''#13+''; end; showmessage(B[1]); i:=0; lastnumber :=(A[0]); for i := 0 to max do begin if ( (A[i] = lastNumber) and not (A[i]='1'))then begin A[i]:='1'; ShowMessage('brethhke idio stoixeio, to ' + (A[i]) + ' sth thesh ' + IntToStr(i)); end else begin lastnumber:=(A[i+1]); end; end; B[0]:='Apotelesmata:'+#13+''; i:=0; for i:=0 to max do begin if (A[i] ='1') then B[0]:=B[0]+inttostr(i+1)+')Diegrafhke'+#13 else B[0]:=B[0]+inttostr(i+1)+')'+(A[i])+#13; end; Showmessage(b[0]); //ektypwsh pinaka Πρεπει να φταιει το σημειο που αλλαζω την τιμη του Α[Ι] , ωστε να γινει η διαγραφη...αλλα οχι σιγουρα..
alkisg Δημοσ. 11 Ιουλίου 2006 Δημοσ. 11 Ιουλίου 2006 Η μέθοδος που σου έγραψα δουλεύει μόνο σε ταξινομημένο πίνακα. Ο πίνακάς σου δεν είναι ταξινομημένος. Χρειάζεσαι παραπάνω κώδικα για να τον ταξινομήσεις. Ψάξε στο google για τον αλγόριθμο bubblesort, θα τον βρεις και για delphi. Αφού ταξινομήσεις τον πίνακα, μετά συνέχισε με τον κώδικα που έγραψες. Γράψε μας και περισσότερες λεπτομέρειες για το αν σε ενδιαφέρει η θέση που βρέθηκαν τα διπλότυπα, αν σε ενδιαφέρει η αρχική θέση των στοιχείων στον πίνακα κτλ. μάλλον πρέπει να διαβάσουμε λίγο περισσότερο, γιατί θα μας κόψει ο alkisg! :)
gerontas Δημοσ. 11 Ιουλίου 2006 Δημοσ. 11 Ιουλίου 2006 Οπως σου ειπε και ο Αλκης, δεν αρκεί ένα for γι γι αυτή τη δουλειά. Αν θέλεις απλά να προσδιορίσεις τις θέσεις των πολλαπλών εμφανίσεων, ο κώδικας θα μπορούσε να γραφεί κάπως έτσι: > var A :array[0..10] of pchar; max,i,j:byte; Begin A[0] := '00001'; A[1] := '00010'; A[2] := '10100'; A[3] := '01000'; A[4] := '10000'; A[5] := '10000'; A[6] := '00001'; A[7] := '10001'; A[8] := '00001'; A[9] := '10001'; max:=9; for i:=0 to max-1 do for j:=i+1 to max do if a[i]=a[j] then writeln('Πολλαπλή Εμφάνιση, Θέσεις:',i:5,j:5); End. Οπως μπορείς να δεις, ενα πρώτο μειονέκτημα είναι ότι αφού εντοπίσει πολλαπλή εμφάνιση του στοιχείου a[0] στις θέσεις a[6] και a[8], στη συνέχεια εντοπίζει ξανά πολλαπλή εμφάνιση, ανάμεσα στις θέσεις a[6] και α[8]. Αυτό μπορεί ν' αντιμετωπισθεί με την χρήση ενός πίνακα από flags, στον οποίο "σημειώνουμε" ποιά στοιχεία έχουμε ελέγξει, ώστε να μην τα εξετάσουμε δεύτερη φορά. Κάπως έτσι: > var A :array[0..10] of pchar; f :array[0..10] of boolean; max,i,j:byte; Begin A[0] := '00001'; A[1] := '00010'; A[2] := '10100'; A[3] := '01000'; A[4] := '10000'; A[5] := '10000'; A[6] := '00001'; A[7] := '10001'; A[8] := '00001'; A[9] := '10001'; max:=9; for i:=0 to max do f[i]:=false; for i:=0 to max-1 do begin f[i]:=true; for j:=i+1 to max do if not f[j] then if a[i]=a[j] then begin writeln('Πολλαπλή Εμφάνιση, Θέσεις:',i:5,j:5); f[j]:=true; end; end; End. Αν τώρα, δεν ενδιαφέρει να προσδιορίσουμε τις θέσεις, αλλά να διαγράφουμε τα στοιχεία που έχουν ήδη εμφανισθεί, τότε τροποποιούμε λίγο τον πρώτο κώδικα, ώστε για κάθε τέτοιο στοιχείο να φέρνουμε όλα τα επόμενά του μια θέση προς τα πίσω και παράλληλα να μειώνουμε κατά ένα τον δείκτη του τελευταίου στοιχείου. Ενας καλός τρόπος είναι αυτός που λέει ο Αλκης, να ταξινομήσουμε τον πίνακα και να ελέγχουμε την ισότητα ανάμεσα σε διαδοχικά στοιχεία. Αν θέλουμε ν' αποφύγουμε την ταξινόμηση, θα μπορούσε να γίνει π.χ. με τον κώδικα που ακολουθεί: > var A :array[0..10] of pchar; max,i,j,k:byte; Begin A[0] := '00001'; A[1] := '00010'; A[2] := '10100'; A[3] := '01000'; A[4] := '10000'; A[5] := '10000'; A[6] := '00001'; A[7] := '10001'; A[8] := '00001'; A[9] := '10001'; max:=9; writeln ('ΑΡΧΙΚΟΣ ΠΙΝΑΚΑΣ'); for i:=0 to max do write(a[i]:8); writeln; for i:=0 to max-1 do for j:=i+1 to max do if a[i]=a[j] then begin for k:=j to max-1 do a[k]:=a[k+1]; max:=max-1; end; writeln ('ΤΕΛΙΚΟΣ ΠΙΝΑΚΑΣ'); for i:=0 to max do write(a[i]:8); writeln; End. Δεν ξέρω, μήπως σ' αυτή την τελευταία περίπτωση σας ζητάνε να απελευθερώσετε τη μνήμη που καταλάμβαναν αρχικά οι επαναλαμβανόμενες τιμές, η χρήση των μεταβλητών τύπου pchar με κάνει να υποψιάζομαι ότι ίσως δεν πρέπει να περιορισθείς σε στατικούς πίνακες, αλλά να χρησιμοποιήσεις δυναμικούς. Hope it helps.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.