求助二维数组插入的方法

你知我劲 2020-10-23 07:57:37
货架例子:
Array
(
[0] => 10110011
[1] => 11110111
[2] => 00000111
[3] => 11111111
[4] => 11101100
[5] => 01100000
[6] => 00000000
[7] => 00000000
[8] => 00000000
[9] => 00000000
)
假设这是一个10层,每层有8个位置的货架,0的代表空位置。1代表已经放了货物。
货物有大有小,例如Array[0]第一个位置1与Array[1]第一个位置1是一,代表放入了一个高2格,宽1格的货物。

求解:例如我想放入一个高2格宽2格的货物,需要找到依次找到一个空位放进去。。肉眼可见,Array[4]第6个位置可以放,求大佬放出算法公式。。。
新手写代码,或者说有更好的表达货架的方式请指教。。
...全文
316 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
你知我劲 2020-10-24
  • 打赏
  • 举报
回复
引用 7 楼 渡目成书 的回复:
这是一个二维数组,数组角标从0开始[1,1]是长宽的坐标点,2x2的块放到二维数组左上角那么长宽坐标就为[1,1],思路就是遍历二维数组每一个点,把每一个点当成2X2块的坐上点,算出2X2覆盖的所有坐标,只要所有坐标都是0那么就可以放2X2的块。H用于跳过货架层数的条件,2x2的块不可能放到$arrs[9]即第10层最多放到9层,同理W也只能从每一行的第7个位置开始放。遍历每个点,只要这个点是空的计算,就从这个点开始计算所有的点是不是空,是空的就能放,结束遍历,打印这个点坐标
那如果是1x1的物品该怎么表示呢? $a = [0,0] ?
你知我劲 2020-10-24
  • 打赏
  • 举报
回复
引用 8 楼 下雨的声音丶 的回复:

class Warehouse
{
    /**
     * @var array
     */
    private $warehouse;

    /**
     * @var int
     */
    private $width;

    /**
     * @var int
     */
    private $height;

    /**
     * Warehouse constructor.
     * @param int $width
     * @param int $height
     */
    public function __construct($width = 8, $height = 8)
    {
        $this->width = $width;
        $this->height = $height;
        $this->warehouse = array_fill(0, $this->height, 0);
    }

    /**
     * 打印当前仓库存储状态
     */
    public function dumpWarehouse()
    {
        $linMax = strlen($this->height);
        echo str_pad(' ', $linMax + 1, ' ') . implode(' ', range(1, $this->width)) . PHP_EOL;
        foreach ($this->warehouse as $key=>$item) {
            echo str_pad($key + 1, $linMax, ' ') . ':' . implode(',', str_split( substr(strrev(decbin($item + pow(2, $this->width))), 0 , -1))) . PHP_EOL;
        }
    }

    /**
     * 写入仓库
     * @param $width
     * @param $height
     * @return array|bool
     */
    public function put($width, $height)
    {
        $bit_sum = [];
        for ($i = 0; $i <= $this->width - $width; $i++) {
            $w = pow(2, $i);
            for ($k = 1; $k < $width; $k++) {
                $w += pow(2, $i + $k);
            }
            $bit_sum[$i] = $w;
        }
        for ($i = 0; $i <= $this->height - $height; $i++) {
            $yu = 0;
            for ($j = 0; $j < $height; $j++) {
                $yu = $this->warehouse[$i + $j] | $yu;
            }
            foreach ($bit_sum as $key=>$value) {
                if (($yu & $value) == 0) {
                    for ($j = 0; $j < $height; $j++) {
                        $this->warehouse[$i + $j] += $value;
                    }
                    return [$key + 1, $i + 1];
                }
            }
        }
        return false;
    }
}
$warehouse = new Warehouse();
var_dump($warehouse->put(1, 2));
$warehouse->dumpWarehouse();
var_dump($warehouse->put(7, 2));
var_dump($warehouse->put(1, 5));
var_dump($warehouse->put(2, 1));
var_dump($warehouse->put(7, 5));
var_dump($warehouse->put(5, 1));
$warehouse->dumpWarehouse();
通过位运算实现的,但是宽度有限制,你也可以试一试
感谢大佬帮忙。 $this->warehouse = array_fill(0, $this->height, 0); 初始化仓库有点没太看懂,数据格式该是怎么样的?
你知我劲 2020-10-24
  • 打赏
  • 举报
回复
感谢大佬帮忙。         $this->warehouse = array_fill(0, $this->height, 0); 初始化仓库有点没太看懂,数据格式该是怎么样的?
你知我劲 2020-10-24
  • 打赏
  • 举报
