Τα πάντα για την C

...του ubuntu και έργων ΕΛ/ΛΑΚ (Έργα-Οδηγοί-Προτάσεις)

Συντονιστής: konnn

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 22 Αύγ 2011, 19:34

migf1 έγραψε:
migf1 έγραψε:...μια συνάρτηση που θα παίρνει σαν όρισμα ένα strings s και θα συγκεντρώνει στην αρχή του s όλα τα σύμφωνα, στο τέλος του όλα τα φωνήεντα, και στη μέση όποιους χαρακτήρες δεν είναι γράμματα. Για ευκολία θεώρησε πως δεν υπάρχουν Ελληνικά γράμματα στο s.

Αυτή την κατάφερε κανείς; (δεν είναι εύκολη)

Εγώ δεν την έχω κοιτάξει ακόμη, αυτή τη στιγμή κοιτώ τον αλγόριθμο....
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 22 Αύγ 2011, 19:53

Πώς όμως δουλεύει αφού εδώ:
Κώδικας: Επιλογή όλων
s[j] = s[1];
s[1] = m;

Δουλεύεις μόνο με το 2 στοιχείο :?:
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 22 Αύγ 2011, 19:58

Πώς όμως δουλεύει αφού εδώ:
Κώδικας: Επιλογή όλων
s[j] = s[1];
s[1] = m;

Δουλεύεις μόνο με το 2 στοιχείο :?: Επίσης με αυτό εδώ
Κώδικας: Επιλογή όλων
j = rand() % l + 1;
δεν αντιγράφεις και το τελευταίο στοιχείο;
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 22 Αύγ 2011, 21:01

Μέσα σε μια επανάληψη του loop παράγω με την rand() μια τυχαία θέση από τη 2η έως και την προτελευταία και εναλλάσσω τα περιεχόμενά της με τα περιεχόμενα της 2ης θέσης.

Όσο για τη 2η ερώτηση, η πράξη: % n σου δίνει αποτέλεσμα από 0 έως n-1, άρα η πράξη: % n + 1 σου δίνει αποτέλεσμα από 1 έως n.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 24 Αύγ 2011, 11:33

Ααααα,οκ το κατάλαβα! ;)
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 25 Αύγ 2011, 13:36

Εντάξει, την έκανα αυτήν με τα σύμφωνα και τα φωνήεντα αλλά έχει μερικά bugs :D
1. Δεν αναγνωρίζει το ο :P
2. Και μερικές φορές βγάζει διάφορα από αυτά τα παράξενα τετραγωνάκια με τους αριθμούς μέσα και τα αγγλικά ερωτηματικά μέσα στους άσπρους κύκλους :problem:
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int is_vowel(char c) {
int i;
char s[] = {'a','A','E','e','I','i','o','O','U','u','Y','y'};
for(i = 0;i<5;i++) {
if(c == s[i]) {
return 0;
}
}
return 1;
}

int is_consonant(char c) {
int i;
char s[] = {'b','B','c','C','d','D','f','F','g','G','h','H','j','J','k','K','l','L','m','M','n','N','p','P','q','Q','r','R','s','S','t','T','v','V','w','W','x','X','z','Z',};
for(i = 0;i<40;i++) {
if(c == s[i]) {
return 0;
}
}
return 1;
}

int main(void) {
int i,i2 = 0,i3 = 0;
char inbuf[256];
char vowel[255];
char consonant[255];
fgets(inbuf,256,stdin);
for(i=0;i<strlen(inbuf);i++) {
if(is_consonant(inbuf[i]) == 0) {
consonant[i2++] = inbuf[i];
}else if(is_vowel(inbuf[i]) == 0) {
vowel[i3++] = inbuf[i];
}
}
printf("Vowels\n");
for(i=0;i<strlen(vowel);i++) printf("%c",vowel[i]);
printf("\nConsonants\n");
for(i=0;i<strlen(consonant);i++) printf("%c",consonant[i]);
putchar('\n');
return 0;
}

Επίσης δεν ήξερα πού έπρεπε να βάλω το Y :problem: Τελικά το έβαλα στα φωνήεντα :P
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 25 Αύγ 2011, 14:34

