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

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

Δημοσ.

Παιδιά καλησπέρα έχω μια απορία στην παρακάτω άσκηση. 
Αν χρησιμοποιήσουμε στοίβα για την υλοποίηση της τότε πως μπορούμε να κρατάμε τον αριθμό των γραμμών όταν κάνουμε εισαγωγή στη στοίβα το σύμβολο { (ή αντίστοιχα το σύμβολο }) ; 

Δηλαδή κάτι αντίστοιχο με hash map που έχει η java. 

Αν έχετε οποιοδήποτε άλλη ιδέα ευπρόσδεκτη.

Σας ευχαριστώ εξ αρχής. 



---------------------------------------------------------------------------------------------------- 

Ζητείται να υλοποιηθεί πρόγραμμα σε C, το οποίο θα εντοπίζει τις σύνθετες προτάσεις μέσα σε ένα αρχείο κειμένου που περιέχει κώδικα σε γλώσσα C. Το πρόγραμμα όταν ξεκινά θα ζητά από τον χρήστη να πληκτρολογήσει το όνομα του αρχείου που επιθυμεί να ανοίξει. Στη συνέχεια θα πρέπει να τον ενημερώνει για το που ξεκινά η κάθε σύνθετη πρόταση (δηλαδή που υπάρχει ανοιχτό άγκιστρο '{') και που τελειώνει η συγκεκριμένη σύνθετη πρόταση (δηλαδή που υπάρχει κλειστό άγκιστρο '}'). 

Παράδειγμα 1: 

Έστω το αρχείο test1.c με τον παρακάτω κώδικα: 
#include <stdio.h> 
int main () 

int i; 
for (i=0;i<10;i++) 

printf("%d\n",i); 



Εκτέλεση προγράμματος: 

Δώσε όνομα αρχείου: test1.c 
1η σύνθετη πρόταση: 
Ανοίγει στην γραμμή 3 
Κλείνει στη γραμμή 9 
2η σύνθετη πρόταση: 
Ανοίγει στην γραμμή 6 
Κλείνει στη γραμμή 8 

Το πρόγραμμα θα πρέπει να λειτουργεί σωστά ακόμα και στην περίπτωση που υπάρχουν πολλαπλά άγκιστρα στην ίδια γραμμή. 

Παράδειγμα 2: 
Έστω το αρχείο test2.c με τον παρακάτω κώδικα: 
#include <stdio.h> 
int main () 

int i; 
for (i=0;i<10;i++) 
{{ 
printf("%d\n",i); 

}} 

Εκτέλεση προγράμματος: 

Δώσε όνομα αρχείου: test2.c 
1η σύνθετη πρόταση: 
Ανοίγει στην γραμμή 3 
Κλείνει στη γραμμή 9 (άγκιστρο 2) 
2η σύνθετη πρόταση: 
Ανοίγει στην γραμμή 6 (άγκιστρο 1) 
Κλείνει στη γραμμή 9 (άγκιστρο 1) 
3η σύνθετη πρόταση: 
Ανοίγει στην γραμμή 6 (άγκιστρο 2) 
Κλείνει στη γραμμή 8 
----------------------------------------------------------------------------------------- 

Δημοσ.

Παιδιά καλησπέρα έχω μια απορία στην παρακάτω άσκηση. 

Αν χρησιμοποιήσουμε στοίβα για την υλοποίηση της τότε πως μπορούμε να κρατάμε τον αριθμό των γραμμών όταν κάνουμε εισαγωγή στη στοίβα το σύμβολο { (ή αντίστοιχα το σύμβολο }) ; 

 

Δηλαδή κάτι αντίστοιχο με hash map που έχει η java. 

Αν έχετε οποιοδήποτε άλλη ιδέα ευπρόσδεκτη.

 

Σας ευχαριστώ εξ αρχής. 

 

 

 

 

---------------------------------------------------------------------------------------------------- 

 

Ζητείται να υλοποιηθεί πρόγραμμα σε C, το οποίο θα εντοπίζει τις σύνθετες προτάσεις μέσα σε ένα αρχείο κειμένου που περιέχει κώδικα σε γλώσσα C. Το πρόγραμμα όταν ξεκινά θα ζητά από τον χρήστη να πληκτρολογήσει το όνομα του αρχείου που επιθυμεί να ανοίξει. Στη συνέχεια θα πρέπει να τον ενημερώνει για το που ξεκινά η κάθε σύνθετη πρόταση (δηλαδή που υπάρχει ανοιχτό άγκιστρο '{') και που τελειώνει η συγκεκριμένη σύνθετη πρόταση (δηλαδή που υπάρχει κλειστό άγκιστρο '}'). 

 

