要求:不申请变量和空间反转字符串,用一个函数实现。VIA笔试题

基本思路:从两头往中间做字符交换。字符串最后一个字符是'\0',表示结束,没有实际意义,可以将它当作中间变量,等处理完成后,再将最后一个字符置'\0'即可

***********************************************************************

void Reverse (char   *s)

{

if(strlen(s) == 1) // 当为一个字符时无需交换或奇数个

return;

if(*(s))   // 0个或偶数个

{

*s   =   *s   +   *(s+strlen(s)-1);

*(s+strlen(s)-1)   =   *s   -   *(s+strlen(s)-1);

*s   =   *s   -   *(s+strlen(s)-1);

// 实现字符串首末字符互换,但加法可能会溢出

*(unsigned   short*)(s+strlen(s)-1)   =   (*(s+strlen(s)-1))<<8;

// 把字符串的最后一个字节往后移了一位,利用了0 = ‘\0’

// 当然也可以利用上面交换字符的方法,不过移位利用了0 = ‘\0’的效率更高

// 上面四步的本质是实现三个数两两互换,最简单的是两次两两互换

// 但是目前结尾符是已知的,直接把第一个放到结尾处,最后一个放第一个,将

// 最后一个用结尾符填上即可,只需三步,易于理解,前提是有变量保存字符串的//长度

// 但是由于不能申请临时变量,移动了结尾符号后,strlen函数就不能用了

// 因此上述强制转换的方式是唯一的

// 然后将去掉了首尾字符的新串传进去,递归调用

Reverse (s+1);

*(unsigned   short*)(s+strlen(s))   =   *(s+strlen(s)+1);

// 将‘\0’逐步后移,还原更改后的子串

}

else

return;

}

图示过程:字符串abcdef

S+1 = Str = abcdef’\0’   abcdef’\0’ > fbcdea’\0’ > fbcde’\0’a

S+1 = Str = bcde’\0  fbcde’\0’a > fecdb’\0’a > fecd’\0’ba

S+1 = Str = cd’\0’   fecd’\0’ba > fedc’\0’ba > fed’\0’cba

S+1 = Str =’\0’   ,递归返回,此时s= cd’\0’ 已经在上一步改为  d’\0’c > dc’\0’ > edcb’\0’ > fedcba’\0’

考虑串的长度为奇数的情况,当为奇数时,最后传进去的串长度为1,此时无需交互,应该直接退出。因此在入口处补上判断奇偶的条件

if(strlen(s) == 1)

return;

当然也可以在递归调用前判断改动后的字符串长度if( strlen(str+ 1) >= 2 )时,才调用,可以消除奇数的影响

当原始字符串为一个时,第一次就应该无任何处理的,所以在入口处判断更合理哦

×××××××××××××××××××××××××××××××

优化,不申请任何变量,支持链式操作,返回char *

char  * Reverse (char   *s)

{

if(strlen(s) == 1)

return s;

if(*(s))

{

*s   =   *s   +   *(s+strlen(s)-1);

*(s+strlen(s)-1)   =   *s   -   *(s+strlen(s)-1);

*s   =   *s   -   *(s+strlen(s)-1);

// 实现字符串首末字符互换,但加法可能会溢出

*(unsigned   short*)(s+strlen(s)-1)   =   (*(s+strlen(s)-1))<<8;

Reverse (s+1);

*(unsigned   short*)(s+strlen(s))   =   *(s+strlen(s)+1);

}

return s;   // 此句没有,程序就错了,因为递归的最外层是进入if(*(s))的,此时无返回值

}

×××××××××××××××××××××××××××××××

申请了一个变量保存串的长度,一般面试这个程序就可以了,能写出这个其实已经很牛b了,整上面那个,估计别人开始怀疑是以前做过这个题目了,呵呵,还得装傻点

char  * Reverse (char   *s)

{

if(strlen(s) == 1)

return s;

if(*(s))

{

int len = strlen(s);

*(s+len) =   *s;

*s   =  *(s+len-1);

*(s+len-1) = '\0';

// 首尾字符及结束符交换位置

// 去掉首尾字符后再递归调用

Reverse (s+1);

//*(unsigned   short*)(s+strlen(s))   =   *(s+strlen(s)+1);

*(s+len-1) = *(s+len);

*(s+len) = '\0'; // 恢复原来改变后的串

}

return s;

}

×××××××××××××××××××××××××××××××

将字符串的最后一个元素递归移动到队头,递归到达尾部,异或^交换,队尾元素前移一格,返回上层,再次交换,最后即将队尾移到队头

void   tail2head(char*   s)

{

if(strlen(s)==1)

{

return;

}

else if(strlen(s)==2)

{

s[0] = s[1]^s[0];

s[1] = s[1]^s[0];

s[0] = s[1]^s[0];

return;

}

else  if(strlen(s)>2)

{

tail2head(s+1);

s[0] = s[1]^s[0];

s[1] = s[1]^s[0];

s[0] = s[1]^s[0];

}

}

递归一次移动队尾至队头,更新队头至下一个元素,再次调用tail2head,最后即可全部逆序

char*   Reverse(char   *s)

{

if(strlen(s)>1)

{

tail2head(s);

Reverse(s+1);

}

return   s;

}

此法元素移动次数最多,但是思路比较清晰,另外整个功能用了两个递归函数实现,打破了通常只有一个接口函数的固定思维

main()

