实验1

任务1:

体会面向对象设计中封装、暴露接口(interface)、基于接口编程的意义

代码:
// 现代C++标准库、算法库体验
// 本例用到以下内容:
// 1. 字符串string, 动态数组容器类vector、迭代器
// 2. 算法库:反转元素次序、旋转元素
// 3. 函数模板、const引用作为形参

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

using namespace std;

// 声明
// 模板函数声明
template<typename T>
void output(const T &c);
// 普通函数声明
void test1();
void test2();
void test3();

int main() {
    cout << "测试1: \n";
    test1();

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

    cout << "\n测试3: \n";
    test3();
}

// 函数实现
// 输出容器对象c中的元素
template <typename T>
void output(const T &c) {
    for(auto &i: c)
        cout << i << " ";
    cout << endl;
}

// 测试1
// 组合使用算法库、迭代器、string反转字符串
void test1() {
    string s0{"0123456789"};
    cout << "s0 = " << s0 << endl;

    string s1{s0};
    reverse(s1.begin(), s1.end());  // 反转指定迭代器区间的元素
    cout << "s1 = " << s1 << endl;

    string s2{s0};
    reverse_copy(s0.begin(), s0.end(), s2.begin()); // 将指定迭代区间的元素拷贝到指定迭代器开始的目标区间,并且在复制过程中反转次序
    cout << "s2 = " << s2 << endl;
}

// 测试2
// 组合使用算法库、迭代器、vector反转动态数组对象vector内数据
void test2() {
    vector<int> v0{2, 0, 4, 9};
    cout << "v0: ";
    output(v0);

    vector<int> v1{v0};
    reverse(v1.begin(), v1.end());
    cout << "v1: ";
    output(v1);

    vector<int> v2{v0};
    reverse_copy(v0.begin(), v0.end(), v2.begin());
    cout << "v2: ";
    output(v2);
}

// 测试3
// 组合使用算法库、迭代器、vector实现元素旋转移位
void test3() {
    vector<int> v0{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    cout << "v0: ";
    output(v0);

    vector<int> v1{v0};
    rotate(v1.begin(), v1.begin()+1, v1.end());  // 旋转指定迭代器区间[v1.begin(), v1.end())之间的数据项,旋转后从迭代器v1.begin()+1位置的数据项开始
    cout << "v1: ";
    output(v1);

    vector<int> v2{v0};
    rotate(v2.begin(), v2.begin()+2, v2.end());
    cout << "v2: ";
    output(v2);

    vector<int> v3{v0};
    rotate(v3.begin(), v3.end()-1, v3.end());
    cout << "v3: ";
    output(v3);

    vector<int> v4{v0};
    rotate(v4.begin(), v4.end()-2, v4.end());
    cout << "v4: ";
    output(v4);
}

编译结果:



任务2:

体验使用C++标准库高效编程解决基础问题 (对指定区间进行排序、赋值;求最大值、最小值、均值)

代码:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
#include <iomanip>

using namespace std;

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

// 普通函数声明
int rand_int_100();
void test1();
void test2();

int main() {
    cout << "测试1: \n";
    test1();

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

// 函数实现
// 输出容器对象c中的元素
template <typename T>
void output(const T &c) {
    for(auto &i: c)
        cout << i << " ";
    cout << endl;
}

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

// 测试1
// 对容器类对象指定迭代器区间进行赋值、排序
void test1() {
    vector<int> v0(10);  // 创建一个动态数组对象v0, 对象大小为10
    generate(v0.begin(), v0.end(), rand_int_100); // 产生[0, 100]之间的随机整数赋值给指定迭代器区间[v0.begin(), v0.end())内的每个数据项
    cout << "v0: ";
    output(v0);

    vector<int> v1{v0};
    sort(v1.begin(), v1.end()); // 对指定迭代器区间[v1.begin(), v1.end())内数据项进行升序排序
    cout << "v1: ";
    output(v1);

    vector<int> v2{v0};
    sort(v2.begin()+1, v2.end()-1); // 对指定迭代器区间[v1.begin()+1, v1.end()-1)内数据项进行升序排序
    cout << "v2: ";
    output(v2);
}

// 测试2
// 对容器类对象指定迭代器区间进行赋值、计算最大值/最小值/均值
void test2() {
    vector<int> v0(10);  
    generate(v0.begin(), v0.end(), rand_int_100); 
    cout << "v0: ";
    output(v0);

    auto iter1 = min_element(v0.begin(), v0.end());
    cout << "最小值: " << *iter1 << endl;

    auto iter2 = max_element(v0.begin(), v0.end());
    cout << "最大值: " << *iter2 << 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)/v0.size();
    cout << "均值: " << fixed << setprecision(2) << avg1 << endl;

    cout << endl;

    vector<int> v1{v0};
    cout << "v0: ";
    output(v0);
    sort(v1.begin(), v1.end());
    double avg2 = accumulate(v1.begin()+1, v1.end()-1, 0)/(v1.size()-2);
    cout << "去掉最大值、最小值之后,均值: " << avg2 << endl;
}

编译结果:



任务3:

编写程序,实现判断回文串

代码:
#include <iostream>
#include <string>
#include <algorithm>

bool is_palindrome(std::string s);

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

    while(cin >> s)  // 多组输入,直到按下Ctrl+Z后结束测试
        cout << boolalpha << is_palindrome(s) << endl;
}

