实验1

任务1.
代码:#include

include

include

include

unsigned char func(unsigned char c);
void test1();
void test2();

int main() {
std::cout << "测试1: 字符串大小写转换\n";
test1();

std::cout << "\n测试2: 字符变换\n";
test2();
}

unsigned char func(unsigned char c) {
if(c == 'z')
return 'a';

if(c == 'Z')
return 'A';

if(std::isalpha(c))
return static_cast(c+1);

return c;
}

void test1() {
std::string s1{"Hello World 2049!"};
std::cout << "s1 = " << s1 << '\n';

std::string s2;
for(auto c: s1)
s2 += std::tolower(c);
std::cout << "s2 = " << s2 << '\n';

std::string s3;
for(auto c: s1)
s3 += std::toupper(c);
std::cout << "s3 = " << s3 << '\n';
}

void test2() {
std::string s1{"I love cosmos!"};
std::cout << "s1 = " << s1 << '\n';

std::string s2(s1.size(), ' ');
std::transform(s1.begin(), s1.end(),
s2.begin(),
func);
std::cout << "s2 = " << s2 << '\n';
}
截图:
3ae43262b01f58f0261a310b82a2dc95
观察与思考:两者的核心区别在于是否改变原序列以及数据去向:

reverse (原地反转)

功能:将指定范围内的元素就地(in-place)反转。
reverse_copy (复制并反转)

功能:将指定范围内的元素反转后,复制到另一个目标位置,原序列保持不变。
三个参数的含义:
std::rotate(first, middle, last)

first:要旋转的范围的起始迭代器。
middle:旋转的“分界点”(或者叫新的首元素)。它必须位于 [first, last) 范围内。
last:要旋转的范围的结束迭代器(不包含此位置)。
如何改变元素顺序(工作原理):
rotate 的作用是将 [middle, last) 范围内的元素移动到容器的前端,将 [first, middle) 范围内的元素移动到容器的后端。可以把它想象成把一段序列看作一个环,然后以 middle 为起点重新展开。

任务2:
代码:#include

include

include

include

include

include

include

// 模板函数声明
template
void output(const T &c);

int generate_random_number();
void test1();
void test2();

int main() {
std::srand(std::time(0)); // 添加随机种子
std::cout << "测试1: \n";
test1();

std::cout << "\n测试2: \n";
test2();
}

// 输出容器对象c中的元素
template
void output(const T &c) {
for(auto &i: c)
std::cout << i << ' ';
std::cout << '\n';
}

// 返回[0, 100]区间内的一个随机整数
int generate_random_number() {
return std::rand() % 101;
}

// 测试1:对容器类对象指定迭代器区间赋值、排序
void test1() {
using namespace std;

vector v0(10); // 创建一个动态数组对象v0, 对象大小为10
generate(v0.begin(), v0.end(), generate_random_number); // 生成随机数填充v0
cout << "v0: "; output(v0);

vector v1{v0};
sort(v1.begin(), v1.end()); // 对整个vector排序
cout << "v1: "; output(v1);

vector v2{v0};
sort(v2.begin()+1, v2.end()-1); // 只对中间部分排序,不包含首尾元素
cout << "v2: "; output(v2);
}

// 测试2:对容器类对象指定迭代器区间赋值、计算最大值/最小值/均值
void test2() {
using namespace std;

vector v0(10);
generate(v0.begin(), v0.end(), generate_random_number);
cout << "v0: "; output(v0);

// 求最大值和最小值
auto min_iter = min_element(v0.begin(), v0.end());
auto max_iter = max_element(v0.begin(), v0.end());
cout << "最小值: " << *min_iter << endl;
cout << "最大值: " << *max_iter << endl;

// 同时求最大值和最小值
auto ans = minmax_element(v0.begin(), v0.end());
cout << "最小值: " << *(ans.first) << endl;
cout << "最大值: " << *(ans.second) << endl;

// 求平均值
double avg1 = accumulate(v0.begin(), v0.end(), 0.0) / v0.size();
cout << "均值: " << fixed << setprecision(2) << avg1 << endl;

sort(v0.begin(), v0.end());
double avg2 = accumulate(v0.begin()+1, v0.end()-1, 0.0) / (v0.size()-2);
cout << "去掉最大值、最小值之后,均值: " << avg2 << endl;
}
截图:
fd7da5b9-fee2-4de7-9154-21608a625688
观察与思考:std::generate 是 C++ 库中的一个算法,它的核心作用是:遍历指定的区间,并用指定的“生成器”函数(或可调用对象)返回的值来覆盖/填充该区间内的每一个元素。
主要优势在于 性能(效率)更高,遍历次数更少。
是的,效果完全相同
Lambda 表达式是 C++11 引入的匿名函数特性,非常适合作为算法的第三个参数(谓词)
任务3:
代码:#include

