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

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

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

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

Δημοσίευσηαπό Qdata » 07 Αύγ 2011, 13:24

Επιτέλους το βρήκα! :mrgreen:
Με πέδεψε πάρα πολύ αλλά με βοήθησε αφού μέχρι να την λύσω χρησιμοποίησα δείκτες,συναρτήσεις κτλ.Τελικά το μόνο που χρειαζόταν ήταν σκέψη στον τρόπο και όχι στον κώδικα!Να και η λύση:
Κώδικας: Επιλογή όλων
/* ------------------------------------------------------
* Από: Qdata
*
* Άσκηση: Γράψτε μια συνάρτηση που θα παίρνει ως ορίσματα δυο strings και
* θα ελέγχει για το αν το ένα είναι αναγραμματισμός του άλλου.
* Θα επιστρέφει TRUE αν είναι, FALSE αν δεν είναι (ή 1 και 0, αντίστοιχα).
*
* Παραδείγματα:
*
* "abcd", "dbca" δίνει TRUE
* "helle", "hollo" δίνει FALSE
* "z", "zzz" δίνει FALSE
* "zzz", "z" δίνει FALSE
* "z", "z" δίνει TRUE
* -----------------------------------------------------
*/

#include <stdio.h>
#include <string.h> /* για strlen() */

/*-------------------- Main Fuction --------------------*/

main()
{
int len,result;
char first_word[100],second_word[100];
printf("Δώστε την πρώτη λέξη: ");
gets(first_word);
printf("Δώστε την δεύτερη λέξη: ");
gets(second_word);
len = strlen(first_word);
result = strcheck(len,first_word,second_word);
if(result == 1)
printf("Οι πρώτη λέξη είναι αναγραμματισμός της άλλης.\n");
else
printf("Καμία από τις λέξεις δεν είναι αναγραμματισμός της άλλης.\n");
}

/*-------------------- String Check --------------------*/

int strcheck(int len_from_main,char str_one[100], char str_two[100])
{
int i,j; /*για for loop*/
int len,count;
len = len_from_main;
count = 0;
for(i=0,j=(len-1);i != (len+1), j != 0;++i,j=j-1)
{
if(str_one[i] == str_two[j])
++count;
}
++count;
if(count == len)
return 1;
else
return 0;
}

/*------------------- End of program -------------------*/



(Συγνώμη που δεν χρησιμοποίησα πολλά σχόλια.Θα προσπαθήσω να κάνω πιο ευανάγνωστο τον κώδικα.)
Επίσης ξέρω πως η γραμμή:
Κώδικας: Επιλογή όλων
if(str_one[i] == str_two[j])

Δεν είναι ότι το καλύτερο για να συγκρίνω την θέση του πίνακα αλλά όταν χρησιμοποιούσα κάτι άλλο που έβγαζε σφάλματα. :problem:

@migf1 Πολύ ωραία η άσκηση! :thumbup: :)
Linux User: #530165
Γνώσεις ⇛ Linux: Μέτριο ┃ Προγραμματισμός: Ναι ┃ Αγγλικά: Καλά
Λειτουργικό ⇛ Ubuntu 11.04 32bit σε Intel(R) Atom(TM) CPU N270 @ 1.60GHz
(Notebook) Προδιαγραφές ⇛ 2x Intel(R) Atom(TM) CPU N270 @ 1.60GHz │ 1016MB │ HDA-Intel - HDA Intel -- USB-Audio - USB AUDIO│ 1024x600 pixels
Νέος στο Linux?Οδηγοί - How to - Tutorials
Qdata
powerTUX
powerTUX
 
Δημοσιεύσεις: 1875
Εγγραφή: 18 Ιουν 2010, 19:40
Τοποθεσία: Σέρρες
IRC: dimos
Εκτύπωση

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

Δημοσίευσηαπό Star_Light » 07 Αύγ 2011, 18:20

migf1 έγραψε:Μήπως εννοεί να πιάσεις το string από την αρχή και να τυπώνεις έναν-έναν όλους του τους χαρακτήρες μέσα σε loop;


Ε ΝΑΙ! :D

μου κανει εντυπωση που το βρηκες.... εσυ!!! :lol:

Κώδικας: Επιλογή όλων


#include<stdio.h>
#include<time.h>

void GetDateTime(void);

int main()
{
GetDateTime();


return 0;
}
//-------------------------------------------------------------------------------
void GetDateTime(void)
{
time_t now;
int i;
char *str;

time(&now);

str=asctime(localtime(&now));

for(i=0; str[i]; i++)
printf("H trexousa imerominia kai wra einai: %c \n", str[i]);

return ;
}
//-----------------------------------------------------------------------------


