01/10/2018, 10:01

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 << "

Ho Va Ten : " << hoten[j] << "
 Nam Sinh: " << namsinh[j] << "
 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 đỡ ạ !

Nguyễn Diệu Linh viết 12:04 ngày 01/10/2018

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

Tao Không Ngu. viết 12:15 ngày 01/10/2018

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.

Nguyễn Diệu Linh viết 12:08 ngày 01/10/2018

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 ạ ?

Tao Không Ngu. viết 12:03 ngày 01/10/2018

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.

Nguyễn Diệu Linh viết 12:12 ngày 01/10/2018
#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 ạ

Tao Không Ngu. viết 12:12 ngày 01/10/2018

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.

Nguyễn Diệu Linh viết 12:13 ngày 01/10/2018

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 ạ …?

rogp10 viết 12:02 ngày 01/10/2018

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.

Nguyễn Diệu Linh viết 12:07 ngày 01/10/2018

xây dựng class HS với opera

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

HK boy viết 12:04 ngày 01/10/2018

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]

Nguyễn Diệu Linh viết 12:07 ngày 01/10/2018

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

HK boy viết 12:15 ngày 01/10/2018
  • Đề 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 đề.
rogp10 viết 12:06 ngày 01/10/2018

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.

Đức Lê viết 12:07 ngày 01/10/2018
#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 ạ !

HK boy viết 12:10 ngày 01/10/2018

@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.
Đức Lê viết 12:14 ngày 01/10/2018

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

HK boy viết 12:03 ngày 01/10/2018

if(a[i].diemtong = a[j].diemtong)

Phải là == chứ.

a[i].namsinh <a [j].namsinh;

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

if(a[i].diemtong &lt; 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;


}

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.

Đức Lê viết 12:17 ngày 01/10/2018

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 .

HK boy viết 12:13 ngày 01/10/2018

int viethoa()
{
int i,n;
char hoten[50];

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
}
Đức Lê viết 12:15 ngày 01/10/2018

Em chỉ sửa những ký tự đầu tiên thôi , chứ ko sửa hết họ tên thành Viết Hoa

Bài liên quan
0