I'll have a list of numbers, each on its own line (say 0 -100). How do I find the numbers that are not listed or missing?
我将有一个数字列表,每个都在自己的行(比如0 -100)。如何找到未列出或缺失的数字?
4 个解决方案
#1
12
Add them all to a set. Then subtract from a set filled with 1-100. Here's an example for 0-9:
将它们全部添加到一组中。然后从填充1-100的集合中减去。这是0-9的示例:
>>> set(range(10)) - set([1, 4, 5, 6, 8, 2])
set([0, 9, 3, 7])
>>>
I had [1, 4, 5, 6, 8, 2]
listed. To find out which numbers in range 0-9 are missing, I created a set with all of 0-9 and then subtracted the set with [1, 4, 5, 6, 8, 2]
from it. And found out that [0, 9, 3, 7]
were missing.
我列出了[1,4,5,6,8,2]。为了找出缺少0-9范围内的数字,我创建了一个全部为0-9的集合,然后从中减去了[1,4,5,6,8,2]的集合。并发现[0,9,3,7]缺失了。
Sets are fairly efficient for this. As an added benefit, duplicates will be handled gracefully.
集合对此非常有效。作为额外的好处,重复将被优雅地处理。
#2
1
If L is the list of numbers, then
如果L是数字列表,那么
set(L).difference(xrange(101))
saves creating a set from the xrange
从xrange中保存创建一个集合
In [1]: L=[1, 4, 5, 6, 8, 2]
In [2]: timeit set(range(101)) - set(L)
10000 loops, best of 3: 21.7 µs per loop
In [3]: timeit set(L).symmetric_difference(range(101))
100000 loops, best of 3: 14.2 µs per loop
In [4]: timeit set(L).difference(range(101))
100000 loops, best of 3: 9.73 µs per loop
#3
0
Here's an awk
solution using an associative (key-value) array:
这是一个使用关联(键值)数组的awk解决方案:
printf '%s\n' 1 4 5 6 8 2 |
awk -F " " -v first=0 -v last=9 '
BEGIN {
for(i=first; i<=last; i++)
array[i] = 0
}
{
for(i=1;i<=NF;i++)
array[$i] += 1
}
END {
for (num in array)
if (array[num] == 0) print num
}
'
- First, we create an array with all numbers of a given range used as single keys with default value 0.
- Every input number then gets processed by awk as a key to the array so that the value gets incremented by 1.
- At the end, only those keys get printed that have not been incremented, i.e. that have a value of 0 (because they were missing in the input range of numbers).
首先,我们创建一个数组,其中给定范围的所有数字都用作单个键,默认值为0。
然后,每个输入数字都被awk作为数组的键处理,以便值增加1。
最后,只有那些没有增加的键被打印出来,即它们的值为0(因为它们在输入的数字范围内丢失)。
#4
0
bash:
# first set up an array containing the whole range
declare -a nums
for i in {0..100}; do
nums[$i]=1
done
# then read the file and remove the numbers from it
while read number; do
unset nums[$number]
done < file.with.numbers
# the remaining array keys are the numbers not found in the file
for number in "${!nums[@]}"; do
echo $number
done
#1
12
Add them all to a set. Then subtract from a set filled with 1-100. Here's an example for 0-9:
将它们全部添加到一组中。然后从填充1-100的集合中减去。这是0-9的示例:
>>> set(range(10)) - set([1, 4, 5, 6, 8, 2])
set([0, 9, 3, 7])
>>>
I had [1, 4, 5, 6, 8, 2]
listed. To find out which numbers in range 0-9 are missing, I created a set with all of 0-9 and then subtracted the set with [1, 4, 5, 6, 8, 2]
from it. And found out that [0, 9, 3, 7]
were missing.
我列出了[1,4,5,6,8,2]。为了找出缺少0-9范围内的数字,我创建了一个全部为0-9的集合,然后从中减去了[1,4,5,6,8,2]的集合。并发现[0,9,3,7]缺失了。
Sets are fairly efficient for this. As an added benefit, duplicates will be handled gracefully.
集合对此非常有效。作为额外的好处,重复将被优雅地处理。
#2
1
If L is the list of numbers, then
如果L是数字列表,那么
set(L).difference(xrange(101))
saves creating a set from the xrange
从xrange中保存创建一个集合
In [1]: L=[1, 4, 5, 6, 8, 2]
In [2]: timeit set(range(101)) - set(L)
10000 loops, best of 3: 21.7 µs per loop
In [3]: timeit set(L).symmetric_difference(range(101))
100000 loops, best of 3: 14.2 µs per loop
In [4]: timeit set(L).difference(range(101))
100000 loops, best of 3: 9.73 µs per loop
#3
0
Here's an awk
solution using an associative (key-value) array:
这是一个使用关联(键值)数组的awk解决方案:
printf '%s\n' 1 4 5 6 8 2 |
awk -F " " -v first=0 -v last=9 '
BEGIN {
for(i=first; i<=last; i++)
array[i] = 0
}
{
for(i=1;i<=NF;i++)
array[$i] += 1
}
END {
for (num in array)
if (array[num] == 0) print num
}
'
- First, we create an array with all numbers of a given range used as single keys with default value 0.
- Every input number then gets processed by awk as a key to the array so that the value gets incremented by 1.
- At the end, only those keys get printed that have not been incremented, i.e. that have a value of 0 (because they were missing in the input range of numbers).
首先,我们创建一个数组,其中给定范围的所有数字都用作单个键,默认值为0。
然后,每个输入数字都被awk作为数组的键处理,以便值增加1。
最后,只有那些没有增加的键被打印出来,即它们的值为0(因为它们在输入的数字范围内丢失)。
#4
0
bash:
# first set up an array containing the whole range
declare -a nums
for i in {0..100}; do
nums[$i]=1
done
# then read the file and remove the numbers from it
while read number; do
unset nums[$number]
done < file.with.numbers
# the remaining array keys are the numbers not found in the file
for number in "${!nums[@]}"; do
echo $number
done