初级编程:一道百度笔试题的试解:如何不使用库函数和定义新变量转置字符串?
【题目】现在要求实现一个函数:
void Revert(const char* s1, char* s2);
要求:不使用任何如strlen等的库函数,不定义新的变量,如何实现上面的函数。
【试解】要解决这道题目必须掌握以下技术:
1.const的作用和限制是什么。
2.如何不利用第三个变量而达到交换两个变量的目的。
知道了上面的两个知识点才能够解决这道题目。
一、const的作用
const的作用我不在这里解释,请大家参看百度百科里对于const的解释,那里解释的挺详细的。链接为:http://baike.baidu.com/view/1065598.htm
二、交换两数
如何交换两数的问题其实很多书上都有讲解,我这里介绍两种方法,也算是借花献佛吧。
方法一:加减交换法
int a = 1, b = 2;
a = a+b;
b = a-b;
a = a-b;
cout<<a<<" "<<b<<endl;
方法二:异或交换法
int a = 1, b = 2;
a = a^b;
b = a^b;
a = a^b;
cout<<a<<" "<<b<<endl;
其实大家很容易看到上面两种方法非常相似,这里只要大家记住就可以啦。但是上面两种方法哪种更好呢?
优劣分析:加减交换法直观明白,但是有一个问题,就是a和b如果都很大,那么a+b就会溢出整数的范围,从而得到一个非意愿的值,这是我们不愿意看到的。然而,异或交换法不会溢出,所以异或交换法更加安全。我个人推荐大家使用异或交换法。当然,如果数值比较小,两种方法都是可取的。
算法实现:有了上述两点之后就可以开始编码实现如何转置了。代码如下(VS2008编译通过):
上面的算法中使用了两个变通的小技巧。第一,使用强制转换来将const的限制化解。这里int(a)和(int)a有什么区别呢?笔者的原意是新建一个int类型的临时对象,并赋值为a。这个不是新定义的变量,而是一个临时的对象,所以是满足题意的。请读者斟酌,请高手赐教。第二,使用递归来不断的逐一交换字符。这个避免了使用循环和临时变量,所以多层循环都是可以转化为递归的。本程序就是一个例子,请读者考虑。
【注】如有问题,请赐教。
#include <iostream>
using namespace std;
void con(char *s1, char* s2)
{
if(s2 > s1)
{
*s1 = (*s1)^(*s2);
*s2 = (*s1)^(*s2);
*s1 = (*s1)^(*s2);
con(s1+1, s2-1);
}
}
void convert(const char *s1, char* s2)
{
s2 = (char*)s1;
while(*s2 != '\0')
s2++;
s2--;
con((char*)s1, s2);
}
void main()
{
char s1[] = "01234567789";
char* s2 = s1;
convert(s1, s2);
int nSize = strlen(s1);
for(int i = 0; i<nSize; i++)
{
cout<<s1[i]<<endl;
}
system("pause");
}