序列

序列

概述

在前面的章节中,我们学习到了数组(C++与Java中)。如果我们需要记录 个数,我们并不需要定义 个变量,而是只需要定义一个长度为 的数组。

为什么我们需要序列?

假设我们现在定义了一个长度为 的数组 arr,并在这个数组中放入了 个数。根据在数组一章的知识,我们可以这样写:

代码实现

#include <bits/stdc++.h>

using namespace std;

int arr[100];
    
int main() {
    for (int i = 0; i < 100; i++) { // 注意!长度为 100 的数组的合法索引范围应为 0 ~ 99
        arr[i] = i + 1;
        // 将 arr[i] 赋值为 i + 1
    }
    
    for (int i = 0; i < 100; i++) {
        cout << arr[i] << " ";
    }
    
    return 0;
}
public class Main {
    public static void main(String[] args) {
        int[] arr = new int[100]; // 创建长度为 100 的数组

        // 填充数组,arr[i] 为 i + 1
        for (int i = 0; i < 100; i++) {
            arr[i] = i + 1;
        }

        // 输出数组的元素
        for (int i = 0; i < 100; i++) {
            System.out.print(arr[i] + " ");
        }
    }
}

但是! 如果我们现在想再多记录一个数呢?由于数组的长度在声明的时候就需要给定,我们无法改变数组的长度。所以,我们需要序列以解决这个问题。

序列的基本操作

序列有以下的常用操作:

  1. 将元素加入序列末尾:将一个元素加入到序列的末尾。例如将 加入到 的末尾,序列变为
  2. 弹出末尾的元素:删除末尾的元素。例如弹出 的末尾,序列变为
  3. 查询序列的长度:查询当前序列中元素的个数。例如 的长度为
  4. 清空序列:将序列中所有元素删除,也就是让序列变成空序列。

C++

在 C++ 中,序列通常是通过标准库中的 vector 类来表示的,vector 是一种动态数组,它可以存储任意类型的数据,并且会自动扩展或收缩以适应数据的变化。

#include <bits/stdc++.h>

using namespace std;
    
int main() {
    vector<int> vec1; // 声明了一个用于存放 int 类型数据的序列
    vector<char> vec2; // 声明了一个用于存放 char 类型数据的序列
    vector<vector<int>> vec3; // 声明了一个用于存放 vector<int> 类型数据的序列
    
    return 0;
}

在这里,我们可以把 vector<int> 看成一种数据类型(就和 intcharlong long 一样)。其中,我们一般用 vector<T> 表示序列,而 T 可以被替换成任意数据类型(intchar,自定义的结构体,或者是 vector<T>)。

注意:

  1. vector 是类型安全的容器,声明时需要指定元素类型。例如:vector<int> 只允许存储 int 类型的元素,vector<char> 只允许存储 char 类型的元素。
  2. 需要注意的是,vector 是基于动态数组实现的,它会自动扩展或收缩,所以不需要显式指定大小

需要注意的是,上述代码声明的序列长度为 ,也就是说,你需要通过 push_back 操作来放入元素,而不能直接使用例如 vec1[3] = 0 的方法来给序列赋值。你可以尝试以下代码:

#include <bits/stdc++.h>

using namespace std;
    
int main() {
    vector<int> vec1; // 声明了一个用于存放 int 类型数据的序列
    
    cout << vec1[3] << '\n'; // 尝试访问索引为 3 的元素
    
    return 0;
}

这是一个未定义行为。根据上文,我们只声明了一个空的序列。也就是说,这个序列的长度为 。访问其中第 个元素是未定义行为(和数组越界的逻辑一致)。

所以,我们需要学习怎么声明一个长度不为 的序列。(当然,由于序列的长度是可变的,所以我们预先声明一定长度的序列实际上可以被更改长度)。语法如下:

vector<int> vec1(5); // 声明一个长度为 5 的 vector,初始值为 0,即初始元素为 {0, 0, 0, 0, 0}
vector<int> vec2(5, 123); // 声明一个长度为 5 的 vector,初始值为 123,即初始元素为 {123, 123, 123, 123, 123}
vector<int> vec3 = {1, 2, 3, 4}; // 声明一个 vector,其中初始元素为 {1, 2, 3, 4}

在 C++ 中,序列最常用的操作可以通过以下代码实现:

功能 语法格式 单次操作时间复杂度 举例
添加元素(末尾) 序列变量名.push_back(需要添加的元素) vec.push_back(3)
删除元素(末尾) 序列变量名.pop_back() vec.pop_back()
访问元素 序列变量名[索引] vec[0]
修改元素 序列变量名[索引] = 新值 vec[0] = 5
获取序列长度 序列变量名.size() vec.size()
判断序列是否为空 序列变量名.empty() vec.empty()
清空序列 序列变量名.clear() vec.clear()

Java

