Algoritmus - číslování pro TOC (Obsah)

hlasů
3

Chci implementovat funkci VBA pro Excel počet řad založených na hloubce seskupení řady.

Ale myslím, že obecný algoritmus pro generování TOC je mnohem zajímavější.

Problém je v tom:

Vzhledem k tomu, seznam „členité“ linek, jako je

One
 Two
  Three
   Four
 Five
Six

(Dále jen „úroveň odsazení“, může se předpokládat, že se známý, který je součástí vstupních dat)

Generovat následující výstup:

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

Samozřejmě můj kód je nahoru a běží ... a také skrytý pod THWoS (Heavy Weight of Shame)

Položena 01/06/2010 v 00:20
zdroj uživatelem
V jiných jazycích...                            


2 odpovědí

hlasů
8

Použijte zásobník pro čísla. Procházení každý řádek, a kontrolovat úroveň odsazení každého řádku, bez zářezu bytí úroveň 1.

  1. Je-li současná úroveň odsazení je větší než velikost zásobníku tlačit jako ty mnoha tento rozdíl je do fronty (rozdíl by obvykle jen jeden, ale to funguje, i když někdo klade nadpis úrovně 3 pod nadpisem úrovně 1, například)
  2. Je-li současná úroveň odsazení je menší než velikost zásobníku, popu a zlikvidujte tolik čísel, jako je tento rozdíl a zvýšit nejvyšší číslo v zásobníku.
  3. Je-li současná úroveň odsazení je rovna velikosti stacku, zvýšit horní číslo v zásobníku

Pro každý řádek, aktuální počet titulů je číslo v zásobníku spojení společně s. od sebe oddělit.

Všimněte si, že velikost zásobníku obratně představuje úroveň odsazení předchozího řádku je.

Pro lidi, kteří mají čitelnější kód, tady je implementace JavaScript pro moderní prohlížeče:

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

Odpovězeno 01/06/2010 v 00:33
zdroj uživatelem

hlasů
2

Tento algoritmus předpokládá, že úroveň odsazení nikdy zvýší o více než 1 jednotka. Pokud ano, pak je třeba nastavit všechny „vynechané“ úrovně 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
Odpovězeno 01/06/2010 v 00:42
zdroj uživatelem

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