# 用PHP 如何高效生成不重复坐标点，比如在100*100 的矩阵随机生成200个坐标点

0

-2
```//点反对的人，把你们的代码留下，否则就别装逼！function()
{
var array = {0...9999};
var arrayMaxIndex = 9999;
var result;

for(int i = 0; i < 200; i++)
{
var index = rand(0, arrayMaxIndex);
var num = array[index];

var x = num / 100;
var y = num % 100;

array.RemoveAt(index);
arrayMaxIndex--;
}

return result;
}```

@北冥那条鱼: 谢谢，看来还得试试才知道，我没有试，惭愧

@北冥那条鱼: 你说的那种耗时0.01s的方法能不能贴出代码让我学习一下啊，谢谢

@北冥那条鱼: 我用c#写了2个方法。第一个方法差不多耗时300毫米，第二个方法更少一些，耗时200毫米。而且每个方法重复调用了50次：

```using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace Rand
{
struct Point
{
public int X { get; set; }

public int Y { get; set; }
}
class Program
{
static void Main(string[] args)
{
Stopwatch watch = new Stopwatch();

watch.Start();
for (int i = 0; i < 50; i++)
{
Point[] points = GetPoints(2000);
}
watch.Stop();
Console.WriteLine("GetPoints:" + watch.ElapsedMilliseconds);

watch.Reset();
watch.Start();
for (int i = 0; i < 50; i++)
{
Point[] pointsAgain = GetPoints2(2000);
}
watch.Stop();
Console.WriteLine("GetPoints2:" + watch.ElapsedMilliseconds);

Console.WriteLine("press any key to exit");
}

private static Point[] GetPoints(int count)
{
Point[] points = new Point[count];
List<Point> allPoints = new List<Point>();

for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
allPoints.Add(new Point { X = i, Y = j });
}
}

int totalPointsCount = 10000;

Random random = new Random();
for (int i = 0; i < count; i++)
{
int index = random.Next(totalPointsCount--);
points[i] = allPoints[index];
allPoints.RemoveAt(index);
}

return points;
}

private static Point[] GetPoints2(int count)
{
Point[] points = new Point[count];
List<int> allNumbers = new List<int>();

for (int i = 0; i < 10000; i++)
{
}

int totalPointsCount = 10000;
Random random = new Random();
for (int i = 0; i < count; i++)
{
int index = random.Next(totalPointsCount--);
int number = allNumbers[index];

int x = number / 100;
int y = number % 100;

allNumbers.RemoveAt(index);

points[i] = new Point { X = x, Y = y };
}

return points;
}
}
}```

@北冥那条鱼: 100的倍数求余等于0对的呀，表示纵坐标是0。100对应的坐标是(1,0)

@会长: 比如说100*100的矩阵，坐标（10，200）这个点，200%100的话就是（10，0），所以需要判断下如果是0的话yCoord就应该是纵坐标纬度

@会长: 没有没有，大家相互学习相互讨论

@会长: PHP代码\$lng 表示经度，\$lat 纬度，\$num 生成坐标数，一开始觉得这种方法要生成所有坐标，不是最好的，昨晚试了下，数量级越大好像耗时比其他越低，但这种方法肯定不是最好的方法

function uniqueCoord(\$lng,\$lat,\$num){
\$coord = array();
\$count = 0;

for(\$i = 1; \$i <= \$lng; \$i++){
for(\$j = 1;\$j <= \$lat;\$j++){
\$coord[]=array('coordX'=> \$i,'coordY'=> \$j);
}
}
\$randArr = array_rand(\$coord,\$num);
foreach(\$randArr as \$key => \$value){
\$arr[\$value+1] = \$coord[\$value];
}
return \$arr;
}

@北冥那条鱼: 我觉得我们好像说岔道了。我的意思是这样的：

@北冥那条鱼: 你这个是用了php内置函数array_rand。那可能比较高效了吧，毕竟是牛人写的函数。

1

0

@北冥那条鱼: 并不会..你弄一个hash.每一次获取随机数后就往hash表里插入.

@吴瑞祥: OK，我试试

0
```var _startTime = new Date().getTime();
/*
二分查找算法
*
* */
var rank = function(key,arr){
var o = 0;
var k = arr.length - 1;
while(o <= k){
var mid = Math.floor((o+k)/2);
if(key > arr[mid]){
o = mid + 1;
}
else if(key < arr[mid]){
k = mid - 1;
}else{
return mid;
}
}
return -1;
}

//最后结果
var result = [];
var j = { //矩阵范围
x:1000,
y:1000
}
var z = 20000; //生成点数

var rand = Math.random;
//已经存在的点
var d = {
x:[],
y:[]
};
for(var i=0;i<z;i++){
var _r = {
x:Math.ceil(rand()*(j.x/2)),
y:Math.ceil(rand()*(j.y/2))
}

if(rank(_r.x,d.x) == -1 || rank(_r.y,d.y) == -1){
d.x.push(_r.x);
d.y.push(_r.y);
result.push(_r);
}else{
i--;
}

}
console.log(result,new Date().getTime()-_startTime);```

您需要登录以后才能回答，未注册用户请先注册