在列C移元素++ [英] Shifting elements in an array C++
问题描述
我已经开发了一个名为旋转我的栈对象类的方法。我所做的是,如果堆栈包含的元素:{0,2,3,4,5,6,7}我需要向前或向后旋转的元素
。在那里,如果我需要2个元素旋转前进,那么我们将有,数组中的{3,4,5,6,7,0,2}。如果我需要向后旋转,或-3元素,然后,看着原来的数组这将是,{5,6,7,0,2,3,4}
所以,我已经开发的方法工作正常。它只是非常ineffecient IMO。我在想,如果我可以通过使用Mod运算符环绕数组?或者,如果他们是无用的code犹豫不决,围绕我还没有意识到的是,等。
我想我的问题是,我怎么能简化这种方法吗?例如少用code。 : - )
无效栈::旋转(INT读)
{
INT I = 0;
而(R&0)//旋转从正面。
{
front.n =项目[顶+ 1] .N;
对于(INT J = 0; J<底部; J ++)
{
项目研究[J] =项[J + 1];
}
项目[计数1]。N = front.n;
R--;
}
而(R< 0)//转负。
{
如果(我==顶部+ 1)
{
front.n =项目[顶+ 1] .N;
项目[顶+ 1] .N =项[计数1] .N; //切换过去与第一
}
back.n =项目[++ i] .N; //第二个元素是新的背
项目[I] .N = front.n;
如果(我==底部)
{
项目[计数1]。N = front.n; //最后是第一
I = 0;
- [R ++;
继续;
}
其他
{
front.n =项目[++ i] .N;
项目[I] .N = back.n;
如果(我==底部)
{
I = 0;
- [R ++;
继续;
}
}
}
}
功能旋转
下面是根据提醒(你的意思是这样下的'mod'的操作? )
这也是非常有效的。
//辅助功能。
//查找GCD。
//见http://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations
INT GCD(INT A,INT B){回复B == 0?答:GCD(B,A%B);}
//元素的算法中的任务数是
//等于(items.size()+ GCD(items.size(),R))。
空旋转(的std ::矢量< INT>&安培;项目,诠释R){
INT大小=(INT)items.size();
如果(大小与LT = 1)返回; // 没事做
R =(R%+尺寸大小)%的大小; //适合R导入[0..size)
INT num_cycles = GCD(大小,R);
对于(INT first_index = 0; first_index< num_cycles ++ first_index){
诠释纪念品=项目[first_index] //项目要素分配
INT指数=(first_index + R)%的大小,INDEX_ preV = first_index;
而(指数!= first_index){
项目[INDEX_ preV =项目[指数] //项目要素分配
INDEX_ preV =指数;
指数=(指数+ R)%的大小;
};
项目[INDEX_ preV =纪念品; //项目要素分配
}
}
当然,如果它适合你改变的数据结构,在其他的答案中所述,你可以得到更有效的解决方案。
I've developed a method called "rotate" to my stack object class. What I did was that if the stack contains elements: {0,2,3,4,5,6,7} I would needed to rotate the elements forwards and backwards.
Where if i need to rotate forwards by 2 elements, then we would have, {3,4,5,6,7,0,2} in the array. And if I need to rotate backwards, or -3 elements, then, looking at the original array it would be, {5,6,7,0,2,3,4}
So the method that I have developed works fine. Its just terribly ineffecient IMO. I was wondering if I could wrap the array around by using the mod operator? Or if their is useless code hangin' around that I havent realized yet, and so on.
I guess my question is, How can i simplify this method? e.g. using less code. :-)
void stack::rotate(int r)
{
int i = 0;
while ( r > 0 ) // rotate postively.
{
front.n = items[top+1].n;
for ( int j = 0; j < bottom; j++ )
{
items[j] = items[j+1];
}
items[count-1].n = front.n;
r--;
}
while ( r < 0 ) // rotate negatively.
{
if ( i == top+1 )
{
front.n = items[top+1].n;
items[top+1].n = items[count-1].n; // switch last with first
}
back.n = items[++i].n; // second element is the new back
items[i].n = front.n;
if ( i == bottom )
{
items[count-1].n = front.n; // last is first
i = 0;
r++;
continue;
}
else
{
front.n = items[++i].n;
items[i].n = back.n;
if ( i == bottom )
{
i = 0;
r++;
continue;
}
}
}
}
The function rotate
below is based on reminders (do you mean this under the 'mod' operation?)
It is also quite efficient.
// Helper function.
// Finds GCD.
// See http://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations
int gcd(int a, int b) {return b == 0 ? a : gcd(b, a % b);}
// Number of assignments of elements in algo is
// equal to (items.size() + gcd(items.size(),r)).
void rotate(std::vector<int>& items, int r) {
int size = (int)items.size();
if (size <= 1) return; // nothing to do
r = (r % size + size) % size; // fits r into [0..size)
int num_cycles = gcd(size, r);
for (int first_index = 0; first_index < num_cycles; ++first_index) {
int mem = items[first_index]; // assignment of items elements
int index = (first_index + r) % size, index_prev = first_index;
while (index != first_index) {
items[index_prev] = items[index]; // assignment of items elements
index_prev = index;
index = (index + r) % size;
};
items[index_prev] = mem; // assignment of items elements
}
}
Of course if it is appropriate for you to change data structure as described in other answers, you can obtain more efficient solution.
这篇关于在列C移元素++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!