Thứ Tư, 25 tháng 12, 2013

Đọc dữ liệu từ tệp vào mảng biết hai kích thước



Đọc dữ liệu từ tệp vào mảng biết hai kích thước
               Đọc dữ liệu kiểu nguyên từ một tệp văn bản vào một mảng hai chiều.
Tệp có cấu trúc như sau:
- Hai số đầu tiên n, m là kích thước của mảng gồm n dòng và m cột.
- Tiếp đến là các dữ liệu ghi liên tiếp nhau theo từng dòng của mảng.
- Các số cách nhau ít nhất một dấu cách.
Thí dụ:
2 3 -1 4 5 3 7 1
cho biết mảng có n = 2 dòng và m = 3 cột với dữ liệu như sau:
-1
4
5
3
7
1
Đặc tả
Ta viết hàm Doc cho giá trị true nếu đọc được dữ liệu. Chú ý rằng dữ liệu vào là đúng do đó không cần kiểm tra tính đúng đắn của chúng. Như vậy Doc sẽ cho giá trị false trong trường hợp không mở được file, do ghi sai đường dẫn hoặc file không được tạo lập từ trước.
Chỉ thị {$I-} yêu cầu hệ thống chỉ ghi nhận chứ không bắt các lỗi vào/ra, tức là không dừng sự thực hiện chương trình. Biến hệ thống IORESULT sẽ ghi nhận số hiệu lỗi. Nếu IORESULT=0 thì thao tác vào ra không sinh lỗi, ngược lại, nếu IORESULT ≠ 0 tức là đã có lỗi.
Chỉ thị {$I+} yêu cầu hệ thống bắt mọi lỗi vào/ra. Như vậy, dòng lệnh
{$I-} reset(f); {$I+}
sẽ được hiểu như sau:
Thoạt tiên ta yêu cầu hệ thống bỏ chế độ bắt lỗi vào/ra {$I-}. Sau đó thực hiện lệnh mở tệp để đọc reset(f).Tiếp đến đặt lại chế độ bắt lỗi {$I+}.
(*  Pascal  *)
uses crt;
const MN = 100;
var a: array[1..MN,1..MN] of integer;
m,n: integer;
Function Doc(fn: string): Boolean;
var
      f: text;
      i, j: integer;
begin
Doc := false; assign(f,fn);
{$I-} reset(f); {$I+}
if IORESULT <> 0 then exit; {không mở được file}
read(f,n,m);{doc kich thuoc n va m cua mang }
for i := 1 to n do
for j:= 1 to m do
read(f,a[i, j]);
close(f);
Doc := true;
end;
procedure Xem(n,m: integer); Hiển thị mảng 2 chiều, tự viết
BEGIN
if Doc('DATA.INP') then Xem(n,m)
else write('Khong mo duoc tep ');
readln;
END.


Giải thích của gia sư tin học
Trong các máy tính hiện đại, bộ nhớ trong RAM đủ lớn để có thể chứa toàn bộ dữ liệu trong hầu hết các file input vì thế với môi trường C# .NET bạn nên đọc một lần dữ liệu từ các file này. Hàm Doc cho ra mảng nguyên hai chiều. Nếu file không tồn tại, hàm cho ra giá trị null. Bạn cần chuẩn bị trước file input với tên Data.inp và ghi vào thư mục BIN\DEBUG trong Project hiện hành. Nếu ghi file vào thư mục khác thì trong tham biến fn phải ghi chi tiết đường dẫn, thí dụ “D:\\MyDIR\\Data.inp”. Khi viết đường dẫn, thay vì viết dấu “\” ta phải viết hai dấu đó, tức là “\\” vì bản thân dấu “\” trong đóng vai trò báo hiệu kí tự đứng sát sau nó là kí tự điều khiển, thí dụ, “\n” biểu thị dấu xuống dòng. Bạn cũng có thể viết dấu đổi mức @ cạnh đường dẫn để chỉ thị rằng bạn muốn dùng một dấu “\” thay vì hai dấu, thí dụ,
@“D:\MyDIR\Data.inp”
Lệnh File.ReadAllText(fn) mở file với đường dẫn fn đọc toàn bộ dữ liệu một lần vào một biến string sau đó tự động đóng file.
Lệnh  Split(cc,StringSplitOptions.RemoveEmptyEntries)
tách các đơn vị trong biến string để ghi vào biến string[] ss đồng thời bỏ đi các dấu trắng mô tả trong biến cc, bao gồm dấu cách ‘ ‘, dấu xuống dòng ‘\n’, dấu tab ‘\t’ và dấu kết RETURN ‘\r’, cuối cùng loại bỏ các đơn vị rỗng, tức là các string không chứa kí tự nào (Length = 0).
Lệnh      int[] c = Array.ConvertAll(ss,
      New Converter<string,int>(int.Parse));
chuyển các string trong ss sang dạng số nguyên và ghi vào mảng nguyên (một chiều) c. Đến đây toàn bộ dữ liệu trong file input fn đã được đọc và ghi vào mảng nguyên c. Các mảng trong C# được đánh chỉ dẫn từ 0 đến Length-1. Theo điều kiện của đầu bài c[0] chứa giá trị n, c[1] chứa giá trị m, từ c[2] trở đi chứa lần lượt  các giá trị trên các dòng của mảng hai chiều.
 

Không có nhận xét nào:

Đăng nhận xét