[C++]algoritmo output su colonne
MI si chiede di fare un programma che scriva in output il calendario di un mese ,sul modello dei calendari da tavolo di questo tipo: http://www.google.it/imgres?q=calendari ... 2,s:0,i:75
L'utente immette il giorno della settimana corrispondente al primo del mese(lunedì=0 … domenica=6) e la lunghezza del mese (28-31).
Bisogna disporre i giorni una colonna alla volta in una griglia di 7 righe, la prima per i lunedì, l'ultima per le domeniche(come nell'immagine del link).Il tutto si deve fare con due cicli for annidati, senza vector o matrici.
Dunque, tralasciando la parte in cui l'utente fissa i parametri del mese,è proprio la disposizione in griglia che non mi riesce.
Non so neanche partire,cioè:una volta ad esempio che l'utente ha scelto giovedì per esempio come primo giorno del mese(quindi 3) come faccio a far venire il numero 1 nella griglia in posizione giusta...
L'unica cosa che mi viene in mente è che la stampa dei numeri non deve essere fatta in ordine colonna per colonna(cioè stampo prima tutta la prima colonna,poi la seconda e così via...),ma per ogni posizione della griglia devo calcolare il valore che ci va messo in base appunto ad un algoritmo che non mi viene in mente...
L'utente immette il giorno della settimana corrispondente al primo del mese(lunedì=0 … domenica=6) e la lunghezza del mese (28-31).
Bisogna disporre i giorni una colonna alla volta in una griglia di 7 righe, la prima per i lunedì, l'ultima per le domeniche(come nell'immagine del link).Il tutto si deve fare con due cicli for annidati, senza vector o matrici.
Dunque, tralasciando la parte in cui l'utente fissa i parametri del mese,è proprio la disposizione in griglia che non mi riesce.
Non so neanche partire,cioè:una volta ad esempio che l'utente ha scelto giovedì per esempio come primo giorno del mese(quindi 3) come faccio a far venire il numero 1 nella griglia in posizione giusta...

L'unica cosa che mi viene in mente è che la stampa dei numeri non deve essere fatta in ordine colonna per colonna(cioè stampo prima tutta la prima colonna,poi la seconda e così via...),ma per ogni posizione della griglia devo calcolare il valore che ci va messo in base appunto ad un algoritmo che non mi viene in mente...
Risposte
Devi per forza stampare una riga alla volta, quindi devi trovare il modo di capire quali giorni stampare conoscendo il numero di riga corrente.
Alla riga i=0 stai stampando i Lunedì del mese. Se il mese comincia con un Lunedì allora dovrai stampare 0, 7, 14, 21, 28.
Alla riga i=1 stai stampando i Martedì del mese. Se il mese comincia con un Lunedì allora dovrai stampare 1, 8, 15, 22, 29.
E così via.
Quindi parti da i e aggiungi 7, finché non superi il numero di giorni nel mese.
Se il mese non comincia per Lunedì è un po' più complicato. I giorni sono sempre distanti 7, però non partono da i, ma da i - il primo giorno.
Quindi se il primo giorno è Mercoledì (== 2), allora i Lunedì partono da -2 e sono: -2, 5, 12, 19, 26.
I Martedì partono da -1 e sono: -1, 6, 13, 20, 27.
I Mercoledì partono da 0 e sono: 0, 7, 14, 21, 28.
E così via.
Ovviamente al posto dei giorni negativi devi stampare uno spazio vuoto.
Un'alternativa è controllare ad ogni riga se l'indice di partenza del ciclo più interno è negativo, nel caso stampare uno spazio vuoto ed aggiungere 7. È un po' meglio perché sposta l'if dal ciclo più interno a quello più esterno, però potrebbe essere meno chiaro.
Alla riga i=0 stai stampando i Lunedì del mese. Se il mese comincia con un Lunedì allora dovrai stampare 0, 7, 14, 21, 28.
Alla riga i=1 stai stampando i Martedì del mese. Se il mese comincia con un Lunedì allora dovrai stampare 1, 8, 15, 22, 29.
E così via.
Quindi parti da i e aggiungi 7, finché non superi il numero di giorni nel mese.
Se il mese non comincia per Lunedì è un po' più complicato. I giorni sono sempre distanti 7, però non partono da i, ma da i - il primo giorno.
Quindi se il primo giorno è Mercoledì (== 2), allora i Lunedì partono da -2 e sono: -2, 5, 12, 19, 26.
I Martedì partono da -1 e sono: -1, 6, 13, 20, 27.
I Mercoledì partono da 0 e sono: 0, 7, 14, 21, 28.
E così via.
Ovviamente al posto dei giorni negativi devi stampare uno spazio vuoto.
#include <iostream> #include <string> #include <iomanip> void printCalendar(int days, int firstDay, std::ostream & stream) { const std::string dayNames[7] = {"Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"}; const int maxDayNameSize = 10; // Ciclo sulle righe. for (int i = 0; i < 7; ++i) { stream << std::setw(maxDayNameSize + 1) << std::left << dayNames[i] << '\t'; // Ciclo sulle colonne della riga i. j avanza di 7 ad ogni colonna. // Se firstDay == 2 per le prime due righe j viene inizializzato a // -2 e -1, e non verrà stampato nella prima colonna. for (int j = i - firstDay; j < days; j += 7) { if (j >= 0) { stream << j + 1; // Togli il +1 se vuoi partire da 0. } stream << '\t'; } stream << '\n'; } } int main() { for (int i = 0; i < 7; ++i) { printCalendar(30, i, std::cout); std::cout << '\n'; } }
Un'alternativa è controllare ad ogni riga se l'indice di partenza del ciclo più interno è negativo, nel caso stampare uno spazio vuoto ed aggiungere 7. È un po' meglio perché sposta l'if dal ciclo più interno a quello più esterno, però potrebbe essere meno chiaro.
void printCalendar(int days, int firstDay, std::ostream & stream) { const std::string dayNames[7] = {"Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato", "Domenica"}; const int maxDayNameSize = 10; // Ciclo sulle righe. for (int i = 0; i < 7; ++i) { stream << std::setw(maxDayNameSize + 1) << std::left << dayNames[i] << '\t'; // Se il giorno di partenza è negativo stampa uno spazio vuoto ed // aggiungi 7. int start = i - firstDay; if (start < 0) { stream << '\t'; start += 7; } // Ciclo sulle colonne della riga i. j avanza di 7 ad ogni colonna. // start è sempre positivo, ed eventuali spazi vuoti sono già stati // stampati. for (int j = start; j < days; j += 7) { stream << j + 1; stream << '\t'; } stream << '\n'; } }
Chiarissimo,grazie!!!
Mi stavo scervellando per creare una applicazione per la creazione di calendari da tavolo e non ero ancora riuscito a capire come fare. Grazie mille per questo post, davvero utilissimo, grazie.
"Mifert4":
L'utente immette il giorno della settimana corrispondente al primo del mese(lunedì=0 … domenica=6) e la lunghezza del mese (28-31).
a me non piace che l'utente debba dirti quale è il primo giorno della settimana del mese ed il numero dei giorni.
Mi sembra più semplice immettere il mese/anno che si intenda stampare...(...sarà il programma che farà il conteggio...)
@Umby: Era chiaramente un esercizio universitario con lo scopo di insegnare a lavorare con i cicli. Sono certamente d'accordo che sarebbe stato più utile un calendario come da te descritto, ma sarebbe stato un esercizio con scopi un po' diversi.