Algoritmul - Numerotarea pentru TOC (Cuprins)

voturi
3

Vreau să pună în aplicare o funcție VBA pentru numărul de rânduri Excel bazate pe adâncimea de grupare a rândului.

Dar cred că un algoritm general pentru generarea TOCuri este mult mai interesant.

Problema este că:

Având în vedere o listă de linii „crestate“, cum ar fi

One
 Two
  Three
   Four
 Five
Six

( „Nivelul de indentare“, se poate presupune că este cunoscută și o parte a datelor de intrare)

Pentru a genera ieșire următoarele:

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

Desigur, codul meu este ascuns sub THWoS în sus și să fie difuzate ... și, de asemenea (Greutatea grea a rușinii)

Întrebat 01/06/2010 la 00:20
sursa de către utilizator
În alte limbi...                            


2 răspunsuri

voturi
8

Utilizați o stivă pentru numere. Buclă prin fiecare rând, și verificați nivelul de indentare fiecărui rând, fără indentare fiind nivelul 1.

  1. Dacă nivelul de indentare curent este mai mare decât dimensiunea împinge stiva cât mai multe altele ca diferența este pe stiva (diferența ar fi, de obicei, doar una, dar acest lucru funcționează chiar dacă cineva pune o poziție de nivel 3 sub un titlu de nivel 1, de exemplu)
  2. Dacă nivelul de indentare actual este mai mică decât dimensiunea de stivă, pop și aruncați cât mai multe numere ca diferența este și apoi incrementat numărul de top de pe stivă.
  3. Dacă nivelul de indentare curent este egal cu mărimea stivei, incrementa numarul de top de pe stivă

Pentru fiecare rând, numărul actual din titlu este numerele de pe stivă concatenate împreună cu un. pentru a le separa.

Notă modul în care dimensiunea stivei reprezintă mînã nivelul de indentare linia precedentă.

Pentru cei care considera ca este mai ușor de citit codul, aici este o punere în aplicare JavaScript pentru browsere moderne:

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;
});

Publicat 01/06/2010 la 00:33
sursa de către utilizator

voturi
2

Acest algoritm presupune că nivelul de indentare nu crește cu mai mult de 1 unitate. Dacă da, atunci trebuie să setați toate nivelurile „omit“ la 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
Publicat 01/06/2010 la 00:42
sursa de către utilizator

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