晚上好,人们!
我正在尝试解决一个相当简单的问题,但是......好吧,似乎我做不到。 :)
我的想法是我有一个带有n个元素的FIFO列表(FIFO队列),并给它一个值k(k 但是,我无处可去。 这是我到目前为止所写的: 非常感谢任何帮助。提前谢谢。#include <iostream>
using namespace std;
void move (int a[100], unsigned n, unsigned k) {
int t[100];
unsigned i;
for (i=0; i<=n-1; i++) t[i]=a[i];
for (i=0; i<=k-1; i++) a[i]=a[i+k-1];
for (i=k; i<=n-1; i++) a[i]=t[i+1];
}
int main () {
int a[100];
unsigned k, n, i;
cout<<"n; k= "; cin>>n>>k;
for (i=0; i<=n-1; i++) cin>>a[i];
move (a, n, k);
for (i=0; i<=n-1; i++) cout<<a[i]<<" ";
}
答案 0 :(得分:2)
我不确定我是否完全理解了你的问题。但看起来你有效地想要旋转数组的内容。
将数组内容向左旋转k次。您可以执行以下操作:
示例:
N = 5,K = 3,并且阵列= [1 2 3 4 5]
C ++函数也是如此:
void move (int a[100], int n, int k) {
int t[100];
int i,j;
for (i=k-1,j=0; i>=0; i--,j++) t[j]=a[i];
for (i=n-1; i>=k; i--,j++) t[j]=a[i];
for (i=n-1,j=0; i>=0; i--,j++) a[j]=t[i];
}
在恒定空间中执行此操作的更好方法是进行原位反转:
void arr_rev(int a[100], int start, int end) {
int temp;
for(;start<end;start++,end--) {
temp = a[start];
a[start] = a[end];
a[end] = temp;
}
}
void move2 (int a[100], int n, int k) {
arr_rev(a,0,k-1);
arr_rev(a,k,n-1);
arr_rev(a,0,n-1);
}
答案 1 :(得分:1)
看起来你想要左旋?这应该不是很困难。只需将第一个k
元素出列,将剩余的n-k
元素向左移动(可能将它们放在临时数组的开头),然后在第一个k
添加按顺序结束。
以这种方式修改代码可能如下所示:
void move (int a[100], unsigned n, unsigned k) {
int t[100];
unsigned i;
for (i=k; i<=n-1; i++) t[i-k]=a[i];
for (int x=0; x<=k-1; x++) t[i++-k]=a[x];
}
由于这仍然是丑陋的,你可能会重写它以使逻辑更清晰,但我会将其作为练习。
这也假设您不允许使用STL数据结构;如果不是这样,请参阅Jerry Coffin的回答。
答案 2 :(得分:1)
由于您已将其标记为C ++,我将假设您正在使用它。在这种情况下,您几乎肯定会使用std::deque
而不是数组来存储数据。另外,队列通常有“前”和“后”,所以“左”并没有多大意义。
假设(仅仅是为了争论)你想要的是从队列的后面取出k个元素并将它们移到前面,你可以做类似的事情:
typedef std::deque<your_type> data;
void push_to_front(data &d, int k) {
if (k > d.size())
return;
for (int i=0; i<k; i++) {
data::value_type v = d.pop_back();
d.erase(d.back());
d.push_front(v);
}
}
如果你想向另一个方向旋转,那就是交换正面和背面角色的问题。
答案 3 :(得分:0)
如果您的意思是“将第k个元素移动到队列的前面”,那么这是一种方法:
void move( int *a, unsigned n, unsigned k )
{
int t; // To store the temporary for the k'th element
t = a[ k ];
// Shift all the elements to the right by one.
for( unsigned i = k; i > 0; --i )
a[ i ] = a[ i - 1 ];
// Put the k'th element at the left of the queue.
a[ 0 ] = t;
}
答案 4 :(得分:0)
#include <iostream>
#include <list>
template <typename T>
void Rotate(std::list<T>& list, int k){
for(int i=0; i<k; ++i){
T tmp(list.back());
list.pop_back();
list.push_front(tmp);
}
}
int main(){
std::list<int> ints;
ints.push_back(1); ints.push_back(2);
ints.push_back(3); ints.push_back(4);
Rotate(ints,2);
for(std::list<int>::const_iterator i = ints.begin(); i!=ints.end(); ++i)
std::cout << *i << std::endl;
return 0;
}
将输出:
3
4
1
2
答案 5 :(得分:0)
这个问题很老了,但现在似乎最简单的解决方案是依赖 std::rotate。复杂度是线性的,但取决于第一个和最后一个之间的距离。所以如果你需要旋转 1 个元素,复杂度是 O(1),对于 3,它是 O(3)。