用bash写ACM题

如果要管理一台 Linux 服务器,bash 可以说是必修课。看了一天 bash 有点手痒痒,可是似乎没那么多实例可以练习ummm还是继续水题吧。

bash 不同于一般的编程语言,它有很多限制。可能没人会拿它写算法,出现很多问题,甚至百度也无果。

读了啥东西?

做题读数字可是家常便饭,比如第一行一个正整数 n,第二行 n 个数。于是:

#!/bin/sh

read n
echo $n
for ((i = 0; i < n; i++))
do
    read sta[i]
    echo ${sta[i]}
done

显然它把第二行整行当作字符串读入了。

如果用 while 呢?(当然不能改变什么)

#!/bin/sh

read n
echo $n
i=0
while [[ $i < $n ]]
do
        read sta[i]
        echo ${sta[i]}
        i+=1
done

昂?死循环?

echo ${sta[i]} 改成 echo $i ,这可好:0,01,011,0111…… 绝了。。

ps:如果用 i++ 而不是 i+=1 ,会报错 i++: 未找到命令i++ 似乎只能用在 for 循环的步长里。

于是用 declare 来固定其类型, -i 是整型:

#!/bin/sh
  
declare -i i n
read n
echo $n
i=0
while [[ $i < $n ]]
do
        read sta[i]
        echo $i
        i+=1
done

既然 read 只能读整行,那就试着分割字符串吧。可别说还真可,这里用了 for 的另一种格式,有点像 python :

#!/bin/sh
  
declare -i i n
declare -ai sta
read n
echo $n
read line
i=0
for str in $line
do
        sta[i]=$str
        echo ${sta[i]}
        i+=1
done

sta[] 是整型数组,其实不 declare 也没事。

ps: for str in $line 这里千万不能少 $ ,不然报错: 表达式中有语法错误 ,这些报错千奇百怪。

万一题目一行一个测试用例,不知道一共几个呢?木事,这样就好了:

#!/bin/sh

declare -i i

while read line
do
        i=0
        for str in $line
        do
                sta[i]=$str
                echo -n ${sta[i]}
                i+=1
        done
        echo ""
done

ps: echo 自动换行,可以用 -n 选项取消换行,也可以用和 C 里几乎一样的 printfecho -n ${sta[i]} 等价于 printf "%d" ${sta[i]}

减号呢?

咱试试倒序输出:

#!/bin/sh

for ((i = 0; i < 5; i++))
do
        read sta[i]
done

for ((j = i-1; j >= 0; j--))
do
        printf "%d " $sta[j]
done
echo ""

居然报错了: ./b.sh: 第 12 行:printf: 3[j]: 无效数字 ummm

3 是我输的 sta[0] 来着,原来少了大括号,加上就好了。

ps: 使用 echo 就能发现,如果 $sta[j] 它会误认为 $sta 加上 "[j]",显然不符合我们的希望。所以要加大括号为 ${sta[j]}

while 又如何?(显然不能改变什么)

#!/bin/sh
  
declare -i j

for ((i = 0; i < 5; i++))
do
        read sta[i]
done

j=i-1
while [[ $j >= 0 ]]
do
        printf "%d " ${sta[j]}
        j-=1
done
echo ""

报: 条件表达式中有语法错误 ,呵,居然没有 >= ,要用 -ge

改正后死循环,报: j-=1: 未找到命令 …… ???

尝试了 -= *= ,似乎只有 += 。改成 j+=-1 才 OK 。

0 是真是假?

为了控制格式,设了个 flag。

#!/bin/sh
  
declare -i flag=0

if [ $flag ]
then
        echo "T"
else
        echo "F"
fi

输出 T 。这点和 C 差的也太多了……

#!/bin/sh
  
flag=false

if [ $flag ]
then
        echo "T"
else
        echo "F"
fi

依然输出 T

#!/bin/sh
  
flag=false

if [ $flag == true ]
then
        echo "T"
else
        echo "F"
fi

一定要这样才行。

示例代码

菜鸡一个,看看笑笑就好了。
学了一天 bash ,写个简单的吧。

# PTA 1010 一元多项式求导
# lang: bash

#!/bin/bash

declare -i i j f
while read line
do
        i=f=0
        for str in $line
        do
                sta[i]=$str
                i+=1
        done

        if [ ${sta[1]} == 0 ]
        then    
                echo "0 0"
                continue
        fi      

        for ((j = 0; j < i; j+=2))
        do
                if [ ${sta[j+1]} == 0 ]
                then    
                        continue
                fi
                if [ $f == 0 ]
                then
                        f=1
                        printf "%d %d" `expr ${sta[j]} \* ${sta[j+1]}` `expr ${sta[j+1]} - 1`
                else
                        printf " %d %d" `expr ${sta[j]} \* ${sta[j+1]}` `expr ${sta[j+1]} - 1`
                fi
        done
        echo ""
done

by SDUST weilinfox
原文链接:https://www.cnblogs.com/weilinfox/p/12376525.html

猜你喜欢

转载自www.cnblogs.com/weilinfox/p/12376525.html