首页 > 试题广场 >

编写一个函数,作用是把一个char组成的字符串循环右移n个。

[问答题]
编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefg” 函数头是这样的:
//pStr是指向以'\0'结尾的字符串的指针
//steps是要求移动的n
void LoopMove ( char * pStr, int steps ) 
{ 
 //请填充... 
} 
#include<iostream>
#include<string>
using namespace std;
void LoopMove ( char * pStr, int steps )
{
int a=strlen(pStr);
char * b=(char*)malloc(a+1);
int c;
for(int i=0;i<a;i++)
{
c=(i+steps)%a;
b[c]=pStr[i];
}
cout<<b<<endl;
}
int main()
{
char * d="qwerty";
LoopMove(d,3);
return 0;
}
编辑于 2017-09-07 09:40:51 回复(0)
更多回答
void LoopMove(char *pStr, int steps){
	assert(pStr != NULL);
	int n=strlen(pStr);
	if (steps >= 0){
		for (int i = 0; i < steps; i++){
			char temp = pStr[n - 1];
			for (int j = n - 1; j > 0; j--){
				pStr[j] = pStr[j-1];
			}
			pStr[0] = temp;
		}
	}
	else{
		steps = -steps;
		for (int i = 0; i < steps; i++){
			char temp = pStr[0];
			for (int j = 0; j < n-1; j++){
				pStr[j] = pStr[j + 1];
			}
			pStr[n - 1] = temp;
		}
	}
}

发表于 2016-07-20 20:25:33 回复(3)
答案不够严谨,n可能为负数。
#include <stdio.h>
#include <string.h>

//pStr是指向以'\0'结尾的字符串的指针
//steps是要求移动的n
void LoopMove(char * pStr, int steps)
{
	int len = strlen(pStr);
	int st = steps % len; // 取余
        // 字符串长度为0,或不需移动,或移动步数小于等于0.返回,也可报错。
	if (len == 0 || st == 0 || steps <= 0) return;
	char temp[100] = {0};
	memcpy(temp, pStr+len-st, st);
	memcpy(temp+st, pStr, len-st);
	memcpy(pStr, temp, len);
}

int main()
{
    char s[128] = "abcd";
    LoopMove(s, 5);
    printf("%s\n", s);
    return 0;
}


发表于 2017-03-05 18:30:58 回复(7)
void LoopMove ( char *pStr, int steps )
{
 if(!pStr || steps<0) //非法输入
 return;
 int nLen=strlen(pStr);
 if(0 == steps%/nLen) //能整除时不需移动
 return;
 char szTmp[MAX_LEN];
 int nStep=steps%nLen;
 memcpy(szTmp,&pStr[nLen-nStep],nStep);
 memcpy(&pStr[nLen-nStep],pStr,nLen-nStep);
 memcpy(pStr,szTmp,nStep);
} 
strcpy遇\0结束,可能会有问题。  当steps大于len时,需要做保护。用memcpy或者memmove保险.
发表于 2015-12-13 15:02:35 回复(3)
#include <iostream>
#include <string.h>

using namespace std;

void Reverse(char **pStr, int begin, int end)
{
    while(begin < end - 1)
    {
        swap((*pStr)[begin], (*pStr)[end-1]);
        begin++;
        end--;
    }
}

void LoopMove(char *pStr, int steps)
{
    if(pStr == NULL || steps < 1)
        return;
    int len = strlen(pStr);
    steps = steps % len;
    Reverse(&pStr, 0, len - steps);
    Reverse(&pStr, len - steps, len);
    Reverse(&pStr, 0, len);
}

int main()
{
    char pStr[] = "abcdef";
    LoopMove(pStr, 2);
    cout << pStr << endl;
    return 0;
}

发表于 2018-03-28 21:59:27 回复(0)
void Swap(char &a, char &b)
{
	char temp = a;
	a = b;
	b = temp;
}

void Reverse(char **pStr, int beg, int end)
{
	while (beg < end-1)
	{
		Swap((*pStr)[beg], (*pStr[end - 1]));
		beg++;
		end--;
	}
}
//step是右移的步数
void LoopMove(char *pStr, int steps)
{
	int len = strlen(pStr);
	Reverse(&pStr, 0, len - steps);
	Reverse(&pStr, len - steps, len);
	Reverse(&pStr, 0, len);
}
仅表示思路,没考虑输入出错的情况
发表于 2016-09-11 14:15:21 回复(1)
加上括号12行,一条龙服务。参考答案忽略了steps可能大于字符串长度的情况
为了方便测试代码返回了char*
char* LoopChar(char* str, int steps) {     if (str == NULL || steps<0)         return NULL;     int num = strlen(str);     char* strtmp = new char[2*num+1];     char* fstr = strcat(strcpy(strtmp, str),str);     int fsteps = steps % num;     for (int k = 0; k < num; k++) {         str[k] = fstr[k+num-fsteps];     }     return str; }
编辑于 2017-10-12 21:02:20 回复(1)
void LoopMove(char*pstr,int steps)
{
if(pstr==NULL||steps<=0)exit(1);
int len=strlen(pstr);
char *p=(char*)malloc(len+1);
if(p==NULL) return ;

memset(p,0,len+1);
memcpy(p,pstr+len-steps,steps);
pstr[len-steps]='\0';
strcat(p,pstr);
memcpy(pstr,p,len+1);
}

