Domanda

Ho una matrice di n = 32 elementi con valori positivi e negativi.I primi n/2 elementi sono positivi e ordinati per valore e i secondi n/2 elementi sono negativi e anch'essi ordinati per valore.Vorrei ordinare l'intero array per valore, partendo dal valore negativo più piccolo fino al valore positivo più grande, il che significa che se ci sono 32 elementi i primi 16 (n/2) elementi ordinati dovrebbero contenere i valori dei secondi 16 elementi dell'array originale e i secondi 16 elementi dell'array ordinato dovrebbero contenere i primi 16 valori dell'array originale.

Esempio ipotetico:

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

Qualcuno sa qual è il modo migliore per spostare gli elementi per generare l'array ordinato dall'originale?

Questo array è comunque legato a un altro array che non ha gli elementi ordinati per dimensione nello stesso modo e deve essere spostato nello stesso modo dell'originale, quindi l'array non deve essere ordinato per dimensione, deve essere spostato.

È stato utile?

Soluzione

Quindi vuoi un secondo array, con il contenuto dell'originale ma nelle posizioni spostate?O farlo esplicitamente:

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

o utilizzando Array.Copy due volte:

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

Altri suggerimenti

Data la natura rigida del problema, Array.Copy:

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

Che ne dici di Linq:

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

Hai provato:

Array.Sort(original);

Basta fare uno scambio tra l'elemento 0 e l'elemento 16, 1 e 17, 2 e 18..eccetera.

Vuoi ordinare un array in base ai valori contenuti in un altro array della stessa dimensione?In tal caso, utilizzare quanto segue:

Array.Sort(keys, values);

Ecco la documentazione Array.Sort(Chiavi dell'array, Elementi dell'array)

Le risposte di Jon Skeet e Marc Gravell♦ forniscono la soluzione corretta, ma se non vuoi allocare un array aggiuntivo puoi:

a) risolvere il problema specifico (spostare la seconda metà prima della prima metà) sul posto:

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

Tieni presente che questo codice non può gestire un array con un numero dispari di elementi.

b) puoi applicare l'algoritmo di spostamento vettoriale che conosco da "Programming Pearls" di Jon Bentley:

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

Nel tuo esempio l'indice sarebbe 16.Questo codice gestisce numeri dispari di elementi e l'indice non si trova nel mezzo.Usando un esempio simile a quello usato nel libro per toRotate={0,1,2,3,4,5,6,7} e indice = 3 Ruota2 produrrebbe {3,4,5,6,7,0,1,2}.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top