[C] l-cicli potenza
Salve ragazzi , sto cercando di implementare un programma puramente algebrico. Vi spiego , sto cercando di implementare un programma che dato in input un $l-ciclo$ del tipo $\sigma=(1,2,....n)$ mi calcoli $\sigma^i$ con $i$ un intero.
Quello che sono riuscito a fare è questo
Ottengo i seguenti errori.
Se inserisco un $n>l$ mi si generano numeri a caso... come risolvo ciò?
Se inserisco un $n$ divisore di $l$ mi viene una sequenza del tipo $a_l , a_(l+1) , a_l , a_(l+1) $...
mi spiego, di norma , ad esempio se ho $(1,2,3,4)$
$(1,2,3,4)^2=(1,3)(2,4)$ ma il codice mi stampa $1 3 1 3$ , come posso correggere ciò?
potete darmi un piccolo hint?
grazie di cuore, arrivederci
Quello che sono riuscito a fare è questo
/* Potenza l-ciclo */
#include <stdio.h>
main()
{
int l;
do {
printf("Inserisci lunghezza del ciclo\n");
scanf("%d",&l);
int ci[l];
int i=0;
while (i<l) {
printf("inserisci il termine %d\n", i+1 );
scanf("%d",&ci[i]);
++i;}
int n;
int j=0;
int count=0;
printf("\nInserisci indice di potenza\n");
scanf("%d",&n);
while (count!=l) {
printf("%d\t",ci[j]);
if (j<n) j=j+n; else j=(j+n)%l;
++count;
} } while (l!=0);
}
Ottengo i seguenti errori.
Se inserisco un $n>l$ mi si generano numeri a caso... come risolvo ciò?
Se inserisco un $n$ divisore di $l$ mi viene una sequenza del tipo $a_l , a_(l+1) , a_l , a_(l+1) $...
mi spiego, di norma , ad esempio se ho $(1,2,3,4)$
$(1,2,3,4)^2=(1,3)(2,4)$ ma il codice mi stampa $1 3 1 3$ , come posso correggere ciò?
potete darmi un piccolo hint?
grazie di cuore, arrivederci
Risposte
Un problema è in questo controllo
Anche se j < n, j + n è sicuramente maggiore di n, che è maggiore di l. Quindi alla prossima iterazione j è oltre la fine dell'array. Un controllo più corretto sarebbe
Ma a questo punto tanto vale risparmiare il controllo è fare semplicemente
Il fatto che ti esca 1313 invece è proprio per la proprietà dei gruppi ciclici. Nel tuo esempio, 1² = 3 e 3² = 1, e nel ciclo applichi solo l'operazione ()², quindi se parti da 1 o 3 non visiterai altri elementi.
Potresti, una volta che completi un sottociclo, far ripartire l'operazione dall'elemento successivo. Qualcosa di simile:
numero_cicli e lunghezza_ciclo dovresti ricavarli dalle proprietà dei gruppi ciclici. Altrimenti impostali entrambi a l, ci saranno delle ripetizioni ma avrai comunque tutti i cicli.
P.S.
Cicli del tipo
che hai usato un paio di volte (nella popolazione dell'array e nel calcolo dei sottocicli), sono più chiari usando cicli for:
Cicli while dovrebbero essere usati quando non sai a priori quante iterazioni farai, cicli for se invece hai questa informazione. Inoltre con il ciclo for è possibile dichiarare la variabile di iterazione (i) dentro il ciclo (cioè nella sua intestazione). In questo modo tale variabile esiste solo all'interno del ciclo, e questo riduce possibilità di errori.
if (j < n)
j = j + n;
else
j = (j + n) % l;Anche se j < n, j + n è sicuramente maggiore di n, che è maggiore di l. Quindi alla prossima iterazione j è oltre la fine dell'array. Un controllo più corretto sarebbe
if (j + n < l)
j = j + n;
else
j = (j + n) % l;Ma a questo punto tanto vale risparmiare il controllo è fare semplicemente
j = (j + n) % l;
Il fatto che ti esca 1313 invece è proprio per la proprietà dei gruppi ciclici. Nel tuo esempio, 1² = 3 e 3² = 1, e nel ciclo applichi solo l'operazione ()², quindi se parti da 1 o 3 non visiterai altri elementi.
Potresti, una volta che completi un sottociclo, far ripartire l'operazione dall'elemento successivo. Qualcosa di simile:
for (int k = 0; k < numero_cicli; ++k) {
int j = k; // Parti da elementi successivi
printf("Ciclo %d:\t", k + 1);
for (int count = 0; count < lunghezza_ciclo; ++count) {
printf("%d\t", ci[j]);
j = (j + n) % l;
}
puts("");
}numero_cicli e lunghezza_ciclo dovresti ricavarli dalle proprietà dei gruppi ciclici. Altrimenti impostali entrambi a l, ci saranno delle ripetizioni ma avrai comunque tutti i cicli.
P.S.
Cicli del tipo
int i = 0;
while (i < l) {
// Codice vario
++i;
}che hai usato un paio di volte (nella popolazione dell'array e nel calcolo dei sottocicli), sono più chiari usando cicli for:
for (int i = 0; i < l; ++i) {
// Codice vario
}Cicli while dovrebbero essere usati quando non sai a priori quante iterazioni farai, cicli for se invece hai questa informazione. Inoltre con il ciclo for è possibile dichiarare la variabile di iterazione (i) dentro il ciclo (cioè nella sua intestazione). In questo modo tale variabile esiste solo all'interno del ciclo, e questo riduce possibilità di errori.
grazie claudio, cercherò di aggiustarlo quanto prima. Grazie mille