Поиск подгруппы - PullRequest
       7

Поиск подгруппы

1 голос
/ 27 декабря 2011

У меня есть такие записи (строки):

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

Определения:

  • группа: набор чисел, разделенных нулями (нулями)
  • подгруппа: набор чисел, разделенных локальными минимумами в группах
  • локальный минимум: числа до и после него больше

В приведенном выше примере есть 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 Ответ

3 голосов
/ 27 декабря 2011

интересное задание.

написал быстрый и грязный скрипт на 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 

-----------------------------
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...