Προς το περιεχόμενο
  • 0
mike2012

Άσκηση σε γλωσσά c

Ερώτηση

Παιδιά έχω να κάνω μια άσκηση η οποία λέει το έξεις :

 

Γράψτε ένα πρόγραμμα που θα διαβάζει από το πληκτρολόγιο έναν ακέραιο αριθμό

N, στη συνέχεια θα διαβάζει N λέξεις, θα υπολογίζει την πιο συχνή λέξη ανάμεσα στις N και

θα την τυπώνει.

 

Άλλα δεν μπορώ να βρω τον έλεγχο της συνθικης μπορεί κανείς να με βοηθήσει ???

 

Ευχαριστώ εκ τον προτέρων

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Προτεινόμενες αναρτήσεις

  • 0

Αν η strcmp επιστρέψει 0 τότε οι δυο λέξεις είναι ίδιες.

 

 

#include <stdio.h>

 

int strcmp(char *string1, char *string2);

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0
Δημοσ. (επεξεργασμένο)

Οι συχνότητες συνήθως μετριούνται με την βοήθεια ιστογράμματος, δηλαδή ενός πίνακα ακεραίων αρχικοποιημένου με μηδενικά. Κάθε θέση του ιστογράμματος αντιστοιχεί σε κάθε μοναδική διαβασμένη λέξη. Εφόσον δεν ξέρεις εξαρχής τις λέξεις, το ιστόγραμμά σου θα έχει Ν θέσεις.

 

Χρειάζεσαι επίσης έναν τρόπο να αντιστοιχείς την κάθε μοναδική λέξη από αυτές που διαβάζεις με την κατάλληλη θέση του ιστογράμματος, δηλαδή ένα hash function όπως λέγεται. Ιδανικά θα ήθελες μια perfect hashing function για τις λέξεις σου, αλλά αυτό είναι πρακτικά αδύνατον αν οι λέξεις σου έχουν απροσδιόριστο μήκος.

 

Μπορείς όμως να κάνεις κάτι που δεν είναι τόσο efficient όσο ένα κανονικό hash-function, αλλά δουλεύει για όλες τις λέξεις ανεξαιρέτως μήκους τους...

 

Φτιάχνεις έναν πίνακα από Ν λέξεις, και για κάθε λέξη που διαβάζεις την προσθέτεις σε αυτόν τον πινάκα μονάχα αν δεν υπάρχει ήδη. Είτε βρεις την λέξη, είτε όχι και την προσθέσεις στον πίνακα, αυξάνεις κατά ένα τον ακέραιο στην αντίστοιχη θέση του ιστογράμματος.

 

Για παράδειγμα...

 

>
...
int histogram[N] = {0};       // το ιστόγραμμα
char *arrWords[N] = {NULL}; // πίνακας Ν (απροσδιόριστου μήκους) λέξεων

int hash_word( const char *word, char *arrWords[N] );
...

 

Τη συνάρτηση hash_word() θα τη φτιάξεις να ψάχνει τη λέξη word στον πίνακα arrWords[].

 

Αν την βρει θα επιστρέφει τη θέση του πίνακα στην οποία βρέθηκε η λέξη. Αν δεν τη βρει θα την προσθέτει στην 1η διαθέσιμη θέση του πίνακα, την οποία και θα επιστρέφει. Σε περίπτωση σφάλματος (π.χ. αν ο πίνακας είναι ήδη γεμάτος) μπορείς να την βάλεις να επιστρέφει μια αρνητική τιμή (π.χ. -1, μιας και οι θέσεις πινάκων ξεκινάνε πάντα από 0).

 

Από εκεί και πέρα, η λύση συρρικνώνεται σε 2 loops (π.χ. μέσα στην main() ):

α) ένα για το διάβασμα και ταυτόχρονο hashing των N λέξεων

β) ένα για τον εντοπισμό της συχνότερης λέξης στο ιστόγραμμα...

 

>
int main( void )
{
   ...
   // read & hash words
   int posHashed = -1;
   for (int i=0; i < N; i++) {
       scanf("%s", word);   // word must have been already malloc'ed
       posHashed = hash_word(word, arrWords);
       if ( -1 != posHashed )
          histogram[ posHashed ]++;
   }

   // find most frequent word
   int maxFreq = posMaxFreq = -1;
   for (int i=0; i < N; i++) {
       if ( histogram[i] > maxFreq ) {
           maxFreq = histogram[i];
           posMaxFreq = i;
       }
   }

   // print most frequent word
   if ( -1 != posMaxFreq )
       printf( "most frequent word: %s (%d) times\n",
           (NULL == arrWords[posMaxFreq]) ?  "***ERROR***" : arrWords[ posMaxFreq ],
           histogram[ posMaxFreq ]    // or maxFreq
       );
   ...
}

 

