2009-04-19 10 views
1

У меня есть массив из n = 32 элементов с положительными и отрицательными значениями. Первые n/2 элемента положительны и отсортированы по значению, а второй n/2 элемента отрицательны и отсортированы по значению. Я хотел бы отсортировать весь массив по значению, начиная с наименьшего отрицательного значения до наибольшего положительного значения, что означает, что если имеется 32 элемента, первые 16 (n/2) отсортированных элементов должны содержать значения вторых 16 элементов исходного массива а вторые 16 элементов сортированного массива должны содержать первые 16 значений исходного массива.Как сместить элементы массива

Гипотетический пример:

double[] original = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, -16, -15, ..., -1}; 

double[] sorted = {-16, -15, ...., -1, 1, 2, ..., 16}; 

Кто-нибудь знает, что это лучший способ, чтобы сдвинуть элементы для создания отсортированного массива из оригинала?

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

+0

Почему они должны быть сдвинуты и не отсортированы? –

+0

, потому что мне нужно переместить другой массив, который не сортируется по размеру так же, как я делаю это для этого. пример hyppothetical представляет ось x и сортируется по размеру, но другой массив содержит значения, которые не следует сортировать по размеру (ось y). –

+0

Вы хотите отсортировать один массив на основе значений, содержащихся в другом массиве? Другими словами: хотите ли вы отсортировать один массив, а затем применить одну и ту же последовательность шагов к другому массиву? –

ответ

9

Итак, вы хотите второй массив, с содержимое оригинала, но в местах сдвинуто? Либо сделать это явно:

double[] result = new double[32]; 
for (int i=0; i < 32; i++) 
{ 
    result[(i+16)%32] = original[i]; 
} 

или с использованием Array.Copy дважды:

double[] result = new double[32]; 
Array.Copy(original, 0, result, 16, 16); 
Array.Copy(original, 16, result, 0, 16); 
0

Просто делать своп на элемент 0 и элемент 16, 1 и 17, 2 и 18 .. и т.д.

0

Вы пробовали:

Array.Sort(original); 
+0

он должен быть смещен не отсортированным! –

+0

В примере, который вы указали, желаемый результат будет получен с помощью Array.Sort. –

+0

Принимая во внимание, что обе половины уже отсортированы (согласно вашему описанию), сдвигающий элемент 0 с 16, 1 и 17, 2 и 19 и т. Д. Будет иметь тот же результат, что и сортировка массива по размеру. –

2

Как насчет в Linq:

int half = original.Length/2; 
var sorted = original.Skip(half).Concat(original.Take(half)).ToArray(); 
+2

Я думаю, вы имеете в виду Concat, а Union-Union удалит все повторяющиеся элементы. –

+0

@Jon: Спасибо ... Я сделал ваше предложение изменить. – Keltex

0

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

Array.Sort(keys, values); 

Вот документация Array.Sort(Array keys, Array items)

3

Учитывая жесткий характер проблемы, Array.Copy:

 int half = original.Length/2; 
     Array.Copy(original, 0, sorted, half, half); 
     Array.Copy(original, half, sorted, 0, half); 
0

ответы Джон Скита и Марк Gravell ♦ 's обеспечивают правильное решение, но если вы не хотите выделять дополнительный массив, вы можете:

a) решить конкретную проблему (смещение 2-го половина будет до 1-я половины) на месте:

private void Rotate1(double[] toRotate) { 
     int startOf2nd = toRotate.Length/2; 
     for (int i=0; i < toRotate.Length/2; i++) { 
      double temp = toRotate [i]; 
      toRotate [i] = toRotate [i + startOf2nd]; 
      toRotate [i + startOf2nd] = temp; 
     } 
    } 

Обратите внимание, что этот код не может иметь дело с массивом с нечетным числом элементов.

б) вы можете применить вектор сдвигая алгоритм я знаю от Джона Бентли «Программирование Жемчужины»:

private void Rotate2(double[] toRotate, int index) { 
     Array.Reverse(toRotate, 0, index); 
     Array.Reverse(toRotate, index, toRotate.Length-index); 
     Array.Reverse(toRotate, 0, toRotate.Length); 
    } 

В вашем примере индекс будет 16. Этот код обрабатывает нечетное число элементов и индекс не являющихся в середине.Используя пример, аналогичный тому, который используется в книге для toRotate = {0,1,2,3,4,5,6,7} и index = 3 Rotate2 будет производить {3,4,5,6,7 , 0,1,2}.

Смежные вопросы