Saat ini untuk sebuah tugas, saya bekerja dengan file input yang memberikan kasus uji terkait Matrix (Perkalian Matriks) yaitu, contoh file input ->

N M
1 3 5 ... 6 (M columns)
....
5 4 2 ... 1 (N rows)

Saya menggunakan read() sederhana untuk mengaksesnya sampai sekarang, tetapi ini tidak efisien untuk file besar berukuran> 10^2. Jadi saya ingin tahu apakah ada cara untuk menggunakan proses untuk melakukan ini secara paralel.
Saya juga berpikir untuk menggunakan beberapa pembaca IO berdasarkan baris, sehingga setiap proses dapat membaca segmen file yang berbeda tetapi tidak dapat menemukan sumber daya yang bermanfaat.

Terima kasih.

PS: Kode saat ini menggunakan ini:

io:fread(IoDev, "", "~d")
1
Shivam Mangale 7 April 2021, 21:32

2 jawaban

Jawaban Terbaik

Apakah Anda mempertimbangkan untuk menggunakan modul re? Saya tidak melakukan tes kinerja, tetapi mungkin efisien. Dalam contoh berikut saya tidak menggunakan baris "M N" pertama. Jadi saya tidak memasukkannya ke dalam file matrix.txt.

Berkas matriks:

1 2 3 4 5 6 7 8 9
11 12 13 14 15 16 17 18 19
21 22 23 24 25 26 27 28 29
31 32 33 34 35 36 37 38 39

Saya membuat konversi di shell

1> {ok,B} = file:read_file("matrix.txt"). % read the complete file and store it in a binary
{ok,<<"1 2 3 4 5 6 7 8 9\r\n11 12 13 14 15 16 17 18 19\r\n21 22 23 24 25 26 27 28 29\r\n31 32 33 34 35 36 37 38 39">>}
2> {ok,ML} = re:compile("[\r\n]+"). % to split the complete binary in a list a binary, one for each line
{ok,{re_pattern,0,0,0,
                <<69,82,67,80,105,0,0,0,0,0,0,0,1,8,0,0,255,255,255,255,
                  255,255,...>>}}
3> {ok,MN} = re:compile("[ ]+"). % to split the line into binaries one for each integer
{ok,{re_pattern,0,0,0,
                <<69,82,67,80,73,0,0,0,0,0,0,0,17,0,0,0,255,255,255,255,
                  255,255,...>>}}
4> % a function to split a line and convert each chunk into integer
4> F = fun(Line) -> Nums = re:split(Line,MN), [binary_to_integer(N) || N <- Nums] end.
#Fun<erl_eval.7.126501267>
5> Lines = re:split(B,ML). % split the file into lines
[<<"1 2 3 4 5 6 7 8 9">>,<<"11 12 13 14 15 16 17 18 19">>,
 <<"21 22 23 24 25 26 27 28 29">>,
 <<"31 32 33 34 35 36 37 38 39">>]
6> lists:map(F,Lines). % map the function to each lines
[[1,2,3,4,5,6,7,8,9],
 [11,12,13,14,15,16,17,18,19],
 [21,22,23,24,25,26,27,28,29],
 [31,32,33,34,35,36,37,38,39]]
7> 

Jika Anda ingin memeriksa ukuran matriks, Anda dapat mengganti baris terakhir dengan:

[[NbRows,NbCols]|Matrix] = lists:map(F,Lines),
case (length(Matrix) == NbRows) andalso 
      lists:foldl(fun(X,Acc) -> Acc andalso (length(X) == NbCols) end,true,Matrix) of
    true -> {ok,Matrix};
    _ -> {error_size,Matrix}
end.
1
Pascal 8 April 2021, 21:57

apakah ada cara untuk menggunakan proses untuk melakukan ini secara paralel.

Tentu saja.

Saya juga berpikir untuk menggunakan beberapa pembaca IO berdasarkan baris, sehingga setiap proses dapat membaca segmen file yang berbeda tetapi tidak dapat menemukan sumber daya yang bermanfaat.

Anda tidak mencari posisi dalam file per baris, melainkan Anda mencari posisi byte. Meskipun sebuah file mungkin terlihat seperti sekumpulan baris, sebuah file sebenarnya hanyalah satu rangkaian karakter yang panjang. Oleh karena itu, Anda perlu mencari tahu posisi byte yang ingin Anda cari dalam file.

Lihat file:position, file:pread.

0
7stud 7 April 2021, 20:45