我有一个List myList = new List(){8,5, 3 ,3,3,3,3, 3 ,4,5,3, 8};
假设我选择列表的第5个元素是3。
我想找到给定元素的相似值的起始和结束索引,只要它是相似的
所以,我需要前3个(在这种情况下为2)和最后3个(在本例中为7)的索引。
为此,我决定使用while循环来进行列表的开始,然后使用另一个while循环来到列表的末尾。
但感觉这是实现理想结果的昂贵/缓慢的方式。
你知道更快/更好的方法吗?
谢谢!
答案 0 :(得分:0)
这是一个可能但不优雅的解决方案:
List<int> myList = new List<int> { 8, 5, 3, 3, 3, 3, 3, 3, 4, 5, 3, 8 };
var index = 5;
var element = myList.ElementAt(index);
int firstIndex=index, lastIndex=index;
int i, j;
bool control1 = true, control2 = true;
for (i = index, j = index; ; i--, j++)
{
if (control1 && i >= 0 && myList[i] == element)
{
firstIndex = i;
}
else
{
control1 = false;
}
if (control2 && j < myList.Count && myList[j] == element)
{
lastIndex = j;
}
else
{
control2 = false;
}
if (!control1 && !control2) break;
if (i < 0 && j >= myList.Count) break;
}
Console.WriteLine(firstIndex);
Console.WriteLine(lastIndex);
输出:
// index = 5
firstIndex = 2, lastIndex = 7
// index = 1
firstIndex = 1, lastIndex = 1
// index = 8
firstIndex = 8, lastIndex = 8
答案 1 :(得分:0)
假设您正在讨论大型列表,那么执行您的方法的两个线程可能会很有用。你需要一个像
这样的功能int getSimilarIndex(IReadOnlyList<int> list, int startIndex, bool forward) {
int index = startIndex;
int startElement = list[startIndex];
while (forward ? (index < list.Count) : (index >= 0) ) {
if (!isSimilar(list[index], startElemen))
break;
if (forward)
++index;
else
++index;
}
return index;
}
返回类似条目的第一个/最后一个索引。现在您可以将该函数的两个版本分配给ThreadPool-Threads:
ThreadPool.QueueUserWorkItem( (WaitCallback) delegate {
this.minSimilarIndex = getSimilarIndex(list, startIndex, false);
});
ThreadPool.QueueUserWorkItem( (WaitCallback) delegate {
this.maxSimilarIndex = getSimilarIndex(list, startIndex, true);
});
您还可能希望向该功能添加事件,以表示作业已完成。
答案 2 :(得分:0)
您可以尝试此解决方案:
var myList = new List<int>() { 8, 5, 3, 3, 3, 3, 3, 3, 4, 5, 3, 8 };
int givenIndex = 11;
int givenValue = myList[givenIndex];
bool firstFound = false, lastFound = false;
int firstIndex = givenIndex, lastIndex = givenIndex;
int index = 1;
int length = myList.Count;
while (!(firstFound && lastFound))
{
if (!lastFound && (givenIndex + index >= length || myList[givenIndex + index] != givenValue))
{
lastFound = true;
lastIndex = givenIndex + index - 1;
}
if (!firstFound && (givenIndex - index <= 0 || myList[givenIndex - index] != givenValue))
{
firstFound = true;
firstIndex = givenIndex - index + 1;
}
index++;
}
Console.WriteLine("The first index is {0} and the last index is {1}.", firstIndex, lastIndex);
}