【C++】B2089 数组逆序重存放



博客主页:[小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C++


文章目录



💯前言

  • 在C++学习过程中,数组的操作是一个非常重要的基础技能,而逆序操作作为一种常见的数组处理任务,往往是很多编程题的考察重点。这次我们讨论了一道典型的逆序重排问题,分析了不同的实现方法,包括你提供的代码与老师的解决方案,并针对各自的特点和使用场景进行了深入比较。同时,我们还拓展了一些优化建议与注意事项。本文将详细梳理这些内容,带您从问题描述到最终解决方案,层层剖析,实现对数组逆序操作的全面掌握。
    C++ 参考手册

💯问题描述

B2089 数组逆序重存放

题目要求如下:

题目:数组逆序重排

将一个数组中的值按逆序重新存放。例如,原来的顺序为:8, 6, 5, 4, 1,经过逆序操作后,数组变为:1, 4, 5, 6, 8

输入格式

输入为两行:

  • 第一行是数组中元素的个数 n n n( 1 < n ≤ 100 1 < n \leq 100 1<n≤100)。
  • 第二行是 n n n 个整数,每两个整数之间用空格分隔。

输出格式

输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔。

输入输出样例

输入样例:

5
8 6 5 4 1

输出样例:

1 4 5 6 8

💯我的代码实现

以下是我的初步代码实现:

cpp 复制代码
#include <iostream>
using namespace std;

int main()
{
    int n = 0;
    cin >> n;
    int arr[n];
    for (int i = 0; i < n; i++)
    {
        cin >> arr[i];
    }

    for (int j = n - 1; j >= 0; j--)
    {
        cout << arr[j] << " ";
    }
    return 0;
}

代码分析

  1. 输入部分:

    • 我们首先读取整数 n,表示数组的大小。
    • 然后定义了一个数组 arr[n],用一个循环依次将用户输入的 n 个数存入数组。
  2. 逆序输出部分:

    • 从数组的最后一个元素开始,使用一个递减循环依次输出每个元素。
    • 每次输出时,添加了一个空格作为分隔。
  3. 注意点:

    • 使用了变长数组(int arr[n]),虽然大部分编译器支持,但这并不符合C++标准。
    • 输出末尾可能会多出一个空格,不符合严格的输出格式要求。

优化建议

  • 避免使用变长数组,可以改为动态数组(std::vector)。
  • 输出时通过条件判断,避免最后一个元素后面多加空格。

改进后的代码如下:

cpp 复制代码
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int n = 0;
    cin >> n;
    vector<int> arr(n);

    for (int i = 0; i < n; i++)
    {
        cin >> arr[i];
    }

    for (int j = n - 1; j >= 0; j--)
    {
        cout << arr[j];
        if (j > 0) cout << " "; // 避免最后一个元素后面多输出空格
    }

    return 0;
}

💯老师的做法与分析

在课堂上,老师提供了两种不同的实现方法,分别为:

方法1:通过双指针反转数组内容后输出

以下是代码实现:

cpp 复制代码
#include <iostream>
using namespace std;

int arr[110] = {0};

int main()
{
    int n = 0;
    cin >> n;
    int i = 0;
    for (i = 0; i < n; i++)
        cin >> arr[i];

    // 逆序
    int left = 0;
    int right = n - 1;
    while (left < right)
    {
        int tmp = arr[left];
        arr[left] = arr[right];
        arr[right] = tmp;
        left++;
        right--;
    }

    for (i = 0; i < n; i++)
        cout << arr[i] << " ";
    return 0;
}

思路分析

  1. 输入部分:

    • 先定义一个全局数组 arr,通过输入循环将数据存入数组。
  2. 反转部分:

    • 使用两个指针 leftright,分别指向数组的开头和末尾。
    • 循环交换这两个指针指向的值,同时将 left 向右移动,right 向左移动,直到两者相遇或交错。
    • 这个过程完成了数组的就地逆序操作。
  3. 输出部分:

    • 反转操作完成后,顺序输出数组中的每个元素。

