поиск пропущенных значений в диапазоне с использованием любого языка сценариев - Perl, Python или сценарий оболочки - PullRequest
7 голосов
/ 28 апреля 2010

Я застрял в одной проблеме поиска пропущенных значений в диапазоне, и диапазон также является переменной для последовательных строк.

ввод

673 673 673 676 676 680
2667 2667 2668 2670 2671 2674

вывод должен быть таким

674 675 677 678 679
2669 2672 2673

Это только одна часть, и значения строк также могут быть больше Если вам нужны какие-либо разъяснения, пожалуйста, дайте мне знать.

Ответы [ 12 ]

8 голосов
/ 07 августа 2013

Чистый Баш.

Используйте две подоболочки и запустите diff, затем очистите результаты.

diff <(cat my_range_with_holes) <(seq 1 1000) | grep '>' | cut -c 3-
6 голосов
/ 28 апреля 2010

В Python:

def report_missing_numbers(f):
    for line in f:
        numbers = [int(n) for n in line.split()]
        all_numbers = set(range(numbers[0], numbers[-1]))
        missing = all_numbers - set(numbers)
        yield missing

Примечание: all_numbers является ложью, поскольку диапазон исключает конечное число, но поскольку это число гарантированно будет в наборе, это не влияет на правильность алгоритм.

Примечание: Я удалил [-1] из своего исходного ответа, поскольку int(n) не заботится о конце '\n'.

5 голосов
/ 28 апреля 2010

Perl:

use Modern::Perl;

for my $line (<DATA>) {
    chomp $line;
    my @numbers     = split /\s+/, $line;
    my ($min, $max) = (sort { $a <=> $b } @numbers)[0, -1];
    my @missing     = grep { not $_ ~~ @numbers } $min .. $max;
    say join " ", @missing;
}

__DATA__
673 673 673 676 676 680
2667 2667 2668 2670 2671 2674
2 голосов
/ 28 апреля 2010

Пример кода с использованием Perl:

#!/usr/bin/perl
use strict;
use warnings;

my @missing;

while(<DATA>) {
    my @data = split (/[ ]/, $_);
    my $i = shift @data;
    foreach (@data) {
        if ($_ != ++$i) {
               push @missing, $i .. $_ - 1;
               $i = $_;
        }
    }
}

print join " ", @missing;

__DATA__
673 673 673 676 676 680
2667 2667 2668 2670 2671 2674

OUTPUT

674 675 677 678 679 2669 2672 2673
2 голосов
/ 28 апреля 2010

Python:

for line in open("inputfile.txt"):
    vals = set(map(int, line.split()))
    minv, maxv = min(vals), max(vals)
    missing = [str(v) for v in xrange(minv + 1, maxv) if v not in vals]
    print " ".join(missing)
1 голос
/ 23 ноября 2011

Perl oneliner:

perl -anE'($a,$b)=@F[0,-1];$,=" ";@h{@F}=();say grep!exists$h{$_},$a..$b'
1 голос
/ 11 мая 2010

Pure Bash:

while read -a line ; do
  firstvalue=${line[0]}
  lastvalue=${line[${#line[@]}-1]}
  output=()
  # prepare the output array
  for (( item=firstvalue; item<=lastvalue; item++ )); do
    output[$item]=1
  done
  # unset array elements with an index from the input set
  for item in ${line[@]}; do
    unset  "output[$item]"
  done
  # echo the remaining indices
  echo -e "${!output[@]}"
done < "$infile"
1 голос
/ 28 апреля 2010

Ruby:

$stdin.each_line do |line|
  numbers = line.scan(/\d+/).map(&:to_i)
  missing = (numbers.min..numbers.max).to_a - numbers
  puts missing.join " "
end

Версия для гольфа (79 знаков):

puts $stdin.map{|l|n=l.scan(/\d+/).map(&:to_i);((n.min..n.max).to_a-n).join" "}
0 голосов
/ 25 апреля 2018
a = [ 673, 673, 673, 676, 676, 680]

def woo(a):
    max_, min_ = a[0:-1]
    a = set(a)

    tot = set(list(range(min_,max_+1)))
    return list( tot - a )

У вас есть список. Оператор Set полезен для сравнения списков. В вашем случае вы хотите найти все элементы, которые:

  • между первым значением и последним
  • пройдено (разрыв)

Оператор Set генерирует все уникальные значения из списка

Чтобы выбрать все значения, которые находятся в tot, но не в a, просто введите tot - a. Просто отформатируйте вывод в виде списка

если вы хотите сохранить a в виде списка, вам нужно использовать copy() в своей функции:

a = [ 673, 673, 673, 676, 676, 680]

def woo(a):
    max_, min_ = a[0:-1]
    a = set(a.copy())

    tot = set(list(range(min_,max_+1)))
    return list( tot - a )
0 голосов
/ 28 апреля 2010

Bash решение:

cat file_of_numbers| xargs -n2 seq | sort -nu
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...