专栏首页魔法师的世界c++ | lwketh | day03

c++ | lwketh | day03

#include <vector>
#include <iostream>
#include <string>

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("||| 测试成功");
    }
}


// 本次作业主要是 string
// string 题目用到的知识仍然是
// 0, 用下标引用字符串
// 2, 循环
// 3, 选择 (也就是 if)
//


// 作业 1
//
string 
nChar(int n) {
    char fillchar = '0';
    string r = "";
    int i = 0;
    while(i < n) {
        r += fillchar;
        i += 1;
    }
    return r;
}
string 
str(int number) {
    string s = to_string(number);
    return s;
}

int
len(const string &s) {
    return s.size();
}

string
zfill(int n, int width) {
    // 把 n 的位数变成 width 这么长,并在右对齐,不足部分用 0 补足并返回
    // 具体请看测试
    // 提示:
    // 计算 n 的长度, 随后生成一串指定长度的 0, 使两者组合后长度为 width

    // 实现步骤
    // 1. 将 n 转化为字符串并计算长度
    //    数字转字符串方法 string n_str = to_string(n);
    // 2. 在 zfill 函数前, 构建一个辅助函数 nChar, 生成一个长度为 n 的 0 字符串
    // 3. 算出需要填充的 0 的个数并使用 nChar 生成
    // 4. 拼接
    string r = str(n);
    int l = len(r);
    if (l < width) {
        r = nChar(width - l) + r;
    }
    return r;
}

// 测试函数
void
testZfill() {
    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");
    log("zfill ok");
}


// 作业 2
//
string 
fill_char(int n, char &fillchar) {
    string r = "";
    int i = 0;
    while(i < n) {
        r += fillchar;
        i += 1;
    }
    return r;
}

string
rjust(const string &s, int width, char fillchar=' ') {
    // 如果 s 长度小于 width, 则在开头用 fillchar 填充并返回

    // 返回 string 类型

    // 提示:
    // 类似于作业 1, 但有几个区别
    // 一是不需要先用 string() 转换类型
    // 二是填充的字符不是 0 而是可以自行定义

    // 分步提示:
    // 1. 计算需要用 fillchar 生成的字符串长度
    // 2. 使用作业 1 中的辅助函数 nChar, 修改它以便符合本题的使用
    // 3. 调用修改后的 nChar 生成填充用的字符串
    // 4. 拼接并返回结果
    string r = s;
    int l = len(s);
    if (l < width) {
        r = fill_char(width - l, fillchar) + r;
    }
    return r;
}

// 测试函数
void
testRjust() {
    ensure(rjust("gua", 5) == "  gua", "rjust 测试 1");
    ensure(rjust("guagua", 5) == "guagua", "rjust 测试 2");
    ensure(rjust("gua", 5, '*') == "**gua", "rjust 测试 3");
    log("rfill ok");
}


// 作业 3
//
string ljust(string s, int width, char fillchar=' ') {
    // s 是 string
    // width 是 整数
    // fillchar 是 长度为 1 的字符串, 默认为空格 ' '

    // 如果 s 长度小于 width, 则在末尾用 fillchar 填充并返回
    // 否则, 原样返回, 不做额外处理

    // 返回 string 类型

    // 提示:
    // 类似于作业 2, 区别是填充位置在左侧而不是右侧

    // 实现步骤
    // 1. 复制作业 2 中的代码, 记得把函数名改成 ljust
    // 2. 把作业 2 最后一步的字符串拼接的两个元素调换位置
    string r = s;
    int l = len(s);
    if (l < width) {
        r += fill_char(width - l, fillchar);
    }
    return r;
}

// 测试函数
void
testLjust() {
    ensure(ljust("gua", 5) == "gua  ", "ljust 测试 1");
    ensure(ljust("guagua", 5) == "guagua", "ljust 测试 2");
    ensure(ljust("gua", 5, '*') == "gua**", "ljust 测试 3");
    log("lfill ok");
}


// 作业 4
//

bool 
isOdd(int number) {
    int n = number;
    bool r = n % 2 > 0;
    // log("number ", number, "r", r);
    return r;
}

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. 拼接字符串, 并返回结果
    string r = s;
    int l = len(s);
    if (l < width) {
         if (isOdd(width - l)) {  
            // log("is odd");
            int left_width = (width - l - 1) / 2;
            int right_width = left_width + 1;
            // log("left ", left_width, "right", right_width);
            string left = rjust(r, left_width + l,  fillchar);
            // log("left len", len(left));
            r = ljust(left, width,  fillchar);
            // log("r len", len(r));
         } else {
            int left_width = (width - l) / 2;
            int right_width = left_width;
            string left = rjust(r, left_width + l,  fillchar);
            r = ljust(left, width,  fillchar);
         }
    }
    // string re = "(" + r + ")";
    // log("re", re);
    return r;
}

// 测试函数
void
testCenter() {
    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");
    log("center ok");
}


