Chưa hình dung ra được hướng lập trình. Nhờ mọi người giúp đỡ

Chào mọi người ạ, e có bài toán chưa hình dung được viết câu lệnh như thế nào, e mới học lập trình được 1 thời gian, mong mọi ngời giúp đỡ, e xin cảm ơn ạ!

Đề ra là : Nhập danh sách n học sinh viết dưới dạng các thuộc tính: họ tên, năm sinh và tổng điểm.
Sắp xếp theo thứ tự giảm dần của tổng điểm. Khi tổng điểm như nhau thì học sinh có năm sinh
nhỏ hơn được đứng trước. In ra danh sách học sinh đã sắp xếp sao cho tất cả các chữ cái đầu của
họ tên chuyển thành chữ hoa.
E mới viết đươc :

#include <iostream>
#include <string>
using namespace std;
int n;
#define max 100
class hocsinh
{
private:
    string hoten[max], namsinh[max];
    float dt[max];
public:
    void nhaphs()
    {
    for (int i = 1; i <= n; i++)
    {
        cout << "Nhap Ho Ten sv: ";
        cin.ignore(1);
        getline(cin, hoten[i]);
        fflush(stdin);
        cout << "Nhap Nam Sinh: ";
        getline(cin, namsinh[i]);
        fflush(stdin);
        cout << "Nhap tong diem: ";
        cin >> dt[i];
        
    }
    }
    void inhs()
    {
        for (int j = 1; j <= n; j++)
        {
            cout << "\n\nHo Va Ten : " << hoten[j] << "\n Nam Sinh: " << namsinh[j] << "\n Diem Tong: " << dt[j]
                 << endl;

        }
    }
    void sapxeptheodiem(int x)
    {
      ....
}

Đến đây thì e chưa hình dung được thêm câu lệnh, ko biết sắp xếp theo điểm thi như thế nào theo từng lớp con, và cả phân in HOA…
Mong mọi người giúp đỡ ạ !

Xin các cao nhân vào chỉ giáo giúp đỡ e với ạ !

Hi Nguyễn Diệu Linh.
Bạn đọc lại nôi quy diễn đàn cũng như cách fỏmat code. Cũng như học lại hướng đối tượng trước.
Còn về bài toán của bạn.
1 Tạo lớp học sinh có các thuộc tính họ tên năm sinh tổng điểm v.v.v…
2 Ghi đè lại toán tử so sánh cho lớp này theo yêu cầu của bài toán.
3 Tạo hàm định dạng lại tên.

P/S Học lại hướng đối tượng trước đi.

2 Likes

Em cảm ơn ạ
E chưa hiểu được làm thế nào để so sánh phần tử trong 2 lớp với nhau …
Anh hướng dẫn cụ thể hơn hoặc có thể cho e tài liệu để e tham khảo được ko ạ ?

Hi Nguyễn Diệu Linh.
Bạn có thể đọc thêm về ghi đè toán tử trong C++. Và xem thêm tài liệu về lập trình hướng đối tượng.

1 Like
#include <iostream>
#include <string>
using namespace std;
int n;
#define max 100
class hocsinh
{
private:
    string hoten[max], namsinh[max];
    float dt[max];
public:
    void nhaphs()
    {
    for (int i = 1; i <= n; i++)
    {
        cout << "Nhap Ho Ten sv: ";
        cin.ignore(1);
        getline(cin, hoten[i]);
        fflush(stdin);
        cout << "Nhap Nam Sinh: ";
        getline(cin, namsinh[i]);
        fflush(stdin);
        cout << "Nhap tong diem: ";
        cin >> dt[i];
        
    }
    }
    void inhs()
    {
        for (int j = 1; j <= n; j++)
        {
            cout << "\n\nHo Va Ten : " << hoten[j] << "\n Nam Sinh: " << namsinh[j] << "\n Diem Tong: " << dt[j]
                 << endl;

        }
    }
    void sapxeptheodiem(int x)
    {
        
      
        for (int i = 1; i <= n; i++)
        {
        tong[i] = dt[i] ;
        }
        for (int j = 1; j <= n; j++)
        {
            if  (tong[j] >= x)
            {
            .....
    }
};
int main()
{
    int x;
    hocsinh a;
    cout << "Nhap so sinh vien: ";
    cin >> n;
    a.nhaphs();
    a.inhs();
    system("pause");
}

Thực sự là bế tắc e đọc mãi ko thông … Chưa hiểu được lắm về hướng đi ạ

Hi Nguyễn Diệu Linh.
Bạn thiết kế sai rồi. Lớp học sinh thì chỉ có một tên một tuổi v.v.v… ở đây lớp học sinh của bạn lai chứ dữ liệu toàn bộ các học sinh luôn. Khi nào bạn tách được lớp học sinh ra rồi tính tiếp.

2 Likes

E chưa hiểu ý của anh lắm ạ, đề ra là nhập vào 1 danh sách học sinh mà…
Hay anh có thể nói cho e hướng đi của bài toán, sau đó e tìm hiểu và làm code được ko ạ …?

Trước tiên bạn phải xây dựng class HS với operator< như đề bài yêu cầu, sau đó lập class DSHS, rồi feed nguyên cái mảng chứa HS thẳng vào std::sort. Phần hậu xử lí thì là bài cơ bản.

2 Likes

Em cảm ơn ạ, để e nghiên cứu tiếp rồi e nhờ mnguoi giúp đỡ nữa ạ

Mình không quen viết OOP, mình sẽ viết 1 hàm boolean so sánh để cho bạn hiểu. Về code thì bạn tự viết.

Đây là hàm so sánh dựa trên code của bạn:

bool cmp(int i, int j) { //so sánh 2 học sinh i và j
    return ((dt[i] > dt[j]) || ((dt[i] == dt[j]) && (namsinh[i] <= namsinh[j])));
}

Lúc sort thì: sort(...)
Vấn đề ở đây: Hàm sort của C++ chỉ cho phép sort trên 1 mảng/vector, mà hàm cmp thì liên quan đến 2 mảng. Rõ ràng bạn không thể viết class hocsinh như thế kia được. Bạn phải cải tiến lại là class này biểu diễn thông tin cho 1 học sinh chứ không phải cho nhiều học sinh, như vậy có thể sort được.

Lúc đó hàm so sánh viết lại thành:

bool cmp(int i, int j) { //vẫn so sánh 2 học sinh i và j
    return ((hs[i].dt > hs[j].dt) || ((hs[i].dt == hs[j].dt) && (hs[i].namsinh <= hs[j].namsinh)));
}

[spoiler]P/s: Mình lại giúp đến tận chân răng rồi :v đáng ra chỉ giúp đến tay thôi…[/spoiler]

2 Likes

Em cảm ơn anh nhiều ạ!
Khi nào e viết ra code nhờ mọi người xem giúp e

  • Đề bài yêu cầu nhập danh sách học sinh với các thông tin khác, tức là có 2 hướng:
  • Quản lí theo lớp: như bạn đã code
  • Quản lí theo học sinh: tạo 1 CTDL chứa thông tin học sinh (ở đây là tên, năm sinh và tổng điểm)
  • Vì đề còn có yêu cầu sắp xếp học sinh theo thông tin, tức là các thông tin gắn chặt vào học sinh và thông số so sánh là 1 thông tin của học sinh. Rõ ràng, nếu như quản lí theo lớp thì khi sắp xếp ta gặp phải vấn đề như mình đã đề cập ở cmt trên, bạn đọc lại, nếu bạn không hiểu chỗ nào thì nói.
  • Bắt sang topic này, về bản chất là tất cả các bài kiểu này đều làm giống nhau hết. struct hay class chỉ là vấn đề ngôn ngữ. Có thể bạn sửa code của bạn, không dùng class nữa (bài này dùng class mình cảm thấy hơi không cần thiết), có thể lúc đấy mới vỡ ra vấn đề.
2 Likes

Bạn đang viết class cho danh sách HS nhưng bạn chưa xây dựng class HS trước nên càng làm càng rối và không sử dụng được thư viện. Để mô hình hóa danh sách các X bạn phải có mô hình X phù hợp với yêu cầu.

1 Like
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<cstring>
#include<string.h>
using namespace std;
class hocsinh{
public:
    char hoten[50];
    int namsinh;
    float diemtong;
    void nhap();
    void xuat();

};
void hocsinh::nhap()
{
        cout<< "Nhap Ten Hoc Sinh :";
        cin.ignore();
        gets(hoten); 
		fflush(stdin);
        cout<< "Nam Sinh :";
        cin>> namsinh;
        cout<< "Diem Tong : ";
        cin>> diemtong;
}
void hocsinh::xuat(){
    cout<< "\nTen Hoc Sinh: "<<hoten<<endl;
    cout<< "Nam sinh:"<<namsinh<<endl;
    cout<< "Diem Tong:"<<diemtong<<endl;
}
void sapxep(hocsinh a[100], int n)
{
    int i,j;
    hocsinh tg;
    for(i = 0 ; i < n ; i++)
        for( j = i +1; j < n; j ++)
           {
               if(a[i].diemtong < a[j].diemtong)
                {
                    tg = a[j];
                    a[j] = a[i];
                    a[i] = tg;
                        if(a[i].diemtong = a[j].diemtong)
                            a[i].namsinh <a [j].namsinh;


                }


           }
}
int viethoa()
{
    int i,n;
    char hoten[50];
        for (i=0;i<=n;i++)
                    if (hoten[i]== ' ' && hoten[i+1]!=' ')
                       if(int(char(hoten[i+1]))>97 && int(char(hoten[i+1]))<=122) // Ep Kieu
                           hoten[i+1]=char(int(hoten[i+1]-32));                   //Ep Kieu
                           cout<<"In Danh Sach: "<<hoten<<endl;
}
int main()
{

    int n,i;
    hocsinh a[100];
    cout<< "Nhap So Luong Hoc Sinh:";
    cin>>n;
    for(i = 0 ; i <n ; i ++)
    {
        a[i].nhap();
    }
    cout<< "Danh Sach Hoc Sinh :";
    for(i = 0 ; i <n ; i ++)
    {
        a[i].xuat();
    }
    cout<< "Danh Sach Hoc Sinh Theo Diem Giam Dan ";
    sapxep(a,n);
    for(i = 0 ; i < n ; i++)
        a[i].xuat();
    viethoa();
    cout<< "Danh Sach Hoc Sinh Duoc Viet Hoa Chu Cai Dau";
    for(i = 0 ; i < n ; i++)
    {
        a[i].xuat();
    }
}

Mình cũng đang làm bài này …
nhưng phần sắp xếp với phần viết Hoa vẫn bị lỗi khi điểm thi trung nhau và khác năm sinh, các bác xem sửa lại giúp e được ko ạ !

1 Like

@Maknae:

  • Code bạn xấu quá. Bạn indent hơi vô tội vạ.
  • Mã chữ thường là từ 97 đến 122, tức là ở chỗ dấu > 97 sửa thành >= 97.
1 Like

Em sửa lại vẫn ko được anh ạ, với chỗ sắp xếp


cứ 2 ng điểm giống nhau là bị sai chương trình, em đang tìm lãi lỗi mà chưa được :frowning:

Phải là == chứ.

Chỗ này bạn chưa sắp xếp lại. Bạn viết ra cái so sánh này để làm gì?
Nói chung là cả đoạn này

sai tất, vì if (a[i].diemtong == a[j].diemtong) có vai trò ngang hàng với if (a[i].diemtong > a[j].diemtong), phải là

if (a[i].diemtong < a[j].diemtong) {
    //swap
} else if (a[i].diemtong == a[i].demtong) {
    if (a[i].namsinh < a[j].namsinh) {
        //swap
    }
}

Lần sau nhớ viết ra vai trò của các câu lệnh so sánh ra giấy thì viết code chính xác hơn.

1 Like

cái dưới so sánh năm sinh để năm sinh thấp hơn sẽ được in ra trước ạ
Em sửa lại và đã được, em cảm ơn ạ, còn khúc mắc chỗ sửa viết hoa e sửa vẫn ko đc .

Bạn khai báo biến char hoten[50] này là biến cục bộ của hàm viethoa, khi sửa chữ viết hoa thì hàm này chỉ sửa biến cục bộ thôi, bạn phải sửa hàm viethoa này thành

void viethoa(hocsinh a) {
    //sửa cách viết hoa của a.hoten
}
1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?