分组发现

时间:2011-12-26 22:25:16

标签: awk

我有这种记录(行):

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

说明:

  • group:由0-s(零)
  • 分隔的数字集合
  • 子组:由组中的本地最小值分隔的数字集合
  • 本地最小值:前后的数字更大

在上面的例子中,有3组和7个子组,即

  • 组:1 4 8 2 3 7 9 3 4 8 9 4 7 9 1,2 5 8 2 4 5 6 1,2 4 8 9
  • 子组:1 4 8,3 7 9,4 8 9,7 9 1,2 5 8,4 5 6 1,2 4 8 9(这最后与组本身相同)

所以,在这些记录中我必须

  • 找到最小值(打印出来:2,3,4,2)
  • 这些子组的大小(字符数)
  • 组中子组数量的位置

我已经开始写点什么,但我被困在这里......

任何人都可以帮我解决这个问题吗?

以下是目前的代码:

#!/usr/bin/awk -f

{
    db = split($0,a,/( 0)+ */)
    for (i=1; i<=db; i++) {
        split_at_max(a[i])
        for (j=1; j<=ret_count; j++) {
            print ""
            for (k=1; k<=maximums[j]; k++) {
                print ret[j,k]
            }
        }
    }
}

function split_at_max(x) {

    m_db = split(x,values," ")
    for (mx in ret) {
        delete ret[mx]
    }
    ret_count = 1
    ret_curr_db = 0
    for (mi=2; mi<m_db; mi++) {
        ret_curr_db++
        ret[ret_count,ret_curr_db] = values[mi-1]

        if ( (values[mi-1] <= values[mi]) &&
              (values[mi] >= values[mi+1]) &&
              (values[mi+1] <= values[mi+2]) ) {
            maximums[ret_count] = ret_curr_db
            ret_count++
            ret_curr_db = 0
        }
    }
    ret_curr_db++
    ret[ret_count,ret_curr_db] = values[mi-1]
    ret_curr_db++
    ret[ret_count,ret_curr_db] = values[mi]

    maximums[ret_count] = ret_curr_db

}

1 个答案:

答案 0 :(得分:3)

有趣的任务。

写了一个快速而又脏的awk脚本。应该有很多优化空间。我不知道你期待什么样的输出...

awk -v RS="0" 'NF>1{

delete g;
print "group:";
    for(i=1;i<=NF;i++){
        printf $i" ";
        g[i]=$i
    } 
    print "";
    t=1;

    delete m;

    for(i=2;i<length(g);i++){
        if(g[i-1]>g[i] && g[i]<g[i+1]) {
            print "found minima:"g[i]
            m[t]=i;
            t++;
            }
    } 
    if(length(m)>0){
    s=0;

    for(x=1;x<=length(m);x++){
            printf "sub-group: "

        for(i=s+1;i<m[x];i++){
            printf g[i]" "
            s=m[x];
        }

        print "";
        if(x+1>length(m)){
            printf "sub-group: ";
            for(i=s+1;i<=length(g);i++)
                printf g[i]" "
            print "";
        }
    }
    }else{
    print "no minima found. sub-group is the same as group:"
    printf "sub-group: "
        for(i=1;i<=NF;i++){
        printf $i" ";
        g[i]=$i
    } 

}
    print "\n-----------------------------" 
} yourFile

示例输入的输出:

group:
1 4 8 2 3 7 9 3 4 8 9 4 7 9 1 
found minima:2
found minima:3
found minima:4
sub-group: 1 4 8 
sub-group: 3 7 9 
sub-group: 4 8 9 
sub-group: 7 9 1 

-----------------------------
group:
2 5 8 2 4 5 6 1 
found minima:2
sub-group: 2 5 8 
sub-group: 4 5 6 1 

-----------------------------
group:
2 4 8 9 
no minima found. sub-group is the same as group:
sub-group: 2 4 8 9 
-----------------------------

<强>更新

修复那些“特殊”元素,如20,30,40 ......

仍然快速而肮脏:

将上面的awk脚本更改为

sed 's/^0$//g' yourFile | awk -v RS="" [following codes are the same as above]......

然后输出是:

group:
6 63 81 31 37 44 20 
found minima:31
sub-group: 6 63 81 
sub-group: 37 44 20 

-----------------------------