大致思路就是这样,希望能够帮到你哦~
按照你第2点描述,你仅仅是想实现随即顺序点名而已,并不是随即点名。我给你个解决方案:
在每次点中一名学生后,将java0803_students.txt文件中做个标示,表示该学生已经在本轮点名中被点过。
直到所有学生都点到后情况这个表示,准备下一轮点名做标记。
下面我给你一段伪代码,包含了 random 的使用方法:
public class CallStudents(){
private static Random random = new Random()
public void call(){
// 重新设置学生被点名的标示(根据点名情况)
reset()
long value = -1
while (true) {
value = random.nextInt(maxValue + 1)// maxValue 是你当前有学生的最大数目
//在这里读取当前随即号对应的学生记录
String student = getStudentByID(value)
//判断该学生是否被点过名
if(!checkCalled(student)){
// 设置已经点过名
setCalled(student)
// 在控制台上显示被点名的学生信息
system.out.println(student)
// 结束循环
break
}
}
}
private String getStudentByID(long id){
// 这个是读取文件,需要你自己实现的
// 返回 java0803_students.txt 文件中对应的学生记录
}
private boolean checkCalled(String student){
// 至于是什么样的规则,有你自己定义
// 我这里给你举个例子
// 如果这条学生记录中包含 一个字符为 called 的话,表明这名学生被点过名
if(student.indexOf("called") != -1){
retrn true
}
return false
}
private void setCalled(String student){
// 至于是什么样的规则,有你自己定义
// 我这里给你举个例子
// 设置学生已被点名
student += "_called"
// 将这个值重新写回到你的java0803_students.txt 文件中,覆盖愿信息!
}
private void reset(){
// 判断是否所有学生都被点过名,如果点过名,清空所有学生被点名的标记
// 这个实现有你自己定义,
// 这里我给你举个例子
// 读取文件,判断每一个学生信息是否都标有 called
// 如果都有,执行删除所有 called 的 *** 作,并保存文件。
// 如果只有部分没有,则表明本轮点名没有结束,不做任何 *** 作。
}
public static void main(String[] args){
String con = // 接受控制台信息
if(con.equals("y")){
CallStudents call = new CallStudents()
call.call()
}
if(con.equals("n")){
// 结束程序
}
}
}
传不了附件,只能贴上来了,有点长
#define _CRT_SECURE_NO_WARNINGS#include <map>
#include <string>
#include <vector>
#include <ctime>
#include <cstdlib>
#include <algorithm>
#include <cctype>
class Database
struct Finish {// 返回是否继续点名
virtual ~Finish() = 0 {}
virtual bool operator()() = 0
}
struct Response {// 响应点名
virtual ~Response() = 0 {}
virtual void operator()(std::string const &) = 0
}
struct Strategy {
virtual ~Strategy() = 0 {}
virtual void generate_id(Database& database, Finish &finish, Response &response) = 0
}
class Database {
struct student_info {
student_info(std::string const &name_, size_t const absence_)
: absence(absence_), name(name_) {}
size_t absence
std::string name
}
typedef std::map<std::string, student_info> data_t
data_t data
// 移除空格
struct not_space {
bool operator()(char const c) const {
return c != ' ' && c != '\t' && c != '\n' && c != '\b'
}
}
static std::string const& remove_space(std::string &str) {
std::copy_if(str.begin(), str.end(), str.begin(), not_space())
return str
}
template<typename Response_>
struct do_call : Response {
do_call(data_t *const data_, Response_ response_)
: data(data_), response(response_) {}
void operator()(std::string const &id) {
student_info& stu = data->find(id)->second
if (!response(id, stu.name)) {// 没到
++stu.absence
}
}
private:
data_t *data
Response_ response
}
public:
typedef data_t::const_iterator const_iterator
void write_data(std::ostream &ostr) const {
if (!ostr) throw std::invalid_argument("坏的输出流")
for (const_iterator p = data.begin() p != data.end() ++p) {
ostr << p->first << " " << p->second.name << " " << p->second.absence << "\n"
}
}
void read_data(std::istream &istr) {
if (!istr) throw std::invalid_argument("坏的输入流")
data.clear()
std::string id, name
size_t absence
while (istr >> id >> name >> absence) {
if (data.find(id) != data.end()) {
throw std::runtime_error("学号重复")
}
data.insert(std::make_pair(id, student_info(name, absence)))
}
if (!istr.eof()) throw std::runtime_error("文件格式有误")
}
bool insert(std::string id, std::string name, size_t const absence = 0) {
if (remove_space(id).empty() || remove_space(name).empty()) return false// 学号或名字为空
return data.insert(std::make_pair(remove_space(id), student_info(remove_space(name), absence))).second
}
void remove(std::string id) {
data.erase(remove_space(id))
}
bool update_name(std::string id, std::string name) {
data_t::iterator const it = data.find(remove_space(id))
if (it == data.end() || remove_space(name).empty()) return false// 没找到该学生或新的名字为空
it->second.name = name
return true
}
bool update_absence(std::string id, size_t const absence) {
data_t::iterator const it = data.find(remove_space(id))
if (it == data.end()) return false// 没找到该学生
it->second.absence = absence
return true
}
size_t size() const {
return data.size()
}
const_iterator begin() const {
return data.begin()
}
const_iterator end() const {
return data.end()
}
template<typename Response>
void call(std::string const strategy, Finish &finish, Response response)
}
void init_random() {
static bool inited
if (!inited) {
inited = true
srand(static_cast<unsigned>(time(0)))
}
}
struct random : Strategy {
void generate_id(Database& database, Finish &finish, Response &response) {
init_random()
std::vector<std::string> tmp
for (Database::const_iterator p = database.begin() p != database.end() ++p) tmp.push_back(p->first)
std::random_shuffle(tmp.begin(), tmp.end())
for (size_t i = 0 i != tmp.size() && !finish() ++i) {
response(tmp[i])
}
}
}
struct random_with_absence : Strategy {
void generate_id(Database& database, Finish &finish, Response &response) {
init_random()
std::vector<std::string> tmp
std::vector<size_t> absence
absence.push_back(0)
for (Database::const_iterator p = database.begin() p != database.end() ++p) {
tmp.push_back(p->first)
absence.push_back(absence.back() + 1 + p->second.absence)
}
for (size_t i = 0 i != tmp.size() && !finish() ++i) {
do {
size_t const val = rand() % absence.back()
size_t const pos = std::upper_bound(absence.begin(), absence.end(), val) - absence.begin() - 1
if (!tmp[pos].empty()) {
response(tmp[pos])
tmp[pos].clear()
break
}
} while (true)
}
}
}
struct by_id : Strategy {
void generate_id(Database& database, Finish &finish, Response &response) {
for (Database::const_iterator p = database.begin() p != database.end() ++p) {
size_t tmp
if (sscanf(p->first.substr(p->first.size() > 2 ? p->first.size() - 2 : 0).data(), "%zu", &tmp) == EOF) throw std::runtime_error("学号的最后两位不能转化为数字")
if (tmp % 5 == 2) {
if (finish()) return
response(p->first)
}
}
}
}
template<typename Response>
void Database::call(std::string const strategy, Finish &finish, Response response) {
Strategy *ptr = 0
if (strategy == "随机") ptr = new random
else if (strategy == "缺勤") ptr = new random_with_absence
else if (strategy == "学号") ptr = new by_id
else throw std::runtime_error("不支持的点名方式")
try {
ptr->generate_id(
*this,
finish,
do_call<Response>(&this->data, response)
)
}
catch (...) {
delete ptr
throw
}
delete ptr
}
#include <fstream>
#include <iostream>
template<typename Arg>
Arg& get(Arg &arg, std::string const &msg) {
do {
std::cout << msg
// 先清空输入
std::cin.clear()
std::cin.ignore(std::cin.rdbuf()->in_avail())
if (std::cin >> arg) {
return arg
}
else if (std::cin.eof()) {
exit(0)// 退出程序
}
else {
std::cerr << "输入有误\n"
}
} while (true)
}
enum Operation { INSERT, REMOVE, UPDATE_NAME, UPDATE_AB, CALL, SAVE_EXIT, EXIT }
Operation get_Operation() {
do {
char c
switch (get(c,
"1. 插入学生信息(学号、姓名、缺勤(默认为0))\n"
"2. 根据学号删除学生\n"
"3. 根据学号更新姓名\n"
"4. 根据学号更新缺勤数\n"
"5. 点名\n"
"6. 保存并退出\n"
"7. 不保存退出\n"
)) {
case '1': return INSERT
case '2': return REMOVE
case '3': return UPDATE_NAME
case '4': return UPDATE_AB
case '5': return CALL
case '6': return SAVE_EXIT
case '7': return EXIT
default:
std::cerr << "不支持的 *** 作\n"
}
} while (true)
}
template<typename Stream>
std::string open(Stream &str, std::string const &msg, bool const if_fail) {
str.close()
std::string filename
do {
str.open(get(filename, msg))
if (!str) {
std::cerr << "文件打开失败\n"
}
else {
break
}
} while (if_fail)
return filename
}
bool response(std::string const &id, std::string const &name) {
std::cout << name << "(" << id << ")答到:"
// 先清空输入
std::cin.clear()
std::cin.ignore(std::cin.rdbuf()->in_avail())
return std::cin.get() == 'y'
}
struct do_finish : Finish {
bool operator()() {
char c
return get(c, "停止点名?") == 'y'
}
}
int main() {
std::cin.sync_with_stdio(false)
std::cout.sync_with_stdio(false)
std::ifstream istr
std::string filename = open(istr, "请输入文件名:", false)
Database db
if (istr) {
try {
db.read_data(istr)
}
catch (std::exception const &err) {
std::cerr << err.what() << "\n"
return 1
}
}
else {
filename.clear()
}
do {
try {
switch (get_Operation()) {
case INSERT: {
std::string id, name
size_t absence
if (!db.insert(get(id, "输入学号:"), get(name, "输入姓名:"), get(absence, "输入缺勤数:"))) std::cerr << "更新失败\n"
break
}
case REMOVE: {
std::string id
db.remove(get(id, "输入学号:"))
break
}
case UPDATE_NAME: {
std::string id, name
if (!db.update_name(get(id, "输入学号:"), get(name, "输入姓名:"))) std::cerr << "更新失败\n"
break
}
case UPDATE_AB: {
std::string id
size_t absence
if (!db.update_absence(get(id, "输入学号:"), get(absence, "输入缺勤数:"))) std::cerr << "更新失败\n"
break
}
case CALL: {
std::string strategy
std::ofstream ostr
db.call(
get(strategy, "点名策略:"),
do_finish(),
response
)
break
}
case SAVE_EXIT: {
std::ofstream ostr
if (!filename.empty()) ostr.open(filename)
if (!ostr || !ostr.is_open()) open(ostr, "请输入文件名:", true)
db.write_data(ostr)
// 往下
}
case EXIT:
return 0
}
}
catch (std::exception const &err) {
std::cerr << err.what() << "\n"
}
} while (true)
return 0
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)