如何在不使用for循环的情况下检查范围编号是否存在于另一个数字列表中?

时间:2012-08-03 10:16:38

标签: c# .net

我有数值范围。

我想检查一个范围内的每个数字是否存在于另一个数字列表中。

我正在使用for循环,但它减慢了我的应用程序。

public void ShowResults()
{
    // The StartNumber and EndNumber is changed depends 
    // upon my requirement, They are not fixed.  
    int StartNumber = 1 ; 
    int EndNumber = 1000000;

    string[] list =
    {
        "1", "equal", "3", "perhaps", "6", "10", "378", 
        "1937", "28936", "26543", "937" .........,
        "understood" "99993"};

    for(int i = StartNumber; i<= EndNumber;i++)
    {
        List<int> resultList = new List<int>();
        int index = Array.IndexOf(list,i.ToString());
        if(index >= 0)
        {
            resultList.Add(i);
        }
    }
}

7 个答案:

答案 0 :(得分:1)

您可以使用二进制搜索在另一个数组中查找一个数组的元素,它需要对其中一个数组进行排序(您执行二进制搜索的数组):

        string[] arr = new string[]{
                    "1", "equal", "3", "perhaps", "6", "10", "378", 
                    "1937", "28936", "26543", "937",
                    "understood", "99993"
        };

        // Create sorted array
        int[] firstMillionNumbers = Enumerable.Range(1, 1000000).ToArray();

        // Parse out numbers only
        List<int> listINT = new List<int>();
        int num;
        foreach (string s in arr)
            if (int.TryParse(s, out num))
                listINT.Add(num);

        // Find elements of a list inside sorted array
        List<int> resultList = new List<int>();
        foreach(int num2 in listINT)
        {
            if (Array.BinarySearch(firstMillionNumbers, num2) >= 0)
                resultList.Add(num2);
        }

答案 1 :(得分:0)

试试这个,

if(list.Intersect(resultList).Count == resultList.Count)
{

}

答案 2 :(得分:0)

尝试用算法而不是编程语言来回答它。

你正在尝试使用两个for循环,这会导致o(n ^ 2)复杂性降低程序的速度。如果你有一个比较范围,为什么不迭代你的列表并用两个简单的ifs检查每个值?这会降低o(n)的复杂性不是吗?

答案 3 :(得分:0)

你可以用你的第一个列表,从“1”到“1000000”,因为它是动态确定的。但是你的第二个怎么样?如果此字符串列表是常量,或者至少生成一次,则应使用HashSet<string>而不是string[]。这样可以更快地查找它:

// This will create an IEnumerable<string> with all numbers to search.
IEnumerable<string> stringsToFind = Enumerable.Range<int>(StartNumber, EndNumber-StartNumber).Select(number => number.ToString());

// This is all the strings in a HashSet. This should be done *beforehand*.
HashSet<string> strings = new HashSet<string>(new [] {  "1", "equal", "3", etc...};

// resultList contains all numbers (from stringToFind) that are in strings).
var resultList = strings.Intersect(stringsToFind);

答案 4 :(得分:0)

首先,您需要拥有类似的集合(具有相同类型的数字或字符串)。比你应该选择较小的集合并采用它到第二个集合。在下面的示例中,我假设list集合将小于带数字的集合。

我不知道这是好还是不好解决。

var originalNumbers = new[] {1, 2, 3, 4, 5, 6};
string[] list =
    {
        "1", "equal", "3", "perhaps", "6", "10", "378",
        "1937", "28936", "26543", "937", "understood", "99993"
    };

IList<int> parsedNumbers = new List<int>();
foreach (var item in list)
{
    int temp;
    if(int.TryParse(item, out temp))
        parsedNumbers .Add(temp);

}

var result = parsedNumbers .Intersect(originalNUmbers);

答案 5 :(得分:0)

通常,迭代一大组变量总是很慢。除了索引或排序之外,没有真正的方法(例如在树中,所以你可以跳过大部分内容)。

但是,由于每次迭代都会重新创建一个新的List<int>(你可能不想这样做,因为你的结果没有任何意义),你的示例代码会变得更慢。

答案 6 :(得分:0)

问题有几个问题。为什么要创建一百万次resultList(并且它只有最后一个值)?你为什么要调用i.ToString一百万次,而不是将小列表过滤到int?

好的,我知道你会说这不是真正的问题。我的回答是发布的问题。如果你想要现实的答案,你需要现实的问题。

int StartNumber = 1 ; 
int EndNumber = 1000000;

string[] list =
{
    "1", "equal", "3", "perhaps", "6", "10", "378", 
    "1937", "28936", "26543", "937" .........,
    "understood" "99993"};

List<int> resultList = new List<int>();
int intOut;
foreach(string li in list)
{
   if (int32.TryParse(li, out intOut))
   {
       if(intOut >= StartNumber && intOut <= EndNumber) resultList.Add(intOut));
   }
}