2010-05-31 3 views
3

Я хочу реализовать функцию VBA для номера строк Excel на основе глубины группировки строки.Алгоритм - Нумерация для TOC (Оглавление)

Но я думаю, что общий алгоритм генерации ТОС более интересен.

Проблема заключается в том:

Учитывая список «вдавленных» линий, таких как

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 

конечно мой код и г unning ... и также скрыты под THWoS (The Heavy Weight of Shame)

+0

У вас есть рабочий код. Что вам тогда нужно? – 2010-05-31 23:23:37

+1

@Moron: Я здесь не для того, чтобы выполнить свою работу, но чтобы лучше узнать других людей и, возможно, помочь им, если смогу. Кстати ... Почему вы тратите свое время на эти комментарии? –

+0

У вас никогда не было конкретного вопроса и, пожалуйста, прочитайте faq: Это не доска объявлений. Пожалуйста, простите меня, если я больше не буду отвечать. – 2010-05-31 23:56:37

ответ

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

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