本题要求实现一个对数组进行循环左移的函数:一个数组a中存有n(>0)个整数,将每个整数循环向左移m(≥0)个位置。即将a中的数据由[a 0 a 1 ...a n−1 ]变换为[a m a m+1 ...a n−1 a 0 a 1 ...a m−1 ](最前m个数循环移至最后面的m个位置)。 函数接口定义: void ArrayShift( int a[], int n, int m ); 其中a[]是用户传入的数组;n是数组的大小;m是左移的位数。函数ArrayShift须将循环左移后的数组元素仍然存放在a[]中。
void ArrayShift(int a[], int n, int m) {
if (n <= 1 || m % n == 0) { // 如果数组大小小于等于1或者移动位数取模等于0,则不需要移动,直接返回。
return;
}
// 对移动位数取模,防止超出数组大小
m %= n;
reverse(a, a + m); // 倒序前m个数
reverse(a + m, a + n); // 倒序后n-m个数
reverse(a, a + n); // 倒序整个数组
}
另一种方式是使用一个临时数组,将需要移动的元素先存储在临时数组中,然后将原数组中剩余的元素依次往左移动m个位置,最后再将临时数组中的元素放到数组的末尾m个位置上。
具体步骤如下:
- 判断特殊情况,如果数组大小小于等于1或者移动位数取模等于0,则不需要移动,直接返回。
- 对移动位数取模,防止超出数组大小。
- 创建一个长度为m的临时数组,将需要移动的元素存储在其中。
- 将原数组中剩余的元素依次往左移动m个位置。
- 将临时数组中的元素依次放到数组的末尾m个位置上。
以下是相应的代码:
void ArrayShift(int a[], int n, int m) {
if (n <= 1 || m % n == 0) { // 如果数组大小小于等于1或者移动位数取模等于0,则不需要移动,直接返回。
return;
}
// 对移动位数取模,防止超出数组大小
m %= n;
int temp[m]; // 创建临时数组
for (int i = 0; i < m; i++) { // 将需要移动的元素存储在临时数组中
temp[i] = a[i];
}
for (int i = m; i < n; i++) { // 将原数组中剩余的元素依次往左移动m个位置
a[i-m] = a[i];
}
for (int i = 0; i < m; i++) { // 将临时数组中的元素放到数组的末尾m个位置上
a[n-m+i] = temp[i];
}
}
这种方法需要使用额外的空间,所以在空间限制较为严格的情况下不太适用,但是移动过程比较直观易懂。