Reputation: 6446
I've got an homework assignment:
need to implement a function (RotateRight) that gets an array of INT and a number:
int[] res = RotateRight(new int[] { 1, 2, 3, 4, 5, 6 }, 2);
//so then res will be {5,6,1,2,3,4}
and return the array after rotating all of the items to the right according to the number that been given, In our case 2.
And I have to do this efficiently in terms of memory space.
my best idea is:
if the number that been given is x, to use a new int[] tmpArray in the size of x to copy all the last x items to it. then with a for loop to shift all the rest of the int to the right. And in the end to copy the items in the tmpArray to the begining of the original array.
Thanks in advance for any advice or help
Upvotes: 7
Views: 7319
Reputation: 8827
C# 8 now has Indices and Ranges
Rotate Right...
int[] r = t[1..].Concat(t[0..1]).ToArray();
Rotate Left...
int[] r = t[^1..^0].Concat(t[..^1]).ToArray();
in place of the "1" above, a variable can also be used: int[] r = t[amt..].Concat(t[0..amt]).ToArray();
Upvotes: 0
Reputation: 463
Here's a quick sample on rotating an array A right K steps:
var splitPoint=A.Length-(K%A.Length);
var result=new int[A.Length];
int idx=0;
for(var pos=0;pos<A.Length;pos++)
{
if(pos<A.Length-splitPoint)
{
result[pos]=A[splitPoint+pos];
}
else
{
result[pos]=A[idx];
idx++;
}
}
return result;
Upvotes: 0
Reputation: 523
You just need to figure out the final index for each element after rotating it k times rather than actually rotating it k times. This worked for me:
for(int i=0;i<a.Length;i++){
rotated[(k+i)%(a.Length)]=a[i];
}
Upvotes: 0
Reputation: 16888
Don't know C#, but here are two C++ versions, both in place, the first (rotate
) does the minimum possible number of element moves by exploiting the cyclic structure of the rotation permutation, the second (rotate_k
) just does 2*n
moves for an array of length n
. In both versions it's used that rotate right by k
is the same as rotate left by n - k % n
, so they in fact do the equivalent left rotation.
#include <iostream>
#include <vector>
#include <algorithm>
void
rotate (size_t k, std::vector<int> &a) {
size_t n = a.size();
k = n - k % n;
size_t m = n;
size_t i = 0;
while (m > 0) {
int t = a[i];
size_t j = i;
while (i != (j + k) % n) {
a[j] = a[(j + k) % n];
j = (j + k) % n;
--m;
}
a[j] = t;
--m;
++i;
}
}
void
rotate_k (size_t k, std::vector<int> &a) {
size_t n = a.size();
k = n - k % n;
std::reverse (a.begin(), a.end());
std::reverse (a.begin(), a.begin() + n - k);
std::reverse (a.begin() + n - k, a.end());
}
int
main () {
std::vector<int> a = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
rotate (12, a);
for (auto i : a)
std::cout << i << " ";
std::cout << std::endl;
}
Upvotes: 0
Reputation: 1963
Most memory possible makes no sense, you probably mean as little memory as possible? If so you should swap each item in the array using XOR, i.e:
var a = 2096;
var b = 842390;
a ^= b;
b ^= a;
a ^= b;
would swap these numbers.
EDIT
Code to do the whole thing in place:
public static void RotateRight(int[] input, int right)
{
for (var i = 0; i < right; i += 1)
{
RotateRightOne(input);
}
}
public static void RotateRightOne(int[] input)
{
var last = input.Length - 1;
for (var i = 0; i < last; i += 1)
{
input[i] ^= input[last];
input[last] ^= input[i];
input[i] ^= input[last];
}
}
Usage:
var arr = new[] {1, 2, 3, 4, 5, 6};
RotateRight(arr, 2);
As Servy points out, this is only for integers
Upvotes: 1
Reputation: 17058
You can use the beauty of the Linq langage to return an IEnumerable without dealing with array size:
/// <summary>
/// Get c = a mod (b) with c in [0, b[ like the mathematical definition
/// </summary>
public static int MathMod(int a, int b)
{
int c = ((a % b) + b) % b;
return c;
}
public static IEnumerable<T> ShiftRight<T>(IList<T> values, int shift)
{
for (int index = 0; index < values.Count; index++)
{
yield return values[MathMod(index - shift, values.Count)];
}
}
Usage :
[TestMethod]
public void TestMethod1()
{
var res = ShiftRight(new [] { 1, 2, 3, 4, 5, 6 }, 2).ToArray();
Assert.IsTrue(res.SequenceEqual(new[] { 5, 6, 1, 2, 3, 4 }));
}
Upvotes: 5