C# 大小为n的移位数组上的左旋转操作

C# 大小为n的移位数组上的左旋转操作,c#,arrays,rotation,C#,Arrays,Rotation,我尝试在大小为n的移位数组上实现左旋转。 例如,我有 数组={1,2,3,4,5} 我有很多班次: 班次=2 处理阵列后,它必须如下所示: 数组={3,4,5,1,2} 我用两个for循环实现了它: var array = new int[]{1,2,3,4,5}; var shifts =3; var temp = 0; for(var j = 0; j < shifts; j++){ temp = array[0]; for(var i = 0; i < ar

我尝试在大小为n的移位数组上实现左旋转。 例如,我有

数组={1,2,3,4,5}

我有很多班次:

班次=2

处理阵列后,它必须如下所示:

数组={3,4,5,1,2}

我用两个for循环实现了它:

var array = new int[]{1,2,3,4,5};
var shifts =3;
var temp = 0;
for(var j = 0; j < shifts; j++){
     temp = array[0];
     for(var i = 0; i < array.Length -1; i++){
         array[i] = array[i + 1];
     }
     array[array.Length-1] = temp;
}
for(var i =0 ; i< array.Length; i++){
    System.Console.Write(array[i]+ " ");
}
 Console.Read();
var数组=newint[]{1,2,3,4,5};
var位移=3;
var-temp=0;
对于(var j=0;j
它正在工作,但是它没有通过一些测试,数组中有大量的数字,我因为超时而被终止


有没有办法在一个循环中实现左旋转?

这是欺骗,但LINQ解决方案可能是:

var array = Enumerable.Range(0, 100).ToArray();
var shiftBy = 2;
var shifted = array.Skip(shiftBy).Concat(array.Take(shiftBy)).ToArray();

如果您的任务只是以这种转换的方式“查看”数组,为了避免创建新数组,请排除end
.ToArray()
并直接迭代
IEnumerable

这是欺骗,但LINQ解决方案可以是:

var array = Enumerable.Range(0, 100).ToArray();
var shiftBy = 2;
var shifted = array.Skip(shiftBy).Concat(array.Take(shiftBy)).ToArray();

如果您的任务只是以这种转换的方式“查看”数组,为了避免创建新数组,请排除end
.ToArray()
并直接迭代
IEnumerable

我认为这与在适当位置旋转数组一样有效。适用于左右旋转,具体取决于旋转的符号

private static void Rotate<T>(T[] array, int rotateBy)
{
    rotateBy %= array.Length;
    // Nothing to do?
    if (rotateBy == 0)
        return;
    // Normalize it to a right rotation
    if (rotateBy < 0)
        rotateBy = array.Length + rotateBy;
    // Allocate the smallest possible temp array
    if (rotateBy > array.Length / 2)
    {
        T[] temp = new T[array.Length - rotateBy];
        Array.Copy(array, 0, temp, 0, array.Length - rotateBy);
        Array.Copy(array, array.Length - rotateBy, array, 0, rotateBy);
        Array.Copy(temp, 0, array, rotateBy, array.Length - rotateBy);
    }
    else
    {
        T[] temp = new T[rotateBy];
        Array.Copy(array, array.Length - rotateBy, temp, 0, rotateBy);
        Array.Copy(array, 0, array, rotateBy, array.Length - rotateBy);
        Array.Copy(temp, 0, array, 0, rotateBy);  
    }
}
private static void Rotate(T[]数组,int rotateBy)
{
rotateBy%=数组长度;
//无事可做?
if(rotateBy==0)
回来
//将其规格化为右旋转
如果(旋转比<0)
rotateBy=数组。长度+rotateBy;
//分配尽可能小的临时数组
if(rotateBy>array.Length/2)
{
T[]温度=新的T[array.Length-rotateBy];
数组.Copy(数组,0,temp,0,数组.Length-rotateBy);
复制(数组,数组,长度-rotateBy,数组,0,rotateBy);
复制(temp,0,Array,rotateBy,Array.Length-rotateBy);
}
其他的
{
T[]温度=新的T[旋转比];
数组.Copy(数组,数组.Length-rotateBy,temp,0,rotateBy);
复制(Array,0,Array,rotateBy,Array.Length-rotateBy);
复制(临时,0,数组,0,旋转比);
}
}

我认为这与在适当位置旋转阵列一样有效。适用于左右旋转,具体取决于旋转的符号

private static void Rotate<T>(T[] array, int rotateBy)
{
    rotateBy %= array.Length;
    // Nothing to do?
    if (rotateBy == 0)
        return;
    // Normalize it to a right rotation
    if (rotateBy < 0)
        rotateBy = array.Length + rotateBy;
    // Allocate the smallest possible temp array
    if (rotateBy > array.Length / 2)
    {
        T[] temp = new T[array.Length - rotateBy];
        Array.Copy(array, 0, temp, 0, array.Length - rotateBy);
        Array.Copy(array, array.Length - rotateBy, array, 0, rotateBy);
        Array.Copy(temp, 0, array, rotateBy, array.Length - rotateBy);
    }
    else
    {
        T[] temp = new T[rotateBy];
        Array.Copy(array, array.Length - rotateBy, temp, 0, rotateBy);
        Array.Copy(array, 0, array, rotateBy, array.Length - rotateBy);
        Array.Copy(temp, 0, array, 0, rotateBy);  
    }
}
private static void Rotate(T[]数组,int rotateBy)
{
rotateBy%=数组长度;
//无事可做?
if(rotateBy==0)
回来
//将其规格化为右旋转
如果(旋转比<0)
rotateBy=数组。长度+rotateBy;
//分配尽可能小的临时数组
if(rotateBy>array.Length/2)
{
T[]温度=新的T[array.Length-rotateBy];
数组.Copy(数组,0,temp,0,数组.Length-rotateBy);
复制(数组,数组,长度-rotateBy,数组,0,rotateBy);
复制(temp,0,Array,rotateBy,Array.Length-rotateBy);
}
其他的
{
T[]温度=新的T[旋转比];
数组.Copy(数组,数组.Length-rotateBy,temp,0,rotateBy);
复制(Array,0,Array,rotateBy,Array.Length-rotateBy);
复制(临时,0,数组,0,旋转比);
}
}

使用大小与移位量相同的旋转缓冲器使其工作

static void ShiftLeft(int[] array, int shifts)
{
    int length = array.Length;
    int actualShifts = shifts % length;
    if (actualShifts == 0) return;
    int[] buffer = new int[actualShifts];
    Array.Copy(array, buffer, actualShifts);
    int indexAddition = actualShifts - (length % actualShifts);
    for (int i = length - 1; i >= 0; i--)
    {
        int current = array[i];
        int bufferIndex = (i + indexAddition) % actualShifts;
        array[i] = buffer[bufferIndex];
        buffer[bufferIndex] = current;
    }
}
编辑:正如@canton7所指出的,循环缓冲区增加了不必要的复杂性。下面应该是@canton7的答案,虽然@canton7由于缓冲区较小,他的答案仍然更有效:

int length = array.Length;
int actualShifts = shifts % length;
if (actualShifts == 0) return;
int[] buffer = new int[actualShifts];
Array.Copy(array, buffer, actualShifts);
Array.Copy(array, actualShifts, array, 0, length - actualShifts);
Array.Copy(buffer, 0, array, length - actualShifts, actualShifts);

让它使用一个旋转缓冲区来工作,这个缓冲区的大小和移位量一样

static void ShiftLeft(int[] array, int shifts)
{
    int length = array.Length;
    int actualShifts = shifts % length;
    if (actualShifts == 0) return;
    int[] buffer = new int[actualShifts];
    Array.Copy(array, buffer, actualShifts);
    int indexAddition = actualShifts - (length % actualShifts);
    for (int i = length - 1; i >= 0; i--)
    {
        int current = array[i];
        int bufferIndex = (i + indexAddition) % actualShifts;
        array[i] = buffer[bufferIndex];
        buffer[bufferIndex] = current;
    }
}
编辑:正如@canton7所指出的,循环缓冲区增加了不必要的复杂性。下面应该是@canton7的答案,虽然@canton7由于缓冲区较小,他的答案仍然更有效:

int length = array.Length;
int actualShifts = shifts % length;
if (actualShifts == 0) return;
int[] buffer = new int[actualShifts];
Array.Copy(array, buffer, actualShifts);
Array.Copy(array, actualShifts, array, 0, length - actualShifts);
Array.Copy(buffer, 0, array, length - actualShifts, actualShifts);
import java.util.*;
公共类排列{
公共静态void main(字符串[]args){
扫描仪sc=新的扫描仪(System.in);
System.out.println(“输入数组大小:”);
int n=sc.nextInt();
int arr[]=新的int[n];
System.out.println(“输入元素:”);
对于(inti=0;i
importjava.util.*;
公共类排列{
公共静态void main(字符串[]args){
扫描仪sc=新的扫描仪(System.in);
System.out.println(“输入数组大小:”);
int n=sc.nextInt();
int arr[]=新的int[n];
System.out.println(“输入元素:”);

对于(int i=0;i)我在谷歌上搜索了20秒:如果生成一个新数组是可以接受的,那么Patrick的解决方案对于大型数组会更快。如果您需要执行就地移位,那么您可以使用该解决方案的组合来提取第一个“移位”元素进入临时数组,然后在单个循环中循环通过数组,通过“shift”移动元素,然后在末尾插入临时值。@PaulF,如果可以使用
IEnumerable
进一步操作,则可以通过排除
.ToArray()来避免新数组
。30秒后谷歌搜索:如果可以生成一个新数组,那么Patrick的解决方案对于大型数组会更快。如果您需要执行就地移位,那么您可以使用该解决方案的组合来提取第一个“移位”元素进入临时数组,然后在单个循环中循环通过数组,通过“shift”移动元素,然后在末尾插入临时值。@PaulF,如果可以使用
IEnumerable
进一步操作,则可以通过排除
.ToA来避免新数组