它获取一个文件作为参数,我需要文件的偶数行和奇数行中偶数和奇数的总和
Input:
1 2 3 4 5
2 3 9 5
4 6 1
6 3 1 2 4
Output:
Sum of odd numbers:(1+3+5+1)=10
Sum of even numbers:(2+6+2+4)=12
我尝试使用 foreach 和不使用它,但我不知道如何将字符串从文件转换为整数并将其放入数组
答案 0 :(得分:1)
这是一种方法。
下面的代码使用输入文件的 Here-String 虚拟表示,但在现实生活中你会使用
$fileIn = Get-Content -Path 'Path\To\The\FileWithNumbers.txt'
$fileIn = @"
1 2 3 4 5
2 3 9 5
4 6 1
6 3 1 2 4
"@ -split '\r?\n'
$oddLine = $true # first line is an odd line
$oddTotal, $evenTotal = 0 # create two variables to total the numbers
foreach ($line in $fileIn) {
[int[]]$numbers = $line.Trim() -split '\s+' # split on whitespace(s) and cast to [int]
foreach ($n in $numbers) {
if ($oddLine) {
if ($n % 2) { $oddTotal += $n }
}
else {
if (($n % 2) -eq 0) { $evenTotal += $n }
}
}
$oddLine = !$oddLine # toggle odd and even line
}
"Sum of odd numbers in odd lines: $oddTotal"
"Sum of even numbers in even lines: $evenTotal"
结果:
Sum of odd numbers in odd lines: 10
Sum of even numbers in even lines: 14
P.S.您的示例输出中存在错误:2+6+2+4
等于 14,而不是 12 ;)
如果您的输出还需要显示添加的数字,您可以执行以下操作:
$oddLine = $true # first line is an odd line
# create two collection objects to gather all the numbers
$oddNumbers = [System.Collections.Generic.List[int]]::new()
$evenNumbers = [System.Collections.Generic.List[int]]::new()
foreach ($line in $fileIn) {
[int[]]$numbers = $line.Trim() -split '\s+' # split on whitespace(s) and cast to [int]
foreach ($n in $numbers) {
if ($oddLine) {
if ($n % 2) { $oddNumbers.Add($n) }
}
else {
if (($n % 2) -eq 0) { $evenNumbers.Add($n) }
}
}
$oddLine = !$oddLine # toggle odd and even line
}
# calculate the totals from the lists
$oddTotal = ($oddNumbers | Measure-Object -Sum).Sum
$evenTotal = ($evenNumbers | Measure-Object -Sum).Sum
"Sum of odd numbers in odd lines: $oddTotal ($($oddNumbers -join '+'))"
"Sum of even numbers in even lines: $evenTotal ($($evenNumbers -join '+'))"
结果:
Sum of odd numbers in odd lines: 10 (1+3+5+1)
Sum of even numbers in even lines: 14 (2+6+2+4)
答案 1 :(得分:1)
我昨天写了这个,但质疑这个问题是否是家庭作业,我最初不想发布。也就是说,既然其他人正在研究它,我想我应该继续分享。
$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
考虑对第 1 行第 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
}
注意:我最初是在常规空间上拆分的。我对空白的想法和 Theo's example 的 .Trim()
进行了分裂。我没有费心投射到 [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
语句。它还可以防止大量的模量计算。在上一个示例中,每次 If/ElseIf
触发时,我都会有一个 ElseIf
ergo 会发生第二次模数计算。当然,我可以预先计算一个变量,但这不会完全删除 Else...
。相反,通过将集合存储在散列中,只需进行简单的比较即可知道要附加哪个集合。
注意:最后 3 个示例从第 1 行开始,将第 1 行视为奇数。相对于第 0 行...
答案 2 :(得分:1)
我想我也会发布我对这个问题的解决方案,目前不想发布,因为我认为这是家庭作业,但因为已经有 2 个答案,而且我已经有了代码......
>代码与Theo's answer非常相似。
$i = 0
$oddArray = [collections.generic.list[int]]::new()
$evenArray = [collections.generic.list[int]]::new()
foreach($line in $array)
{
$numbers = $line -split '\s+'
if($i = -not $i)
{
# Odd Lines
foreach($number in $numbers)
{
# If this number is Odd
if($number%2)
{
$oddArray.Add($number)
}
}
}
else
{
#Even Lines
foreach($number in $numbers)
{
# If this number is even
if(-not($number%2))
{
$evenArray.Add($number)
}
}
}
}
[int]$sum = 0
$oddArray|%{$sum+=$_}
"Sum of odd numbers: ({0}) = {1}" -f ($oddArray -join '+'),$sum
[int]$sum = 0
$evenArray|%{$sum+=$_}
"Sum of even numbers: ({0}) = {1}" -f ($evenArray -join '+'),$sum
# Output looks like this
Sum of odd numbers: (1 + 3 + 5 + 1) = 10
Sum of even numbers: (2 + 6 + 2 + 4) = 14