Алгоритм разбить статью, не нарушая поток чтения или HTML-код - PullRequest
2 голосов
/ 16 июня 2010

У меня очень большая база данных статей различной длины.В статьях есть HTML-элементы.Мне нужно вставить некоторые объявления (простые элементы) в тело каждой статьи, когда она отображается (я знаю, я ненавижу рекламу, которая также мешает моему чтению).

Теперь проблема в том, что каждыйобъявление должно быть вставлено примерно в одну и ту же позицию в каждой статье.Самое простое решение - просто разбить статью на фиксированное количество символов (без разбивки слов) и вставить рекламный код.Однако это рискует вставить объявление в середину HTML-тега.

Я мог бы пойти по пути регулярных выражений, но я думал о следующем решении, используя JS:

  1. Установить количество символов Порог .Например, «добавление должно быть вставлено примерно в 200 слов»
  2. Установить допустимые отклонения в каждом направлении, скажем -20, +20 символов.
  3. Проходить через каждоетекстовый узел внутри статьи, и при этом сохраняйте count от общего количества символов на данный момент
  4. Как только счет превысит пороговое значение, примите следующее решение:

    4.1.Если число превышает пороговое значение на величину ниже положительного допустимого отклонения (например, 17 символов), вставьте рекламный код сразу после текущего текстового узла.

    4.2.Если число больше, чем сумма порога и отклонения, выполните откат к предыдущему текстовому узлу и примите то же решение, только на этот раз используйте предыдущий счет и проверьте, меньше ли оно разницы между порогом и отклонениеми, если нет, вставьте объявление между текущим узлом и предыдущим.

    4.3.Если произойдет сбой 4.1 и 4.2 (что означает, что предыдущий узел достиг слишком малого числа символов, а текущий узел слишком большого числа), вставьте объявление после того, как в текущем элементе необходимо любое количество символов.

Я знаю, что это запутанно, но это первое, что у меня в голове, и у него есть преимущество в том, что, пытаясь вставить рекламу между текстовыми узлами, возможно, она не нарушит поток статьи так же плохо, как она.если бы я просто вставил его (как в последнем случае 4.3)

Вот некоторый псевдокод, который я собрал, я не доверяю своим навыкам объяснения английского языка:

threshold = 200
deviation = 20
current_count = 0

for each node in article_nodes {
    previous_count = current_count
    current_count = current_count + node.length
    if current_count < threshold {
        continue // next interation
    }

    if current_count > threshold + deviation {
        if previous_count < threshdold - deviation {
            // insert ad in current node
        } else {
            // insert ad between the current and previous nodes
        }
    } else {
        // insert ad after the current node
    }

    break;
}

Я слишком усложняю вещи, или мне не хватает более простого и элегантного решения?

PS : решения как на стороне сервера, так и на стороне клиента для меня вполне приемлемы.

1 Ответ

1 голос
/ 11 февраля 2011
  1. Я бы в идеале вставлял рекламу только с разрывом абзаца (возможно, тегом p) или разрывом строки (возможно, тегом br).

В противном случае, при разрыве слова. И если это не удастся, вставьте его между персонажами. (Чтобы покрыть странные угловые случаи.)

Так вот, К.И.С.С. Решение:

  1. считайте буквы, слова, строки и абзацы по ходу движения.

Просто выполните каскадный сбой в направлении вашего предпочтительного решения:

  1. если вы наберете 2000 символов - просто включите рекламу и начните все заново считать.

Этого бы никогда не произошло, кроме как в странных случаях.

  1. Если вы наберете 250 слов - просто вставьте объявление и начните заново считать все с нуля.

Это случается очень редко, только с плохо отформатированным текстом, странными языками пришельцев и т. Д.

  1. Если вы наберете 50 новых строк - просто вставьте объявление и начните заново считать все с нуля.

Это могло бы случиться только с авторами, которые не используют разрывы абзацев.

  1. И, наконец, если вы дойдете до 3 новых параграфов - вставьте объявление и начните все заново считать.

Это то, что обычно происходит.

Я не будет беспокоиться о таких сложных идеях, как возврат в соседних случаях и т. Д. И т. Д. Это просто не стоит. Это почти всегда дает вам лучшее общее долгосрочное решение для последовательного и простого подхода «каскадных сбоев». Сделайте вышеописанное, и все готово!

Это гораздо больше, чем искусство, делать что-то подобное. Вам понравится выше, надеюсь, это поможет!

Очевидно, мелодия числа, которые я положил в псевдокод выше. Большая часть работы на такой работе - это настройка параметров на реальном испытательном стенде. Написание самого кода - это ничто, вам нужно создать хороший тестовый стенд, чтобы вы могли сделать это на своих глазах и увидеть, как он работает (в идеале нужно включить «циферблаты» для параметров, чтобы вы могли видеть результаты в реальном времени, понимаете? ) Вот как ты это делаешь!

...