随机点名程序设计 C语言编程

随机点名程序设计 C语言编程,第1张

设置一个足够大的随机池,给每一个学生分配相同的空间,然后利用随机数来选取被点名的学生,同时对该学生所分配的空间和其他学生的空间进行缩减或增加。然后执行下一轮。

大致思路就是这样,希望能够帮到你哦~

按照你第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

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7923853.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-11
下一篇 2023-04-11

发表评论

登录后才能评论

评论列表(0条)

保存