[C++/PTA] 数据的间距问题(重载+函数模板)

简介: [C++/PTA] 数据的间距问题(重载+函数模板)

题目要求

三个类如下设计:类cTime有三个数据成员,hh,mm,ss,分别代表时,分和秒,并有若干构造函数和一个重载-(减号)的成员函数。类point有两个数据成员,x,y分别坐标,并有若干构造函数和一个重载-(减号)的成员函数。类date有三个数据成员,year,month,day分别代表年月日,并有若干构造函数和一个重载-(减号)的成员函数。

要求设计一个函数模板template <\class T>\ double dist(T a, T b) 对int,float,cTime,point和date或者其他类型的数据,返回间距。

其中,hh = 3600 * ss, mm = 60 * ss, year = 365 * day, month = 30 * day,对于cTime和date类型,数据在转换成ss或者day后进行运算。

输入格式:

每一行为一个操作,每行的第一个数字为元素类型,1为整型元素,2为浮点型元素,3为point类型,4,为time类型,5为date类型,若为整型元素,接着输入两个整型数据,

若为浮点型元素,接着输入两个浮点型数据,若为point型元素,输入两个point型数据(x1 y1 x2 y2),若为time型元素, 输入两个cTime型数据(hh1 mm1 ss1 hh2 mm2 ss2),若为date型数据,输入两个date型数据(year1 month1 day1 year2 month2 day2)。输入0时标志输入结束。

输出格式:

对每个输入,每行输出一个间距值。

样例输入:

1 2 5

4 18 21 22 18 20 31

3 2 4 5 9

5 2013 5 14 2013 5 15

2 2.2 9.9

0

样例输出:

3

51

5.83095

1

7.7

解题思路

定义 4 个类:Point、Time、Date 和一个未命名类(类别编号为 1 或 2 时使用),分别表示点、时间和日期。

在主函数中,首先读入一个整数 classType,代表后面要进行的操作类型。如果 classType 为 0,则退出循环。否则,根据 classType 的值选择不同的操作。

当 classType 为 1 或 2 时,使用未命名类进行操作,读入两个元素 a 和 b,并输出其差的绝对值。
当 classType 为 3 时,使用 Point 类进行操作,读入两个点 a 和 b,并输出两点之间的距离。
当 classType 为 4 时,使用 Time 类进行操作,读入两个时间 a 和 b,
并输出两个时间之间的时间间隔。
当 classType 为 5 时,使用 Date 类进行操作,读入两个日期 a 和 b,
并输出两个日期之间的日期间隔天数。

每个类都有一个构造函数,默认将类的成员变量初始化为 0。

每个类都有一个 set 函数,用于设置类的成员变量。

每个类都有一个重载的输入运算符 >>,用于从标准输入读入数据并设置类的各个成员变量。

除了未命名类外,其他三个类都重载了 - 运算符,用于计算类对象之间的差。

代码