Το κλειδι εδω ειναι οτι μια συμβολοσειρά ειναι ένας πίνακας χαρακτήρων αποτελεί δηλαδη εναν πίνακα χαρακτήρων. Και επειδή η asctime() επιστρέφει ακριβως αυτο , αυτο ειναι και αυτο που θα εκμεταλευτούμε ωστε το printf να δεχθει σαν παράμετρο τον μορφοποιητή %c και τελικα να εκτυπωσει την ώρα και την ημερομηνία σαν έναν χαρακτήρα μεμονομένα καθε φορα που ταυτοχρονα αποτελει και την λυση της ασκησης. :)
Γνώσεις ⇛ Linux: Βασικές ┃ Προγραμματισμός: Δέν θέλω μεροκάματο , θέλω C και κακο θάνατο! ┃ Αγγλικά: Lower
Λειτουργικό ⇛ Ubuntu 10.10 σε Dual Boot με Windows 7
Προδιαγραφές ⇛ Επεξεργαστής : Intel(R) Core(TM) i3 CPU 540 @3.07Ghz (64bit)
RAM : Kingston 2GB
HDD : Coreshare 500GB
Κάρτα Γραφικών : Intel Corporation Core Processor Integrated Graphics Controller(rev 18) (prog-if 00 [VGA controller]) [8086:0042]
Star_Light
superbTUX
superbTUX
 
Δημοσιεύσεις: 2787
Εγγραφή: 01 Μάιος 2010, 21:07
Τοποθεσία: Αθήνα
IRC: Star_Light
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 07 Αύγ 2011, 23:18

Καλησπέρα στην παρέα :)

Καταρχήν είμαι πολύ χαρούμενος για τον φίλο Qdata που έλυσε την άσκηση! :clap: :bow: :thumbup: (μπαίνω να κάνω ένα μπανάκι και μετά θα κοιτάξω και τον κώδικα, και θα σας γράψω μετά κώδικα και για τους 3 τρόπους επίλυσης που περιέγραφα στο προηγούμενο ποστ) :)

@star_light: lucky guess έκανα :lol:
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό stamatiou » 08 Αύγ 2011, 01:07

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

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

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

Χαλαρά, περιμένω αν είναι :)

Στο μεταξύ πρόσθεσα μια ΠΟΛΥ χρήσιμη λειτουργία στη συνάρτηση: s_get() που σας έχω δώσει να χρησιμοποιείται αντί της καταργημένης gets(). Λοιπόν της πρόσθεσα τη δυνατότητα να κάνει ταυτόχρονα και fflush(stdin) ανεξαρτήτως πλατφόρμας :ugeek:

Την ονόμασα: s_getflushed
Κώδικας: Επιλογή όλων

// -----------------------------------------------------------------------------------
// ΣΥΝΑΡΤΗΣΗ: s_getflushed
// βελτιωμένη παραλλαγή της fgets για την κύρια είσοδο (σβήνει το '\n' + fflush)
//
// Διαβάζει από την κύρια είσοδο έως len-1 χαρακτήρες ή μέχρι να πατηθεί ENTER,
// τους καταχωρεί στο s και το επιστρέφει με μηδενισμένο τον τελικό χαρακτήρα.
// Αν πληκτρολογήθηκαν len-1 χαρακτήρες πριν πατηθεί το ENTER, τότε οι περιττοί
// χαρακτήρες αφαιρούνται από το buffer της εισόδου (stdin).
//
char *s_getflushed(char *s, size_t len)
{
char *cp;
for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ )
;

if ( *cp != '\n') { // len reached withoutn '\n'
*cp = '\0'; // null terminate s and
while (getchar() != '\n') // flush remaining chars
;
}
else // '\n' found
*cp = '\0'; // null-terminate

return s;
}

Οπότε μπορείτε να τη χρησιμοποιείται πάντα και σε οποιαδήποτε πλατφόρμα όποτε θέλετε να διαβάζετε την κύρια είσοδο μονοκόμματα ως ένα string, χωρίς να έχετε ποτέ πρόβλημα με τυχόν απομεινάρια (αυτή η συνάρτηση τα καθαρίζει :) )

Δηλαδή, για παράδειγμα στον παρακάτω κώδικα:
Κώδικας: Επιλογή όλων

#define MAXINBUF 6+1
int main( void )
{
char inbuf[ MAXINBUF ];
int n;

s_getflushed( inbuf, MAXINBUF ];
n = atoi( inbuf );

return 0;
}