// 作业 5
//
bool
isSpace(const string &s) {
    // 检查 s 中是否只包含空格

    // 返回 布尔值
    // 如果 s 中包含的只有空格则返回 true
    // 否则返回 false

    // 提示:
    // 遍历 s 中的所有字符, 其中如果包含非空格字符, 返回 false, 否则返回 true

    // 实现步骤
    // 1. 如果是一个空字符串返回 false
    // 2. 遍历 s 中的每个字符
    // 3. 如果字符不是空格, 返回 false
    // 4. 在循环结束后, 返回 true
    char fillchar = ' ';
    int i = 0;
    // 特殊情况
    if (len(s) == 0) {
        return true;
    } 
    while(i < len(s)) {
        if (s[i] != fillchar) {
            return false;
        }
        i += 1;
    }
    return true;
}

// 测试函数
void
testIsSpace() {
    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");
    log("is_space ok");
}

bool
char_in_digit(const char c) {
    string number = "0123456789";
    int i = 0;
    while(i < len(number)) {
        if (number[i] == c) {
            return true;
        }
        i += 1;
    }
    return false;
}
   
// 作业 6
//
bool
isDigit(const string &s) {
    // 检查 s 中是否只包含数字
    // 返回: 布尔值

    // 提示:
    // 类似于作业 5, 判断的条件从空格变为了数字

    // 实现步骤
    // 1. 复制 isSpace 函数中的代码
    // 2. 将判断字符是否为空格的部分改为判断是否为数字
    //     通过判断字符是否在字符串 "0123456789" 中, 来判断其是否为数字
    char fillchar = ' ';
    int i = 0;
    // 特殊情况
    if (len(s) == 0) {
        return false;
    } 
    while(i < len(s)) {
        if (!char_in_digit(s[i])) {
            return false;
        }
        i += 1;
    }
    return true;
}

// 测试函数
void
testIsDigit() {
    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");
    log("id_digit ok");
}

int 
find_not_space(const string &s, char fillchar) {
    int i = 0;
    while(i < len(s)) {
        if (s[i] != fillchar) {
            // log("i", i);
            return i;
        }
        i += 1;
    }
    return -1;
}
void
test_find_not_space() {
    ensure(find_not_space("   123", ' ') == 3, "find_not_space  测试 1");
    log("debug find_not_space");
}

int 
find_not_space_left(const string &s, char fillchar) {
    int i = 0;
    while(i < len(s)) {
        if (s[i] != fillchar) {
            // log("i", i);
            return i;
        }
        i += 1;
    }
    return -1;
}
// 作业 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
    // 第一个参数表示开始的下标,第二个参数表示切片的个数
    if (isSpace(s)) {
        // log("is space debug");
        return "";
    }
    int index = find_not_space_left(s, ' ');
    int all = len(s) - index;
    // log("总数", all);
    string r = s.substr(index, all);
    // log("r", len(r), r);
    return r;
}

// 测试函数
void
testStripLeft() {
    ensure(stripLeft("  gua") == "gua", "stripLeft 测试 1");
    ensure(stripLeft(" gua  ") == "gua  ", "stripLeft 测试 2");
    ensure(stripLeft("") == "", "stripLeft 测试 3");
    ensure(stripLeft("    ") == "", "stripLeft 测试 4");
    log("StripLef ok");
}


// 作业 8
//
int 
find_not_space_right(const string &s, char fillchar) {
    int i = len(s) - 1;
    while(i > 0) {
        if (s[i] != fillchar) {
            // log("i", i);
            return i;
        }
        i -= 1;
    }
    return -1;
}


string
stripRight(const string &s) {
    // 返回一个「删除了字符串末尾的所有空格」的字符串

    // 提示:
    // 类似于作业 7
    // 区别在于这次需要从右至左遍历字符串

    // 实现步骤
    // 1. 创建一个循环, 从右到左遍历字符串
    //     从右到左遍历的方式是让数字从 n 到 0
    // 2. 遍历字符串找到不是空格的字符的下标
    // 3. 切片并返回
    if (isSpace(s)) {
        // log("is space debug");
        return "";
    }
    int index = find_not_space_right(s, ' ');
    int all =  index + 1;
    // log("总数", all);
    string r = s.substr(0, all);
    // log("r", len(r), r);
    return r;
}

// 测试函数
void
testStripRight() {
    ensure(stripRight("gua") == "gua", "stripRight 测试 1");
    ensure(stripRight(" gua  ") == " gua", "stripRight 测试 2");
    ensure(stripRight("") == "", "stripRight 测试 3");
    ensure(stripRight("    ") == "", "stripRight 测试 4");
    log("stripRight  ok");
}


// 作业 9
//
string
strip(const string &s) {
    // 返回一个「删除了字符串首尾的所有空格」的字符串

    // 返回 string

    // 提示:
    // 依次调用作业 7 和作业 8 中的函数即可

    // 分布提示:
    // 1. 调用 stripLeft
    // 2. 对上一步的结果继续调用 stripRight
    // 3. 返回结果
    string r = stripRight(stripLeft(s));
    return r;
}