{

char   streven[10]   =   "abcdef";

char   strood[10]   =   "1234567";

char   strone[10]   =   "1";

char   strtwo[10]   =   "12";

printf("string 'abcdef' reversed is '%s'\n",Reverse(streven));

printf("string '1234567' reversed is '%s'\n",Reverse(strood));

printf("string '1' reversed is '%s'\n",Reverse(strone));

printf("string '12' reversed is '%s'\n",Reverse(strtwo));

return 0;

//string 'abcdef' reversed is 'fedcba'

//string '1234567' reversed is '765123?' 当串的长度为奇数时好像还有点问题

//string '1234567' reversed is '7654321' 补充了判断条件后无误

//string '1' reversed is '1'

//string '12' reversed is '21'

}

◆◆

评论读取中....

请登录后再发表评论!

◆◆

修改失败,请稍后尝试

c语言中字符串交换位置,c如何实现字符串奇偶位置的互换相关推荐

  1. LeetCode简单题之仅执行一次字符串交换能否使两个字符串相等

    题目 给你长度相等的两个字符串 s1 和 s2 .一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符. 如果对 其中一个字符串 执行 最多一次字符串 ...

  2. LeetCode 1790. 仅执行一次字符串交换能否使两个字符串相等

    文章目录 1. 题目 2. 解题 1. 题目 给你长度相等的两个字符串 s1 和 s2 . 一次 字符串交换 操作的步骤如下:选出某个字符串中的两个下标(不必不同),并交换这两个下标所对应的字符. 如 ...

  3. 谈谈你对c语言中数据(各种常量,变量,函数参数,字符串)的存储认识,自考《高级语言程序设计》知识点总结(二)...

    2.1 C语言的数据类型 数据类型包含两方面的内容:数据的表示和对数据加工的操作.数据的全部可能表示构成数据类型的值的集合.数据全部合理的操作构成数据类型的操作集合. 在C语言中,把整型.实型和字符型 ...

  4. 在C语言中如何高效地复制和连接字符串?

    就目前而言,在编程领域中,C语言的运用非常之多,它兼顾了高级语言的汇编语言的优点,相较于其它编程语言具有较大优势. 作者 | Martin Sebor 译者 | 苏本如,责编 | 刘静 出品 | CS ...

  5. C语言中如何将小数或整数和字符串合二为一

    如何将小数和字符串结合在一起 问题 用到的知识 字符串拼接 C 字符串函数 sprintf() 实现功能 后续 问题 我们在平时的开发中,经常会遇到,想将小数或者整数和字符串结合在一起,然后使用或者输 ...

  6. C语言中如何使用宏连接多个字符串(#和##的用法)

    最近在编写一个项目的代码时,需要在宏定义中连接多个字符串,具体来说就是,先定义一个软件版本号,然后再定义一个硬件版本号, 然后再将他们拼合起来生成一个综合版本号.这些动作我都希望在宏定义中直接完成,提 ...

  7. c语言字符串前加l,【C】 30_C语言中的字符串

    字符串的概念 字符串是有序字符的集合 字符串是程序中的基本元素之一 C 语言中没有字符串的概念 C 语言中通过特殊的字符数组模拟字符串 C 语言中的字符串是以 '\0' 结尾的字符数组 字符串与字符数 ...

  8. c语言中.和-区别,c语言中-和.的区别

    对于c语言中"->"和"."的区别总结如下: 1.A.B则A为对象或者结构体: 2.A->B则A为指针,->是成员提取,A->B是提取A ...

  9. 【C语言进阶剖析】14.C语言中的单引号和双引号

    文章目录 一.单引号和双引号 二.小贴士 三.程序实例分析1 四.程序实例分析2 五.容易混淆的代码 六.小结 一.单引号和双引号 C语言中的单引号用来表示字符字面量 C语言中的双引号用来表示字符串字 ...

  10. c语言中体积用什么字母表示,C语言中求圆柱体体积符号

    数学中求模如何定义?对比求模,C语言中计算符号"%"是否与其意义相当? 数学中模这个字被用于很多个不同领域(但是意义不同)一.C语言中的计算符号%,这个求模在数学中是指属于数论内容 ...

最新文章

  1. Python小知识: List的赋值方法,不能直接等于
  2. 快手基于RocketMQ的在线消息系统建设实践
  3. java改写weka中的算法_用Eclipse在Weka中嵌入新算法
  4. mysql 交集_MYSQL交集函数
  5. Memcache分布式部署方案
  6. python程序设计知识点汇总_Python入门知识点汇总
  7. 控制工程基础Chapter2 Mathematical models of systems
  8. 超 8 亿人收发微信春节红包;苹果自研 iPhone 芯片;暴雪或将大裁员 | 极客头条...
  9. python自学看什么书-如何自学Python ?自学看什么书比较好?
  10. KL距离(衡量两个概率分布的差异情况)
  11. python zemax_最新Python中文版发布,跨界程序员零压力学Python之道!(附下载)
  12. 初学者安装mysql5.7_CentOS7入门_安装并配置mysql5.7.18
  13. 可以免费下载视频素材和模板网站汇总
  14. PHP导出Excel,亲测有用
  15. 数十亿红包,正谋杀我们的春节
  16. java catch后面_java 异常被catch后 将会继续执行的操作
  17. 森林防火(资源监管)“空天地人”四位一体监测系统方案
  18. Xsd文件验证xml的java实现
  19. 初识go-micro
  20. 伯努利分布的最大似然估计

热门文章

  1. 中国农民丰收节精神 2020(广东)功能性农业·农业大健康大会
  2. docker仓库(未完)
  3. 人工智能的黎明:混战中的语音识别
  4. php的jit,PHP8.0新特性:JIT即时编译
  5. pcb入门之PCB封装自制
  6. 走进数据结构 - 树(Tree)的世界
  7. word-1.每行后加逗号
  8. 抖音发布首张专辑《听见,看见》启动“2019看见音乐计划”
  9. 数据库系统概念笔记-引言
  10. 好心情:别在该躺平的时候动脑子,10种方法让大脑高效休息