循环右移----由简单到卓越

作者在 2008-06-05 17:14:19 发布以下内容

/*************************************************************************************\

命题:数组array,长度为n,要求向右循环移动k(0<k &lt; n),时间复杂度和空间复杂度尽可能小。

\*************************************************************************************/

一、第一反应

对于初次遇到此命题的人,一般都会这么做:先设置一个零时变量,将数组最后一个存入变量,然后将数组中前n-1个,从最后一个开始,依次存入后面一个位置,这样做的效果就把前n-1个整体向右平移一个单位,再把零时变量的值存入数组头,如此数组完成了向右循环移动1位的工作,再外加一个循环控制,循环右移k次,于是便完成了。代码如下:

template&lt;typename T>

void cycle_move(T* array,int n,int k)

{

     for(int i = 0;i < k;i++)             //k次循环右移

     {

         T temp = array[n-1];             //设置零时变量

         for(int j = n - 1;j > 0 ;j--)

              array[j] = array[j - 1];

         array[0] = temp;

     }

}

这是最直观的解法,算法外循环k次,内循环n-1次,k (k=1,2…n-1)是个随机值,等概率分布,循环次数的数学期望=[1*1/(n-1)+2*/(n-1)+…+(n-1)*1/(n-1)]*(n-1)=n(n-1)/2,所以时间复杂度为O(n2),空间复杂度为O(1)。时间复杂度难以让人接受。

 

二、换位思考

前一种方法目的是将后面的k个数据一个个的移到前面,可以换过来想想:将前面的一次性放到所要放的地方。

如:0 1 2 3 4 5 6 7右移3

