[英]Removing duplicates from collection of points, with mapping
我有一個點數組,我們稱之為rawPoints,其中包含重復項。 實際上,幾乎每個點都重復了2到6次。 在某處重復,而不是在連續的位置。 我想刪除重復項以獲得一個新的集合,我稱之為goodPoints。 另外, 我想知道從rawPoints到goodPoints的映射。 換句話說,對於rawPoints中的每個點P,我想知道(唯一)索引i,使得goodPoints [i] = P.
我在C#編碼,所以我想知道是否有任何.NET集合可以幫助解決這個問題。
我已經讀過使用HashSet是刪除重復項的好方法。 但這不會給我映射。
一種可能的解決方案是“AddorFind(P)”函數,我可以使用它將點P添加到goodPoints。 如果P還不是goodPoints的成員,那么AddorFind(P)將添加它。 如果P已經是goodPoints的成員,則AddorFind(P)將返回索引i,使得goodPoints [i] = P.
有類似的東西存在,還是有其他簡單而合理的快速解決方案?
雖然HashSet<Point>
無法幫助在goodPoints
找到唯一索引, goodPoints
Dictionary<Point,int>
會。
除了List<Point> goodPoints
,還要創建一個字典Dictionary<Point,int> mappings
,它將點Dictionary<Point,int> mappings
到goodPoints
列表中的索引。 當您瀏覽rawPoints
數組時,請遵循以下算法:
rawPoints[i]
是否在mappings
。 如果是,繼續下一點 goodPoints
添加到rawPoints[i]
mappings
中,然后將rawPoints[i]
添加到gooodPoints
列表中。 假設您的Point
表示具有良好的散列函數,並且它正確地覆蓋了Equals
,則此算法會生成goodPoints
列表和O(N)中的映射。
您將需要兩個輸出:
我認為這段代碼會生成以下兩件事:
using System;
using System.Collections.Generic;
using System.Drawing;
namespace Demo
{
class Program
{
static void Main()
{
var rawPoints = createRandomPoints(10000, 100, 100);
int[] goodPointMap = new int[rawPoints.Length];
var map = new Dictionary<Point, int>();
var goodPoints = new List<Point>();
for (int i = 0; i < rawPoints.Length; ++i)
{
Point p = rawPoints[i];
int index;
if (map.TryGetValue(p, out index))
{
goodPointMap[i] = index;
}
else
{
map[p] = goodPoints.Count;
goodPointMap[i] = goodPoints.Count;
goodPoints.Add(p);
}
}
// At this point we no longer need 'map', which is used only to generate 'goodPoints[]'
// and 'goodPointMap[]'.
Console.WriteLine("Number of good points = " + goodPoints.Count);
// Every point in rawPoints[] should have a point in goodPoints
// which you can reference via goodPointMap[].
// Let's verify that:
for (int i = 0; i < rawPoints.Length; ++i)
if (rawPoints[i] != goodPoints[goodPointMap[i]])
Console.WriteLine("Failed!");
}
static Point[] createRandomPoints(int n, int maxX, int maxY)
{
var rng = new Random();
var result = new Point[n];
for (int i = 0; i < n; ++i)
result[i] = new Point(rng.Next(maxX), rng.Next(maxY));
return result;
}
}
}
您可以使用Linq完成此任務:
List<Point> points = new List<Point>();
points.Add(new Point(1, 1));
points.Add(new Point(1, 1));
points.Add(new Point(1, 1));
points.Add(new Point(1, 2));
points.Add(new Point(1, 2));
points.Add(new Point(1, 2));
List<Point> goodPoints = new List<Point>();
foreach (Point p in points)
{
goodPoints.Add(p);
//goodPoints = goodPoints.Distinct().ToList();
//int idx = goodPoints.IndexOf(p);
int idx = (goodPoints = goodPoints.Distinct().ToList()).IndexOf(p);
Debug.WriteLine(string.Format("Index of Point({0}, {1}) = {2}", p.X, p.Y, idx));
}
您可以創建一個PointComparer類,並在Distinct方法中使用它。
public class PointComparer : IEqualityComparer<Point>
{
public bool Equals(Point p1, Point p2)
{
return p1.x==p2.x && p1.y == p2.y;
}
public int GetHashCode(Point p1)
{
return p1.x*p2.x;//bla bla
}
}
和
goodPoints = rawPoints.Distinct(new PointComparer()).ToList();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.