miei programmi in c su knoppix e relativi problemi

anche_per_il_direttore

Nuovo Utente
63
2
salve
il codice di oggi e un quicksort, il codice misembra a posto l unico problema e' che non riesco ad ottenere il vettore ordinato, sembra che il mio pc ci impieghi un eternita a darmi i risultati, comunque posto il codice e se qualcuno puo provare a farlo girare sul proprio pc e vedere come va sarebbe un aiuto
ciao
C:
/* ordinamento quicksort di un vettore di interi
il codice divide in due blocchi il vettore, gli elementi
a sinistra e gli elementi a destra del pivot (il pivot"perno"
qui e dato dalla media)  e poi fa lo stesso
con i due sottoblocchi e cosi via fino ad ordinare il vettore*/



         #include <stdio.h>
         #define N 10
         int v[N];  //vettore di interi
        
        
    
     void quick (int,int);
     void scambia (int*,int*);
    
               
               int main(void)
               {
                 int i;
                
                 for (i=0;i<N;i++)
                 {
                    printf("\nInserire un intero n:%d ",i);
                    scanf("%d",&v[i]);
                   
                 }
                   
                    quick (0,N-1);
                   
                    for (i=0;i<N;i++)
                    printf("\n%d",v[i]);
                    putchar ('\n');
                    }
                   
          void quick (int sx, int dx) //funzione ricorsiva quicksort
     {
     int i,j,media;             
         media = (v[sx]+v[dx])/2;
         i = sx;
         j = dx;
        
         do {
         while (v[i]<media) 
         i++;
         while (media<v[j])
         j--;
         }      
              
         while (j>=i);
         if (sx<j)
                    quick (sx,j);
        if (i<dx)
                    quick (i,dx);
                    }     
                  
         void scambia (int *a,int *b)
         {
         int temp;
         temp=*a;
         *a=*b;
         *b=temp;
         }
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Il codice non fa niente, va in un loop infinito, perché la procedura "scambia" non viene mai chiamata. Inoltre come pivot utilizzi la media tra il primo e l'ultimo elemento dell'array, mentre dovresti usare la media tra il primo e l'ultimo indice, cioè l'elemento centrale dell'array. Che algoritmo stai usando? Per favore, cerca di indentare e scrivere uniformemente il codice altrimenti diventa difficile da leggere.
 

anche_per_il_direttore

Nuovo Utente
63
2
Ciao Fabio grazie Dei suggerimenti non appena riesco Lo riguardo
A proposito come faccio a indentare il codice?
Quando Lo creo uso mcedit di linux e poi faccio copia incolla Sulla finestra utilizzando l inserisci codice e poi modifico code con code=C
Avvolte uso kwrite che sembra mantenere una buona indentazione che pero perdo nella procedura di copia incolla
Ps mi sono appena accorto che non ho ricopiato tutto il codice nel mio pc dal pezzo di carta, purtroppo devo fare a cazzotti con I minuti ogni volta, non appena riesco faccio girare il codice completo e poi risposto, ciao e grazie dell aiuto
 
Ultima modifica:

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Basta usare uno stile di programmazione costante, per esempio un tab per le indentazioni, e usare le parentesi in maniera uniforme, esempio:
C:
while (condizione) {
    // do something;
}
if (condizione) {
    // do something;
} else {
    //do something else;
}
e non
C:
while (condizione) {
// do something (senza indentazione);
}
if (condizione) {
/* do something;*/}
else {
do something else;
          }
 

anche_per_il_direttore

