用C语言旋转字符串
我尝试将字符串左右移动,给定要移动字符串的位置数 这是我到目前为止写的,但它不起作用用C语言旋转字符串,c,string,C,String,我尝试将字符串左右移动,给定要移动字符串的位置数 这是我到目前为止写的,但它不起作用 void Shift(char* string, shift) { int length = strlen(string)-1; int i; char *buff; buff = malloc((sizeof(char) *shift) + 1); strncpy(buff, string, shift); buff[shift] = '/0'; whi
void Shift(char* string, shift)
{
int length = strlen(string)-1;
int i;
char *buff;
buff = malloc((sizeof(char) *shift) + 1);
strncpy(buff, string, shift);
buff[shift] = '/0';
while (string[i + shift] != '/0')
string[i++] = string[i + shift];
strcat(string, buff);
}
我怎样才能解决这个问题?
这应该是一个例子:
移位=1
你好->
OHELL我的解决方案是基于模的,使用负数向左移位,使用正数向右移位
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
void shift(char* string, int shift)
{
char *tmp = strdup(string);
int len = strlen(string);
if (shift < 0)
shift = len + (shift % len);
for (int i = 0; string[i] != 0; i++) {
int new_idx = (i + shift) % len;
tmp[new_idx] = string[i];
}
memcpy(string, tmp, len);
free(tmp);
}
int main(void) {
char test[] = "coucou";
shift(test, -9);
printf("%s\n", test);
return 0;
}
#包括
#包括
#包括
#包括
无效移位(字符*字符串,整数移位)
{
char*tmp=strdup(字符串);
int len=strlen(字符串);
如果(移位<0)
移位=len+(移位%len);
for(int i=0;字符串[i]!=0;i++){
int new_idx=(i+shift)%len;
tmp[new_idx]=字符串[i];
}
memcpy(字符串、tmp、len);
免费(tmp);
}
内部主(空){
字符测试[]=“coucou”;
班次(试验-9);
printf(“%s\n”,测试);
返回0;
}
诀窍是计算每个字符在目标字符串中的结束位置。通过使用总大小的模,您可以确保它保持在边界之间,从而添加偏移量,然后确保它保持在边界内,从而给出正确的索引
对于左移位,我只是将左移位偏移转换为右移位偏移,并重新使用右移位代码 您可以使用XOR逐位运算符交换字符并循环以反转字符
#include <stdio.h>
#include <stdlib.h>
void reverse(char *a, int n) {
for (int i=0, j=n-1; i < j; i++, j--) {
a[i] = a[i] ^ a[j];
a[j] = a[j] ^ a[i];
a[i] = a[i] ^ a[j];
}
}
int main(int argc, char const *argv[]) {
int k = 1; // shift count
int n = 5;
char a[] = "HELLO";
reverse(&a[n-k], k); // reverse end of array
reverse(a, n-k); // reverse beginning of array
reverse(a, n); // reverse entire array
// print output
for (int i=0; i < n; i++) {
printf("%c\n", a[i]);
}
return 0;
#包括
#包括
无效反向(字符*a,整数n){
对于(int i=0,j=n-1;i
}我的解决方案使用O(1)存储将字符串旋转到位:
#包括
#包括
#包括
void rotleftmem(void*p,大小长度,大小移位)
{
无符号字符*d;
开始时的尺寸;
尺寸dx,sx;
待办事项的规模;
无符号字符x;
如果(!len)
返回;
lshift%=len;
如果(!lshift)
返回;
d=p;
todo=len;
对于(开始=0;todo;开始++){
x=d[开始];
dx=开始;
而(1){
待办事项--;
sx=dx+l换档;
如果(sx>=len | | sx
代码的核心是函数rotleftmem
,它将指定长度的内存块向左旋转一个指定的、无符号的“左移位”值rotatemem
是围绕rotleftmem
的一个包装器,可沿任意方向旋转;负移位值向左旋转,正移位值向右旋转;符号移位值转换为正“左移位”值rotatestr
是一个围绕rotateM
的包装器,它使用指向以null结尾的字符串的指针,而不是指向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
是什么?它与什么有什么关系?修复你的函数签名。它不是标准的。它被称为字符串的“旋转”。这个线程是一场灾难。这个问题非常不完整:只是一个普通的“呃,它不起作用”,没有任何东西可以建立,评论是在一辆高速行驶的火车上,指向完全不同的地方,而且到目前为止发布的所有答案都没有解释原答案的错误而丢弃了代码。a[i]^=a[j]^=a[i]^=a[j]代码>具有未定义的行为。每个作业之间需要一个序列点。@IanAbbott我继续并扩展了它。现在应该定义操作顺序。三异或交换是一种反模式。它执行了太多的内存写入,并创建了一个干扰流水线的错误依赖项。只是使用一个临时的;这些日子里寄存器很多,所以你最好使用一个。如果要加快反转速度,请使用SIMD指令在最近的CPU上一次反转16个字节(每端8个字节),甚至更多。
#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;
}