一个长度为len的字符串,对其循环右移n位

[期望]
char str[] = "abcdefg";
右移3次后,变成"efgabcd"

[思路]

思路1.

如果用每移动一次,就要把整个字符串整体移动一次的方法,显得太费劲了。
我们可以用空间换时间,通过内存拷贝来实现。
需要新申请一块相同大小的内存,把原字符串的后n个字节拷贝到它的开始地址,把原字符串的前(len-n)个字节拷贝到它的(开始地址+n)处。

为便于查看结果,我们先定义一个打印字符串的函数void print_str(char *str);

void print_str(char *str)
{
int i,len;
if (str == NULL) {
return;
}
len = strlen(str);
for(i=; i<len; i++) {
printf("%c",str[i]);
}
printf("\n");
}

print_str

思路1的代码实现:

#include <stdio.h>
#include <string.h>
#include <stdlib.h> void print_str(char *str)
{
int i,len;
if (str == NULL) {
return;
}
len = strlen(str);
for(i=; i<len; i++) {
printf("%c",str[i]);
}
printf("\n");
} int str_rshift_1(char *str, int n)
{
int len;
char *tmp; len = strlen(str);
if (len < n) {
return ;
} tmp = (char *)malloc(len);
if (tmp == NULL) {
return ;
} memcpy(tmp, str+len-n, n);
memcpy(tmp+n, str, len-n);
memcpy(str, tmp, len);
free(tmp);
str[len] = '\0';
return ;
} void str_rshift_1_test()
{
char str[] = "abcdefg";
str_rshift_1(str, );
print_str(str);
} void main()
{
str_rshift_1_test();
}

思路2.

来自《编程珠玑》里的算法,利用字符串的逆序来实现。
比如字符串"abcdefg",要循环右移3位,那么这个字符串可以分为2部分:
前半部分:"abcd" 和后半部分 "efg"。
我们先把前半部分逆序变成   ->         "dcba"
再把后半部分逆序变成->                        "gfe"
这时整体字符串应该是                     "dcbagfe"
我们再对整个字符串逆序一遍,结果-> "efgabcd"。
bingo,循环右移完成。

总结一下,总共要进行3次逆序:前半部分逆序,后半部分逆序,整体逆序。
逆序用到的函数原型是void str_reverse(char *str, int left, int right);它的实现在这里

思路2的代码实现:

int str_rshift_2(char *str, int n)
{
int len = strlen(str); if (len < n) {
return ;
} str_reverse(str, , len-n-);
str_reverse(str, len-n, len-);
str_reverse(str, , len-);
return ;
} void str_rshift_2_test()
{ char str[] = "abcdefg";
str_rshift_2(str, );
print_str(str);
} void main()
{
str_rshift_2_test(); }

字符串循环右移-c语言的更多相关文章

  1. 字符串循环右移N位

    给一个长度为n的字符串,把这个字符串循环右移N位(0<N<n),要求只用O(1)的额外空间和O(N)时间,有些什么方法 一开始想到的是先保存temp=s[0],在左起第N个移到s[0]的位 ...

  2. 用C语言实现循环左移和循环右移

    有天重建一段代码时,遇到了循环右移指令,不知道用C语言怎么实现,后来得到小伟指点,感谢.. me 15:56:38004BD2C9 8B55 F8 MOV EDX,DWORD PTR SS:[EBP- ...

  3. PAT自测_打印沙漏、素数对猜想、数组元素循环右移、数字加倍重排、机器洗牌

    -自测1. 打印沙漏() 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号 ...

  4. PAT 1008. 数组元素循环右移问题 (20)

    一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0 A1--AN-1)变换为(AN-M -- AN-1 A0 ...

  5. 线性表(一)——数组循环右移算法

    源码:rshift.cpp #include "stdafx.h" #include <stdio.h> /****************************** ...

  6. PAT乙级 1008. 数组元素循环右移问题 (20)

    1008. 数组元素循环右移问题 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 一个数组A中存有N(N>0)个整数,在不允 ...

  7. PAT (Basic Level) Practise:1008. 数组元素循环右移问题

    [题目连接] 一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>=0)个位置,即将A中的数据由(A0A1……AN-1)变换为(AN-M …… A ...

  8. PAT乙级真题1008. 数组元素循环右移问题 (20)

    原题: 1008. 数组元素循环右移问题 (20) 时间限制400 ms内存限制65536 kB 一个数组A中存有N(N>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M&g ...

  9. PAT-乙级-1008. 数组元素循环右移问题 (20)

    1008. 数组元素循环右移问题 (20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 一个数组A中存有N(N>0)个整数,在不允 ...

随机推荐

  1. highchart学习网址

    http://www.highcharts.me/api/index.html   

  2. hdu 4463 Outlets(最小生成树)

    题意:n个点修路,要求总长度最小,但是有两个点p.q必须相连 思路:完全图,prim算法的效率取决于节点数,适用于稠密图.用prim求解. p.q间距离设为0即可,最后输出时加上p.q间的距离 pri ...

  3. Backbone.js之model篇(一)

    Backbone.js之model篇(一) Backbone 是一个前端 JS 代码 MVC 框架,它不可取代 Jquery,不可取代现有的 template 库.而是和这些结合起来构建复杂的 web ...

  4. Caused by: Unable to load bean: type: class:com.opensymphony.xwork2.ObjectFactory - bean - jar

    转自:https://blog.csdn.net/u011422744/article/details/39851693 在SSH开发,搭建环境的时候,启动tomcat服务器,就报这个异常! 信息: ...

  5. Meet User Expectations---满足用户的期待

    Back to App Design Meet User Expectations OS X incorporates the latest technologies for creating gre ...

  6. 035--MySQL基本操作

    一.数据库的定义及相关名词解释  数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. 我们也可以 ...

  7. FTP相关内容

    FTP相关介绍 FTP 1)File Transfer Protocol ( FTP ) 是相当古老的网络协议之一,他最主要的功能就是进行 Server端与 Client 端之间的档案传送的功能.这个 ...

  8. django QQ认证登录

    一.开发环境 django 1.10.2 python3.5.2 django-social-auth 0.3.6 二.申请QQ互联 APPID及SECRECT_KEY 大致步骤: 1.成为QQ互联开 ...

  9. 枚举与#define 宏的区别

    1),#define 宏常量是在预编译阶段进行简单替换.枚举常量则是在编译的时候确定其值.2),一般在编译器里,可以调试枚举常量,但是不能调试宏常量.3),枚举可以一次定义大量相关的常量,而#defi ...

  10. 查看软件安装的位置 Ubuntu

    Ubuntu和windows不一样,不是所有的软件都在一个文件夹,而是不同类型的分散在不同的文件夹下 所以查找起来也是不同的 如果知道是用 apt-get install 方法安装的,可以直接用 dp ...