Παράδειγμα 1: 

 

Έστω το αρχείο test1.c με τον παρακάτω κώδικα: 

#include <stdio.h> 

int main () 

int i; 

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

printf("%d\n",i); 

 

Εκτέλεση προγράμματος: 

 

Δώσε όνομα αρχείου: test1.c 

1η σύνθετη πρόταση: 

Ανοίγει στην γραμμή 3 

Κλείνει στη γραμμή 9 

2η σύνθετη πρόταση: 

Ανοίγει στην γραμμή 6 

Κλείνει στη γραμμή 8 

 

Το πρόγραμμα θα πρέπει να λειτουργεί σωστά ακόμα και στην περίπτωση που υπάρχουν πολλαπλά άγκιστρα στην ίδια γραμμή. 

 

Παράδειγμα 2: 

Έστω το αρχείο test2.c με τον παρακάτω κώδικα: 

#include <stdio.h> 

int main () 

int i; 

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

{{ 

printf("%d\n",i); 

}} 

 

Εκτέλεση προγράμματος: 

 

Δώσε όνομα αρχείου: test2.c 

1η σύνθετη πρόταση: 

Ανοίγει στην γραμμή 3 

Κλείνει στη γραμμή 9 (άγκιστρο 2) 

2η σύνθετη πρόταση: 

Ανοίγει στην γραμμή 6 (άγκιστρο 1) 

Κλείνει στη γραμμή 9 (άγκιστρο 1) 

3η σύνθετη πρόταση: 

Ανοίγει στην γραμμή 6 (άγκιστρο 2) 

Κλείνει στη γραμμή 8 

----------------------------------------------------------------------------------------- 

 

 

 

Αν και δεν έχω καταλάβει πως συνδέεις στο μυαλό σου το hashmap της Java με την ερώτησή σου, μέσα στο node της στοίβας μπορείς να κρατάς όποια και όσες πληροφορίες χρειάζεσαι.

 

Αν λοιπόν έχω καταλάβει σωστά τι ρωτάς, τότε το κάθε node της στοίβας εκτός από το πεδίο char που θα κρατάει το σύμβολό θα μπορούσε να έχει κι ένα πεδίο int (ή long int) που θα κρατάει τη γραμμή στην οποία βρέθηκε το σύμβολο...

 

typedef struct Node {
    char c;    /* symbol */
    int  l;       /* line */
    struct Node *prev;
} Node;
Οπότε για παράδειγμα μόλις βρίσκεις στο αρχείο σου ένα δεξί άγκιστρο και η στοίβα σου δεν είναι άδεια, τότε το node στην κορυφή της στοίβας θα περιέχει και τον αριθμό γραμμής στην οποία υπάρχει το αναμενόμενο αντίστοιχο αριστερό άγκιστρο. Με παρόμοια λογική θα μπορούσες να κρατάς μέσα στο node και το τρέχον count του συμβόλου (αριστερό άγκιστρο).

 

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

 

Δηλαδή, έτσι κι αλλιώς στο βασικό loop που θα διαβάζει το αρχείο θα χρησιμοποιήσεις counters και για τις γραμμές και για τα ανοιχτά άγκιστρα (σύνθετες προτάσεις) οπότε μπορείς να τα τυπώνεις επί τόπου μόλις βρεις ανοιχτό άγκιστρο ... όταν βρεις κλειστό άγκιστρο θα τυπώνεις μόνο την τρέχουσα γραμμή.

 

ΥΓ. Σχετικο-άσχετο με την αρχική σου ερώτηση, αλλά σου παραθέτω κι ένα link από ένα εργαστήριο του NorthEastern University, που σου δίνει αλγόριθμο για να διαχειρίζεσαι και πιο σύνθετες καταστάσεις: http://www.ccs.neu.edu/home/sbratus/com1101/lab4.html (το Reminder section που διαβάζει το αρχείο είναι σε C++ αλλά είναι τετριμμένο να το μετατρέψεις σε C αν το χρειαστείς).

  • Like 1
Δημοσ.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