Nuovo Utente
63
2
ok questo dovrebbe funzionare, ho tenuto sempre la media tra il primo e l ultimo elemento del vettore come pivot, per quanto riguarda l algoritmo, ho solo seguito la teoria, in giro ci saranno algoritmi
molto piu ottimizzati che non utilizzano la ricorsivita, ma per me e piu semplice ragionare in questi
termini a scapito dell ottimizzazione del codice 9che mi propongo di fare tempo permettendo), ciao
C:
/* ordinamento quicksort di un vettore di interi
il codice divide in due blocchi il vettore, gli elementi
a sinistra e gli elementi a destra del pivot (il pivot"perno"
qui e dato dalla media tra il primo e l ultiumo elemento
del vettore) , poi fa lo stesso con i due sottoblocchi e cosi
via fino ad ordinare il vettore*/



         #include <stdio.h>
         #define N 10
       
       
         int v[N];  //vettore di interi
      
      
        void scambia (int*,int*);
       
         void scambia (int *a,int *b) //definizione funzione scambia
    {
            int temp;
            temp=*a;
            *a=*b;
            *b=temp;
    }    
      
                                   
   
        void quick (int,int);
   
        void quick (int sx, int dx) //definizione di funzione ricorsiva quicksort
    {
           int i,j,media;            
           media = (v[sx]+v[dx])/2;
           i = sx;
           j = dx;
       
         do
            {
                while (v[i]<media)  i++;
                while (media<v[j])  j--;
       
                if (i<=j)   {
                                scambia (&v[i],&v[j]);
                                i++;
                                j--;
                            }     
            }
       
         while (j>=i);
       

       
         if (sx<j)
                    quick (sx,j);
         if (i<dx)
                    quick (i,dx);
    }    
                 
     
       
       
       
              
               int main(void)
    {
               int i,j,sx,dx;
               
             
             
               for (i=0;i<N;i++)
               
               {
                    printf("\nInserire un intero n:%d ",i);
                    scanf("%d",&v[i]);
               }
                  
                    quick (0,N-1);
                  
                    for (i=0;i<N;i++)
                  
                        printf("\n%d",v[i]);
                        putchar ('\n');
    }
 
Ultima modifica:

anche_per_il_direttore

Nuovo Utente
63
2
salve tempo fa avevo scritto un codice per la generazione di numeri casuali senza che questi numeri si ripetessero, il codice che sto postando genera un vettore di numeri casuali di dimensione n, questi numeri vengono generati in un intervallo [0;n-1] come ritorno della funzione rand.
ora quello che vorrei fare e generare numeri casuali con un offset.
ossia la funzione rand()%n mi genera numeri casuali nell intervallo di cui sopra, io vorrei invece che me li generasse nell intervallo [0+offset;n-1+offset];
so gia che se uso la rand()%n+offset ottengo il risultato ma nel mio codice e' un po piu complicato; comunque se qualcuno ha qualche idea sarebbe un aiuto
ecco il codice
PS per controllare i valori di ritorno
cat dati33.txt

C:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>


int main()  

{



    FILE *pf;              //pf e il puntatore o lo stream

    int i,j,d,n,estratto,*v;


    v = malloc (n* sizeof(int));


    printf ("inserisci la dimensione del vettore \n");
    scanf ("%d",&n);        //n rappresenta l ampiezza
   
    pf = fopen ("dati33.txt", "w+");  //creo un file in lettura/scrittura
   
    if (pf == NULL)   
    {        
    printf ("impossibile aprire il file dati33.txt");
    exit(1);
    }

   
    srand(time(NULL));                              /*inizializzazione seme col clock*/
                       
   
    fprintf(pf,"elementi del vettore v:\n");
   
    fprintf(pf,"num pall num extr\n");
   
   
    for (i=0;i<n;i++)
    {
    v[i]=i;
    }    
    
     d=n;
   
   
    for (i=0; i<n; i++)
    {
  
    j = rand()%d;             /*scelgo elemento casuale del vettore, ossia il numero della pallina*/
    estratto = v[j];             /*ne estraggo il valore, questo e il risultato dell estrazione*/
   
    fprintf (pf,"%d\t %d\n",i,estratto);
    v[j] = v[d-1];             /*sposto ultimo elemento al posto di quello estratto*/
    d--;                 /*non rimetto la pallina nel contenitore*/
   
    }

    fclose(pf);            //chiudo il file dati33.txt
   
    return 0;
   
    free (v);
   
}
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Ciao, come hai già scritto l'offset si imposta "sommandolo" alla funzione rand() % n. A cosa ti serve esattamente?
PS.: vedo che hai di nuovo scritto la malloc prima della scanf, è un errore! Così crei un vettore di dimensione casuale. Poi l'istruzione free deve venire prima di return 0, perché sennò non viene eseguita, dato che quando incontra la return il programma termina.
 

anche_per_il_direttore

