Стабильный, эффективный вид?

Простейшим (и поэтому, вероятно, лучшим) подходом было бы просто использовать string.Split, а затем итерировать массив:

var source = "File_name,cost_per_page,0.23,color_code,343,thickness,0.01";

var splitted = source.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries)
var result = new Dictionary<string, string>();
// Note: Starting from 1 to skip the "file_name"
// moving 2 indexes in each iteration, 
// and ending at length - 2.
for(int i = 1; i < splitted.Length - 1; i+=2)
{
    result.Add(splitted[i], splitted[i+1]);
}

Я пытался найти умный способ сделать это с linq, но лучшее, что я придумал, на самом деле совсем не так умно:

var valuesWithIndexes = source
    .Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries)
    .Skip(1)
    .Select((v, i) => new {v, i});

var keys = valuesWithIndexes.Where(x => x.i % 2 == 0);
var values = valuesWithIndexes.Where(x => x.i % 2 == 1);

var dictionary = keys.Zip(values, (k, v) => new {k, v})
    .ToDictionary(key => key.k,
                  val => val.v);

Я думаю, что простой цикл for - явный победитель в этом случае.

14
задан Nescio 22 September 2008 в 03:26
поделиться

12 ответов

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

10
ответ дан 1 December 2019 в 07:20
поделиться

Не волнуйтесь слишком много о O (n, регистрируют n), пока Вы не можете продемонстрировать, что он имеет значение. Если можно найти O (n^2) алгоритмом с решительно ниже постоянный, пойдите для него!

общий худший вариант не релевантен, если Ваши данные высоко ограничиваются.

Короче говоря: Запустите некоторый тест.

1
ответ дан 1 December 2019 в 07:20
поделиться

Возможно вид оболочки ? Если я вспоминаю свой курс структур данных правильно, он имел тенденцию быть стабильным, но это - худшее время случая, O (n log^2 n), хотя он выполняет O (n) почти на отсортированных данных. Это основано на виде вставки, таким образом, это сортирует на месте.

1
ответ дан 1 December 2019 в 07:20
поделиться

Поскольку Ваши элементы находятся в массиве (а не, скажем, связанный список), у Вас есть некоторая информация об их первоначальном заказе, доступном Вам в самих индексах массива. Можно использовать в своих интересах это путем записи вида и функций сравнения для знания об индексах:

function cmp( ar, idx1, idx2 )
{
   // first compare elements as usual
   rc = (ar[idx1]<ar[idx2]) ? -1 : ( (ar[idx1]>ar[idx2]) ? 1 : 0 );

   // if the elements are identical, then compare their positions
   if( rc != 0 )
      rc = (idx1<idx2) ? -1 : ((idx1>idx2) ? 1 : 0);

   return rc; 
}

Эта техника может использоваться для создания любого вида стабильным, пока вид ТОЛЬКО выполняет подкачки элемента. Индексы элементов изменятся, но относительный порядок идентичных элементов останется таким же, таким образом, вид останется устойчивым. Это не будет работать из поля на вид как пирамидальная сортировка, потому что исходный heapification "выбрасывает" относительное упорядочивание, хотя Вы могли бы быть в состоянии адаптировать идею другим видам.

2
ответ дан 1 December 2019 в 07:20
поделиться

Существует список алгоритмов сортировки для Википедия . Это включает классификацию ко времени выполнения, устойчивости и выделению.

Ваш лучший выбор, вероятно, будет изменением эффективного нестабильного вида, чтобы быть стабильным, таким образом, делая это менее эффективным.

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

Что относительно quicksort?

Exchange может сделать это также, могло бы быть более "стабильным" по Вашим условиям, но quicksort быстрее.

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

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

Редактирование: фаза слияния линейна, таким образом сортировка с объединением является nlog_n.

2
ответ дан 1 December 2019 в 07:20
поделиться

Примечание : стандарт quicksort не O (n, регистрируют n)! В худшем случае может потребоваться до O (n^2) время. Проблема состоит в том, что Вы могли бы вертеться вокруг элемента, который далек от медианы, так, чтобы Ваши рекурсивные вызовы были высоко несбалансированными.

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

я думаю, что самый практический подход должен реализовать стабильный quicksort (легко сохранить стабильность), но используйте медиана 5 случайных значений как центр на каждом шаге. Это делает его очень вряд ли, что Вы будете иметь медленный вид и стабильны.

Между прочим, сортировка слиянием может быть сделана оперативная, хотя это хитро, чтобы сделать и оперативный и стабильный.

9
ответ дан 1 December 2019 в 07:20
поделиться

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

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

Я использовал этот метод с C qsort() функция, чтобы не писать мое собственное. Каждая запись имеет 32-разрядное целое число, добавленное и заполненное со стартовым порядковым номером перед вызовом qsort().

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

Ваш пробег может варьироваться, поэтому всегда помнить: Измерьте, не угадывайте!

2
ответ дан 1 December 2019 в 07:20
поделиться

Может быть, я немного запутался, но мне нравится ручная сортировка слиянием. Это' простая, стабильная и хорошо управляемая. Дополнительное временное хранилище, которое ему нужно, составляет всего N * sizeof (int) , что неплохо.

0
ответ дан 1 December 2019 в 07:20
поделиться

Быструю сортировку можно сделать стабильной, выполнив ее в связанном списке. Это стоит n, чтобы выбрать случайное или среднее значение из 3 опорных точек, но с очень маленькой константой (обход списка).

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

Итак, в заключение, перечислите все свои элементы и запустите быструю сортировку на список

2
ответ дан 1 December 2019 в 07:20
поделиться
Другие вопросы по тегам:

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