Καλησπέρα,

stamatiou έγραψε:Εντάξει, την έκανα αυτήν με τα σύμφωνα και τα φωνήεντα αλλά έχει μερικά bugs :D
1. Δεν αναγνωρίζει το ο :P

Σου έχει ξεφύγει και μέσα στο for της is_vowel() το i το σταματάς στο 5, ενώ το s που περιέχει τα φωνήεντα έχει 12 χαρακτήρες ;)

έγραψε:2. Και μερικές φορές βγάζει διάφορα από αυτά τα παράξενα τετραγωνάκια με τους αριθμούς μέσα και τα αγγλικά ερωτηματικά μέσα στους άσπρους κύκλους :problem:

Για αυτό πρέπει να φταίει πως όταν αρχικοποιείς τα s μέσα στις is_vowel() και is_consonant() έχεις ξεχάσει να προσθέσεις τον μηδενικό χαρακτήρα στο τέλος.

Πάντως είναι περιττό να αρχικοποιείς strings όπως αρχικοποιείς τα arrays, γιατί τα arrays of char τα διαχειρίζεται ως ειδική περίπτωση η C, οπότε αντί να γράφεις:
Κώδικας: Επιλογή όλων

char s[] = {'a','A','E','e','I','i','o','O','U','u','Y','y','\0'};

μπορείς να γράφεις:
Κώδικας: Επιλογή όλων

char s[] = "aAEeIioOUuYy";
που είναι το ίδιο πράγμα και πιο όμορφο στο μάτι (σε αυτή την περίπτωση τον μηδενικό χαρακτήρα τον βάζει αυτόματα στο τέλος ο compiler).

έγραψε:Επίσης δεν ήξερα πού έπρεπε να βάλω το Y :problem: Τελικά το έβαλα στα φωνήεντα :P

Μια χαρά, έτσι το έχω βάλει κι εγώ στη δική μου λύση.

Υπάρχει όμως ένα πρόβλημα, έλυσες άλλη άσκηση :lol: Αυτή που έβαλα εγώ λέει να συγκεντρώσεις όλα τα φωνήεντα στην αρχή του s, τα σύμφωνα στο τέλος του s, και οποιονδήποτε άλλον χαρακτήρα στη μέση του s. Εσύ πιάνεις το s και απλά τυπώνεις τα φωνήεντα που βρίσκεις, και μετά το ξαναπιάνεις και τυπώνεις τα σύμφωνα.

Πριν από λίγο κατέθεσα το συγκεκριμένο πρόβλημα και στο greekcodes.gr με αναλυτική εκφώνηση: http://greekcodes.gr/index.php?option=c ... Itemid=534 (και δείγματα εξόδου).
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 25 Αύγ 2011, 15:51

Λοιπόν αυτό δεν το έχω ξαναδεί! :problem: :problem:
Spoiler: show
Κώδικας: Επιλογή όλων
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int is_vowel(char c) {
int i;
char s[] = {'a','A','E','e','I','i','o','O','U','u','Y','y'};
for(i = 0;i<12;i++) {
if(c == s[i]) {
return 0;
}
}
return 1;
}

int is_consonant(char c) {
int i;
char s[] = {'b','B','c','C','d','D','f','F','g','G','h','H','j','J','k','K','l','L','m','M','n','N','p','P','q','Q','r','R','s','S','t','T','v','V','w','W','x','X','z','Z','\0'};
for(i = 0;i<40;i++) {
if(c == s[i]) {
return 0;
}
}
return 1;
}

int main(void) {
int i,i2 = 0,i3 = 0,i4 = 0;
char inbuf[256];
char vowel[255];
char consonant[255];
char other[255];
fgets(inbuf,256,stdin);
for(i=0;i<strlen(inbuf);i++) {
if(is_consonant(inbuf[i]) == 0) {
consonant[i2++] = inbuf[i];
}else if(is_vowel(inbuf[i]) == 0) {
vowel[i3++] = inbuf[i];
}else {
if(inbuf[i] > 31 && inbuf[i] <= 64) {
other[i4++] = inbuf[i];
}
}
}
for(i=0;i<strlen(inbuf);i++) inbuf[i] = 0;
strcat(inbuf,vowel);
strcat(inbuf,other);
strcat(inbuf,consonant);
for(i=0;i<strlen(inbuf);i++) printf("%c",inbuf[i]);
putchar('\n');
return 0;
}
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό migf1 » 25 Αύγ 2011, 16:32

