Αλγόριθμος - Αρίθμηση για TOC (Πίνακας Περιεχομένων)

ψήφοι
3

Θέλω να εφαρμόσουν μια συνάρτηση VBA σε αριθμό γραμμών Excel με βάση το βάθος ομαδοποίηση της σειράς.

Αλλά νομίζω ότι ένας γενικός αλγόριθμος για τη δημιουργία TOCs είναι πιο ενδιαφέρουσα.

Το ΠΡΟΒΛΗΜΑ ΕΙΝΑΙ:

Λαμβάνοντας υπόψη μια λίστα των «δαντελωτές» γραμμές, όπως

One
 Two
  Three
   Four
 Five
Six

(Η «επίπεδο εσοχής» μπορεί να υποτεθεί να είναι γνωστό και μέρος των δεδομένων εισόδου)

Για να δημιουργήσετε το ακόλουθο αποτέλεσμα:

1.    One
1.1    Two
1.1.1   Three
1.1.1.1  Four
1.2    Five
2.    Six

Φυσικά κωδικός μου είναι σε πλήρη λειτουργία ... και κρυμμένα κάτω από THWoS (του μεγάλου βάρους της ντροπής)

Δημοσιεύθηκε 01/06/2010 στις 00:20
πηγή χρήστη
Σε άλλες γλώσσες...                            


2 απαντήσεις

ψήφοι
8

Χρησιμοποιήστε μια στοίβα για τους αριθμούς. Βρόχο μέσω κάθε σειρά, και ελέγξτε το επίπεδο εσοχής της κάθε σειράς, χωρίς οδόντωση να είναι επίπεδο 1.

  1. Εάν το τρέχον επίπεδο εσοχής είναι μεγαλύτερο από το μέγεθος της στοίβας ώθηση όσες αυτά η διαφορά είναι πάνω στη στοίβα (η διαφορά θα είναι συνήθως μόνο ένα, αλλά αυτό λειτουργεί ακόμα και αν κάποιος βάζει μια επικεφαλίδα επιπέδου 3 σε κλάση επίπεδο 1, για παράδειγμα)
  2. Εάν το τρέχον επίπεδο εσοχής είναι μικρότερο από το μέγεθος της στοίβας, ποπ και απορρίψτε όσους αριθμούς η διαφορά είναι και στη συνέχεια να αυξήσετε την κορυφή αριθμό στη στοίβα.
  3. Εάν το τρέχον επίπεδο εσοχής είναι ίσο με το μέγεθος της στοίβας, αυξάνει την κορυφή αριθμό στη στοίβα

Για κάθε σειρά, ο τρέχων αριθμός τίτλου είναι οι αριθμοί στη στοίβα συνεχόμενα μαζί με. να τους χωρίσει.

Σημειώστε πως το μέγεθος της στοίβας αντιπροσωπεύει επιδέξια επίπεδο εσοχής της προηγούμενης γραμμής.

Για τους ανθρώπους που είναι ευκολότερο να διαβάσει κώδικα, εδώ είναι μια εφαρμογή την Javascript για τα σύγχρονα προγράμματα περιήγησης:

const toc = `
One
 Two
  Three
   Four
 Five
  Six
  Seven
 Eight
Nine
Ten
`;

let stack = [];

toc.trim().split(/\n/g).forEach(line => {
  // Gets the identitation level with 1 being no indentation and so forth
  let level = line.match(/^\s*/)[0].length + 1;

  if (level > stack.length) {
    while (level > stack.length)
      stack.push(1);
  } else {
    while (level < stack.length)
      stack.pop();

    stack[stack.length - 1]++;
  }
  
  let title = stack.join(".") + ". " + line.trim();

  document.body.appendChild(document.createElement("div")).innerText = title;
});

Απαντήθηκε 01/06/2010 στις 00:33
πηγή χρήστη

ψήφοι
2

Αυτός ο αλγόριθμος υποθέτει ότι το επίπεδο εσοχής ποτέ δεν αυξάνεται κατά περισσότερο από 1 μονάδα. Αν το κάνει, τότε θα πρέπει να ορίσετε όλα τα επίπεδα «υπερπήδηση» στο 1.

#use a vector instead, if your language supports it
numbering = {0, 0, 0, 0, 0, 0, 0}

for line in lines:
    level = indentLevel(line) #starting from 0

    numbering[level] = numbering[level] + 1
    numbering[level + 1] = 0 #create it if it doesn't exist
    for n = 0 to level - 1
        print numbering[n], ".",
    print numbering[level], " ", line
Απαντήθηκε 01/06/2010 στις 00:42
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more