include

include

include

unsigned char func(unsigned char c);
void test1();
void test2();

int main() {
std::cout << "测试1: 字符串大小写转换\n";
test1();

std::cout << "\n测试2: 字符变换\n";
test2();
}

unsigned char func(unsigned char c) {
if(c == 'z')
return 'a';

if(c == 'Z')
return 'A';

if(std::isalpha(c))
return static_cast(c+1);

return c;
}

void test1() {
std::string s1{"Hello World 2049!"};
std::cout << "s1 = " << s1 << '\n';

std::string s2;
for(auto c: s1)
s2 += std::tolower(c);
std::cout << "s2 = " << s2 << '\n';

std::string s3;
for(auto c: s1)
s3 += std::toupper(c);
std::cout << "s3 = " << s3 << '\n';
}

void test2() {
std::string s1{"I love cosmos!"};
std::cout << "s1 = " << s1 << '\n';

std::string s2(s1.size(), ' ');
std::transform(s1.begin(), s1.end(),
s2.begin(),
func);
std::cout << "s2 = " << s2 << '\n';
}
截图:

c0d77823-dfd9-4884-95fa-f4493ac85cef
观察与思考:转换规则
tolower(int c):将字符转换为小写。如果传入的是大写字母('A'-'Z'),返回其对应的小写字母;如果已经是小写或其他字符,则原样返回。

toupper(int c):将字符转换为大写。如果传入的是小写字母('a'-'z'),返回其对应的大写字母;如果已经是大写或其他字符,则原样返回。
参数 1 (first1):第一个输入序列的起始迭代器(例如 s1.begin())。

参数 2 (last1):第一个输入序列的结束迭代器(例如 s1.end())。

参数 3 (first2):第二个输入序列的起始迭代器(例如 s2.begin())。它指示了从哪里开始读取第二个序列的数据。

参数 4 (result):目标序列的起始迭代器。指示处理后的结果存放到哪里

任务4:
代码:#include

include

include

bool is_palindrome(const std::string &s);
bool is_palindrome_ignore_case(const std::string &s);

int main() {
using namespace std;
string s;

// 多组输入,直到按下Ctrl+Z结束测试
while(cin >> s) {
cout << boolalpha
<< "区分大小写: " << is_palindrome(s) << "\n"
<< "不区分大小写: " << is_palindrome_ignore_case(s) << "\n\n";
}
}

// 函数is_palindrome定义
bool is_palindrome(const std::string &s) {
int left = 0;
int right = s.length() - 1;

while (left < right) {
if (s[left] != s[right]) {
return false; // 只要有一对不相等,就不是回文串
}
left++;
right--;
}
return true; // 所有对应位置都相等,则是回文串
}

// ×××

// 函数is_palindrome_ignore_case定义
bool is_palindrome_ignore_case(const std::string &s) {
int left = 0;
int right = s.length() - 1;

while (left < right) {
// 使用 tolower 将字符统一转换为小写后再比较
if (std::tolower(s[left]) != std::tolower(s[right])) {
return false;
}
left++;
right--;
}
return true;
}
// ×××
截图:
2bb27da2-11f7-4e27-ac5d-bfaedd1ea0cd
观察与思考:
std::getline 函数可以读取一整行,直到遇到换行符 \n 为止,非常适合读取包含空格的字符串
任务5:
代码:#include

include

include

std::string dec2n(int x, int n = 2);

