程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 數據搜索算法

數據搜索算法

編輯:關於.NET

這一篇我們來關注一下搜索。我們同樣把目光放在Array這個最基礎的數據類 型上面。我們從幾個實例來講解怎麼利用.NET的內部機制實現檢索

1. Array.Exists

這個方法是判斷是否在指定數組中存在某個成員。讓我們 來看看這個方法的定義

該方法返回一個bool值,這很好理解。它的第一個參數是一個Array, 這也很好理解。(就是我們要搜索的數據源),而第二個參數是一個所謂的 Predicate類型。我們展開來看一下這個東西吧

這是一個委托。也就是說它是一個指針,需要我們告訴它如何判斷數 據存在的依據。那麼怎麼給出這個參數呢?

傳統的做法,我們准備一個 方法,這個方法是滿足該委托的簽名的(有一個參數,而且返回一個bool),然 後通過該委托去調用該方法。(假設我們這裡判斷存在的依據是該數字等於2)

static bool MatchInt(int input)
{
    return input == 2;
}

然後,在Exists方法中使用委托來調用這個 MatchInt方法去進行判斷。(有兩種寫法)

static void Main (string[] args)
{
    int[] numbers = new int[] { 3, 7, 2, 4, 10, 1 };
    Console.WriteLine(Array.Exists<int> (numbers, new Predicate<int>(MatchInt)));//這是原始寫法
     Console.WriteLine(Array.Exists<int>(numbers, MatchInt));// 這是上面一句代碼的簡寫

    Console.Read();

}

從上面的代碼可以看出,為了做這個判斷,我們專門寫了一個方 法,這在很多時候會增加代碼閱讀的麻煩,因為閱讀者需要從一個方法跳到另外 一個方法,不斷反復。

所以,在C# 2.0中,提出了匿名方法的概念,也 就是對於此類不太需要單獨封裝的地方,可以直接將方法體合並在委托聲明中。 也就是說,沒有必要單獨寫MatchInt這個方法。

Console.WriteLine (Array.Exists<int>(numbers, delegate(int i) { return i == 2; }));

這一句代碼就可以完成所有事情了。其實也很直觀。

而在最 新的C# 3.0中,針對這這種問題,又有了改進,就是所謂的Lambda表達式,大家 來看一下代碼是如何寫的

Console.WriteLine (Array.Exists<int>(numbers, i => i == 2));

你可能一下子 還不理解Lambda,但只要大致看一下C# 3.0的新語法例子,其實還是比較通俗的 。

如果有興趣的朋友,可以通過IL代碼看到,第二種方式和第三種方式其實是 一模一樣的。匿名方法和Lambda是語言之上的改進,編譯的結果還是需要通過 delegate來實現的。你也可以說,它們與第一種沒有根本區別。

但在事 實上,他們確實更加直觀和簡潔。

2. Array.Find, Array.FindLast

如果我們需要搜索一個數組中的某個元素,而不光是判 斷它是否存在。我們大致的寫法如下

Console.WriteLine (Array.Find<int>(numbers, i => i == 2));

注意,如果找到 了,則返回2這個數值。Find方法是找到一個即停止。而如果要找最後一個匹配 的值,就需要用FindLast

3. Array.FindAll

這個方法是搜索所有 匹配的數據,返回一個數組。

int[] foundnumbers = Array.FindAll<int>(numbers, i => i % 2 == 0);//搜索所有的偶數
foreach (var item in foundnumbers)
{
    Console.WriteLine(item);
}

有意思的是,上面的代碼可 以簡寫為下面一句代碼

Array.ForEach<int> (Array.FindAll<int>(numbers, i => i % 2 == 0), i => Console.WriteLine(i));

4. Array.FindIndex, Array.FindLastIndex

這個方法是檢索相應的值在數組中的索引號

Console.WriteLine(Array.FindIndex<int>(numbers, i => i == 1));

Console.WriteLine (Array.FindLastIndex<int>(numbers, i => i == 1));

5. Array.BinarySearch

上面的Find方法,基本上都 是基於順序的。也就是,如果某個數字很不湊巧在最後面,那麼搜索程序就不得 不將每個數字都檢查一次,比較他們。這樣,在很多時候效率是不夠高的。當然 ,如果數據本身沒有規律,是隨機分布的,這也是無法避免的。

如果說 數據本身有順序,那麼就可以利用二進制搜索來提高速度。二進制搜索其實是一 個折半搜索算法。也就是說,既然數據本身有順序,就可以不要一個一個比較, 而是可以在某個范圍內比較

從這個原理可以知道,二進制搜索是依賴數據本身排序的。事實上,如果數 據沒有排序,則該方法也不會出錯,但是會返回一個負數或者一些奇怪的結果。

我們用例子來比較一下二進制搜索和順序搜索的差別

static void Main(string[] args)
  {

       //准備一個數組,隨機填充10000000個數字
      int[] numbers = new int[10000000];
      Random rnd = new Random ();
      for (int i = 0; i < numbers.Length; i++)
      {
          numbers[i] = rnd.Next (10000000);
      }

      //采用順序搜索的方 式,查找裡面100這個數值(如果運氣比較好,正好有100的話)
       Stopwatch watch = Stopwatch.StartNew();
      Console.WriteLine(Array.Find<int>(numbers, i => i == 100));
      watch.Stop();
      Console.WriteLine("順序搜索使用的時間為:{0}毫秒", watch.ElapsedMilliseconds);

      //采用二進制搜索的方 式,查找裡面100這個數值
      watch.Reset();
      watch.Start();
      Array.Sort<int>(numbers);//先排序
      watch.Stop();
      Console.WriteLine("排序 的

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved