对于循环建议

时间:2013-01-11 05:41:26

标签: perl

我有一个字段,取值从0到6,00,000

对于该字段,数据库中的值为5,6,7,8,45,91,92,93,94

我必须获得此字段的免费值和使用价值建议

1.适用
Minvalue = 0 maxvalue = 94(来自数据库)

我使用for循环(i = minvalue; i< = maxvalue; i ++) 在这种情况下循环运行94次,每次检查是否与数据库条目匹配(5,6,7,45..94)

我打印输出范围,如
使用值:
5至8
45 91至94

由于价值较低,因此工作速度很快。如果在数据库中甚至有一个像490000这样的条目那么循环就会运行很长时间。

2.FREE
最小值= 0 maxvalue = 600000(来自字段定义)

我在这里也有相同的循环概念,所以循环运行5lac次。输出永远不会耗费太多时间

我希望输出像
自由值:
0到4
9至44
46至90
95-600000

任何减少循环执行或使用其他逻辑的方法?

3 个答案:

答案 0 :(得分:3)

不要那样做。

如果可能,请将此数据库列设置为AUTO_INCREMENT(或您的SQL引擎最接近的替代方案),以便自动分配新值。如果无法做到这一点,您可以改为SELECT MAX(col) + 1 FROM table来确定下一个可用值(但请注意,这很容易出现竞争)。

在任何一种情况下,都不用担心会留下空白。在大多数应用程序中,它不是问题。如果您的应用程序中存在域名要求,这会给您留下有限数量的ID(为什么?),那么当您分配所有ID时,您可能会遇到最终问题,因此您需要为此做好计划。

如果您处于一些非常不寻常的情况,即您需要有效分配少量可用值,那么您应该明确地跟踪这些值。为每个可用值创建一个表,并指定一个表示分配内容的字段,并使用SELECT id FROM id_table WHERE inuse = 0 LIMIT 1之类的内容搜索该表。

答案 1 :(得分:0)

如果数据库表中有 N 行,那么0和 N 之间的值中至少有一个必须是未使用的,因此您只需要循环< em> N +1次。

在Perl中执行此操作的有效方法是将使用的值存储为散列键,并且只是在循环中递增变量,直到它不再匹配散列中的任何键:

my @values = (5,6,7,8,45,91,92,93,94);

my %hash;
undef @hash{@values};

my $x = 0;
$x++ while exists $hash{$x};

# now $x is the lowest unused value

答案 2 :(得分:0)

无需遍历特定范围内的所有值。只需查看您的值,然后分别查找连续值(例如,当前值大于前一个值)或间隙。这会快得多。

打印使用的范围

my @values = (5, 6, 7, 8, 45, 91, 92, 93, 94);
my $start = shift @values;
my $i = $start;
for my $v (@values) {
    if ($v > $i + 1) {
        if ($i == $start) {
            print "$start\n";
        } else {
            print "$start to $i\n";
        }

        $start = $v;
    }

    $i = $v;
}

if ($i == $start) {
    print "$start\n";
} else {
    print "$start to $i\n";
}

并找到自由值的范围

my @values = (5, 6, 7, 8, 45, 91, 92, 93, 94);
my $i = 0;
my $max = 600000;
for my $v (@values) {
    if ($v > $i + 1) {
        print "$i to ", $v - 1, "\n";
    } elsif ($v == $i + 1) {
        print "$i\n";
    }

    $i = $v + 1;
}

if ($i < $max) {
    print "$i to $max\n";
}