我昨天写了这篇文章,但质疑这个问题是否是家庭作业,我最初不想发帖。也就是说,既然其他人正在研究它,我想我应该继续分享。
$Numbers = @( Get-Content 'C:\temp\numbers.txt' )
$EvenOdd = @{ 0 = 'even'; 1 = 'odd' }
For( $i = 0; $i -lt $Numbers.Count; ++$i )
{
$LineOdd = $i % 2
$Sum =
$Numbers[$i].Trim() -Split "\s+" |
Where-Object{ $_ % 2 -eq $LineOdd } |
Measure-Object -Sum |
Select-Object -ExpandProperty Sum
"Line {0} : Sum of {1} numbers:({2})={3}" -f $i, ($EvenOdd[$LineOdd]), ($NumberArray -Join '+'), $Sum
}
结果:
Line 0 : Sum of even numbers:(2+4)=6
Line 1 : Sum of odd numbers:(3+9+5)=17
Line 2 : Sum of even numbers:(4+6)=10
Line 3 : Sum of odd numbers:(3+1)=4
考虑第一行 Line#1 的一些小调整:
$Numbers = @( Get-Content 'C:\temp\numbers.txt' )
$EvenOdd = @{ 0 = 'even'; 1 = 'odd' }
For( $i = 1; $i -le $Numbers.Count; ++$i )
{
$LineOdd = $i % 2
$Sum =
$Numbers[$i-1] -Split "\s+" |
Where-Object{ $_ % 2 -eq $LineOdd } |
Measure-Object -Sum |
Select-Object -ExpandProperty Sum
"Line {0} : Sum of {1} numbers:({2})={3}" -f $i, ($EvenOdd[$LineOdd]), ($NumberArray -Join '+'), $Sum
}
注意:我最初是在常规空间上拆分的。我将空格的想法和.Trim() 与Theo's example 分开。我没有打扰到[int]。
注意:这些示例无法与Theo's answer 进行比较。很明显,我们对这个问题的解释不同。如果我有时间,我会研究另一种解释。
分别对奇偶行中的所有数字进行交替求和:
$Numbers = @( Get-Content 'C:\temp\numbers.txt' )
$EvenNumbers = [System.Collections.Generic.List[int]]::new()
$OddNumbers = [System.Collections.Generic.List[int]]::new()
For( $i = 1; $i -le $Numbers.Count; ++$i )
{
$LineOdd = $i % 2
$NumberHash =
$Numbers[$i-1].Trim() -Split "\s+" |
Group-Object { $_ % 2 } -AsHashTable
Switch ($LineOdd)
{
0 { $NumberHash[0].foreach( { $EvenNumbers.Add($_) } ); Break }
1 { $NumberHash[1].foreach( { $OddNumbers.Add($_) } ); Break }
}
}
$SumEven = ($EvenNumbers | Measure-Object -Sum).Sum
$SumOdd = ($OddNumbers | Measure-Object -Sum ).Sum
"Sum of odd lines : {0}{1}" -f "($($OddNumbers -join '+'))=",$SumOdd
"Sum of even lines : {0}{1}" -f "($($EvenNumbers -join '+'))=", $SumEven
回想起来,用ForEach-Object{} 代替Group-Object 和Switch 也同样有效,所以我添加了另一个示例:
$Numbers = @( Get-Content 'C:\temp\numbers.txt' )
$EvenNumbers = [System.Collections.Generic.List[int]]::new()
$OddNumbers = [System.Collections.Generic.List[int]]::new()
For( $i = 1; $i -le $Numbers.Count; ++$i )
{
$LineOdd = $i % 2
$Numbers[$i-1].Trim() -Split "\s+" |
ForEach-Object{
If( !$LineOdd -and $_ % 2 -eq 0 ) {
$EvenNumbers.Add($_)
}
Elseif( $LineOdd -and $_ % 2 -eq 1 ) {
$OddNumbers.Add($_)
}
}
}
$SumEven = ($EvenNumbers | Measure-Object -Sum).Sum
$SumOdd = ($OddNumbers | Measure-Object -Sum ).Sum
"Sum of odd lines : {0}{1}" -f "($($OddNumbers -join '+'))=",$SumOdd
"Sum of even lines : {0}{1}" -f "($($EvenNumbers -join '+'))=", $SumEven
还有一个比上一个更高效、更雄辩的版本:
$Numbers = @( Get-Content 'C:\temp\numbers.txt' )
$Sum = @{
0 = [System.Collections.Generic.List[int]]::new()
1 = [System.Collections.Generic.List[int]]::new()
}
For( $i = 1; $i -le $Numbers.Count; ++$i )
{
$LineOdd = $i % 2
$Numbers[$i-1].Trim() -Split "\s+" |
ForEach-Object{
If( $_ % 2 -eq $LineOdd ) {
$Sum[$LineOdd].Add($_)
}
}
}
$SumOdd = ($Sum[1] | Measure-Object -Sum).Sum
$SumEven = ($Sum[0] | Measure-Object -Sum).Sum
"Sum of odd lines : {0}{1}" -f "($($Sum[0] -join '+'))=", $SumOdd
"Sum of even lines : {0}{1}" -f "($($Sum[1] -join '+'))=", $SumEven
所以,这是一个改进,因为它只需要循环内的单个 If 语句。它还可以防止大量的模数计算。在前面的示例中,每次ElseIf 触发时,我都会有一个If/ElseIf ergo,会发生第二次模数计算。当然,我可以预先计算一个变量,但这不会完全删除Else...。通过将集合存储在哈希中,只需进行简单的比较即可知道要附加哪个集合。
注意:最后 3 个示例从第 1 行开始,并认为第 1 行是奇数。与第 0 行相反...