Powershell 偶数和奇数

时间:2021-05-07 20:15:20

标签: powershell

它获取一个文件作为参数,我需要文件的偶数行和奇数行中偶数和奇数的总和

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 和不使用它,但我不知道如何将字符串从文件转换为整数并将其放入数组

3 个答案:

答案 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-ObjectSwitch 一样有效,因此我添加了另一个示例:

$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
相关问题