Nhập, xuất ma trận bằng con trỏ

Nhập, xuất ma trận bằng con trỏ thì e biết nhưng mà với yêu cầu hàm như thế này thì chưa biết làm sao. Bác nào giúp e với !!!
Xuất ra đúng dạng ma trận, ví dụ 2 dòng, 3 cột

1 2 3
4 5 6

Xây dựng hàm nhập một ma trận các số nguyên (mảng động). Xây dựng ĐÚNG nguyên
mẫu sau: void Nhap(int*&, int) hoặc void Nhap(int*, int)
2) Xây dựng hàm xuất một ma trận các số nguyên. Xây dựng ĐÚNG nguyên mẫu sau:
void Xuat(int*, int)

Sao hàm chỉ có 2 tham số nhỉ?
Đúng ra là phải 3 tham số chứ:

  • Con trỏ (tham chiếu) đến ma trận.
  • Số dòng.
  • Số cột.

:thinking:

4 Likes

V mới khó anh ơi :v, chứ có sẵn như anh nói thì có gì là khó nữa :v. Đề này là của HCMUS - K19 đó anh

Đề này chắc là cho số dòng làm tham số thứ 2 của void Nhap và Xuat nhỉ.

Về cơ bản là không có gì là không thể, chỉ là báo hiệu code sẽ phức tạp và xấu.


Mò mẫm đề 1 tí:

Nếu tham số thứ 2 là số dòng thì cứ bắt tay vào làm.

