Necesito desplazar hacia la derecha y hacia la izquierda una matriz en N lugares.¿Implementación de cambio de matriz rápida en C#?
Los elementos que salen en el lado donde cambio deben volver al otro lado.
Shift derecho 13:
[0,1,2,3,4,5,6,7,8,9] -> [7,8,9,0,1,2,3,4,5,6]
Shift dejado por 15:
[0,1,2,3,4,5,6,7,8,9] -> [5,6,7,8,9,0,1,2,3,4]
Esta operación sucede a millones de veces y debe ser muy rápido.
Mi implementación actual es la siguiente. Eche un vistazo y sugiera si hay alguna optimización que hacer.
if (shift > 0)
{
int offset = array.Length % shift;
if (offset > 0)
{
byte[] temp = new byte[offset];
if (!right)
{
Array.Copy(array, temp, offset);
Array.Copy(array, offset, array, 0, array.Length - offset);
Array.Copy(temp, 0, array, array.Length - offset, temp.Length);
}
else
{
Array.Copy(array, array.Length - offset, temp, 0, offset);
Array.Copy(array, 0, array, offset, array.Length - offset);
Array.Copy(temp, 0, array, 0, temp.Length);
}
}
}
Como un consejo sobre cuánto va a obtener cambiado (pero dudo que puede conducir a la optimización):
- depends on the entropy of the array itself
- for aray that are full of same values it will get shifted roughtly 0
- more entropy means higher shift value
- direction of shift will be used generally more to the left
PS. No se puede obtener el permiso de seguridad para ejecutar código inseguro:/
PS2: la matriz resultante debe pasarse como una matriz hacia adelante a una biblioteca diferente para su posterior procesamiento, por lo que no puedo simplemente envolver y reindexar.
PS3: Prefiero trabajar en la misma matriz ya que el método usa ref
, y hacer eso en una nueva matriz y luego copiar de nuevo tomaría mucho tiempo (estoy usando la matriz 'temp' para la parte que se cae debido al cambio).
¿De verdad necesita cambiar la matriz? ¿No puedes hacer una envoltura que actúe como si la matriz se hubiera cambiado? – svick
No necesita un código inseguro. – SLaks
¿No sería posiblemente más eficiente no mover los elementos en absoluto, simplemente hacer un seguimiento de un índice y acceder de forma circular a los elementos sin copiarlos en ningún lugar? – aardvarkk