1.实现一个函数,可以左旋字符串中的k个字符。
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
方式1:
void left_reverse_one(char *str, int len)//左旋一次
{
int tmp = str[0];//存储第一位
int i = 0;
while (i < len - 1)//i最大到len-2
{
str[i] = str[i + 1];
i++;
}
str[i] = tmp;//将第一位放到最后一位
}
void left_reverse(char *str,int len,int n)
{
assert(str);
assert(len > 0);
assert(n > 0);
n %= len;//去掉无效次数
while (n--)//左旋n次
{
left_reverse_one(str, len);
}
}
int main()
{
int n = 0;
printf("Please Enter:");
scanf_s("%d", &n);
char str[] = "abcd1234";//若为*str,程序崩溃
int len = strlen(str);
printf("%s\n", str);
left_reverse(str, len, n);
printf("%s\n", str);
system("pause");
return 0;
}
方式2:
将字符串逆置:如abcd1234 左旋4次为 1234abcd
左旋几次将从第一个元素起数几个元素并进行逆置为dcba
并将剩余的进行逆置为dcba4321,在进行整体逆置1234abcd
假设左旋n次,字符串长度为len
则逆置顺序为 0-n-1,n->len-1,0-len-1;
void reverse(char *start, char *end)
{
while (start<end)
{
*start ^= *end;
*end ^= *start;
*start ^=*end;
start++;
end--;
}
}
void left_reverse1(char *str, int len, int n)
{
assert(str);
assert(len > 0);
assert(n > 0);
n %= len;//去掉无效次数
reverse(str, str + n - 1);
reverse(str + n, str + len - 1);
reverse(str, str + len - 1);
}
int main()
{
int n = 0;
printf("Please Enter:");
scanf_s("%d", &n);
char str[] = "abcd1234";
int len = strlen(str);
printf("%s\n", str);
left_reverse1(str, len, n);
printf("%s\n", str);
system("pause");
return 0;
}
方式3 用库函数 双倍字符串法
abcd1234abcd1234包含了左旋的所有结果
需申请一段空间来存储,malloc申请,free释放
void left_reverse2(char *str, int len, int n)
{
assert(str);
assert(len > 0);
assert(n > 0);
n %= len;//去掉无效次数
char *mem = (char*)malloc(2 * len + 1);//申请时包含'\0'
if (mem == NULL)//判断是否申请成功
{
return 0;
}
strcpy(mem, str);//将str拷贝入mem
strcat(mem, str);//构建双倍字符串
strncpy(str, mem+n,len);//字符串左旋n次,拷贝个数为字符串长度
free (mem); //谁申请谁释放
}
int main()
{
int n = 0;
printf("Please Enter:");
scanf_s("%d", &n);
char str[] = "abcd1234";
int len = strlen(str);
printf("%s\n", str);
left_reverse2(str, len, n);
printf("%s\n", str);
system("pause");
return 0;
}
2,2.判断一个字符串是否为另外一个字符串旋转之后的字符串。
给定s1 = AABCD和s2 = BCDAA,返回1,给定s1 = abcd和s2 = ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
//思路:同上方式三,用双倍字符串的方法编写
int find_left_reverse(char *str1, int len1,\
char *str2,int len2)
{
assert(str1);
assert(len1 > 0);
assert(str2);
assert(len2 > 0);
if (len1 != len2)
{
return 0;
}
char *mem = (char*)malloc(2 * len1 + 1);//申请时包含'\0'
if (mem == NULL)//判断是否申请成功
{
return -1;
}
strcpy(mem, str1);//将str1拷贝入mem
strcat(mem, str1);//构建双倍字符串
if (strstr(mem, str2) != NULL)//判断是否是子串
{
return 1;
}
else
{
return 0;
}
free (mem); //谁申请谁释放
}
int main()
{
char *str1 = "abcd1234";
char *str2 = "bcd12342";
int len1 = strlen(str1);
int len2 = strlen(str2);
int ret = find_left_reverse(str1, len1, str2, len2);
printf("ret=%d\n", ret);
system("pause");
return 0;
}
这里用到了两个函数:
1.strncat函数:用于将n个字符追加到一个字符串的结尾。函数原型为:
char *strncat( char *strDest, const char *strSource, size_t count );
若追加的个数大于strSource的长度,则将strSource全部追加到strDest中。
strncat函数会将strDest字符串中的’\0’,覆盖,追加完成后,再加上’\0’。
返回值:返回字符串strDest。
2.strstr函数:这个函数我们不大常见,其函数原型为:
char *strstr( const char *s1, const char *s2 );
找出s1在s2中的位置,若找不到,返回空指针。
更多函数内容可在MSDN中查询。