作業(yè)題
代碼
#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) {
// 在條件不成立的時(shí)候, 輸出 message
if (not condition) {
log("*** 測試失敗: ", message);
} else {
log("||| 測試成功");
}
}
// 作業(yè) 1
//
string
nChar(int n, char fillchar) {
// 生成一個(gè) n 長度的 00000字符串
string r = "";
int i = 0;
while(i < n) {
r += fillchar;
i += 1;
}
return r;
}
string
zfill(int n, int width) {
// 把 n 的位數(shù)變成 width 這么長象迎,并在右對齊,不足部分用 0 補(bǔ)足并返回
// 具體請看測試
// 提示:
// 計(jì)算 n 的長度, 隨后生成一串指定長度的 0, 使兩者組合后長度為 width
// 本題需要求 string 的長度,例子如下
// log("字符串長度", string("gua").length());
// 輸出結(jié)果是 “字符串長度 3”
// 實(shí)現(xiàn)步驟
// 1. 將 n 轉(zhuǎn)化為字符串并計(jì)算長度
// 數(shù)字轉(zhuǎn)字符串方法 string n_str = to_string(n);
// 2. 在 zfill 函數(shù)前, 構(gòu)建一個(gè)輔助函數(shù) nChar, 生成一個(gè)長度為 n 的 0 字符串
// 3. 算出需要填充的 0 的個(gè)數(shù)并使用 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;
}
}
// 測試函數(shù)
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");
}
// 作業(yè) 2
//
string
rjust(const string &s, int width, char fillchar=' ') {
// 如果 s 長度小于 width, 則在開頭用 fillchar 填充并返回
// 返回 string 類型
// 提示:
// 類似于作業(yè) 1, 但有幾個(gè)區(qū)別
// 一是不需要先用 string() 轉(zhuǎn)換類型
// 二是填充的字符不是 0 而是可以自行定義
// 分步提示:
// 1. 計(jì)算需要用 fillchar 生成的字符串長度
// 2. 使用作業(yè) 1 中的輔助函數(shù) nChar, 修改它以便符合本題的使用
// 3. 調(diào)用修改后的 nChar 生成填充用的字符串
// 4. 拼接并返回結(jié)果
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;
}
}
// 測試函數(shù)
void
testRjust() {
log("----------------------");
ensure(rjust("gua", 5) == " gua", "rjust 測試 1");
ensure(rjust("guagua", 5) == "guagua", "rjust 測試 2");
ensure(rjust("gua", 5, '*') == "**gua", "rjust 測試 3");
}
// 作業(yè) 3
//
string
ljust(string s, int width, char fillchar=' ') {
// s 是 string
// width 是 整數(shù)
// fillchar 是 長度為 1 的字符串, 默認(rèn)為空格 ' '
// 如果 s 長度小于 width, 則在末尾用 fillchar 填充并返回
// 否則, 原樣返回, 不做額外處理
// 返回 string 類型
// 提示:
// 類似于作業(yè) 2, 區(qū)別是填充位置在左側(cè)而不是右側(cè)
// 實(shí)現(xiàn)步驟
// 1. 復(fù)制作業(yè) 2 中的代碼, 記得把函數(shù)名改成 ljust
// 2. 把作業(yè) 2 最后一步的字符串拼接的兩個(gè)元素調(diào)換位置
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;
}
}
// 測試函數(shù)
void
testLjust() {
log("----------------------");
ensure(ljust("gua", 5) == "gua ", "ljust 測試 1");
ensure(ljust("guagua", 5) == "guagua", "ljust 測試 2");
ensure(ljust("gua", 5, '*') == "gua**", "ljust 測試 3");
}
// 判斷一個(gè)數(shù)是否為偶數(shù)的函數(shù)
bool
isEven(int n) {
if (n % 2 == 0) {
return true;
}
else{
return false;
}
}
// 作業(yè) 4
//
string
center(const string &s, int width, char fillchar=' ') {
// 如果 s 長度小于 width, 則在兩邊用 fillchar 填充并返回
// 如果 s 長度和 width 互為奇偶, 則無法平均分配兩邊的 fillchar
// 這種情況下, 讓左邊的 fillchar 數(shù)量小于右邊
// 返回 string 類型
// 提示:
// 需要計(jì)算 s 左右兩側(cè)字符串的長度后, 分別生成左右填充字符串, 并最終把三者按順序拼接
// 實(shí)現(xiàn)步驟
// 1. 計(jì)算左右填充字符串的總長度
// 2. 計(jì)算左右填充字符串的長度魔熏,注意要是整數(shù)
// C++ 中 5/2 結(jié)果是 2
// 3. 生成左右兩個(gè)填充字符串
// 4. 拼接字符串, 并返回結(jié)果
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);
}
}
}
// 測試函數(shù)
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");
}
// 作業(yè) 5
//
bool
isSpace(const string &s) {
// 檢查 s 中是否只包含空格
// 返回 布爾值
// 如果 s 中包含的只有空格則返回 true
// 否則返回 false
// 提示:
// 遍歷 s 中的所有字符, 其中如果包含非空格字符, 返回 false, 否則返回 true
// 實(shí)現(xiàn)步驟
// 1. 如果是一個(gè)空字符串返回 false
// 2. 遍歷 s 中的每個(gè)字符
// 3. 如果字符不是空格, 返回 false
// 4. 在循環(huán)結(jié)束后, 返回 true
if (s == "") {
return false;
}
else {
int i = 0;
while (i < s.length()) {
if (s[i] != ' ') {
return false;
}
i++;
}
return true;
}
}
// 測試函數(shù)
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 函數(shù)
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;
}
}
// 作業(yè) 6
//
bool
isDigit(const string &s) {
// 檢查 s 中是否只包含數(shù)字
// 返回: 布爾值
// 提示:
// 類似于作業(yè) 5, 判斷的條件從空格變?yōu)榱藬?shù)字
// 實(shí)現(xiàn)步驟
// 1. 復(fù)制 isSpace 函數(shù)中的代碼
// 2. 將判斷字符是否為空格的部分改為判斷是否為數(shù)字
// 通過判斷字符是否在字符串 "0123456789" 中, 來判斷其是否為數(shù)字
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;
}
}
// 測試函數(shù)
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");
}
// 作業(yè) 7
//
string
stripLeft(const string &s) {
// 返回一個(gè)「刪除了字符串開始的所有空格」的字符串
// 返回 string
// 實(shí)現(xiàn)步驟
// 從左側(cè)遍歷字符串, 記錄第一個(gè)非空格字符的位置, 并由此切割字符串
// 1. 使用作業(yè) 5 的 isSpace 函數(shù)來判斷 s 是否只包含空格衷咽,
// 如果 s 只包含空格,返回空字符串
// 2. 遍歷字符串找到不是空格的字符的下標(biāo)
// 3. 切片并返回
// string 的切片方法如下
// 0123456789
// string s = "kuaibiancheng";
// string s1 = s.substr(2, 5);
// 結(jié)果是 aibia
// 第一個(gè)參數(shù)表示開始的下標(biāo)蒜绽,第二個(gè)參數(shù)表示切片的個(gè)數(shù)
int len = s.length();
int i = 0;
while (i < len) {
if (s[i] != ' ') {
return s.substr(i, len - i);
}
i++;
}
return "";
}
// 測試函數(shù)
void
testStripLeft() {
log("----------------------");
ensure(stripLeft(" gua") == "gua", "stripLeft 測試 1");
ensure(stripLeft(" gua ") == "gua ", "stripLeft 測試 2");
ensure(stripLeft("") == "", "stripLeft 測試 3");
ensure(stripLeft(" ") == "", "stripLeft 測試 4");
}
// 作業(yè) 8
//
string
stripRight(const string &s) {
// 返回一個(gè)「刪除了字符串末尾的所有空格」的字符串
// 提示:
// 類似于作業(yè) 7
// 區(qū)別在于這次需要從右至左遍歷字符串
// 實(shí)現(xiàn)步驟
// 1. 創(chuàng)建一個(gè)循環(huán), 從右到左遍歷字符串
// 從右到左遍歷的方式是讓數(shù)字從 n 到 0
// 2. 遍歷字符串找到不是空格的字符的下標(biāo)
// 3. 切片并返回
int len = s.length();
int i = len - 1;
while (i >= 0) {
if (s[i] != ' ') {
return s.substr(0, i + 1);
}
i--;
}
return "";
}
// 測試函數(shù)
void
testStripRight() {
log("----------------------");
ensure(stripRight("gua") == "gua", "stripRight 測試 1");
ensure(stripRight(" gua ") == " gua", "stripRight 測試 2");
ensure(stripRight("") == "", "stripRight 測試 3");
ensure(stripRight(" ") == "", "stripRight 測試 4");
}
// 作業(yè) 9
//
string
strip(const string &s) {
// 返回一個(gè)「刪除了字符串首尾的所有空格」的字符串
// 返回 string
// 提示:
// 依次調(diào)用作業(yè) 7 和作業(yè) 8 中的函數(shù)即可
// 分布提示:
// 1. 調(diào)用 stripLeft
// 2. 對上一步的結(jié)果繼續(xù)調(diào)用 stripRight
// 3. 返回結(jié)果
string result = stripLeft(s);
result = stripRight(result);
return result;
}
// 測試函數(shù)
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;
}
運(yùn)行結(jié)果
運(yùn)行結(jié)果
補(bǔ)充說明
- 因?yàn)闀r(shí)間已經(jīng)晚了镶骗,第十題沒來得及做,如果明天有時(shí)間的話會盡快補(bǔ)上躲雅。希望大家見諒鼎姊!
- 本次代碼在變量命名上出現(xiàn)了不統(tǒng)一的問題,有的時(shí)候是駝峰式的相赁,有的時(shí)候是下劃線分割相寇,據(jù)我以往的認(rèn)知這種分裂是不好的,我后續(xù)會改善钮科。也許C++的編碼規(guī)范允許這樣不同的形式唤衫,我也不太了解。