C# 使用foreach很难从一大串数字中求和项

C# 使用foreach很难从一大串数字中求和项,c#,foreach,C#,Foreach,我一直在尝试Euler项目的一个挑战,但我遇到了一个恼人的问题 double sum = 0; string numbers = "3710728753390210279...." foreach (int item in numbers) sum += item; Console.WriteLine(sum); Console.ReadLine(); 当我运行这段代码时,它不会按照我的预期分割每个数字,例如,第一个数字3将是51,第二个数字7将是55。我不明白这些数字是从哪里来的 提前感

我一直在尝试Euler项目的一个挑战,但我遇到了一个恼人的问题

double sum = 0;
string numbers = "3710728753390210279...."

foreach (int item in numbers) sum += item;

Console.WriteLine(sum);
Console.ReadLine();
当我运行这段代码时,它不会按照我的预期分割每个数字,例如,第一个数字3将是51,第二个数字7将是55。我不明白这些数字是从哪里来的


提前感谢。

如果您确定字符串中只有数字,那么您可以实际减去char
'0'
的值,这将为您带来神奇的效果:

int sum = 0;
string numbers = "371";

foreach (char item in numbers) 
    sum += item - '0';

Console.WriteLine(sum);

请注意,
foreach
中有
char
,因此不存在对
int
的隐式强制转换。而且
int
也用于
sum
,而不是
double
,因为这里实际上不需要浮点数

如果您确定字符串中只有数字,那么您实际上可以减去char
'0'
的值,这将为您带来神奇的效果:

int sum = 0;
string numbers = "371";

foreach (char item in numbers) 
    sum += item - '0';

Console.WriteLine(sum);

请注意,
foreach
中有
char
,因此不存在对
int
的隐式强制转换。而且
int
也用于
sum
,而不是
double
,因为这里实际上不需要浮点数

此解决方案有点冗长,但它可以让您清楚地看到发生了什么,还可以排除字符串中可能出现的任何非数字字符:

double sum = 0;
string numbers = "3710728753390210279";

foreach (char item in numbers)
{
    int intVal;
    if(int.TryParse(item.ToString(), out intVal))
        sum += intVal;
}
Console.WriteLine(sum);

此解决方案有点冗长,但它可以让您清楚地看到发生了什么,并且还可以排除字符串中可能弹出的任何非数字字符:

double sum = 0;
string numbers = "3710728753390210279";

foreach (char item in numbers)
{
    int intVal;
    if(int.TryParse(item.ToString(), out intVal))
        sum += intVal;
}
Console.WriteLine(sum);

如果您知道字符串仅包含数字,则此操作有效:

string numbers = "3710728753390210279";
int sum = numbers.Sum(x => x - '0');
如果您不确定它只包含数字,则这将过滤掉非数字:

int sum = numbers.Where(char.IsDigit).Sum(x => x - '0');

如果您知道字符串仅包含数字,则此操作有效:

string numbers = "3710728753390210279";
int sum = numbers.Sum(x => x - '0');
如果您不确定它只包含数字,则这将过滤掉非数字:

int sum = numbers.Where(char.IsDigit).Sum(x => x - '0');

这里的其他答案并没有解释为什么你会看到这些意想不到的数字

我认为您可能希望循环
foreach(数字中的int项)
遍历字符串中的单个“数字”,并自动将这些数字转换为整数。这不是正在发生的事情(是的,但不是你所期望的)

foreach
循环正在将
字符串
转换为
IEnumerable
,并迭代字符串中的每个
char
字符,开始于
'3','7','1',…

.Net
中,字符和字符串用UTF-16编码(正如@TomBlodget在注释中指出的)。这意味着每个
char
都可以转换为其字符代码单元。您的代码实际上将对字符代码单位求和

C#
中,字符
'0','1','9'
的代码单位在48,…,57范围内。因此,您可以执行类似@Yeldar的回答:

foreach (char item in numbers) 
    sum += item - '0';     //  if item == '9' this is equivalent to 57 - 48 = 9
因此,如果字符串只包含数字,那么减去
'0'
字符将隐式地将
字符转换为它的
int
对应项,最后得到它所表示的实际数值(即
'7'-'0'=>55-48=7


这里的其他答案提供了克服这个问题的解决方案。我想解释一下为什么会发生这种情况会很有用。

这里的其他答案没有解释为什么会看到这些意外的数字

我认为您可能希望循环
foreach(数字中的int项)
遍历字符串中的单个“数字”,并自动将这些数字转换为整数。这不是正在发生的事情(是的,但不是你所期望的)

foreach
循环正在将
字符串
转换为
IEnumerable
,并迭代字符串中的每个
char
字符,开始于
'3','7','1',…

.Net
中,字符和字符串用UTF-16编码(正如@TomBlodget在注释中指出的)。这意味着每个
char
都可以转换为其字符代码单元。您的代码实际上将对字符代码单位求和

C#
中,字符
'0','1','9'
的代码单位在48,…,57范围内。因此,您可以执行类似@Yeldar的回答:

foreach (char item in numbers) 
    sum += item - '0';     //  if item == '9' this is equivalent to 57 - 48 = 9
因此,如果字符串只包含数字,那么减去
'0'
字符将隐式地将
字符转换为它的
int
对应项,最后得到它所表示的实际数值(即
'7'-'0'=>55-48=7


这里的其他答案提供了克服这个问题的解决方案。我认为这将有助于解释为什么会发生这种情况。

字符3的ASCII值为51
foreach
将其集合视为
IEnumerable
,您将传递一个
字符串,该字符串实现
IEnumerable
。在C#中,
char
隐式转换为
int
,即代码集中字符的值(ASCII/Unicode)。为什么将
sum
作为
double
?如果这是关于Project Euler问题13(),则您的方法不会得到正确的解决方案。您有一个由100个数字组成的数组(或字符串),每个数字有50个数字,并且要求您提供所有这些50个数字总和的前10个数字。在C#中,使用System.Math.BigInteger和LINQ这一点相对简单。字符3的ASCII值为51
foreach
将其集合视为
IEnumerable
,并传递一个
字符串,该字符串实现
IEnumerable
。在C#中,
char
隐式转换为
int
,即代码集中字符的值(ASCII/Unicode)。如果考虑到这一点,为什么将
sum
作为
double