回复
引用 12 楼 下雨的声音丶 的回复:
比如有8列那么0就可以表示 00000000
引用 6 楼 下雨的声音丶 的回复:

class Warehouse
{
    /**
     * @var array
     */
    private $warehouse;

    /**
     * @var int
     */
    private $width;

    /**
     * @var int
     */
    private $height;

    /**
     * Warehouse constructor.
     * @param int $width
     * @param int $height
     */
    public function __construct($width = 8, $height = 8)
    {
        $this->width = $width;
        $this->height = $height;
        $this->warehouse = array_fill(0, $this->height, array_fill(0, $this->width, 0));
    }

    /**
     * 打印当前仓库存储状态
     */
    public function dumpWarehouse()
    {
        $linMax = strlen($this->height);
        echo str_pad(' ', $linMax + 1, ' ') . implode(' ', range(1, $this->width)) . PHP_EOL;
        foreach ($this->warehouse as $key=>$item) {
            echo str_pad($key + 1, $linMax, ' ') . ':' . implode(',', $item) . PHP_EOL;
        }
    }

    /**
     * 写入仓库
     * @param $width
     * @param $height
     * @return array|bool
     */
    public function put($width, $height)
    {
        for ($i = 0; $i <= $this->height - $height; $i++) {
            for ($j = 0; $j <= $this->width - $width; $j++) {
                $w = false;
                if (!$this->warehouse[$i][$j]) {
                    //判断是否满足条件
                    $w = true;
                    for ($m = 0; $m < $height; $m++) {
                        for ($n = 0; $n < $width; $n++) {
                            if ($this->warehouse[$i + $m][$j + $n]) {
                                continue 2;
                            }
                        }
                    }
                }
                if ($w == true) {
                    $this->edit([$i, $j], $width, $height);
                    return [$i + 1, $j + 1];
                }
            }
        }
        return false;
    }

    /**
     * 将满足条件的置为1
     * @param array $start
     * @param $width
     * @param $height
     */
    private function edit(array $start, $width, $height)
    {
        for ($i = 0; $i < $width; $i++) {
            for ($j = 0; $j < $height; $j++) {
                $this->warehouse[$start[0] + $j][$start[1] + $i] = 1;
            }
        }
    }
}
$warehouse = new Warehouse();
var_dump($warehouse->put(1, 2));
$warehouse->dumpWarehouse();
var_dump($warehouse->put(8, 5));
$warehouse->dumpWarehouse();
var_dump($warehouse->put(7, 2));
$warehouse->dumpWarehouse();
试一试
此代码经过测试智能识别第一行有足够位置,没有识别到第二行。 测试代码:
   public function test($width = 8, $height = 15)
    {
        $this->width = $width;
        $this->height = $height;
//        $this->warehouse = array_fill(0, $this->height, array_fill(0, $this->width, 0));
        $this->warehouse = [
                            0 => [1,0,1,1,0,0,1,1],
                            1 => [1,1,1,1,0,1,1,1],
                            2 => [0,0,0,0,0,1,1,1],
                            3 => [1,1,1,1,1,1,1,1],
                            4 => [1,1,1,0,1,1,0,0],
                            5 => [0,1,1,0,0,0,0,0],
                            6 => [0,0,0,0,0,0,0,0],
                            7 => [0,0,0,0,0,0,0,0],
                            8 => [0,0,0,0,0,0,0,0],
                            9 => [0,0,0,0,0,0,0,0],
                            10 => [0,0,0,0,0,0,0,0],
                            11 => [0,0,0,0,0,0,0,0],
                            12 => [0,0,0,0,0,0,0,0],
                            13 => [0,0,0,0,0,0,0,0],
                            14 => [0,0,0,0,0,0,0,0],
                        ];
        debug($this->warehouse);
    }
    /**
     * 打印当前仓库存储状态
     */
    public function dumpWarehouse()
    {
        $linMax = strlen($this->height);
        echo str_pad(' ', $linMax + 1, ' ') . implode(' ', range(1, $this->width)) . '<br>';
        foreach ($this->warehouse as $key=>$item) {
            echo str_pad($key + 1, $linMax, ' ') . ':' . implode(',', $item) . '<br>';
        }
    }

    /**
     * 写入仓库
     * @param $width
     * @param $height
     * @return array|bool
     */
    public function put($width, $height)
    {
        for ($i = 0; $i <= $this->height - $height; $i++) {
            for ($j = 0; $j <= $this->width - $width; $j++) {
                $w = false;
                if (!$this->warehouse[$i][$j]) {
                    //判断是否满足条件
                    $w = true;
                    for ($m = 0; $m < $height; $m++) {
                        for ($n = 0; $n < $width; $n++) {
                            if ($this->warehouse[$i + $m][$j + $n]) {
                                continue 2;
                            }
                        }
                    }
                }
                if ($w == true) {
                    $this->edit([$i, $j], $width, $height);
                    return [$i + 1, $j + 1];
                }
            }
        }
        return false;
    }
