我的解决方案使用了O旋转串代替(1)存储:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void rotleftmem(void *p, size_t len, size_t lshift)
{
unsigned char *d;
size_t start;
size_t dx, sx;
size_t todo;
unsigned char x;
if (!len)
return;
lshift %= len;
if (!lshift)
return;
d = p;
todo = len;
for (start = 0; todo; start++) {
x = d[start];
dx = start;
while (1) {
todo--;
sx = dx + lshift;
if (sx >= len || sx < dx /*overflow*/)
sx -= len;
if (sx == start) {
d[dx] = x;
break;
}
d[dx] = d[sx];
dx = sx;
}
}
}
void *rotatemem(void *p, size_t len, ssize_t rshift)
{
if (len) {
size_t lshift = rshift < 0 ? -rshift : len - rshift % len;
rotleftmem(p, len, lshift);
}
return p;
}
char *rotatestr(char *s, ssize_t rshift)
{
return rotatemem(s, strlen(s), rshift);
}
int main(int argc, char *argv[])
{
ssize_t rshift;
char *s;
if (argc != 3) {
fprintf(stderr,
"usage: %s N STR\n"
"Rotate STR right by N or left by -N\n",
argv[0]);
return 2;
}
rshift = strtol(argv[1], NULL, 10);
s = argv[2];
printf("%s\n", rotatestr(s, rshift));
return 0;
}
代码的胆是在功能rotleftmem
,其旋转的存储器块指定的长度留下一个指定的,无符号的“左移”值。 rotatemem
是围绕rotleftmem
围绕任一方向旋转的包装;负移位值向左旋转,正移位值向右旋转;带符号的移位值被转换为正的“左移”值。 rotatestr
是一个围绕rotatemem
的包装,它接受一个指向空终止字符串的指针,而不是指向void加长度的指针。 rotatestr
和rotatemem
都返回原始指针。
对于rotleftmem
,如果块长度(len
)是非零的,“左移位”的值(lshift
)降低模len
。如果len
或(减少的)lshift
值中的任一值为0,则该函数不执行任何操作。否则,外环将迭代GCD(len, lshift)
次(其中GCD(a, b)
是a
和b
最大公约数)。对于外部循环的每次迭代,内部循环将迭代len/GCD(len, lshift)
次,因此内部循环的迭代总数为len
。时间复杂度是O(n),其中n是块的长度。
“不起作用”不是一个明确的问题陈述。你能否用更具体的问题陈述来编辑你的问题? –
'buff [n] ='\ 0''中的n是什么?它与什么有关? – AnT
修复您的功能签名。这不是标准。 –