Losowanie danych z pliku tekstowego

0

Podpowie mi ktoś, jak z pliku tekstowego zawierającego 100 imion/nazwisk, losować do tablicy rekordow o wielkości 25000? Czy dane wczytane do tablicy mozna losować tak by wypełnił ową tablicę losowo dobranymi imieniami i nazwiskami ? Teraz wczytałem dane bezposrednio bez losowania i niestety wypełnia tablicę tyle ile jest danych w pliku a kolejne pola tablicy są puste, co jest zrozumiałe.

4

Najpierw sobie wczytaj do jakiejś tymczasowej macierzy/listy zawartość pliku, a potem losuj numerki i wypełniaj tą dużą tablicę danymi z pierwszej; Skoro masz w pliku 100 imion/nazwisk, to załaduj je do małej macierzy, następnie ustaw pętlę od 0 do 24999 i w każdej iteracji losuj numerek od 0 do 99, i do bieżącego elementu dużej tablicy kopiuj dane z małej tablicy, z elementu o wylosowanym indeksie;

Aby zmniejszyć ilość potrzebnej pamięci i przyspieszyć losowanie, w dużej tablicy (tej z 25000 elementów) przechowuj indeksy elementów z małej tablicy, fizycznie nie kopiując z niej łańcuchów; Wszystko zależy od tego co z tym chcesz dalej robić, ale tego już nie napisałeś, tak jak i nie podałeś zawartości pliku oraz deklaracji dużej tablicy.

0

Dzięki, generalnie ma być to procedura która;

Tworzącą plik binarny składający się z 25000 losowych rekordów typu tosoba. Imiona i nazwiska mają być także przydzielane losowo do rekordu z zewnętrznej listy co najmniej 100 imion i 100 nazwisk (np. z pliku tekstowego).

rekord
tosoba = record
id: longint;
Imie: string[20];
Nazwisko: string[40];
Pesel: string[11];
Płeć: typ dowolny odpowiednio interpretowany przez program
end;

Pesel mam, id też, teraz właśnie chcę losować te imiona i nazwiska. Zaraz zobaczę co wyjdzie z tego co napisałeś.

1

Treść tego zadania jest dziwna, bo:

Imiona i nazwiska mają być także przydzielane losowo do rekordu [...]

Także? To co jeszcze (prócz imienia i nazwiska) ma być losowane? Płeć? PESEL też? Ktoś się nie popisał formułując treść zadania; A co do tematu, zrób tak jak napisałem - losuj indeks elementu z pierwszej macierzy i kopiuj łańcuch z małej macierzy do dużej w odpowiednie miejsce (do odpowiedniego elementu); Pisząc "kopiuj" mam na myśli zwykłe przypisanie zamiast fizycznego kopiowania.

0

Tak płeć, pesel mają być również losowane, ale to nie jest problem, bo to już mam. Wykonam tak jak mówisz i jutro się odezwę :)

0

Wracam :)

Nie wiem czy o to chodziło, ale wyglada,że tak, ponieważ losuje imię i zapełnia całą tablicę. Wcześniej może trochę źle napisałem. Mam dwa osobne pliki Imiona i nazwiska, nie mam pojęcia dlaczego,ale przy nazwiskach wyrzuca krytyczny błąd, i kompilator sypie się cały. Nawet na próbę podmieniłem imiona na nazwiska gdzie imiona działają ładnie, ale dalej to samo. Sprawdzałem sam plik i wygląda też normalnie. Oczywiście wypisanie danych niczemu konkretnemu nie służy, tylko dla sprawdzenia poprawności sobie je wypisuje. Cały rekord i tak ma być w pliku zapisany.

Przepraszam za formatowanie kodu, ale nie mogę sobie wyrobić nawyku recznego formatowania. Generalnie też w kodzie jest kilka niepotrzebnych zmiennych, ale to również dla testów wszystko, dlatego prosiłbym o nie zwracanie na to uwagi.

Bład w załączniku.

program lista1;

{$APPTYPE CONSOLE}

uses
  SysUtils, Math;
 const
   Max_record=25000;


type
  tosoba=record
  id:longint;
  imie:string[20];
  nazwisko:string[20];
  pesel:string[11];
  plec: string[10];
  end;
    type
      tab=array[1..Max_record] of tosoba;



  var
       opcja: integer;
       meskie:textFile;
       nazwiska:textFile;
       zenskie:textFile;
       dane:textFile;
       rekordy: file of tosoba;


       tab1:tab;

            procedure losuj;
             var
                     k,nr,i,j:integer;

                     liczba:array[1..11] of integer;
                     imie:array[1..500] of string;
                     nazwisko:array[1..1000] of string;



            begin

            assign (meskie, 'male.txt');  // kojarzenie plikow
            assign (nazwiska,'nazwiska.txt');

            reset(meskie); // otwarcie plikow do odczytu
            reset(nazwiska);


                 i:=0;
              while not EOF(meskie) do
                begin

                readln(meskie, imie[i]);
                inc(i);



                for j:=1 to 25000 do
                begin
                i:=random(99)+1;
                tab1[j].imie:=imie[i];

                 end;
                    end;
                  close (meskie);
                  close (nazwiska);
           
