Newsgroup: it.comp.programmare
Titolo: Aiuto su ciclo for

Salve,
dato il seguente pezzo di codice C++
#include <iostream>
int A[3];
int main() {
        for (A[0] = 1; A[0] <= 3; A[0]++)
            for (A[1] = 1; A[1] <= 3; A[1]++)
                for (A[2] = 1; A[2] <= 3; A[2]++)
                    std::cout << A[0] << " " << A[1] << " " << A[2] <<
std::endl;
        return 0;
}
Sapreste indicarmi un modo per poter accorpare tutto in un unico ciclo for
facendo uso di un solo indice A[i] e gestendo i vari indici dei vari cicli
annidati proprio lavorando con i?
Considerate che ho messo solo 3 cicli annidati per semplicità ma sono alla
ricerca di una soluzione più generale per n cicli for.
Grazie

 annidati proprio lavorando con i?
Supponendo che il limite dei tre cicli sia lo stesso (nell'esempio era 
3) e chiamiamo "n" tale valore, si possono memorizzare tutti gli indici 
come cifre di un numero in base "n". Le cifre cominciano da zero e 
quindi dovrai aggiungere 1 per ottenere i tuoi valori.
Per esempio, la terna di indici (1, 2, 3), corrisponde al numero 
ternario "012", che e' uguale al numero decimale 5.
Il problema e' che occorre estrarre le cifre ternarie dal numero intero.
Ecco un esempio di programma in C++ che usa tale tecnica.
#include <iostream>
using namespace std;
const int n = 3;
int main() {
   // Calcolo del valore massimo (nell'esempio, 3 * 3 * 3 = 27).
   int nn = n;
   for (int j = 1; j < n; ++j) nn *= n;
   for (int i = 0; i < nn; ++i) {
     // Estrazione e stampa della prima cifra.
     int k = i;
     for (int j = 1; j < n; ++j) {
       k /= n;
     }
     std::cout << k % n + 1 << " ";
     // Estrazione e stampa della seconda cifra.
     k = i;
     for (int j = 2; j < n; ++j) {
       k /= n;
     }
     std::cout << k % n + 1 << " ";
     // Estrazione e stampa della terza cifra.
     k = i;
     for (int j = 3; j < n; ++j) {
       k /= n;
     }
     std::cout << k % n + 1 << std::endl;
   }
   return 0;
}
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 Ecco un esempio di programma in C++ che usa tale tecnica.
Stampare quella sequenza di numeri era solo un esempio. A me serve poter
modificare i vari contatori attraverso l'indice in quanto il valore del
contatore devo poterlo anche utilizzare per fare dei confronti.
Ciao

Noixe ha scritto:

Ecco due funzioni valide sia in C che in C++.
La prima estrae una cifra da un numero intero data la posizione a 
partire da 0 e data la base.
Per esempio get_digit(12345, 1, 10) rende 4.
int get_digit(int n, int pos, int base) {
    while (pos) {
       n /= base;
       --pos;
    }
    return n % base;
}
La seconda rende il numero che si ottiene sostituendo in "n" la cifra di 
posizione "pos" con la cifra "digit", usando la base "base".
Per esempio set_digit(12345, 8, 1, 10) rende 12385.
int set_digit(int n, int digit, int pos, int base) {
    int n2 = base;
    while (pos) {
       digit *= base;
       n2 *= base;
       --pos;
    }
    return n / n2 * n2 + digit + n % (n2 / base);


 Ecco due funzioni valide sia in C che in C++.
[cut]
Grazie lo stesso, ma nel post precedente (per certi versi simile a quello
che mi hanno suggerito su i.c.l.c++) il discorso della stampa dei valori
calcolando il modulo mi è servito (ci avevo pensato un po' anche io ma ho
lasciato perdere subito e invece...) e sono riuscito a modificare il tutto
in modo da risolvere il mio problema. In pratica non mi servono estrazioni
di cifre etc... quello che ho postato era solo un esempio che in effetti ha
permesso di risolvere il problema proprio per la sua semplicità e per il
fatto che si basava sulla stampa di numeri. Infatti a me quello che serviva
(e che ho scritto) era un algoritmo per il calcolo delle disposizioni e
combinazioni, semplici e con ripetizioni di n oggetti presi a k a k. Come
dicevo anche io avevo intrapreso la strada del calcolo del modulo ma non
pensavo fosse molto corretta probabilmente perché facevo le mie prova
stampando lettere e mi sono lasciato ingannare. Fortunatamente i vostri due
interventi mi hanno dato l'idea giusta da sviluppare, grazie :)