-2
votes

Comment localiser la colonne de données au lieu de la position de caractère n'utilise pas la boucle pour rechercher dans Perl et Bash?

Ce que je veux savoir, c'est comment localiser Atom H Emplacement (en tant que numéro de colonne au lieu de numéro de caractères) dans une chaîne / une matrice à l'aide de Perl ou de bash? J'ai essayé d'éviter des boucles inutiles de rechercher le H car mes données ont plus de millions de lignes.

J'ai des données de recherche indiquées ci-dessous p> xxx pré>

où, il y a des atomes O, H, CA et Al. Le premier atome est la cible de l'oxygène atome et le reste d'entre eux sont des voisins qui obligent avec l'oxygène cible. À l'exception du premier atome (oxygène), le nombre d'entiers avant chaque atome est l'ID d'Atom, et le numéro de flotteur après sa longueur de liaison avec le premier atome O (ID = 16652). P>

$line = 'FRAM_#     20000000      5000000(fs)  CN= 1    PRMRYTGT     16652'
        . '      O     16654      H  1.036      8140     CA  2.586'
        . '     7319     AL  1.963';
@values = split(/\s+/, $line);
my $bondlength;
my $neighbor_ID;
for (my $i = 10; $i <= $#values; $i = $+3) {
  if ($values[$i] eq 'H') {
    $neighbor_ID = $values[$i-1];
    $bondlength = $values[$i+1];
  } else {
    next;
  }


13 commentaires

Que voulez-vous, valeur après h?


Vous devez nous donner plus de détails. Pour cette ligne d'entrée, quelle sortie voulez-vous?


J'ai besoin d'obtenir l'identifiant Atom (voici h) et la longueur de la liaison entre H et l'atome cible (ici est l'oxygène).


Je demande à nouveau. Pour cette ligne d'entrée, quelle sortie voulez-vous?


@Leon toujours poster un exemple minimal, complet et vérifiable


Je veux trouver l'emplacement de H. C'est la première étape pour que je puisse analyser davantage mes données. Dans cette question, je veux trouver un lien d'hydrogène. Donc, d'abord, je dois trouver l'emplacement de H. et puis je peux obtenir l'identifiant Atom et la longueur des obligations associées. J'ai essayé d'éviter la boucle, car le coût de temps est O (n).


@Anubis, merci pour votre suggestion. J'ai ajouté les codes pour montrer ce que je veux faire.


@Dave Cross, merci pour votre question, je vous ai invité. Je veux obtenir l'emplacement de h dans un tableau. Je dois d'abord localiser H emplacement H, puis je peux obtenir l'identifiant de longueur d'aide et d'atome.


L'utilisation de regex augmentera la complexité. Quoi qu'il en soit, la ligne de saisie sera bouclée à peu près de l'outil / l'algorithme que vous choisissez.


@oguzismail merci pour votre commentaire. Que diriez-vous d'utiliser la table de hachage qui a O (1)? Je ne sais pas comment attribuer des données séparées dans un hachage. Toute suggestion?


La division des données implique au moins une boucle.


Oui. Je comprends que. Mon objectif est de réduire ces boucles inutiles. Pour une instance, si je divise la chaîne en une table correction (si je pouvais, je cherche les questions et solutions d'historique), puis je peux rechercher le H dans O (1). Toute suggestion?


@oguzismail Oui. La fonction est la même pour mes codes énumérés dans ma question. Quoi qu'il en soit, merci pour votre discussion.


4 Réponses :


0
votes
open(FH, "data.txt") or die "Can’t open data.txt: $!";

while(<FH>)
{
 if (@d=/\bO\s+(\d+)\s+H\s+(1\.[5-9]\d*|[2-9][\d.]*)/) {print "$_\n" for @d}
$ID=$d[0]
$len=$d[1]
}
each data line only results in ID, put in $d[0], and bond length, in $d[1] if is greater/equal to 1.5, of @d array

0 commentaires

0
votes

Voici votre code, légèrement reformaté pour la lisibilité (WhitSpace n'est pas en fourniture courte!)

$line = "FRAM_#     20000000      5000000(fs)  CN= 1  PRMRYTGT     16652      O      16654      H  1.036      8140     CA  2.586      7319     AL  1.963";

@values = split(/\s+/, $line);

my ($bondlength, $neighbor_ID);

for (my $i = 10; $i <= $#values; $i = $+3) {
  if ($values[$i] eq 'H') {
    $neighbor_ID = $values[$i-1];
    $bondlength = $values[$i+1];
    last; # stop looking once you've found it
  }
}


1 commentaires

Merci pour votre réforme. Oui. Cela devient plus clair dans ce cas. Malheureusement, ce n'est pas ce que je veux. J'espère trouver un autre moyen d'améliorer l'efficacité du code. Cette recherche est O (n). Pour une recherche individuelle, ce n'est pas un problème. Cependant, pour des millions de données, cela coûterait plus de temps. C'est pourquoi je veux trouver une autre façon d'éviter une telle boucle de recherche.



0
votes

Il n'est pas clair ce que représente exactement le résultat attendu pour l'entrée donnée. Si c'est la paire de chiffres avant et après la lettre h code>, vous suivrez. xxx pre>

entrée d'échantillon: p>

16654,1.036


0 commentaires

1
votes

Perl: Utilisez fidusidx code> de Liste :: Poursutils

my ($neighbour_id, $bond_length) = $line =~ /(\d+) \s+ H \s+ (\S+)/x;
return $neighbour_id if $bond_length > 1.5;


0 commentaires