查找最近的点

查找一个点的最近点可以应用到很多的地方,下面是我写的一个实例,找到一个点的最近点。

package com.test;

import java.util.List;

/***********************************************
 ** 创建人: 黎荣恒 
 ** 日 期 : 2015-9-21 上午11:08:02
 ** 描述 : 点信息
 ** 
 ** 版 本 : 1.0 修改人: 日 期 : 修改记录:
 ************************************************/
public class Point
{
	private int id;
	private String name;
	private int hasLogo;//1:有logo   0:没有
	private String description;//商店描述
	private String phoneNumber;//电话号码
	private int type;
	private Coords coords;//商品位置信息
	private List<Coords> list;//商品边缘位置信息
	
	public int getId()
	{
		return id;
	}
	public void setId(int id)
	{
		this.id = id;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public int getHasLogo()
	{
		return hasLogo;
	}
	public void setHasLogo(int hasLogo)
	{
		this.hasLogo = hasLogo;
	}
	public String getDescription()
	{
		return description;
	}
	public void setDescription(String description)
	{
		this.description = description;
	}
	public String getPhoneNumber()
	{
		return phoneNumber;
	}
	public void setPhoneNumber(String phoneNumber)
	{
		this.phoneNumber = phoneNumber;
	}
	public int getType()
	{
		return type;
	}
	public void setType(int type)
	{
		this.type = type;
	}
	public Coords getCoords()
	{
		return coords;
	}
	public void setCoords(Coords coords)
	{
		this.coords = coords;
	}
	public List<Coords> getList()
	{
		return list;
	}
	public void setList(List<Coords> list)
	{
		this.list = list;
	}
}

package com.test;
/***********************************************
 ** 创建人: 黎荣恒 
 ** 日 期 : 2015-9-21 上午11:21:20
 ** 描述 : 位置坐标
 ** 
 ** 版 本 : 1.0 修改人: 日 期 : 修改记录:
 ************************************************/
public class Coords
{
	private int x;
	private int y;
	
	public int getX()
	{
		return x;
	}
	public void setX(int x)
	{
		this.x = x;
	}
	public int getY()
	{
		return y;
	}
	public void setY(int y)
	{
		this.y = y;
	}
	
}

这是匹配的核心代码:

package com.test;

import java.util.ArrayList;
import java.util.List;

/**
 * 匹配算法
 * @author 黎荣恒
 * 
 */
public class Match
{
	private int square = 2;
	private MatchInfo shopMatchInfo;

	public void setShopMatchInfo(MatchInfo shopMatchInfo)
	{
		this.shopMatchInfo = shopMatchInfo;
	}

	/**
	 * 匹配方法
	 * @param shopList 商铺信息队列
	 * @param coords 点击位置
	 */
	public void match(List<Point> shopList, Coords coords)
	{
		List<Double> list = calculate(shopList, coords);
		compare(list);
	}

	public List<Double> calculate(List<Point> shopList, Coords coords)
	{
		int coordsX = coords.getX();
		int coordsY = coords.getY();
		List<Double> list = new ArrayList<Double>();
		for (int i = 0; i < shopList.size(); i++)
		{
			int coordsX1 = shopList.get(i).getCoords().getX();
			int coordsY1 = shopList.get(i).getCoords().getY();
			double sum = Math.pow(Math.abs(coordsX - coordsX1), square)
					+ Math.pow(Math.abs(coordsY - coordsY1), square);
			double value = Math.sqrt(sum);
			list.add(value);
		}
		return list;
	}

