1. 调整数组使奇数全部都位于偶数前面。
题目:
输入一个整数数组,实现一个函数,
来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,
所有偶数位于数组的后半部分。
思路:
- 给定两个下标left和right,left放在数组的起始位置,right放在数组中最后一个元素的位置
- 循环进行一下操作
a. 如果left和right表示的区间[left, right]有效,进行b,否则结束循环
b. left从前往后找,找到一个偶数后停止
c. right从后往前找,找到一个奇数后停止
d. 如果left和right都找到了对应的数据,则交换,继续a,
方法一
#include <stdio.h>
void move_odd_even(int arr[], int sz)
{
int left = 0;
int right = sz - 1;
while (1)
{
// 从前往后,找到一个偶数,找到后停止
for (; left < sz; left++)
{
if (arr[left] % 2 == 0)
{
break;
}
}
// 从后往前找,找一个奇数,找到后停止
for (; right >= 0; right--)
{
if (arr[right] % 2 == 1)
{
break;
}
}
//当 left > right 时交换完成,退出循环
if (left > right)
{
break;
}
// 如果偶数和奇数都找到,交换这两个数据的位置
int tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
left++;
right--;
}
}
int main()
{
int arr[] = { 1,3,2,4,7,5,6,9,8 };
int sz = sizeof(arr) / sizeof(arr[0]);
move_odd_even(arr, sz);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
运行结果如图:
方法二
void swap_arr(int arr[], int sz)
{
int left = 0;
int right = sz-1;
int tmp = 0;
while(left<right)
{
// 从前往后,找到一个偶数,找到后停止
while((left<right)&&(arr[left]%2==1))
{
left++;
}
// 从后往前找,找一个奇数,找到后停止
while((left<right)&& (arr[right]%2==0))
{
right--;
}
// 如果偶数和奇数都找到,交换这两个数据的位置
// 然后继续找,直到两个指针相遇
if(left<right)
{
tmp = arr[left];
arr[left] = arr[right];
arr[right] = tmp;
}
}
}
2. 字符串左旋
实现一个函数,可以左旋字符串中的k个字符。
例如:
ABCD左旋一个字符得到BCDA
ABCD左旋两个字符得到CDAB
方法一
#include <stdio.h>
#include <string.h>
void reverse_left(char* arr,int k)
{
int len = strlen(arr);
k %= len;//长度为5的情况下,旋转6、11、16...次相当于1次,7、12、17...次相当于2次,以此类推。
while (k)
{
char tmp = *arr;
int i = 0;
for (i = 1; i < len; i++)
{
arr[i - 1] = arr[i];
}
arr[len - 1] = tmp;
k--;
}
}
int main()
{
char arr[] = "abcdefg";
int k = 0;
scanf("%d", &k);
k %= 10;
reverse_left(arr,k);
printf("%s\n", arr);
}
方法二
这个方法要用到一个数组形成的辅助空间,让人觉得有点不爽,还可以有更好的选择,例如ABCDEFG,左旋3次后变成DEFGABC,有一个特殊的操作方式:
先将要左旋的前三个家伙逆序(CBADEFG),然后将后半段也逆序(CBAGFED),最后整体逆序(DEFGABC)即可。这样只需要做数值交换即可,可以写一个函数帮我们完成局部逆序,代码如下
#include <stdio.h>
#include <string.h>
void reverse(char* left, char* right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[] = "abcdefg";
int len = strlen(arr);
int k = 0;
scanf("%d", &k);
k %= len;
reverse(arr, arr + k - 1);//逆序前段
reverse(arr + k, arr + len - 1);//逆序后段
reverse(arr, arr + len - 1);//整体逆序
printf("%s", arr);
}
运行结果如图
3. 字符串右旋
实现一个函数,可以右旋字符串中的k个字符。
例如:
ABCD右旋一个字符得到DABC
ABCD右旋两个字符得到DCAB
方法一
#include <stdio.h>
#include <string.h>
void reverse_right(char* arr, int k)
{
int len = strlen(arr);
k %= len;
int i = 0;
for (i = 0; i < k; i++)
{
char tmp = arr[len - 1];
int j = 0;
for (j = len - 2; j >= 0; j--)
{
arr[j + 1] = arr[j];
}
arr[0] = tmp;
}
}
int main()
{
char arr[] = "abcedf";
int k = 0;
scanf("%d", &k);
reverse_right(arr, k);
printf("%s", arr);
return 0;
}
方法二
#include <stdio.h>
#include <string.h>
void reverse(char* left, char* right)
{
while (left < right)
{
char tmp = *left;
*left = *right;
*right = tmp;
left++;
right--;
}
}
int main()
{
char arr[] = "abcdefg";
int len = strlen(arr);
int k = 0;
scanf("%d", &k);
k %= len;
reverse(arr, arr + len - 1);//整体逆序
reverse(arr, arr + k - 1);//逆序前段
reverse(arr + k, arr + len - 1);//逆序后段
printf("%s", arr);
}
运行结果如图: