Сожмите отсортированные целые числа

Пример использования «С» и назначения блока из массива:

'copy from database to the pricing schedule as a 
'   non formatted list of all the info - this runs quickly, 
'   but I am open to changing it
With Range("Client_Register")

    For Each rw In .Rows
        If .Cells(rw.Row, 2) = selectedClient Then

            collect(i, 1) = .Range("E" & rw.Row)
            collect(i, 2) = .Range("D" & rw.Row)
            collect(i, 3) = .Range("F" & rw.Row)
            collect(i, 4) = .Range("J" & rw.Row)
            collect(i, 5) = .Range("K" & rw.Row)
            collect(i, 6) = .Range("L" & rw.Row)
            collect(i, 7) = .Range("M" & rw.Row)
            collect(i, 8) = .Range("P" & rw.Row)
            collect(i, 9) = .Range("I" & rw.Row)
            collect(i, 10) = .Range("H" & rw.Row)

            'you could even skip the row-by-row population of values
            '  and assign as a block after exiting the loop
            ws2.Range("B" & i + 6).Resize(1, 10).Value = _
                    Array(collect(i, 1), collect(i, 2), collect(i, 3), _
                          collect(i, 4), collect(i, 5), collect(i, 6), _
                          collect(i, 7), collect(i, 8), collect(i, 9), _
                          collect(i, 10))

            i = i + 1
        End If
    Next

End With

Обратите внимание, что это сломается, если ваш Client_Register ссылается на диапазон, который не начинается на строке 1, из-за относительных ссылок на диапазон.

Например:

 Range("A1:A10").Range("A1") 'refers to A1
 Range("A2:A10").Range("A1") 'refers to A2
10
задан Daniel 7 February 2009 в 13:15
поделиться

9 ответов

Если Вы храните целые числа, которые являются близко друг к другу (например: 1, 3, 4, 5, 9, 10 и т.д....), а не некоторые случайные целые числа на 32 бита (982346..., 3487623412.., и т.д.), можно сделать одну вещь:

Найдите различия между смежными числами, которые были бы похожи 2,1,1,4,1... и т.д. (в нашем примере), и затем Huffman кодирует это числа.

Я не думаю, что Кодирование методом Хаффмана будет работать при прямом применении их к исходному списку чисел, Вы имеете.

Но если у Вас есть отсортированный список соседних чисел, разногласия хороши, что Вы получите очень хорошую степень сжатия путем выполнения Кодирования методом Хаффмана различий в числе, может быть лучшее отношение, чем использование алгоритма LZW, используемого в библиотеках Zip.

Так или иначе благодарит отправить этот интересный вопрос.

19
ответ дан 3 December 2019 в 14:00
поделиться

Целые числа сгруппированы плотным способом или редким путем?

Плотным я обращаюсь к:

[1, 2, 3, 4, 42, 43, 78, 79, 80, 81]

Редким я обращаюсь к:

[1, 4, 7, 9, 19, 42, 53, 55, 78, 80]

Если целые числа сгруппированы плотным способом, Вы могли бы сжать первый вектор для содержания трех диапазонов:

[(1, 4), (42, 43), (78, 81)]

Который является 40%-м сжатием. Конечно, этот алгоритм не работает хорошо над редкими данными, поскольку сжатые данные подняли бы на 100% больше пространства, чем исходные данные.

8
ответ дан 3 December 2019 в 14:00
поделиться

Поскольку Вы обнаружили, отсортированная последовательность целых чисел на 32 бита N не имеет 32*N биты данных. Это не удивительно. При принятии дубликатов для каждой отсортированной последовательности существуют N! неотсортированный seqeuences, содержащий те же целые числа.

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

Однако возьмите последовательность Fibonacci. Это определенно отсортировало целые числа. Различием между F (n) и F (n+1) является F (n-1). Следовательно, сжатие последовательности различий эквивалентно сжатию самой последовательности - это не помогает вообще!

Так, в чем мы действительно нуждаемся, статистическая модель Ваших входных данных. Учитывая последовательность N [0]... N [x], каково распределение вероятностей N [x+1]? Мы знаем, что P (N [x+1] <N [x]) = 0, поскольку последовательность отсортирована. differential/Huffman-based решения представили работу, потому что они принимают P (N [x+1] - N [x] = d), довольно высоко для маленького положительного d и независим от x, таким образом, они используют, может использовать несколько битов для небольших различий. Если можно дать другую модель, можно оптимизировать для этого.

6
ответ дан 3 December 2019 в 14:00
поделиться

Если Вам нужен быстрый поиск произвольного доступа, то Кодирование методом Хаффмана различий (как предложено Niyaz) является только половиной истории. Вам, вероятно, также будет нужна своего рода схема подкачки страниц/индексации так, чтобы было легко извлечь энное число.

Если Вы не делаете этого, то извлечение энного числа является O (n) операция, поскольку необходимо читать, и Huffman декодируют половину файла, прежде чем можно будет найти число, которым Вы были после. Необходимо выбрать размер страницы тщательно для балансировки издержек хранения смещений страницы против скорости поиска.

2
ответ дан 3 December 2019 в 14:00
поделиться

Условия в списках целых чисел немного отличаются, но Сжатие вопроса для уникального потока данных предлагает несколько подходов, которые могли помочь Вам.

Я предложил бы предварительно проникнуть данные в a start и серия offsets. Если Вы знаете, что смещения будут надежно маленький, Вы могли даже закодировать их 1-или 2-байтовые количества вместо 4 байтов. Если Вы не знаете это, каждое смещение могло бы все еще составить 4 байта, но так как они будут маленьким diffs, Вы получите намного больше повторений, чем Вы были бы, храня исходные целые числа.

После предварительной фильтрации выполненной Ваш вывод через схему сжатия по Вашему выбору - что-то, что работает на уровне байта, как gzip или zlib, вероятно, сделало бы действительно хорошее задание.

1
ответ дан 3 December 2019 в 14:00
поделиться

Я предположил бы, что Кодирование методом Хаффмана будет вполне appropiate с этой целью (и относительно быстро по сравнению с другими алгоритмами с подобными степенями сжатия).

Править: Мой ответ был только общим указателем. Предложение Niyaz кодирования различий между последовательными числами является хорошим. (Однако, если бы список не заказан, или интервал чисел очень неправилен, я думаю, что было бы не менее эффективно использовать простое Кодирование методом Хаффмана. На самом деле LZW или подобный, вероятно, был бы лучшим в этом случае, хотя возможно все еще не очень хороший.)

1
ответ дан 3 December 2019 в 14:00
поделиться

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

В Java, например, можно использовать GZIPOutputStream для применения gzip сжатия.

0
ответ дан 3 December 2019 в 14:00
поделиться

Возможно, Вы могли сохранить различия между последовательными 32-разрядными целыми числами как 16-разрядные целые числа.

0
ответ дан 3 December 2019 в 14:00
поделиться

Ответ MSalters интересен, но может отвлечь вас, если вы не проанализируете должным образом. Есть только 47 чисел Фибоначчи, которые умещаются в 32-битные.

Но он точно знает, как правильно решить проблему, анализируя серию приращений, чтобы найти шаблоны для сжатия.

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

1
ответ дан 3 December 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: