今天學了不少,之前沒怎麼接觸哈希函數,以爲哈希函數很難,不過它的確是個很複雜高深的函數。但是哈希函數用起來頗有效率,對於提升查找速度有很大的幫助,減小了程序的時間複雜度。哈希函數的時間複雜度爲O(1)。
哈希函數在C#裏有兩個類 HashTable哈希表類和Dictionary 字典類。下面將仔細學習字典類Dictionary。HashTable相似。
類表達式:
Dictionary<TKey,TValue>
TKey:表示Key的數據類型,TValue:表示Value的數據類型;
聲明一個Dictionary對象的語句:
例如 Dictionary<string,string> dic=new Dictionary<string,string>();
在Dictionary中存儲值是都是成對的。每一對值由兩部分組成,一部分是鍵(Key),一部分是值(Value),這對稱爲鍵/值 對,鍵與值是一一對應的。
注意:1.給定的鍵在字典(Dictionary)中是不能重複的,也不能爲null,可是值能夠爲null。鍵、值的數據類型都是任意的,便可以定義爲任何數據類型。
2.字典(Dictionary)是無序可言的。
字典有個特性:能夠使用索引器向字典中添加元素,若是指定的元素還不存在的話,這個元素會新增到字典中,若是指定的鍵已經存在的話,新增的值會覆蓋舊的值。
如:Dictionary<string,int> BookDic=new Dictionary<string,int>(); //實例化一個書本Dictionary類,鍵用於保存字符串類型的書本名字,值用於保存整型的書本數量
BookDic["C#"]=1; //使用索引器向字典添加元素
強化練習:
1. 要求產生1000個互不重複的介於1-20000之間的隨機數, 放到一個長度爲1000的數組中
public class TestArrayDictionary
{
//第一次方案
int[] array;
public int[] CreateRandomArray()
{
array = new int[1000];
Dictionary<int, int> dic = new Dictionary<int, int>();
Random rand = new Random();
int count = 0;
while (count < 1000)
{
int temp = rand.Next(1, 20001);
if (!dic.ContainsValue(temp))
{
dic.Add(count, temp);
array[count] = temp;
count++;
}
}
return array;
}
public int[] CreateRandomArray2()
{
//第2次方案
array = new int[1000];
Dictionary<int, object> dic = new Dictionary<int, object>();
//爲隨機數發生器添加一個種子值,這樣能夠使每次產生的序列不一樣
Random rand = new Random((int)DateTime.Now.Ticks);
while (dic.Count != 1000)
{
int temp = rand.Next(1, 20001);
//檢查數是否是已經在字典中有了,只有沒有的狀況下才添加進去
if (!dic.ContainsKey(temp))
{
dic[temp] = null; //這條語句將數據添加到字典中
}
}
array = dic.Keys.ToArray();
return array;
}
2.給定任意以字符串(能夠包含中文),長度爲任意,要求找出出現次數最多的字符及次數。
public void CountChar(string str)
{
//該函數的缺點:可用性差,沒有返回值,只是把值輸出而已
Dictionary<char, int> dic = new Dictionary<char, int>();
for (int i = 0; i < str.Length; i++)
{
if (!dic.ContainsKey(str[i]))
{
dic[str[i]] = 1;
}
else
{
dic[str[i]]++;
}
}
int mostCount = dic.Values.Max();
char mostChar = ' ';
foreach (KeyValuePair<char, int> kvp in dic)
{
if (kvp.Value == mostCount)
{
mostChar = kvp.Key;
}
}
Console.WriteLine("{0}出現最多的字符是:{1},次數爲:{2}",str,mostChar,mostCount);
}
//改進後的代碼:
public KeyValuePair<char, int> CountChar2(string str)
{
Dictionary<char, int> dic = new Dictionary<char, int>();
for (int i = 0; i < str.Length; i++)
{
if (!dic.ContainsKey(str[i]))
{
dic[str[i]] = 1;
}
else
{
dic[str[i]]++;
}
}
int? numx = null; //int? 在值類型後面加了問號,表示可空類型null。普通值類型的值是不能夠爲null的。這個機制只是針對值類型,引用類型後面加了沒意義。
//int? 解析詳見 《Nullable類型的使用》篇
KeyValuePair<char, int>? max = null;
foreach (KeyValuePair<char, int> pair in dic)
{
if (max == null)
{
max = pair;
}
else
{
if (pair.Value > max.Value.Value)
{
max = pair;
}
}
}
return max.Value;
}