Estou aprendendo Perl, mas não sei como resolver esse problema.
Eu tenho um .txt
arquivo no seguinte formato:
1 16.3346384
2 11.43483
3 1.19819
4 1.1113829
5 1.0953443
6 1.9458343
7 1.345645
8 1.3847385794
9 1.3534344
10 2.1117454
11 1.17465
12 1.4587485
A primeira coluna contém apenas o número da linha, que não interessa aqui, mas está presente no arquivo; os valores na segunda coluna são a parte relevante.
Quero gerar a sequência contígua mais longa de linhas que apresente números menores que 2,00 na segunda coluna. Para o exemplo acima, seriam as linhas 3 a 9 e a saída deveria ser:
1.19819
1.1113829
1.0953443
1.9458343
1.345645
1.3847385794
1.3534344
Perl uma linha:
Multilinha para melhor legibilidade:
Um forro com
awk
:Multilinha:
Esta não é uma tarefa tão trivial. Também há debate se fornecer um programa finalizado é útil para outros aprenderem a resolver um problema em uma linguagem de programação, mas acredito que tem seus méritos, então proponho o seguinte programa (vamos chamá-lo de
findlongestsequence.pl
:Você pode chamar o programa como
Isso primeiro interpretará os parâmetros da linha de comando usando
Getopt::Long
.Em seguida, ele abrirá o arquivo e o lerá em linha, mantendo um contador de linha em
$lineno
. Cada linha será dividida em colunas no espaço em branco.$limit
($ingroup
é zero), mas encontrar uma linha adequada, ele registrará que agora está em tal grupo ($ingroup
definido como um), armazenará o início do grupo$groupstart
e começará a armazenar em buffer o valores da coluna 2 em uma matriz@groupbuf
.$limit
, ele reconhecerá o final do grupo e calculará seu comprimento. Se for maior que o grupo mais longo registrado anteriormente, o conteúdo (@groupbuf
) e o comprimento ($currlength
) do novo grupo mais longo serão copiados para@longestgroup
e$maxlength
, respectivamente.Como é possível que um grupo seja encerrado no final do arquivo em vez de uma linha com valor >
$limit
, execute esta verificação também se$ingroup
for verdadeiro no final do arquivo.No final, o conteúdo de
@longestgroup
é impresso\n
como separador de token.Usando qualquer awk:
Talvez algo como:
Ou se, em vez do número de linhas nesse maior grupo de linhas, você quiser ver essas linhas de acordo com as edições mais recentes da sua pergunta:
Se, como alguém editou na sua pergunta, os números das linhas fazem parte dos dados, adicione a
-a
opção (modo awk onde os registros são divididos no@F
array) e substitua$_
(o registro inteiro) por$F[1]
(o segundo campo,$F[0]
sendo o primeiro).Solução idiomática utilizando
<>
para leitura a entrada e o operador flipflop.Usando Raku (anteriormente conhecido como Perl_6)
OU:
Aqui estão as respostas escritas em Raku, um membro da família Perl de linguagens de programação. Raku apresenta números racionais , caso você precise manter a precisão ao realizar operações matemáticas simples (por exemplo
say 0.1 + 0.2 - 0.3;
).A primeira resposta lê linhas
$_
usando-ne
sinalizadores linewise sem impressão automática. Tanto a@max
quanto@tmp
array são declarados. A linha é quebrada em espaços em brancowords
e.=
salva novamente em$_
. Se (if
instrução) a.[1]
segunda coluna satisfizer os critérios, os valores serãopush
inseridos na@tmp
matriz. Caso contrário, o@tmp
array substitui o@max
array se tiver maiselems
(elementos). Independentemente disso, a@tmp
matriz estáEmpty
(esvaziada). ParaEND
garantir que uma sequência contígua final seja/não a mais longa, o operador ternário Test??
True!!
False de Raku é usado para determinarput
a matriz mais longa.A segunda resposta é semelhante à primeira, exceto que
when
são usadas declarações. No Raku, uma vezwhen
satisfeita uma condicional, seu bloco associado é executado e o controle reverte para o bloco externo, ignorando quaisquer instruçõeswhen
or subsequentesdefault
. Veja a referência abaixo.Entrada de amostra:
Saída de amostra:
NOTA: O código acima produzirá a primeira sequência contígua mais longa no caso de empate.
https://docs.raku.org/syntax/when
https://docs.raku.org/
https://raku.org
Se você não quiser engenharia excessiva, tente esta linha de comando de linha única:
awk
esort
.