	/**
	 * 比较方法
	 * @param list
	 */
	private void compare(List<Double> list)
	{
		Double temp = 0.0;
		for (int i = 0; i < list.size(); i++)
		{
			if (i == 0)
			{
				temp = list.get(i);
			} else
			{
				temp = temp < list.get(i) ? temp : list.get(i);
			}
		}
		for (int i = 0; i < list.size(); i++)
		{
			if (list.get(i) == temp)
			{
				shopMatchInfo.matchSuccess(i);
				break;
			}
		}
	}
}

匹配成功回调接口:

package com.test;
/***********************************************
 ** 创建人: 黎荣恒 
 ** 日 期 : 2015-9-21 下午3:55:43
 ** 描述 : 匹配接口
 ** 
 ** 版 本 : 1.0 修改人: 日 期 : 修改记录:
 ************************************************/
public interface MatchInfo
{
	public void matchSuccess(int index);
}

主方法:

package com.test;

import java.util.ArrayList;
import java.util.List;

/**
 * 测试类
 * @author 黎荣恒
 */
public class Main implements MatchInfo
{
	
	static List<Point> pointList;
	
	public static void main(String[] args)
	{
		new Main();
	}
	
	public Main(){
		Match match = new Match();
		pointList = new ArrayList<Point>();
		Point point = null;
		//生成20个点
		for (int i = 0; i < 20; i++)
		{
			point = new Point();
			point.setId(i);
			Coords coords = new Coords();
			coords.setX(i);
			coords.setY(i);
			point.setCoords(coords);
			pointList.add(point);
		}
		Coords coords = new Coords();
		coords.setX(5);
		coords.setY(3);
		match.setShopMatchInfo(Main.this);
		match.match(pointList, coords);
	}

	/**
	 * 查找成功回调
	 */
	@Override
	public void matchSuccess(int index)
	{
		System.out.println("最近点id为:"+pointList.get(index).getId());
	}
}

案例代码下载: http://download.csdn.net/detail/u013043346/9334005


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于kd-tree算法实现的C语言代码,实现查找最近: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #define MAXN 10005 typedef struct Point { double x, y; char c; } Point; typedef struct Node { Point p; struct Node *lc, *rc; } Node; int n, m; Point points[MAXN]; Node *root; int cmp(const void *a, const void *b) { Point *p1 = (Point *)a; Point *p2 = (Point *)b; if (p1->x != p2->x) return p1->x < p2->x ? -1 : 1; return p1->y < p2->y ? -1 : 1; } void build_kd_tree(Node **p, int l, int r, int depth) { if (l >= r) return; int mid = l + r >> 1; *p = (Node *)malloc(sizeof(Node)); (*p)->p = points[mid]; build_kd_tree(&(*p)->lc, l, mid, depth + 1); build_kd_tree(&(*p)->rc, mid + 1, r, depth + 1); if (depth & 1) qsort(&points[l], r - l, sizeof(Point), cmp); else qsort(&points[l], r - l, sizeof(Point), cmp); } double dist(Point *p1, Point *p2) { double dx = p1->x - p2->x, dy = p1->y - p2->y; return sqrt(dx * dx + dy * dy); } double query_kd_tree(Node *p, Point *q, double d, int depth) { if (!p) return d; double d1 = dist(&p->p, q); if (d1 < d) d = d1; double dl = query_kd_tree(p->lc, q, d, depth + 1); double dr = query_kd_tree(p->rc, q, d, depth + 1); if (depth & 1) { if (q->y - d < p->p.y) d = fmin(d, dl); if (q->y + d > p->p.y) d = fmin(d, dr); } else { if (q->x - d < p->p.x) d = fmin(d, dl); if (q->x + d > p->p.x) d = fmin(d, dr); } return d; } int main() { scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) scanf("%lf%lf%*c%c", &points[i].x, &points[i].y, &points[i].c); build_kd_tree(&root, 0, n, 0); for (int i = 0; i < m; ++i) { Point q; scanf("%lf%lf", &q.x, &q.y); printf("%.4f\n", query_kd_tree(root, &q, 1e10, 0)); } return 0; } ``` 该算法中,首先将二维平面上的按照x轴或y轴的大小排序,然后以中间为根节,递归构建kd-tree。在查询过程中,根据当前节所在深度的奇偶性,判断需要遍历左子树或右子树,并且在遍历过程中,通过比较当前节和查询之间的距离和当前最小距离,来决定是否需要更新最小距离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值