【问题标题】:Perl deleting array elements after a few iterations of code, with a call to a sub functionPerl 在几次代码迭代后删除数组元素,并调用子函数
【发布时间】:2016-12-13 00:56:25
【问题描述】:

我的代码在前几次迭代中有效,但经过几次 while 循环后,我的数组元素似乎被删除了。

我从输入参数构造的数组中取出数字,我只能说,当我得到一个传入两次的数字时,我得到一个错误。

我这样调用我的脚本

./branchandboundNoComments.pl 1 2 3 4 5 5 7 7 9 9 10 10 12 14 19

我应该把它作为输出

0, 7, 9, 10, 14, 19

这是我的脚本

#!/usr/bin/perl -w 

use strict;

my @input  = @ARGV;
my $maxAll = $input[-1];
$#input = $#input - 1;
my @multiset = ( 0, $maxAll );
my @stack;

my $rotation = 0;    # this is 0,1, or 2.

while ( @input != 0 ) {

    my $max = $input[-1];

    my @deltamultiset;
    for ( my $i = 1; $i <= $#multiset; $i++ ) {
        push @deltamultiset, $multiset[$i] - $max;
    }
    push @deltamultiset, $max;

    my @deltamultiset2;
    for ( my $i = 1; $i <= $#multiset; $i++ ) {
        push @deltamultiset2, $multiset[$i] - ( $maxAll - $max );
    }
    push @deltamultiset2, $max;

    if ( subset( \@deltamultiset, \@input ) and $rotation == 0 ) {

        for ( my $i = 0; $i < $#deltamultiset; $i++ ) {
            pop @input;
        }

        push @multiset, $max;
        push @stack,    $max;
        push @stack,    0;
    }
    elsif ( subset( \@deltamultiset2, \@input ) and $rotation <= 1 ) {

        for ( my $j = 0; $j < $#deltamultiset; $j++ ) {
            pop @input;
        }

        push @multiset, ( $maxAll - $max );
        push @stack,    ( $maxAll - $max );
        push @stack, 1;
        $rotation = 0;
    }
    elsif ( @stack != 0 ) {

        $rotation = $stack[-1];
        $#stack--;
        $max = $stack[-1];
        $#stack--;
        $rotation++;

        for ( my $i = 0; $i < $#multiset; $i++ ) {
            if ( $multiset[$i] == $max ) {
                delete $multiset[$i];
                last;
            }
        }

        for ( my $i = 0; $i < $#deltamultiset; $i++ ) {
            push @input, $deltamultiset[$i];
        }
    }
    else {
        print "no solutions \n";
        exit;
    }
}

print "@multiset is a solution \n";

sub subset {
    my ( $deltamultisetSubref, $multisetSubref ) = @_;
    my @deltamultisetSub = @{$deltamultisetSubref};
    my @multisetSub      = @{$multisetSubref};

    while ( @deltamultisetSub != 0 ) {

        for ( my $i = $#multisetSub; $i >= -1; $i-- ) {

            if ( $multisetSub[$i] == $deltamultisetSub[-1] ) {
                pop @deltamultisetSub;
                $#multisetSub--;
                last;
            }

            if ( $i == -1 ) {
                return 0;
            }
        }
    }

    return 1;
}

这就是输出

Use of uninitialized value in subtraction (-) at ./branchandboundNoComments.pl line 20.
Use of uninitialized value in subtraction (-) at ./branchandboundNoComments.pl line 26.
no solutions 

【问题讨论】:

  • 你可以使用-1来索引最后一个数组元素,不需要$#。我不确定您是否意识到分配给$# 会修改数组。您的循环似乎有时会跳过第一个元素,有时会跳过最后一个元素。您不必要地复制数组引用来检查它们的内容。无论如何,我现在太困惑了,无法弄清楚你真正想要实现的目标。我很确定问题在于分配而不是比较的 if 语句,以及数组上的后续 delete(我认为您打算使用 splice)。
  • Re "我很确定问题是分配而不是比较的 if 语句",这意味着 if ($multiset[$i] = $max) 应该是 if ($multiset[$i] == $max)
  • 请!始终使用use strict; use warnings qw( all );! (我看到您使用了-w,这是后者的可接受替代品。)
  • @ikegami 哦,对,抱歉,我修复了一些问题并更新了我的代码,我进行了一些打印测试,因为我认为它更清晰
  • 这个算法有没有在线描述?我想了解您的代码的用途,因为无法区分正确与错误。

标签: arrays perl branch-and-bound


【解决方案1】:

我无法理解您尝试实现的算法,因此可能存在更多错误,但最直接的问题是该语句

delete $multiset[$i]

除非它是最后一个元素,否则不会从数组中删除该元素;否则数组保持相同的长度,该元素上的exists 将返回 false,并将评估为 undef

如果你想移除这个看起来最有可能的元素,那么你想要

splice @multiset, $i, 1;

但是我已经使用该修复程序测试了您的代码,虽然它不再产生 Use of uninitialized value in subtraction 错误,但结果仍然是 没有解决办法

很遗憾,我无法理解您要实现什么,也无法对可能出现的问题做出任何有用的猜测,除非您可以向我提供底层算法的描述

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-27
    • 2016-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    相关资源
    最近更新 更多