在不使用字典的情况下在 C# 中计算字符串的几何值

Calculating Gematrical Value of a String in C# without Using a Dictionary

下面的代码尝试计算字符串的几何值:

    for (int i = 0; i < str.Length; i++){
            switch(str[i].ToString()){
                case "A":
                    gemValue += 1;
                    break;
                case "a":
                    gemValue += 1;
                    break;
                case "B":
                    gemValue += 2;
                    break;
                case "b":
                    gemValue += 2;
                    break;
                // other characters to follow
                default:
                    gemValue += 0;
                    break;
            }
        }
        Console.WriteLine("The gematrical value of the word or phrase is " +                
        gemValue);
        Console.ReadKey();

有没有一种方法可以在不使用字典(或任何类型的数组)的情况下简化代码和逻辑?

创建整数列表,如:

      int A, a = 1;
      int B, b = 2;
      ...

并不比将所有案例都插入开关更好。我考虑过犯规并只获取每个字符的 ascii 值,但在本练习中也应避免这种情况。

有什么想法吗?

string sample = "abc";
int sum = (from c in sample select char.IsLetter(c) ? char.IsUpper(c) ? c - 'A' + 1 : c - 'a' + 1 : 0).Sum();
Console.WriteLine("The gematrical value of the word or phrase is {0}", sum);

你可以

string str = "Hello";

int gemValue = 0;

for (int i = 0; i < str.Length; i++)
{
    char ch = str[i];

    if (ch >= 'A' && ch <= 'Z')
    {
        gemValue += ch - 'A' + 1;
    }
    else if (ch >= 'a' && ch <= 'z')
    {
        gemValue += ch - 'a' + 1;
    }
}

因为最后,chars是0-65535范围内的数字,其中A=65,B=66,...,Z=90,a=97,b=98, ... z = 122.

请注意,世界是一个大而有趣的地方,到处都是奇妙的语言,而不仅仅是使用 A-Za-z。

string str = "Hèållo"; // Doesn't work with æ, ø
int gemValue = 0;

string str2 = string.Concat(
    str.Normalize(NormalizationForm.FormD)
       .Where(x => CharUnicodeInfo.GetUnicodeCategory(x) != UnicodeCategory.NonSpacingMark));

for (int i = 0; i < str.Length; i++)
{
    char ch = str2[i];

    if (ch >= 'A' && ch <= 'Z')
    {
        gemValue += ch - 'A' + 1;
    }
    else if (ch >= 'a' && ch <= 'z')
    {
        gemValue += ch - 'a' + 1;
    }
    else if (char.IsLetter(ch))
    {
        throw new NotSupportedException(string.Format("{0} contains non A-Z letters", str));
    }
}

这至少会尝试解决某些字母的问题,例如 àèéìòù(以及许多其他字母),将它们转换为 aeeiou 并在您尝试时抛出 NotSupportedException传递它无法识别的字母(如 æ、ø、阿拉伯语、日语、中文……)。请注意,它会忽略非字母,如空格、逗号、点、...

您可以创建小写字符值的字典,然后在简单的 LINQ 查询中将每个字符投射到值:

var str = "aBb";

var letterValues = new Dictionary<char, int> {
    {'a', 1},
    {'b', 2}
};

int gemValue = str.Select(Char.ToLower)
                  .Sum(ch => letterValues.Contains(ch) ? letterValues[ch] : 0);

或者为了获得更好的性能,您可以使用 TryGetValue 方法来避免重复查找字典中包含的字符:

int gemValue = 0;

foreach (var ch in str.Select(Char.ToLower))
{
    int value;
    if (letterValues.TryGetValue(ch, out value))
        gemValue += value;
}

这应该有效:

int minLetter = (int) 'A' - 1;
int sum = "Hello World".Sum(c => (int)Char.ToUpper(c) - minLetter);

测试成功:

var coll = new[] { "a", "A", "aA", "AA", "abc", "ABC", "AbC", "123", "hello World" };
foreach (string str in coll)
{
    int sum = str.Sum(c => (int)Char.ToUpper(c) - minLetter);
    Console.WriteLine(sum);
}

但是,正如 vc74 评论的那样,如果与字母关联的值不取决于其在字母表中的位置,则字典是将每个字母映射到其值的最佳方式。