mã giả vờ
void Nhap(int* _matrix, int _rows) {
    for (int i = 0; i < _rows; i++) {
        char* line;
        // đọc 1 dòng vào biến line
        // tách line thành mảng các số
        int* new_row = break_line_to_numbers(line);
        int _cols = sizeof(new_row) / sizeof(new_row[0]);
        
        // magic là đây: rã mảng 2 chiều thành 1 chiều rồi làm như mảng 2 chiều thật
        // nối tiếp mảng new_row vào đuôi _matrix từ vị trí (i * _cols) đến ((i+1) * _cols - 1)
    }
}
void Xuat(int* _matrix, int _rows) {
    int _cols = (sizeof(_matrix) / sizeof(_matrix[0])) / _rows;
    for (int i = 0; i < _rows; i++) {
        for (int j = 0; j < _cols; j++) {
             // tiếp tục magic trên 
             printf("%d ", _matrix[i * _cols + j];
        }
        printf("\n");
    }
}

Nếu tham số thứ 2 là số cột thì làm gần tương tự.

tìm điểm khác biệt

Hàm Nhap() lúc này sẽ viết 1 vòng for đọc từng dòng cho đến khi không thể đọc được nữa, có 1 biến _rows sẽ tăng dần, quy trình còn lại thì y hệt trường hợp trên.

Nếu tham số thứ 2 là số khác thì đọc đề chửi đề xé đề đi về thôi chứ còn làm gì nữa.

3 Likes

e code như này, ra kết quả đúng như yêu cầu, anh thấy có được không ?
e sẽ dùng cái a[0] để lưu lại số cột, còn giá trị bắt đầu lưu từ a[1]

void nhap(int*& a, int dong)
{
	int cot = 0;
	cout << "Nhap so cot: ";
	cin >> cot;
	a = new int[dong * cot + 1];
	a[0] = cot;

	for (int i = 1; i < dong * cot + 1; i++)
	{
		cout << "Nhap a[" << (i - 1) / cot << "][" << (i - 1) % cot << "]: ";
		cin >> a[i];
	}
}

void xuat(int* a, int dong)
{
	int cot = a[0];
	for (int i = 1; i < dong * cot + 1; i++)
	{
		cout << a[i] << "\t";
		if (i % cot == 0)
			cout << endl;
	}
}
1 Like

Mình muốn xác nhận lại xíu. :slightly_smiling_face:

  1. Là đề yêu cầu nhập từ file hay nhập từ bàn phím vậy. Vì nếu như nhập từ file thì có phải là cái cout << "Nhap so cot: "; không phải là thừa sao. :smiley:

  2. Như ví dụ của bạn thì chỉ có là ví dụ của một ma trận 2x3, chứ mình không thấy một ví dụ Input/Output nào cả mà code của bạn lại có thêm phân hỏi nhập số cột/dòng kia.

  3. Nếu là nhập từ file thì vẫn có thể dễ dàng xác định được số dòng và số cột của ma trận, nên việc cho thêm một tham số nữa vào hàm nhập có phải hơi thừa, và có chắc tham số đó là số dòng/cột. :smiley:

Do đề như trên thì khá là mơ hồ, không biết bạn có thể cho mình xem đề gốc được không nhỉ. :wink:

4 Likes
  • Nạp vào hàm nhập ma trận với số dòng rồi, tự dưng nhập số cột thì vi phạm S trong SOLID.

  • Có tổng số phần tử của ma trận, có số dòng, hoàn toàn có thể suy ra được số cột mà không cần phải lưu lại giá trị số cột trong ma trận làm gì.

  • Đừng in ra những dòng mời mọc kiểu Nhap gi do nữa.

4 Likes

file gốc đây anh ơi!

Theo như kia thì mình đoán có thể nó sẽ là như thế này:

  • Tham số thứ hai của hàm Nhap(), Xuat()SapXep()số phần tử của ma trận.

  • Có thể lưu số dòng hoặc số cột vào a[0].

  • Về nguyên mẫu của hàm Nhap()

    • Nếu là Nhap(int*&, int) thì sẽ cấp phát ngay bên trong hàm. (vì có thể thay đổi giá trị của con trỏ)

    • Nếu là Nhap(int*, int) thì cần phải cấp phát bên ngoài hàm trước rồi mới nhập được.

    Do đó số phần tử và hình dạng của ma trận phải là đã biết.

  • Hàm Xuat() thì dựa vào a[0] và tham số thứ hai để in ra.


Mà bạn chụp như kia vẫn thiếu đoạn đầu phải không. :smiley:

Còn nữa, nếu đây là bài tập của bạn phải làm thì sao không thắc mắc với giáo viên sau khi nhận bài tập. :kissing:

4 Likes

Biết đâu ma trận vuông :slight_smile:

3 Likes

Đây là full đề rồi á anh. Em không có học lớp này nên không có thắc mắc được với giáo viên anh ơi.

Không học thì tự nhiên đâm đầu vô giải bài trời ơi này làm gì? :face_with_raised_eyebrow:

3 Likes

anh ơi em nghĩ biểu diễn mảng 2 chiều m x n theo mảng 1 chiều
tức là tạo ra 1 mảng 1 chiều có m x n ô nhớ liệu có khả thi không ạ.

Thoải mái nhé. Chú ý lúc truy cập phần tử thôi.

4 Likes

2 chiều, 3 chiều hay n chiều chỉ là cái ta tưởng tượng thế.
Bản chất dữ lieu nó vẫn là 1 chiều (1 dãy dữ liệu liên tiếp).

Cái ma trận:
1 2 3
4 5 6
thực ra nó sẽ như thế này :
{1 2 3} {4 5 6}

Số 5 nằm ở hàng 1 cột 1. Nếu truy cập theo kiểu 2 chiều thì nó là :
Matrix[1][1].
Nhưng có thể truy cập kiểu 1 chiều là:
(&Matrix[0][0] + 5)[1 * rows + 1]

Vậy là chỉ cần biết thông số hàng, cột , con trỏ, chỉ số hàng, chỉ số cột vẫn có thể làm việc.

6 Likes

Có gì khó!?
Đề có yêu cầu gì về giới hạn chiều dài chiều rộng ko?
Nếu ko có gì yêu cầu đặc biệt thì.
Chẻ đôi 1 int(4bytes) thành 2 cái , mỗi cái 2bytes(max ~ 0xFFFF = 65535).
Giả sử : Prototype là Func(int* pi_Arr, int i_Size)
Thì : row là 2 byte cao của i_Size, col là 2 byte thấp của i_Size.

unsigned short us_rowCount = (unsigned short) ( ((unsigned long) i_Size) >> 16 ) & 0xFFFF);
unsigned short us_colCount = (unsigned short) ((unsigned long) i_Size) & 0xFFFF);

Khi gọi hàm và truyền vào thì cũng theo style đó.
int i_Size = (int)(unsigned long)(( us_rowCount << 16 ) | us_colCount ));
Func(pi_Arr, i_Size);

Với cách làm trên và kiểu int yêu cầu của đề, ta có thể làm việc với ma trận có size tối đa là 65535 x 65535

P/s: Mà Int là 2byte, 4byte hay 8byte còn tùy Compiler option (đi kèm với OS và CPU), thông thường thì int = 4byte.

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?