在不使用字典的情况下在 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;
}
}
因为最后,char
s是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 评论的那样,如果与字母关联的值不取决于其在字母表中的位置,则字典是将每个字母映射到其值的最佳方式。
下面的代码尝试计算字符串的几何值:
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;
}
}
因为最后,char
s是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 评论的那样,如果与字母关联的值不取决于其在字母表中的位置,则字典是将每个字母映射到其值的最佳方式。