How to shift array elements

我们两清 提交于 2019-12-08 08:59:16

问题


I have an array of n = 32 items with positive and negative values. First n/2 elements are positive and sorted by value and second n/2 elements are negative and sorted by value as well. I would like to sort the whole array by value, starting from the smallest negative value to biggest positive value which means if there are 32 elements the first 16 (n/2) sorted elements should contain the values of second 16 elements of the original array and the second 16 elements of the sorted array should contain the first 16 values of the original array.

Hypothetical example:

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

Does anyone know what is the best way to shift the elements to generate the sorted array from original?

This array is by the way tied to another array which doesn't have the elements sorted by size the same way and has to be shifted the same way as original so the array shouldn't be sorted by size, it has to be shifted.


回答1:


So you want a second array, with the contents of the original but at locations shifted? Either do it explicitly:

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

or using Array.Copy twice:

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



回答2:


Given the rigid nature of the problem, Array.Copy:

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



回答3:


How about in Linq:

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



回答4:


Have you tried:

Array.Sort(original);



回答5:


Just do a swap on element 0 and element 16, 1 and 17, 2 and 18.. etc.




回答6:


Do you want to sort one array based on the values contained in another array of the same size? If so, use the following:

Array.Sort(keys, values);

Here's the documentation Array.Sort(Array keys, Array items)




回答7:


Jon Skeet's and Marc Gravell♦'s answers provide the correct solution, but if you don't want to allocate an extra array you can:

a) solve you specific problem (shifting the 2nd half to be before the 1st half) in place:

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

Note that this code cannot deal with an array with odd number of items.

b) you can apply the vector shifting algorithm I know from Jon Bentley's 'Programming Pearls':

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

In your example the index would be 16. This code handles odd numbers of items and index not being in the middle. Using an example similar to the one used in the book for toRotate={0,1,2,3,4,5,6,7} and index = 3 Rotate2 would produce {3,4,5,6,7,0,1,2}.



来源:https://stackoverflow.com/questions/765863/how-to-shift-array-elements

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!