遍历字典是常数时间吗? (因为查找是不变的?)
Is iterating over a dictionary constant time? (Since lookup is constant?)
我的问题是关于字典的常量 O(1) 查找时间。
所以我有一本 key/value 对的字典。我有一个我正在迭代的项目列表。对于每个项目,我想检查它是否在字典中,如果不在,我想添加它,否则我会简单地通过。这是常数时间还是线性时间?
因为我正在遍历整个字典,但是我知道在字典中查找是 O(1)?- 这让我很困惑!
我真正的问题是,整体时间复杂度是O(N^2)吗?因为对于列表中的每个项目,我正在检查整个字典以查看它是否存在,如果不存在,我将每个项目添加到其中。
现在我不确定你在问什么,但是实现代码是:
foo_list = [1, 2, 3, 4, 5]
foo_dict = {1: "1", 4: "4", 6: "6"}
for i in foo_list:
if i not in foo_dict:
foo_dict[i] = str(i)
整体复杂度为O(n)。您正在执行 n 次查找,每次查找需要 O(1) 次,总时间复杂度为 O(n×1) = O(n).
For each item, I want to check whether it is in the dictionary, and if it is not in there, I want to add it...
旁注,在单独的步骤中检查和添加是一种常见的代码味道。简单地尝试插入通常更好。如果key已经存在则插入失败,无需先检查。这更有效,因为它执行一次查找而不是两次查找&mdash — 毕竟,插入必须执行与键检查完全相同的查找,以确定要插入的 位置 。首先检查重复工作。
在最坏的情况下,这不仅是一种效率提升,也是一种正确性。如果字典由多个线程访问,则先检查后插入访问模式可能会导致 time-of-check to time-of-use (TOCTOU) 错误。即,您可以检查密钥是否存在;它没有,所以你试图插入它;但与此同时,另一个线程悄悄进入并在您不注意时插入了相同的密钥,并且您覆盖了另一个线程的条目。
另一个常见的 TOCTOU 错误是检查文件是否存在,如果不存在则创建它。有关详细信息和示例,请参阅 Common Weakness Enumeration 367 - TOCTOU Race Condition。
当我们说字典中的查找是 O(1) 时,这意味着当在字典中查找时,您执行的操作比字典的大小要少得多(无需输入所考虑的详细信息一个操作)。
如果你进行 n 次查找,你会在字典的大小附近执行一些操作。所以你说它是 O(n),其中 n 是字典的大小。
本例中的 O 表示法只是一种相对度量,用于查看与输入大小相比执行了多少操作。
换句话说,O 表示法是我们用来谈论一个算法需要多长时间 运行 的语言。这就是我们比较不同方法解决问题的效率的方式。使用 O 表示法,我们根据输入变大时相对于输入的增长速度来表示 运行时间。
对于正式定义,请检查 here。
我的问题是关于字典的常量 O(1) 查找时间。
所以我有一本 key/value 对的字典。我有一个我正在迭代的项目列表。对于每个项目,我想检查它是否在字典中,如果不在,我想添加它,否则我会简单地通过。这是常数时间还是线性时间?
因为我正在遍历整个字典,但是我知道在字典中查找是 O(1)?- 这让我很困惑!
我真正的问题是,整体时间复杂度是O(N^2)吗?因为对于列表中的每个项目,我正在检查整个字典以查看它是否存在,如果不存在,我将每个项目添加到其中。
现在我不确定你在问什么,但是实现代码是:
foo_list = [1, 2, 3, 4, 5]
foo_dict = {1: "1", 4: "4", 6: "6"}
for i in foo_list:
if i not in foo_dict:
foo_dict[i] = str(i)
整体复杂度为O(n)。您正在执行 n 次查找,每次查找需要 O(1) 次,总时间复杂度为 O(n×1) = O(n).
For each item, I want to check whether it is in the dictionary, and if it is not in there, I want to add it...
旁注,在单独的步骤中检查和添加是一种常见的代码味道。简单地尝试插入通常更好。如果key已经存在则插入失败,无需先检查。这更有效,因为它执行一次查找而不是两次查找&mdash — 毕竟,插入必须执行与键检查完全相同的查找,以确定要插入的 位置 。首先检查重复工作。
在最坏的情况下,这不仅是一种效率提升,也是一种正确性。如果字典由多个线程访问,则先检查后插入访问模式可能会导致 time-of-check to time-of-use (TOCTOU) 错误。即,您可以检查密钥是否存在;它没有,所以你试图插入它;但与此同时,另一个线程悄悄进入并在您不注意时插入了相同的密钥,并且您覆盖了另一个线程的条目。
另一个常见的 TOCTOU 错误是检查文件是否存在,如果不存在则创建它。有关详细信息和示例,请参阅 Common Weakness Enumeration 367 - TOCTOU Race Condition。
当我们说字典中的查找是 O(1) 时,这意味着当在字典中查找时,您执行的操作比字典的大小要少得多(无需输入所考虑的详细信息一个操作)。
如果你进行 n 次查找,你会在字典的大小附近执行一些操作。所以你说它是 O(n),其中 n 是字典的大小。
本例中的 O 表示法只是一种相对度量,用于查看与输入大小相比执行了多少操作。
换句话说,O 表示法是我们用来谈论一个算法需要多长时间 运行 的语言。这就是我们比较不同方法解决问题的效率的方式。使用 O 表示法,我们根据输入变大时相对于输入的增长速度来表示 运行时间。
对于正式定义,请检查 here。