Algoritme - Nummerering for TOC (Innhold)

stemmer
3

Jeg ønsker å implementere en VBA-funksjonen for å tall Excel rader basert på gruppering dybden på rad.

Men jeg tror en generell algoritme for å generere TOCs er mer interessant.

Problemet er:

Gitt en liste over innrykket linjer som

One
 Two
  Three
   Four
 Five
Six

(Det innrykk kan antas å være kjent, og en del av inngangsdata)

For å generere følgende resultat:

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

Selvfølgelig koden min er oppe og går ... og også gjemt under THWoS (The Heavy Weight of Shame)

Publisert på 31/05/2010 klokken 23:20
kilden bruker
På andre språk...                            


2 svar

stemmer
8

Bruk en stabel for tallene. Sløyfe gjennom hver rad, og kontroller innrykk nivået for hver rad, med noen innsnitt være nivå 1.

  1. Hvis gjeldende innrykksnivå er større enn størrelsen av stabelen presse så mange som som forskjellen er på stakken (forskjellen vil vanligvis være bare en, men dette fungerer selv om noen setter et nivå 3 overskrift under et nivå en overskrift, for eksempel)
  2. Hvis gjeldende innrykksnivå er mindre enn størrelsen av stabelen, pop og forkaste så mange tall som forskjellen er, og deretter øke den øverste nummeret på stabelen.
  3. Hvis gjeldende innrykksnivå er lik størrelsen av stabelen, inkrementer topp nummeret på stabelen

For hver rad, er strømmen tittelnummeret tallene på stabelen bundet sammen med en. for å skille dem.

Legg merke til hvordan størrelsen av stabelen handily representerer den forrige linjen innrykksnivå.

For folk som synes det er lettere å lese kode, her er Javascript implementering for moderne nettlesere en:

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

Svarte 31/05/2010 kl. 23:33
kilden bruker

stemmer
2

Denne algoritmen forutsetter at innrykksnivå øker aldri med mer enn en enhet. Hvis den gjør det, så må du sette alle de "hoppet over" nivåer til en.

#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
Svarte 31/05/2010 kl. 23:42
kilden bruker

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