Nuovo Utente
63
2
ciao, ho corretto gli errori che hai sottolineato, il codice funziona, solamente che volevo avere la liberta' di far variare l'estrazione dentro uno spazio con l offset.
se fai girare il codice vedrai nel file dati33.txt nella prima colonna l indice che varia tra 0 e n-1 e nella seconda colonna le estrazioni di numeri casuali che non si ripetono (sono tutti diversi), l algoritmo estrae tutti gli n valori (ad esempio se n e' 40 le estrazioni avverranno nel range 0-39), quello che volevo fare e' avere estrazioni in un range [0+offset;n-1+offset] mantenendo naturalmente la possibilita' di scegliere la dimensione n.
tieni presente che l urna dalla quale vengono estratti i numeri (urna di elementi che vanno da 0 a n-1) diventa sempre piu piccola man mano che le estrazioni proseguono (il che equivale a dire che non rimetto il numero che estraggo di nuovo nell urna, un po come nel gioco della tombola).
lo scopo una volta che aggiusto questo algoritmo per fargli fare quello che voglio e' quello di passare successivamente questo vettore alla quicksort postata precedentemente e magari memorizzare la colonna risultato(vettore ordinato a fianco della colonna delle estrazioni casuali sullo stesso file dati33.txt)
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
quello che volevo fare e' avere estrazioni in un range [0+offset;n-1+offset]
Ho capito come funziona il programma, non ho capito invece perché, se l'offset è uguale sia a sinistra che a destra, non va bene l'istruzione offset + rand().
 
Ultima modifica:

anche_per_il_direttore

Nuovo Utente
63
2
ok posto due codici, il primo genera numeri casuali senza ripetizioni (in questo codice per come e' fatto non posso impostare l offset)
il secondo codice mi permette di allocare un vettore in maniera dinamica, costruisce un vettore indice compreso tra [offset;n+offset], la funzione rand() pesca valori in tale range ma il vettore dei numeri generati ha dei numeri che si ripetono (ho provato a imitare il primo codice che ho creato e che effettivamente fa quello che voglio)
quello che vorrei dal codice numero 2 e':
1)avere la possibilita' di scegliere il valore n (che sarebbe l equivalente dell ampiezza)
2)scegliere l'offset
3)generare numeri che non si ripetono
di seguito i due codici (aiuti sempre benvenuti)
C:
#include<stdio.h>
#include<stdlib.h>

#define NMAX 5
                       /*nel programma vengono estratte tutte le palline*/

  int  main()
{
    int i,j,d,estratto;
    int v[NMAX];
  
        /*inizializzo il vettore per la ricerca casuale*/
  
    for (i=0; i<NMAX; i++)
    {
    v[i]=i;                        /*la posizione della pallina nell urna coincide col numero che riporta, ossia
                        la pallina numero uno ha stampato sopra il numero uno e cosi via*/
  
                        /*cerco elemento casuale tra i valori NMAX di v*/
    d=NMAX;
     }
   
    printf("num pall num extr\n");
   
    for (i=0; i<NMAX; i++)
    {
    j= rand()%d;             /*scelgo elemento casuale del vettore, ossia il numero della pallina*/
    estratto = v[j];             /*ne estraggo il valore, questo e il risultato dell estrazione*/
  
    printf ("%d\t %d\n",i,estratto);
    v[j] = v[d-1];             /*sposto ultimo elemento al posto di quello estratto*/
    d--;                 /*non rimetto la pallina nel contenitore*/
  
    }

  
}
  
  

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


int main() 