ακόμα κι αν ο χρήστης μας πληκτρολογήσει 100 χαρακτήρες στην κύρια είσοδο, η s_getflushed() θα βάλει μέσα στο inbuf μονάχα τους 6 πρώτους (+ 1 για τον μηδενικό χαρακτήρα στο τέλος) και θα καθαρίσει όλους τους υπόλοιπους από την κύρια είσοδο, ώστε την επόμενη φορά που θα πάμε να διαβάσουμε κάτι από την κύρια είσοδο δεν θα υπάρχουν απομεινάρια από πριν.

Άρα ο παραπάνω κώδικας μετατρέπει σε ακέραιο νούμερο και το καταχωρεί στη μεταβλητή n μέχρι το πολύ 6 χαρακτήρες από αυτούς που θα πληκτρολογήσει ο χρήστης :)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 08 Αύγ 2011, 03:02

Qdata έγραψε:Επιτέλους το βρήκα! :mrgreen:
Με πέδεψε πάρα πολύ αλλά με βοήθησε αφού μέχρι να την λύσω χρησιμοποίησα δείκτες,συναρτήσεις κτλ.Τελικά το μόνο που χρειαζόταν ήταν σκέψη στον τρόπο και όχι στον κώδικα!Να και η λύση:
Spoiler: show
Κώδικας: Επιλογή όλων
/* ------------------------------------------------------
* Από: Qdata
*
* Άσκηση: Γράψτε μια συνάρτηση που θα παίρνει ως ορίσματα δυο strings και
* θα ελέγχει για το αν το ένα είναι αναγραμματισμός του άλλου.
* Θα επιστρέφει TRUE αν είναι, FALSE αν δεν είναι (ή 1 και 0, αντίστοιχα).
*
* Παραδείγματα:
*
* "abcd", "dbca" δίνει TRUE
* "helle", "hollo" δίνει FALSE
* "z", "zzz" δίνει FALSE
* "zzz", "z" δίνει FALSE
* "z", "z" δίνει TRUE
* -----------------------------------------------------
*/

#include <stdio.h>
#include <string.h> /* για strlen() */

/*-------------------- Main Fuction --------------------*/

main()
{
int len,result;
char first_word[100],second_word[100];
printf("Δώστε την πρώτη λέξη: ");
gets(first_word);
printf("Δώστε την δεύτερη λέξη: ");
gets(second_word);
len = strlen(first_word);
result = strcheck(len,first_word,second_word);
if(result == 1)
printf("Οι πρώτη λέξη είναι αναγραμματισμός της άλλης.\n");
else
printf("Καμία από τις λέξεις δεν είναι αναγραμματισμός της άλλης.\n");
}

/*-------------------- String Check --------------------*/

int strcheck(int len_from_main,char str_one[100], char str_two[100])
{
int i,j; /*για for loop*/
int len,count;
len = len_from_main;
count = 0;
for(i=0,j=(len-1);i != (len+1), j != 0;++i,j=j-1)
{
if(str_one[i] == str_two[j])
++count;
}
++count;
if(count == len)
return 1;
else
return 0;
}

/*------------------- End of program -------------------*/



(Συγνώμη που δεν χρησιμοποίησα πολλά σχόλια.Θα προσπαθήσω να κάνω πιο ευανάγνωστο τον κώδικα.)
Επίσης ξέρω πως η γραμμή:
Κώδικας: Επιλογή όλων
if(str_one[i] == str_two[j])

Δεν είναι ότι το καλύτερο για να συγκρίνω την θέση του πίνακα αλλά όταν χρησιμοποιούσα κάτι άλλο που έβγαζε σφάλματα. :problem:

@migf1 Πολύ ωραία η άσκηση! :thumbup: :)

Δυστυχώς κι αυτή έδωσε λάθος αποτέλεσμα στην 1η μου κιόλας προσπάθεια ("abcd", "cdab")

ΥΓ. Πάω να γράψω κώδικα για τις λύσεις και να τις ποστάρω.
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 08 Αύγ 2011, 04:18

migf1 έγραψε:
/* ------------------------------------------------------
* Άσκηση: Γράψτε μια συνάρτηση που θα παίρνει ως ορίσματα δυο strings και
* θα ελέγχει για το αν το ένα είναι αναγραμματισμός του άλλου.
* Θα επιστρέφει TRUE αν είναι, FALSE αν δεν είναι (ή 1 και 0, αντίστοιχα).
*
* Παραδείγματα:
*
* "abcd", "dbca" δίνει TRUE
* "helle", "hollo" δίνει FALSE
* "z", "zzz" δίνει FALSE
* "zzz", "z" δίνει FALSE
* "z", "z" δίνει TRUE
* -----------------------------------------------------
*/