main()
{
 
   char ch, file_name[50];
   FILE *fp;
   int  line_count=1,open_count=0,close_count=0; 
    
   printf("Dose onoma arxeiou:\n");
   gets(file_name);
 
   fp = fopen(file_name,"r"); // read mode
 
   if( fp == NULL )
   {
      perror("Error while opening the file.\n");
      exit(-1);
   }
   
   printf("--------------------------------------------\n");
   printf("The contents of %s file are :\n", file_name);
 
   while( ( ch = fgetc(fp) ) != EOF )
   {
      if( ch == '\n')
      {
         line_count++;
      }
      
      if( ch == '{')
      {      
         printf("%di syntheti protasi: \n", ++open_count); 
         printf("Anoigei stin grammi %d\n",line_count); 
      }
      
        if( ch == '}')
      {
        close_count++;  
        printf("Kleinei stin grammi %d\n",line_count); 
      }
      
   }
   printf("--------------------------------------------\n");
   fclose(fp);
   system("pause");
} 

 

Παίδες θα μπορούσε να γίνει η άσκηση χωρίς την χρήση στοίβας ;

Με άλλο τρόπο δηλαδή ; 

Για αρχή παραθέτω τον κώδικα που δουλεύω να μου πείτε ιδέες.

 

 

Ως έξοδο παίρνω(αν δώσω ως test1.txt)

Dose onoma arxeiou:
test1.txt
--------------------------------------------
The contents of test1.txt file are :
1i syntheti protasi:
Anoigei stin grammi 3
2i syntheti protasi:
Anoigei stin grammi 6
Kleinei stin grammi 8
Kleinei stin grammi 9
--------------------------------------------

ενώ αν δώσω (test2.txt) παίρνω

Dose onoma arxeiou:
test2.txt
--------------------------------------------
The contents of test2.txt file are :
1i syntheti protasi:
Anoigei stin grammi 3
2i syntheti protasi:
Anoigei stin grammi 6
3i syntheti protasi:
Anoigei stin grammi 6
Kleinei stin grammi 8
Kleinei stin grammi 9
Kleinei stin grammi 9
--------------------------------------------

 

Υπάρχει κάποιος τρόπος να ομαδοποιήσουμε τις γραμμές ανοίγει και κλείνει μεταξύ τους ;;

 

 

Δημοσ.
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

# define p 100
main()
{
   char ch, file_name[50];
   FILE *fp;
   int  line_count=1,open_count=0,close_count=0; 
   int  i=0,j=0;
   int  *a,*b,*c,*d;
   int  zero=0;
    
   printf("Dose onoma arxeiou:\n");
   gets(file_name);
 
   fp = fopen(file_name,"r"); // read mode
 
   if( fp == NULL )
   {
      perror("Error while opening the file.\n");
      exit(-1);
   }
   
   a=(int*)calloc(p,sizeof(int));
   b=(int*)calloc(p,sizeof(int));
   c=(int*)calloc(p,sizeof(int));
   d=(int*)calloc(p,sizeof(int));
   
   
   printf("--------------------------------------------\n");
   printf("The contents of %s file are :\n", file_name);
 
   while( ( ch = fgetc(fp) ) != EOF )
   {
      if( ch == '\n')
      {
         line_count++;
      }
      
      if( ch == '{')
      {      
          b[i]=++open_count;
          a[i]=line_count;
         i++;
      }
      
        if( ch == '}')
      {
         c[j]=line_count;
         j++;
      }
   }

       printf("--------------------------------------------\n");
   
       for(j=0;j<p;j++)
      {
        d[j]=c[p-1-j]; 
      }
      
       
     for(i=0;i<p;i++)
    {
                if(d[i]==0)
                {
                      zero++;
                }    
    }
    
     for(i=0;i<p;i++)
    {
                 if(d[i]==0)
                {
                 d[i]=d[zero+i]; 
                }  
    }
 
      
      
      printf("--------------------------------------------\n");
   
   
   for(i=0;i<p;i++)
    {
                    if(b[i]!=0)
                    {
                    printf("%di syntheti protasi: \n", b[i]); 
                    }
                    if(a[i]!=0)
                    {
                    printf("Anoigei stin grammi %d\n", a[i]); 
                    printf("Kleinei sti grammi  %d\n", d[i]);     
                    }      
                               
    }     
 
   fclose(fp);
   system("pause");
}

Παίδες για πείτε μου την γνώμη σας για τον παραπάνω κώδικα;

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

Δημοσ.

Καλημέρα,

 