ΥΓ. Ο κώδικας είναι untested (τον έγραψα απευθείας στον editor του φόρουμ, οπότε ενδέχεται να έχει bugs).

 

Επίσης, δεν προβλέπει περαιτέρω ανάλυση σε περίπτωση που υπάρχουν περισσότερες της μιας λέξης με την υψηλότερη συχνότητα εμφάνισης. Σε τέτοιες περιπτώσεις τυπώνει την 1η.

Επεξ/σία από migf1

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

προσπαθω να εφαρμόσω όλα αυτα που μου λετε αλλα δεν τα καταφέρνω γινετε να μου τα κανετε πιο σαφη......εχω καταλαβει πως λειτουργεί h strcmp αλλα δεν μπορω να το κανω να μπει μια φορα

 

 

for( i=0; i<=n; i++)

{

for( j=0; j<n; j++)

{

if( strcmp( &l[j], &l[i+1][j])==0)

{

k++;

 

}

 

}

}

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

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

 

Σε περίπτωση που έχεις σημαντικές ελλείψεις υπόβαθρου δεν μπορείς να λύσεις την άσκηση. Αν υπάρχει χρόνος μπορείς να καλύψεις τις όποιες ελλείψεις διαβάζοντας την ύλη που προϋποθέτει η λύση της άσκηση. Αν δεν υπάρχει χρόνος, υποθέτω συμφιλιώνεσαι με την ιδέα πως δεν θα την λύσεις (ή προσπαθείς να βρεις να σου τη λύσει κάποιος άλλος, με ή χωρίς πληρωμή).

 

Μια πιθανή συνάρτηση που ελέγχει αν μια λέξη βρίσκεται ή όχι σε έναν πίνακα λέξεων (με περιορισμό πως αν μια θέση περιέχει NULL, σηματοδοτεί τη λήξη των χρήσιμων περιεχόμενων... συνήθως αναφέρονται ως NULL terminated string arrays) θα μπορούσε να είναι κάπως έτσι (!!!untested!!!)...

 

>
int arrWords_lookup( char *arrWords[N], const char *word )
{
   for (int i=0; i < N; i++) {
       if ( NULL == arrWords[i] )
           return -1;
       if ( 0 == strcmp(arrWords[i], word) )
           return i;
   }

   return -1;
}

 

Επιστρέφει -1 είτε σε περίπτωση ο πίνακας arrWords[] είναι γεμάτος είτε σε περίπτωση που η λέξη word δεν υπάρχει στον πίνακα. Aλλιώς επιστρέφει -1.

 

Για να μετατραπεί στη συνάρτηση hash_word() που αναφέρω στην αρχική μου απάντηση, θα πρέπει να τροποποιηθεί έτσι ώστε να προσθέτει την λέξη στην 1η διαθέσιμη του πίνακα, σε περίπτωση που δεν υπάρχει ήδη, και να επιστρέφειτη θέση της.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Μια άλλη μέθοδος που θα άρεσε και στον καθηγητή σου είναι να φτιάξεις μια συνδεδεμένη λίστα από struct.

Κάθε struct περιέχει τη λέξη (char* ), τον αριθμό εμφανίσεων της (freq), και το next.

Aν μια λέξη υπάρχει στη λίστα αύξησε της το freq κατά 1, αλλιώς πρόσθεσε στη λίστα ένα struct με τη συγκεκριμένη λέξη και freq=1.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Μια άλλη μέθοδος που θα άρεσε και στον καθηγητή σου είναι να φτιάξεις μια συνδεδεμένη λίστα από struct.

Κάθε struct περιέχει τη λέξη (char* ), τον αριθμό εμφανίσεων της (freq), και το next.

Aν μια λέξη υπάρχει στη λίστα αύξησε της το freq κατά 1, αλλιώς πρόσθεσε στη λίστα ένα struct με τη συγκεκριμένη λέξη και freq=1.

 

Yeap!

 

Αν και η λογική είναι ακριβώς η ίδια. Του πρότεινα πίνακα (δυναμικά ορισμένο ή VLA) γιατί η άσκηση δίνει πεπερασμένο πλήθος στοιχείων N.

 

Το ιστόγραμμα και ο arrWords[N] μπορούν να ενοποιηθούν σε έναν πίνακα, με το κάθε του στοιχείο να έχει την δομή που περιγράφεις).

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Γενικά αποφεύγω τον πινάκα όταν το Ν το δίνει ο χρήστης. Η πίνακες θέλουν το Ν γνωστό από πριν.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

βασικά δεν μας έχει κάνει ακόμα πολυδιάστατους πινάκες και δεν ξέρω πως να τους χρησιμοποιήσω έχουμε κάνει μονό τα βασικά.. για αυτο

 

