我有一个看起来像这样的表:
<22 23-27
8-10 1.3 1.8
11-13 2.2 2.8
14-16 3.2 3.8
然后继续。所以我想查找这样的值:
lookup(11,25)
并获得响应,在本例中为2.8。用于此目的的最佳数据结构是什么?我有CSV格式的数据。
我希望用PHP编程。
谢谢。
答案 0 :(得分:2)
我当然没有声称这是最好或最有效的数据结构,但这就是我将数据映射到一个非常类似于原始数据的二维PHP数组的方式:
$fp = fopen('data.csv', 'r');
$cols = fgetcsv($fp);
array_shift($cols); // remove empty first item
$data = array();
while ($row = fgetcsv($fp)) {
list($min, $max) = explode('-', $row[0]);
// TODO: Handle non-range values here (e.g. column header "<22")
$data["$min-$max"] = array();
for ($x = 0; $x < count($cols); $x++) {
$data["$min-$max"][$cols[$x]] = $row[$x + 1];
}
}
然后,您需要在lookup
函数中添加一些解析逻辑:
function lookup($row, $col) {
$return = null;
// Loop through all rows
foreach ($data as $row_name => $cols) {
list($min, $max) = explode('-', $row_name);
if ($min <= $row && $max >= $row) {
// If row matches, loop through columns
foreach ($cols as $col_name => $value) {
// TODO: Add support for "<22"
list($min, $max) = explode('-', $col_name);
if ($min <= $col && $max >= $col) {
$return = $value;
break;
}
}
break;
}
}
return $return;
}
答案 1 :(得分:1)
某种二维数据结构怎么样?
X "coordinates" being <22, 23-27
Y "coordinates" being ...
二维数组可能会用于此目的。
然后你需要一些函数来将特定的X和Y值映射到范围,但这不应该太难。
答案 2 :(得分:1)
数据库结构:
values
------
value
x_range_start
x_range_end
y_range_start
y_range_end
代码:
function lookup(x, y) {
sql = "
SELECT * FROM values
WHERE
x >= x_range_start
AND
x <= x_range_end
AND
y >= y_range_start
AND
y <= y_range_end
"
/---/
}
您的数据将映射到数据库,如下所示:
<22 23-27
8-10 1.3 1.8
11-13 2.2 2.8
14-16 3.2 3.8
(value, x start, x end, y start, y end)
1.3, 0, 22, 8, 10
1.8, 23, 27, 8, 10
2.2, 0, 22, 11, 13
...
基本上存储表中每个值的x和y轴开始和结束编号。
答案 3 :(得分:0)
最简单的选项:创建数组数组,其中每个数组由5个元素组成:minX,maxX,minY,maxY,value,在你的情况下它将是
$data = array(
array(8, 10, 0, 22, 1.3),
array(8, 10, 23, 27, 1.8),
array(11, 13, 0, 22, 2.2), etc
写一个遍历每个元素的循环并比较min&amp;参数的最大值:
function find($x, $y) {
foreach($data as $e) {
if($x <= $e[0] && $x >= $e[1] && $y <= $e[2] && $y >= $e[3])
return $e[4];
}
使用小数据集,这将正常工作,如果您的数据集更大,您应该考虑使用数据库。
答案 4 :(得分:0)
我偏向于具有“哈希”功能的2维数组,该功能将范围映射到表格中的特定地址。
因此,您的基础数据结构将是一个二维数组:
0 1
0 1.3 1.8
1 2.2 2.8
2 3.2 3.8
然后你会写两个函数:
int xhash(int);
int yhash(int);
将原始参数转换为索引并将其转换为数组。所以xhash执行转换:
8-10 0
11-13 1
14-16 2
最后,您的查找操作变为。
function lookup($x, $y)
{
$xIndex = xhash($x);
$yIndex = yhash($y);
// Handle invalid indices!
return $data[$xIndex][$yIndex];
}
答案 5 :(得分:0)
嗯,其他答案都使用2D数组,这意味着使用2D循环来检索它。其中,如果你的范围是年龄范围或类似的东西,可能是有限的(只有这么多的年龄范围!),而不是一个问题(几百次迭代是什么?)。如果您的范围预计会扩展到庞大的数字,那么哈希地图上的游戏可能是您最好的选择。因此,您创建一个散列函数,将任何数字转换为相关范围,然后直接查找,而不是循环。它将是O(1)访问而不是O(n ^ 2)。
所以你的哈希函数可以是:function hash(n){if(n&lt; 22)return 1; if(n <25)返回2;返回-1;然后你可以用这些哈希值(1,2等)来指定你的范围,然后再去$ data [hash(11)] [hash(25)]