【问题标题】:Bash script - a puzzleBash 脚本 - 一个谜题
【发布时间】:2014-09-03 20:03:48
【问题描述】:

脚本只接受一个参数(称为n)。然后它交替地加减从 1 到 n 的每个数字。

例如:

n = 12

1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 - 1 + 0 - 1 + 1 - 1 + 2

输出:5

#!/bin/bash
number=$1
result=1
if (( number == 1 || number == 0 )); then
    echo
    echo number: $number
    echo
else
    for (( i = 1; i < number; i++ )); do
        if (( i < 10 )); then
            if (( i % 2 == 0 )); then
                let "result = result + i + 1"
            else
                let "result = result - i - 1"
            fi
        else
            for (( i = 10; i <= number; i++ )); do
                if (( i < 100 && i >= 10)); then
                    let "result = result - i/10 + i%10"
                else
                    let "result = result - i/100 + (i%100)/10 - (i/100)%10"
                fi
            done
        fi
    done

    echo
    echo result: $result
    echo number: $number
    echo
fi

它适用于整数 0 到 9,但对于 n>9,它给出了错误的答案。

请更正我的脚本并向我解释为什么会这样。

PS 我是 bash 脚本的新手,所以我很想看到这个难题的另一种解决方案

PPS我对java很熟悉

编辑

我修复了代码,现在可以正常工作了

#!/bin/bash
number=$1
result=1
if (( number == 1 || number == 0 )); then
    echo
    echo number: $number
    echo
    else
    for (( i = 1; i < number; i++ )); do
        if (( i < 9 )); then
            if (( i % 2 == 0 )); then
                let "result = result + i + 1"
            else
                let "result = result - i - 1"
            fi
        fi
    done
    for (( i = 10; i <= number; i++ )); do
        if (( i < 100 )); then
            let "result = result - i/10 + i%10"
        else
            if (( i % 2 == 0 )); then
                let "result = result - i/100 + (i%100)/10 - (i%100)%10"
            else
                let "result = result + i/100 - (i%100)/10 + (i%100)%10"
            fi
        fi
    done

    echo
    echo result: $result
    echo number: $number
    echo
fi

【问题讨论】:

  • 这是你想要的吗?您在这里期望什么运算符优先级? result = result - i - 1
  • 您应该使用i &lt;= number...这意味着由于09 的正确原因,脚本实际上没有正确运行。
  • @KyleStrand 是的,整数 >= 9 是正确的,我将编辑代码
  • 什么?不,现在您毫无理由地嵌套了for 循环。我指的是第一行for。结束条件错误。
  • 如果一个问题还没有被隔离到你知道 bash 在哪里做你不期望的事情的地步,它还没有准备好问。要弄清楚发生的地点/方式/原因,您需要做的就是echos。

标签: bash shell puzzle


【解决方案1】:

好的,我很抱歉我之前错过了这个问题

number=$1
MATSTR="";
for((i=1; i <= number; i++)); do
        MATSTR="$MATSTR$i";
done;
echo $MATSTR | sed -e 's/\(.\)\(.\)/\1-\2+/g' | sed 's/+$//' | bc 

解释:

  • For 循环创建连接从 1 到数字的所有数字的字符串。
  • sed 语句将每两位数字替换为第一个数字减去第二个数字加
  • sed 删除任何尾随加号
  • bc 计算语句

【讨论】:

  • 但是,我相信它从10 开始给出了错误的答案。如果10 应该是+0 来生成11=1,那么答案应该是5 for i=10 而不是4
  • 谢谢,10 应该是 1 - 2 + 3 - 4 + 5 - 6 + 7 - 8 + 9 - 1 + 0 等于 4
  • 现在我明白了!使用来自10 的两个数字,而不仅仅是制作10=0。你成功了——唯一的方法是连接所有数字,然后沿着字符串添加和减去每个数字。公元前干得好。
  • @DavidC.Rankin 我已经在第 1 篇文章中修复了我的代码,现在可以使用了。所以这不是唯一的方法:P
  • bc 解决方案比循环解决方案更有效。取 1100 (ans=310)。循环time =&gt; 2.1 sec,与 bc time =&gt; 0.19 sec
【解决方案2】:

这是您的原始解决方案,但修复了错误(在 cmets 中)。当然,它仍然不适用于number &gt; 99

#!/bin/bash
number=$1
result=0                                            # Don't start at 1!!
if (( number == 1 || number == 0 )); then
    echo
    echo number: $number
    echo
else
    for (( i = 1; i <= number; i++ )); do           # <=, not <
        if (( i < 10 )); then                       # < 10, not < 9
            if (( i % 2 == 0 )); then
                let "result = result - i"           # subtraction! Also, the +1 was unnecessary
            else
                let "result = result + i"           # addition!
            fi
        else
            if (( i < 100 && i >= 10)); then
                let result=result-i/10+i%10
            else
                let "result=result-i/100+(i%100)/10-(i/100)%10"
            fi
        fi
    done

    echo
    echo result: $result
    echo number: $number
    echo
fi 

【讨论】:

  • @Fizunik 我已经解释了您的代码是如何工作的(似乎或多或少是偶然的)。我还修复了它,使其以合理、大部分可读且语义正确的方式工作。为什么你假设它不起作用而不是尝试一下?
  • 是的,对不起..我已经复制粘贴了,但在测试时没有保存。我的错。我明白你的意思了。
【解决方案3】:

在误读问题后,(或问题不清楚),答案只做了微小的调整。 sting 解决方案可能是使用modulo 切换+/- 的最简单方法:

#!/bin/bash

declare -i num=$1
declare -i res=0
str=""

[ "$num" -gt 1 ] || {
    printf "\n Error: invalid input. usage: %s int (greater than 1)\n\n" "${0//*\//}"
    exit 1
}

for ((i = 1; i <= $num; i++)); do    # create the string of digits
    str="${str}${i}"
done

printf "\n Calculations:\n\n"

for ((i = 0; i < ${#str}; i++)); do  # walk down the string adding/subtracting each digit
    if [ $((i % 2)) -eq 0 ]; then
        ((res+=${str:$i:1}))
        printf "  res + %3s = %3s\n" "${str:$i:1}" "$res"
    else
        ((res-=${str:$i:1}))
        printf "  res - %3s = %3s\n" "${str:$i:1}" "$res"
    fi
done

printf "\n Final Result: %s\n\n" "$res"

exit 0

输出:

$ ./puzzle.sh 12

Calculations:

  res +   1 =   1
  res -   2 =  -1
  res +   3 =   2
  res -   4 =  -2
  res +   5 =   3
  res -   6 =  -3
  res +   7 =   4
  res -   8 =  -4
  res +   9 =   5
  res -   1 =   4
  res +   0 =   4
  res -   1 =   3
  res +   1 =   4
  res -   1 =   3
  res +   2 =   5

Final Result: 5

【讨论】:

  • 从 10 开始应该将数字分成 1 和 0、11 = 1 和 1 等。
  • 它仍然无法正常工作,对于n = 99,输出应该是-40 而不是50
  • 我想我现在明白了。是的99 =&gt; -40。好拼图!
猜你喜欢
  • 2023-03-14
  • 2016-05-10
  • 2017-01-26
  • 2011-03-18
  • 2023-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多