βασικά δεν μας έχει κάνει ακόμα πολυδιάστατους πινάκες και δεν ξέρω πως να τους χρησιμοποιήσω έχουμε κάνει μονό τα βασικά.. για αυτο

και προσπαθώ να λύσω την άσκηση με δισδιάστατο πινάκα

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Γενικά αποφεύγω τον πινάκα όταν το Ν το δίνει ο χρήστης. Η πίνακες θέλουν το Ν γνωστό από πριν.

 

Οι δυναμικοί πίνακες όχι...

 

>
int n = 0, *arr = NULL;
...
scanf( "%d", &n)
...
if ( NULL == (arr=calloc(n, sizeof(int))) )
  exit(1);

for (int i=0; i < n; i+)
   printf( "%d ", arr[i] );
puts("\b");
...
free( arr );
exit(0);

 

βασικά δεν μας έχει κάνει ακόμα πολυδιάστατους πινάκες και δεν ξέρω πως να τους χρησιμοποιήσω έχουμε κάνει μονό τα βασικά.. για αυτο

 

και προσπαθώ να λύσω την άσκηση με δισδιάστατο πινάκα

 

Θα πρέπει τότε να μας πεις τι γνωσικοί περιορισμοί υπάρχουν για την λύση της άσκησης. Αν και οι λέξεις είναι έτσι κι αλλιώς 2Δ πίνακες χαρακτήρων, οπότε αν δεν σας έχει μιλήσει για 2Δ πίνακες, η άσκηση αυτή είναι εκτός ύλης.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Βασικά αυτό που μας ζητάει η άσκηση είναι να βρούμε πόσες φορές εμφανίζετε μια λέξη ..... και όχι αν ένας πινάκας είναι γεμάτος

αυτό που κάνω εγώ είναι ότι δημιουργώ ένα πινάκα κ[1000][1000] και αποθηκευω μια λέξη σα κάθε γραμμή και μετά με την strcmp ελέγχω αν είναι αυτές οι δυο ίδιες αλλά αυτή ελενχει έναν έναν χαρακτήρα και μου αυξάνει τον μετρητή και εγώ θέλω να των αυξήσει μονο μια φορά

 

Οι δυναμικοί πίνακες όχι...

 

>
int n = 0, *arr = NULL;
...
scanf( "%d", &n)
...
if ( NULL == (arr=calloc(n, sizeof(int))) )
exit(1);

for (int i=0; i < n; i+)
printf( "%d ", arr[i] );
puts("\b");
...
free( arr );
exit(0);

 

 

 

Θα πρέπει τότε να μας πεις τι γνωσικοί περιορισμοί υπάρχουν για την λύση της άσκησης. Αν και οι λέξεις είναι έτσι κι αλλιώς 2Δ πίνακες χαρακτήρων, οπότε αν δεν σας έχει μιλήσει για 2Δ πίνακες, η άσκηση αυτή είναι εκτός ύλης.

εχουμε να την παραδώσουμε στης 5 του μηνά και μέχρι τότε θα τούς κάνουμε αλλά μένει λίγος χρόνος μετά και προσπαθω μονός μου να βγάλω ακρη

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Αν έχεις ένα μονοδιάστατο πίνακα από λέξεις με πολλαπλές εμφανίσεις πρέπει να κάνεις κάποια αλφαβητική ταξινόμηση. Αν έχετε μάθει bubble sort, merge sort η quicksort για αριθμούς , το ίδιο ισχύει και για λέξεις (τις συγκρίνεις ( < > = ) με την strcmp).

Μετά μετράς το bloc με τις περισσότερες επαναλαμβανόμενες λέξεις.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

στην c άμα αποθηκεύσω ένα string σε ενα πινάκα δεν βάζει στο κάθε "κουτί"ένα γραμμα

 

Από default όχι. Το κάθε string είναι ένας πίνακας χαρακτήρων, ο οποίος για να μπορεί να χρησιμοποιηθεί με τις στάνταρ συναρτήσεις διαχείρισης της γλώσσας (όπως π.χ. την strcmp() ) πρέπει ο τελευταίος τους χρήσιμος χαρακτήρας να ακολουθείται από έναν ή περισσότερους μηδενικούς χαρακτήρες.

 

Ρίξε μια ματιά στο link της υπογραφής μου, ίσως σε βοηθήσει.

 

ΥΓ. Παρεμπιπτόντως, αν εξαιρέσουμε τις λέξεις, όλα τα υπόλοιπα που έχουμε γράψει στο νήμα χρησιμοποιούν λογική μονοδιάστατων πινάκων.

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Μπορείς να έχεις μονοδιάστατο πινάκα από δείκτες σε λέξεις (char*).

 