// 测试函数
void
testStrip() {
    ensure(strip("  gua") == "gua", "strip 测试 1");
    ensure(strip(" gua  ") == "gua", "strip 测试 2");
    ensure(strip("") == "", "strip 测试 3");
    ensure(strip("    ") == "", "strip 测试 4");
    log("strip", strip);
}


// 作业 10
//
int
index_by_old_str(const string &s, const string &old_str) {
    int i = 0;
    int space = len(old_str);
    while(i < len(s)) {
        string new_str = s.substr(i, space);
        if (new_str == old_str) {
            log("i", i);
            return i;
        }
        i += 1;
    }
    return -1;
}

string
replace(const string &s, const string &old_str, const string &new_str) {
    // 返回一个「将 s 中的 old_str 字符串替换为 new_str 字符串」的字符串
    // 假设 old 存在并且只出现一次

    // 返回 string

    // 提示:
    // 找到指定旧字符串的起始下标, 将其前后字符串与新字符串进行拼接

    // 实现步骤
    // 1. 找到 old_str 的下标
    // 2. 把 s 切成 2 个不包含 old_str 的字符串
    // 3. 拼接并返回结果
    int index = index_by_old_str(s, old_str);
    string left = s.substr(0, index);
    log("left", left);
    int right_index = index + len(old_str);
    string right = s.substr(right_index, len(s));
    log("right", right);
    string r = left + new_str + right;
    return r;
}

// 测试函数
void
testReplace() {
    ensure(replace("guagua", "ag", "l") == "gulua", "replace 测试 1");
    ensure(replace("g  ", "  ", "a") == "ga", "replace 测试 2");
    ensure(replace("l", "l", "") == "", "replace 测试 3");
}


void
test() {
    testZfill();
    testRjust();
    testLjust();
    testCenter();
    testIsSpace();
    testIsDigit();
    test_find_not_space();
    testStripLeft();
    testStripRight();
    testStrip();
    testReplace();
    // 剩下的测试函数调用需要你自行补足
}

int
main(int argc, const char *argv[]) {
    test();

    return 0;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • c++ | lwketh | day01

    李朝
  • c++ | lwketh | day_04

    李朝
  • c++ | lwketh | day04

    李朝
  • c++ | lwketh | day02

    李朝
  • 说说FactoryBean

    常用的使用场景为:根据不同的配置类型返回不同类型的处理Bean,整体上简化了XML配置等。

    春哥大魔王
  • Spark Core快速入门系列(5) | RDD 中函数的传递

    我们进行 Spark 进行编程的时候, 初始化工作是在 driver端完成的, 而实际的运行程序是在executor端进行的. 所以就涉及到了进程间的通讯, 数...

    不温卜火
  • day03

        True,False   str:存储少量数据,进行操作     'fjdsal' ,'二哥','13243','fdshklj' ...

    py3study
  • Java基础-day03-代码题

    Java基础-day03-代码题 ★ 1生成Random随机数,范围在99-999之间 ★ ? 实现代码 package StudyJavaSE; //1.导包...

    Java帮帮
  • Java基础-day03-基础题

    Java基础-day03-基础题 1.Scanner类,练习案例 Test1,定义main()方法,按以下步骤编写代码: A.导入Scanner类; B.在ma...

    Java帮帮
  • 从零搭建Spring Boot脚手架(4):手写Mybatis通用Mapper

    今天继续搭建我们的kono Spring Boot脚手架,上一文把国内最流行的ORM框架Mybatis也集成了进去。但是很多时候我们希望有一些开箱即用的通用Ma...

    码农小胖哥
  • 从零学Python(案例源码)

    https://gitee.com/itcode-itcode/Python.git

    程序源代码
  • SQL操作三

    爱撒谎的男孩
  • 拟南芥的基因ID批量转换?差异基因,GO/KEGG数据库注释(转录组直接送你全套流程)

    可以看到基因的ID和symbol的对应关系就出来了,根使用网页工具是类似的,感兴趣的朋友可以试试看网页工具和R代码的ID批量转换差别有多大。

    生信技能树
  • 爬虫系列(18)Python-Spider。

    小Gy
  • django学习-day03

    #DTL模板中的python语句使用 ###if->elif->else: <body> {% if k.o.1 < 2 %} \<p>是的\</p> ...

    kirin
  • Java基础-Day03

    将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问。

    软件小生活
  • Linux基础Day03

    uniq 命令用于检查及删除文本文件中重复出现的行,一般与 sort 命令结合使用。

    ChinaManor
  • Linux 常用文本处理命令和vim文本编辑器

      col,用于过滤控制字符,-b过滤掉所有控制字符,这个命令并不常用,但可以使用man 命令名| col -b >help.txt

    砸漏
  • Python OOP - practice_2

    若尘_

扫码关注云+社区

领取腾讯云代金券