題目要求:
A為一個包含有n個元素的數組{a0,a1,a2,a3,…,a(p-1),ap,a(p+1)…,a(n-2),a(n-1)},現在將A中的元素循環左移p個單位,得到新的數組B={a(p),a(p1),……,a(n-1),a1,a2,……a(p-1)},
要求編寫程序模擬以上的循環左移過程。
解題思路1:
建立一個大小為p的一維數組,存放數組A的前p個元素,然后將A中的p~n-1個元素向前移動p個單位,然后將將p中的數組放回A中,得到B。
程序代碼:
#include<iostream>
using namespace std;
int main()
{
const int n=10,p=4;
int a[n]={1,2,3,4,5,6,7,8,9,10};
int b[p];
int i;
for(i=0;i<p;i++)b[i]=a[i];
for(;i<n;i++)a[i-p]=a[i];
for(i=0;i<p;i++)a[n-p+i]=b[i];
for(i=0;i<n;i++)cout<<a[i]<<" ";
cout<<endl;
} 運行結果:
5 6 7 8 9 10 1 2 3 4
該算法的時間復雜度為O(n),空間復雜度為O(p).
解題思路2:
我們將A的前p個元素看做a,剩下的n-p個元素看做b,則A=ab,B=ba,我們先對A逆置得到b^-1 a^-1,然后再對b^-1和a^-1逆置得到ba。
程序代碼:
#include<iostream>
using namespace std;
void Reverse(int *a,int left,int right)
{
int mid = (left+right)/2;
int temp;
for(int i=0;i<=(mid-left);i++)
{
temp = a[left+i];
a[left+i] = a[right-i];
a[right-i]= temp;
}
}
int main()
{
const int n=10,p=4;
int a[n]={1,2,3,4,5,6,7,8,9,10};
Reverse(a,0,n-1); //先對A進行逆置得到b^-1 a^-1
Reverse(a,0,n-1-p); //對b^-1進行逆置
Reverse(a,n-p,n-1); //對a^-1進行逆置
for(int i=0;i<n;i++)cout<<a[i]<<" ";
cout<<endl;
}
運行結果:
5 6 7 8 9 10 1 2 3 4
該算法的時間復雜度為O(n),空間復雜度為O(1).
所以,兩種方法的時間復雜度相同,而第二種的方法的空間復雜度小於第第一種的,這在n和p比較大的時候,差別就會比較明顯。
所以相比較而言,第二種方法更好一些。
循環右移的情況與左移類似,我們使用第二種方法來做:
A為一個包含有n個元素的數組{a0,a1,a2,a3,……,a(n-2),a(n-1)},現在將A中的元素循環左移p個單位,得到新的數組B={a(n-p),a(n-p+1),……,a(n-1),a1,a2,……a(n-p-1)},
解題思路:
我們將數組A中的后p個元素記為b,前n-p個元素記為a,則A=ab,B=ba,我們先對A逆置得到b^-1 a^-1,然后再對b^-1和a^-1逆置得到ba。
#include<iostream>
using namespace std;
void Reverse(int *a,int left,int right)
{
int mid = (left+right)/2;
int temp;
for(int i=0;i<=(mid-left);i++)
{
temp = a[left+i];
a[left+i] = a[right-i];
a[right-i]= temp;
}
}
int main()
{
const int n=10,p=4;
int a[n]={1,2,3,4,5,6,7,8,9,10};
Reverse(a,0,n-1); //先對A進行逆置得到b^-1 a^-1
Reverse(a,0,p-1); //對b^-1進行逆置
Reverse(a,p,n-1); //對a^-1進行逆置
for(int i=0;i<n;i++)cout<<a[i]<<" ";
cout<<endl;
}
運行結果:
7 8 9 10 1 2 3 4 5 6
