Suppose I have an array
unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9};
Is there a way to perform shift operation on them besides just copying them all into another array. We can easily do it using linked lists but I was wondering if we can use a shift operator and get work done faster.
Note: The data in this question is just an example. The answer should be irrecpective of the data in the array.
The block swap algorithm for array rotation is an efficient algorithm that is used for array rotation. It can do your work in O(n) time complexity. So, in array rotation, we are given an array arr[] of size n and a number k that define the no.
An array is said to be right rotated if all elements of the array are moved to its right by one position. One approach is to loop through the array by shifting each element of the array to its next position. The last element of the array will become the first element of the rotated array.
The shift() method removes the first element from an array and returns that removed element.
If you're looking for a pure C solution, here it is, including a driver program. It turns out to be pretty simple: to rotate by n
, you:
n
elements in-place,This requires one element worth of extra storage (for reversing).
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
/* print an array */
static void print_array(unsigned char *arr, size_t n, const char *prefix)
{
size_t i;
if (prefix) {
printf("%s: ", prefix);
}
for (i=0; i < n; ++i) {
printf("%02x ", (unsigned int)arr[i]);
}
printf("\n");
}
/* reverse 'arr', which has 'narr' elements */
static void reverse(unsigned char *arr, size_t narr)
{
size_t i;
for (i=0; i < narr / 2; ++i) {
unsigned char tmp = arr[i];
arr[i] = arr[narr-i-1];
arr[narr-i-1] = tmp;
}
}
/* rotate 'arr' of size 'narr' by 'shift' */
static void rotate(unsigned char *arr, size_t narr, unsigned long shift)
{
reverse(arr, shift);
reverse(arr + shift, narr - shift);
reverse(arr, narr);
}
/* driver program */
int main(int argc, char *argv[])
{
unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9,10};
size_t narr = sizeof arr / sizeof arr[0];
unsigned long shift = 2;
if (argc > 1) {
char *eptr;
shift = strtoul(argv[1], &eptr, 0);
if (*eptr || errno == ERANGE) {
perror("strtoul");
return EXIT_FAILURE;
}
}
print_array(arr, narr, "before shift");
rotate(arr, narr, shift);
print_array(arr, narr, "after shift");
return EXIT_SUCCESS;
}
If you want a circular shift of the elements:
std::rotate(&arr[0], &arr[1], &arr[10]);
... will do the trick. You'll need to #include the algorithm header.
As long as the array is modifiable, you can use memmove to shift them (but don't mistakenly use memcpy as memcpy is not meant for overlapping regions):
memmove(&arr[0], &arr[1], sizeof(arr) - sizeof(*arr));
(sizeof(arr) - sizeof(*arr) is the size in bytes of all but 1 element of the array).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With