{Kolejne ID}
            for i:=1  to Max_record  do
                begin
                  tab1[i].id:=i;
                   end;



            for i:=1 to Max_record do
                 begin

                 writeln('Id to : ' ,tab1[i].id);
                 writeln('Nazwisko to: ' ,tab1[i].nazwisko);
                 writeln('Imie to: ' ,tab1[i].imie);
                 writeln('pesel nr :  to : ');

                 for j:=1 to 11 do
                   begin
                     liczba[j]:=random (9)+1;
                     str(liczba[j],tab1[i].pesel); //zamiana 11 liczb na string
                     write(tab1[i].pesel);
                       end;

                        writeln;
                        writeln;
                      end;
                       writeln;
                       writeln;

                       end;

begin

   randomize;

  writeln(' Witaj w bazie danych- wybierz jedna z ponizszych opcji ');
  writeln('  1 - Dodaj ');
  writeln('  2 - Usun'  );
  writeln('  3 - Wyszukaj');
  writeln('  4 - Zakoncz');
    readln ( opcja);

    case (opcja) of
 1:losuj;

 end;
 readln;

end.
1
Greku napisał(a):

Przepraszam za formatowanie kodu, ale nie mogę sobie wyrobić nawyku recznego formatowania.

Przepraszam za kupę na środku pokoju, ale nie mogę sobie wyrobić nawyku chodzenia do toalety.

A wracając do kodu. To tablice masz indeksowane o 1 a robisz takiego babola:

i:=0;
while not EOF(meskie) do
begin
   readln(meskie, imie[i]);
//...

Na dodatek masz zagnieżdżone dwie pętle co powoduje, że wczytujesz tylko jedno imię z pliku (zresztą źle je wczytujesz i błędy się sypią) a następnie z pustej tablicy losujesz imiona i powtarzasz tak aż plik się nie skończy.

while not EOF(meskie) do
begin
  readln(meskie, imie[i]);
  inc(i);
  for j:=1 to 25000 do
  begin
    i:=random(99)+1;
    tab1[j].imie:=imie[i];
  end;
end;

Tylko te dwa błędy wyłowiłem bo nie mam zamiaru dokładniej analizować niesformatowanego kodu.

1

@Greku - chyba jasno wyraziłem się we wcześniejszym poście: zawartość pliku masz wczytać najpierw, a po wczytaniu zacząć losowanie i uzupełnianie dużej macierzy; Ty robisz wszystko naraz, co prowadzi do wielkiego WTFu;

I sformatuj kod, bo ciężko się go analizuje; Jak nie umiesz tego robić sam, to skorzystaj z gotowych narzędzi, przeznaczonych do tego celu; Poelcam też nauczyć się formatowania kodu na bieżąco, bo to powinien znać i stosować każdy, bez względu na stopień zaawansowania.

0

Dzięki, jest to już zrobione. Problem mam teraz z ostatnią procedurą już, ale nie bardzo wiem jak ją ugryźć.

procedura wpisujaca do tablicy dynamicznej rekordy z pliku z zakresu od N do M gdzie N i M są pozycjami w pliku binarnym podawanymi podczas działania programu. Parametrem procedury ma być tablica

wg mnie:
1 kojarzę plik binarny
2 Otwieram do zapisu i odczytu ( reset)
3 i tu padam

Jak to ugryźć?

0

Poczytaj o plikach typowanych

0

1 kojarzę plik binarny

Nie binarny, tylko typowany, bo zapewne taki masz użyć, tylko treść zadania jest nieprecyzyjna; Oczywiście nic nie stoi na przeszkodzie, aby faktycznie użyć plik binarny;

2 Otwieram do zapisu i odczytu ( reset)

A po grzyba? Masz zapisać dane do pliku to otwórz go do zapisu - Rewrite;

3 i tu padam

Czego nie wiesz? Jak zapisać dane do pliku amorficznego? Masz do dyspozycji chiciażby procedurę BlockWrite (do odczytu BlockRead); Najlepszym sposobem jest wykorzystanie strumienia klasy TFileStream do operacji na plikach; Klasa ta ma sporo możliwości i jest bardzo wygodna w użyciu.

0

Zrobione już. Może bez użycia procedur BlockWrite itd, ale działa jak należy wszystko. O samych procedurach poczytam na dniach bo nigdy z nich nie korzystałem jeszcze. Dzięki za pomoc, temat można zamknąć ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1