rhkvik
rhkvik

Reputation: 101

how to rotate the given string to left or right in C?

C function to rotate a string by a given number to the right or to the left. When a character is rotated past the end or the beginning of a string depending on the direction, it should wrap around

Upvotes: 3

Views: 12972

Answers (4)

Alex Reynolds
Alex Reynolds

Reputation: 96937

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* strrot (int offset, size_t size, const char *inStr);

int main (int argc, const char * argv[]) {
    const char *rotStr = "rotateme";
    size_t rotStrSize = strlen(rotStr);
    char *resultStr;

    resultStr = strrot(-3, rotStrSize, rotStr);
    printf("-3, %s\n", resultStr);
    free(resultStr);

    resultStr = strrot(2, rotStrSize, rotStr);
    printf("+2, %s\n", resultStr);
    free(resultStr);

    resultStr = strrot(11, rotStrSize, rotStr);
    printf("+11, %s\n", resultStr);
    free(resultStr);

    resultStr = strrot(0, rotStrSize, rotStr);
    printf("0, %s\n", resultStr);
    free(resultStr);

    resultStr = strrot(-11, rotStrSize, rotStr);
    printf("-11, %s\n", resultStr);
    free(resultStr);

    return 0;
}

char* strrot (int offset, size_t size, const char *inStr) {
    char *result = (char *)malloc(size * sizeof(char));
    int trueOffset = size - (offset % size);

    int inIndex = trueOffset;
    int outIndex = 0;

    for (inIndex = trueOffset; inIndex < (int)size; inIndex++, outIndex++) {
        result[outIndex] = inStr[inIndex];
    }
    for (inIndex = 0; inIndex < trueOffset; inIndex++, outIndex++) {
        result[outIndex] = inStr[inIndex];
    }

    result[(int)size] = '\0';

    return result;
}

Results:

-3, atemerot
+2, merotate
+11, emerotat
0, rotateme
-11, atemerot

Upvotes: 0

barkmadley
barkmadley

Reputation: 5297

given a string str which has length length and a rotation amount n

rotate left is equivalent to

reverse(str, 0, n);
reverse(str, n, length);
reverse(str, 0, length);

rotate right is equivalent to

reverse(str, 0, length - n);
reverse(str, length - n, length);
reverse(str, 0, length);

Now you just need a reverse function.

Update: I thought of how you can use mod's to make you always rotate in the right direction depending on the sign of n.

e.g.

int mod = n % length;
if (mod != 0) { //if 0, don't rotate
    reverse(str, 0, mod);
    reverse(str, mod, length);
    reverse(str, 0, length);
}

going through the various cases

if n == 5 and length = 10, mod = 5

if n == 16 and length = 10, mod = 6 -- rotating left by 16 = rotating left by 6

if n == 0 and length = anything, mod = 0

if n == -1 and length = 10, mod = 9 -- rotating right by 1 is the same as rotating left by 9

if n == -15 and length = 9, mod = 3 -- rotating right by 15 is the same as rotating left by 3

Upvotes: 11

Blindy
Blindy

Reputation: 67380

I'd do something like this:

void rot(char *buf, int len, int r)
{
  char *temp=malloc(r>=0?r:-r);
  if(r>=0)
  {
    memcpy(temp, buf+len-r, r);
    memmove(buf+r, buf, len-r);
    memcpy(buf, temp, r);
  }
  else
  {
    memcpy(temp, buf, r);
    memmove(buf, buf+r, len-r);
    memcpy(buf+len-r, temp, r);
  }

  free(temp);
}

provided of course that r<len, len is at least 1, you know, normal sanitation checks.

Upvotes: 2

Related Questions