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 ạ :smiley:

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("\nvi 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("\n");
	for(h=0;h<spt;h++)
	{
	printf("%d ",a[h]);
	}
}

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

2 Likes

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

1 Like

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 :’(

@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ẻ.

1 Like

Em cảm ơn anh, lần sau em khi post bài hỏi em sẽ rút kinh nghiệm :smiley:
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

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;
}

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;
}

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;
}
2 Likes

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 :smiley:

2 Likes

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

1 Like

Em cám ơn anh nhiều, hàm của anh viết dễ hiểu hơn nhiều :smiley: 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;
}
1 Like

Em cám ơn góp ý của anh :smiley:
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

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.

1 Like

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

1 Like

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.

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