字符串相关问题
字符串问题 ,一直以来是编程人员练习的 ,各种稀奇古怪的问题层出不断,让我们感到很难缠。。
下面是我总结的一些字符串问题 :
如 果想要了解字符串库函数模拟 string库函数
让我们来看看吧!!!
1、字符串的翻转
翻转问题,一个很常见的问题,就是将一个字符串逆序输出。。。。
代码分析
char *my_reverse(char *left,char* right )//left为字符串左端,right为字符串右端
{
char *ret = left;
assert(left);
assert(right);
while(left<right)
{
char str = *left;//两端交换
*left = *right;
*right = str;
left++;
right--;
}
return ret;
}
当然有时候
老师,会让我们用递归的方法来完成这个问题
例如 "abcdefg"
现将字符串的第一个字符保存起来 将最后一个放到第一个字符处 ,最后一位赋上“\0”;
字符串指针++;
如果条件满足就进入 递归
否则就将 保存的字符 传 给 最后 一个地址处
流程是;
abcdefg
gbcdef\0 a
gfcde\0\0b
gfed\0\0\0c
gfedc\0\0
gfedcb\0
gfedvba
代码分析
char *my_reverse(char *str)
{
char tem = *str;
int len = strlen(str);
*str = *(str+len -1);
*(str+len -1) ='\0';
if(strlen(str+1)>1) //表示没有走到最中间
{
my_reverse(str+1);
}
*(str+len-1)=tem; //将前面的字符放到后面
return str;
}
2、字符串有序翻转
有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
要求:
不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)
要求:
不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)
这个问题看成是先将字符串整个翻转 ,然后将每个单词 翻转
char *Part_reverse(char *str)
{
char *left = str;
char *right = str;
char *ret = str;
int len = 0;
assert(str);
while(*str)//求字符串的右端
{
str++;
}
str--;
my_reverse(ret,str);//将字符串整个翻转
while(*left)
{
while(*right!=' '&&*right!='\0')//遇到空格 和\0停下
{
right++;
}
right--;
my_reverse(left,right);//单词翻转
right++;
if(*right)
right++;
left =right;
}
return ret;
}
3、字符串替换空格
请实现一个函数,把字符数组中的每个空格替换成“%20”。例如输入“we are happy.”,则输出“we%20are%20happy.”。
这字符串问题就是将空格换成%20 所以原字符串空间大小一定要充足,足够将替换后的字符串放入
我做的方法是这样的 ,先找出字符串中有几个空格,判断出要往后移动几个字节
然后,遇到空格后替换
char *replace_blank(char *str)
{
char *ret = str;
int n =0 ;
assert(str);
while(*str)
{
if(*str==' ')//计算空格个数
{
n++;
}
str++;
}
while(n)
{
while(*str !=' ')
{
*(str+2*n) = *str;//将单词后移
str--;
}
*(str+2*n)='0';//替换空格
*(str+2*n-1)='2';
*(str+2*n-2)='%';
str--;
n--;//递减空格
}
return ret;
}
4、字符串的左旋和右旋
左旋
实现一个函数,可以左旋字符串中的k个字符。
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
实现这个函数有两种方法 :
1、就是先全体翻转,再部分翻转;
2、就是死办法 ——一个一个的前移;
方法一代码:
char *Left_move(char *dest,size_t n)//n不为0;
{
char *ret= dest;
char *start = dest;
char *end = NULL;
assert(dest);
end = start+strlen(dest) - 1;//字符串结尾指针
my_reverse(start,end);//先整个翻转
my_reverse(start,end-n);//左半部分翻转
my_reverse(end-n+1,end);//右半部分翻转
return dest;
}
翻转的代码 ,前面第一个就是;
但是这个代码旋转数为 0时 ,会有问题;
方法二代码:
char *Left_move(char *dest,size_t n)
{
char *ret = dest;
char *cp = dest;
assert(dest);
while(n--)
{
char temp = *cp;//保存第一个字符
while(*(cp+1))//向前移动
{
*cp = *(cp+1);
cp++;
}
*cp = temp;//将第一个字符放到结尾
cp = dest;
}
return ret;
}
右旋
实现一个函数,可以右旋字符串中的k个字符。
AABCD右旋一个字符得到 D A ABC
AABCD右旋一个字符得到 D A ABC
AABCD右旋两个字符得到
CD
AA
B
实现这个函数同样也有两种方法 :
1、就是先全体翻转,再部分翻转;
2、就是死办法 ——一个一个的后移;
代码1:
char * Right_move(char *str,size_t n)//右旋函数 n为旋转量
{
char *ret = str;
char *start= str;
char *end = str;
int len =0 ;//不含‘\0’
assert(str);
len = strlen(str);
end = (start+len-1);
my_reverse(start,end); //整个翻转
my_reverse(start,start+ n-1); //左半部分翻转
my_reverse(start+n,end); //右半部分翻转
return ret;
}
同样的 n 不为0;
代码2:
char * Right_move(char *dest,size_t n)//右旋函数 n为旋转量
{
char *ret = dest;
char *cp = dest+strlen(dest)-1;
assert(dest);
while(n--)
{
char temp = *cp;//保存最后一个字符
while(cp!=dest)//向后移动
{
*cp = *(cp-1);
cp--;
}
*cp = temp;//将最后一个字符放到开头
cp = dest+strlen(dest)-1;
}
return ret;
}
5、模拟实现atoi函数
atoi 函数是什么意思,大家都很清楚 ————就是用来将一个字符串转化输出成整数
比如输入"12345",就会输出整型 数12345
现在我们就来实现一下这个函数 StrToInt()函数
atoi函数的参数类型与返回值类型是
int atoi( const char *string );
代码分析
int myatoi(const char * str)
{
assert(str);
int ret = 0 ;
char * str1 = (char*) str;
bool state = true;
int num = 1;//表示正负号
while(isblank(*str1))
{
*str1++;
}
if(*str1 == '-'||*str1 == '+')
{
if(*str1 == '-')
{
num =-1;
}
++str1;
}
while(isdigit(*str1))
{
ret *= 10;
ret += *str1 - '0';
++str1;
}
return ret*num;
}