问题重述:数组的循环左移。要求设计三种算法,将数组中的N个元素能够实现循环左移p个位置。
算法1:
先将数组中的前p个元素存放在一个临时数组中,再将余下的N-p个元素左移p个位置,最后将前p个元素从临时数组复制回原数组中后面的p个位置。
void leftMoveal1(int p)//方案1:先移动前p个元素,再移动后N-p个元素,最后再移动p个元素。
算法2:
先设计一个leftmoveone()函数将数组向左循环移动1个位置,再调用该算法p次。
void leftmoveone() ( )//方案2的子函数:将数组循环左移1个数字
void leftMoveal12(int p)//方案2:每次循环左移1个数字,调用p次
{
循环调用p次 leftmoveone() ();
}
算法3:
将这个问题看作是把数组AB转换成数组BA(A代表数组的前p个元素,B代表数组中余下的N-p个元素),先将A置逆,再将B置逆,两次逆置之后得到BA,最后再将整个BA逆置。
void reverary(DataType a[],int low, int high);//方案3的子函数,将数组的low 到high逆置,注意下标。
void leftmoveal3(int p)//方案3,先逆置前p个元素,再逆置后N-p个元素,最后整体逆置N个元素
{
逆置函数的调用
….
}
程序的实现:
head.h
#pragma once
#include <iostream>
using namespace std;
const int maxsize = 100;//使用户输入的数组可以尽可能的大
class leftmove
{
private:
int data[maxsize];
int length;
public:
leftmove(int a[], int b);//a[]为临时数组,b是数组的长度
void leftMoveal1(int p);//算法1
void leftmoveone();
void leftMoveal12(int p);//算法2
void reverary(int low, int high);
void leftmoveal3(int p);//算法3
void display();
};
head.cpp
#include "head.h"
leftmove::leftmove(int a[], int b)
{
int i;
if (b<0 || b>maxsize)
cout << "Error!" << endl;
else
for (i = 0; i < b; i++)
data[i] = a[i];
length = b;
}
void leftmove::leftMoveal1(int p)
{
int i;
int* q = new int[p];
for (i = 0; i < p; i++)
q[i] = data[i];
for (i = 0; i < length - p; i++)
data[i] = data[i + p];
for (i = 0; i < p; i++)
data[i + length - p] = q[i];
}
void leftmove::leftmoveone()
{
int i, temp;
temp = data[0];
for (i = 0; i < length - 1; i++)
data[i] = data[i + 1];
data[length - 1] = temp;
}
void leftmove::leftMoveal12(int p)
{
int i;
for (i = 0; i < p; i++)
leftmoveone();
}
//算法3选择1
/*void leftmove::reverary(int low, int high)
{
int i;
int* p = new int[high - low + 1];
for (i = 0; i < high - low + 1; i++)
p[i] = data[low - 1 + i];
for (i = 0; i < high - low + 1; i++)
data[low + i - 1] = p[high - low - i];
}
void leftmove::leftmoveal3(int p)
{
reverary(1, p);
reverary(p + 1, length);
reverary(1, length);
}*/
//算法3选择2
void leftmove::reverary(int low, int high)
{
int s = low, t = high;
while (s < t)
{
int r = data[s];
data[s] = data[t];
data[t] = r;
s++;
t--;
}
}
void leftmove::leftmoveal3(int p)
{
reverary(0, p - 1);
reverary(p, length - 1);
reverary(0, length - 1);
}
void leftmove::display()
{
int i;
if (length == 0)
cout << "empty!" << endl;
else
for (i = 0; i < length; i++)
cout << data[i];
cout << endl;
}
main.cpp
#include "head.h"
int main()
{
int length, i, q;
cout << "Please input length:";
cin >> length;
int* p = new int[length];
cout << "Please input the data:";
for (i = 0; i < length; i++)
cin >> p[i];
class leftmove test(p, length);
test.display();
cout << "please input the q:";
cin >> q;
int choice;
cout << "请选择算法1、2、3:" << endl;
cin >> choice;
if (choice == 1)
test.leftMoveal1(q);
else if (choice == 2)
test.leftMoveal12(q);
else if (choice == 3)
test.leftmoveal3(q);
else
cout << "Error!" << endl;
test.display();
return 0;
}
代码运行的截图:
以上分别为算法1、2、3的运行结果截图。其中算法3不管是选择一方法或是选择二方法,均可实现。
最后鸣谢:
1.该代码由男朋友舍友刘浩、男朋友马志豪以及我共同完成。更多的思路都是前两位提供的,我只是进行了少量的修改,以及最后的整合工作。希望我们能在简单的大学生活中留下自己的记忆,也希望之后的未来 前程似锦。
2.其中算法3的选择二是参考了“菜鸟成长之路-wei”的《数组循环向左移动k位的算法》这一篇文章其中的颠倒交换法。