发表于 2017-07-03 02:29:17 回复(0)
#include<iostream>  
#include<iomanip>  
#include <assert.h>
using namespace std;
#define MAXLEN 20



void LoopMove1(char *pStr, int steps)
{
	assert(pStr != NULL);
	int len = strlen(pStr);
	int remain = len - steps;

	char tmp[MAXLEN];//[];
	strcpy(tmp, pStr + remain);
	strcpy(tmp + steps, pStr);
	tmp[len] = '\0';

	strcpy(pStr, tmp);
}

void LoopMove2(char *pStr, int steps)
{
	assert(pStr != NULL);
	int len = strlen(pStr);
	int remain = len - steps;

	char tmp[MAXLEN];
	memcpy(tmp, pStr + remain, steps);
	memcpy(tmp + steps, pStr, remain);
	memcpy(pStr, tmp, len);
}

int main()
{
	char a1[] = "abcdefghi";
	char a2[] = "abcdefghi";

	LoopMove1(a1, 2);
	char*b = a1;

	LoopMove2(a2, 2);
	char*c = a2;

	return 0;
}
测了没问题。

有个疑问:
1. 最后一行为什么不能pStr = tmp
而是需要
memcpy(pStr, tmp, len); 或 strcpy(pStr, tmp);
发表于 2017-06-13 21:16:04 回复(4)
void loopMove ( char * pStr, int steps )
{
     int i = 0;     
     int len = strlen(pStr);

     char *tmp = (char*)malloc(sizeof(char)*len); strcpy(tmp, pStr);

     for (i=0; i<len; i++) {
         tmp[(i+steps)%len] = pStr[i];
     }

     cout<<tmp<<endl;

     free(tmp);
     tmp = NULL;
}
编辑于 2017-05-04 08:46:31 回复(0)
#include<iostream>
using namespace std;
void LoopMoveChar(char* ch, int K)
{
	if (ch == nullptr || K <= 0)
		return;
	int length = strlen(ch);

	//循环移位长度超过字符串长度
		if(K>length)
			K = K % length;

	char temp[255];//存放后面会被覆盖的值
	for (int i = 0; i < K; ++i)
		temp[i] = ch[length - K + i];

	for (int i = length - 1; i >K-1; --i)//从后向前依次获得移位后的字符
		ch[i] = ch[i - K];

	for (int i = 0; i < K; ++i)//前K个值
		ch[i] = temp[i];

}

发表于 2016-08-24 20:31:08 回复(0)
正确解答1:  
void LoopMove ( char *pStr, int steps ) 
{ 
 int n = strlen( pStr ) - steps; 
 char tmp[MAX_LEN];  
 strcpy ( tmp, pStr + n );  
 strcpy ( tmp + steps, pStr);  
 *( tmp + strlen ( pStr ) ) = '\0'; 
 strcpy( pStr, tmp ); 
} 
正确解答2:  
void LoopMove ( char *pStr, int steps ) 
{ 
 int n = strlen( pStr ) - steps; 
 char tmp[MAX_LEN];  
 memcpy( tmp, pStr + n, steps );  
 memcpy(pStr + steps, pStr, n );  
 memcpy(pStr, tmp, steps );  
} 
【剖析】  
这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。  
最频繁被使用的库函数包括:  
(1) strcpy  
(2) memcpy  
(3) memset  
发表于 2015-10-28 18:03:58 回复(12)
发表于 2016-07-19 22:46:49 回复(8)
NWU头像 NWU

原型声明 功能
char *strcpy(char* dest, const  char *src);
把从src地址开始且含有NULL结束符的字符串复
制到以dest开始的地址空间
void *memset(void *s,int c,size_t n)
将已开辟内存空间 s 的首 n 个字节的值设为值  c


原型声明:
void *memcpy(void *dest, const void *src, size_t n);
功能:
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
发表于 2015-12-22 20:11:11 回复(0)
void LoopMove(char*pStr,int steps)
{
    steps%=strlen(pStr);//万一输入的数大于字符长度时的处理
    int len=strlen(pStr)-steps;
    char temp[105];
    memcpy(temp,pStr+len,steps);
    memcpy(temp+steps,pStr,len);
    memcpy(pStr,temp,strlen(pStr));
}
发表于 2021-11-21 19:20:11 回复(0)
循环左移或右移都可以用三次逆置完成,先两次小的部分逆置,然后整体逆置一次。两个小的部分以实际需要移动的step划分
发表于 2020-04-15 17:50:26 回复(0)
注意注意
发表于 2020-04-05 17:52:22 回复(0)
str作为形参,不是传副本吗,在函数里面对它的修改如何起效?
发表于 2020-03-13 09:53:49 回复(1)
首先是对steps的判断,小于0和大于字符串时的处理,然后有两种方法,一种是将须后移的字符串长度反转,再将剩余反转,最后一起反转;另一种是,用一新字符数组将后面移到前面,再将前面移到后面最后整体输出。
发表于 2019-12-10 14:22:36 回复(0)

为什memcpy最后的拷贝数量是steps,不理解!请教大神!

发表于 2019-09-24 08:07:59 回复(0)