Ho un elenco di lunghezza variabile in cui gli elementi sono stringhe di lunghezza variabile. Voglio stamparli con (N speculare) / ordinare per colonna.
I punti principali sono:
- Le colonne devono avere una larghezza fissa == i dati più ampi in quella colonna.
- Deve essere il più compatto possibile.
- Il numero di colonne è variabile / indotto dalla larghezza della tela disponibile.
- L'ordine degli articoli dovrebbe non essere riorganizzato.
- (Gli elenchi di articoli stampati su colonna in ordine orizzontale mi disgustano.)
A scelta:
- La distribuzione dovrebbe facoltativamente preferire in basso a sinistra o in alto a destra.
Attualmente lo uso in terminale da bash, C ecc. ma altri usi non sono difficili da immaginare.
Il risultato dei calcoli dovrebbe essere:
- Colonne
- linee
- larghezza di ogni colonna
Come, da questo, si può facilmente stampare i dati in una tabella fissa con colonne.
Domanda principale : esiste un modo elegante per farlo. (Mi ispiro alle riflessioni di Knuth's Computer .)
Il mio attuale approccio è piuttosto semplice. Difficile specificare la domanda senza alcuni dettagli cruenti, quindi eccoci qui:
Esempi di dati
es. (tramite l'indice dell'array di stringhe):
0 4 8 12 or 0 4 8 12 or 0 3 6 9 12 15
1 5 9 13 1 5 9 13 1 4 7 10 13
2 6 10 14 2 6 10 2 5 8 11 14
3 7 11 15 3 7 11
favouring lower left favouring upper right
0 4 8 12 0 4 8 11
1 5 9 13 1 5 9 12
2 6 10 2 6 10 13
3 7 11 3 7
es. (per dati - output effettivo):
0) Item number 00000 4) Item Number 04 8) Item Number 008 12) Item Number 00012
1) Item Number 00001 5) Item Number 5 9) Item Number 00009 13) Item Number 0013
2) Item Number 02 6) Item Number 00000006 10) Item Number 10
3) Item Number 003 7) Item Number 7 11) Item Number 11
Implementazione corrente
A partire da ora lo faccio da (circa) ad es. in bash:
- Aggiunta della lunghezza di ogni elemento all'array
lens
e traccia% elemento% ch_de%. - Aggiungi larghezza per il numero + 1 per
longest
+ 1 per)
aspace
elemento. - Calcola le colonne massime in base alla larghezza.
- Ricalcolo della larghezza del numero dell'articolo (quello prima
longest
nella stampa.) per ogni colonna. - Calcolo della larghezza effettiva più lunga per gli articoli in ogni colonna.
-
Re-calcolo:
while 'lines' > 1 ; do * Available width = Canvas width - total print width * Test: Find longest item in last column as if columns was increased by 1. * If longest_in_last_column_test < available width increase columns by 1. recalculate all column widths. Else break End If done
-
Stampa elenco.
Pensieri
Non posso aiutare, ma mi chiedo se ci sia un modo per calcolarlo con altri mezzi. Per esempio. usando la matematica a matrice, - o forse un buon algoritmo là fuori.
Forse difficile in bash, ma in C da puntatori a struct o linguaggi correlati agli oggetti.
Exempli gratia:
struct item {
int len;
char *val;
}
struct item items = {{5, "Hello"}, {3, "You"}, ...}
Quale darebbe una matrice tipicamente
# index:length
0:5 1:2 2:1 3:3 4:5
5:2 6:6 7:9 8:1 9:6
Quindi avendo il vincolo di somma di ogni riga di < = larghezza disponibile, ad es. 25, riorganizzare la matrice.
longest: 5 5 9 6 => sum 25
--------------------------
5 3 6 1 => sum 15
5 5 9 6 => sum 25
1 2 1 => sum 4