|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 20, 2003 19:56:29 · Поправил: volodya Народ, подскажите мне, тупому, какая такая сортировка есть, чтобы она мне в массиве (или в списке при связанном хранении, неважно) грохнула все одинаковые int. И вообще, более общий вопрос. Есть, положим массив из int. Сортировать его или нет - мне побоку, а вот все одинаковые int в нем надо удалить. Как это сделать? Достаточно будет сказать только название сортировки. А дальше я уж сам разберусь. Благо, сайтов по алгортимам хватает :) Да, и ыще :) Было бы классно, если бы кто-то бросил линк на С-операции со списками. Я надыбал кой-чего, но может кто-то давно уже что-то такое знает. А? |
|
|
Дата: Авг 21, 2003 07:31:33 какая такая сортировка есть, чтобы она мне в массиве (или в списке при связанном хранении, неважно) грохнула все одинаковые int Сортировка - это не удаление элементов, поэтому вопрос поставлен некорректно. Для удаления одинаковых элементов лучше сначала массив отсортировать, а дальше дело техники. А какую сортировку использовать, в принципе, неважно, хотя из соображения эффективности лучше взять быструю сортировку, бинарную (корпоративную) сортировку или сортировку методом Шелла. Есть и другие способы, например, использование битового массива для хранения признака, присутствует ли элемент в массиве (1 или 2 бита на каждый элемент - надо это обдумать хорошенько). При этом требуется всего один-два прохода, но много памяти. Например, если диапазон чисел от 0 до 2^20, потребуется 2^17 или 2^18 байт. Если массив не очень большой и/или время выполнения не сильно ограничено, я думаю, первый способ будет наиболее эффективным. Кстати, эта тема обсуждалась в книге "Жемчужины программирования" издательства "Питер", серия "Библиотека программиста", автора не помню. Может, там ещё какой алгоритм есть. |
|
|
Дата: Авг 21, 2003 15:11:37 Artem Сортировка - это не удаление элементов, поэтому вопрос поставлен некорректно Вообще то нет. Вопрос верный. Сортировка -- это операция упорядочевания. Удаление элементов -- это так же операция упорядочевания. P.S на выходных закончу свой алгоритм.. Так что жди :)) |
|
|
Дата: Авг 21, 2003 15:53:57 сортируешь массив arr[0..size-1] по возрастанию или убыванию, потом делаешь цикл:
i:=0;
while i<(size-1) do
if arr[i]=arr[i+1] then delete(i) else inc(i);
з.ы. писАл по ходу, должно работать... |
|
|
Дата: Авг 21, 2003 16:03:22 Max Это уже было :)) В теме по перл :) |
|
|
Дата: Авг 21, 2003 17:08:47 Edmond не знаю, не читал ;-) я вот когда начинал, лет 15 назад, придумал алгоритм сортировки, а потом узнал, что он называется "пузырьковым" :))) вот так вот бывает... |
|
|
Дата: Авг 21, 2003 17:16:39 Max Это отнюдь не самый быстрый алгоритм. Я потому вопрос и задал, что мне нужно что-то быстрое. Буду ждать Димонова решения... Однако, спасибо. |
|
|
Дата: Авг 21, 2003 17:30:05 Max вот так вот бывает... Ну не только у тебя, я например ООП разработал.. за пол года о его прочтении :))) |
|
|
Дата: Авг 21, 2003 17:40:10 · Поправил: Max volodya Это отнюдь не самый быстрый алгоритм Согласен, но сомневаюсь, что можно сделать быстрее. В связке qucksort + цикл все работает очень быстро. Узкое место тут - delete(i), если при этом делать релок памяти то действительно будет медленно, если сначала отмаркировать записи подлежащие удалению, будет быстро. А если заточить под SSE2, то вместо if arr=arr[i+1], можно сравнивать arr[i] сразу с 4-мя последующими элементами. [i]Буду ждать Димонова решения... Интересно было бы посмотреть... [З.Ы. quicksort всмысле...] |
|
|
Дата: Авг 21, 2003 17:54:15 Max Код примера будет компилироваться под 14 операционных систем и приблизительно еще две архитектуры процов, отличных от Intel - к примеру, sparc. Ясно, что никакие SSE2 мне тут не катят :( |
|
|
Дата: Авг 22, 2003 00:08:25 · Поправил: volodya Я еще просил инфу по связанным спискам. Т.е. спискам вида val|ptr_to_next_node->val|ptr_to_next_node->val|0; Поскольку никто ни чем для меня не разродился, я тут налабал маленько. Не скажу, что функции САМЫЕ эффективные, поэтому, если кто хочет пнуть - силь ву пле :)
typedef struct valnodeEx {
int intvalue; /* first int to play with*/
int intvalue2; /* second one */
struct valnodeEx *next; /* next in linked list */
} ValNodeEx, *ValNodePtrEx;
/********************
* my own implementation of some functions to play with ValNodeEx
********************
*/
ValNodePtrEx ValNodeAddIntsEx(ValNodePtrEx vnp, int val1, int val2)
{
ValNodePtrEx newnode = NULL;
if(!vnp->next && !vnp->intvalue && !vnp->intvalue2)
{
vnp->intvalue = val1;
vnp->intvalue2 = val2;
}
else
{
if((newnode = (ValNodePtrEx) malloc(sizeof(ValNodeEx))))
{
while(vnp->next)
vnp = vnp->next;
newnode->intvalue = val1;
newnode->intvalue2 = val2;
newnode->next = 0;
vnp->next = newnode;
return newnode;
}
}
return newnode;
}
ValNodePtrEx ValNodeCreateHeadEx(void)
{
ValNodePtrEx head = NULL;
if((head = (ValNodePtrEx) malloc(sizeof(ValNodeEx))))
{
memset (head,0,sizeof(ValNodeEx));
return head;
}
return head;
}
void ValNodeFreeAllEx(ValNodePtrEx head)
{
ValNodePtrEx next = NULL;
while(head)
{
next = head->next;
free(head);
head = next;
}
}
Ща еще буду себе голову морочить над удалением избыточности из такого односвязного списка. Честно говоря, самая главная вещь, которую я понял - так это то, что со списками я связываться больше не хочу! |
|
|
Дата: Авг 22, 2003 20:10:09 По поводу односвязанных списков и удаления избыточности. Единственное, что пришло мне в голову. Точнее, почти единственное. Что мы можем сделать. Вариант 1:
for(начало списка; последний элемент?; взять элемент)
{
взять этот элемент и сравнить его со следующим;
if( элементы идентичны согласно заданному критерию)
{
убрать элемент к чертям и перестроить список;
}
и так до конца массива!;
и с каждым элементом!;
}
Не скажу, что я в восторге от этой идеи. Другая, альтернативная. Список применяется тогда, когда ты не знаешь, сколько данных у тебя будет. Так вот - я не знаю :) Но работать с односвязанным списком очень неудобно, т.к. я могу двигаться только от начала к концу. Двусвязанный список уже лучше, но требует больших расходов памяти, что тоже не есть хорошо. Я вот и думаю, может прочесать односвязанный список, создать массив из указателей на next node (и только из них - для моего случая - в три раза меньше памяти), и смотреть уже по указателям - тогда можно применить частный случай быстрой сортировки - т.е. разбить напополам и смотреть. |
|
|
Дата: Авг 22, 2003 20:33:37 Я вот и думаю, может прочесать односвязанный список, создать массив из указателей на next node ПРАВИЛЬНО. Делаешь массив, а потом просто берёшь любой алгоритм, например радиксную сортировку, или быструю, и ПЕРЕМЕЩАЕШЬ УКАЗАТЕЛИ В МАССИВЕ. А потом, просто делаешь рендеринг указателей в списках, с теми что в массиве. |
|
|
Дата: Авг 22, 2003 20:44:37 Edmond Не совсем так. Очевидно, перемещать сами по себе указатели - мне до задницы, т.к. это ничего не даст. Смысла нет. Видно, придется выколупывать из списка еще и данные для сравнения, скармливать их быстрой сортировке, а уж потом рендерить поинтеры в списке заново! Но оригинально. |
|
|
Дата: Авг 22, 2003 20:54:38 volodya Не совсем так. Очевидно, перемещать сами по себе указатели - мне до задницы Да нет же!!!! Просто доступ к элементу осуществляется через адрес. Ну да, это медленнее, а что ж ты хотел? Впрочем, если у тебя элемент -- только один, то конечно можно было сразу их только и помещать,.. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.092 |