2012-08-03 53 views
0

我有數值範圍。如何檢查範圍號碼是否存在於另一個號碼列表中而不使用for循環?

我想檢查一個範圍內的每個數字是否存在於另一個數字列表中。

我使用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); 
     } 
    } 
} 
+5

您每次通過循環創建'resultList' - 發佈的代碼將創建*一百萬個列表*,這可能是您的性能問題的一部分。你究竟在做什麼? – 2012-08-03 10:21:50

+0

如果你的字符串列表'list'比'EndNumber'減去'StartNumber'短得多,那麼你也可以說'list.Where(str => {int n; bool ok = int.TryParse(str,out n); return ok && n> = StartNumber && n <= EndNumber;})'或類似的。 – 2012-08-03 10:38:26

+0

將resultList的聲明移至for循環外部以解決性能降低問題 – Alex 2012-08-03 10:54:37

回答

0

試試這個,

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

} 
+0

需要注意的是,這仍將在後臺使用循環。這很慢,因爲比較一百萬個值*是*很慢。 – 2012-08-03 10:20:25

0

試圖回答這個問題在算法方面,而不是在編程語言..

你要使用兩個用於排放造成Ø循環(N^2)複雜性減慢程序。如果你有一個比較範圍,爲什麼不迭代你的列表,並用兩個簡單的if檢查每個值?這會降低o(n)的複雜性是不是?

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); 
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); 
0

通常,迭代大量變量總是會很慢。除索引或排序之外,沒有真正的方法(例如,在樹中,因此您可以跳過其中的大部分內容)。

但是,由於每次迭代都會重新創建一個新的List<int>,因此您的示例代碼會變得更慢(這可能不是您想要做的事情,因爲您的結果不會有任何意義)。

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); 
     } 
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)); 
    } 
} 
相關問題