{



    FILE *pf;              //pf e il puntatore o lo stream

    int i,j,d,n,offset,estratto,*v;




    printf ("inserisci la dimensione del vettore \n");
    scanf ("%d",&n);        //n rappresenta l ampiezza
  
    printf ("inserisci l'offset \n");
    scanf ("%d",&offset);        //n rappresenta l ampiezza
  
    v = malloc ((n+offset)* sizeof(int));

//    v = malloc (offset* sizeof(int));

    pf = fopen ("dati33.txt", "w+");  //creo un file in lettura/scrittura
  
    if (pf == NULL)  
    {       
    printf ("impossibile aprire il file dati33.txt");
    exit(1);
    }

  
    srand(time(NULL));                              /*inizializzazione seme col clock*/
                      
  
    fprintf(pf,"elementi del vettore v:\n");
  
    fprintf(pf,"num pall num extr\n");
  
  
  
    for (i=offset;i<n+offset;i++)
    {
    v[i]=i;
    }
 
     d=n+offset;
  
  
  
    for (i=offset; i<n+offset; i++)
    {
 
    j = rand()%d;             /*scelgo elemento casuale del vettore, ossia il numero della pallina*/
    estratto = v[j];             /*ne estraggo il valore, questo e il risultato dell estrazione*/
  
    fprintf (pf,"%d\t %d\n",i,estratto);
    v[j] = v[d-1];             /*sposto ultimo elemento al posto di quello estratto*/
    d--;                 /*non rimetto la pallina nel contenitore*/
  
    }

    fclose(pf);            //chiudo il file dati33.txt
    free (v);
  
    return 0;
  
  
  
}
 

anche_per_il_direttore

Nuovo Utente
63
2
posto altri due codici (fatti al volo), il primo che non funziona vorrebbe essere un vettore di puntatori di puntatori (anche qui funzione free da applicare correttamente)
il secondo e' una matrice allocata dinamicamente (non sono sicuro se ho applicato la funzione free correttamente)
ecco i codici, ciao

C:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>



int main()   {
            
int **vett;            //vettore a due dimensioni puntatore di puntatori
int righe,colonne,i,j;

printf ("inserisci la dimensione delle righe\n");
scanf ("%d",&righe);

printf ("inserisci la dimensione delle colonne\n");
scanf ("%d",&colonne);

vett=(int**)malloc(righe*sizeof(int*));
                                   
//vett=(int**)malloc(colonne*sizeof(int*));

for(i=0;i<righe;i++) 
{
    for(j=0;j<colonne;j++)
    {
    vett[i][j]=4;

    printf("%d",vett[i][j]);
    printf("\n");
    }
}

for (i=0;i<righe;i++)
{

free(vett[i]);
free(vett);           
   
}


return 0;







#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>



int main()  
{
             
int *vett;            //allocazione dinamica di una matrice
int righe,colonne,i,j;

printf ("inserisci la dimensione delle righe\n");
scanf ("%d",&righe);

printf ("inserisci la dimensione delle colonne\n");
scanf ("%d",&colonne);

vett= malloc(sizeof(int[righe][colonne]));
                                   

for(i=0;i<righe;i++)  
{
    for(j=0;j<colonne;j++)

    vett[i,j]=33;
   
}

printf("la matrice vett e' la seguente\n");

for(i=0;i<righe;i++)  
{
    for(j=0;j<colonne;j++) 
    {

        printf("%5d",vett[i,j]);

    }
    printf("\n");
}


//for (i=0;i<righe;i++) {

//free(vett[i,j]);

free(vett);           // }


return 0;
}

}
 

fabio93

Utente Attivo
609
173
CPU
AMD Ryzen 5 2400G
Dissipatore
Arctic Alpine64 Plus
Scheda Madre
Gigabyte GA-AX370-Gaming 3
HDD
Crucial MX500 250 GB, Crucial BX500 240 GB
RAM
G.Skill F4-3200C14D-16GFX FlareX 16 GB
Monitor
HP 2010i
PSU
Corsair TX550M
Case
Sharkoon M25-W
Periferiche
Magicforce 68, Logitech G203
OS
Windows 10 Pro, Fedora 31
Occhio che per indicizzare un array bidimensionale (matrice) in c non si usa "a[riga, colonna]" ma "a[riga][colonna]". Il primo comando infatti viene interpretato come "a[colonna]", perché la virgola è interpretata come operatore virgola (per questa ragione non viene sollevato un errore di sintassi, e la compilazione fila liscia).
Per allocare dinamicamente un array bidimensionale ci sono vari modi. Per me i più semplici sono due, ed entrambi usano un puntatore a puntatore a <tipo di dato>. Volendo si può fare anche con un puntatore "semplice" ma poi l'indicizzazione diventa più complessa (con l'aritmetica dei puntatori).
Fondamentalmente il primo metodo consiste nell'allocare lo spazio per le righe e poi, per ciascuna riga, allocare lo spazio per le colonne, ed è quello più intuitivo, secondo me. Il secondo alloca tutte le righe in modo contiguo (spiegazione: http://c-faq.com/aryptr/dynmuldimary.html).
Ecco un'implementazione del primo metodo:
C:
#include<stdio.h>
#include<stdlib.h>

