看了编程珠玑第二章,这里面讲了三道题目,这里说一下第二题,一维向量旋转算法。

题目:将一个n元一维向量(例数组)向左旋转i个位置。

解决方法:书上讲解了5种方法,自己只想起来2种最简单方法(下面讲的前两种)。

1.原始方法。

  从左向右依次移动一位,对所有数据平移;这样循环i次,算法最坏时间复杂度达n^2.耗时不推荐。

2.空间换时间。

  顾名思义,申请一个i长度的空间,把前i半部分放到申请空间中,再把后面的所有数据向左移动i个位置,最后把申请的空间中的数据放到后半部分。浪费空间,不推荐。

3.杂技算法(编程珠玑叫的,另叫求模置换法)

  我们知道第一种方法,每次向左旋转一个位置(其时间正比于n),总共需要旋转i次。这个方案会消耗过多的运行时间。而求模置换的方法则是尽量让每个数一次移动到位。总体的思想是:以i为除数对n求模,将向量遍历完并一次移动到位。

  另编程珠玑讲解:移动x[0]到临时变量t,然后移动x[i]到x[0],x[2i]到x[i],依次类推,直到取到x[0](其中下标都对长度n取模);然后依次对x[1]...x[i-1]执行上面操作。

  此算法技巧性比较强,一般不大好想,代码稍微复杂,也不推荐。

  另书上有代码参考,c++形式如下:

 1 //求公约数的代码,欧几里得算法
 2 unsigned int Gcd(unsigned int a, unsigned int b)
 3 {
 4     unsigned int temp;
 5     while (b != 0)
 6     {
 7         temp = a % b;
 8         a = b;
 9         b = temp;
10     }
11 
12     return a;
13 }
14 //对数组array[n]向左旋转rotdisk个位置
15 void zcxShift(int array[], int n, int rotdist)
16 {
17     unsigned int gcd = Gcd(n, rotdist);
18 
19     for (int i = 0; i < gcd; i ++)
20     {
21         int temp = array[i];
22         int j = i;
23         int k;
24         while(1)
25         {
26             int k = j +  rotdist;
27             if (k >= n)
28             {
29                 k -= n;
30             }
31             
32             if (k == i)
33             {
34                 break;
35             }
36 
37             array[j] = array[k];
38             j = k;
39         }
40         array[j] = temp;
41     }
42 
43 }
View Code

相关文章:

  • 2021-08-13
  • 2021-09-23
  • 2021-10-25
  • 2021-11-09
  • 2021-08-09
  • 2021-12-09
  • 2022-02-13
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-09-27
  • 2022-02-19
  • 2021-12-30
  • 2021-07-04
  • 2021-09-07
相关资源
相似解决方案