项目总结——hashtable排序问题

前言:

对于Hashtable在我的上篇博客中有提到,是用在了事务处理中,向sqlhelper传递参数,这个用的很巧妙不知道大家有没有进一步的研究,但是为什么现在需要用到Hashtable的排序呢。大家跟着我想这样的一个场景,现在需要注册一个新用户,注册用户的时候需要有如下的业务逻辑:每个用户拥有或多张卡,注册用户的时候需要对卡进行一定金额的充值。


一、业务表分析:


对于这个业务逻辑我们建立的关系表需要有三张,1.用户信息表,用于保存用户的基本信息;2.卡信息表,用于保存卡的基本信息;3.充值记录表,用于保存充值记录信息。当然考虑数据库建立的三范式,我们还需要保证这三张表具有主外键的关系。用一张数据库关系图来表示:


二、与事务机制的联系:


当然我们会想到这“三件”事必须同时完成或同时不完成,他们的这种关系就组成了一个事务操作,而这个要求即事务的原子性。

三、为什么要对Hashtable排序:


要实现这样的需求,还需要满足的操作要求:三张表的插入顺序是:用户表——卡表——充值表。

对于Hashtable有一定了解的人都知道Hashtable的一个重要的特点就是排序无序的。

对于这个无序的说明有这样的一个例子:

publicstaticvoidMain()
{
	Hashtableht=newHashtable();
	
	ht.Add("key1","value1");
	ht.Add("key2","value2");
	ht.Add("key3","value3");
	ht.Add("key4","value4");
	ht.Add("key5","value5");
	
	foreach(stringstrinht.Keys)
	{
		Console.WriteLine(str+":"+ht[str]);
	}
}

运行的结果:

通过这个小例子就可以理解了哈希表的无序性。那我们怎么保证程序按照我们想要的顺序在sqlhelper中逐个的执行呢。(这个执行的代码看上篇博客)我们就需要Hashtable进行排序了。


四、排序的方法:


这里我主要给大家介绍3种方法:


1.我按什么顺序加进去就按什么顺序输出:

publicclassNoSortHashTable:Hashtable
{
	privateArrayListlist=newArrayList();
	publicoverridevoidAdd(objectkey,objectvalue)
	{
		base.Add(key,value);
		list.Add(key);
	}
	publicoverridevoidClear()
	{
		base.Clear();
		list.Clear();
	}
	publicoverridevoidRemove(objectkey)
	{
		base.Remove(key);
		list.Remove(key);
	}
	publicoverrideICollectionKeys
	{
		get
		{
			returnlist;
		}
	}
}

这里注意:ArrayList是不排序的(添加的顺序就是输出的顺序)。让它和hashtable结合不就实现这种功能的吗?这样继承了Hashtable具有Hashtable的丰富功能,又满足ArrayList不排序的功能。满足我们的要求。

publicstaticvoidMain()
{
	NoSortHashTableht=newNoSortHashTable();
	
	ht.Add("key1","value1");
	ht.Add("key2","value2");
	ht.Add("key3","value3");
	ht.Add("key4","value4");
	ht.Add("key5","value5");
	foreach(stringstrinht.Keys)
	{
		Console.WriteLine(str+":"+ht[str]);
	}
}

这样一运行就满足我的要求了:

成功了!


2.我按Hashtable中键的大小顺序进行排序

实际上是按照每一个字符的ASCII的值就行排序的。从左到右比较每个字符的Ascii的值,直到满足两个字符的ASCII的值不同即停止比较

publicstaticvoidMain()
{
	Hashtableht=newHashtable();
	
	ht.Add("ee","value1");
	ht.Add("dd","value2");
	ht.Add("cc","value3");
	ht.Add("bb","value4");
	ht.Add("aa","value5");
	ArrayListlist=newArrayList(ht.Keys);
	list.Sort();
	foreach(stringstrinlist)
	{
		Console.WriteLine(str+":"+ht[str]);
	}
}

运行效果:

成功了!


3.我按Hashtable中的值得大小就行排序

原理同上:实际上是按照每一个字符的ASCII的值就行排序的。从左到右比较每个字符的Ascii的值,直到满足两个字符的ASCII的值不同即停止比较

publicstaticvoidMain()
{
	Hashtableht=newHashtable();
	ht.Add("a","3");
	ht.Add("b","4");
	ht.Add("c","2");
	ht.Add("d","1");
	ArrayListlist=newArrayList(ht.Values);
	list.Sort();
	foreach(stringsvalueinlist)
	{
		IDictionaryEnumeratoride=ht.GetEnumerator();
		while(ide.MoveNext())
		{
			if(ide.Value.ToString()==svalue)
			{
				Console.WriteLine(ide.Key+":"+svalue);
			}
		}
	}
}

运行效果:

成功了!


五、总结:


针对第二,第三,我们可以看出来了通过下面的这个方法把Hashtable的键(keys)或值(values)转换成Arraylist.

ArrayListlist=newArrayList(ht.Values);

ArrayListlist=newArrayList(ht.Keys);

这样就可以把Hashtable的排序转换成ArrayList的排序了!

另外ArrayList提供的很多方法排序:

ArrayList.Sort()-------------------按字符的Ascii的值排序

ArrayList.Reverse()---------------反转数组

等还多ArrayList方法。如果都不满足你要的排序功能的话,那就自己针对ArrayList这个数组写算法就能对ArrayList排序,ArrayList排序也就完成了Hashtable的排序。


六、重点说明:


另外,需要说明一点,上面的排序是不严谨的,有值相等时会有重复输出。

