力扣 192. 转置文件 解决之道

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

题目

image.png

问题解决

方案1

看到这种问题,第一想到的是,awk的二维数组(awk 并不支持二维数组,只是用一维数组模拟而来的),可以将问题数据存入 数组中,数据格式如下 image.png

换种输出方式,即可达到题中所述(其实数组数据并未改变) image.png

如何获取数据的 列数 和 行数呢? 引入 awk 内置变量 NF: 列数 NR: 行数

于是乎,编写脚本如下

awk '
{
        for (i=1;i<=NF;i++) {
                data[NR,i] = $i
        }
}
END {
        for (i=1;i<=NF;i++) {
                for (j=1;j<=NR;j++) {
                        printf("%s ",data[j,i])
                }
                printf("\n")
        }
}
' file.txt

提交代码却发现抛错了 image.png

经过仔细的比对,我发现,自己脚本输出的有一个空格 , 而黑色测试中的,并没有该空格,这。。。从提交记录或者报错界面上看,怎么能够发现的了呢(果然 空格 才是最大的bug吧。。。前些天刚栽了一波坑,这次又来。。。)

无奈,又改写代码,将最后一列的空格删除掉 代码如下

awk '
{
        for (i=1;i<=NF;i++) {
                data[NR,i] = $i
        }
}
END {
        for (i=1;i<=NF;i++) {
                for (j=1;j<NR;j++) {
                        printf("%s ",data[j,i])
                }
                printf("%s\n",data[j,i])
        }
}
' file.txt

再次提交,通过了。

方案2

对于方案1 中的暴力求解,太蠢了,所以想寻求有没有一种不用存储其值的方案

假设我能够取出第一列,并且将它转换为 一行,不就解决了么?

元素数据

name age
alice 21
ryan 30

脚本

cat file.txt | awk '{print $1}' | tr -t '\n' ' '

结果

name alice ryan

赞!

新的问题来了,我怎么样求文件的列数呢?

如1 所示,awk NF 可以求出 列数,我们于是乎,可以这么写

awk '{print NF}' file.txt

输出的结果

2
2
2

这明显不是我们想要的,我们想要第一行即可,我们可以这么写 awk '{print NF}' file.txt | head -n 1

其实还可以这么写 awk '{if(NR==1){print NF;exit}}' file.txt

判断是否为第一行,若为第一行,则求出列数,并且退出awk

好,我们组装一下该脚本,即为

#!/bin/bash

readonly fileName="file.txt"

column=`awk '{if(NR==1){print NF;exit}}' $fileName`

for i in `seq $column`
do
        awk "{print \$$i}"  $fileName | tr -t '\n' ' '  | sed 's#[ ]*$##g'
        echo  ""
done

至于 sed 's#[ ]*$##g其实是将每行最后的空格给替换掉,至于为什么,如方案1 错误所示。 readonly是只读变量,也可以写为: declare -r

肯定还有更为简单的方法,算了,不想了。 溜了,溜了

执行效率

对比2个方案的执行效率 方案1 image.png

方案2 image.png

posted @ 2022-03-23 17:58  pdudos  阅读(0)  评论(0)    收藏  举报  来源