Strona 2 z 3 PierwszyPierwszy 123 OstatniOstatni
Pokaż wyniki 11 do 20 z 22

Temat: [Perl]wczytywanie liczb do tablicy

  1. #11

    Domyślnie

    Cytat Napisał TQM Zobacz post
    Sorry, nie czytam kodu bo blad jest gdzie indziej.

    == dziala dla liczb
    eq dziala dla stringow

    ... ale Twoje pliki nie maja identycznych linii, bo jedno ma hh:mm:ss a drugie ma hh:mm:ss.nnn, wiec nie mozna ich porownac w zaden sposob bo na 10000% nie beda sobie rowne :-)

    Co potrzebujesz to wyrazenie regularne, czyli ze linia z drugiego pliku musi zaczynac sie od linii z pierwszego. w skrocie:
    ^
    Kod:
    if ($druga =~ /^$pierwsza/) { print "Dopasowanie OK\n" };
    Czy w takiej sytuacji potrzebuje jesze funkcji, ktora bedzie zmieniala wartosc na posatc daty?

    zastosowalam wyrazenie regularne, ktore powyzej napisales:
    Kod:
    if ($date[$i]->[0] =~/^$date2[$j]->[1]/)
    ale wyskakuje blad:
    Use of uninitialized value in pattern match

    Czy w ogole w wyrazeniu regularnym moge zastosowac referencje? hmmm
    Ostatnio edytowane przez Gosik : 01-14-2013 - 01:23

  2. #12
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Mozesz, oczywiscie, tak dlugo jak dlugo zmienna ma sens.
    Regex'y pomagaja i to w wielu sytuacjach - to bedzie jeden z nich

    Wybacz ze pojde na calosc ale najszybsze rozwiazanie (bardziej zlozone) jest takie:

    Kod:
    # zawartosc plikow wczytana do tablic jednowymiarowych - wiersz pliku = wiersz tabeli
    chomp(@date1 = <PLIK1>);
    chomp(@date2 = <PLIK2>);
    
    #*dla kazdego elementu w @date1 znajdzmy pasujace wiersze w @date2
    map {
      my @pasujace = grep(/^$_/, @date2);
      foreach my $pasuje (@pasujace) {
        print "$_,$pasuje\n";
      }
    } @date1;
    map{} to odpowiednik petli foreach, grep() pozwala wybrac elementy z tablicy jesli spelniaja warunek - calosc w manualu
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  3. #13

    Domyślnie

    Czyli mam rozumiec, ze czegos takiego nie moge zrobic?

    Kod:
     if ($date[$i]->[0] =~/^$date2[$j]->[1]/)

  4. #14

    Domyślnie

    Dobra. W ten sposob mi nie wychodzi zadanie, wiec probuje w inny.

    Wczytuje kolumny z danymi do tablic i kolejno pierwsza kolumne (te z godzinami) dziele wg ':'
    Kod:
    my @tab1;
    my @tab2;
    my @time;
    open(K, 'plik2.txt');
    while (<K>) {
        chomp $_;
        my $w = $_;
        my @div = split(' ', $w);
        push ( @tab1, $div[0]);
        push ( @tab2, $div[1]);
            
        for (my $i=1; $i<=$#tab1; ++$i){
         @podz = split(':',$tab1[$i]);
        push (@time, @podz);
        }
    }
    
    close(K);
    Teraz mam pytanie jak zrobic, gdy tab1 jest postaci
    12:01:11
    12:01:12
    12:01:13

    By tablica time byla postaci:
    120111
    120112
    120113

    Uzylam funkcji join:
    Kod:
    print join '' , @time, "\n";
    ale wartosci wyswietlane sa w jednej linni, tzn. bez przejscia do nowego wiersza.
    Ostatnio edytowane przez Gosik : 01-16-2013 - 22:52

  5. #15

    Domyślnie

    Cytat Napisał Gosik Zobacz post
    Dobra. W ten sposob mi nie wychodzi zadanie, wiec probuje w inny.

    Teraz mam pytanie jak zrobic, gdy tab1 jest postaci
    12:01:11
    12:01:12
    12:01:13

    By tablica time byla postaci:
    120111
    120112
    120113

    Uzylam funkcji join:
    Kod:
    print join '' , @time, "\n";
    ale wartosci wyswietlane sa w jednej linni, tzn. bez przejscia do nowego wiersza.
    Ok. ten problem udalo mi sie rozwiazac.

    Teraz wrocialam to Twojego rozwiazania!

    Kod:
    #*dla kazdego elementu w @date1 znajdzmy pasujace wiersze w @date2
    map { 
        my @pasujace = grep(/^$_/, @date2);
      foreach my $pasuje (@pasujace) {
        open (PLIK,'>>plik.txt');
        print PLIK "$pasuje\n";
        close PLIK;
      }
    } @date1;
    NIe wiem dlaczego, ale po zainplementowaniu tego koldu, wyswietla mi tylko wszystkie elementy @date2.

    Czyli

  6. #16

    Domyślnie

    Dobra. Dalej kombinuje:

    Kod:
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    my @date1;
    my @date2;
    open (K, 'plik1.txt'); while (<K>) {
    open (P, 'plik2.txt'); while (<P>) {
    
    chomp(@date1 = <K>);
    chomp(@date2 = <P>);
    
     }
    }
    
    close(K);
    close(P);
    
    my @pasuje;
    
      foreach (@date1) {
      @pasuje = grep(/^$_/, @date2);
      }
      print @pasuje;
    Czy ktos z Was moze mi wyjasnic dlaczego moj kod nie porownuje wierszy tablicy date1 i date2, lecz wyswietla wszystkie elementy tablicy date2?

    Plik1 ma postac:
    13:26:10
    13:26:11
    13:26:12
    13:26:13
    13:26:14
    13:26:15
    13:26:20

    Natomiast plik2:
    13:26:07.1
    13:26:08.1
    13:26:09.1
    13:26:10.1
    13:26:11.1
    13:26:12.1
    13:26:13.1
    13:26:14.1
    13:26:15.1
    13:26:16.1

    Bede bardzo wdzieczna za pomoc!

  7. #17
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Nie dzialal dlatego ze ciagle w petli nadpisujesz @pasuje a wyswietlasz awrtosc na samym koncu po zakonczeniu petli wiec jesli ostatni wiersz nie pasuje to masz pusta tablice do wyswietlenia.

    Zamien @pasuje = grep(/^$_/, @date2); na push @pasuje, grep(/^$_/, @date2); i powinno chodzic
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

  8. #18

    Domyślnie

    Cytat Napisał TQM Zobacz post
    Nie dzialal dlatego ze ciagle w petli nadpisujesz @pasuje a wyswietlasz awrtosc na samym koncu po zakonczeniu petli wiec jesli ostatni wiersz nie pasuje to masz pusta tablice do wyswietlenia.

    Zamien @pasuje = grep(/^$_/, @date2); na push @pasuje, grep(/^$_/, @date2); i powinno chodzic
    Tez tak probowalam, ale lipa.

    Mam wrazenie, ze nic nie jest podstawiane, za S_

    Teraz mam taki efekt:
    13:26:08.1 13:26:09.1 13:26:10.1 13:26:11.1 13:26:12.1 13:26:13.1 13:26:14.1 13:26:15.1 13:26:16.1 13:26:17.1 13:26:08.1 13:26:09.1 13:26:10.1 , itd

    Czyli wyswietlana jest cala tablica date2, tyle razy ile jest wierszy w date1.
    Ostatnio edytowane przez Gosik : 01-21-2013 - 08:02

  9. #19

    Domyślnie

    ok, juz doszlam do tego dlaczego tak sie dzieje!

    Petla foreach powinna wygladac nastepujaco:

    Kod:
    foreach my $date (@date1){
            push @match, grep (/^$date/, @date2);
    }

    Jednakże grep nie uwzględnia faktu, iż w @date2 są godziny podane z kropką, tzn.: 13:26:07.1.
    W związku z tym nic nie jest wyświetlane.

    Czy jest jakiś sposób, by z tego wybrnąć?

  10. #20
    Zarejestrowany
    Jun 2006
    Skąd
    rand(.eu)
    Postów
    8,748

    Domyślnie

    Nie rozumiem na prawde w czym problem - zobacz co robi regex. Podalas ze chcesz dopasowac linie, nie ze chcesz usunac ulamki sekundy.
    ctrl-alt-del.cc - soft reset site for IT admins and other staff :-)

Zasady Postowania

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •  
Subskrybuj