• 第 2 章 第 3 题 数组旋转问题 杂技算法实现


    问题分析

      输入:目标数组,旋转位数。

      处理:将目标数组旋转指定的位数。

      约束:无

    解答思路

      见P13页底部,一种类似杂技演员表演的移动元素的技巧。

      PS:控制每次" 杂技 "的结束是实现这个算法的关键所在,也是回答本题的第二问,请参考下面代码的注释部分。

    代码实现

     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 // 数组旋转函数
     6 void rotate(int *array, int n, int r);
     7 // 最大公约数函数
     8 int gcd( int a, int b);
     9 
    10 int main(void)
    11 {
    12     // 建立并初始化,输出测试数组。
    13     int array[10];
    14     int n=10;
    15     for (int i=0; i<10; i++) {
    16         array[i] = i+1;
    17     }
    18     cout << "目标数组:" << endl;
    19     for (int i=0; i<10; i++) {
    20         cout << array[i] << " ";
    21     }
    22     cout << endl;
    23 
    24     // 获取旋转位数
    25     int r;
    26     cout << "旋转位数:";
    27     cin >> r;
    28 
    29     // 处理旋转位数
    30     if (r<0) {
    31         cout << "非法的旋转位数" << endl;
    32         return 0;
    33     }
    34     else
    35         r %= n;
    36 
    37     // 调用数组旋转函数
    38     rotate(array, n, r);
    39 
    40     // 打印旋转结果
    41     cout << endl << "旋转后的数组:" << endl;
    42     for (int i=0; i<10; i++) {
    43         cout << array[i] << " ";
    44     }
    45     cout << endl;
    46 
    47     return 0;
    48 }
    49     
    50 void rotate(int *array, int n, int r) {
    51     // 数组长度 n 和旋转位数 r 的最大公约数就是需要置换的轮次数
    52     // 或者理解为表演杂技的" 次数 "
    53     int d = gcd(r, n);
    54 
    55     for (int i=0; i<d; i++) {
    56         // t 暂存旋转操作的首元素
    57         int t = array[i];
    58 
    59         // 每个轮次的操作
    60         int j = i;
    61         while ( (j+r)%n != i ) {
    62             array[j] = array[(j+r)%n];
    63             j = (j+r)%n;
    64         }
    65 
    66         // 将 t 中暂存元素放回数组
    67         array[j] = t;
    68     }
    69 }
    70 
    71 int gcd( int a, int b ){
    72     return b==0 ? a : gcd(b, a%b);
    73 }

    运行测试

      

    小结

      这个算法很不错,不需要特别的空间,消耗的时间也不多。

      但需要记住 n 和 r 的最大公约数的求法

  • 相关阅读:
    Mac sublime text4 修改选中行背景色
    转|java反射方法和使用详解
    浅析Java8中default关键字
    HashMap知识点梳理、常见面试题和源码分析
    100道运维常见面试题
    Python遇到的问题和解决方法汇总
    Git分支管理规范
    29个运维经典面试题
    运维必备技能
    PMP:挣值管理(PV、EV、AC、SV、CV、SPI、CPI)的记忆方法
  • 原文地址:https://www.cnblogs.com/scut-fm/p/3638783.html
Copyright © 2020-2023  润新知