今天学了不少,之前没怎么接触哈希函数,以为哈希函数很难,不过它的确是个很复杂高深的函数。但是哈希函数用起来颇有效率,对于提升查找速度有很大的帮助,减小了程序的时间复杂度。哈希函数的时间复杂度为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;
}