日本好好热aⅴ|国产99视频精品免费观看|日本成人aV在线|久热香蕉国产在线

  • <cite id="ikgdy"><table id="ikgdy"></table></cite>
    1. 西西軟件園多重安全檢測下載網(wǎng)站、值得信賴的軟件下載站!
      軟件
      軟件
      文章
      搜索

      首頁編程開發(fā)其它知識 → 不要為了面向?qū)ο蠖嫦驅(qū)ο螅瑸榱薼ambda而lambda

      不要為了面向?qū)ο蠖嫦驅(qū)ο,為了lambda而lambda

      相關(guān)軟件相關(guān)文章發(fā)表評論 來源:本站整理時(shí)間:2010/12/20 7:26:38字體大。A-A+

      作者:佚名點(diǎn)擊:55次評論:0次標(biāo)簽: 面向?qū)ο?/a> lambda

      • 類型:商務(wù)模板大小:1.3M語言:中文 評分:10.0
      • 標(biāo)簽:
      立即下載
       記得年初剛來上海的時(shí)候,有一次面試時(shí)遇到一道題,是讀取一個(gè)文本文件里的英文單詞,要算出來每個(gè)單詞的個(gè)數(shù)并降序排列,當(dāng)時(shí)我的思路是循環(huán)每一個(gè)字符并判斷來查找單詞,然后使用dictionary<string,count>來進(jìn)行保存,并使用linq排序。現(xiàn)在想來.,重新寫一下,沒有寫讀取文件部分。感覺當(dāng)時(shí)的思路沒有充分發(fā)揮.net2.0的優(yōu)勢。而且當(dāng)時(shí)寫的代碼沒有面對對象的感覺。

      當(dāng)時(shí)的代碼大概是這樣的,但當(dāng)時(shí)沒有用正則。



      1 protected void CountWords(string text) 2 { 3 Dictionary<string, int> dict = new Dictionary<string, int>(); 4 string[] words= System.Text.RegularExpressions.Regex.Split(text,@"\W+"); 5 foreach (string word in words) 6 { 7 if (dict.ContainsKey(word.ToLower())) 8 { 9 dict[word.ToLower()]++;10 }11 else12 {13 dict.Add(word.ToLower(), 1);14 }15 }16 //按詞頻高低順序排列 17 var items = from w in dict18 orderby w.Value ascending19 select w;20 StringBuilder sb = new StringBuilder();21 22 foreach (var w in items)23 {24 sb.AppendFormat("{0}:{1}\r\n", w.Key, w.Value);25 }26 27 MessageBox.Show(sb.ToString());28 }





      現(xiàn)在又把代碼寫成這樣:

      1 //存儲單詞的數(shù)量 和 單詞的內(nèi)容 2 struct myword 3 { 4 public string word { get; set; } 5 public int count { get; set; } 6 7 public override string ToString() 8 { 9 return string.Format("{0}:{1}", word, count);10 }11 }12 13 //計(jì)算單詞個(gè)數(shù)14 protected void countWords(string content)15 {16 List<myword> wordlist = new List<myword>();17 MatchCollection mc = Regex.Matches(content, @"[a-zA-Z]+\b");18 foreach (Match m in mc)19 {20 myword word = wordlist.Find((w) =>21 {22 return w.word.ToLower() == m.Value.ToLower();23 });24 if (word.count == 0)//如果是初次添加25 {26 wordlist.Add(new myword { word = m.Value, count = 1 });27 }28 else29 {30 wordlist.Remove(word);31 wordlist.Add(new myword { word = m.Value, count = word.count + 1 });32 }33 }34 //按count由高到低排序35 wordlist.Sort(36 (x, y) =>37 {38 return y.count.CompareTo(x.count);39 }40 );41 wordlist.ForEach( w => Console.WriteLine(w) ); 42 }



      各位看官,如果仔細(xì)看一定就會(huì)發(fā)現(xiàn)問題的所在了。

      統(tǒng)計(jì)單詞個(gè)數(shù),本來就是個(gè)小功能。只要在單詞引用數(shù)上+1就行了。

      為了看起來更加面向?qū)ο,原文作者,寫了個(gè)myword類,

      而后用了大量lambda表達(dá)式!


      我對這位作者佩服的五體投地!

      蛋疼,上面的代碼效率起碼是下面的3倍以上,如果重復(fù)的單詞少,文章內(nèi)容長的話,慢10倍都很正常。

      上面的代碼,扣去正則執(zhí)行時(shí)間,運(yùn)算量是o(n), n代碼單詞個(gè)數(shù),

      而下面的代碼,運(yùn)算深度為o((1+2+3+...+n)*n)

      還不包括每次都傻不垃圾的new myword, List的Add,Remove運(yùn)算操作,

      算上gc1,gc2深度的垃圾回收時(shí)間,樓主很強(qiáng)大!



      直接用word.count++不就行了。

      另外樓主貌似不知道,在key,value檢索下,Dictionary是o(1)計(jì)算深度,

      而List的Find是由c#提供的lambda表達(dá)式,實(shí)際就是遍歷一遍List對象,效率也是o(n),

      此處的ni為已找到的單詞個(gè)數(shù),再乘以總個(gè)數(shù)n, 就可以算出來運(yùn)算量為 o ( ( 1 + 2 + 3 + ... + n ) * n )

      為了面向?qū)ο蠖嫦驅(qū)ο螅很自我感覺良好的用了lambda表達(dá)式,



      而且從我本人一向偏好的省代碼角度出發(fā)◎,下面的代碼要比上面還多14行!

      雖說在現(xiàn)在流程配置的電腦上,這兩段代碼在效率上的優(yōu)勢差距并不明顯,

      但是如此般的改進(jìn),我不知道是作者搬門弄武,顯擺對c#的水平有多高,

      還是作者對c#越來越不了解了?



      寫這種技術(shù)類文章也不怕被人罵的,真是攤糟水?dāng)偟郊伊耍?br />


      我的改進(jìn)方法:將List類還是改用Dictionary, Lambda表達(dá)式還可以用。

      下面的 new myword(); add(new myword()); remove(word); 去掉;

      直接word.count++;來的痛快!



      不好意思,剛才review了一遍原文,發(fā)現(xiàn):

      “ 當(dāng)時(shí)的代碼大概是這樣的,但當(dāng)時(shí)沒有用正則。 ”

      又發(fā)現(xiàn)了如下的代碼:


      string[] words= System.Text.RegularExpressions.Regex.Split(text,@"\W+");




      我現(xiàn)在開始簡直懷疑原文作者到底是中文表達(dá)能力不好?,還是根本不懂正則表示式是什么!



      \W+ 不是顯擺著就是正則表達(dá)式嘛~~

      我又著實(shí)被雷到了!

      又發(fā)現(xiàn)新問題了:

      struct myword 的申明中:


      1 public override string ToString()2 {3 return string.Format("{0}:{1}", word, count);4 }



      雖然說結(jié)構(gòu)的基類也是Object,但是結(jié)構(gòu)就要像結(jié)構(gòu)的用法去用!

      因?yàn)榻Y(jié)構(gòu)實(shí)際上是一種值類型。


      結(jié)構(gòu)是值類型:值類型在堆棧上分配地址,所有的基類型都是結(jié)構(gòu)類型,例如:int 對應(yīng)System.int32 結(jié)構(gòu),string 對應(yīng) system.string 結(jié)構(gòu) ,通過使用結(jié)構(gòu)可以創(chuàng)建更多的值類型

        類是引用類型:引用類型在堆上分配地址

        堆棧的執(zhí)行效率要比堆的執(zhí)行效率高


      作為值類型,結(jié)構(gòu)變量的創(chuàng)建一般不用 new 進(jìn)行,就像 c# 中的 int 類型一樣,直接 myword.word = ""; myword.count=1; 即可。

      各位可以嘗試以下代碼:

      1. int x = new int(1);

      2. int y = 1;

      然后在Expression Watch中查看 變量 x, y 。

      前者現(xiàn)實(shí)類型為 Object(int)

      后者類型為原生值類型 int



      換成myword

      也應(yīng)該是:new 出來的為 Object(myword) ; 而 直接賦值的 為 原生 myword 結(jié)構(gòu)。



      雖然到目前為止我還不清楚這兩者的區(qū)別,

      但是在Java中,int x = 1 ; 和 Integer y = new Integer(1) ; 是存在本質(zhì)區(qū)別的。

      一個(gè)是原生的值類型,另外一個(gè)是 value package Object,就是數(shù)據(jù)包裝類型。是類的實(shí)例,即對象!



      兩者在JIL上的執(zhí)行效率可謂相差甚大!,但是我不知道在.net中 new int() 跟 int x = 1 的效率相差有多大!

      因?yàn)?net的外表太華麗了,把所有的細(xì)節(jié)都隱藏在背后,要知道 int 類型執(zhí)行之所以同樣具有 int.Parase();

      int.ToString() 方法,都是因?yàn)?net封裝的好,把ValueTypeObject跟正常的Object封裝的一模一樣,天衣無縫!

      但是對于new出來的 Object(int) 跟 int 類型的區(qū)別,我就不是很清楚了。
        讀書筆記
        (95)讀書筆記
        書中自有黃金屋,書中自有顏如玉,我們總能從書中學(xué)習(xí)到很多意想不到的知識,看見不一樣的風(fēng)景。特別是在我們的學(xué)生時(shí)代,不僅是教科書,更要涉及各種各樣的課外書籍,不僅要讀,還要學(xué)會(huì)做讀書筆記。我們讀再多,不做讀書筆記,沒有讀后感,也相當(dāng)于白讀,做讀書筆記的過程就相當(dāng)于仔細(xì)品讀的過程,而不是一目十行的略讀。本合集是由西西為大家整理的讀書筆記合集,歡迎有需要的朋友前來下載。讀書筆記怎么寫讀書筆記是人們在讀書...更多>>