例如:

publicstaticvoidMain()
{
	Hashtable hs = new Hashtable();
	hs.Add(5, 40);
	hs.Add(4, 20);
	hs.Add(3, 20);
	hs.Add(2, 15);
	hs.Add(1, 5);
	ArrayList als = new ArrayList(hs.Values);
	als.Sort();
	foreach (object ob in als)
	{
		IDictionaryEnumerator ide = hs.GetEnumerator();
		while (ide.MoveNext())
		{
			if (ide.Value.ToString() == ob.ToString())
			Console.WriteLine(ide.Key.ToString() + ":" + ob.ToString());
		}
	}
}

运行结果为:


引起这个问题主要是那hashtable中允许有重复的值引起的。如果要想解决这个问题的话,在转换成ArrayList时候需要把重复的value去掉。(key不允许重复就不会出现)

可以将程序改为:

publicstaticvoidMain()
{

	Hashtable ht = new Hashtable();
	ht.Add(5, 40);
	ht.Add(4, 20);
	ht.Add(3, 20);
	ht.Add(2, 15);
	ht.Add(1, 5);
	ArrayList listTemp = new ArrayList(ht.Values);
	ArrayList list = new ArrayList();
	foreach (object value in listTemp)
	{
		if (!list.Contains(value))
		{
			list.Add(value);
		}
	}
	list.Sort();
	foreach (object obj in list)
	{
		IDictionaryEnumerator ide = ht.GetEnumerator();
		while (ide.MoveNext())
		{
			if (ide.Value.ToString() == obj.ToString())
			{
				Console.WriteLine(ide.Key.ToString() + ":" + obj.ToString());
			}
		}
	}
}

运行结果为:


成功了!

阅读更多
换一批

问个Hashtable排序问题

04-11

我的类源码:rn----------------------------------------------------------------------------------------rnusing System;rnusing System.Collections.Generic;rnusing System.Linq;rnusing System.Text;rnusing System.Collections;rnrnnamespace ConsoleApplicationrnrn /// rn /// 哈希表,名-值对。类似于字典(比数组更强大)。哈希表是经过优化的,访问下标的对象先散列过。rn /// 如果以任意类型键值访问其中元素会快于其他集合。rn /// GetHashCode()方法返回一个int型数据,使用这个键的值生成该int型数据。rn /// 哈希表获取这个值最后返回一个索引,表示带有给定散列的数据项在字典中存储的位置。rn /// rn class myHashtablern rn static void Main()rn rn Hashtable ht = new Hashtable(); rn ht.Add("1","严");rn ht.Add("2", "由");rn ht.Add("3", "剑");rn ht.Add("4","是");rn ht.Add("5","蜗牛");rn PrintKeyAndValue(ht);rn Console.WriteLine("按任意键结束...");rn Console.ReadKey();rn rn public static void PrintKeyAndValue(Hashtable ht)rn rn Console.WriteLine("Hashtable Key");rn foreach (string key in ht.Keys)rn rn Console.WriteLine(key);rn rn Console.WriteLine("-Key- -Value- -HashCode-");rn foreach (DictionaryEntry dic in ht)rn rn Console.WriteLine("0:1:2",dic.Key,dic.Value,dic.GetHashCode());rn rn rn rnrn-------------------------------------------------------------------------------------rn下面是输出的结果:rn Hashtable Keyrn4rn5rn1rn2rn3rn-Key- -Value- -Hashrn4:是:-1258779796rn5:蜗牛:-1258779797rn1:严:-1258779793rn2:由:-1258779794rn3:剑:-1258779795rn按任意键结束...rn问顺序怎么会变成这样,他是按什么排序的?rn

c# hashtable排序问题

02-02

以下是我编的程序,主要功能,是可以输入一句话,然后统计这段话中每个单词出现的次数,然后出现次数少的在前,多的在后,就是说按升序排列,应该是对HashTable的VALUE排序,不过我弄不出来,以下是我的代码!我是用VS 2005进行编辑的!rnusing System;rnusing System.Collections;rnnamespace ConsoleApplication1rnrn /// rn /// Summary description for Class1.rn /// rn class Class1rn rn /// rn /// The main entry point for the application.rn /// rn [STAThread]rn static void Main(string[] args)rn rn Console.WriteLine("Please enter one sentence");rn String strSentence = Console.ReadLine();rn String[] strArr = strSentence.Split();rnrn Hashtable hTable = new Hashtable();rn for (int i = 0; i < strArr.Length; i++)rn rn String strCurrWord = strArr[i];rn if (hTable.ContainsKey(strCurrWord))rn rn int counter = (int)hTable[strCurrWord];rn counter++;rn hTable[strCurrWord] = counter;rn rn elsern rn hTable[strCurrWord] = 1;rn rnrn rnrn ArrayList newArrayList = new ArrayList(hTable.Values);rnrn newArrayList.Sort(); // 升序排列rnrn ArrayList newArray = new ArrayList();rnrn foreach (int score in newArrayList)rn rnrn if (!newArray.Contains(score))rn rn ICollection colKeys = hTable.Keys;rn IEnumerator it = colKeys.GetEnumerator();rnrn while (it.MoveNext())rn rn if ((int)it.Current== score)rn rnrn String strKey = (String)it.Current;rn Console.Out.WriteLine("The word" + strKey + "has appeared" + hTable[strKey] + "times!");rn rnrn rnrn newArray.Add(score);rnrn rn rnrn Console.ReadLine();rn rn rnrnrn

没有更多推荐了,返回首页