Λύση 1η (με χρήση των στάνταρ συναρτήσεων: strchr & strlen)
Spoiler: show
Κώδικας: Επιλογή όλων

#include <stdio.h>
#include <string.h>
// --------------------------------------------------------------
int isanagram( char *s, char *t )
{
int i;
for (i=0; s[i] != '\0' && strchr(t, s[i]) != NULL; i++)
;
return i == strlen(t) ? 1 : 0;

/*** ΕΝΑΛΛΑΚΤΙΚΟΣ ΚΩΔΙΚΑΣ ΜΕ ΔΕΙΚΤΕΣ
int i=0;
for (; *s && strchr(t, *s++); i++)
;
return i == strlen(t) ? 1 : 0;
***/
}
// --------------------------------------------------------------
int main( void )
{
char s1[] = "abcd", s2[] = "cdab"; // 1 TRUE
char s3[] = "helle", s4[] = "hollo"; // 0 FALSE
char s5[] = "z", s6[] = "zzz"; // 0 FALSE
char s7[] = "zzz", s8[] = "z"; // 0 FALSE
char s9[] = "z", s10[] = "z"; // 1 FALSE

printf("%d\n", isanagram(s1, s2) );
printf("%d\n", isanagram(s3, s4) );
printf("%d\n", isanagram(s5, s6) );
printf("%d\n", isanagram(s7, s8) );
printf("%d\n", isanagram(s9, s10) );

return 0;
}

Λύση 2η (με χαρτογράφηση όλου του πίνακα ASCII στη μεταβλητή-πίνακα: map)
Spoiler: show
Κώδικας: Επιλογή όλων

