У меня есть блок текста (произвольной длины), в котором конкретное слово выделяется желтым цветом всякий раз, когда оно появляется. Я хочу показать только фрагмент текста из 400 слов, но я хочу показать фрагмент с наиболее выделенными словами.

Кто-нибудь знает хороший алгоритм для этого?

У меня есть позиция символа каждого выделенного слова, поэтому алгоритм должен найти самый плотный кластер неравномерно расположенных целых чисел?

3
Tom 17 Июл 2009 в 20:21

4 ответа

Лучший ответ

Я не уверен, откуда вы знаете, что они выделены, но вот простой O (n) подход, который я бы попробовал.

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

Не слишком элегантно, но довольно просто.

6
Victor 17 Июл 2009 в 16:29

У вас есть признаки выделенных слов ... Я думаю, что приведенный ниже подход является хорошим и быстрым подходом, поскольку он не требует "поиска" каждого слова (для выполнения кругового цикла). Для этого он использует «размер блока», полученный из числа символов, а не слов. Затем вы можете «округлить вверх» или «вниз» до ближайшего окончания слова, и вот вам кусок.

Я думаю, что метод определения количества выделенных индикаторов находится в пределах «размера блока» впереди в вашем образце.

Псевдо

string GetHighestDensityChunk(){

// {chunk size} = 400 * average word length
// {possible start positions} = 0, highlighted indicies, and (sample - {chunk size})

int position
int bestPositionSoFar = 0
int maxHighLightedCountSoFar = 0


for each position in {possible start position}
{
    highlightedCount = GetNumberOfHighlightedWithinChunkSize(position)

    if(highlightedCount > maxHighLightedCountSoFar) 
    {
        maxHighLightedCountSoFar = highlightedCount
        bestPositionSoFar = position
    }
}

// "round up" to nearest word end
// gives index of next space after end of chunk starting from current best position
{revised chunk size} = sample.indexOf(' ', startingAt = bestPositionSoFar + {chunk size}) - bestPositionSoFar

return sample.substring(bestPositionSoFar, {revised chunk size})
}   


 int GetNumberOfHighlightedWithinChunkSize(position)
{
    numberOfHighlightedInRange = 0

    // starts from current position and scans forward counting highlighted indicies that are in range
    for(int i= {possible start position}.indexOf(position); i<= {possible start position}.length; i++){
        if({possible start position}[i] < position + {chunk size}){
            numberOfHighlightedInRange++;
        } else {
            break;
        }
    }
    return numberOfHighlightedInRange;
}
1
Ray 17 Июл 2009 в 17:14

Это не совсем то, о чем вы просили, но я использовал что-то подобное в прошлом при поиске слов (charPos относится к позиции начального символа слова). Примечание: оператор '/' выполняет целочисленное деление, т.е. 4200/2000 = 2.

if hasKey(charPositionHashtable[charPos/2000]):
    charPositionHashtable[charPos/2000]) += 1
else:
    charPositionHashtable[charPos/2000]) = 1

После завершения поиска charPositionHashtable имеет набор пар ключ / значение, содержащих "указатель" для блоков по 2000 символов и количество найденных в них слов. Возьмите максимум и используйте кусок, соответствующий этому индексу. Я думаю, это имеет то преимущество, что лучше, чем O (n) (но я не проводил много анализа по этому поводу).

1
sigint 17 Июл 2009 в 16:39

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

2
Draemon 17 Июл 2009 в 16:25