我有一个适用于我的“items”int 数组的工作旋转函数。下面的代码完成了它,只是我不必要地传输了值。我试图实现“就地”旋转。我的意思是,ptr 会递增或递减,而不是从数组中获取值。我需要以这种方式“提高”此方法的效率级别。有什么建议吗?
void quack::rotate(int nRotations)
{
if ( count <= 1 ) return;
else // make sure our ptrs are where we want them.
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt;
}
for (int temp = 0; nRotations != 0;)
{
if ( nRotations > 0 )
{
temp = *intFrontPtr;
*intFrontPtr = *intBackPtr;
*intBackPtr = temp; // Connect temps for the rotation
--intBackPtr; // Move left [...<-] into the array
}
else if ( nRotations < 0 )
{
temp = *intBackPtr;
*intBackPtr = *intFrontPtr;
*intFrontPtr = temp; // Connect temps for the rotation
++intFrontPtr; // Move right [->...] into the array
}
if ( intBackPtr == &items[0].myInt ||
intFrontPtr == &items[count-1].myInt )
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt; // need to re-set
if ( nRotations > 0 ) nRotations--; // Which ways did we rotate?
else nRotations++;
}
}
}
哦,是的,我正在尝试练习 C++,并且知道它们有许多函数,这些函数已经被编程为可以执行此操作...我正在尝试“构建我自己的”。我想我已经在语法上把它写下来了,但效率始终是我挣扎的地方。作为一个新手,我非常感谢对这方面的批评。
I have a working rotating function going for my "items" int array. The code below gets it done, except that im transferring values out unnecessarily. Im trying to acheive the "inplace" rotation. What I mean by that is where the ptrs would increment or decrement instead of grabbing values out of the array..By which I need to "up" the efficiency level in that way for this method..Any Suggestions?
void quack::rotate(int nRotations)
{
if ( count <= 1 ) return;
else // make sure our ptrs are where we want them.
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt;
}
for (int temp = 0; nRotations != 0;)
{
if ( nRotations > 0 )
{
temp = *intFrontPtr;
*intFrontPtr = *intBackPtr;
*intBackPtr = temp; // Connect temps for the rotation
--intBackPtr; // Move left [...<-] into the array
}
else if ( nRotations < 0 )
{
temp = *intBackPtr;
*intBackPtr = *intFrontPtr;
*intFrontPtr = temp; // Connect temps for the rotation
++intFrontPtr; // Move right [->...] into the array
}
if ( intBackPtr == &items[0].myInt ||
intFrontPtr == &items[count-1].myInt )
{
intFrontPtr = &items[0].myInt;
intBackPtr = &items[count-1].myInt; // need to re-set
if ( nRotations > 0 ) nRotations--; // Which ways did we rotate?
else nRotations++;
}
}
}
Oh yes, Im trying to practice c++ and know their are many functions floating around that are programmed to do this already...Im trying to "build my own". I think i've got it down syntactically, but the efficiency is always where i struggle. As, a novice, I would greatly appreciate critisim towards this aspect..
发布评论
评论(10)
有一个旋转数组中元素的老技巧(我第一次在编程珍珠中看到它)
假设您想将数组向左旋转三个元素。
首先反转前三个元素,然后反转其余元素,然后反转整个数组。
可以就地反转数组的部分,因此不需要任何额外的内存。
There is an old trick for rotating elements in an array (I first saw it in Programming Pearls)
Say you want to rotate an array to the left by three elements.
First reverse the first three elements, next reverse the remaining elements, and then reverse the entire array.
Reversing portions of the array can be done in place so you don't need any extra memory.
您可以将数据保留在适当的位置,并使用“基本索引”成员来指示数组应从何处开始。然后,您需要在访问数组时使用它来调整索引。数组本身应该是私有的,并且只能通过进行调整的访问器函数来访问。像这样的东西:
虽然我会把它称为
RotatableArray
,而不是quack
。You can leave the data in place, and have a "base index" member to indicate where the array should start. You then need to use this to adjust the index when accessing the array. The array itself should be private, and only accessed through accessor functions that do the adjustment. Something like this:
although I'd call it something like
RotatableArray
, rather thanquack
.像往常一样,如果您确实必须物理旋转元素,那么 C++ 的正确答案是使用 std::rotate,它正是您想要做的。
如果您必须手动实现它(作为练习作业),请查看这些 幻灯片。
As usual, if you really have to physically rotate the elements, the correct answer for C++ would be to use
std::rotate
, which does exactly what you want to do.If you have to implement it manually (as a practice assignment), take a look at these slides for algorithms from John Bentley's "Programming Pearls".
一项一项地轮换确实不是办法。如果你做的事情超过 2 或 3 圈,它就会变得非常慢非常快。
编辑:
作为最后的想法...将元素放入(双)链接的“循环”列表中(因此最后一个元素指向第一个),将需要旋转以仅将头指针移动几个元素。 (头指针是指示循环列表中哪个元素是开始的指针)。
这是迄今为止对元素列表进行旋转的最快(也是最简单)的方法
doing the rotations one by one is really not the way to go. If you are doing anything more than 2 or 3 rotations it gets really slow really quick.
edit:
as a final thought... putting the elements in a (double) linked 'looped' list (so the final element points to the first), would require for a rotate to only move the head pointer a few elements. (The head pointer being a pointer to indicate which element in the looped list is the beginning).
this is by far the quickest (and easiest) way to do a rotate on a list of elements
实际上,做到这一点的方法是使用索引而不是指针。
Really the way to do it is to use indexes instead of pointers.
我可能有另一种解决方案来内联旋转数组。这种方法不像之前提出的那样采用反转元素集的老技巧,而是按如下方式工作:
初始化:(
注意 q = 左移量,n = 数组长度)
在 i=0 到 n-1 上循环,其中 n = 数组长度
以下内容可能有助于解释如何进行这有效。
例如,向左旋转 2 个字符:
abcdefg
cdefgab
正如您所看到的,这需要不超过 n 次迭代,因此它是线性时间算法,也内联旋转(除了少数临时变量之外不需要额外的存储)。
这是一个实现上述算法的函数,您可以尝试一下:
I may have an alternate solution to rotating the array inline. Rather than the old trick of reversing sets of elements, as proposed earlier, this approach works as follows:
Initialization:
(Note q = amount to shift left, n = length of array)
Loop on i=0 to n-1, where n = length of array
The following may help explain how this works.
Example, rotate to the left by 2 characters:
a b c d e f g
c d e f g a b
As you can see, this requires no more than n iterations, so it is linear time algorithm that also rotates inline (requires no additional storage other than the few temporary variables).
Here is a function that implements the above algorithm so you can try it out:
这是我通过修改此处的代码得到的:
Here's one that I got by modifying the code here:
这是 sdtom 解决方案的代码
Here is code for sdtom solution
https://stackoverflow.com/q/17119000/2383578:这与此处讨论的内容有些相似。将数组旋转特定量。
https://stackoverflow.com/q/17119000/2383578 : This is somewhat similar to what is discussed here. Rotating the array by a particular amount.
有很多方法可以按 d 位进行数组旋转。
下面的链接来自Programming Pearls pdf。看看这个。用代码解释的非常清楚。
http://www.cs.bell-labs.com/cm /cs/pearls/s02b.pdf
There are many ways to do array rotation by d places.
The link below is from Programming Pearls pdf. Check this out. Explained very clearly with code.
http://www.cs.bell-labs.com/cm/cs/pearls/s02b.pdf