亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#中使用基數排序算法對字符串進行排序的示例

2020-01-24 01:07:18
字體:
來源:轉載
供稿:網友

開始之前

假設最長字符串的長度是L,以L作為輸入的長度, 然后假定所有的字符串都"補齊"到此長度,這個補齊只是邏輯上的,我們可以假想有一種"空字符", 它小于任何其它字符,用此字符補齊所有長度不足的字符串。例如:最長的字符串長度為9,有一個字符串A長度為6, 那么當比較第7位字符的時候,我們讓A[7]為"空字符"。

如果要包含所有的字符似乎并不容易,我們先定義一個字符集, 待排序字符串中的所有字符都包含在這個字符集里

//字符集private string _myCharSet = "0123456789qwertyuiopasdfghjklzxcvbnm";

再來一個生成隨機字符串的方法(C#實現):

private Random _random = new Random(); string[] GetRandStrings(int size, int minLength, int maxLength){  string[] strs = new string[size];  int len = 0;  StringBuilder sb = new StringBuilder(maxLength);   for (int i = 0; i < strs.Length; i++)  {    //先隨機確定一個長度    len = _random.Next(minLength, maxLength);    for (int j = 0; j < len; j++)    {      //隨機選取一個字符      sb.Append(_myCharSet[_random.Next(_myCharSet.Length)]);    }    strs[i] = sb.ToString();    sb.Clear();  }  return strs;}

這里按照字符的整數表示來確定桶的范圍,再為"空字符"準備一個桶。 為了表示"空字符"這個特例,這里用default(char),即'/0'表示它, 因為當調用string.ElementAtOrDefault(int)方法時,如果超出索引會返回'/0'。

初級版本(C#)

void StringRadixSort(string[] strArray){  if (strArray == null    || strArray.Length == 0    || strArray.Contains(null))  {    return;  }   //獲得字符串的最大長度  int maxLength = 0;  foreach (string s in strArray)  {    if (s.Length > maxLength)    {      maxLength = s.Length;    }  }   //確定字符的整數范圍  int rangeStart = _myCharSet[0];  int rangeEnd = _myCharSet[0];  foreach (char ch in _myCharSet)  {    if (ch < rangeStart)      rangeStart = ch;    if (ch >= rangeEnd)      rangeEnd = ch + 1;  }   //也要為"空字符"分配一個桶,其索引為0  int bucketCount = rangeEnd - rangeStart + 1;  LinkedList<string>[] buckets = new LinkedList<string>[bucketCount];   //初始化所有的桶  for (int i = 0; i < buckets.Length; i++)  {    buckets[i] = new LinkedList<string>();  }   //從最后一個字符開始排序  int currentIndex = maxLength - 1;  while (currentIndex >= 0)  {    foreach (string theString in strArray)    {      //如果超出索引,返回'/0'字符(default(char))      char ch = theString.ElementAtOrDefault(currentIndex);      if (ch == default(char))      {  //"空字符"的處理        buckets[0].AddLast(theString);      }      else      {  //將字符映射到桶        int index = ch - rangeStart + 1;        buckets[index].AddLast(theString);      }    }    //從桶里依次取回字符串,完成一趟排序    int i = 0;    foreach (LinkedList<string> bucket in buckets)    {      while (bucket.Count > 0)      {        strArray[i++] = bucket.First();        bucket.RemoveFirst();      }    }    currentIndex--;  }}

稍作"改良"

用作確定字符的整數范圍的代碼略顯蛋疼,而且根據字符集來看, 并不是區間內所有的整數對應的字符都可能出現,因此會有這樣的情況: 我們給某些根本不會出現的字符分配了桶,這純屬浪費。 我們可以用一個字典(散列)來記錄字符和它的桶之間的映射。于是有了下面的代碼。

private Dictionary<char, int> _charOrderDict =         new Dictionary<char, int>(_myCharSet.Length);void BuildCharOrderDict(){  char[] sortedCharSet = _myCharSet.ToArray();  //使用默認的比較器排序  Array.Sort(sortedCharSet);  //為"空字符"單獨創建映射  _charOrderDict.Add(default(char), 0);  for (int i = 0; i < sortedCharSet.Length; i++)  {    // 保存的是字符及其對應的桶的索引    _charOrderDict.Add(sortedCharSet[i], i + 1);  }}

也可以不用默認的字符排序來作為映射,而完全自己定義字符之間的大小關系。 下面是調整后的代碼:

void StringRadixSort(string[] strArray){  if (strArray == null    || strArray.Length == 0    || strArray.Contains(null))  {    return;  }  //獲得字符串的最大長度  int maxLength = 0;  foreach (string s in strArray)  {    if (s.Length > maxLength)    {      maxLength = s.Length;    }  }   //為每一個字符(包括空字符'/0')分配一個桶  //"空字符"索引應為0  int bucketCount = _myCharSet.Length + 1;  LinkedList<string>[] buckets = new LinkedList<string>[bucketCount];   //初始化所有的桶  for (int i = 0; i < buckets.Length; i++)  {    buckets[i] = new LinkedList<string>();  }   //從最后一個字符開始排序  int currentIndex = maxLength - 1;  while (currentIndex >= 0)  {    foreach (string theString in strArray)    {      //如果超出索引,返回'/0'字符(default(char))      char ch = theString.ElementAtOrDefault(currentIndex);      //根據字符順序的定義查詢字符      int index = _charOrderDict[ch];      buckets[index].AddLast(theString);    }    //從桶里依次取回字符串,完成一趟排序    int i = 0;    foreach (LinkedList<string> bucket in buckets)    {      while (bucket.Count > 0)      {        strArray[i++] = bucket.First();        bucket.RemoveFirst();      }    }    currentIndex--;  }}

Now, it works! 如果采用的快速排序來做, 其時間復雜度為O(n∗logn)O(n∗logn)。表面上看,基數排序更好,不過嚴格來說, 基數排序的時間復雜度應該是O(k∗n)O(k∗n),其中k和字符串長度正相關。 此時兩種算法的比較可以通過比較k和lognlogn的比較結果近似得出。 如果字符串的長度很長,即k很大,而輸入規模n不大的時候, 就會有k>lognlogn,此時快速排序反而更有優勢。反之,則基數排序可能更優。

最后...

杯具的是,當我擴大字符集,將鍵盤上所有字符都加進去后, 發現基數排序的結果和Array.Sort(string[]方法的排序結果并不一樣。 仔細觀察資源管理器對文件名的排序,才發現其字符串排序的規則要復雜的多,并非簡單的比較字符。 查詢相關資料后發現,字符串的排序甚至還要考慮區域文化的影響,即使都是拉丁字母, 不同地區的排序規則都可能不一樣,因此, 使用基數排序實現的字符串排序算法好像并無多大實用價值<T-T>。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美裸体xxxx极品少妇| 91精品国产99久久久久久| 久久资源免费视频| 91九色视频在线| 精品久久久在线观看| 日韩影视在线观看| 成人免费网站在线看| 欧美成人第一页| 欧美激情性做爰免费视频| 精品国产一区二区三区久久久| 日韩在线视频中文字幕| 亚洲视频电影图片偷拍一区| 欧美裸体xxxx极品少妇软件| 国产视频亚洲视频| 国产精品美女在线| 亚洲成人在线网| 精品久久久久久久久久久久久久| 日韩av电影手机在线观看| 欧美多人乱p欧美4p久久| 国产视频久久久久久久| 精品国产一区二区三区久久久| 欧美精品在线免费播放| 日韩精品亚洲精品| 97精品国产97久久久久久春色| 国产成人精品在线观看| 国产精品久久久av久久久| 国产精品亚洲一区二区三区| 日韩av中文字幕在线| 久久青草精品视频免费观看| 精品国产一区二区三区四区在线观看| 国产精品丝袜视频| 亚洲自拍偷拍一区| 国产精品日韩在线| 欧美日韩国产精品一区二区三区四区| 国产91色在线|免| 国产精品免费一区二区三区都可以| 欧美午夜视频一区二区| 91成人免费观看网站| 欧美性猛交丰臀xxxxx网站| 伊人伊成久久人综合网站| 欧美最猛性xxxxx(亚洲精品)| 国产成人高清激情视频在线观看| 久久久精品国产亚洲| 最近2019中文字幕一页二页| 久久精品成人欧美大片古装| 亚洲欧美中文日韩v在线观看| 成人免费直播live| 91最新国产视频| 久久久精品中文字幕| 一本大道香蕉久在线播放29| 国产日韩欧美黄色| 日本一区二三区好的精华液| 国产精品久久视频| 亚洲韩国欧洲国产日产av| 欧美日韩aaaa| 色偷偷av一区二区三区乱| 成人av色在线观看| 亚洲精品av在线| 欧美亚洲日本网站| 亚洲欧美日韩一区在线| 中文字幕九色91在线| 亚洲午夜国产成人av电影男同| 欧美性xxxx极品高清hd直播| 精品中文字幕在线观看| 欧美资源在线观看| 久久久久久网址| 亚洲片av在线| 日韩免费在线观看视频| 日韩视频免费大全中文字幕| 亚洲黄页视频免费观看| 成人写真福利网| 亚洲男人的天堂在线| 亚洲午夜精品久久久久久久久久久久| 亚洲国产成人在线播放| 91国产视频在线播放| 亚洲一区二区自拍| 97人洗澡人人免费公开视频碰碰碰| www.日韩欧美| 日韩欧美a级成人黄色| 日韩电影在线观看永久视频免费网站| 17婷婷久久www| 亚洲一区二区在线播放| 国产视频久久久久久久| 国产精品久久久久久久天堂| 久久精品男人天堂| 九九热精品视频| 日韩av电影国产| 78m国产成人精品视频| 国产日韩欧美在线观看| 国产精品天天狠天天看| 国产精品aaa| 91免费看国产| 91在线观看欧美日韩| 中文字幕精品一区二区精品| 欧美伊久线香蕉线新在线| 国产视频在线一区二区| 国产精品女视频| 久久久免费电影| 亚洲视频综合网| 欧美视频裸体精品| 国产中文日韩欧美| 97精品在线观看| 日韩精品中文字幕有码专区| 国产精品999999| 欧美精品少妇videofree| 欧美精品第一页在线播放| 91精品国产综合久久男男| 国产日韩在线播放| 日韩av手机在线观看| 一本一本久久a久久精品综合小说| 欧美视频裸体精品| 欧美性生交大片免费| 日韩电影中文字幕一区| 国产经典一区二区| 国产精品免费网站| 欧美日韩在线观看视频| 最近2019年日本中文免费字幕| 亚洲激情自拍图| 欧美日韩综合视频| 国产色视频一区| 欧美成人午夜激情视频| 久久躁日日躁aaaaxxxx| 亚洲第一在线视频| 91精品国产综合久久久久久久久| 大荫蒂欧美视频另类xxxx| 国语自产精品视频在线看抢先版图片| 欧美丰满少妇xxxxx做受| 韩国美女主播一区| 午夜精品一区二区三区在线播放| 午夜精品福利视频| 岛国av在线不卡| 亚洲欧美在线免费| 日韩专区中文字幕| 色多多国产成人永久免费网站| 国产99久久精品一区二区 夜夜躁日日躁| 97碰碰碰免费色视频| 51精品国产黑色丝袜高跟鞋| 欧美激情第一页xxx| 国产日韩欧美一二三区| 最新中文字幕亚洲| 欧美高清视频一区二区| 亚洲丝袜av一区| 欧美精品videossex88| 国产欧美韩国高清| 亚洲免费电影一区| 国产一区二区在线播放| 91深夜福利视频| 91久久国产精品| 一区二区中文字幕| 91国自产精品中文字幕亚洲| 亚洲精品久久久久中文字幕二区| 亚洲一区中文字幕| 亚洲国产美女精品久久久久∴| 91深夜福利视频| 国产欧美 在线欧美| 欧美视频在线免费| 亚洲美女精品久久| 亚洲精品aⅴ中文字幕乱码| 国产精品视频免费在线| 国产日韩在线一区| 国产亚洲激情视频在线| 亚洲高清色综合| 国产一区香蕉久久| 日韩高清a**址|