- Messaggi: 6
- Ringraziamenti ricevuti 0
LINUX AVANZATO 2007
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
18 Anni 2 Mesi fa #53259
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic LINUX AVANZATO 2007
il compito del 14/09/2007:
Scrivere un progrmma che costruisce una lista bidirezionale di N elementi del seguente tipo:
struct elemento {
struct list_head lh;
int valore;
};
N è passato tramite riga di comando. L'area di memoria richiesta per contenere un nuovo elemento è ottenuta facendo uso
della funzione malloc(); I puntatori della lista bidirezionale sono realizzati dalla seguente struttura:
struct list_head {
struct list_head *next;
struct list_head *prev;
};
Il valore di ogni elemento della lista è un numero casuale compreso tra 1 e 100. Dopo aver costruito la lista, il programma
stampa i valori degli elementi a partire dall'inizio della lista. Il programma effettua quindi un riordinamento per valori crescenti degli elementi della lista e stampa a partire dall'inizio della lista i valori degli elemnenti della lista ordinata.
Scrivere un progrmma che costruisce una lista bidirezionale di N elementi del seguente tipo:
struct elemento {
struct list_head lh;
int valore;
};
N è passato tramite riga di comando. L'area di memoria richiesta per contenere un nuovo elemento è ottenuta facendo uso
della funzione malloc(); I puntatori della lista bidirezionale sono realizzati dalla seguente struttura:
struct list_head {
struct list_head *next;
struct list_head *prev;
};
Il valore di ogni elemento della lista è un numero casuale compreso tra 1 e 100. Dopo aver costruito la lista, il programma
stampa i valori degli elementi a partire dall'inizio della lista. Il programma effettua quindi un riordinamento per valori crescenti degli elementi della lista e stampa a partire dall'inizio della lista i valori degli elemnenti della lista ordinata.
Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
18 Anni 2 Mesi fa #53274
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic LINUX AVANZATO 2007
Ciao,
Qualcuno mi può far vedere il codice di questo compito?
Grazie,
Daniele
Qualcuno mi può far vedere il codice di questo compito?
Grazie,
Daniele
Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
18 Anni 2 Mesi fa #53276
da COM_EASYSOCIAL_GUEST_NAME
Così è come l'ho fatto io. Sembra funzionare
Allora alla fine sia la lista originale che quella ordinata sono circolari quindi potete farci fare tutti i giri che volete. Se sapete suggerire delle ottimizzazione al codice ben vengano.
Per dubbi postate pure
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic LINUX AVANZATO 2007
/* ****************************************
Scrivere un progrmma che costruisce una lista bidirezionale di N elementi del seguente tipo:
Elemento {
struct list_head lh;
int valore;
};
N è passato tramite riga di comando. L'area di memoria richiesta per contenere un nuovo elemento è ottenuta facendo uso
della funzione malloc(); I puntatori della lista bidirezionale sono realizzati dalla seguente struttura:
struct list_head {
struct list_head *next;
struct list_head *prev;
};
Il valore di ogni elemento della lista è un numero casuale compreso tra 1 e 100. Dopo aver costruito la lista, il programma
stampa i valori degli elementi a partire dall'inizio della lista. Il programma effettua quindi un riordinamento per valori crescenti degli elementi della lista e stampa a partire dall'inizio della lista i valori degli elemnenti della lista ordinata.
******************************************* */
#include<stdio.h>
#include<stdlib.h>
struct head_li {
struct head_li *next;
struct head_li *prev;
};
struct elem {
struct head_li li;
int val;
};
typedef struct elem Elem;
typedef struct head_li Head;
Elem* list_add(Elem* list) {
Elem* temp;
if(list == NULL) {
list = (Elem*)malloc(sizeof(Elem));
list->li.prev = NULL;
list->val = rand()%100;
list->li.next = NULL;
return list;
}
list->li.next = malloc(sizeof(Elem));
temp = list;
list = (Elem*)list->li.next;
list->val = rand()%100;
list->li.prev = (Head*)temp;
list->li.next = NULL;
temp = (Elem*)list->li.prev;
return list;
}
Elem* list_add_e(Elem* list,Elem* e) {
Elem* temp;
if(list == NULL) {
list = malloc(sizeof(Elem));
list->li.prev = NULL;
list->val = e->val;
list->li.next = NULL;
return list;
}
list->li.next = malloc(sizeof(Elem));
temp = list;
list = (Elem*)list->li.next;
list->val = e->val;
list->li.prev = (Head*)temp;
list->li.next = NULL;
temp = (Elem*)list->li.prev;
return list;
}
Elem* minimo(Elem* list, int N) {
Elem* min = list;
Elem* f = (Elem*)list->li.next;
int m = list->val;
int i;
for(i=1; i<N; i++) {
if(f->val <= m && f->val>0 || m == -1) {
m = f->val;
min = f;
}
f = (Elem*)f->li.next;
}
return min;
}
Elem* ordina_lista(Elem* list, int N) {
Elem *ordinata, *f;
Elem *min;
int i;
for(i=0; i<N; i++) {
min = minimo(list,N);
printf("min: %i\n",min->val);
ordinata = list_add_e(ordinata,min);
if(i==0) {
f = ordinata;
}
min->val = -1;
}
f->li.prev = (Head*)ordinata;
ordinata->li.next = (Head*)f;
/* stampa lista ordinata */
i=0;
while(i<N) {
Elem* t;
t = (Elem*)f->li.prev;
printf("[O] %i\t%i\n",f->val,(t==NULL)?-3:t->val);
f = (Elem*)(f->li.next);
i++;
}
}
int main(int args, char* argv[]) {
Elem *e,*f,*l;
int i;
int N;
if(args<2) {
printf("Usage: %s <N>\n",argv[0]);
exit(0);
}
N = atoi(argv[1]);
if(N<1) {
printf("Inserire un valore di N > 1\n");
exit(1);
}
e = NULL;
for(i=0;i<N;i++) {
e = list_add(e);
if(i==0)
f = e;
}
f->li.prev = (Head*)e;
e->li.next = (Head*)f;
i=0;
while(i<N) {
Elem* t;
t = (Elem*)f->li.prev;
printf("[L] %i\t%i\n",f->val,(t==NULL)?-1:t->val);
f = (Elem*)(f->li.next);
i++;
}
ordina_lista(f,N);
}Così è come l'ho fatto io. Sembra funzionare
Allora alla fine sia la lista originale che quella ordinata sono circolari quindi potete farci fare tutti i giri che volete. Se sapete suggerire delle ottimizzazione al codice ben vengano.
Per dubbi postate pure
Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
18 Anni 2 Mesi fa #53286
da COM_EASYSOCIAL_GUEST_NAME
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic LINUX AVANZATO 2007
Ecco la mia soluzione. Ci ho messo un'ora esatta, però già avevo letto e capito il testo ieri... 
/*
Prova di programmazione del 14/09/2007:
Scrivere un programma che costruisce una lista bidirezionale di N elementi del seguente tipo:
struct elemento {
struct list_head lh;
int valore;
};
N è passato tramite riga di comando. L'area di memoria richiesta per contenere un nuovo elemento è ottenuta facendo uso
della funzione malloc(); I puntatori della lista bidirezionale sono realizzati dalla seguente struttura:
struct list_head {
struct list_head *next;
struct list_head *prev;
};
Il valore di ogni elemento della lista è un numero casuale compreso tra 1 e 100. Dopo aver costruito la lista, il programma
stampa i valori degli elementi a partire dall'inizio della lista. Il programma effettua quindi un riordinamento per valori crescenti degli elementi della lista e stampa a partire dall'inizio della lista i valori degli elemnenti della lista ordinata.
*/
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
struct list_head {
struct list_head *next;
struct list_head *prev;
};
struct elemento {
struct list_head lh;
int valore;
};
struct list_head* genera_lista(int N);
void stampa_lista(struct list_head *lista, int N);
struct list_head* ordina_lista(struct list_head *lista);
/* MAIN */
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("Usage: %s <N>", argv[0]);
exit(1);
}
int N = atoi(argv[1]);
struct list_head *lista = NULL;
srand(time(NULL));
/* costruisco la lista */
lista = genera_lista(N);
/* stampa lista */
stampa_lista(lista, N);
/* ordina lista */
lista = ordina_lista(lista);
/* stampa lista */
stampa_lista(lista, N);
return 0;
}
/* genera la lista bidirezionale circolare lunga N con valori random */
struct list_head* genera_lista(int N) {
struct list_head* last = NULL;
struct list_head* first = NULL;
struct elemento* elem = NULL;
if (N == 0) return NULL;
elem = (struct elemento*)malloc(sizeof(struct elemento));
elem->valore = rand()%100 + 1;
last = (struct list_head*)elem;
first = last;
(elem->lh).next = first;
(elem->lh).prev = last;
N--;
while (N > 0) {
elem = (struct elemento*)malloc(sizeof(struct elemento));
elem->valore = rand()%100 + 1;
(elem->lh).next = first;
(elem->lh).prev = last;
last->next = (struct list_head*)elem;
last = last->next;
N--;
}
return first;
}
/* stampa la lista circolare lunga N */
void stampa_lista(struct list_head *lista, int N) {
struct list_head* l = lista;
if (l == NULL) return;
while (N > 0) {
printf("%d -> ", ((struct elemento*)l)->valore);
l = l->next;
N--;
}
printf("\n\n");
}
/* una sorta di selection sort */
struct list_head* ordina_lista(struct list_head *lista) {
struct list_head* l = lista;
struct elemento* elem1 = NULL;
struct elemento* elem2 = NULL;
int numswap = 0;
int temp;
while(1) {
elem1 = (struct elemento*)l;
elem2 = (struct elemento*)(l->next);
if (elem1->valore > elem2->valore) { /* scambio solo il valore */
temp = elem1->valore;
elem1->valore = elem2->valore;
elem2->valore = temp;
numswap++;
}
l = l->next;
if (l->next == lista) {
if (numswap == 0) break; /* lista ordinata */
numswap = 0;
l = l->next;
}
}
return lista;
}Si prega Accedi o Crea un account a partecipare alla conversazione.
- martina inn
-
- Offline
- New Member
-
Riduci
Di più
18 Anni 2 Mesi fa #53289
da martina inn
Risposta da martina inn al topic LINUX AVANZATO 2007
Ecco la mia soluzione. Per risalire dall'indirizzo della struct list_head a quello della relativa struct elemento ho usato il costrutto della container_of() di Linux...
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MIN_VAL 1
#define MAX_VAL 100
typedef struct list_head {
struct list_head *next, *prev;
} list_head;
typedef struct elemento {
list_head lh;
int valore;
} elemento;
void add(elemento **lista, int elem)
{
elemento *new, *app1, *app2;
list_head *temp;
new = (elemento *) malloc(sizeof(elemento));
new->valore = elem;
new->lh.next = NULL;
new->lh.prev = NULL;
if(*lista == NULL)
{
*lista = new;
}
else
{
app1 = app2 = *lista;
while(app1->lh.next != NULL)
{
temp = app1->lh.next;
app1 = (elemento *) ((char *) temp - ((size_t)&((elemento *)0)->lh));
app2 = app1;
}
app1 = new;
app2->lh.next = &(new->lh);
app1->lh.prev = &(app2->lh);
}
}
void stampa(char *label, elemento *lista)
{
printf("%s -> : ", label);
if(lista != NULL)
{
printf("%d ", lista->valore);
while(lista->lh.next != NULL)
{
lista = (elemento *) ((char *) lista->lh.next - ((size_t)&((elemento *)0)->lh));
printf("%d ", lista->valore);
}
printf("\n");
}
printf("%s <- : ", label);
if(lista != NULL)
{
printf("%d ", lista->valore);
while(lista->lh.prev != NULL)
{
lista = (elemento *) ((char *) lista->lh.prev - ((size_t)&((elemento *)0)->lh));
printf("%d ", lista->valore);
}
printf("\n");
}
}
void sort(elemento **lista, int N)
{
elemento *temp, *elem1, *elem2;
int i, app;
for(i = 0; i < (N-1); i++)
{
temp = *lista;
while(temp->lh.next != NULL)
{
elem1 = (elemento *) ((char *) &(temp->lh) - ((size_t)&((elemento *)0)->lh));
elem2 = (elemento *) ((char *) temp->lh.next - ((size_t)&((elemento *)0)->lh));
if (elem1->valore > elem2->valore) {
app = elem1->valore;
elem1->valore = elem2->valore;
elem2->valore = app;
}
temp = (elemento *) ((char *) temp->lh.next - ((size_t)&((elemento *)0)->lh));
}
}
}
int main(int argc, char *argv[])
{
elemento *lista = NULL;
char *label;
int i, N, r;
if(argc != 2)
{
fprintf(stderr, "Uso: %s <N>\n", argv[0]);
exit(EXIT_FAILURE);
}
N = atoi(argv[1]);
if(N < 1) {
fprintf(stderr, "Inserire un valore di N maggiore (o uguale) a 1\n");
exit(EXIT_FAILURE);
}
srand(time(0));
for(i = 0; i < N; i++)
{
r = rand() % MAX_VAL + MIN_VAL;
printf("Genero il numero casuale %d\n", r);
add(&lista, r);
}
label = "Lista";
stampa(label, lista);
sort(&lista, N);
label = "Lista ordinata";
stampa(label, lista);
return 0;
}Si prega Accedi o Crea un account a partecipare alla conversazione.
- COM_EASYSOCIAL_GUEST_NAME
-
- Visitatori
-
18 Anni 2 Mesi fa #53308
da COM_EASYSOCIAL_GUEST_NAME
ho l'ho fatto cosi ...
Risposta da COM_EASYSOCIAL_GUEST_NAME al topic LINUX AVANZATO 2007
#include <stdio.h>
#include <stdlib.h>
struct list_head {
struct list_head *next;
struct list_head *prev;
}typedef list_head;
struct elemento {
struct list_head lh;
int valore;
}typedef elemento;
elemento *crealista(int);
void stampalista(elemento *);
void ordinalista(elemento * );
int main (int argc, char const* argv[]){
int n;
if(argc < 2 ){
printf("errore nel passaggio dei parametri\n");
exit(1);
}
n = atoi(argv[1]);
elemento *testa;
testa = crealista(n);
stampalista(testa);
ordinalista(testa);
stampalista(testa);
return 0;
}
elemento *crealista(int n){
int i;
elemento *r,*p,*q;
r=(elemento *)malloc(sizeof(elemento));
r->valore=-1;
r->lh.prev=NULL;
p=r;
for( i = 0; i < n; i += 1 ){
p->lh.next = (list_head*)malloc(sizeof(elemento));
q =(elemento*) p->lh.next;
q->valore = rand() % n;
q->lh.prev =(list_head*) p;
p = q;
}
q->lh.next =NULL;
return r;
}
void stampalista(elemento *r){
elemento *p;
int i ;
p=r;
printf("stampa della lista\n");
while( p != NULL){
printf("-> %d\n", p->valore );
p=(elemento*)p->lh.next;
}
}
void ordinalista(elemento *r){
elemento *p,*q;
int tmp;
int flag = 0 ;
p=r;
while(p!=NULL){
q=(elemento*)p->lh.next;
if( (q!=NULL) && (p->valore > q->valore) ){
tmp = q->valore;
q->valore = p->valore;
p->valore = tmp;
flag=1;
}
p=(elemento*)p->lh.next;
}
if(flag)
ordinalista(r);
}Si prega Accedi o Crea un account a partecipare alla conversazione.