PDA

View Full Version : [C] Liste con numeri binari


xbubbax
16-08-2007, 09:48
Si scriva una funzione, siete liberi di scegliere il prototipo, somma_binari che dati due numeri binari B1 e B2 costruisca una terza lista B3 con le cifre della somma B1+B1

ad esempio

B1->1->1->0->NULL
B2->0->-0->1->NULL

B3->1->1->1->NULL

come procedereste?

ancora non ho capita come si inizializza una lista, mi fate ad esempio un inizializzazione di B1 e B2 con i numeri dell'esempio?

andbin
16-08-2007, 10:21
ancora non ho capita come si inizializza una lista, mi fate ad esempio un inizializzazione di B1 e B2 con i numeri dell'esempio?Scusa eh ... ma è praticamente la stessa cosa di quanto era stato detto <qui> (http://www.hwupgrade.it/forum/showthread.php?t=1526774). ;)
Cambia solo il tipo di dato.... qui come 'data' avrai solo 0 o 1.

Comunque una cosa che non hai specificato (e che con l'esempio che hai fatto non si capisce): quale è il LSB (least significant bit), il bit meno significativo? Il primo della lista o l'ultimo? Immagino il primo, altrimenti sarebbe un po' un casino.

qwerty86
16-08-2007, 10:25
Si scriva una funzione, siete liberi di scegliere il prototipo, somma_binari che dati due numeri binari B1 e B2 costruisca una terza lista B3 con le cifre della somma B1+B1

ad esempio

B1->1->1->0->NULL
B2->0->-0->1->NULL

B3->1->1->1->NULL

come procedereste?

ancora non ho capita come si inizializza una lista, mi fate ad esempio un inizializzazione di B1 e B2 con i numeri dell'esempio?

Allora prima di tutto devi dichiarare una struct, ossia una struttura o anche record.

typedef struct nodo
{
int numbin;
struct elemento *next;
} B1;


in questo modo hai creato la struttura. Per utilizzarla si fa così :

per creare un nuovo nodo devi allocare spazio in memoria :
newnode = (B1 *) malloc(sizeof(B1));
newnode->next= NULL /* cioè non punta a nessun altro elemento*/

newnode->numbin=1



Per collegare un nuovo nodo a questo creato fai così:

newnode2 = (B1 *) malloc(sizeof(B1));
newnode2->next= NULL /* cioè non punta a nessun altro elemento*/
newnode->next=newnode2
newnode2->numbin=1



Insomma è un pò maccheronico ma il concetto è quello di creare una struttura con due campi. Il primo è il numero binario e l'altro è un puntatore al prossimo elemento. Crei il primo elemento , nel campo numbin inserisci il numero e nel campo next inserisci NULL che serve ad indicare che non c'è un successore. Nel momento in cui crei un nuovo elemento lo colleghi a quello di prima. Poi avresti bisogno di un elemento che ti punta alla testa della lista, in modo da poterla sempre scorrere. Non sono stato forse chiarissimo , ma vado un pò di fretta ciao ciao.

xbubbax
16-08-2007, 10:29
Si, per il bit meno significativo è come dici tu andbin

ora provo a scrivere qualcosa

intanto date un'occhiata qui?

int sommaelementi(int vett[], int n, int min, int max){
if(n>=1){
if((vett[n-1]>=min)&&(vett[n-1]<=max)){
return vett[n-1]+sommaelementi(vett,n-1,min,max);}
else return sommaelementi(vett,n-1,min,max);}}

è una semplice funzione ricorsiva che però mi da come risultato un numero enorme

ad esempio dato un vettore di 6 elementi io devo stampare la somma di tutti gli elementi compresi tra min e max

xbubbax
16-08-2007, 10:36
ho provato a inizializzarla ma non ci riesco proprio, non so perchè, non capisco bene quello che c'è scritto, perciò l'ho richiesto andbin, perchè anche quando me l'hai spiegato tu non ho capito tanto bene

vogliamo partire prima dalla funzione, poi la inizializziamo alla fine la lista

voi come fareste?

qwerty86
16-08-2007, 10:42
Si, per il bit meno significativo è come dici tu andbin

ora provo a scrivere qualcosa

intanto date un'occhiata qui?

int sommaelementi(int vett[], int n, int min, int max){
if(n>=1){
if((vett[n-1]>=min)&&(vett[n-1]<=max)){
return vett[n-1]+sommaelementi(vett,n-1,min,max);}
else return sommaelementi(vett,n-1,min,max);}}

è una semplice funzione ricorsiva che però mi da come risultato un numero enorme

ad esempio dato un vettore di 6 elementi io devo stampare la somma di tutti gli elementi compresi tra min e max

Mha ad occhio sembra essere corretto , hai provato a farti fare un paio di stampe per vedere se somma i valori giusti ?

andbin
16-08-2007, 10:42
intanto date un'occhiata qui?

int sommaelementi(int vett[], int n, int min, int max){
if(n>=1){
if((vett[n-1]>=min)&&(vett[n-1]<=max)){
return vett[n-1]+sommaelementi(vett,n-1,min,max);}
else return sommaelementi(vett,n-1,min,max);}}

è una semplice funzione ricorsiva che però mi da come risultato un numero enormePostare in nuovo thread? E postare codice correttamente indentato?
Comunque è sbagliato, se n = 1 fai la chiamata ricorsiva e quindi n diventa 0. Ma cosa ritorni??? Nulla....

int sommaelementi(int vett[], int n, int min, int max)
{
if (n > 0)
return sommaelementi (vett, n-1, min, max) +
(vett[n-1] >= min && vett[n-1] <= max ? vett[n-1] : 0);
else
return 0;
}

xbubbax
16-08-2007, 10:51
si, mi ero dimenticato l'else return 0, ora funziona


comq l'esercizio sulle liste lo facciamo un'altra volta, voglio prima imparare bene come si inizializzano e fare qualche esercizio sulle strutture, anche se al di là dell'inizializzazione, le liste le so gestire abbastanza bene all'interno delle funzioni

grazie comq

magari posso posso postare i dubbi sugli altri esercizi, per evitare di aprire 10mila thread

xbubbax
16-08-2007, 10:59
Ad esempio questo esercizio sarebbe una cavolata se non fosse per il fatto che devo usare un puntatore a funzione:

Si scriva una funzione che prenda da input una stringa, un intero compreso tra 0 e 2 e un puntatore a funzione.
Se l'intero è 0 la funzione dovrà eliminare le cifre presenti nella stringa e stampare la stringa risultante.
Se l'intero è 1 allora la funzione dovrà invertire la stringa e stampare quella risultante in output
Se l'intero è 2 allora la funzione dovrà sostituire le lettere minuscole della stringa con degli asterischi e stampare la stringa risultante

Ma come si usa un puntatore a funzione? Cioè che significa?

qwerty86
16-08-2007, 11:05
Ad esempio questo esercizio sarebbe una cavolata se non fosse per il fatto che devo usare un puntatore a funzione:

Si scriva una funzione che prenda da input una stringa, un intero compreso tra 0 e 2 e un puntatore a funzione.
Se l'intero è 0 la funzione dovrà eliminare le cifre presenti nella stringa e stampare la stringa risultante.
Se l'intero è 1 allora la funzione dovrà invertire la stringa e stampare quella risultante in output
Se l'intero è 2 allora la funzione dovrà sostituire le lettere minuscole della stringa con degli asterischi e stampare la stringa risultante

Ma come si usa un puntatore a funzione? Cioè che significa?

Ecco un esempio trovato in rete :

/*
2 Mostra l'uso dei puntatori a funzione
3 */
4 #include<stdio.h>
5
6 int sottrazione(int, int);
7 int somma (int, int);
8 int prodotto(int, int);
9 int divisione(int, int);
10
11
12 int main()
13 {
14 int a = 48;
15 int b = 2;
16 int risultato,scelta;
17 int (*puntatore)();
18 for(;;){
19 printf("1\t per la somma\n");
20 printf("2\t per la sottrazione\n");
21 printf("3\t per il prodotto\n");
22 printf("4\t per la divisione\n");
23 printf("0\t per uscire\n");
24
25 scanf("%d", &scelta);
26 switch(scelta){
27 case 1:
28 puntatore = somma;
29 break;
30 case 2:
31 puntatore = sottrazione;
32 break;
33
34 case 3:
35 puntatore = prodotto;
36 break;
37
38 case 4:
39 puntatore = divisione;
40 break;
41 case 0:
42 exit(0);
43
44 }
45
46 risultato = puntatore(a,b);
47 printf("Il risultato vale %d", risultato);
48 break;
49
50 }/* fine for */
51
52 }
53
54 int somma(int a, int b)
55 {
56 return a+b;
57 }
58
59 int sottrazione(int a, int b)
60 {
61 return a-b;
62 }
63
64 int prodotto(int a, int b)
65 {
66 return a*b;
67 }
68
69 int divisione(int a, int b)
70 {
71 return (a/b);
72 }

andbin
16-08-2007, 11:07
Ecco la somma dei bit:
#include <stdio.h>
#include <stdlib.h>

typedef struct bitnode
{
char bit;
struct bitnode *next;
} BITNODE, *PBITNODE, **PPBITNODE;

int BitList_Append (PPBITNODE pproot, char bit)
{
PBITNODE pnode;

if (pproot == NULL)
return 0;

if ((pnode = (PBITNODE) malloc (sizeof (BITNODE))) == NULL)
return 0;

pnode->bit = bit & 1;
pnode->next = NULL;

while (*pproot != NULL)
pproot = &(*pproot)->next;

*pproot = pnode;
return 1;
}

void BitList_Free (PPBITNODE pproot)
{
PBITNODE pnode, next;

if (pproot == NULL)
return;

pnode = *pproot;

while (pnode != NULL)
{
next = pnode->next;
free (pnode);
pnode = next;
}

*pproot = NULL;
}

int BitList_Sum (PBITNODE proot1, PBITNODE proot2, PPBITNODE pproot_out)
{
char carry = 0;

while (proot1 != NULL || proot2 != NULL)
{
if (proot1 != NULL)
{
carry = carry + proot1->bit;
proot1 = proot1->next;
}

if (proot2 != NULL)
{
carry = carry + proot2->bit;
proot2 = proot2->next;
}

if (!BitList_Append (pproot_out, carry))
return 0;

carry >>= 1;
}

if (carry && !BitList_Append (pproot_out, carry))
return 0;

return 1;
}

void BitList_Print (PBITNODE proot)
{
while (proot != NULL)
{
printf ("%d ", proot->bit & 1);
proot = proot->next;
}

printf ("\n");
}


int main (void)
{
PBITNODE proot1 = NULL;
PBITNODE proot2 = NULL;
PBITNODE proot3 = NULL;

BitList_Append (&proot1, 1);
BitList_Append (&proot1, 0);
BitList_Append (&proot1, 1);
BitList_Append (&proot1, 1);

BitList_Append (&proot2, 1);
BitList_Append (&proot2, 0);
BitList_Append (&proot2, 0);
BitList_Append (&proot2, 1);
BitList_Append (&proot2, 0);
BitList_Append (&proot2, 1);

BitList_Sum (proot1, proot2, &proot3);

BitList_Print (proot1);
printf ("+\n");
BitList_Print (proot2);
printf ("=\n");
BitList_Print (proot3);

BitList_Free (&proot1);
BitList_Free (&proot2);
BitList_Free (&proot3);

return 0;
}
Come al solito, per brevità, nel main non ho testato i valori di ritorno delle varie funzioni.

xbubbax
16-08-2007, 11:10
però non devo creare 3 funzioni io

quindi il puntatore lo devo usare solo per immagazzinare il risultato della funzione?


andbin non lo leggo per niente l'esercizio, ci voglio provare io:D se poi non ci riesco prenderò spunto da quello

xbubbax
16-08-2007, 11:25
ho abbozzato qualcosa del genere, ditemi solo se sono sulla giusta strada o se non ho capito come va fatto l'esercizio

#include <stdio.h>
#include <ctype.h>
#define SIZE 10
void funzione(char *stringa, int n, *puntatore);
int main(){

char *stringa[SIZE];
int n;
int *puntatore;

printf("Inserisci una stringa di 9 caratteri:\n");
scanf("%s", stringa);

printf("Inserisci un intero compreso tra 0 e 2:\n");
scanf("%d", &n);

puntatore=funzione(*stringa, n, *puntatore);





void funzione(char *stringa, int n, *puntatore){
int i;
int temp;
int y=n;

if(n=0){
for(;*stringa!='\0';stringa++){
if((*stringa>='0')&&(*stringa<='9')){
*stringa=2;}}}
if(n=1){
for(i=0;i<n/2;i++){
temp=stringa[i];
stringa[i]=stringa[y-1];
stringa[y-1]=temp;}
if(n=2){
for(;*stringa!='\0';stringa++){
if(isupper(*stringa)==1){
*stringa=*;}}}



if(n=0){
while(*stringa!='\0'){
if(*stringa==2){
printf("%c",*stringa);}
stringa++;}}
if(n=1){
return *stringa;}
if(n=2){
return *stringa;}}

cionci
16-08-2007, 15:58
Per favore xbubbax indenta il codice come si deve...te l'avevo già detto e non te l'ho detto solo io, altrimenti è illeggibile !!!

andbin
20-08-2007, 15:48
Dopo qualche giorno di vacanza rieccomi qua. @xbubbax: come è con la somma dei bit?

Volevo giusto fare una precisazione sul mio codice che ho postato. Non so se qualcuno se n'è accorto :D ma ho dimenticato una piccola cosuccia.... :doh:

Proprio il giorno in cui ho postato il codice ma nel pomeriggio, ero all'aeroporto di Parigi e stavo aspettando l'imbarco per Amburgo. Non sapendo cosa fare :fiufiu: , chissà perché mi sono messo a pensare al "carry" (il flag) . Nella funzione BitList_Sum sommo i bit fin quando ce ne sono nei due numeri e questo è corretto. Già ma dopo il while il carry non lo uso .... mentre sarebbe più corretto che se il carry finale è a 1, lo inserisco al fondo della lista per "estendere" il risultato. :muro:

Appena ho un attimo sistemo il codice. EDIT: ho corretto il mio codice sopra.