下雨的声音丶 2020-10-24
  • 打赏
  • 举报
回复
比如有8列那么0就可以表示 00000000
下雨的声音丶 2020-10-23
  • 打赏
  • 举报
回复
[3] => 11111111 [4] => 11101100 [5] => 01100000 如你所说 那第4-5行是放入了 高2宽1还是2还是3? 还是放入了高3宽1?2?,你这个好像不能明确表示吧?
下雨的声音丶 2020-10-23
  • 打赏
  • 举报
回复

class Warehouse
{
    /**
     * @var array
     */
    private $warehouse;

    /**
     * @var int
     */
    private $width;

    /**
     * @var int
     */
    private $height;

    /**
     * Warehouse constructor.
     * @param int $width
     * @param int $height
     */
    public function __construct($width = 8, $height = 8)
    {
        $this->width = $width;
        $this->height = $height;
        $this->warehouse = array_fill(0, $this->height, 0);
    }

    /**
     * 打印当前仓库存储状态
     */
    public function dumpWarehouse()
    {
        $linMax = strlen($this->height);
        echo str_pad(' ', $linMax + 1, ' ') . implode(' ', range(1, $this->width)) . PHP_EOL;
        foreach ($this->warehouse as $key=>$item) {
            echo str_pad($key + 1, $linMax, ' ') . ':' . implode(',', str_split( substr(strrev(decbin($item + pow(2, $this->width))), 0 , -1))) . PHP_EOL;
        }
    }

    /**
     * 写入仓库
     * @param $width
     * @param $height
     * @return array|bool
     */
    public function put($width, $height)
    {
        $bit_sum = [];
        for ($i = 0; $i <= $this->width - $width; $i++) {
            $w = pow(2, $i);
            for ($k = 1; $k < $width; $k++) {
                $w += pow(2, $i + $k);
            }
            $bit_sum[$i] = $w;
        }
        for ($i = 0; $i <= $this->height - $height; $i++) {
            $yu = 0;
            for ($j = 0; $j < $height; $j++) {
                $yu = $this->warehouse[$i + $j] | $yu;
            }
            foreach ($bit_sum as $key=>$value) {
                if (($yu & $value) == 0) {
                    for ($j = 0; $j < $height; $j++) {
                        $this->warehouse[$i + $j] += $value;
                    }
                    return [$key + 1, $i + 1];
                }
            }
        }
        return false;
    }
}
$warehouse = new Warehouse();
var_dump($warehouse->put(1, 2));
$warehouse->dumpWarehouse();
var_dump($warehouse->put(7, 2));
var_dump($warehouse->put(1, 5));
var_dump($warehouse->put(2, 1));
var_dump($warehouse->put(7, 5));
var_dump($warehouse->put(5, 1));
$warehouse->dumpWarehouse();
通过位运算实现的,但是宽度有限制,你也可以试一试
渡目成书 2020-10-23
  • 打赏
  • 举报
回复
这是一个二维数组,数组角标从0开始[1,1]是长宽的坐标点,2x2的块放到二维数组左上角那么长宽坐标就为[1,1],思路就是遍历二维数组每一个点,把每一个点当成2X2块的坐上点,算出2X2覆盖的所有坐标,只要所有坐标都是0那么就可以放2X2的块。H用于跳过货架层数的条件,2x2的块不可能放到$arrs[9]即第10层最多放到9层,同理W也只能从每一行的第7个位置开始放。遍历每个点,只要这个点是空的计算,就从这个点开始计算所有的点是不是空,是空的就能放,结束遍历,打印这个点坐标
下雨的声音丶 2020-10-23
  • 打赏
  • 举报
回复

class Warehouse
{
    /**
     * @var array
     */
    private $warehouse;

    /**
     * @var int
     */
    private $width;

    /**
     * @var int
     */
    private $height;

    /**
     * Warehouse constructor.
     * @param int $width
     * @param int $height
     */
    public function __construct($width = 8, $height = 8)
    {
        $this->width = $width;
        $this->height = $height;
        $this->warehouse = array_fill(0, $this->height, array_fill(0, $this->width, 0));
    }

