例题一:格式化输入输出

  • 函数模板的语法:和类模板写法有区别,容易记混格式
  • 手写排序算法:冒泡 / 插入排序的边界容易写错
  • 自定义类 + 运算符重载:Point 类要重载 < 做比较、重载 << 做输出
  • 格式化输入输出:点的输入是 (x,y) 格式,要处理括号、逗号

编写一个对n个元素的数组升序排序的函数模板mysort,其中元素类型可以是基本数据类型,也可以是点对象(按点到原点的距离比较)。(要求不能用C++提供的sort函数模板)

输入

第一行输入测试次数

每次测试输入二行,第1行先输入一个大写字母表示数组类型,I表示整数类型,S表示字符串型,D表示双精度数类型,P表示点,最后输入n表示数组长度。第2行输入n个数据。

输出

每次测试输出一行排序后的结果

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

// 通用冒泡排序函数模板
template<typename T>
void mysort(T arr[], int n) {
    for(int i = 0; i < n-1; ++i) {
        bool flag = false;
        for(int j = 0; j < n-1-i; ++j) {
            if(arr[j] > arr[j+1]) {
                T temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
                flag = true;
            }
        }
        if(!flag) break;
    }
}

// 点类:重载比较运算符供排序使用
class Point {
    double x, y;
public:
    Point() : x(0), y(0) {}
    Point(double x, double y) : x(x), y(y) {}
  bool operator<(const Point& other) const {
        double dist1 = x*x + y*y;
        double dist2 = other.x*other.x + other.y*other.y;
        return dist1 < dist2;
    }
    
    bool operator>(const Point& other) const {
        return other < *this;
    }
    
   friend ostream& operator<<(ostream& out, const Point& p) {
       ios old_fmt(NULL);//1.创建一个格式存档对象 
       //cout的所有格式设置:小数位数,对齐方式,进制都存在ios状态里面
       //old_fmt存之前的格式 
        old_fmt.copyfmt(out);//2.把当前cout的所有格式设置,完整保存下来 
        //把传进来的流对象 out(也就是调用时的 cout)当前的全部格式设置,完整复制到 old_fmt 里 
        out << fixed << setprecision(1);
        out << "(" << p.x << ", " << p.y << ")";//设置的新格式 
        
         out.copyfmt(old_fmt);//把保存的旧格式还原回去 
        return out;
    }//如果不这样做就会改变全局输出格式,导致其他类型数据的输出格式也随之变化 
     friend istream& operator>>(istream& in, Point& p) {
        in >> p.x >> p.y;
        return in;
    }
};

template<typename T>
void printArr(T arr[], int n) {
    for(int i = 0; i < n; ++i) {
        if(i != 0) cout << " ";
        cout << arr[i];
    }
    cout << endl;
}

int main() {
    int t;
    cin >> t;
    while(t--) {
        char type;
        int n;
        cin >> type >> n;
        
        if(type == 'I') {
            int* arr = new int[n];
            for(int i = 0; i < n; ++i) cin >> arr[i];
            mysort(arr, n);
            printArr(arr, n);
            delete[] arr;
        } else if(type == 'D') {
            double* arr = new double[n];
            for(int i = 0; i < n; ++i) cin >> arr[i];
            mysort(arr, n);
            printArr(arr, n);
            delete[] arr;
        } else if(type == 'S') {
            string* arr = new string[n];
            for(int i = 0; i < n; ++i) cin >> arr[i];
            mysort(arr, n);
            printArr(arr, n);
            delete[] arr;
        } else if(type == 'P') {
            Point* arr = new Point[n];
            for(int i = 0; i < n; ++i) cin >> arr[i];
            mysort(arr, n);
            printArr(arr, n);
            delete[] arr;
        }
    }
    return 0;
}

例题二:类模板 + 模板特化

Data 类不只是存数据,它把输入读取、区间越界裁剪、排序、格式化输出一整套业务流程全打包进了类里。

#include <bits/stdc++.h>
#include <iomanip>
using namespace std;

template<typename T>
class Data {
    vector<T> data;
public:
    Data(int n) : data(n) {
        for(int i = 0; i < n; ++i) {
            cin >> data[i];
        }
    }

    void sortRange(int beg, int end) {
        int left = max(beg, 0);
        int right = min(end, (int)data.size());
        if(left >= right) return;
        sort(data.begin() + left, data.begin() + right);
    }

    void show() {
        cout << "[";
        for(int i = 0; i < data.size(); ++i) {
            if(i != 0) cout << ", ";
            cout << data[i];
        }
        cout << "]" << endl;
    }
};

template<>
void Data<float>::show() {
    cout << "[" << fixed << setprecision(1);
    for(int i = 0; i < data.size(); ++i) {
        if(i != 0) cout << ", ";
        cout << data[i];
    }
    cout << "]" << endl;
}

int main() {
    int t;
    cin >> t;
    while(t--) {
        string type;
        int n, x, y;
        char c;
        cin >> type >> n;
        
        cin >> c;
        cin >> x;
        cin >> c;
        cin >> y;
        cin >> c;
        cin >> c;

        if(type == "int") {
            Data<int> d(n);
            d.sortRange(x, y);
            d.show();
        } else if(type == "string") {
            Data<string> d(n);
            d.sortRange(x, y);
            d.show();
        } else if(type == "float") {
            Data<float> d(n);
            d.sortRange(x, y);
            d.show();
        }
    }
    return 0;
}
  • template<>:空尖括号是全特化的标志,模板参数已经全部指定为具体类型,没有占位符了;
  • Data<float>::show():明确说明:这是给 T = float 版本的 Data 类专属的 show 函数;
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