{ }codelper

学习 › C#

数据 · 10

列表和数组

把多个值排成一列:个数、首尾、求和、全部转换。

列表(数组)按顺序存放多个值。
下面的示例读入一些数,输出个数、首尾两个值和总和,再把每个值都乘 2。

using System;using System.Linq; class Program{    static void Main()    {        int n = int.Parse(Console.ReadLine());        int[] nums = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();        Console.WriteLine(nums.Length);        Console.WriteLine($"{nums[0]} {nums[^1]}");        Console.WriteLine(nums.Sum());        int[] doubled = nums.Select(x => x * 2).ToArray();        Console.WriteLine(string.Join(" ", doubled));    }}
stdin
5
3 1 4 1 5
stdout
5
3 5
14
6 2 8 2 10

要点

  • 下标从 0 开始,所以最后一个值是 个数 - 1。
  • 有两种:大小固定的数组,和可以继续添加的列表。
    名字和用法因语言而异。
  • 求和、求最大值都是从头到尾遍历一遍。
    有的语言能用一行写出“全部乘 2”这样的变换。
  • b = a 不是复制。
    它只是给同一个列表再起一个名字,所以往 b 里添加,a 也会变(只有 C++ 的 vector 赋值时会复制)。
  • 越界读取时,大多数语言会报错停止。
    不停下来、悄悄给出错误值的语言反而更危险。

各语言的写法

Pythonlist — append、len(nums),最后一个是 nums[-1]。
有 sum、max;乘 2 写成 [x * 2 for x in nums]。
越界报 IndexError
JavaScript数组 — push、length,最后一个是 nums.at(-1)。
求和用 reduce,最大值用 Math.max(...nums),变换用 map。
越界不报错,得到 undefined
TypeScript和 JavaScript 一样。
像 number[] 这样写出元素类型
Java固定数组 int[] a = new int[n](a.length),可变的 ArrayList<Integer>(add、size()、get(i))。
求和用 Arrays.stream(a).sum() 或循环。
越界报 ArrayIndexOutOfBoundsException
C#固定的 int[](Length),可变的 List<int>(Add、Count)。
最后一个是 nums[^1]。
LINQ Sum()、Max()、Average()、Select。
越界报 IndexOutOfRangeException
C++std::vector<int> — push_back、size(),最后一个是 back()。
求和用 std::accumulate,最大值用 std::max_element。
[] 不检查范围,at(i) 会抛异常
C像 int a[1000] 这样事先定好大小,个数要自己另外记。
求和、最大值、变换都用循环。
越界读取也不会提示
Craykon[ ] — 添加、数量(最多 1 万个),最后一个是 nums[nums.数量 - 1]。
求和、最大值用循环。
越界会报“列表只有 0~4 号”的错误

常见错误

最大值从 0 开始

nums = [-3, -1]
best = 0
for x in nums:
    if x > best: best = x
print(best)

→ 0 — 所有值都是负数,一次也没有更新(答案应是 -1)

从第一个值 nums[0] 开始。

平均值被截成了整数Java · C# · C · C++

int sum = 14, n = 5;
double avg = sum / n;

→ 2 — 14 / 5 先做了整数除法(不是 2.8)

除之前先转换:(double)sum / n → 2.8。

越界读取却没有停下JavaScript · TypeScript · C · C++

const nums = [3, 1, 4];
console.log(nums[3]);
console.log(nums[-1]);

→ 输出两次 undefined,不报错。C 和 C++ 的 [] 会读到旁边内存里的任意值

读取前先检查下标是否在 0 到 个数 - 1 之间。

各语言的差异
整个列表直接输出时,各语言的样子不同:Python [3, 1, 4],JavaScript [ 3, 1, 4 ],Java 数组是 [I@1b6d3586 这样的标记,C# 数组是 System.Int32[]。
要用空格隔开输出,Python 用 print(*nums),JavaScript 用 nums.join(" "),C# 用 string.Join(" ", nums),Java 用循环;Craykon 的 控制台.输出(nums) 直接输出 3 1 4。

练习题