数组和循环管理

时间:2014-02-24 07:49:02

标签: php arrays loops foreach

这里我编写了简单的程序,但在管理方面我没有什么问题。

我有6分,每个点我想计算到其他点的距离。

DEmo - http://ideone.com/mYl30O

代码:

<?php
$a_points = array(
    array(0, -1),
    array(-2, 3),
    array(4, 0),
    array(3, 1),
    array(5, 2),
    array(0, 1),
);
$k = 0;
$a_sum_dists = array();
$sum = array();
foreach ($a_points as $i => $pt1) {
    list($x1, $y1) = $pt1;
    //$sum = 0;
    foreach ($a_points as $j => $pt2) {
        if ($j == $i) continue;
        list($x2, $y2) = $pt2;
        $sum[$k] = pow($x2- $x1, 2) + pow($y2- $y1, 2);
        $k++;
    }
    //$a_sum_dists[$i] = $sum;
}

?>

我想要的是什么:

  1. 对于每个点,与所有其他点保持距离。然后打印最小距离的点。如果超过一个这样的点,则打印所有

  2. 现在我们每个点都有最小距离点。因此,现在打印最常出现的最小距离点。如果超过一个这样的点,则打印所有

2 个答案:

答案 0 :(得分:3)

现在,当你详细指定算法时,我可以为它建议实现:

$a_all_ids = array_keys($a_points);
$a_neibor_ids = array();
foreach ($a_points as $i => $pt1) {
    list($x1, $y1) = $pt1;
    $a_dists = array();
    foreach ($a_points as $j => $pt2) {
        if ($j == $i) continue;
        list($x2, $y2) = $pt2;
        $a_dists[$j] = pow($x2- $x1, 2) + pow($y2- $y1, 2);
    }
    $min_dist = min($a_dists);
    $a_neibor_ids = array_merge(
        $a_neibor_ids,
        array_keys(array_filter($a_dists, function ($v) use ($min_dist) {
            return $v == $min_dist;
        }))
        );
}

$a_counts = array_count_values($a_neibor_ids);
$max_count = max($a_counts);

$a_result_points = array_intersect_key(
    $a_points, 
    array_filter($a_counts, function ($v) use ($max_count) {
        return $v == $max_count;
    })
);

符号:

  • $a_dists - 从当前点到其余点的距离。
  • $a_neibor_ids - 我们找到每个点的最近点。 $a_neibor_ids是所有这些点(包括重复点)的结合。
  • $a_counts - 来自$ a_neibor_ids的每个值的出现次数。

Demo

答案 1 :(得分:1)

直接实现您所描述的内容:

$points = [
    [0, -1],
    [-2, 3],
    [4, 0],
    [3, 1],
    [5, 2],
    [0, 1],
];

$max_closest = [];

foreach ($points as $i => list($ax, $ay)) {
        $min_dist = INF;
        $dists = [];

        foreach ($points as $j => list($bx, $by)) {
                if ($i == $j) {
                        continue;
                }
                $dists[$j] = $sq_dist = ($bx - $ax) * ($bx - $ax) + ($by - $ay) * ($by - $ay);

                if ($sq_dist < $min_dist) {
                        $min_dist = $sq_dist;
                }
        }

        // select closest points
        foreach (array_keys($dists, $min_dist, true) as $key) {
                print_r($points[$key]); // print point

                // keep track of points that were closest
                if (isset($max_closest[$key])) {
                        ++$max_closest[$key];
                } else {
                        $max_closest[$key] = 1;
                }
        }
}

rsort($max_closest);

foreach (array_keys($max_closest, $max_closest[0], true) as $key) {
        print_r($points[$key]); // print point
}