算法 - TOC编号(目录)

Dr.*_*ius 3 algorithm pseudocode

我想实现一个VBA函数,根据行的分组深度对Excel行进行编号.

但我认为生成TOC的通用算法更有趣.

问题是:

给出一个"缩进"行列表,如

One
 Two
  Three
   Four
 Five
Six
Run Code Online (Sandbox Code Playgroud)

(可以假设"缩进级别"是已知的并且是输入数据的一部分)

要生成以下输出:

1.    One
1.1    Two
1.1.1   Three
1.1.1.1  Four
1.2    Five
2.    Six
Run Code Online (Sandbox Code Playgroud)

当然我的代码已启动并运行......并且还隐藏在THWoS(耻辱的重量级)下

Mat*_*nen 8

使用堆栈表示数字.循环遍历每一行,并检查每行的缩进级别,没有缩进级别为1.

  1. 如果当前缩进级别大于堆栈的大小,则推送多个,因为差异在堆栈上(差异通常只有一个,但即使有人将级别3标题放在级别1标题下,这也有效,例如)
  2. 如果当前缩进级别小于堆栈的大小,则弹出并丢弃与差异一样多的数字,然后递增堆栈上的顶部数字.
  3. 如果当前缩进级别等于堆栈的大小,则递增堆栈上的顶部数字

对于每一行,当前标题号是堆栈中的数字与a连接在一起.分开他们.

注意堆栈的大小如何方便地表示前一行的缩进级别.

对于那些更容易阅读代码的人来说,这是现代浏览器的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;
});
Run Code Online (Sandbox Code Playgroud)