Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Алгоритмы > Закодировать массив


Автор: Fixin 20.1.2004, 20:36
Люди?!! Есть, естественно, проблема - дан массив из n элементов от 0 до n. Нужно превратить это все
в что-то по короче - то, что можно записать вручную, ну на бумаге хотябы. И из этой записи потом все восстановить - теже числа и на томже месте, если это реально?
P.S.
Массив - бывший упорядоченный, в котором в каждой ячейке жранился его номер, а потом все перемесили, но без утрат - это так, может поможет.

Автор: maxim1000 20.1.2004, 21:02
ну сохранять напрямую весь массив, действительно, избыточно
если это делать, нужно записать одно из n^n чисел
всего же различных комбинаций - n!, что намного меньше
таким образом, нужно просто перевести сведения о порядке элементов в одно число
сделать это можно, например, так:
Код
int encode(CSomeArray array)
{
 int n,i;

 n=array.Length();
 i=array.Find(n-1);
 array.Cut(i);
 return i+n*function(array);
};

класс CSomeArray - придуман для наглядности алгоритма
методы:
Length() - возвращает длину массива
Find(x) - ищет элемент x в массиве и возвращает его индекс
Cut(i) - вырезает элемент с индексом i (длина приэтом уменьшается на 1)
Insert(x,i) - вставляет элемент x в позицию с номером i (все, что после него - сдвигается)

на самом деле здесь реализован просто перевод числа в другую систему счисления
особенностью является переменное основание этой системы:
для младшего разряда оно=1
для старшего - n
число записывается так:
0*1+i1*1*2+i2*1*2*3+i3*1*2*3*4+...
i1 - положение 1 в массиве, который получится после выкидывания всех чисел кроме 0 и 1
i2 - положение 2 в массиве из 0,1,2
...

декодировать можно так:
Код
CSomeArray decode(int x,int n)
{
 CSomeArray result;
 int i;
 int nn;

 for(i=0;i<n;i++)
   result.Insert(i,x%(i+1));
 return result;
};

может, что-нибудь и напутал, но, надеюсь, алгоритм понятен

Автор: acp 21.1.2004, 00:50
Цитата
Массив - бывший упорядоченный, в котором в каждой ячейке жранился его номер, а потом все перемесили, но без утрат

Не понимаю. Массив был такой [1, 2, 3, ..., n]?
Известна может быть последовательность перемешивания?
Если да, то можно её записывать.
Если нет, то её можно попробовать отыскать.
Можно попробовать какие-нибудь методы сжатия простейшие

Цитата
таким образом, нужно просто перевести сведения о порядке элементов в одно число

Прикольно придумано smile.gif
Ещё здесь можно использовать не только "циферное" представление числа, но и "символьное". Т.е. использовать буквы латинского алфавита.

Автор: maxim1000 21.1.2004, 11:08
Цитата
Ещё здесь можно использовать не только "циферное" представление числа, но и "символьное". Т.е. использовать буквы латинского алфавита.

результатом работы вышеописанного алгоритма является число
а его можно выводить уже в системе счисления любого постоянного основания
действительно, можно за основание взять, например, 36 (цифры+латинские буквы) или 62(+большие)

Автор: Fixin 21.1.2004, 20:07
Цитата
Известна может быть последовательность перемешивания?


Нет, замесь производится рандомом.

Цитата
return i+n*function(array);


function(CSomeArray array) - это что, или я не все догоняю, мне-то далеко до толковых прог-мистов.

Автор: maxim1000 22.1.2004, 11:23
Цитата
function(CSomeArray array) - это что, или я не все догоняю, мне-то далеко до толковых прог-мистов.

это - ничего страшного, это - моя ошибка smile.gif
просто я сначала писал только функцию кодирования и, чтоб долго не думать, обозвал ее function
потом я вспомнил, что неплохо было бы ее и раскодировать smile.gif, и переобозвал функцию кодирования encode, а в рекурсивном вызове заменить забыл...

Автор: Fixin 22.1.2004, 22:01
Точно! надо было подумать!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)