0移到第三位,1移到第1+3位……如此原来的数需要保存,于是可以很容易想到:将03交换,但3也需要移到3+3位,于是可以交换此时的第0位和第6位,于是交换后第0位是6,而此时的6+3位则需要取8的模(6+3%8=1,于是跟第1位交换……

于是大概的雏形便出现了:每次用第一位跟第(i+k% n位的数据交换,终止条件是模为0

伪代码如下:

/*******************************************\

1. i = 0

2. i = (i + k)% n

3. if(i == 0) 退出循环

4. swap(array[0],array[i]),转到第步

\********************************************/

貌似很简单,但是问题便出来了,(i+k% n能访问到数组中所有的位置吗?如果能,那么每个位置是否只被访问了一次?下面将继续探讨。

 

三、深入探讨

首先举几个例子。

例一:0 1 2 3 4 5 6 7右移3位(n=8,k=3

1

3

1

2

0

4

5

6

7

2

6

1

2

0

4

5

3

7

3

1

6

2

0

4

5

3

7

4

4

6

2

0

1

5

3

7

5

7

6

2

0

1

5

3

4

6

2

6

7

0

1

5

3

4

7

5

6

7

0

1

2

3

4

循环了7次,i访问了所有点,且仅仅访问了一次。

例二:0 1 2 3 4 5 6 7 8右移3位(n=9,k=3

1

3

1

2

0

4

5

6

7

8

2

6

1

2

0

4

5

3

7

8

3次时i = (i+k)%n = 0;于是出故障了。

例三:0 1 2 3 4 5 6 7 9右移6位(n=9,k=6

1

6

1

2

3

4

5

0

7

8

2

3

1

2

6

4

5

3

7

8

3次时i = (i+k)%n = 0;于是也出故障了。

再细想一下也很容易发现,当nk的整数倍时,循环(n/k – 1)次一定会回到第0位,这是很显然的。而且条件可以更宽些,当nk不是互质时,循环[ n/(n,k) – 1 ]次也会回到第0( (n,k)表示nk的最大公约数)

于是我们先看看(n,k) = 1(即互质)

 

1. (n,k) = 1时的情况

/************************************************\

已知(n,k) = 1

i = 0;

i = (i + k)%n;

i == 0 时退出

求证:i可以访问数组中的每一个元素,且仅访问一次

\************************************************/

这个证明很简单:

<1>我们可以先取j = 0; j = j + k;i同时循环,则I = (I + k)%n j%n 是等价的。当I = (I + k)%n = 0时,则有j%n = 0,而j = j + k = pk (j初值为0p为一正整数),于是pk%n = 0,即 pkn的倍数,而kn是互质的,所以pn的倍数,又因为只要pk%n = 0,则退出,所以pn最小的倍数,所以必有p = n。所以i共访问了n个元素。

<2>因为I = j%n,设不同时刻的i1,i2i1 – i2 = (j1 – j2)%n = (p1*k – p2*k)%n = (p1 – p2)*k%n,若i1 = i2,则p1 – p2一定是n的倍数,显然不同时刻p1 != p2(因为j是递增的),所以任意时刻i1 != i2。即in产生的模互不相等。

<3>综合12,得in的所有余数一一映射,则必然可以得到i可以访问数组中的每一个元素,且仅访问一次。

于是对于(k,n) = 1的情况可以写出代码:

template<typename T>

void cycle_move(T* array,int n,int k)

{

     int i = 0;

     while((i = (i + k) % n) != 0)

         swap(array[0],array[i]);

}

 

2.考虑(k,n) != 1的情况

这种情况,有一个及其简单的思路----分段。

(k,n) = m,则可以把n个数看成每段长度为mn/m段数据的集合。例如:

0 1 2 3 4 5 6 7 8右移6位(n=9,k=6,m=3

可以看成:

{0 1 2} {3 4 5} {6 7 8}三段,

此时向右移动6位即将这三段向右移动2 (2 = k / m),鉴于前面的程序,则可以将每段中同一个位置的元素看成可以移动的集合,如{0 3 6},此时的n’k’必然是互质的,于是可以内嵌上面的一段程序。于是可以这样组织代码:

int greatest_common(int m,int n)      //求出最大公约数

{

     int r;

     while(r = m % n)   {    m = n;   n = r;   }

     return n;

}

template<typename T>

void cycle_move(T* array,int n,int k)

{

     int r = greatest_common(n,k);

     for(int i = 0;i < r;i++)

     {

         int j = i;

         while((j = (j + k) % n) != i)

              swap(array[0],array[j]);

     }

}

 

四、多一点思考

前面所做的一切都是为了这段代码,而这段代码却如此简练。

复杂度分析:

求最大公约数时间复杂度为O(logn), cycle_move循环次数为n,而logn &lt; n

所以该算法时间复杂度为O(n)。空间复杂度为O(1),产生在交换中。

事情到这里似乎已经很完美了,但何不多想一点?

这个程序最不好的地方在哪里呢?

很显然,最不好的地方在交换!每循环一次就得交换一次,二交换的实现类似于:

template&lt;typename T>

void swap(T& left,T& right)

{

     T temp = left;

     left = right;

     right = temp;

}

需要频繁地使用数组下表和这三个赋值语句,这就是我们需要改善的。

那么如何避免交换呢?

下面仍然先从(k,n) = 1说起。

前一种方法中,所有数据通过第0位作中转,以存储到目标位置,这就是交换产生的原因。如果另设一个中转的变量temp,源数据保存在temp中,每次需要将temp中的数据存到目标位,但此时目标位的数据就需要保存下来,如果保存下来了,则以此类推,得到最后一个被访问的(也就是第0位)需要被保存。这样一来就豁然开朗了:只要先保存第0位,然后按照跟前面 i 访问次序相反的次序访问,就可以不被覆盖。于是又得到下面的代码:

template<typename T>

void cycle_move(T* array,int n,int k)

{

     T temp = array[0];

     int i = 0,prei;

     while((prei = (n + i - k) % n) != 0)

     {

         array[i] = array[prei];

         i = prei;

     }

     array[i] = temp;

}

于是对于(k,n)!=1的情况可以这样组织代码:

template<typename T>

算法 | 阅读 3892 次
文章评论,共7条
夜风依旧(作者)
2008-06-05 17:37
1
部分小于号 或 尖括号 被转义了
tengzhao201
2010-04-28 10:30
2
//最高效的循环右移算法!!<br />
//这个是递归的写法 <br />
//author:tengzhao201 QQ:715572192<br />
//time:2010-4-24<br />
//时间复杂度为O(n),空间复杂度O(1),交换点在中间时比逆序法快一倍!!!<br />
void TZshift1(int a[],int N,int K)<br />
{<br />
&nbsp; &nbsp; &nbsp; &nbsp; K=K%N;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; if(0==K)return;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; int temp,qq,pp=0;<br />
&nbsp; &nbsp; &nbsp; &nbsp; pp=0;qq=K;<br />
&nbsp; &nbsp; &nbsp; &nbsp; for(int i=0;i&lt;N-K;i++,pp++,qq++)<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //swap(a[i%K],a[i+K]);问题的关键在于找到原来的第i个元素现在在哪里,通过观察可以发现在a[i%K]的位置,下面的代码实现了a[i%K]和a[i+K]的互换<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(K==pp)pp=0;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; temp=a[pp];<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[pp]=a[qq];<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[qq]=temp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; TZshift1(a,K,K-pp);<br />
}<br />
<br />
//最高效的循环右移算法!!<br />
//非递归的写法<br />
//author:tengzhao201 QQ:715572192<br />
//time:2010-4-24<br />
//时间复杂度为O(n),空间复杂度O(1),交换点在中间时比逆序法快一倍!!!<br />
void TZshift0(int a[],int N,int K)<br />
{<br />
&nbsp; &nbsp; &nbsp; &nbsp; K=K%N;<br />
&nbsp; &nbsp; &nbsp; &nbsp; if(0==K)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; //int count=0;<br />
&nbsp; &nbsp; &nbsp; &nbsp; int temp,qq,pp=0;<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; while(K&gt;0)<br />
&nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pp=0;qq=K;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(int i=0;i&lt;N-K;i++,pp++,qq++)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //swap(a[i%K],a[i+K]);问题的关键在于找到原来的第i个元素现在在哪里,通过观察可以发现在a[i%K]的位置,下面的代码实现了a[i%K]和a[i+K]的互换<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(K==pp)pp=0;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; temp=a[pp];<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[pp]=a[qq];<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a[qq]=temp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //count+=2;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; N=K;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(0==pp)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; K-=pp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //TZshift(a,K,K-pp);<br />
&nbsp; &nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; &nbsp; &nbsp; //cout&lt;&lt;&quot;In tatal,has used &quot;&lt;&lt;count&lt;&lt;&quot; steps.&quot;&lt;&lt;endl;<br />
}
tengzhao201
2010-04-28 13:20
3
经过测试,比楼主的求最大公约数的算法快一倍!
夜风依旧(作者)
2010-04-28 23:29
4
<div class="quote"><span class="q"><b>tengzhao201</b>: 经过测试,比楼主的求最大公约数的算法快一倍!</span></div>其实我慢在太多的取模运算,我优化了一下,终于比你快了!!!
夜风依旧(作者)
2010-04-28 23:30
5
<div class="quote"><span class="q"><b>tengzhao201</b>: 经过测试,比楼主的求最大公约数的算法快一倍!</span></div>#include &lt;algorithm&gt;<br />
#include &lt;iostream&gt;<br />
<br />
using namespace std;<br />
<br />
//最高效的循环右移算法!!<br />
//这个是递归的写法<br />
//author:tengzhao201 QQ:715572192<br />
//time:2010-4-24<br />
//时间复杂度为O(n),空间复杂度O(1),交换点在中间时比逆序法快一倍!!!<br />
void TZshift1(int a[],int N,int K)<br />
{<br />
&nbsp; &nbsp; K=K%N;<br />
<br />
&nbsp; &nbsp; if(0==K)return;<br />
<br />
&nbsp; &nbsp; int temp,qq,pp=0;<br />
&nbsp; &nbsp; pp=0;qq=K;<br />
&nbsp; &nbsp; for(int i=0;i&lt;N-K;i++,pp++,qq++)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//swap(a[i%K],a[i+K]);问题的关键在于找到原来的第i个元素现在在哪里,通过观察可以发现在a[i%K]的位置,下面的代码实现了 a[i%K]和a[i+K]的互换<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if(K==pp)pp=0;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;temp=a[pp];<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;a[pp]=a[qq];<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;a[qq]=temp;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; TZshift1(a,K,K-pp);<br />
}<br />
<br />
//最高效的循环右移算法!!<br />
//非递归的写法<br />
//author:tengzhao201 QQ:715572192<br />
//time:2010-4-24<br />
//时间复杂度为O(n),空间复杂度O(1),交换点在中间时比逆序法快一倍!!!<br />
void TZshift0(int a[],int N,int K)<br />
{<br />
&nbsp; &nbsp; K=K%N;<br />
&nbsp; &nbsp; if(0==K)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return;<br />
<br />
&nbsp; &nbsp; //int count=0;<br />
&nbsp; &nbsp; int temp,qq,pp=0;<br />
<br />
&nbsp; &nbsp; while(K&gt;0)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;pp=0;qq=K;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;for(int i=0;i&lt;N-K;i++,pp++,qq++)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;{<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//swap(a[i%K],a[i+K]);问题的关键在于找到原来的第i个元素现在在哪里,通过观察可以发现在a[i%K]的位置,下面的代码实现了 a[i%K]和a[i+K]的互换<br />
<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if(K==pp)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; pp=0;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;temp=a[pp];<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;a[pp]=a[qq];<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;a[qq]=temp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;//count+=2;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;N=K;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if(0==pp)<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;return;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;K-=pp;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;//TZshift(a,K,K-pp);<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; //cout&lt;&lt;&quot;In tatal,has used &quot;&lt;&lt;count&lt;&lt;&quot; steps.&quot;&lt;&lt;endl;<br />
}<br />
<br />
int greatest_common(int&nbsp;&nbsp;m,int&nbsp;&nbsp;n)&nbsp; &nbsp;&nbsp; &nbsp;//求出最大公约数<br />
{<br />
&nbsp; &nbsp; while(n) {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;m %= n;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;if(m == 0) {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;return n;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;n %= m;<br />
&nbsp; &nbsp; }<br />
&nbsp; &nbsp; return m;<br />
}<br />
<br />
template&lt;typename T&gt;<br />
void cycle_move(T* array,int n,int k)<br />
{<br />
&nbsp; &nbsp; k %= n;<br />
&nbsp; &nbsp; int r = greatest_common(k,n);<br />
&nbsp; &nbsp; for(int i = 0;i &lt; r;i++)<br />
&nbsp; &nbsp; {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;int t = i + k;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;int prej = i;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;int j = t;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;T tmp = array[j];<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;do {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;array[j] = array[prej];<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;j = prej;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;prej -= k;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;if(prej &lt; 0) {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp; prej += n;<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;}while(prej != t);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;array[j] = tmp;<br />
&nbsp; &nbsp; }<br />
}<br />
<br />
#include &quot;MsClock.h&quot;<br />
<br />
int main() {<br />
&nbsp; &nbsp; const int N = 100;<br />
&nbsp; &nbsp; const int K = 55;<br />
&nbsp; &nbsp; const int R = 100000;<br />
&nbsp; &nbsp; int a[N];<br />
<br />
&nbsp; &nbsp; for(int i = 0;i &lt; N;i++) {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;a<i> = i;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp;&nbsp;&nbsp;MsClock clk;<br />
&nbsp; &nbsp;&nbsp;&nbsp;for(int i = 0;i &lt; R;i++) {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;TZshift0(a,N,K);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;TZshift0(a,N,N-K);<br />
&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp;&nbsp;&nbsp;cout&lt;&lt;clk.Now()&lt;&lt;endl;<br />
&nbsp; &nbsp;&nbsp;&nbsp;copy(a,a+N,ostream_iterator&lt;int&gt;(cout,&quot; &quot;));<br />
&nbsp; &nbsp;&nbsp;&nbsp;cout&lt;&lt;endl;<br />
 <br />
&nbsp; &nbsp;&nbsp;&nbsp;clk.Restart();<br />
&nbsp; &nbsp;&nbsp;&nbsp;for(int i = 0;i &lt; R;i++) {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;cycle_move(a,N,K);<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;cycle_move(a,N,N-K);<br />
&nbsp; &nbsp;&nbsp;&nbsp;}<br />
&nbsp; &nbsp;&nbsp;&nbsp;cout&lt;&lt;clk.Now()&lt;&lt;endl;<br />
&nbsp; &nbsp;&nbsp;&nbsp;copy(a,a+N,ostream_iterator&lt;int&gt;(cout,&quot; &quot;));<br />
&nbsp; &nbsp;&nbsp;&nbsp;cout&lt;&lt;endl;<br />
<br />
&nbsp; &nbsp; return 0;<br />
}
夜风依旧(作者)
2010-04-28 23:31
6
<div class="quote"><span class="q"><b>tengzhao201</b>: 经过测试,比楼主的求最大公约数的算法快一倍!</span></div>//<br />
// MsClock.h<br />
//<br />
<br />
#ifndef _MS_CLOCK<br />
#define _MS_CLOCK<br />
<br />
#include &lt;Windows.h&gt;<br />
<br />
typedef unsigned long u_long;<br />
<br />
class MsClock {<br />
public:<br />
&nbsp; &nbsp; MsClock() {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ulStart = ::GetTickCount();<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; void Restart() {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;ulStart = ::GetTickCount();<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; u_long Now() {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return ::GetTickCount() - ulStart;<br />
&nbsp; &nbsp; }<br />
<br />
public:<br />
&nbsp; &nbsp; static u_long NowAbsolute() {<br />
&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return ::GetTickCount();<br />
&nbsp; &nbsp; }<br />
<br />
private:<br />
&nbsp; &nbsp; u_long ulStart;<br />
};<br />
<br />
#endif
夜风依旧(作者)
2010-05-04 10:38
7
<div class="quote"><span class="q"><b>tengzhao201</b>: 经过测试,比楼主的求最大公约数的算法快一倍!</span></div>最终发现问题不是模运算的问题,而是当数据量超过1个页面甚至多个页面时,我的算法发生缺页中断的频率非常高,所以性能不好,不过数据量小于1个页面时 表现良好。
游客请输入验证码