// 函数is_palindrom定义
// 待补足
// ×××

根据上面代码我们可知判断逻辑还未完成,所以我们只需要对翻转后的字符串与源字符串进行比较即可

待补全代码:
bool is_palindrome(std::string s)
{
	std::string reversed_s(s.rbegin(),s.rend());
	return reversed_s == s;
}

编译结果:



任务4:

编写程序实现进制转换

代码:
#include <iostream>
#include <string>
#include <algorithm>

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

int main() {
    using namespace std;

    int x;
    while(cin >> x) {
        cout << "十进制: " << x << endl;
        cout << "二进制: " << dec2n(x) << endl;
        cout << "八进制: " << dec2n(x, 8) << endl;
        cout << "十六进制: " << dec2n(x, 16) << endl << endl;
    }
}

// 函数dec2n定义
// 待补足
// ×××


当我们进行十进制数转换为其他进制时,被除数对除数进行取余操作,并在取余之后对被除数进行除10的操作,直到被除数商为0为止,这时候余数进行倒序排序便是被转换之后的数

但如果余数有大于10的怎么办呢?比如说我们进行10转16进制,这个时候我们要对余数进行处理,判断是否大于10,再按照A-F进行处理

待补全代码:
std::string dec2n(int x,int n)
{
	if(x==0) return "0";
	std::string s;
	char digit;
	while(x!=0)
	{
		int reminder = x%n;
		if(reminder<10)
		{
			digit = '0'+reminder;
		 } else
		 {
		 	digit = 'A'+(reminder-10);
		 }
		 s+=digit;
		 x/=n;
	}
	std::string reversed_s(s.rbegin(),s.rend());
  	return reversed_s;
}

编译结果:



任务5:

编写一个程序,在屏幕上打印字母密文对照表。

代码:
#include <iostream>  
#include <iomanip>  
using namespace std;  
  
void outPassword() {  
    const int alphabetSize = 26;  
    char alphabetStart = 'a';  
  
    // 打印原始字母表作为标题行  
    cout << "  " <<" ";  
    for (char x = alphabetStart; x <= alphabetStart + alphabetSize - 1; ++x) {  
        cout << setw(2) << x;  
    }  
    cout << endl;  
    // 打印凯撒密码表  
    for (int shift = 0; shift < alphabetSize; ++shift) {  
        cout << setw(2) << shift << " ";  
        for (char x = alphabetStart; x <= alphabetStart + alphabetSize - 1; ++x) {  
            char shiftedChar = 'a' + (x - alphabetStart + shift) % alphabetSize;  
            cout << setw(2) << shiftedChar;  
        }  
        cout << endl;  
    }  
}  
  
int main() {  
    outPassword();  
    return 0;  
}

编译结果:



任务6:

编写一个程序,实现自动生成算术运算题目并自动评测。

代码:
#include <iostream>  
#include <cstdlib>  
#include <ctime>  
#include <iomanip>  
  
using namespace std;  
  
// 生成随机数,范围在[min, max]之间  
int randInRange(int min, int max) {  
    return min + rand() % (max - min + 1);  
}  
  
// 生成随机的算术题目  
void generateQuestion(int& num1, char& operation, int& num2, int& answer) {  
    int opType = rand() % 4; // 0: 加, 1: 减, 2: 乘, 3: 除  
    num1 = randInRange(1, 10);  
    num2 = 1; // 初始化为1,稍后再根据运算类型调整  
    answer = 0; // 初始化为0,稍后再计算正确答案  
  
    switch (opType) {  
        case 0: // 加法  
            operation = '+';  
            num2 = randInRange(1, 10);  
            answer = num1 + num2;  
            break;  
        case 1: // 减法  
            operation = '-';  
            num2 = randInRange(1, num1 - 1); // 确保num1 > num2  
            answer = num1 - num2;  
            break;  
        case 2: // 乘法  
            operation = '*';  
            num2 = randInRange(1, 10);  
            answer = num1 * num2;  
            break;  
        case 3: // 除法  
            operation = '/';  
            // 找到一个能整除num1的num2  
            for (int i = 1; i <= num1; ++i) {  
                if (num1 % i == 0) {  
                    num2 = i;  
                    answer = num1 / num2;  
                    break;  
                }  
            }  
            // 注意:这里假设了总能找到一个除数(因为num1在1到10之间,所以总能被1整除)  
            // 在实际应用中,可能需要更复杂的逻辑来确保总能生成题目  
            break;  
    }  
}  
  
int main() {  
    srand(time(0)); // 以当前时间作为随机数种子,确保每次运行生成的题目不同  
    int correctCount = 0;  
    for (int i = 0; i < 10; ++i) {  
        int num1, num2, userAnswer, correctAnswer;  
        char operation;  
        generateQuestion(num1, operation, num2, correctAnswer);  
  
        // 输出题目  
        cout << num1 << " " << operation << " " << num2 << " = ";  
        cin >> userAnswer;  
  
        // 判断答案是否正确  
        if (userAnswer == correctAnswer) {  
            correctCount++;  
        }  
    }  
  
    // 计算并输出正确率  
    double accuracy = static_cast<double>(correctCount) / 10 * 100;  
    cout << fixed << setprecision(2) << "正确率: " << accuracy << "%" << endl;  
  
    return 0;  
}

编译结果:

posted @ 2024-10-15 21:00  22软件一班毛俊东  阅读(7)  评论(0编辑  收藏  举报