如何找到未列出或缺失的数字?

时间:2022-07-25 15:05:30

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.
  • 首先,我们创建一个数组,其中给定范围的所有数字都用作单个键,默认值为0。

  • Every input number then gets processed by awk as a key to the array so that the value gets incremented by 1.
  • 然后,每个输入数字都被awk作为数组的键处理,以便值增加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(因为它们在输入的数字范围内丢失)。

#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.
  • 首先,我们创建一个数组,其中给定范围的所有数字都用作单个键,默认值为0。

  • Every input number then gets processed by awk as a key to the array so that the value gets incremented by 1.
  • 然后,每个输入数字都被awk作为数组的键处理,以便值增加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(因为它们在输入的数字范围内丢失)。

#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