【问题标题】:How to analysis the "neighborhood relationship" of an array with perl如何用perl分析数组的“邻里关系”
【发布时间】:2014-09-18 05:38:41
【问题描述】:

(一)。我有一个包含命令“矩形(x1,x2,y1,y2)”的软件,它可以在xy上生成一个左下角坐标(x1,y1)和右上角坐标(x2,y2)的矩形飞机

(二)。我想用这个软件在 x-y 平面上创建所有带有堆叠矩形的字母数字,基本上我想通过 perl 打印出这些命令

(三)。我的想法是通过用矩形填充此表来创建一个 5x7 表,然后将其放置到我想要的坐标如下:

#!/usr/bin/perl

use strict;
use warnings;
###=================================================================================###
###=================================================================================###
###========= This script will generate alphanumeric by filling polygon in =========###
###==================== the specific position of a 5 x 7 table =====================###
###================= following case represents the alphanumeric:"1"================###
###=================================================================================###
###===           ---------------------                                           ===###
###===           |   |   | O |   |   |  6                                        ===###
###===           ---------------------                                           ===###
###===           |   | O | O |   |   |  5                                        ===###
###===           ---------------------                                           ===###
###===           |   |   | O |   |   |  4                                        ===###
###===           ---------------------                                           ===###
###===           |   |   | O |   |   |  3  row number                            ===###
###===           ---------------------                                           ===###
###===           |   |   | O |   |   |  2                                        ===###
###===           ---------------------                                           ===###
###===           |   |   | O |   |   |  1                                        ===###
###===           ---------------------                                           ===###
###===           |   | O | O | O |   |  0                                        ===###
###===           ----------*----------    "*" stand for (coor_x, coor_y)         ===###
###===            -2  -1   0   1   2  --> column number                          ===###                                       

my grid_x = 1;   # the size of a grid along x-direction
my grid_y = 1;   # the size of a grid along y-direction

sub alphanum_1 {

my $coor_x = shift;              # the x coordinate that I wanna put this "polygon 1"
my $coor_y = shift;              # the y coordinate that I wanna put this "polygon 1"

my ($i,$j,$mkrstring);
my @col_neg2 = ("");            # the positions which needs to be filled in col -2
my @col_neg1 = (0,5);           # the positions which needs to be filled in col -1
my @col_zero = (0,1,2,3,4,5,6); # the positions which needs to be filled in col 0
my @col_pos1 = (0);             # the positions which needs to be filled in col +1
my @col_pos2 = ("");            # the positions which needs to be filled in col +2
my (@marker,@anchor);

for ($i=0; $i<=$#col_zero-1; $i++) {
$marker[$i] = ($col_zero[$i+1] - $col_zero[$i] == 1)? "m" : "0";
$mkrstring = $mkrstring.$marker[$i];
}
}

&alphanum_1;

问题来了,你可以看到列 0 需要被所有 7 行填充,如果我只想使用“矩形”命令一次而不是 7 次:

假设 coor_x=0, coor_y=0
方法一:

rectangle(-0.5,0.5,0,7)  

方法二:

rectangle(-0.5,0.5,0,1)
rectangle(-0.5,0.5,1,2)
rectangle(-0.5,0.5,2,3)
rectangle(-0.5,0.5,3,4)
rectangle(-0.5,0.5,4,5)
rectangle(-0.5,0.5,5,6)
rectangle(-0.5,0.5,6,7)  

方法1和2会达到同样的效果,但我更喜欢使用方法1,这意味着我需要检查同一列中的“邻里关系”,但我卡在这部分,基本上,我想坚持矩形,只要它们可以在同一列中粘在一起即可。

我是 perl 的新手,有什么提示吗?我需要你的帮助!

【问题讨论】:

  • 这看起来更像是一个算法问题,而不是一些 perl 技巧。在我看来,这就像一个 NP 完成任务,以最小化矩形函数的调用。几个问题:1)两个矩形可以重叠吗? (即您可以先调用rectangle(-0.5,0.5,0,7),然后再调用rectangle(-1.5,1.5,0,1)) 2)不多次调用矩形函数的原因到底是什么?您想将其称为 最少 次,还是对较小的减少量感到满意?
  • (1) 是的,所有矩形都可以重叠,只要能完成正确的形状即可
  • (2)。我需要使用“矩形”函数百万次,所以我想做一些减少,最小值很棒,但没有必要

标签: perl


【解决方案1】:

这是一种如何稍微减少矩形数量的方法(绝对不是减少到最小,但是它可以提供帮助):

首先,我会选择矩阵的另一种表示:

my @one = ([0,0,0,0,0,0,0],
           [1,0,0,0,0,1,0],
           [1,1,1,1,1,1,1],
           [1,0,0,0,0,0,0],
           [0,0,0,0,0,0,0]);

@one 变量是对表示列的数组的引用数组。然后, 我会创建一个必须绘制的矩形数组:

my @rectangles;

for my $columnRef (@one) {
    my @column = @$columnRef;
    my @colRects = ();

    my $inRectangle = 0;
    my $rectBegin = 0;

    for my $i (0 .. $#column) {
        my $pixel = $column[$i];

        # closing a rectangle
        if($inRectangle == 1 and $pixel == 0) {
            $inRectangle = 0;

            my $rectEnd = $i - 1;
            push @colRects, [$rectBegin, $rectEnd];
        }

        # opening a rectangle
        if ($inRectangle == 0 and $pixel == 1) {
            $inRectangle = 1;
            $rectBegin = $i;
        }
    }

    # don't forget to close a rectangle if opened
    if ($inRectangle == 1) {
        push @colRects, [$rectBegin, $#column];
    }

    push @rectangles, \@colRects;
}

此代码应使用每列的矩形开始和结束列表填充@rectangles 变量:

([], [[0,0],[5,5]], [[0,6]], [[0,0]], [])

您可以使用它产生所需的输出

my $x = -2;
for my $col_rectangles (@rectangles) {
    for my $col_rectangle (@$col_rectangles) {
        printf("rectangle(%d,%d,%d,%d)",
           $x - 0.5,
           $x + 0.5,
           @$col_rectangle,
        );
    }
}

现在,您已将每列中rectangle 函数的调用次数降至最低。但是,此解决方案在更多水平方向的字母上表现不佳。

您当然可以转置它并对行而不是列执行优化,但不知何故我认为这不会更好。

【讨论】:

  • 感谢您的帮助!你介意解释一下$inRectangle在这里扮演的角色吗?
  • 您浏览一列中的像素。每次您看到“开启”的像素时,您都在输入一个矩形。当您在一个矩形中并看到一个“关闭”的像素时,您刚刚离开了该矩形。当你离开一个矩形并且你记得你在哪里输入它时,你可以从头开始绘制它到你离开它的地方。 $inRectangle 只是一个变量,告诉你是否在这样的矩形中。
  • 谢谢,我知道算法了,现在我需要弄清楚数组和列表之间的关系,还有很多工作要做......
  • 哦,我明白了。如果可以的话,我会否决我之前的评论.. :)
猜你喜欢
  • 1970-01-01
  • 2011-03-05
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 2020-12-31
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
相关资源
最近更新 更多