int main() {
int x;
while(std::cin >> x) {
std::cout << "十进制: " << x << '\n'
<< "二进制: " << dec2n(x) << '\n'
<< "八进制: " << dec2n(x, 8) << '\n'
<< "十二进制: " << dec2n(x, 12) << '\n'
<< "十六进制: " << dec2n(x, 16) << '\n'
<< "三十二进制: " << dec2n(x, 32) << "\n\n";
}
}

// 函数dec2n定义
std::string dec2n(int x, int n) {
// 处理特殊情况 0
if (x == 0) return "0";

// 定义字符映射表,支持最大到 36 进制 (0-9, A-Z)
const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

std::string result = "";

// 使用 while 循环不断取余数
while (x > 0) {
result += digits[x % n]; // 计算余数,并通过映射表转换为对应的字符
x /= n; // 将 x 除以基数,继续下一轮
}

// 此时 result 中存放的是低位到高位的字符(逆序的),需要将其反转
std::reverse(result.begin(), result.end());

return result;
}
截图:
f7218784-7e1c-4187-b79a-e0560209a2a4

任务6:
代码:#include

include // 用于 std::setw

int main() {
// 1. 打印第一行:小写字母表
std::cout << " "; // 两个空格,用于对齐下方两位数行号
for (char c = 'a'; c <= 'z'; ++c) {
std::cout << c;
}
std::cout << "\n";

// 2. 打印后续 26 行
for (int i = 1; i <= 26; ++i) {
// 打印行号,宽度为 2,右对齐
std::cout << std::setw(2) << i;

// 打印每一行的 26 个大写字母
for (int j = 0; j < 26; ++j) {
// 计算当前要打印的字母偏移量
// i=1时,j=0 应打印 'A',所以初始偏移是 i-1
// 加上 j 后,如果超过 25 (即超过了 'Z'),就通过取余数 % 26 循环回到 'A'
int char_offset = (i - 1 + j) % 26;

// 将偏移量转换回大写字母
char c = 'A' + char_offset;
std::cout << c;
}
std::cout << "\n";
}

return 0;
}
截图:
091e44fc-6448-4d26-9c91-af7d36a8e297

任务7:
代码:#include

include // 用于 rand(), srand()

include // 用于 time()

include // 用于 setprecision(), fixed 格式化输出

using namespace std;

int main() {
// 设置随机数种子,确保每次运行生成的题目不同
srand(time(0));

int correct_count = 0; // 记录答对的题目数量
const int TOTAL_QUESTIONS = 10;

// 循环生成 10 道题目
for (int i = 0; i < TOTAL_QUESTIONS; ++i) {
int num1, num2, correct_answer, user_answer;
char op;

// 1. 随机生成运算符 (0:+, 1:-, 2:, 3:/)
int op_type = rand() % 4;
switch (op_type) {
case 0:
op = '+';
num1 = rand() % 10 + 1; // 1~10
num2 = rand() % 10 + 1;
correct_answer = num1 + num2;
break;
case 1:
op = '-';
// 要求减法被减数 >= 减数
num1 = rand() % 10 + 1;
num2 = rand() % 10 + 1;
if (num1 < num2) swap(num1, num2);
correct_answer = num1 - num2;
break;
case 2:
op = '
';
num1 = rand() % 10 + 1;
num2 = rand() % 10 + 1;
correct_answer = num1 * num2;
break;
case 3:
op = '/';
// 要求整除,最简单的方法是先随机生成除数和商,再算被除数
num2 = rand() % 10 + 1; // 除数 1~10
correct_answer = rand() % 10 + 1; // 商 1~10
num1 = num2 * correct_answer; // 被除数 = 除数 * 商 (保证能整除)
break;
}

// 2. 输出题目并读取用户输入
cout << num1 << " " << op << " " << num2 << " = ";
cin >> user_answer;

// 3. 判断对错并计分
if (user_answer == correct_answer) {
correct_count++;
}
}

// 4. 计算正确率并输出(保留两位小数)
double accuracy = (static_cast(correct_count) / TOTAL_QUESTIONS) * 100.0;

cout << "正确率: " << fixed << setprecision(2) << accuracy << "%" << endl;

return 0;
}
截图:
1bce7574-c5c9-4bf9-8904-85e7a2c558ba

posted @ 2026-10-18 21:09  王轶轩  阅读(3)  评论(0)    收藏  举报