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.
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.
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ś.
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.
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ę :)
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.
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.
@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.
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źć?
Poczytaj o plikach typowanych
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.
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ąć ;)