30/09/2018, 16:14

Cần giải thích một số hàm về mảng một chiều

Em đang học về hàm và mảng 1 chiều và thầy cho 3 bài tập và đã giải. Nhưng hôm thầy giáo chữa bài thì em nghỉ, mượn vở bạn về chép về đọc thì em không hiểu các hàm này lắm, mọi người giải thích cho em với ạ

Bài giải như sau

Bài 1: Tìm vị trí phần tử lớn nhất trong mảng

void tim_vi_tri(int a[], int spt)
{
	int i,j=0,max,vitri=1;
	max=a[0];
	for(i=1;i<spt;i++)
	{
		j++;
		if(a[i]>a[i-1]&&a[i]>max)
		{
		max=a[i];
		vitri=j+1; 
		}
		else
		{
		a[i-1]=max;
		}
	}
	printf("Phan tu lon nhat co vi tri: %d",vitri);
}

Bài 2: Tìm phần tử lớn thứ 2 đầu tiên của mảng

void tim_phan_tu_lon_thu_2_dau_tien(int a[],int spt)
{
	int i,j,k;
	for(i=0;i<spt;i++)
	{
		k=1;
		for(j=0;j<spt;j++)
		{
			if(a[i]<a[j])
			k++;
		}
		if(k==2)
		{
			printf("phan tu lon thu 2 = %d",a[i]);
			printf("
vi tri: %d",i+1);
			break;
		}
	}
}

Bài 3: Nhập 1 mảng rồi sắp xếp mảng đó sao cho chẵn ở đầu, lẻ ở cuối, trật tự tương đối không đổi

void sap_xep_chan_le(int a[], int spt)
{
	int i,j,k,g=0,h,tg;
	for(i=0;i<spt;i++)
	{
		if(a[i]%2!=0)
		g++;
	}
	for(j=0;j<g;j++)
	{
		for(k=0;k<spt-1;k++)
		{
			if(a[k]%2!=0)
			{
				tg=a[k+1];
				a[k+1]=a[k];
				a[k]=tg;
			}
		}
	}
	printf("
");
	for(h=0;h<spt;h++)
	{
	printf("%d ",a[h]);
	}
}
Thực tế khắc nghiệt viết 18:28 ngày 30/09/2018

bạn phải nói rõ bạn k hiểu ở đoạn nào mới đc chứ ?!

Nguyễn Minh Dũng viết 18:21 ngày 30/09/2018

Bổ sung cho câu trả lời của @Honey_moon

Le Tran Dat – 13 Nov 14

Người mới học lập trình cần biết – Phần 1 – Học lập trình thông qua hỏi đáp

Là một lập trình viên chuyên nghiệp Đạt tích lũy được kinh nghiệm lập trình thông qua nhiều năm tự học và làm việc. Quá trình tự học đó kéo dài, nhưng chung quy lại việc học lập trình bao gồm các q…

Le Tran Dat – 13 Nov 14

Người mới học lập trình cần biết – Phần 2 – Học lập trình thông qua thảo luận

Là một lập trình viên chuyên nghiệp Đạt tích lũy được kinh nghiệm lập trình thông qua nhiều năm tự học và làm việc. Quá trình tự học đó kéo dài, nhưng chung quy lại việc học lập trình bao gồm các q…

mitomchua viết 18:30 ngày 30/09/2018

Cả đoạn code luôn anh ạ, hôm thầy giáo chữa bài thì em nghỉ, mượn vở bạn về chép thì đọc k hiểu j :’(

Nguyễn Minh Dũng viết 18:22 ngày 30/09/2018

@mitomchua em đã đọc 2 cái links anh gửi chưa? Anh nói ngắn gọn nhé,

  • Thứ nhất, em đang học cái gì anh không biết.
  • Thứ hai, bài này giải cái gì anh cũng không biết
  • Thứ ba, em không hiểu cái gì anh cũng không biết luôn

Sao anh giải thích được cho em?

Sơ sơ ta có thể hiểu các hàm như sau:

  • Hàm tim_vi_tri nói chính xác hơn là tim_vi_tri_phan_tu_lon_nhat hoặc nếu muốn viết ngắn gọn thì viets tim_vi_tri_max. Viết tim_vi_tri hoặc là muốn đánh đố hoặc quá lười.

  • Hàm tiếp theo ổn hơn, tim_phan_tu_lon_thu_2_dau_tien cái tên hàm đã giải thích cụ thể nó muốn làm gì rồi, tìm phần tử lớn thứ 2 đầu tiên (của mảng).

  • Hàm này cũng thế sap_xep_chan_le, sắp xếp chẵn lẻ.

mitomchua viết 18:18 ngày 30/09/2018

Em cảm ơn anh, lần sau em khi post bài hỏi em sẽ rút kinh nghiệm
Những bài này là em đang bắt đầu học về hàm và mảng 1 chiều
Bài 1: Tìm vị trí phần tử lớn nhất trong mảng
Bài 2: Tìm phần tử lớn thứ 2 đầu tiên của mảng
Bài 3: Nhập 1 mảng rồi sắp xếp mảng đó sao cho chẵn ở đầu, lẻ ở cuối, trật tự tương đối không đổi

Nguyễn Minh Dũng viết 18:30 ngày 30/09/2018

Bài 1: Tìm vị trí phần tử lớn nhất trong mảng

Code kia dài dòng quá, anh viết lại như thế này em hiểu không?

int vi_tri_lon_nhat(int mang[], int size)
{
    int max = mang[0];
    int vi_tri_max = 0;
    for(int i = 1; i < size; ++i)
        if (max < mang[i])
        {
            max = mang[i];
            vi_tri_max = i;
        }
    return vi_tri_max;
}

Bài 2: Tìm phần tử lớn thứ 2 đầu tiên của mảng

Phức tạp hơn tí, code của thầy em chắc em chép sai hay sao mà không tìm được phần tử lớn thứ 2. Nên anh không giải thích nhé. Đây là code anh viết.

int vi_tri_lon_thu_hai_dau_tien(int mang[], int size)
{
    int max = mang[0];
    int second = max;
    int vi_tri_max = 0;
    int vi_tri_lon_thu_hai = vi_tri_max;
    for(int i = 0; i < size; ++i)
    {
        if (max < mang[i])
        {
            second = max;
            vi_tri_lon_thu_hai = vi_tri_max;
            max = mang[i];
            vi_tri_max = i;
        }
        else if (second < mang[i] && max != mang[i])
        {
            second = mang[i];
            vi_tri_lon_thu_hai = i;
        }
    }

    return vi_tri_lon_thu_hai;
}

Bài 3: Nhập 1 mảng rồi sắp xếp mảng đó sao cho chẵn ở đầu, lẻ ở cuối, trật tự tương đối không đổi

Tương tự, code thầy em sử dụng nhiều biến i,j,k,g,h,tg nên anh cũng chả hiểu gì. Anh viết lại sử dụng hàm hoán vị, và hàm kiểm tra số chẵn nhé.

void hoan_vi(int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

int so_chan(int n)
{
    return n % 2 == 0;
}

void sep_chan_le(int mang[], int size)
{
    int vi_tri_moi = 0;
    for(int i = 1; i < size; ++i)
        if (so_chan(mang[i]))
            hoan_vi(&mang[i], &mang[vi_tri_moi++]);
}

Tổng hợp 3 bài

#include <stdio.h>

int vi_tri_lon_nhat(int mang[], int size)
{
    int max = mang[0];
    int vi_tri_max = 0;
    for(int i = 1; i < size; ++i)
        if (max < mang[i])
        {
            max = mang[i]; // gán max bằng giá trị mới, lớn hơn 
            vi_tri_max = i; // lưu lại vị trí đó
        }
    return vi_tri_max;
}

int vi_tri_lon_thu_hai_dau_tien(int mang[], int size)
{
    int max = mang[0];
    int second = max;
    int vi_tri_max = 0;
    int vi_tri_lon_thu_hai = vi_tri_max;
    for(int i = 0; i < size; ++i)
    {
        if (max < mang[i])
        {
            second = max; // second gán bằng max
            vi_tri_lon_thu_hai = vi_tri_max; // lưu lại vị trí second 
            max = mang[i]; // lấy giá trị mới, lớn hơn
            vi_tri_max = i; // lưu vị trí mới
        }
        else if (second < mang[i] && max != mang[i])
        {
            second = mang[i]; // trường hợp này để tìm giá trị second nhỏ hơn max
            vi_tri_lon_thu_hai = i;
        }
    }

    return vi_tri_lon_thu_hai;
}

// Code này em chép nhầm nên không tìm được phần tử thứ 2 nhé.
void tim_phan_tu_lon_thu_2_dau_tien(int a[],int spt)
{
    int i,j,k;
    for(i=0; i<spt; i++)
    {
        k=1;
        for(j=0; j<spt; j++)
        {
            if(a[i]<a[j])
                k++;
        }
        if(k==2)
        {
            printf("phan tu lon thu 2 = %d",a[i]);
            printf("\nvi tri: %d",i+1);
            break;
        }
    }
}

void hoan_vi(int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

int so_chan(int n)
{
    return n % 2 == 0;
}

void sep_chan_le(int mang[], int size)
{
    int vi_tri_moi = 0;
    for(int i = 1; i < size; ++i)
        if (so_chan(mang[i])) // nếu chẵn
            hoan_vi(&mang[i], &mang[vi_tri_moi++]); // thì đổi chỗ
}

#define SIZE 10

int main()
{
    int mang[SIZE] = {5,9,3,1,6,7,9,9,7,4};
    printf("Mang hien tai\n");
    for(int i = 0; i < SIZE; ++i)
        printf("%d ", mang[i]);
    printf("\n");

    int lon_nhat = vi_tri_lon_nhat(mang,SIZE);
    printf("vi tri lon nhat cua mang %d gia tri %d\n", lon_nhat, mang[lon_nhat]);

    int lon_nhi = vi_tri_lon_thu_hai_dau_tien(mang,SIZE);
    printf("vi tri lon nhat cua mang %d gia tri %d\n", lon_nhi, mang[lon_nhi]);

    // Khong tim duoc phan tu lon thu 2
    tim_phan_tu_lon_thu_2_dau_tien(mang,SIZE);

    sep_chan_le(mang,SIZE);
    printf("Mang sau khi sap xep\n");
    for(int i = 0; i < SIZE; ++i)
        printf("%d ", mang[i]);

    return 0;
}
Người Cô Đơn viết 18:27 ngày 30/09/2018

Bạn hỏi thế này mình nghĩ bạn rỗng kiến thức rồi.Chịu khó tìm hiểu thêm,đọc thêm tài liệu và quan trọng nhất code thật nhiều để tự mình rút ra được.Chứ cứ chép lại bài rồi nhờ người giải thích thì khó mà nhớ lâu được lắm.Tập code rồi cố gắng tìm lời giải đáp,không được thì mới mang lên hỏi.Thời gian đầu mình ngu lắm,giờ đỡ rồi

Nguyễn Minh Dũng viết 18:27 ngày 30/09/2018

Một phần là do code kia cũng hơi khó hiểu, @Lang_Khach thử đọc coi hehe

mitomchua viết 18:20 ngày 30/09/2018

Em cám ơn anh nhiều, hàm của anh viết dễ hiểu hơn nhiều hàm của thầy em chắc dùng nhiều biến quá nên lắm lúc em cũng k hiểu biến đó để làm gì.
Hàm 1 của anh em chạy thử thì hình như lỗi 1 xíu anh à
Ví dụ như số đầu tiên em nhập là số lớn nhất thì nó in ra vị trí = 0
Còn số lớn nhất là số thứ 3 thì nó in ra vị trí = 2
Ví dụ: nhập lần lượt 4 số: 6 7 8 9 => số lớn nhất ở vị trí thứ 3
nhập lần lượt 4 số: 9 8 7 6 => số lớn nhất vị trí 0
Em sửa lại ntn thì nó chạy đúng

int vi_tri_lon_nhat(int a[], int n)
{
    int max = a[0];
    int vi_tri_max = 1;
    for(int i = 1; i < n; i++)
        if (max < a[i])
        {
            max = a[i];
            vi_tri_max = i+1;
        }
    return vi_tri_max;
}
mitomchua viết 18:16 ngày 30/09/2018

Em cám ơn góp ý của anh
Thật ra em cũng chạy thử code r, và cũng tự làm các bài tập đơn giản hơn, r tìm trên mạng code chạy thử, r tự sửa tùm lum khác đi xem nó ntn

Nguyễn Minh Dũng viết 18:23 ngày 30/09/2018

Hàm 1 của anh em chạy thử thì hình như lỗi 1 xíu anh à Ví dụ như số đầu tiên em nhập là số lớn nhất thì nó in ra vị trí = 0Còn số lớn nhất là số thứ 3 thì nó in ra vị trí = 2 Ví dụ: nhập lần lượt 4 số: 6 7 8 9 => số lớn nhất ở vị trí thứ 3nhập lần lượt 4 số: 9 8 7 6 => số lớn nhất vị trí 0Em sửa lại ntn thì nó chạy đúng

Không, em sai rồi.

Trong ngôn ngữ lập trình C hay C++ và nhiều ngôn ngữ lập trình khác. Vị trí bắt đầu của mảng không phải là 1, mà là 0.

Đó là lý do tại sao anh xuất ra đúng vị trí bằng 0. Còn nếu em muốn xuất ra vị trí 1, thì em cho kết quả + 1 là được.

À, bài anh dư ở một điểm là không cần so sánh với phần tử 0 làm gì, vì max đã là phần tử 0.

Anh sửa lại như sau:

int vi_tri_lon_nhat(int mang[], int size)
{
    int max = mang[0]; // vì max là phần tử 0
    int vi_tri_max = 0; 
    for(int i = 1; i < size; ++i) // nên ta thay 0 bằng 1
        if (max < mang[i])
        {
            max = mang[i];
            vi_tri_max = i;
        }
    return vi_tri_max;
}

Khi sử dụng hàm này thì em in ra như sau

int lon_nhat = vi_tri_lon_nhat(mang,SIZE);
printf("vi tri lon nhat cua mang %d gia tri %d\n", lon_nhat + 1, mang[lon_nhat]);

Vì nếu không thì mang[lon_nhat] sẽ trả ra giá trị sai.

Tuy nhiên anh không thích cách làm này, là lập trình viên em phải luôn nghĩ mảng bắt đầu từ 0 chứ không phải là 1. Trừ một số ít ngôn ngữ khác có chỉ số bắt đầu bằng 1.

X viết 18:28 ngày 30/09/2018

code dài dòng khó hiểu quá @@

Đoàn Hiếu Tâm viết 18:21 ngày 30/09/2018

Code viết dài dòng quá. Bài tìm MAX mà so sánh a[i] với a[i-1] chi vậy nhỉ? Mới nhìn tưởng bubble sort.

Bài liên quan
0