Extraindo subsequências inteiras que começam com um número repetido

Extraindo subsequências inteiras que começam com um número repetido

Eu tenho um arquivo que contém uma única coluna de números inteiros. Quero extrair deste arquivo a lista de todas as subsequências contíguas (ou seja, subsequências que ocorrem em ordem consecutiva) que começam com o mesmo número duas vezes seguidas e que têm comprimento de 12 números inteiros (incluindo subsequências sobrepostas).

Além disso, quaisquer linhas não inteiras no arquivo devem ser ignoradas/removidas e se alguma sequência atingir o final da entrada antes de 12 números inteiros serem alcançados, a sequência abreviada ainda deverá ser gerada.

Por exemplo, suponha que meu arquivo de entrada contenha os seguintes dados:

1
junk
1

1
2
3
4
4
5
6
7
8
9
10
11
12
13
14
15
15
16

Então a solução deve produzir a seguinte saída:

1 1 1 2 3 4 4 5 6 7 8 9
1 1 2 3 4 4 5 6 7 8 9 10
4 4 5 6 7 8 9 10 11 12 13 14
15 15 16

Observe que a junklinha e a linha vazia são ignoradas, de modo que as três primeiras 1linhas são tratadas como contíguas.

Responder1

Aqui está um script Python que faz o que você deseja:

#!/usr/bin/env python2
# -*- coding: ascii -*-
"""extract_subsequences.py"""

import sys
import re

# Open the file
with open(sys.argv[1]) as file_handle:

    # Read the data from the file
    # Remove white-space and ignore non-integers
    numbers = [
        line.strip()
        for line in file_handle.readlines()
        if re.match("^\d+$", line) 
    ]

    # Set a lower bound so that we can output multiple lists
    lower_bound = 0
    while lower_bound < len(numbers)-1:

        # Find the "start index" where the same number
        # occurs twice at consecutive locations
        start_index = -1 
        for i in range(lower_bound, len(numbers)-1):
            if numbers[i] == numbers[i+1]:
                start_index = i
                break

        # If a "start index" is found, print out the two rows
        # values and the next 10 rows as well
        if start_index >= lower_bound:
            upper_bound = min(start_index+12, len(numbers))
            print(' '.join(numbers[start_index:upper_bound]))

            # Update the lower bound
            lower_bound = start_index + 1

        # If no "start index" is found then we're done
        else:
            break

Suponha que seus dados estejam em um arquivo chamado data.txt. Então você poderia executar este script assim:

python extract_subsequences.py data.txt

Suponha que seu arquivo de entrada data.txtseja semelhante ao seguinte:

1
1
1
2
3
4
5
6
7
8
9
10
11
12

Então sua saída ficaria assim:

1 1 1 2 3 4 5 6 7 8 9 10
1 1 2 3 4 5 6 7 8 9 10 11

Para salvar a saída em um arquivo, use o redirecionamento de saída:

python extract_subsequences.py data.txt > output.txt

Responder2

AWKabordagem:

Considerando apenas 2 números consecutivos idênticos encontrados inicialmente, ou seja, é adequado para extrações múltiplas, mas sem considerar a condição de que 2 números consecutivos idênticos possam estar dentro de uma sequência de 10 números seguida sob uma fatia processada.

awk 'NR==n && $1==v{ print v ORS $1 > "file"++c; tail=n+11; next }
     { v=$1; n=NR+1 }NR<tail{ print > "file"c }' file

Responder3

Primeira variante - O(n)

awk '
/^[0-9]+$/{
    arr[cnt++] = $0;
}

END {
    for(i = 1; i < cnt; i++) {
        if(arr[i] != arr[i - 1])
            continue;

        last_element = i + 11; 
        for(j = i - 1; j < cnt && j < last_element; j++) {
            printf arr[j] " ";
        }
        print "";
    }
}' input.txt

Segunda variante - O(n * n)

awk '
BEGIN {
    cnt = 0;
}

/^[0-9]+$/{
    if(prev == $0) {
        arr[cnt] = prev;
        cnt_arr[cnt]++;
        cnt++;
    }
    
    for(i = 0; i < cnt; i++) {
        if(cnt_arr[i] < 12) {
            arr[i] = arr[i] " " $0; 
            cnt_arr[i]++;
        }
    }

    prev = $0;        
}

END {
    for(i = 0; i < cnt; i++)
        print arr[i];
}' input.txt

Saída

1 1 1 2 3 4 4 5 6 7 8 9
1 1 2 3 4 4 5 6 7 8 9 10
4 4 5 6 7 8 9 10 11 12 13 14
15 15 16

informação relacionada