【问题标题】:Generate A Short Integer From A Unique String Without .GetHashCode()从没有 .GetHashCode() 的唯一字符串生成短整数
【发布时间】:2020-03-05 21:48:28
【问题描述】:

我想在给定一个唯一字符串时生成一个短整数。请注意,字符串的长度永远不会超过 3 个字符,只有字母字符,可以是大写或小写。例如,AB 不应返回与BA 相同的值。我尝试了类似以下(如下)的方法,但遇到BA 等于AK

public static class StringExtensions
{
    public static int StringToASCIIValue(this string str)
    {
        if (string.IsNullOrWhiteSpace(str)) 
            throw new ArgumentException("string must not be null or whitespace");

        int result = 0;
        foreach (char singleChar in str)
        {
            result = 10 * result + singleChar - '0';
        }
        return result;
    }
}

【问题讨论】:

  • 为什么要避开GetHashCode
  • 我并没有真正看到尝试限制您从中获得的整数的好处。 int 占用 int 的空间,无论它来自 GethashCode 还是使用“较小”的数字计算。
  • 最简单的方法是将每个字符转换为它的 ascii 值,然后将两者连接成一个整数。然后AB = 6566BA = 6665AK = 6575等。没有两个组合会是相同的
  • @TheBatman 的方法非常好,但要知道,如果您决定需要能够转换回来,您将需要一些额外的逻辑(例如,11165 是否应该转换回来到1116511165?显然只有第一个在您的特定情况下有效)。
  • @BrootsWaymb 我需要事先知道这些数字才能进行枚举。

标签: c# string type-conversion


【解决方案1】:

这是实现此目的的简单方法。没有两个结果会是相同的。我们获取字符串,然后对于其中的每个字符,我们将 ascii 值附加到字符串构建器。完成后,我们可以为该字符组合输出一个唯一的整数。

string first = "AB";
StringBuilder stringBuilder = new StringBuilder();

foreach(char c in first)
{
     stringBuilder.Append((int)c);
}

Console.WriteLine(stringBuilder.ToString());

输出

6566

【讨论】:

  • 您只需使用string.Concat(first.Select(c => (int)c))即可获得相同的输出。
  • 不幸的是; char 是一个很宽泛的概念,下面两个会产生相同的hash: 'int i1 = ("" + (char)1234 + (char)567).StringToASCIIValue(); int i2 = ("" + (char)123 + (char)4567).StringToASCIIValue();'
  • @OguzOzgul char 是一个宽泛的概念,但“字母字符,大小写”不是。这些是 OP 提供的约束。
  • @TheBatman ÜĞİŞÇÖ 和 üğışçö 怎么样,它们是非 ASCII 土耳其语大写和小写字符。你看对了吗?如果是,那要归功于支持 UTF-8 的浏览器。如果您真的打算说“字母字符、大小写不是一个广泛的概念”,我邀请您阅读有关字符集、unicode、UTF-8、UTF-16 等的内容。
【解决方案2】:

如果您真的确定您所查看的字母(A-Za-z)字符数不超过 3 个,那么您应该能够只获得 ASCII 编码字节并将它们直接转换为int

public static class StringExtensions
{
    public static int ToInt32(this string str)
    {
        // Checks for null omitted.
        var ascii = System.Text.Encoding.ASCII.GetBytes(str);
        int result = 0;
        for (int i = 0; i < ascii.Length; i++)
        {
            result = result | (ascii[i] << (i * 8));
        }
        return result;
    }
}

如果重要,您可以将 int 带回生成它的 string

public static class StringExtensions
{   
    public static string AsciiIntBackToString(this int value)
    {
        var bytes = BitConverter
            .GetBytes(value)
            .Where(b => b > 0)
            .ToArray();
        return System.Text.Encoding.ASCII.GetString(bytes);
    }
}

【讨论】:

    猜你喜欢
    • 2015-01-08
    • 1970-01-01
    • 2020-08-11
    • 2012-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    相关资源
    最近更新 更多