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

作业题

第三次作业题

代码

#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++的编码规范允许这样不同的形式,我也不太了解。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342