优缺点

  • 优点:
    • 反转操作是就地完成的,空间复杂度为 O ( 1 ) O(1) O(1)。
    • 修改了原数组内容,方便后续使用。
  • 缺点:
    • 修改了数组原有顺序,若后续需要原始顺序,则需要额外保存。

方法2:直接逆序输出数组

以下是代码实现:

cpp 复制代码
#include <iostream>
using namespace std;

int arr[110] = {0};

int main()
{
    int n = 0;
    cin >> n;
    int i = 0;
    for (i = 0; i < n; i++)
        cin >> arr[i];

    // 逆序输出
    for (i = n - 1; i >= 0; i--)
        cout << arr[i] << " ";

    return 0;
}

思路分析

  1. 输入部分:

    • 与方法1类似,首先读取数组的长度和内容。
  2. 逆序输出部分:

    • 从数组的最后一个元素开始,依次向前输出每个元素。
    • 仅在输出过程中完成逆序,不改变数组本身的内容。

优缺点

  • 优点:
    • 实现简单,逻辑清晰,不修改原数组内容。
    • 适合只需要输出逆序结果的场景。
  • 缺点:
    • 若后续需要逆序后的数组内容,还需再次操作。

💯对比与总结

通过上述代码实现和分析,可以得出以下结论:

特点 方法1:反转数组内容 方法2:直接逆序输出
实现复杂度 略复杂,需要两个指针和交换操作 简单,只需逆序遍历索引即可
时间复杂度 O ( n ) O(n) O(n) O ( n ) O(n) O(n)
空间复杂度 O ( 1 ) O(1) O(1) O ( 1 ) O(1) O(1)
修改原数组 修改了原数组内容 不修改原数组内容
适用场景 需要使用反转后的数组 仅需逆序输出结果即可

💯扩展与建议

在实际开发中,选择哪种实现方法取决于具体需求。如果需要对数组进行多次操作并且对逆序后的结果有后续需求,可以选择方法1;如果仅需输出结果且对原数组不做修改,则方法2是更好的选择。此外,以下是一些扩展建议:

  1. 使用标准库函数:

    • 在C++中可以利用std::reverse对数组或容器进行快速反转,例如:

      cpp 复制代码
      #include <algorithm>
      #include <vector>
      using namespace std;
      
      int main() {
          vector<int> arr = {8, 6, 5, 4, 1};
          reverse(arr.begin(), arr.end());
          for (int num : arr) {
              cout << num << " ";
          }
          return 0;
      }
  2. 优化输入输出:

    • 对于大数据量,可以使用cin.tie(0)ios::sync_with_stdio(false)提高输入输出效率。
  3. 考虑更多场景:

    • 如果数组需要进行部分逆序或多次逆序操作,可以结合具体需求设计更灵活的算法。

💯小结

本文详细分析了数组逆序重排的两种常见实现方法,并对其优缺点和适用场景进行了全面的比较。在实际编程中,应根据具体需求选择合适的方法,同时注意代码的规范性和扩展性。通过学习这道题目,我们不仅掌握了逆序操作的实现,还了解了C++数组操作中的一些技巧和注意事项,这对后续学习和开发都有很大帮助。



相关推荐
学习前端的小z9 小时前
【C++】P1428 小鱼比可爱
c
学习前端的小z12 小时前
【C++】图像模糊处理题目详解与实现
c
学习前端的小z1 天前
【C++】深入理解C语言中的特殊字符处理与问题分析优化
c
XLYcmy2 天前
分布式练手:Client
c++·windows·分布式·网络安全·操作系统·c·实验源码
XLYcmy2 天前
分布式练手:Server
c++·windows·分布式·网络安全·操作系统·c·实验源码
charlie1145141914 天前
如何使用 OpenCV 扫描图像、查找表和时间测量
c++·opencv·学习·计算机视觉·c·教程
charlie1145141914 天前
Linux Kernel Programming4
linux·c·makefile·内核开发·内核日志
学习前端的小z5 天前
【C++】2029:【例4.15】水仙花数
c
学习前端的小z5 天前
【C++】探索一维数组:从基础到深入剖析
c