#include<iostream>
#include<cmath>
using namespace std;
// 定义Time类
class Time {
private:
    int hh; // 时
    int mm; // 分
    int ss; // 秒
public:
    Time() { // 构造函数
        hh = 0;
        mm = 0;
        ss = 0;
    }
    void set(int h, int m, int s) { // 设置 hh,mm,ss 的值
        hh = h;
        mm = m;
        ss = s;
    }
    friend int operator-(Time, Time); // 友元函数,重载 - 运算符
    friend istream& operator>>(istream&, Time&); // 友元函数,重载输入运算符 >>
};
// 重载输入运算符 >>
istream& operator>>(istream& set, Time& t) {
    set >> t.hh >> t.mm >> t.ss; // 从标准输入中读入数据
    return set;
}
// 重载 - 运算符 
int operator-(Time t1, Time t2) {
    int totalSecond1 = t1.hh * 3600 + t1.mm * 60 + t1.ss; // 计算总秒数
    int totalSecond2 = t2.hh * 3600 + t2.mm * 60 + t2.ss;
    return totalSecond2 - totalSecond1; // 返回时间间隔
}
// 定义Date类
class Date {
private:
    int year; // 年
    int month; // 月
    int day; // 日
public:
    Date() { // 构造函数
        year = 0;
        month = 0;
        day = 0;
    }
    void set(int y, int m, int d) { // 设置 year,month,day 的值
        year = y;
        month = m;
        day = d;
    }
    friend int operator-(Date, Date); // 友元函数,重载 - 运算符
    friend istream& operator>>(istream&, Date&); // 友元函数,重载输入运算符 >>
};
// 重载输入运算符 >>
istream& operator>>(istream& set, Date& d) {
    set >> d.year >> d.month >> d.day; // 从标准输入中读入数据
    return set;
}
// 重载 - 运算符 
int operator-(Date d1, Date d2) {
    int totalDay1 = d1.year * 365 + d1.month * 30 + d1.day; // 计算总天数
    int totalDay2 = d2.year * 365 + d2.month * 30 + d2.day;
    return totalDay1 - totalDay2; // 返回日期间隔天数
}
// 定义 Point 类
class Point {
private:
    int x;
    int y;
public:
    Point() { // 构造函数
        x = y = 0;
    }
    void set(int a, int b) { // 设置 x 和 y 的值
        x = a;
        y = b;
    }
    friend double operator-(Point, Point); // 友元函数,重载 - 运算符
    friend istream& operator>>(istream&, Point&); // 友元函数,重载输入运算符 >>
};
// 重载输入运算符 >>
istream& operator>>(istream& set, Point& p) {
    set >> p.x >> p.y; // 从标准输入中读入数据
    return set;
}
// 重载 - 运算符 
double operator-(Point p1, Point p2) {
    return sqrt((1.0 * p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y)); // 返回点间距离
}
// 主函数
int main() {
    int classType;
    while (cin >> classType) { // 循环读入类别
        if (classType == 0) break; // 若为 0,则退出循环
        switch (classType) { // 根据类别选择不同的操作
            case 1: { // 整型元素
                int a, b;
                cin >> a >> b;
                cout << abs(b - a) << endl; // 输出 a 和 b 之间的距离
                break;
            }
            case 2: { // 浮点型元素
                double a, b;
                cin >> a >> b;
                cout << abs(b - a) << endl; // 输出 a 和 b 之间的距离
                break;
            }
            case 3: { // Point 类型
                Point a, b;
                cin >> a >> b;
                cout << abs(b - a) << endl; // 输出 a 和 b 之间的距离
                break;
            }
            case 4: { // Time 类型
                Time a, b;
                cin >> a >> b;
                cout << abs(b - a) << endl; // 输出 a 和 b 之间的时间间隔
                break;
            }
            case 5: { // Date 类型
                Date a, b;
                cin >> a >> b;
                cout << abs(b - a) << endl; // 输出 a 和 b 之间的日期间隔天数
                break;
            }
        }
    }
    return 0;
}

总结

该题结合重载函数模板考察数据的间距问题,读者可躬身实践。

我是秋说,我们下次见。

目录
相关文章
|
13天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
40 12
|
4天前
|
存储 监控 算法
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
12 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
|
15天前
|
编译器 C++
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
㉿㉿㉿c++模板的初阶(通俗易懂简化版)㉿㉿㉿
|
2天前
|
安全 C++
【c++】模板详解(2)
本文深入探讨了C++模板的高级特性,包括非类型模板参数、模板特化和模板分离编译。通过具体代码示例,详细讲解了非类型参数的应用场景及其限制,函数模板和类模板的特化方式,以及分离编译时可能出现的链接错误及解决方案。最后总结了模板的优点如提高代码复用性和类型安全,以及缺点如增加编译时间和代码复杂度。通过本文的学习,读者可以进一步加深对C++模板的理解并灵活应用于实际编程中。
9 0
|
13天前
|
存储 安全 算法
深入理解C++模板编程:从基础到进阶
在C++编程中,模板是实现泛型编程的关键工具。模板使得代码能够适用于不同的数据类型,极大地提升了代码复用性、灵活性和可维护性。本文将深入探讨模板编程的基础知识,包括函数模板和类模板的定义、使用、以及它们的实例化和匹配规则。
|
2月前
|
存储 算法 搜索推荐
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
47 5
|
4月前
|
安全 编译器 C++
【C++11】可变模板参数详解
本文详细介绍了C++11引入的可变模板参数,这是一种允许模板接受任意数量和类型参数的强大工具。文章从基本概念入手,讲解了可变模板参数的语法、参数包的展开方法,以及如何结合递归调用、折叠表达式等技术实现高效编程。通过具体示例,如打印任意数量参数、类型安全的`printf`替代方案等,展示了其在实际开发中的应用。最后,文章讨论了性能优化策略和常见问题,帮助读者更好地理解和使用这一高级C++特性。
131 4
|
4月前
|
算法 编译器 C++
【C++】模板详细讲解(含反向迭代器)
C++模板是泛型编程的核心,允许编写与类型无关的代码,提高代码复用性和灵活性。模板分为函数模板和类模板,支持隐式和显式实例化,以及特化(全特化和偏特化)。C++标准库广泛使用模板,如容器、迭代器、算法和函数对象等,以支持高效、灵活的编程。反向迭代器通过对正向迭代器的封装,实现了逆序遍历的功能。
53 3
|
4月前
|
编译器 C++
【c++】模板详解(1)
本文介绍了C++中的模板概念,包括函数模板和类模板,强调了模板作为泛型编程基础的重要性。函数模板允许创建类型无关的函数,类模板则能根据不同的类型生成不同的类。文章通过具体示例详细解释了模板的定义、实例化及匹配原则,帮助读者理解模板机制,为学习STL打下基础。
52 0
|
13天前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。