//有一个字符数组的内容为:"student a am i",请你将数组的内容改为"i am a student".
// 要求:
// 不能使用库函数。只能开辟有限个空间(空间个数和字符串的长度无关)。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
int Mystrlen(const char *src)
{
int len = 0;
assert(src !=NULL);
while (*src++ != '\0')
{
len++;
}
return len;
}
void reverse_str(char *p1, char *p2) //翻转函数。
{
char ch = 0;
assert(p1 != NULL && p2 != NULL);
while (p1 < p2)
{
ch = *p1;
*p1 = *p2;
*p2 = ch;
p1++;
p2--;
}
}
void Myreverse(char * array)
{
int len = 0;
char *start = NULL;
char *end = NULL;
assert(array !=NULL);
len = Mystrlen(array);
reverse_str(array, array+len-1); //翻转整个字符串。接下来要做的就是翻转每个单词了。
//printf("array = %s\n",array);
while (*array != '\0') //这个循环就是翻转每个单词了。
{
start = array;
while ((*array != ' ') && (*array != '\0'))
{
array++; //arrray指向了空格或者是'\0'
}
end = array - 1;
reverse_str(start, end);
if (*array != '\0') //这里容易出错。记得要加上这个条件。
{
array++; //当它指向空格时,前进一步指向新的单词的起始位置。但是如果到字符串的尾部的话,array再加加,将使它跳过\0,导致最外层的循环不会结束。
}
}
}
int main()
{
char array[100] = "student a am i";
//myreverse(array);
Myreverse(array);
printf("array = %s\n",array);
printf("hello...\n");
system("pause");
return 0;
}
//2.实现一个函数,可以左旋字符串中的k个字符。
// AABCD左旋一个字符得到ABCDA
// AABCD左旋两个字符得到BCDAA
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
//方法一:
void reverse_ch(char * str, int n)
{
int i = 0;
char *p = NULL;
char *p1 = NULL;
assert(str != NULL);
p = str;
p1 = str + strlen(str);
n = n % 5; //这样一条语句,能让循环减少很多次,提高效率。因为旋转5次字符串变成原来的字符串了。
for (i = 0; i < n; i++) //将n个字符旋转到字符串的后面。
{
*p1++ = *p++;
}
*p1 = '\0';
while ( (*(p-n) = *p++) != '\0') //将整个字符串前移
{
;
}
}
//方法二 前n个字符翻转一次,字符串剩下的字符翻转一次,最后整个字符串翻转一次。这个方法简单,但是n一定要小于等于strlen(str).
void myreverse(char *left, char *right)
{
char temp = 0;
assert(left != NULL && right != NULL);
while (left < right)
{
temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
}
void reverse_ch3(char *str, int n) //这个方法简单,但是n一定要小于等于strlen(str).
{
assert(str != NULL);
myreverse(str,str+n-1);
myreverse(str+n,str+strlen(str)-1);
myreverse(str,str+strlen(str)-1);
}
int main()
{
char str[100] = "AABCD";
/*reverse_ch(str, 20);
printf("str = %s\n",str);*/
reverse_ch3(str, 6);
printf("str = %s\n",str);
printf("hello...\n");
system("pause");
return 0;
}
//3.
// 判断一个字符串是否为另外一个字符串旋转之后的字符串。
// 例如:给定s1 = AABCD和s2 = BCDAA,返回1,给定s1=abcd和s2=ACBD,返回0.
//
//
// AABCD左旋一个字符得到ABCDA
// AABCD左旋两个字符得到BCDAA
//
// AABCD右旋一个字符得到DAABC
// AABCD右旋两个字符得到CDAAB
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>
//方法一: 字符串旋转一次判断一下。
void reverse_ch1(char * str, int n)
{
int i = 0;
char *p = NULL;
char *p1 = NULL;
assert(str != NULL);
p = str;
p1 = str + strlen(str);
for (i = 0; i < n; i++) //将n个字符旋转到字符串的后面。
{
*p1++ = *p++;
}
*p1 = '\0';
while ( (*(p-n) = *p++) != '\0') //将整个字符串前移
{
;
}
}
int is_revstr(char *str1, char *str2) //str1源字符串,str2是判断字符串
{
int len1 = 0;
int len2 = 0;
assert(str1 != NULL && str2 != NULL);
len1 = strlen(str1);
len2 = strlen(str2);
if (len1 != len2)
{
return 0; //一个字符串不为另外一个字符串旋转之后的字符串。
}
else
{
while (len1 > 0) //源字符串向左旋转len1-1次,看每次旋转后的结果是否为另个字符串。
{
if(strcmp(str1, str2) == 0)
{
return 1;
}
reverse_ch1(str1,1);
len1--;
}
}
return 0;
}
//方法二: 简单方法。将源字符串追加到源字符的后面,形成一个新的字符串,在看str2是否是这个新字符串的子串,如果是,则是翻转后的字符串。
int is_revstr2(char *str1, char *str2)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
assert(str1 != NULL && str2 != NULL);
if (len1 != len2)
{
return 0; //一个字符串不为另外一个字符串旋转之后的字符串。
}
strncat(str1,str1,strlen(str1));//将源字符串追加到源字符的后面,形成一个新的字符串,在看str2是否是这个新字符串的子串,如果是,则是翻转后的字符串。
if (strstr(str1, str2) != NULL) //strncat会自动加上\0,这里不能用strcat,用这个会崩溃。
{
return 1;
}
else
return 0;
}
int main()
{
int ret = 0;
char array[100] = "AABCD";
char array2[100] = "DAABC";
//ret = is_revstr(array,array2);
ret = is_revstr2(array,array2);
if (ret == 1)
{
printf("两个字符串旋转后相同\n");
}
else
{
printf("两个字符串旋转后不同\n");
}
printf("hello...\n");
system("pause");
return 0;
}