int main()
{
    int **vett;            //allocazione dinamica di una matrice
    int righe,colonne,i,j;

    printf ("inserisci la dimensione delle righe\n");
    scanf ("%d",&righe);

    printf ("inserisci la dimensione delle colonne\n");
    scanf ("%d",&colonne);
   
    // alloca memoria per tanti puntatori quante sono le righe
    vett = malloc(righe * sizeof(int*));
   
    /* per ciascun puntatore, alloca memoria per tanti interi
    /* quante sono le colonne (cioè per quanti interi sono contenuti in una riga) */
    for (i=0;i<righe;i++) {
        vett[i] = malloc(colonne * sizeof(int));
    }

    for(i=0;i<righe;i++) {
        for(j=0;j<colonne;j++) {
            vett[i][j]=33;
        }
    }

    printf("la matrice vett e' la seguente\n");

    for(i=0;i<righe;i++) {
        for(j=0;j<colonne;j++) {
            printf("%5d",vett[i][j]);
        }
        printf("\n");
    }

    // libera la memoria, prima quella puntata da ciascun puntatore "interno"...
    for (i=0;i<righe;i++) {
        free(vett[i]);
    }
    // ... poi quella puntata dal puntatore ai puntatori.
    free(vett);          
    return 0;
}
 

anche_per_il_direttore

Nuovo Utente
63
2
ciao, grazie della risposta, stavo appunto guardando il primo metodo da te indicato che ho trovato su una guida online fatta molto bene, devo solo studiarci un po sopra(tempo permettendo)
 

anche_per_il_direttore

Nuovo Utente
63
2
ok, credo di aver afferrato il concetto di puntatore e vettori di puntatori.
la parte di codice che posto e sempre relativa al problema della creazione di un vettore che rappresenti uno spazio bidimensionale, cerco di spiegarmi.
se devo costruire una funzione z(x,y) ho due strade.
la prima e di costruirla dentro gnuplot (facile risoluzione)
la seconda che vorrei sviluppare e quella di costruire un file dove memorizzare una colonna per le x, una colonna per le y e una colonna per le z(x,y), in pratica le prime due colonne rappresentano i punti di un piano cartesiano.
qualcuno ha qualche idea di come costruire queste due colonne ?
posto un tentativo di costruzione di tale spazio che vorrei cercare di automatizzare.
ecco parte del codice
basta guardare solo il primo ciclo for, i successivi sono identici cambia solo il valore della y, ora l idea e quella di creare un vettore x simmetrico rispetto a 0 (gia fatto)e poi variano la y ottengo lo spazio
in questo caso il primo for rappresenta la retta reale a y=0 che in questo caso si trova nella prima posizione
dovrei manualmente spostarla "nel mezzo delle iterazioni" per ottenere un piano cartesiano centrato su 0, questo posso farlo manualmente
quello che vorrei fare e' ottenere una procedura automatizzata che mi permetta di riportare alle varie quote y il vettore x
un altra soluzione forse piu semplice sarebbe quella di poter estrarre (se possibile) i valori x e y da gnuplot dopo aver creato il grafico ?????????




C:
for (i=0; i<n; i++)       {


x[i]=i-n/2;
y[i]=0;
                   
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));
                   
                          }


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


x[i]=i-n/2;
y[i]=-1;
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));                   
                   
                          }


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


x[i]=i-n/2;
y[i]=-2;
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));                   
                   
                          }
                         
for (i=0; i<n; i++)       {


x[i]=i-n/2;
y[i]=-3;
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));                   
                   
                          }
                         
                         
                         
for (i=0; i<n; i++)       {


x[i]=i-n/2;
y[i]=1;
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));                   
                   
                          }


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


x[i]=i-n/2;
y[i]=2;
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));                   
                   
                          }

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


x[i]=i-n/2;
y[i]=3;
     fprintf(pf,"%d\t%d\t%f\n",x[i],y[i],fn1z(x[i],y[i]));                   
                   
                          }
 

Ci sono discussioni simili a riguardo, dai un'occhiata!

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!

Discussioni Simili