δυστυχώς δεν έχω τον χρόνο να κοιτάξω τον κώδικα, αλλά η χρήση της στοίβας απλοποιεί κατά πολύ τα πράγματα, δεν τα δυσκολεύει. Για αυτό και αποτελεί τον στάνταρ τρόπο αντιμετώπισης τέτοιου είδους προβλημάτων (brackets matching).

 

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

Δημοσ.

Ζητείται να υλοποιηθεί πρόγραμμα σε C,

Παίδες για πείτε μου την γνώμη σας για τον παραπάνω κώδικα;

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

Παραβλέποντας το indentation του κώδικα μια και το φόρουμ έχει πολλά προβλήματα στο code tag, έχω να πω ότι ο κώδικας που έδωσες δεν είναι C αλλά Turbo C σε DOS. Ίσως να μη φταις εσύ μια και στη δική μου σχολή επίσης διδάσκουν Turbo C.

 

#include <conio.h>
Σε C δεν υπάρχει τέτοιο αρχείο κεφαλίδας (Υπάρχει σε Turbo C και σε πολλές υλοποιήσεις των Windows)

 

# define p 100
Σε ένα τόσο μικρό πρόγραμμα δεν παίζει και τόσο ρόλο αλλά είθισται τα macro να ορίζονται με κεφαλαία γράμματα (και επίσης να είναι λίγο πιο περιγραφικά από "p").

 

main()
Αυτό που είπα πριν. Ο παραπάνω ορισμός της main ήταν συνήθης στα χρόνια της Turbo C αλλά δεν είναι σωστός. Η main ορίζεται ως "int main(void)" και μόνο έτσι (τουλάχιστον μέχρι να μάθετε και τον άλλο ορισμό).

 

    gets(file_name);
Πάντα σε ασκήσεις βλέπουμε να χρησιμοποιείται η gets. Αυτό οφείλεται πιο πολύ σε αδράνεια γιατί πολλοί καθηγητές έμειναν σε εποχές DOS και στην gets (ή τουλάχιστον τότε έγραψαν το βιβλίο που παρέχουν στους μαθητές). Εκτός αυτού όμως είναι και πιο εύκολη λύση από τις εναλλακτικές οπότε είναι πιο εύκολο να την εξηγήσεις στο μαθητή. Με αυτό το σκεπτικό δεν βλέπω κακό στο να την χρησιμοποιείς σε αυτές τις ασκήσεις αν έχεις κατανοήσει ότι δεν πρέπει να την χρησιμοποιείς ποτέ (αρκεί να πούμε ότι στην τελευταία έκδοση του προτύπου έχει αφαιρεθεί εντελώς για να δούμε πόσο σημαντικά προβλήματα έχει).

 

    a = (int *) calloc(p, sizeof(int));
    b = (int *) calloc(p, sizeof(int));
    c = (int *) calloc(p, sizeof(int));
    d = (int *) calloc(p, sizeof(int));
Καλό είναι να αποφεύγεις το cast στις *alloc συναρτήσεις.

 

    char ch;
    while ((ch = fgetc(fp)) != EOF) {
Η μεταβλητή ch πρέπει να είναι τύπου int και όχι char.

 

        if (ch == '\n') {
        if (ch == '{') {
        if (ch == '}') {
Έχετε διδαχθεί την switch ? Αν ναι τότε μπορείς να γράψεις πιο όμορφα τον παραπάνω κώδικα για να μην έχεις όλα αυτά τα if.

 

    for (j = 0; j < p; j++) {
    for (i = 0; i < p; i++) {
    for (i = 0; i < p; i++) {
Το σώμα των τριών if δεν μπορεί να υλοποιηθεί μόνο με ένα if ?

 

    system("pause");
Παίζει μόνο σε windows αλλά το βλέπουμε στο 99% των κωδίκων οπότε δεν το δίνουμε σημασία πια :P

 

Δεν κοίταξα καθόλου την λογική του κώδικα αλλά μου φαίνεται ότι μπορείς να τον γράψεις πολύ πιο σύντομα και όμορφα. Επίσης κάτι που μου χτύπησε άσχημα είναι ο αριθμός των μεταβλητών. Τις χρειάζεσαι όλες ?

 

Επίσης, οποτεδήποτε εκχωρείς μνήμη με μια από τις *alloc συναρτήσεις, πρέπει / καλό_είναι να την απελευθερώνεις τρέχοντας την συνάρτηση free.

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

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

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

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

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

Σύνδεση

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

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