对非描述性问题表示歉意;如果你能想到一个更好的人,我会全力以赴。
我正在编写一些Perl来实现一个算法,而我的代码却有些腥味。由于我没有CS背景,所以我的后袋里没有很多关于标准算法的知识,但这看起来可能就像它一样。
让我用隐喻来描述我正在做的事情:
因此,我们有一个处理列表中项目的算法,如果它们符合某些标准,它们应该被添加到一个结构中,当它满足其他一些标准时,应该“关闭”。此外,一旦处理完列表,如果存在“开放”结构,它也应该“关闭”。
天真地,我假设算法包含一个循环遍历列表的循环,带有条件以查看列表元素是否属于结构,还有条件查看结构是否需要“关闭”。 在循环之外,还有一个条件可以关闭任何未完成的结构。
所以,这是我的问题:
我将此标记为“Perl”,因为Perlish方法很有意思,但我很想知道其他任何语言都有这方面的解决方案。
答案 0 :(得分:9)
它非常适合功能性方法 - 您可以迭代Orange流,对其进行测试,分组和操作。在Scala中,它将类似于:
val oranges:Stream[Oranges] = ... // generate a stream of Oranges
oranges.filter(_.isNotRotten).grouped(10).foreach{ o => {(new Box).fillBox(o)}}
(grouped
在末尾的部分框中做正确的事情)
可能有Perl等价物。
答案 1 :(得分:5)
是否有一种有效的方法可以将“关闭盒子”活动合并到一个地方, 而不是一次进入循环并且一次进入循环之外?
是。只需在“结构需要关闭”功能中添加“......或没有更多的橙子”。最简单的方法是使用do / while构造(从技术上讲,它不是Perl中的循环,虽然它看起来像一个):
my $current_container;
my $more_objects;
do {
my $object = get_next_object(); # Easiest implementation returns undef if no more
$more_objects = more_objects($object) # Easiest to implement as "defined $object"
if (!$more_objects || can_not_pack_more($current_container) {
close_container($current_container);
$current_container = open_container() if $more_objects;
}
pack($object, $current_container) if $more_objects;
} while ($more_objects);
恕我直言,如果close_container()
被封装到一个方法中,这并没有真正赢得任何东西 - 在循环内外调用它没有重大的技术或代码质量成本。实际上,我强烈认为上面提到的一个复杂的解决方法是WORSE代码质量明智而不是直截了当:
my $current_container;
while (my $more_objects = more_objects(my $object = get_next_object())) {
if (can_not_pack_more($current_container)) { # false on undef
close_container($current_container);
}
$current_container = open_container_if_closed($current_container); # if defined
pack($object, $current_container);
}
close_container($current_container);
答案 2 :(得分:3)
对于你所描述的问题,似乎有点过于复杂,但听起来理论上接近Petri网。检查Petri Nets on wikipedia
可以找到perl实现here
我希望这会对你有所帮助,
Jerome Wagner
答案 3 :(得分:1)
我认为此算法没有名称。对于直接实现,您需要进行两项测试:一种是在处理循环中检测完整的盒子,另一种是在循环后检测部分满的盒子。可以将“关闭框”逻辑设置为子例程以避免重复它。功能性方法可以提供一种解决方法:
use List::MoreUtils qw(part natatime);
my ($good, $bad) = part { $_->is_rotten() } @oranges;
$_->dispose() foreach @$bad;
my $it = natatime 10, @$good;
while (my @batch = $it->()) {
my $box = Box->new();
$box->add(@batch);
$box->close();
$box->stack();
}
答案 4 :(得分:0)
在查看算法时,主流的CS倾向于处理非常复杂情况,或采用非常复杂方法(例如查找NP-Complete)。此外,算法倾向于关注优化。这个系统如何更有效率?如何在此生产计划中使用更少的步骤?我可以在酒吧里容纳最多的foos?等
在我看来,复杂方法的一个例子是快速排序,因为递归非常天才。我知道这是标准的,但我真的很喜欢它。如果您喜欢算法,那么请查看Simplex Algorithm - 它非常有影响力。
复杂情况的一个例子是,如果你有橙子进入,分成5个橙色的堆,然后去5个不同的地方去皮,然后所有回来的另一条橙色路径到10个橙色桩,然后将每个橙子单独切片,并装入完全 2磅的组。
回到你的例子。您的示例是flow network的简化版本。没有那么多的侧面路径和选项,只有一条路径,一次只能容纳一个橙色。在流网络算法中,Ford-Fulkerson algorithm可能是最有影响力的。
因此,您可以将这些算法中的一种放入所提出的示例中,但这将通过简化过程实现。基本上没有足够的复杂性需要任何优化。并且不存在以低效时间复杂度运行的风险,因此不需要运行“完美方法”。
您详细说明的方法在这里会很好,上面接受的答案可以很好地为定义的问题提供实际的功能解决方案。我只想在算法方面增加2美分。