HashSet表示唯一字符

时间:2013-11-06 15:14:41

标签: c# character hashset

我有一个characters数组,我将迭代。一旦我找到了以前没有找到的角色,我就会做点什么。

这意味着我需要跟踪我已经遇到的角色。我的第一个选择是HashSet,但我不确定这是否是正确的选择,因为hashing单个字符可能需要的时间超过comparing两个字符。我想知道这是不是真的。

  1. HashSet是否是正确的选择,或者是否有更好的选择,例如使用非常小的哈希,或者根本没有。
  2. 澄清转储

    这个数组实际上是一个二维数组,我从一个大学写的函数中得到它。我也需要找到每个角色的位置。某种类型的字符的位置与之无关,只要该字符类型的函数不被调用两次。

    我需要知道的是多维数组中的所有唯一字符,以及每个唯一字符中其中一个的位置。

4 个答案:

答案 0 :(得分:3)

如果您只关心 ASCII ,那么最好的方法是大小为128的数组并转换为int。

 boolean[] array = new bolean[128];
 char c = 'a';
 array[(int) c] = true; 

任何类型的更大编码,绝对只是使用我想的地图。

答案 1 :(得分:1)

您可以从以下数组中获取HashSet

char[] array = new[] { 'a', 'a', 'b', 'c', 'c' };
HashSet<char> hashSet = new HashSet<char>(array);

这比自己比较和检测重复项更好。

答案 2 :(得分:1)

如果你在谈论简单的字符,我想你可以选择一些简单的东西:

bool[] map = new bool[256];

对于元素访问:

map[(int)'a'];

答案 3 :(得分:1)

如果你真的担心优化它,那么你可以使用查找表来表示你的角色:

var lookup = Enumerable.Repeat(true, 256).ToArray();
var otherCharacters = HashSet<char>();

然后,您可以使用查找“小”字符,找到时将其翻转到true,并使用otherCharacters作为unicode内容......

这样的事情:

foreach (var c in myListOfChars)
{
    try
    {
        if (!lookup[(int)c]) { // do something }
        lookup[(int)c] = true;
    }
    catch (IndexOutOfRangeException e)
    {
        if (!otherCharacters.Contains(c)) { // do something }
        otherCharacters.Add(c);
    }
}

对于查找表范围之外的字符,这将达到一个缓慢的位,这取决于您的语言环境是否可接受。对于基于拉丁语的字符集,这应该可以正常工作!

现在......并非所有的世界都在ascii / latin-1范围内工作......浏览阿拉伯语的文本将需要不同的范围。

编辑:嗯......我刚检查了GetHashCode()的输出数字......好吧......结果发现{{1}的哈希码这是int本身...所以使用我们的查找表进行优化可能只是愚蠢......我将检查下一步HashSet的实现......