Python 竞赛编程输入方法

2024 年 8 月 29 日 | 阅读 6 分钟

Python 语言非常友好,唯一的缺点就是运行速度慢。它比 C、C++ 和 Java 慢得多。在在线编程平台,如果 C/C++ 的限制是 X。通常情况下,Python 提供的时间是 Java 的 5 倍。

对于需要大量输入输出的问题,语言提供了各种输入输出方式来加速代码执行。

一个例子

考虑一个要求输入 N 个数字并求和的问题。

输入 N 的值。

输入 N 个整数,用单个空格分隔在同一行。

输入

输出

10

Python 解决该问题的各种方法

普通 Python 实践:(Python 2.7)(Python 2.7)

  1. `raw_input()` 函数可以有一个可选的提示参数。它生成的字符串也没有末尾的换行符。
  2. 当使用 `print` 来格式化输入时(参数之间和末尾相对较新的内容),会调用特定对象的写入函数。

输出

3
1 2 3
6

利用内置 `stdin` 和 `stdout` 的更快技巧:Python 2.7

  1. 另一方面,**`sys.stdin`** 是一个文件对象。它就像构造任何其他文件对象一样工作,用于从文件接收输入。在这种情况下,文件将是一个典型的输入缓冲区。
  2. `stdout.write('Dn')` 比 `print 'D'` 执行得更快。
  3. 一次性将所有内容写入 `stdout` 更快。

`write("".join(list-comprehension))`,但这取决于输入的大小(内存使用方面)。

输出

The time difference:
timing overview (100k lines each)
??????????-
Print: 6.04 s
Write time: 0.122 seconds
Print in 0.121 seconds using Stdout

正如我们到目前为止所看到的,为了提高代码效率,将数据从普通系统读取并输入到标准系统总是个好主意,这在竞争性编程中总是必需的。但是,每次需要这些长段落时,您都想写出来吗?那么,使用 Python 的优势是什么呢。

让我们谈谈如何解决这个问题。我们可以做的是创建不同的函数来接受不同类型的数据并按需调用它们。

当你希望接受一行包含特定数量数字的输入时

假设输入格式如下。

我们希望不同的变量来引用它们。我们想要的是

因此,下面是编写一个名为 `get_ints()` 的方法的方法

我们不再需要一遍又一遍地输入这行代码。为了接受这种格式的输入,你只需要调用 `get_ints()` 函数。`map` 函数在本方法 `get_ints` 中被使用。

当我们想接受一行输入的整数列表时

假设输入格式如下。

我们希望整个整数列表包含在一个变量中。我们想要的是

因此,我们将通过以下方式构建一个名为 `get_list()` 的函数

你不再需要一遍又一遍地输入这行代码。要接受这种格式的输入,你只需要调用 `get_ints()` 函数。

当你希望接受字符串输入时

假设输入格式如下。

我们希望将此字符串存储在一个引用变量中。我们想要的是

因此,我们将通过以下方式构建一个名为 `get_string()` 的函数

你不再需要一遍又一遍地输入这行代码。要接受这种格式的输入,你只需要调用 `get_string()` 函数。

添加了缓冲管道 IO:Python 2.7

  1. 为了加快输出速度,只需在提交代码之前放置缓冲 IO 代码。
  2. `io.BytesIO` 对象有一个优点,那就是它们实现了标准接口,也称为“类文件”对象。每次在 `BytesIO` 对象上调用 `read(n)` 时,内部指针都会向前移动。
  3. `atexit` 模块提供了一个简单的接口,用于在程序正常关闭时注册要调用的方法。`sys` 模块也提供了一个名为 `sys.exitfunc` 的钩子,但那里只能注册一个函数。使用 `atexit` 注册。

标准方法在处理大量数据时经常超时。方法 2 使得维护大量的 I/O 数据变得容易。最快的方法是方法 3。通常,方法 2 和 3 对于处理大于 2 或 3 MB 的输入数据文件很有用。

请注意,上面显示的 Python 代码是 Python 2.7 版本。对于 Python 3.X 版本,只需使用 Python 3.X 的 `input()` 语法代替 `raw_input()`。其余的应该可以正常工作。

Reload(module)

重新加载先前导入的模块。由于参数是模块对象,因此它必须已经成功导入。如果我们使用外部编辑器修改了模块源数据,并且想在不退出 Python 解释器的情况下测试更新后的版本,这很有用。模块对象是返回值(与模块参数相同)。

调用 `Reload(module)` 时

  • Python 模块的代码被逆向工程,并且模块级别的代码被再次执行,以定义与模块字典中的名称关联的新对象集。扩展模块不会第二次调用 `init` 函数。
  • 旧对象,就像所有其他 Python 对象一样,只有当它们的引用计数达到零时才会被回收。
  • 任何新的或修改的对象都通过模块命名空间中的更新标识符进行引用。
  • 要引用新对象,必须为每个命名空间(例如模块外部的名称)修改对旧工件(例如模块外部的名称)的进一步引用。

当模块重新加载时,模块的字典(包含模块的全局变量)会被保留。这通常不是问题,因为名称的重新解释将优先于之前的定义。如果模块的新版本没有定义先前版本已定义的名称,则会保留之前的定义。