在 Java 中,序列通常通过 ArrayList 类来表示,它是一个动态数组,可以自动扩展或收缩以适应数据的变化。

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>(); // 声明一个长度为 5 的 ArrayList,初始值为 0,即初始元素为 {0, 0, 0, 0, 0}
        ArrayList<Integer> list = new ArrayList<>(Collections.nCopies(5, 123)); // 声明一个长度为 5 的 ArrayList,初始值为 123,即初始元素为 {123, 123, 123, 123, 123}
        List<Integer> list = Arrays.asList(1, 2, 3, 4); // 声明一个 ArrayList,其中初始元素为 {1, 2, 3, 4}
    }
}

Java 中,序列最常用的操作可以通过以下代码实现:

功能 语法格式 单次操作时间复杂度 举例
添加元素(末尾) 序列变量名.add(需要添加的元素) list.add(3)
删除元素(末尾) 序列变量名.remove(序列变量名.size() - 1) list.remove(list.size() - 1)
访问元素 序列变量名.get(索引) list.get(0)
修改元素 序列变量名.set(索引, 新值) list.set(0, 5)
获取序列长度 序列变量名.size() list.size()
判断序列是否为空 序列变量名.isEmpty() list.isEmpty()
清空序列 序列变量名.clear() list.clear()

Python

Python 中,序列通常使用 list 来表示,它是一个灵活的容器,可以存储不同类型的数据。

my_list = []  # 声明一个空的列表
my_list = [123] * 5 # 声明一个长度为 5 的列表,初始化为 123,即初始元素为 {123, 123, 123, 123, 123}
my_list = [1, 2, 3, 4] # 声明一个列表,其中初始元素为 {1, 2, 3, 4}

Python 中,序列最常用的操作可以通过以下代码实现:

功能 语法格式 单次操作时间复杂度 举例
添加元素(末尾) 序列变量名.append(需要添加的元素) my_list.append(3)
删除元素(末尾) 序列变量名.pop() my_list.pop()
访问元素 序列变量名[索引] my_list[0]
修改元素 序列变量名[索引] = 新值 my_list[0] = 5
获取序列长度 len(序列变量名) len(my_list)
判断序列是否为空 len(序列变量名) == 0 len(my_list) == 0
清空序列 序列变量名.clear() my_list.clear()

序列的遍历

序列的遍历与数组的遍历相似,也是按照顺序访问序列中的所有元素。

vector<int> vec = {1, 2, 3, 4};

for (int i = 0; i < vec.size(); i++) {
    cout << vec[i] << " ";  // 输出每个元素
}

for (int value : vec) {
    cout << value << " ";  // 输出每个元素
}
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);

for (int i = 0; i < list.size(); i++) {
    System.out.print(list.get(i) + " ");  // 输出每个元素
}

for (int value : list) {
    System.out.print(value + " ");  // 输出每个元素
}
my_list = [1, 2, 3, 4]

for i in range(len(my_list)):
    print(my_list[i], end=" ")  # 输出每个元素

for value in my_list:
    print(value, end=" ")  # 输出每个元素

序列的排序

对于一个序列(以 为例),升序排序指按照元素的大小从小到大排序,结果为 降序排序指按照元素的大小从大到小排序,结果为

/*
升序排序:sort(vec.begin(), vec.end())
降序排序:sort(vec.begin(), vec.end(), greater<int>())
*/
#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> v = {1, 1, 4, 5, 1, 4};
    
    // 使用自定义比较函数进行排序
    sort(v.begin(), v.end());
    
    // 输出排序结果
    for (int i = 0; i < v.size(); i++) {
        cout << v[i] << " ";
    }
    return 0;
}

/*
升序排序:Collections.sort(list)
降序排序:Collections.sort(list, Collections.reverseOrder())
下文为自定义排序方法
*/

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

class Point {
    int x, y;
    
    // 构造函数
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Main {
    public static void main(String[] args) {
        ArrayList<Point> points = new ArrayList<>();
        points.add(new Point(1, 3));
        points.add(new Point(2, 2));
        points.add(new Point(3, 1));
        points.add(new Point(4, 4));
        
        // 自定义排序:按照 x * y 降序排序
        Collections.sort(points, new Comparator<Point>() {
            @Override
            public int compare(Point a, Point b) {
                return (b.x * b.y) - (a.x * a.y);  // 按照 x * y 降序排序
            }
        });
        
        // 输出排序结果
        for (Point p : points) {
            System.out.print("(" + p.x + ", " + p.y + ") ");
        }
    }
}
# 升序排序:sorted(my_list) 或 my_list.sort()
# 降序排序:sorted(my_list, reverse=True) 或 my_list.sort(reverse=True)
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"({self.x}, {self.y})"

# 创建结构体对象列表
points = [Point(1, 3), Point(2, 2), Point(3, 1), Point(4, 4)]

# 自定义排序:按照 x * y 降序排序
points_sorted = sorted(points, key=lambda p: p.x * p.y, reverse=True)

# 输出排序结果
print(points_sorted)

练习

题目描述

例题:序列操作

给定一个序列,你需要维护以下操作:

