Cho mình hỏi 2 vấn đề
1/ giả sử , mình có 1 lớp gồm 60 Sinh vien , mình muốn chọn ngẫu nhiên 6 sinh viên để tạo thành 1 group (10 group)thì mình làm cách nào ( ko dùng cách cắt , 10 người đầu , rồi tới 10 người tiếp theo …)
2/mình dùng mảng struct để quản lý sinh viên với số điểm tăng dần (ví dụ 5 7 10), giờ mình muốn chèn thêm 1 sinh viên ( tên abc, điểm 7 ) vào mà vẫn giữ nguyên tính chất dãy tăng thì làm sao ( chèn cả tên , và điểm muôn ).
Chọn ngẫu nhiên n phần tử của một mảng?
1/ std::random_shuffle cả lớp, rồi từ 0-5 là nhóm 1, 6-11 là nhóm 2, v.v…
2/ chèn vô mảng thì trước tiên tìm kiếm nhị phân ra vị trí chèn rồi chèn. C++ thì có std::lower_bound hoặc std::upper_bound. Vd mảng 1 2 2 2 3 thì lower_bound của 2 là số 2 đầu tiên, còn upper_bound của 2 là số 3.
hoặc xài std::multiset…
- Bạn có thể lưu số thứ tự sinh viên trong một mảng rồi sinh ngẫu nhiên chọn một phần tử bất kỳ trong mảng ta được 1 sinh viên, loại bỏ phần tử ra khỏi mảng, tiếp tục đến khi chọn được 6 sinh viên.
- Đơn giản là bạn so sánh điểm của các sinh viên đến khi nào gặp sinh viên có điểm cao hơn thì chèn sinh viên cần thêm vào phía trước( dịch mảng sang phải), hoặc nếu duyệt hết mảng mà không có thì chèn vào cuối mảng.
P/s: Lưu ý số lượng phần tử của mảng phải > 60. Nếu không thì dùng danh sách liên kết việc chèn sẽ nhanh hơn
1/Bạn có thể viết dùm code ngắn dùm cái đc ko , mình ko hiểu cho lắm về cách dùng
nếu lopHoc
là std::vector<SinhVien> lopHoc
thì gọi std::random_shuffle(lopHoc.begin(), lopHoc.end());
là xong. lopHoc[0]
tới lopHoc[5]
là nhóm 1, lopHoc[6]
tới lopHoc[11]
là nhóm 2, v.v…
nếu lopHoc là mảng SinhVien lopHoc[100]
và có thêm int soLuongSv
là số lượng sv hiện tại trong lớp học thì gọi std::random_shuffle(lopHoc, lopHoc+soLuongSv);
là xong
nhớ include thêm <algorithm>
. Thêm <ctime>
, <cstdlib>
để gọi srand(time(0));
ngay sau khi vào main nữa.
vô đây coi ví dụ http://www.cplusplus.com/reference/algorithm/random_shuffle/
ok thanks you
xài std::vector đi, xài mảng mất công lắm.
1/ chỗ xuất danh sách nhóm là ta viết dài dòng vậy thôi chứ sau dòng 27 là sắp xếp nhóm xong rồi. Để mỗi lần chạy chương trình thì nó shuffle khác nhau thì nhớ thêm dòng 18 (srand) nữa.
2/ dòng 47-49: thêm 1 phần tử vào vector ở vị trí ko phải ở cuối thì xài insert(iter, newElement), trong đó iter là vị trí muốn insert. Vị trí này nhờ hàm lower_bound (tìm chặn dưới) tìm dùm, vì lopHoc đã được sort rồi nên lower_bound sẽ tìm đúng. lower_bound ở đây ta xài có 4 tham số: từ đâu tới đâu (2 tham số), phần tử cần tìm chặn dưới, và tham số thứ 4 là hàm so sánh. Nếu SinhVien có thể so sánh <
với nhau rồi thì khỏi cần truyền tham số thứ 4 này. Ở đây SinhVien ko có operator<
nên xài hàm cmpByScore
, nên để hàm này trong class SinhVien luôn, coi như SinhVien là 1 namespace, để static
vì nó thuộc chung tất cả SinhVien chứ ko phải của 1 SinhVien riêng lẻ nào.
.
.
.
.
nếu xài multiset làm danh sách sv tăng dần theo điểm thì: http://ideone.com/6nfR56
// tạo danh sách sv có điểm tăng dần
std::multiset<SinhVien, SinhVien::Comparator>
dssv(lopHoc.begin(), lopHoc.end(), SinhVien::cmpByScore);
// chèn thêm 1 sv tên Mai có điểm 7
dssv.emplace("Mai", 7); //hoặc dssv.insert(newSv);
// xuất danh sách lớp học
std::cout << "\nDanh sách lớp học (điểm từ thấp đến cao)\n";
for (const auto& sv : dssv)
std::cout << sv.ten << ": " << sv.diem << "\n";
typedef 1 cái bool (*Comparator)(const SinhVien&, const SinhVien&)
trong class SinhVien cho đỡ… Mệt chỗ định nghĩa nhưng khi chèn rất là vô tư. Xuất danh sách thì nếu xài C++11 thì cũng vô tư như xài vector hay mảng vậy.