    /**
     * 打印当前仓库存储状态
     */
    public function dumpWarehouse()
    {
        $linMax = strlen($this->height);
        echo str_pad(' ', $linMax + 1, ' ') . implode(' ', range(1, $this->width)) . PHP_EOL;
        foreach ($this->warehouse as $key=>$item) {
            echo str_pad($key + 1, $linMax, ' ') . ':' . implode(',', $item) . PHP_EOL;
        }
    }

    /**
     * 写入仓库
     * @param $width
     * @param $height
     * @return array|bool
     */
    public function put($width, $height)
    {
        for ($i = 0; $i <= $this->height - $height; $i++) {
            for ($j = 0; $j <= $this->width - $width; $j++) {
                $w = false;
                if (!$this->warehouse[$i][$j]) {
                    //判断是否满足条件
                    $w = true;
                    for ($m = 0; $m < $height; $m++) {
                        for ($n = 0; $n < $width; $n++) {
                            if ($this->warehouse[$i + $m][$j + $n]) {
                                continue 2;
                            }
                        }
                    }
                }
                if ($w == true) {
                    $this->edit([$i, $j], $width, $height);
                    return [$i + 1, $j + 1];
                }
            }
        }
        return false;
    }

    /**
     * 将满足条件的置为1
     * @param array $start
     * @param $width
     * @param $height
     */
    private function edit(array $start, $width, $height)
    {
        for ($i = 0; $i < $width; $i++) {
            for ($j = 0; $j < $height; $j++) {
                $this->warehouse[$start[0] + $j][$start[1] + $i] = 1;
            }
        }
    }
}
$warehouse = new Warehouse();
var_dump($warehouse->put(1, 2));
$warehouse->dumpWarehouse();
var_dump($warehouse->put(8, 5));
$warehouse->dumpWarehouse();
var_dump($warehouse->put(7, 2));
$warehouse->dumpWarehouse();
试一试
你知我劲 2020-10-23
  • 打赏
  • 举报
回复
求2×2不应该是[2,2]么
你知我劲 2020-10-23
  • 打赏
  • 举报
回复
感谢解答,没大看懂,请问这a=[1,1]怎么解?$w为什么是arrs[0]-a[0] ,解成明文也就是w=8-1 h=10-1 没太能理解这里的声明。。
渡目成书 2020-10-23
  • 打赏
  • 举报
回复
这样应该可以找出来
<?php


$arrs =
    [
        0 => [1, 0, 1, 1, 0, 0, 1, 1],
        1 => [1, 1, 1, 1, 0, 1, 1, 1],
        2 => [0, 0, 0, 0, 0, 1, 1, 1],
        3 => [1, 1, 1, 1, 1, 1, 1, 1],
        4 => [1, 1, 1, 0, 1, 1, 0, 0],
        5 => [0, 1, 1, 0, 0, 0, 0, 0],
        6 => [0, 0, 0, 0, 0, 0, 0, 0],
        7 => [0, 0, 0, 0, 0, 0, 0, 0],
        8 => [0, 0, 0, 0, 0, 0, 0, 0],
        9 => [0, 0, 0, 0, 0, 0, 0, 0]
    ];


//2X2 坐标
$a =[1,1];
$w = count($arrs[0]) - $a[0];
$h = count($arrs) - $a[1];

foreach ($arrs as $key => $arr) {
    if ($key >= $h) {
        break;
    }
    foreach ($arr as $k => $i) {
        if ($k >= $w) {
            break;
        }
        if ($i==1){
            continue;
        }
            $sum =[];
        for ($s=0;$s<=$a[1];$s++){
            for ($d=0;$d<=$a[0];$d++){
                $sum =array_merge($sum,[$arrs[$s+$key][$d+$k]]);
            }
        }
            $site=[];
        if (count($sum)>0){
            if (array_sum($sum)<1){
                $site=[$key,$k];
                break;
            }
        }

    }

    if (count($site)>0){
        var_dump($site);//坐标
        break;
    }
}

你知我劲 2020-10-23
  • 打赏
  • 举报
回复
假设性放入宽2高2物品到这个货架,那么放置物品后[4]就是11101111,[5]就是01100011,这是个比喻。我的意思是怎么计算出数组里面哪里有位置放置这个宽2高2的物品,并返回这个位置当然物品不一定是宽2高2的。只是需要一种计算方式知道哪个地方有位置放指定高度宽度的物品

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