我有一个SortedList,其中包含元素的长数据类型元素 可能会重复(也有一些重复的记录)。
例如: ValueCov = {1,2,2,2,5,5,5,5,6,6,7,7,7,.......... }
我必须搜索一个值" x"每次在此列表中都有选项 二进制搜索(x)在C#中和值#34; x"是不是在那里 ValueCov列表,我需要找到下一个更接近的值的索引。 (最小 从价值差异" x" )。
我在这里遇到的问题是,如果我搜索,可以使用重复元素 对于值x = 3,这应该从valueCov返回value = 2&#39的索引( 指数= 1)。但是第二次搜索值= 3时,这不应该 返回先前返回的索引,因为我正在修复它 其他一些工作的位置。所以当我搜索时我需要索引为= 2 第二次。
请为此搜索提供解决方案,同时在列表中提供重复项。
for (int i = 0; i < valueWat.Count; i++)
{
var x=valueWat[i];
int index = valueCov.BinarySearch(x);
//Console.Write(index + ",");
if (index >= 0)
{
//Console.Write(sortedCov[index].Key + ",");
Console.WriteLine("addr of w/m" + sortedWat[i].Key);
//adding addr of w/m and coveraddr
blockedWaterCoverMap.Add(sortedCov[index].Key, sortedWat[i].Key);
//valueCov.Remove(x);
//valueCov[index] = 10000000000;
valueCov[index] = -100000000;
// valueWat[i] = 20000000000;
//foreach (var z in blockedWaterCoverMap)
//{
// Console.WriteLine("cov,wat indexpair" + z.Key+z.Value);
//}
}
else
{
int ind = findClosest(x);
Console.WriteLine("index,value@index\t" + ind + "\t" + valueCov[ind]);
blockedWaterCoverMap.Add(sortedCov[ind].Key, sortedWat[i].Key);
valueCov[ind] = 00000; valueCov[index] = 00000;
}
}
/////////
private int findClosest(long data)
{
int i = 0; // index of currently checked element from valueCov
int ind =i; // returned index of the closest element
// current lowest distance to searched value:
long min = long.MaxValue;
// currently counted difference between input value
// and the next element of the list valueCov
long diff = 0;
var valueCov = new List<long>();
foreach (var y in sortedCov)
{
valueCov.Add(y.Value);
}
for ( i = 0; i < valueCov.Count; i++)
{
var x=valueCov[i];
if ((diff = Math.Abs(x - data)) < min)
{
min = diff;
ind = i; // the searched index is updated
//Console.WriteLine("findclosest i\t" + i);
}
}
// random selection of the index from the closest
// found values
List<int> indices = new List<int>();
for (int n = 0; n < valueCov.Count; n++)
{
if (valueCov[n] == valueCov[ind])
indices.Add(n);
}
Random r = new Random();
ind = indices[r.Next(indices.Count)];
return ind;
}
答案 0 :(得分:0)
我只想使用linq获取值,然后您可以通过BinarySearch
获取索引
public static void Main()
{
var valueCov = new long[]{ 1,2,2,2,5,5,5,5,6,6,7,7,7};
var result = 0L;
var x = 3;
result = FindNextCloseset(valueCov, x, result);
Console.WriteLine(result);
result = FindNextCloseset(valueCov, x, result);
Console.WriteLine(result);
}
public static long FindNextCloseset(long[] values, int occurrence, long searchAfterValue)
{
return values
.Where(i => i > searchAfterValue)
.GroupBy(i => i)
.Where(i => i.Count() == occurrence)
.Select(i => i.Key)
.FirstOrDefault();
}
答案 1 :(得分:0)
这是我想出的一个解决方案,你可以从这开始。它很长,你应该创建单元测试并重构它,因为它包含很多逻辑:
public static int FindIndexOfClosest(List<long> list, long value_to_search_for, int time)
{
int index = list.BinarySearch(value_to_search_for);
if (index >= 0) //We found the value
{
while (index > 0 && list[index - 1] == value_to_search_for)
//BinarySearch might not return the index of the first occurance
{
index--;
}
index += time;
if (index >= list.Count || list[index] != value_to_search_for)
return -1;
return index;
}
else
{
int location_for_next_larger_number = ~index; //This could be equal to Count
int? larger_index = location_for_next_larger_number == list.Count
? (int?) null
: location_for_next_larger_number;
int? smaller_index = null;
if (!larger_index.HasValue)
{
if (list.Count > 0)
smaller_index = list.Count - 1;
}
else
{
int i = location_for_next_larger_number;
while (i > 0 && list[i - 1] == larger_index.Value)
i--;
if (i > 0)
smaller_index = i - 1;
}
int? closer_number_index = null;
if (larger_index.HasValue)
closer_number_index = larger_index.Value;
if (smaller_index.HasValue)
{
if (!closer_number_index.HasValue)
closer_number_index = smaller_index.Value;
else
{
if (Math.Abs(list[smaller_index.Value] - value_to_search_for) < Math.Abs(list[closer_number_index.Value] - value_to_search_for))
closer_number_index = smaller_index.Value;
}
}
if (closer_number_index.HasValue)
{
while (closer_number_index > 0 && list[closer_number_index.Value - 1] == list[closer_number_index.Value])
closer_number_index = closer_number_index.Value - 1;
long closer_number_value = list[closer_number_index.Value];
closer_number_index += time;
if (closer_number_index.Value >= list.Count || list[closer_number_index.Value] != closer_number_value)
return -1;
return closer_number_index.Value;
}
return -1;
}
}
你可以这样测试:
static void Main(string[] args)
{
List<long> list = new List<long> {1, 2, 2, 2, 5, 5, 5, 5, 6, 6, 7, 7, 7};
var test1 = FindIndexOfClosest(list, 3, 0); // returns 1
var test2 = FindIndexOfClosest(list, 3, 1); // returns 2
var test3 = FindIndexOfClosest(list, 3, 2); // returns 3
var test4 = FindIndexOfClosest(list, 3, 3); // returns -1 (not found)
}
确保您为FindIndexOfClosest
方法提供的列表始终排序。
查看reference for the BinarySearch method,因为它可以帮助您理解我提供的代码。