30/09/2018, 17:55

Chọn ngẫu nhiên n phần tử của một mảng?

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 ).

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

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…

Nguyễn Văn Tâm viết 20:08 ngày 30/09/2018
  1. 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.
  2. Đơ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
thai tan loi viết 20:11 ngày 30/09/2018

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

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

nếu lopHocstd::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/

thai tan loi viết 20:00 ngày 30/09/2018

ok thanks you

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

Ideone.com

Ideone.com

Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.


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.

Bài liên quan
0