我有一项任务,我必须检查有多少奇数。例如:
cw(string[54]); //37 42 44 61 62
由此我需要知道这个字符串中有多少个奇数。我想出的唯一方法是将字符串切成5个整数,因此int 1为37,2为42,依此类推。但即使采用方法,这也是一个非常漫长而缓慢的过程。
任何帮助,或者我应该坚持看起来像这样的“切割”:
for (int y = 0; y < all_number.Length; y++)
{
for (int x = 0; x < 5; x++)
{
cutter = all_number[y];
placeholder = cutter.IndexOf(" ");
final[x] = Convert.ToInt32(cutter.Remove(placeholder));
}
}
这是第一个数字,因此在37 42 44 61 62最终将是37。
答案 0 :(得分:4)
我首先使用外部foreach
循环,而不是按索引引用数组值,除非索引很重要(它看起来不像在这里)。
我然后使用string.Split
按空格分割每个字符串,然后使用LINQ将奇数相加。
例如:
foreach (string line in lines)
{
var oddSum = line.Split(' ')
.Select(int.Parse) // Parse each chunk
.Where(number => (number & 1) == 1) // Filter out even values
.Sum(); // Sum all the odd values
// Do whatever you want with the sum of the odd values for this line
}
如果您实际上只想计算奇数,您可以使用接受谓词的Count
重载:
foreach (string line in lines)
{
var oddCount = line.Split(' ')
.Select(int.Parse) // Parse each chunk
.Count(number => (number & 1) == 1) // Count the odd values
// Do whatever you want with the count of the odd values for this line
}
请注意,这将在遇到的第一个非整数值处抛出异常(在int.Parse
中)。这可能没问题,但您可以使用int.TryParse
来避免异常。但是,LINQ使用起来比较困难;如果您需要此功能,请说明您希望如何处理它们。
答案 1 :(得分:1)
首先,使用您可用的内置工具。
要按预定义字符拆分字符串,请使用var numbers = allNumbersString.Split(' ');
:
int.TryParse
现在你有一个字符串数组,每个字符串都包含一个我们希望是数字的字符串表示。
现在我们需要从每个字符串中提取数字。最安全的方法是使用foreach (var n in numbers)
{
if (int.TryParse(out var number)
{
//ok we got a number
}
else
{
//we don't. Do whatever is appropriate:
//ignore invalid number, log parse failure, throw, etc.
}
}
:
number % 2 != 0
现在,只需返回那些奇怪的:public static IEnumerable<int> ExtractOddNumbers(
string s
char separator)
{
if (s == null)
throw new ArgumentNullException(name(s));
foreach (var n in s.Split(separator))
{
if (int.TryParse(out var number)
{
if (number % 2 != 0)
yield return number;
}
}
}
;
全部放在一起:
var countOfOddNumbers = ExtractOddNumbers(s, ' ').Count();
所以,如果你想知道给定字符串中有多少个奇数,你可以这样做:
public static IEnumerable<int> ExtractNumbers(
string s
char separator
Func<int, bool> predicate)
{
if (s == null)
throw new ArgumentNullException(name(s));
foreach (var n in s.Split(separator))
{
if (int.TryParse(out var number)
{
if (predicate(number))
yield return number;
}
}
}
这种方法的好处在于,现在,它易于扩展。对我们当前方法的一个小修改使它变得更加强大:
ExtractNumbers(s, ' ', n => n % 2 != 0)
看看我们做了什么?我们已经将过滤标准作为方法调用的另一个参数;现在您可以根据任何条件提取数字。奇数? ExtractNumbers(s, ' ', n => n % 7 == 0)
。 7的倍数? ExtractNumbers(s, ' ', n => n > 100)
。大于100? $ git clone https://github.com/me/proj-hope.git .
等等。
答案 2 :(得分:0)
正如其他人所说,Split
方法就是你所追求的。
如果您想要奇数的计数,那么您可以像这样完成任务:
var oddCount = lines.SelectMany(line => line.Split(' ')) // flatten
.Select(int.Parse) // parse the strings
.Count(n => n % 2 != 0); // count the odd numbers
或者如果你想要总结,你可以这样做:
var oddSum = lines.SelectMany(line => line.Split(' '))// flatten
.Select(int.Parse) // parse the strings
.Where(n => n % 2 != 0)// retain the odd numbers
.Sum();// sum them
这假设字符串中没有无效字符,否则,您需要在继续之前使用Where
子句执行检查。
答案 3 :(得分:0)
另一种方法是循环字符串的字符,如果当前字符是空格或字符串的结尾,前一个字符是'1','3','5','7'或' 9'(奇数以奇数结尾),增加计数。
这允许字符串包含比int大得多的数字,不分配新内存(与String.Split一样)并且不需要解析整数。它假设一个有效数字的有效字符串:
var count = 0;
for(var i = 1; i < cw.Length; i++)
{
int numberIndex = -1;
if(i == cw.Length - 1) numberIndex = i;
if(cw[i] == ' ') numberIndex = i - 1;
if(numberIndex != -1)
{
if(cw[numberIndex] == '1' || cw[numberIndex] == '3' ||
cw[numberIndex] == '5' || cw[numberIndex] == '7' ||
cw[numberIndex] == '9')
{
count++;
}
}
}