  • 操作 :向序列的末尾增加一个数
  • 操作 :删掉序列末尾的数(保证此时序列非空)
  • 操作 :输出序列中第 个数(起始下标为
  • 操作 :向序列中的第 个数与第 个数之间插入一个数 (起始下标为
  • 操作 :将序列升序排序
  • 操作 :将序列降序排序
  • 操作 :输出序列的长度
  • 操作 :输出整个序列
#include <bits/stdc++.h>

using namespace std;

int main() {
    vector<int> vec;
    int n, i, x, count;
    string operation;

    cin >> count;  // 输入操作的次数

    while (count--) {
        cin >> operation;

        if (operation == "1") {
            cin >> x;
            vec.push_back(x);  // 向序列末尾增加一个数
        }
        else if (operation == "2") {
            vec.pop_back();  // 删掉序列末尾的数
        }
        else if (operation == "3") {
            cin >> i;
            cout << vec[i] << endl;  // 输出序列中第 i 个数
        }
        else if (operation == "4") {
            cin >> i >> x;
            vec.insert(vec.begin() + i, x);  // 插入数 x 在第 i 和 i + 1 之间
        }
        else if (operation == "5") {
            sort(vec.begin(), vec.end());  // 升序排序
        }
        else if (operation == "6") {
            sort(vec.begin(), vec.end(), greater<int>());  // 降序排序
        }
        else if (operation == "7") {
            cout << vec.size() << endl;  // 输出序列的长度
        }
        else if (operation == "8") {
            for (int v : vec) {
                cout << v << " ";  // 输出整个序列
            }
            cout << endl;
        }
    }
    return 0;
}
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> list = new ArrayList<>();
        int count = sc.nextInt();  // 输入操作的次数

        for (int i = 0; i < count; i++) {
            String operation = sc.next();
            
            if (operation.equals("1")) {
                int x = sc.nextInt();
                list.add(x);  // 向序列末尾增加一个数
            }
            else if (operation.equals("2")) {
                list.remove(list.size() - 1);  // 删掉序列末尾的数
            }
            else if (operation.equals("3")) {
                int index = sc.nextInt();
                System.out.println(list.get(index));  // 输出序列中第 i 个数
            }
            else if (operation.equals("4")) {
                int index = sc.nextInt();
                int x = sc.nextInt();
                list.add(index, x);  // 插入数 x 在第 i 和 i + 1 之间
            }
            else if (operation.equals("5")) {
                Collections.sort(list);  // 升序排序
            }
            else if (operation.equals("6")) {
                Collections.sort(list, Collections.reverseOrder());  // 降序排序
            }
            else if (operation.equals("7")) {
                System.out.println(list.size());  // 输出序列的长度
            }
            else if (operation.equals("8")) {
                for (int v : list) {
                    System.out.print(v + " ");  // 输出整个序列
                }
                System.out.println();
            }
        }
    }
}
# 导入所需模块
from collections import deque

def main():
    # 使用 deque 来模拟 Java 中的 List
    my_list = []
    
    count = int(input())  # 输入操作的次数

    for _ in range(count):
        operation = input()  # 读取操作类型
        
        if operation == "1":
            x = int(input())  # 向序列末尾增加一个数
            my_list.append(x)
        
        elif operation == "2":
            my_list.pop()  # 删掉序列末尾的数
        
        elif operation == "3":
            index = int(input())  # 输出序列中第 i 个数
            print(my_list[index])
        
        elif operation == "4":
            index = int(input())  # 插入数 x 在第 i 和 i + 1 之间
            x = int(input())
            my_list.insert(index + 1, x)
        
        elif operation == "5":
            my_list.sort()  # 升序排序
        
        elif operation == "6":
            my_list.sort(reverse=True)  # 降序排序
        
        elif operation == "7":
            print(len(my_list))  # 输出序列的长度
        
        elif operation == "8":
            print(*my_list)  # 输出整个序列

if __name__ == "__main__":
    main()

课后习题

习题 1:求峰谷点数

习题 2:挤地铁

习题 3:逗号整合器

习题 4:丢手绢

习题 5:向量点乘

习题 6:向量叉乘

牛客代码笔记-牛栋 文章被收录于专栏

汗牛充栋,学海无涯。<br/> 内含算法知识点讲解,以及牛客题库精选例题。<br/> 学习算法,从牛栋开始。

全部评论

相关推荐

葬爱~冷少:我当时都是上午刷力扣,下午背八股,有活给我先别急,没活就干自己的事情
点赞 评论 收藏
分享
吴offer选手:HR:我KPI到手了就行,合不合适关我什么事
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务