#include <stdio.h>
// --------------------------------------------------------------------------------------
int isanagram(char *s, char*t)
{
int map[256] = {0}; // αρχικοποίηση όλων των στοιχείων σε 0
int val; // προσωρινή για τιμές στοιχείων του map

int i = 0;
while ( s[i] || t[i] ) // γέμισμα του map...
{ // για κάθε γράμμα του s αυξάνουμε
if ( s[i] ) // κατά 1 την τιμή του στοιχείου που
map[ s[i] ]++; // του αντιστοιχεί στον πίνακα map
if ( t[i] ' ) // (για κάθε γράμμα του t μειώνουμε κατά
map[ t[i] ]--; // 1 το στοιχείο που αντιστοιχεί στο map)
i++;
}

i = 0; // εξέταση του map για το
while (s[i] && t[i] && (val=map[ s[i] ]) == 0) // πρώτο MH μηδενικό στοιχείο
i++; // ή έως να τελειώσουν τα γράμματα στο s ή στο t

return val || t[i] ? 0 : 1; // είναι το val ή το t[i] != 0 ? FALSE : TRUE

/*** ΕΝΑΛΛΑΚΤΙΚΟΣ ΚΩΔΙΚΑΣ ΜΕ ΔΕΙΚΤΕΣ

int val, map[256] = {0};
char *cp1 = s, *cp2 = *t;

for (; *s || *t ;) {
if ( *s )
map[*s++]++;
if ( *t )
map[*t++]--;
}

while(*cp1 && *cp2++ && !(val=map[*cp1++]) )
;

return val || *cp2 ? 0 : 1;

***/
}
// --------------------------------------------------------------------------------------
int main( void )
{
char s1[] = "abcd", s2[] = "cdab"; // 1 TRUE
char s3[] = "helle", s4[] = "hollo"; // 0 FALSE
char s5[] = "z", s6[] = "zzz"; // 0 FALSE
char s7[] = "zzz", s8[] = "z"; // 0 FALSE
char s9[] = "z", s10[] = "z"; // 1 FALSE

printf("%d\n", isanagram(s1, s2) );
printf("%d\n", isanagram(s3, s4) );
printf("%d\n", isanagram(s5, s6) );
printf("%d\n", isanagram(s7, s8) );
printf("%d\n", isanagram(s9, s10) );

return 0;
}

Λύση 3η (με ταξινόμηση των strings και κατόπιν έλεγχο για ισότητα των γραμμάτων τους ένα προς ένα)
Spoiler: show
Κώδικας: Επιλογή όλων

#include <stdio.h>
#include <string.h> // για strlen(), strcmp()
#include <stdlib.h> // για qsort()
// -----------------------------------------------------------------------
int isanagram( char *s, char *t )
{
size_t slen = strlen(s);
size_t tlen = strlen(t);

if (slen != tlen)
return 0;

qsort(s, slen, sizeof(char), strcmp );
qsort(t, tlen, sizeof(char), strcmp );

while (*s && *s++ == *t++)
;
return *s == '\0';
}
// --------------------------------------------------------------------------------------
int main( void )
{
char s1[] = "abcd", s2[] = "cdab"; // 1 TRUE
char s3[] = "helle", s4[] = "hollo"; // 0 FALSE
char s5[] = "z", s6[] = "zzz"; // 0 FALSE
char s7[] = "zzz", s8[] = "z"; // 0 FALSE
char s9[] = "z", s10[] = "z"; // 1 FALSE

printf("%d\n", isanagram(s1, s2) );
printf("%d\n", isanagram(s3, s4) );
printf("%d\n", isanagram(s5, s6) );
printf("%d\n", isanagram(s7, s8) );
printf("%d\n", isanagram(s9, s10) );

return 0;
}
Τελευταία επεξεργασία από migf1 και 08 Αύγ 2011, 11:37, έχει επεξεργασθεί 4 φορά/ες συνολικά
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

Δημοσίευσηαπό Qdata » 08 Αύγ 2011, 11:03

migf1 έγραψε:Δυστυχώς κι αυτή έδωσε λάθος αποτέλεσμα στην 1η μου κιόλας προσπάθεια ("abcd", "cdab")

ΥΓ. Πάω να γράψω κώδικα για τις λύσεις και να τις ποστάρω.


Κώδικας: Επιλογή όλων
Δώστε την πρώτη λέξη: abcd
Δώστε την δεύτερη λέξη: cdab
Καμία από τις λέξεις δεν είναι αναγραμματισμός της άλλης.


Η πρώτη λέξη που έδωσες δεν είναι αναγραμματισμός της άλλης.Οπότε πρέπει να σου βγάλει:
Κώδικας: Επιλογή όλων
Καμία από τις λέξεις δεν είναι αναγραμματισμός της άλλης.


Σε εμένα το πρόγραμμα λειτουργεί μια χαρά.Τι αποτέλεσμα σου δίνει εσένα;
Linux User: #530165
Γνώσεις ⇛ Linux: Μέτριο ┃ Προγραμματισμός: Ναι ┃ Αγγλικά: Καλά
Λειτουργικό ⇛ Ubuntu 11.04 32bit σε Intel(R) Atom(TM) CPU N270 @ 1.60GHz
(Notebook) Προδιαγραφές ⇛ 2x Intel(R) Atom(TM) CPU N270 @ 1.60GHz │ 1016MB │ HDA-Intel - HDA Intel -- USB-Audio - USB AUDIO│ 1024x600 pixels
Νέος στο Linux?Οδηγοί - How to - Tutorials
Qdata
powerTUX
powerTUX
 
Δημοσιεύσεις: 1875
Εγγραφή: 18 Ιουν 2010, 19:40
Τοποθεσία: Σέρρες
IRC: dimos
Εκτύπωση

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

Δημοσίευσηαπό migf1 » 08 Αύγ 2011, 11:15

Qdata έγραψε:
migf1 έγραψε:Δυστυχώς κι αυτή έδωσε λάθος αποτέλεσμα στην 1η μου κιόλας προσπάθεια ("abcd", "cdab")

ΥΓ. Πάω να γράψω κώδικα για τις λύσεις και να τις ποστάρω.


Κώδικας: Επιλογή όλων
Δώστε την πρώτη λέξη: abcd
Δώστε την δεύτερη λέξη: cdab
Καμία από τις λέξεις δεν είναι αναγραμματισμός της άλλης.


Η πρώτη λέξη που έδωσες δεν είναι αναγραμματισμός της άλλης.Οπότε πρέπει να σου βγάλει:
Κώδικας: Επιλογή όλων
Καμία από τις λέξεις δεν είναι αναγραμματισμός της άλλης.


Σε εμένα το πρόγραμμα λειτουργεί μια χαρά.Τι αποτέλεσμα σου δίνει εσένα;

Μα είναι αναγραμματισμός :lol:

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

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

Δημοσίευσηαπό migf1 » 08 Αύγ 2011, 11:38

Πρόσθεσα και την 3η λύση, με την ταξινόμηση των strings πριν τον έλεγχο: viewtopic.php?p=201881#p201881 (το υλοποίησα μόνο με δείκτες)
Go under the hood with C: Pointers, Strings, Linked Lists
Άβαταρ μέλους
migf1
powerTUX
powerTUX
 
Δημοσιεύσεις: 2082
Εγγραφή: 03 Ιουν 2011, 16:32
Εκτύπωση

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

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