课后作业

2024/4/29

# 第二十一课

# 1. 假设你是一家电子商务公司的数据分析师,你的公司每天都会收集到大量的销售订单数据。现在,你需要编写一个程序,使用C++实现冒泡排序算法,来对一天内的销售订单按照销售额进行录入后排序存储

订单数据包括订单号、产品名称、销售数量和销售金额。你需要按照销售金额从高到低的顺序对订单进行排序,并输出排序后的订单信息

// 结构体示例
struct Order {
    string orderNumber;
    string productName;
    int quantity;
    double amount;
};
// 输入输出示例:
请输入订单数量:3
请输入第 1 个订单的信息:
订单号: 20220429001
产品名称: 手机
销售数量: 20
销售金额: 6000.0
请输入第 2 个订单的信息:
订单号: 20220429002
产品名称: 电脑
销售数量: 10
销售金额: 8000.0
请输入第 3 个订单的信息:
订单号: 20220429003
产品名称: 平板
销售数量: 15
销售金额: 4500.0
排序后的订单信息:
订单号: 20220429002, 产品名称: 电脑, 销售数量: 10, 销售金额: 8000
订单号: 20220429001, 产品名称: 手机, 销售数量: 20, 销售金额: 6000
订单号: 20220429003, 产品名称: 平板, 销售数量: 15, 销售金额: 4500
  • 历史解析
    • 整体题解思路正确,本题主要考查结构体冒泡排序,没有问题💯

# 2. 假设你是一家物流公司的调度员,你负责安排货车按照货物的重量从重到轻进行装载。现在,你需要编写一个程序,使用C++实现选择排序算法,来对一批货物按照重量进行排序,并输出装载顺序

货物数据包括货物编号、货物名称和重量。你需要按照货物的重量从大到小的顺序对货物进行排序,并输出排序后的装载顺序

// 结构体示例
struct Cargo {
    string cargoNumber;
    string cargoName;
    double weight;
};
// 输入输出示例
请输入货物数量:3
请输入第 1 个货物的信息:
货物编号: 001
货物名称: 电视
重量: 150.2
请输入第 2 个货物的信息:
货物编号: 002
货物名称: 冰箱
重量: 200.5
请输入第 3 个货物的信息:
货物编号: 003
货物名称: 洗衣机
重量: 180.0
装载顺序:
货物编号: 002, 货物名称: 冰箱, 重量: 200.5
货物编号: 003, 货物名称: 洗衣机, 重量: 180
货物编号: 001, 货物名称: 电视, 重量: 150.2
  • 历史解析
    • 整体题解思路正确,本题主要考查结构体选择排序,没有问题💯

# 3. 假设你是一家电商平台的数据分析师,你需要统计用户购买商品的总金额,并计算平均每笔订单的金额。但是,由于订单量巨大,订单金额可能超过了 C++ 中 intlong long 的表示范围,因此你需要使用高精度数来处理。现在,请你设计一个程序,输入每个订单的金额,直到输入为负数为止(负数标志着输入结束),然后计算总金额平均每笔订单的金额,并输出

// 输入输出示例
请输入每个订单的金额(负数表示输入结束):
100
200
300
400
-1
总金额为:1000
平均每笔订单的金额为:250
  • 历史解析

    • 根据题目要求,订单金额可能超过了 C++ 中 intlong long 的表示范围,而你当前使用的是 long long 类型,即无法保证基础输入条件,故直接错误
    • 对于此题,我们需要使用高精度数来处理,即需要自己实现高精度数的加法与高精低精除法,而你的代码中并没有实现高精度运算,故直接错误
  • 参考答案

#include <iostream>
#include <string>
#include <cstring> // 包含C风格字符串处理函数的头文件
#include <algorithm> // 包含reverse函数

using namespace std;

// 高精度数加法
string add(string num1, string num2) {
    int len1 = num1.size();
    int len2 = num2.size();
    int maxlen = max(len1, len2); // 找到最长的字符串长度
    string result(maxlen, '0'); // 初始化结果字符串为最长字符串长度,并填充为 '0'

    int carry = 0; // 进位初始化为 0

    // 从个位开始逐位相加
    for (int i = maxlen - 1; i >= 0; i--) {
        int digit1 = (i < len1) ? (num1[i] - '0') : 0; // 如果num1长度不够,用 0 补齐
        int digit2 = (i < len2) ? (num2[i] - '0') : 0; // 如果num2长度不够,用 0 补齐
        int sum = digit1 + digit2 + carry; // 当前位相加结果加上进位
        result[i] = (sum % 10) + '0'; // 取个位数作为当前结果的数字
        carry = sum / 10; // 计算进位
    }

    // 如果最高位有进位,需要在结果前面再加上一位
    if (carry > 0) {
        result.insert(result.begin(), carry + '0');
    }
    
    return result;
}

// 高精度除法除以低精度
string divide(string num, int divisor) {
    int len = num.size();
    string result(len, '0'); // 初始化结果字符串为原字符串长度,并填充为 '0'

    int remainder = 0; // 余数初始化为 0

    // 逐位进行长除法
    for (int i = 0; i < len; i++) {
        remainder = remainder * 10 + (num[i] - '0');
        result[i] = (remainder / divisor) + '0';
        remainder %= divisor;
    }

    // 移除结果字符串前面的零
    result.erase(0, min(result.find_first_not_of('0'), result.size() - 1));

    return result;
}

int main() {
    cout << "请输入每个订单的金额(负数表示输入结束):" << endl;

    string totalAmount = "0"; // 总金额初始化为 "0"
    int count = 0;

    string input;
    while (true) {
        cin >> input;
        if (input == "-1") {
            break;
        }

        totalAmount = add(totalAmount, input);
        count++;
    }

    if (count == 0) {
        cout << "未输入任何订单金额!" << endl;
    } else {
        string average = divide(totalAmount, count);
        
        cout << "总金额为:" << totalAmount << endl;
        cout << "平均每笔订单的金额为:" << average << endl;
    }

    return 0;
}
上次更新: 2024-10-19 10:01:51