我尝试在大小为n个移位的数组上实现向左旋转。 例如,我有
array = {1,2,3,4,5};
我有很多班次:
shifts = 2;
处理完数组后,它必须像这样:
array = {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();
它可以正常工作,但是它没有通过数组中包含大量数字的测试,因此我由于超时而终止错误;
有没有办法在一个循环中实现左旋转?
答案 0 :(得分:3)
我认为这与就地旋转数组一样有效。可以左右旋转,具体取决于rotateBy
的符号:
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);
}
}
答案 1 :(得分:2)
这是作弊,但是LINQ解决方案可能是:
var array = Enumerable.Range(0, 100).ToArray();
var shiftBy = 2;
var shifted = array.Skip(shiftBy).Concat(array.Take(shiftBy)).ToArray();
如果您的任务只是以这种转换后的方式“查看”数组,为避免创建新数组,请排除结尾.ToArray()
并直接遍历IEnumerable<int>
。
答案 2 :(得分: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);
答案 3 :(得分:0)
import java.util.*;
public class ArrayRotation{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("enter size of array:");
int n=sc.nextInt();
int arr[]=new int[n];
System.out.println("enter elements:");
for(int i=0;i<n;i++)
arr[i]=sc.nextInt();
System.out.println("enter shifts:");
int d=sc.nextInt();
int arr1[]=new int[d];
for(int i=0;i<d;i++)
arr1[i]=arr[i];
System.out.println("Array after rotating");
for(int i=d;i<n;i++)
System.out.print(arr[i]+" ");
for(int i=0;i<d;i++)
System.out.print(arr1[i]+" ");
}
}