Вопрос

У меня есть массив из 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};

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

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

Это было полезно?

Решение

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

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);

Другие советы

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

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

А как насчет Linq:

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

Попытался ли ты:

Array.Sort(original);

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

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

Array.Sort(keys, values);

Вот документация Array.Sort(ключи массива, элементы массива)

Ответы Джона Скита и Марка Грэвелла♦ дают правильное решение, но если вы не хотите выделять дополнительный массив, вы можете:

а) решить конкретную проблему (сдвинув вторую половину до первой половины) на месте:

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. Повернуть2 будет производить {3,4,5,6,7,0,1,2}.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top