Αν πας γράμμα γράμμα τότε θες διδιαστατο 1000x20 (πίνακα από πίνακες 1000 λέξεις , 19 γράμματα το πολύ η λέξη) ,μετά γίνεται πιο περίπλοκη η ταξινόμηση .

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες
  • 0

Βασικά αυτό που μας ζητάει η άσκηση είναι να βρούμε πόσες φορές εμφανίζετε μια λέξη ..... και όχι αν ένας πινάκας είναι γεμάτος

 

Και η δική μου απάντηση για να βρεις πόσες φορές εμφανίζεται μια λέξη ήταν. Το να βρεις αν ένας πίνακας είναι γεμάτος είναι safety measure κατά τη διάρκεια της διαδικασίας κατά την οποία ψάχνεις να βρεις πόσες φορές εμφανίζεται μια λέξη.

 

Από αυτό που γράφεις καταλαβαίνω πως δεν έχεις καταλάβει σχεδόν τίποτα από την αρχική μου απάντηση. Κυρίως το τι, πως και γιατί χρησιμοποιούμε ιστογράμματα όταν θέλουμε να μετρήσουμε συχνότητες εμφάνισης.

 

Είναι όμως ο πλέον διαδεδομένος τρόπος, και κατά την γνώμη μου είναι θεμελιώδης η κατανόησή του, προκειμένου να μπορέσεις να λύσεις την άσκηση.

 

αυτό που κάνω εγώ είναι ότι δημιουργώ ένα πινάκα κ[1000][1000] και αποθηκευω μια λέξη σα κάθε γραμμή και μετά με την strcmp ελέγχω αν είναι αυτές οι δυο ίδιες αλλά αυτή ελενχει έναν έναν χαρακτήρα και μου αυξάνει τον μετρητή και εγώ θέλω να των αυξήσει μονο μια φορά

...

 

Το ότι δεσμεύεις έναν πίνακα 1000x1000 χαρακτήρων όχι μόνο δεν ενδείκνυται για την συγκεκριμένη άσκηση, αλλά είναι κι εσφαλμένο. Π.χ. τι θα κάνεις αν το Ν που θα σου δώσει ο χρήστης είναι ας πούμε 1001? Οι πίνακές σου θα πρέπει να οριστούν με N στοιχεία στην 1η τους διάσταση (αν είναι 2Δ) ή στην μόνη τους διάσταση (αν είναι 1Δ). Όσα στοιχεία δηλαδή σου δώσει ο χρήστης (όπως λέει η εκφώνηση)... που στην πράξη εν πολλοίς σημαίνει: dynamic (allocated) array. Οτιδήποτε άλλο είναι αχρείαστα inefficient ή/και πολύπλοκο.

 

Επίσης, το να αποθηκεύεις αδιακρίτως όλες τις λέξεις που διαβάζεις μέσα σε έναν πίνακα (επιτρέποντας δηλαδή ίδιες λέξεις σε διαφορετικές θέσεις) και περιπλέκει αχρείαστα τον κώδικα (πολύ περισσότερο από αυτά που σου έχουμε προτείνει στο νήμα) και τον κάνει πάρα πολύ in-efficient (ειδικά αν σκέφτεσαι να τον ταξινομήσεις κιόλας τον πίνακα).

 

Πες ότι τις πέρασες τις λέξεις στον πίνακα, διπλο-τριπλο-περασμένες σε διαφορετικές θέσεις. Κατόπιν πως σκοπεύεις να μετρήσεις ποια εμφανίζεται περισσότερες φορές;

 

Με άλλα λόγια, προσπάθησε να καταλάβεις τι είναι, πως και γιατί χρησιμοποιούμε ιστογράμματα για αυτές τις δουλειές. Είτε από την αρχική μου απάντηση, είτε από τα βιβλία σας, είτε από το Google, είτε από οπουδήποτε αλλού. Αν δεν σε καλύπτει η αρχική μου απάντηση, ευχαρίστως να σου διευκρινήσω τα σημεία που θα μου υποδείξεις.

 

Αρκεί να μην θέλεις να σου γράψω εγώ και το υπόλοιπο 1/4 που έχει απομείνει χωρίς κώδικα σε αυτό το νήμα στη λύση της άσκησης :P

Κοινοποιήστε αυτήν την ανάρτηση


Σύνδεσμος στην ανάρτηση
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε έναν λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι εύκολο!

Εγγραφείτε για έναν νέο λογαριασμό

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
×
×
  • Δημιουργία νέου...

Χρήσιμες πληροφορίες

Με την περιήγησή σας στο insomnia.gr, αποδέχεστε τη χρήση cookies που ενισχύουν σημαντικά την εμπειρία χρήσης.