美文网首页
萧井陌“雷课堂”第三次作业(持续更新)

萧井陌“雷课堂”第三次作业(持续更新)

作者: 禁卫君 | 来源:发表于2020-05-07 22:02 被阅读0次

    作业题

    第三次作业题

    代码

    #include <vector>
    #include <iostream>
    #include <string>
    #include <list> 
      
    using namespace std;
    
    
    template<class T>
    void
    _print(T arg) {
        cout << arg << " ";
    }
    
    template<class... Args>
    void
    log(Args... args) {
        int arr[] = { (_print(args), 0)... };
        cout << endl;
    }
    
    
    void
    ensure(bool condition, const string &message) {
        // 在条件不成立的时候, 输出 message
        if (not condition) {
            log("*** 测试失败: ", message);
        } else {
            log("||| 测试成功");
        }
    }
    
    
    // 作业 1
    //
    string 
    nChar(int n, char fillchar) {
        // 生成一个 n 长度的 00000字符串
        string r = "";
        int i = 0;
        while(i < n) {
            r += fillchar;
            i += 1;
        }
        return r;
    }
    
    string
    zfill(int n, int width) {
        // 把 n 的位数变成 width 这么长,并在右对齐,不足部分用 0 补足并返回
        // 具体请看测试
        // 提示:
        // 计算 n 的长度, 随后生成一串指定长度的 0, 使两者组合后长度为 width
    
        // 本题需要求 string 的长度,例子如下
        // log("字符串长度", string("gua").length());
        // 输出结果是 “字符串长度 3”
    
        // 实现步骤
        // 1. 将 n 转化为字符串并计算长度
        //    数字转字符串方法 string n_str = to_string(n);
        // 2. 在 zfill 函数前, 构建一个辅助函数 nChar, 生成一个长度为 n 的 0 字符串
        // 3. 算出需要填充的 0 的个数并使用 nChar 生成
        // 4. 拼接
        string n_str = to_string(n);
        int len = n_str.length();
        if (len >= width) {
            return n_str;
        }
        else {
            int len_of_0 = width - len;
            string fill = nChar(len_of_0, '0');
            return fill + n_str;
        }
    }
    
    // 测试函数
    void
    testZfill() {
        log("-----------------------");
        ensure(zfill(1, 4) == "0001", "zfill 测试 1");
        ensure(zfill(23, 4) == "0023", "zfill 测试 2");
        ensure(zfill(12345, 4) == "12345", "zfill 测试 3");
        ensure(zfill(169, 5) == "00169", "zfill 测试 4");
    }
    
    
    // 作业 2
    //
    string
    rjust(const string &s, int width, char fillchar=' ') {
        // 如果 s 长度小于 width, 则在开头用 fillchar 填充并返回
    
        // 返回 string 类型
    
        // 提示:
        // 类似于作业 1, 但有几个区别
        // 一是不需要先用 string() 转换类型
        // 二是填充的字符不是 0 而是可以自行定义
    
        // 分步提示:
        // 1. 计算需要用 fillchar 生成的字符串长度
        // 2. 使用作业 1 中的辅助函数 nChar, 修改它以便符合本题的使用
        // 3. 调用修改后的 nChar 生成填充用的字符串
        // 4. 拼接并返回结果
        int len = s.length();
        if (len >= width) {
            return s;
        }
        else {
            int len_of_char = width - len;
            string pre = nChar(len_of_char, fillchar);
            return pre + s;
        }
    }
    
    // 测试函数
    void
    testRjust() {
        log("----------------------");
        ensure(rjust("gua", 5) == "  gua", "rjust 测试 1");
        ensure(rjust("guagua", 5) == "guagua", "rjust 测试 2");
        ensure(rjust("gua", 5, '*') == "**gua", "rjust 测试 3");
    }
    
    
    // 作业 3
    //
    string 
    ljust(string s, int width, char fillchar=' ') {
        // s 是 string
        // width 是 整数
        // fillchar 是 长度为 1 的字符串, 默认为空格 ' '
    
        // 如果 s 长度小于 width, 则在末尾用 fillchar 填充并返回
        // 否则, 原样返回, 不做额外处理
    
        // 返回 string 类型
    
        // 提示:
        // 类似于作业 2, 区别是填充位置在左侧而不是右侧
    
        // 实现步骤
        // 1. 复制作业 2 中的代码, 记得把函数名改成 ljust
        // 2. 把作业 2 最后一步的字符串拼接的两个元素调换位置
        int len = s.length();
        if (len >= width) {
            return s;
        }
        else {
            int len_of_char = width - len;
            string pre = nChar(len_of_char, fillchar);
            return s + pre;
        }
        
    
    }
    
    // 测试函数
    void
    testLjust() {
        log("----------------------");
        ensure(ljust("gua", 5) == "gua  ", "ljust 测试 1");
        ensure(ljust("guagua", 5) == "guagua", "ljust 测试 2");
        ensure(ljust("gua", 5, '*') == "gua**", "ljust 测试 3");
    }
    
    
    // 判断一个数是否为偶数的函数
    bool
    isEven(int n) {
        if (n % 2 == 0) {
            return true;
        }
        else{
            return false;
        }
    }
    
    // 作业 4
    //
    string
    center(const string &s, int width, char fillchar=' ') {
        // 如果 s 长度小于 width, 则在两边用 fillchar 填充并返回
        // 如果 s 长度和 width 互为奇偶, 则无法平均分配两边的 fillchar
        //     这种情况下, 让左边的 fillchar 数量小于右边
    
        // 返回 string 类型
    
        // 提示:
        // 需要计算 s 左右两侧字符串的长度后, 分别生成左右填充字符串, 并最终把三者按顺序拼接
    
        // 实现步骤
        // 1. 计算左右填充字符串的总长度
        // 2. 计算左右填充字符串的长度,注意要是整数
        //      C++ 中 5/2 结果是 2
        // 3. 生成左右两个填充字符串
        // 4. 拼接字符串, 并返回结果
        int len = s.length();
        if (len >= width) {
            return s;
        }
        else {
            int len_of_char = width - len;
            if (isEven(len_of_char)) {
                return nChar(len_of_char / 2, fillchar) + s + nChar(len_of_char / 2, fillchar); 
            }
            else {
                return nChar(len_of_char / 2, fillchar) + s + nChar(len_of_char / 2 + 1, fillchar);
            }
        }
        
    }
    
    // 测试函数
    void
    testCenter() {
        log("----------------------");
        ensure(center("gua", 5) == " gua ", "center 测试 1");
        ensure(center("gua", 5, '*') == "*gua*", "center 测试 2");
        ensure(center("gw", 5) == " gw  ", "center 测试 3");
        ensure(center("gua", 6) == " gua  ", "center 测试 4");
    }
    
    
    // 作业 5
    //
    bool
    isSpace(const string &s) {
        // 检查 s 中是否只包含空格
    
        // 返回 布尔值
        // 如果 s 中包含的只有空格则返回 true
        // 否则返回 false
    
        // 提示:
        // 遍历 s 中的所有字符, 其中如果包含非空格字符, 返回 false, 否则返回 true
    
        // 实现步骤
        // 1. 如果是一个空字符串返回 false
        // 2. 遍历 s 中的每个字符
        // 3. 如果字符不是空格, 返回 false
        // 4. 在循环结束后, 返回 true
        if (s == "") {
            return false;
        }
        else {
            int i = 0;
            while (i < s.length()) {
               if (s[i] != ' ') {
                   return false;
               } 
               i++;
            }
            return true;
        }
    }
    
    // 测试函数
    void
    testIsSpace() {
        log("----------------------");
        ensure(isSpace(" "), "isSpace 测试 1");
        ensure(isSpace("   "), "isSpace 测试 2");
        // C++ 中 not 可以替代 !
        // 同理还有 and 替代 && 和 or 替代 ||
        ensure(not isSpace(""), "isSpace 测试 3");
        ensure(not isSpace("gua"), "isSpace 测试 4");
        ensure(not isSpace("  gua"), "isSpace 测试 5");
    }
    
    
    // 定义 find 函数
    int
    find(const string &s, char c) {
        if (s == "") {
            return -1;
        }
        else {
            int i = 0;
            while (i < s.length()) {
                if (c == s[i]) {
                    return i;
                }
                i++;
            }
            return -1;
        }
    }
    
    // 作业 6
    //
    bool
    isDigit(const string &s) {
        // 检查 s 中是否只包含数字
        // 返回: 布尔值
    
        // 提示:
        // 类似于作业 5, 判断的条件从空格变为了数字
    
        // 实现步骤
        // 1. 复制 isSpace 函数中的代码
        // 2. 将判断字符是否为空格的部分改为判断是否为数字
        //     通过判断字符是否在字符串 "0123456789" 中, 来判断其是否为数字
        const string digit_string = "0123456789";
        if (s == "") {
            return false;
        }
        else {
            int i = 0;
            while (i < s.length()) {
               if (find(digit_string, s[i]) == -1) {
                   return false;
               } 
               i++;
            }
            return true;
        }
        
        
    }
    
    // 测试函数
    void
    testIsDigit() {
        log("----------------------");
        ensure(isDigit("123"), "is_digit 测试 1");
        ensure(isDigit("0"), "is_digit 测试 2");
        ensure(not isDigit("  "), "is_digit 测试 3");
        ensure(not isDigit("1.1"), "is_digit 测试 4");
        ensure(not isDigit("gua"), "is_digit 测试 5");
        ensure(not isDigit(""), "is_digit 测试 6");
    }
    
    
    // 作业 7
    //
    string
    stripLeft(const string &s) {
        // 返回一个「删除了字符串开始的所有空格」的字符串
    
        // 返回 string
    
        // 实现步骤
        // 从左侧遍历字符串, 记录第一个非空格字符的位置, 并由此切割字符串
        // 1. 使用作业 5 的 isSpace 函数来判断 s 是否只包含空格,
        //    如果 s 只包含空格,返回空字符串
        // 2. 遍历字符串找到不是空格的字符的下标
        // 3. 切片并返回
        //      string 的切片方法如下
        //             0123456789
        // string s = "kuaibiancheng";
        // string s1 = s.substr(2, 5);
        // 结果是 aibia
        // 第一个参数表示开始的下标,第二个参数表示切片的个数
        int len = s.length();
        int i = 0;
        while (i < len) {
            if (s[i] != ' ') {
                return s.substr(i, len - i);
            }
            i++;
        }
        return "";
    
    }
    
    // 测试函数
    void
    testStripLeft() {
        log("----------------------");
        ensure(stripLeft("  gua") == "gua", "stripLeft 测试 1");
        ensure(stripLeft(" gua  ") == "gua  ", "stripLeft 测试 2");
        ensure(stripLeft("") == "", "stripLeft 测试 3");
        ensure(stripLeft("    ") == "", "stripLeft 测试 4");
    }
    
    
    // 作业 8
    //
    string
    stripRight(const string &s) {
        // 返回一个「删除了字符串末尾的所有空格」的字符串
    
        // 提示:
        // 类似于作业 7
        // 区别在于这次需要从右至左遍历字符串
    
        // 实现步骤
        // 1. 创建一个循环, 从右到左遍历字符串
        //     从右到左遍历的方式是让数字从 n 到 0
        // 2. 遍历字符串找到不是空格的字符的下标
        // 3. 切片并返回
        int len = s.length();
        int i = len - 1;
        while (i >= 0) {
            if (s[i] != ' ') {
                return s.substr(0, i + 1);
            }
            i--;
        }
        return "";
    }
    
    // 测试函数
    void
    testStripRight() {
        log("----------------------");
        ensure(stripRight("gua") == "gua", "stripRight 测试 1");
        ensure(stripRight(" gua  ") == " gua", "stripRight 测试 2");
        ensure(stripRight("") == "", "stripRight 测试 3");
        ensure(stripRight("    ") == "", "stripRight 测试 4");
    }
    
    
    // 作业 9
    //
    string
    strip(const string &s) {
        // 返回一个「删除了字符串首尾的所有空格」的字符串
    
        // 返回 string
    
        // 提示:
        // 依次调用作业 7 和作业 8 中的函数即可
    
        // 分布提示:
        // 1. 调用 stripLeft
        // 2. 对上一步的结果继续调用 stripRight
        // 3. 返回结果
        string result = stripLeft(s);
        result = stripRight(result);
        return result;
    }
    
    // 测试函数
    void
    testStrip() {
        log("----------------------");
        ensure(strip("  gua") == "gua", "strip 测试 1");
        ensure(strip(" gua  ") == "gua", "strip 测试 2");
        ensure(strip("") == "", "strip 测试 3");
        ensure(strip("    ") == "", "strip 测试 4");
    }
    
    
    void
    test() {
        testZfill();
        testRjust();
        testLjust();
        testCenter();
        testIsSpace();
        testIsDigit();
        testStripLeft();
        testStripRight();
        testStrip();
    }
    
    int main (void) {
        test();
        return 0;
    }
    

    运行结果

    运行结果

    补充说明

    • 因为时间已经晚了,第十题没来得及做,如果明天有时间的话会尽快补上。希望大家见谅!
    • 本次代码在变量命名上出现了不统一的问题,有的时候是驼峰式的,有的时候是下划线分割,据我以往的认知这种分裂是不好的,我后续会改善。也许C++的编码规范允许这样不同的形式,我也不太了解。

    相关文章

      网友评论

          本文标题:萧井陌“雷课堂”第三次作业(持续更新)

          本文链接:https://www.haomeiwen.com/subject/orttnhtx.html