0

我有数值范围。

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

我正在使用 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);
        }
    }
}
4

7 回答 7

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);
        }
于 2012-08-03T10:48:43.000 回答
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));
   }
}
于 2012-08-03T12:46:34.660 回答
0

通常,迭代大量变量总是很慢。除了索引或排序(例如在树中,因此您可以跳过其中的大部分内容)之外,没有其他真正的方法可以解决它。

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

于 2012-08-03T10:37:07.053 回答
0

对于第一个列表,即从“1”到“1000000”的列表,您无能为力,因为它是动态确定的。但是你的第二个呢?如果这个字符串列表是常量,或者至少生成一次并且很早,你应该使用 aHashSet<string>而不是 a 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);
于 2012-08-03T10:32:24.650 回答
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);
于 2012-08-03T10:33:03.013 回答
0

尝试这个,

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

}
于 2012-08-03T10:19:14.070 回答
0

试图用算法而不是编程语言来回答它..

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

于 2012-08-03T10:22:08.810 回答