一、字符串左旋
一、题目概述
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
二、解题思路
方法一:一个一个移
图解:
1.移动多少次?
也就是说:我们虽然只有4个字符,但是可以移动很多次,而且每移动四次就回到了最初的起点,我们可以得出结论:
左旋k个字符 % 字符个数 -> 左旋字符次数
用代码诠释就是: time = k % len;
2.怎么左旋?
我们只需要把字符放在字符数组里面,用一个变量去存放要左旋的字符,其他字符++存放数组里
图解:
代码实现如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
void LeftRound(char * str, int k, int len)
{
int i = 0;
int j = 0;
char temp = 0;
int time = k % len; //计算左旋多少次
for (i = 0; i < time; i++)
{
temp = str[0];
for (j = 0; j < len - 1; j++)
{
str[j] = str[j + 1];
}
str[j] = temp;
}
}
int main()
{
int i = 0;
int k = 0;//左旋多少次
char ch[] = "ABCD";
int len = strlen(ch);//计算字符数组一共多少字符
scanf("%d", &k);
LeftRound(ch, k, len);
printf("%s", ch);
return 0;
}
方法二:局部翻转
1.什么是翻转? 也就是逆置数组,如上图要翻转三次,所以写一个函数专门去翻转效率会高很多。
代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
void Reverse(char* str, int left, int right)
{
while (left < right)
{
int temp = str[left];
str[left] = str[right];
str[right] = temp;
left++;
right--;
}
}
void LeftRound(char* str, int k, int len)
{
Reverse(str, 0, k - 1);
Reverse(str, k, len - 1);
Reverse(str, 0, len - 1);
}
int main()
{
char ch[] = "ABCD";
int k = 0;
scanf("%d", &k);
int len = strlen(ch);
LeftRound(ch, k, len);
printf("%s", ch);
return 0;
}
二、字符串旋转结果
一、题目概述
写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
例如:给定s1 =AABCD和s2 = BCDAA,返回1
给定s1=abcd和s2=ACBD,返回0.
AABCD左旋一个字符得到ABCDA
AABCD左旋两个字符得到BCDAA
AABCD右旋一个字符得到DAABC
二、解题思路
在看下面的解题思路之前,先了解几个库函数
1.strcpy()
char *strcpy(char *dest, const char *src)
- dest: 指向用于存储复制内容的目标数组
- src: 要复制的字符串
该函数返回一个指向最终的目标字符串 dest 的指针。
2.strcat()
char *strcat(char *dest, const char *src)
-
dest:指向目标数组,该数组包含了一个 C 字符串,且足够容纳追加后的字符串。
-
src:指向要追加的字符串,该字符串不会覆盖目标字符串。
该函数返回一个指向最终的目标字符串 dest 的指针。
3.strstr()
char *strstr(const char *haystack, const char *needle)
- haystack:要被检索的 C 字符串。
- needle:在 haystack 字符串内要搜索的小字符串。
该函数返回在 haystack 中第一次出现 needle 字符串的位置,如果未找到则返回 null。
方法:库函数
将一个字符串复制1份,拼接在一起,要判断的那个旋转后字符串一定在拼接后的字符串
如上图,若找BCDAA,可以看到确实在拼接的字符串内,若找CDAAB,可以看到确实在拼接的字符串内
代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int find(char* s1, char* s2)
{
char ch[256] = { 0 };
strcpy(ch, s1);
strcat(ch, s1);
return strstr(ch, s2) != NULL;
}
int main()
{
char s1[] = "AABCD";
char s2[] = "BCDAA";
int ret = find(s1, s2);
printf("%d", ret);
return 0;
}
三、冒泡排序
一、题目概述
实现一个对整形数组的冒泡排序
二、解题思路
冒泡排序核心思想:相邻的元素进行比较
为方便演示,下图就用5个数字做演示
第一趟冒泡排序
第二趟冒泡排序
可以看到,5已经是最大的数字,固定在最后一位,所以我们在进行第二趟冒泡排序的时候,只需要对前四个数字进行排序即可
第三趟冒泡排序
可以看到,4和5的位置已经确定,只需要对前3个数字排序即可
第四趟冒泡排序
可以看到,3和4和5的位置已经确定,只需要对前2个数字进行排序即可
第四趟冒泡排序后,四个数字的位置已经确定,总共5个数字,进行了4趟排序,那么最后一个数字自然已经是排好序了
步骤:
1.确定趟数:有多少个数字,就要判断要交换多少趟,以上图为例,5个数字,只需要排序4趟,那么有n个数字,就需要进行n-1次的冒泡排序
2.确定每躺需要交换的次数:我们可以看到,每一趟冒泡排序之中,需要比较的次数都会减少。
3.如果出现了一趟都没有发生交换,那么我们可以用break提前跳出循环。
三、代码实现
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void Sort(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
int flag = 1;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
flag = 0;
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
if (flag == 1)
{
break;
}
}
int main()
{
int arr[10] = { 10,9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
Sort(arr, sz);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}