Ποιο εννοείς δεν έχεις ξαναδεί;

ΥΓ1. Πάλι το άφησες χωρίς '\0' στο τέλος το s στην is_vowel. Όσο για τη νέα λύση, δεν την δοκίμασα αλλά φαίνεται σωστή! :) Το δύσκολο τώρα είναι να κάνεις τη δουλειά in-place, δηλαδή με ένα μόνο loop που θα διατρέχει το s και θα κάνει τις αναγκαίες ανακατατάξεις χαρακτήρων σε πραγματικό χρόνο.

ΥΓ2. Και μια επισήμανση για τη χρήση του strlen(inbuf) που έχεις μέσα στις συνθήκες του for... έτσι όπως είναι τώρα σε ΚΑΘΕ επανάληψη του κάθε loop επανα-υπολογίζει το μήκος του inbuf (φαντάσου π.χ. να περιείχε το inbuf τα περιεχόμενα ενός αρχείου μεγέθους 100Mb... σε κάθε επανάληψη του κάθε for μετράς 2 φορές 100+ εκατομμύρια bytes... κι έχεις 3 for στο πρόγραμμά σου που έχουν το strlen(inbuf) μέσα στη συνθήκη τους. Η λύση είναι να υπολογίσεις μια και μόνο φορά το μήκος του inbuf σε μια μεταβλητή (π.χ. leninbuf = strlen(inbuf) ) και κατόπιν να χρησιμοποιείς αυτή τη μεταβλητή μέσα στις συνθήκες των for.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

Re: Τα πάντα για την C/C++

Δημοσίευσηαπό stamatiou » 25 Αύγ 2011, 16:47

migf1 έγραψε:Ποιο εννοείς δεν έχεις ξαναδεί;

ΥΓ1. Πάλι το άφησες χωρίς '\0' στο τέλος το s στην is_vowel. Όσο για τη νέα λύση, δεν την δοκίμασα αλλά φαίνεται σωστή! :) Το δύσκολο τώρα είναι να κάνεις τη δουλειά in-place, δηλαδή με ένα μόνο loop που θα διατρέχει το s και θα κάνει τις αναγκαίες ανακατατάξεις χαρακτήρων σε πραγματικό χρόνο.

ΥΓ2. Και μια επισήμανση για τη χρήση του strlen(inbuf) που έχεις μέσα στις συνθήκες του for... έτσι όπως είναι τώρα σε ΚΑΘΕ επανάληψη του κάθε loop επανα-υπολογίζει το μήκος του inbuf (φαντάσου π.χ. να περιείχε το inbuf τα περιεχόμενα ενός αρχείου μεγέθους 100Mb... σε κάθε επανάληψη του κάθε for μετράς 2 φορές 100+ εκατομμύρια bytes... κι έχεις 3 for στο πρόγραμμά σου που έχουν το strlen(inbuf) μέσα στη συνθήκη τους. Η λύση είναι να υπολογίσεις μια και μόνο φορά το μήκος του inbuf σε μια μεταβλητή (π.χ. leninbuf = strlen(inbuf) ) και κατόπιν να χρησιμοποιείς αυτή τη μεταβλητή μέσα στις συνθήκες των for.

Χμ, θα προσπαθήσω και με ένα loop...
Αλλά έκανα τις διορθώσεις και συνεχίζουν τα σύμβολα όμως πάντα και σε κάποια κομμάτια περνούν και τα γράμματα από μέσα (απ' τα τετράγωνα)! :problem:
stamatiou
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 947
Εγγραφή: 25 Ιουν 2010, 20:23
Εκτύπωση

ΠροηγούμενηΕπόμενο

Επιστροφή στο Ανάπτυξη Λογισμικού / Αλγόριθμοι