banner
Nanomoa

Nanomoa's Blog

"Bytes and Brackets: My Journey in Go and C++ Exploration."
github
zhihu
telegram
twitter

CS106L Spring 2024 Assignment

课程主页: CS106L

作业列表#

作业序号作业标题作业链接
Assignment 1SimpleEnroll前往完成
Assignment 2Marriage Pact前往完成
Assignment 3Make a class!前往完成
Assignment 4Weather Forecast前往完成
.........

Assignment 1: SimpleEnroll#

目前做不了,这个作业的网盘不对外开放 (大概

Assignment 2: Marriage Pact#

知识点: STL's containers and pointers

简介#

start code:

  • main.cpp - 源代码文件
  • students.txt - 所有学生的姓名,一行一个,形如 Xxxxx Xxxxx

本次作业需要从所有名字中找出与自己名字匹配的一项,当且仅当某个名字的首字母缩写和自己名字相同时匹配,然后采用任意策略从所有匹配项中找到唯一的一项

Part 1: Get all applicants#

本部分需要读取文件中所有名字到 std::set<std::string>std::unordered_set<std::string>

思路:

std::ifstream 配合 std::stringstream 即可

代码:

std::set<std::string> get_applicants(std::string filename) {
    std::set<std::string> result;

    std::ifstream ifs(filename);

    if (ifs.is_open()) {
        std::stringstream ss;
        ss << ifs.rdbuf();

        std::string line;
        while (std::getline(ss, line)) {
            result.insert(line);
        }
    }

    return result;
}

Part 2: Find matches#

本部分需要找出所有匹配项放入 std::queue<const std::string*>

思路:

std::set 有序可二分,我名字缩写为TG, 故,先二分找到 T 开头的名字的左右边界,而后遍历该区间找到匹配项即可

代码:

std::queue<const std::string*> find_matches(std::set<std::string> &students) {
    std::queue<const std::string*> result;

    std::string Prefix("T");
    auto itLeft = students.lower_bound(Prefix);

    std::string nextPrefix("U");
    auto itRight = students.lower_bound(nextPrefix);

    for (auto it = itLeft; it != itRight; it++) {
        const std::string& name = *it;

        std::stringstream ss(name);

        std::string first, last;
        ss >> first >> last;

        if(last[0] != 'G') {
            continue;
        }

        result.push(&name);
    }

    return result;
}


然后要从匹配项中取出唯一一项,我这里随机取出一项

完整代码:

/* 
Assignment 2: Marriage Pact

This assignment asks you to discover your one true love using containers and pointers.
There are two parts: implement get_applicants and find_matches.

Submit to Paperless by 11:59pm on 2/1/2024.
*/

#include <iostream>
#include <string>
#include <queue>
#include <set>
#include <fstream>
#include <sstream>
#include <random>

std::set<std::string> get_applicants(std::string filename) {
    std::set<std::string> result;

    std::ifstream ifs(filename);

    if (ifs.is_open()) {
        std::stringstream ss;
        ss << ifs.rdbuf();

        std::string line;
        while (std::getline(ss, line)) {
            result.insert(line);
        }
    }

    return result;
}

std::queue<const std::string*> find_matches(std::set<std::string> &students) {
    std::queue<const std::string*> result;

    std::string Prefix("T");
    auto itLeft = students.lower_bound(Prefix);

    std::string nextPrefix("U");
    auto itRight = students.lower_bound(nextPrefix);

    for (auto it = itLeft; it != itRight; it++) {
        const std::string& name = *it;

        std::stringstream ss(name);

        std::string first, last;
        ss >> first >> last;

        if(last[0] != 'G') {
            continue;
        }

        result.push(&name);
    }

    return result;
}



int main() {
    auto students = get_applicants("students.txt");

    for (const auto& name : students) {
        std::cout << name << std::endl;
    }

    auto matches = find_matches(students);

    std::default_random_engine generator;
    std::uniform_int_distribution<int> distribution(1, static_cast<int>(matches.size()));
    int rand_int = distribution(generator);

    int position = 1;
    std::string trueLove;

    while (!matches.empty()) {
        const std::string* name = matches.front();
        matches.pop();

        trueLove = *name;

        if (position == rand_int) {
            break;
        }

        position++;
    }

    std::cout << "Your true love is " << trueLove << '\n';

    return 0;
}

Assignment 3: Make a Class#

知识点: class, constructor overloading, const-correctness

简介#

start code:

  • class.h - 类的定义文件 (头文件)
  • class.cpp - 类的实现
  • main.cpp - 主要文件 (实例化并运行)

本次作业需要自行实现一个类,并满足如下要求:

  1. 必须有一个自定义的构造函数
  2. 必须有一个默认构造函数
  3. 必须有私有成员
  4. 必须有共有成员
  5. 必须有至少一个getter方法以及一个setter方法

const-correctness#

const-correctness 是一个原则,鼓励使用 const 关键字来防止改变不应该 / 不需要被改变的值,有助于减少错误以及提高代码可读性 (清晰度), 还有获得编译器优化的机会

在本次作业中,主要反映在 getter 方法以及 setter 方法的参数上

代码#

  • class.h
// Blank header file

#include <string>

class Student {
private:
    std::string name;
    int age;
    std::string id;
    std::string dept;
public:
    Student();

    Student(const std::string& _name, int _age, const std::string& _id, const std::string& _dept);

    void setName(const std::string& _name);

    const std::string& getName() const;

    void setAge(int _age);

    int getAge() const;

    void setId(const std::string& _id);

    const std::string& getId() const;

    void setDept(const std::string& _dept);

    const std::string& getDept() const;
};
  • class.cpp
// Blank cpp file

#include "class.h"

Student::Student() = default;

Student::Student(const std::string& _name, int _age, const std::string& _id, const std::string& _dept) {
    this->name = _name;
    this->age = _age;
    this->id = _id;
    this->dept = _dept;
}

void Student::setName(const std::string& _name) {
    this->name = _name;
}

const std::string &Student::getName() const {
    return this->name;
}

void Student::setAge(int _age) {
    this->age = _age;
}

int Student::getAge() const {
    return this->age;
}

void Student::setId(const std::string &_id) {
    this->id = _id;
}

const std::string &Student::getId() const {
    return this->id;
}

void Student::setDept(const std::string &_dept) {
    this->dept = _dept;
}

const std::string &Student::getDept() const {
    return this->dept;
}
  • main.cpp
#include <memory>
#include <iostream>
#include "class.h"

/*
 * Assigment 3: Make a class!
 * Requirements:
 * Must have a custom constructor 
 * Must have a default constructor 
    - i.e. constructor overloading
 * Must have private members (functions and/or variables) 
 * Must have public members (functions) 
 * Must have at least one getter function 
 * Must have at least one setter function 
 */

int main() {
  // initialize class and run this file
  auto stu = std::make_unique<Student>("Nanomoa", 20, "12345678", "Computer Science");

  std::cout << "Name: " << stu->getName() << '\n';
  std::cout << "Age: " << stu->getAge() << '\n';
  std::cout << "ID: " << stu->getId() << '\n';
  std::cout << "Dept: " << stu->getDept() << '\n';

  // or
  auto stu1 = std::make_unique<Student>();

  stu1->setName("Nanomoa");
  stu1->setAge(20);
  stu1->setId("12345678");
  stu1->setDept("Computer Science");

  std::cout << "Name: " << stu1->getName() << '\n';
  std::cout << "Age: " << stu1->getAge() << '\n';
  std::cout << "ID: " << stu1->getId() << '\n';
  std::cout << "Dept: " << stu1->getDept() << '\n';

  return 0;
}

Assignment 4: Weather Forecast#

知识点: template function, lambda

简介#

start code:

  • main.cpp 主要代码文件
  • output,txt 输出文件

已知某周中每天不同时段的华氏温度,本次作业需要配合template functionlambda 对其做一些处理

Part 1: Temperature Converter#

使用 Template Function 实现函数 convert_f_to_c, 将华氏温度转换为摄氏温度,返回一个double 类型的值

注意: 传入华氏温度的类型未知

转换公式: (Fahrenheit32)×5÷9( Fahrenheit - 32) \times 5 \div 9

代码:

template<typename Type>
double convert_f_to_c(Type f) {
    return (static_cast<double>(f) - 32) * 5 / 9;
}

Part 2: The Weekly Forecast#

完善实现函数 get_forecast 完成结果统计

函数模板:

template<typename Function>
std::vector<double> get_forecast(std::vector<std::vector<double>> readings, Function fn) {
  // TODO
}

注意: 此处的 fn 需要接受一个lambda作为参数

我们只需要遍历每一天,之后调用fn计算后存入结果即可

代码:

template<typename Function>
std::vector<double> get_forecast(std::vector<std::vector<double>> readings, Function fn) {
    std::vector<double> result;
    result.reserve(readings.size());
    for (const auto& day : readings) {
        result.push_back(fn(day));
    }
    return result;
}

Part 3: Putting it all together#

我们需要在 main 函数中调用上面实现的函数完成如下功能:

  1. readings 转为摄氏温度并输出到output.txt
  2. 统计出每天的最高温度并输出到output.txt
  3. 统计出每天的最低温度并输出到output.txt
  4. 统计出每天的平均温度并输出到output.txt

其中2~4条需要实现对应的lambda作为参数传入get_forecast函数

代码:

    // TODO: Convert temperatures to Celsius and output to output.txt
    for (auto& vec : readings) {
        for (auto& item : vec) {
            item = convert_f_to_c(item);
        }
    }

    std::ofstream ofs("output.txt");
    if (ofs.is_open()) {
        for (auto& vec : readings) {
            for (auto& item : vec) {
                ofs << item << " ";
            }
            ofs << '\n';
        }
        ofs.close();
    }

    // TODO: Find the maximum temperature for each day and output to output.txt
    auto maximum_temps = [](const std::vector<double>& day) -> double {
        return *std::max_element(day.begin(), day.end());
    };

    auto max_temps = get_forecast(readings, maximum_temps);

    ofs.open("output.txt", std::ios_base::app);
    if (ofs.is_open()) {
        for (auto& item : max_temps) {
            ofs << item << " ";
        }
        ofs << '\n';
        ofs.close();
    }

    // TODO: Find the minimum temperature for each day and output to output.txt
    auto minimum_temps = [](const std::vector<double>& day) -> double {
        return *std::min_element(day.begin(), day.end());
    };

    auto min_temps = get_forecast(readings, minimum_temps);

    ofs.open("output.txt", std::ios_base::app);
    if (ofs.is_open()) {
        for (auto& item : min_temps) {
            ofs << item << " ";
        }
        ofs << '\n';
        ofs.close();
    }

    // TODO: Find the average temperature for each day and output to output.txt
    auto average_temps = [](const std::vector<double>& day) -> double {
        double sum = std::accumulate(day.begin(), day.end(), 0.0);
        return sum / static_cast<double>(day.size());
    };

    auto avg_temps = get_forecast(readings, average_temps);

    ofs.open("output.txt", std::ios_base::app);
    if (ofs.is_open()) {
        for (auto& item : avg_temps) {
            ofs << item << " ";
        }
        ofs << '\n';
        ofs.close();
    }

完整代码:#

/* 
Assignment 4: Weather Forecast

This assignment works with template functions and lambdas to become the best weather forecaster
at the Stanford Daily. Be sure to read the assignment details in the PDF.

Submit to Paperless by 11:59pm on 5/10/2024.
*/

// TODO: import anything from the STL that might be useful!
#include <iostream>
#include <vector>
#include <fstream>
#include <algorithm>
#include <numeric>


// TODO: write convert_f_to_c function here. Remember it must be a template function that always returns
// a double.
template<typename Type>
double convert_f_to_c(Type f) {
    return (static_cast<double>(f) - 32) * 5 / 9;
}

template<typename Function>
std::vector<double> get_forecast(std::vector<std::vector<double>> readings, Function fn) {
    std::vector<double> result;
    result.reserve(readings.size());
    for (const auto& day : readings) {
        result.push_back(fn(day));
    }
    return result;
}

int main() {
    std::vector<std::vector<double>> readings = {
            {70, 75, 80, 85, 90},
            {60, 65, 70, 75, 80},
            {50, 55, 60, 65, 70},
            {40, 45, 50, 55, 60},
            {30, 35, 40, 45, 50},
            {50, 55, 61, 65, 70},
            {40, 45, 50, 55, 60}
    };

    // TODO: Convert temperatures to Celsius and output to output.txt
    for (auto& vec : readings) {
        for (auto& item : vec) {
            item = convert_f_to_c(item);
        }
    }

    std::ofstream ofs("output.txt");
    if (ofs.is_open()) {
        for (auto& vec : readings) {
            for (auto& item : vec) {
                ofs << item << " ";
            }
            ofs << '\n';
        }
        ofs.close();
    }

    // TODO: Find the maximum temperature for each day and output to output.txt
    auto maximum_temps = [](const std::vector<double>& day) -> double {
        return *std::max_element(day.begin(), day.end());
    };

    auto max_temps = get_forecast(readings, maximum_temps);

    ofs.open("output.txt", std::ios_base::app);
    if (ofs.is_open()) {
        for (auto& item : max_temps) {
            ofs << item << " ";
        }
        ofs << '\n';
        ofs.close();
    }

    // TODO: Find the minimum temperature for each day and output to output.txt
    auto minimum_temps = [](const std::vector<double>& day) -> double {
        return *std::min_element(day.begin(), day.end());
    };

    auto min_temps = get_forecast(readings, minimum_temps);

    ofs.open("output.txt", std::ios_base::app);
    if (ofs.is_open()) {
        for (auto& item : min_temps) {
            ofs << item << " ";
        }
        ofs << '\n';
        ofs.close();
    }

    // TODO: Find the average temperature for each day and output to output.txt
    auto average_temps = [](const std::vector<double>& day) -> double {
        double sum = std::accumulate(day.begin(), day.end(), 0.0);
        return sum / static_cast<double>(day.size());
    };

    auto avg_temps = get_forecast(readings, average_temps);

    ofs.open("output.txt", std::ios_base::app);
    if (ofs.is_open()) {
        for (auto& item : avg_temps) {
            ofs << item << " ";
        }
        ofs << '\n';
        ofs.close();
    }

    return 0;
}
加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。