算法设计与分析之C++习题

一 参考C++ STL的string类构造一个自定义的字符串类

构造一个自定义的字符串类类似于 C++ 标准库中的 std::string,需要支持字符串的动态分配、拷贝、拼接、访问字符等基本操作。我们可以从构造函数、析构函数、运算符重载、以及常见的字符串操作函数等方面来设计这个类。

1. 基本思路

  • 存储方式:字符串本质是一个字符数组,我们可以用一个指针来存储字符串数据,并通过动态分配内存来管理字符数组。
  • 长度管理:使用一个变量来存储字符串的长度。
  • 内存管理:实现拷贝构造函数、赋值运算符和析构函数以避免内存泄漏和重复分配。
  • 功能实现:添加一些常见的功能,比如字符串拼接、访问单个字符、获取字符串长度等。

2. 代码实现

#include <iostream>
#include <cstring>  // 用于 std::strlen 和 std::strcpy

class MyString {
private:
    char* data;  // 存储字符串数据
    size_t length;  // 存储字符串的长度

public:
    // 默认构造函数
    MyString() : data(nullptr), length(0) {}

    // 带参数的构造函数
    MyString(const char* str) {
        if (str) {
            length = std::strlen(str);  // 获取传入字符串的长度
            data = new char[length + 1];  // 为字符串分配内存(+1 为了放终止符 '\0')
            std::strcpy(data, str);  // 复制字符串数据
        } else {
            data = nullptr;
            length = 0;
        }
    }

    // 拷贝构造函数
    MyString(const MyString& other) {
        length = other.length;
        data = new char[length + 1];  // 分配新的内存
        std::strcpy(data, other.data);  // 复制字符串数据
    }

    // 移动构造函数 (C++11)
    MyString(MyString&& other) noexcept : data(other.data), length(other.length) {
        other.data = nullptr;  // 转移所有权,防止双重释放
        other.length = 0;
    }

    // 析构函数
    ~MyString() {
        delete[] data;  // 释放内存
    }

    // 赋值运算符重载 (拷贝赋值)
    MyString& operator=(const MyString& other) {
        if (this == &other) {
            return *this;  // 防止自我赋值
        }

        delete[] data;  // 释放当前对象的内存

        length = other.length;
        data = new char[length + 1];  // 分配新内存
        std::strcpy(data, other.data);  // 复制数据

        return *this;
    }

    // 赋值运算符重载 (移动赋值) (C++11)
    MyString& operator=(MyString&& other) noexcept {
        if (this == &other) {
            return *this;
        }

        delete[] data;  // 释放当前对象的内存

        data = other.data;  // 转移所有权
        length = other.length;
        other.data = nullptr;
        other.length = 0;

        return *this;
    }

    // 重载加号运算符,用于字符串拼接
    MyString operator+(const MyString& other) const {
        size_t newLength = length + other.length;
        char* newData = new char[newLength + 1];

        std::strcpy(newData, data);  // 复制第一个字符串
        std::strcat(newData, other.data);  // 拼接第二个字符串

        MyString newString(newData);  // 构造新字符串对象
        delete[] newData;  // 释放临时的内存
        return newString;
    }

    // 获取字符串长度
    size_t size() const {
        return length;
    }

    // 获取字符串数据
    const char* c_str() const {
        return data;
    }

    // 重载 [] 操作符,访问字符
    char& operator[](size_t index) {
        if (index >= length) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    const char& operator[](size_t index) const {
        if (index >= length) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    // 输出流重载,用于打印字符串
    friend std::ostream& operator<<(std::ostream& os, const MyString& str) {
        os << str.data;
        return os;
    }
};

int main() {
    MyString str1("Hello");
    MyString str2(" World!");

    MyString str3 = str1 + str2;  // 拼接字符串
    std::cout << "Concatenated string: " << str3 << std::endl;  // 输出 Hello World!

    str1[0] = 'h';  // 修改字符
    std::cout << "Modified str1: " << str1 << std::endl;  // 输出 hello

    return 0;
}

3. 代码解释

(1) 构造函数与析构函数
  • 默认构造函数:构造一个空字符串(即 data 指向 nullptr)。
  • 带参数的构造函数:根据传入的 C 风格字符串初始化 MyString 对象。
  • 拷贝构造函数:深拷贝,确保两个对象拥有独立的字符串内存。
  • 移动构造函数:将另一个对象的资源“转移”给当前对象,避免不必要的内存分配和释放。
  • 析构函数:释放动态分配的内存。
(2) 赋值运算符重载
  • 拷贝赋值:确保在赋值时进行深拷贝,并处理自我赋值的情况。
  • 移动赋值:通过移动语义实现高效的资源转移,避免重复分配内存。
(3) + 运算符重载

实现字符串拼接,将两个字符串连接成一个新字符串,并返回新的 MyString 对象。

(4) [] 运算符重载

允许通过索引访问或修改字符串中的单个字符,同时处理索引越界的情况。

(5) size()c_str() 方法
  • size():返回字符串的长度。
  • c_str():返回 C 风格字符串(即 char*),方便与 C 库函数交互。
(6) 输出流运算符重载

重载 << 运算符,使得 MyString 对象可以通过标准输出流 std::cout 输出。

4. 总结

这个自定义的 MyString 类提供了基本的字符串操作功能,包括动态内存管理、字符串拼接、字符访问、以及支持移动语义。它与 C++ STL 中的 std::string 类有类似的功能,但实际应用中 std::string 已经过高度优化,所以在实际项目中我们一般会优先选择标准库中的 std::string

二 参考C++ STL的vector类模板构造一个自定义的顺序表类模板。

要基于C++ STL 的 vector 类模板构造一个自定义的顺序表类模板,可以使用模板类,并实现常见的顺序表操作,例如添加元素、删除元素、访问元素、清空等。为了使这个类更具通用性和实用性,我们将使用模板来支持不同类型的数据,并且模仿 vector 类的一些常用接口。

顺序表类模板的基本设计

设计一个 SequenceList 类模板来实现顺序表功能。它将具备以下特性:

  • 内部使用动态分配的数组来存储元素。
  • 提供增删、插入、访问等基本操作。
  • 提供容量管理(例如扩容和缩容)。
  • 提供访问操作符和边界检查。
#include <iostream>
#include <stdexcept>

template <typename T>
class SequenceList {
private:
    T* data;         // 动态数组,存储顺序表的元素
    size_t size;     // 当前存储的元素个数
    size_t capacity; // 当前容量(分配的内存大小)

    // 辅助函数:扩容
    void expandCapacity() {
        // 新的容量是原来的两倍
        size_t newCapacity = capacity == 0 ? 1 : capacity * 2;
        T* newData = new T[newCapacity];
        
        // 将旧数据拷贝到新的数组
        for (size_t i = 0; i < size; ++i) {
            newData[i] = data[i];
        }

        // 删除旧数组
        delete[] data;
        data = newData;
        capacity = newCapacity;
    }

public:
    // 构造函数
    SequenceList(size_t initialCapacity = 10)
        : size(0), capacity(initialCapacity) {
        data = new T[capacity];
    }

    // 析构函数
    ~SequenceList() {
        delete[] data;
    }

    // 返回当前元素个数
    size_t getSize() const {
        return size;
    }

    // 返回当前容量
    size_t getCapacity() const {
        return capacity;
    }

    // 判断顺序表是否为空
    bool isEmpty() const {
        return size == 0;
    }

    // 添加元素到顺序表的末尾
    void pushBack(const T& value) {
        if (size == capacity) {
            expandCapacity();
        }
        data[size++] = value;
    }

    // 删除顺序表末尾的元素
    void popBack() {
        if (isEmpty()) {
            throw std::out_of_range("SequenceList is empty");
        }
        --size;
    }

    // 插入元素到指定位置
    void insert(size_t index, const T& value) {
        if (index > size) {
            throw std::out_of_range("Index out of range");
        }
        if (size == capacity) {
            expandCapacity();
        }
        // 将元素向后移动
        for (size_t i = size; i > index; --i) {
            data[i] = data[i - 1];
        }
        data[index] = value;
        ++size;
    }

    // 删除指定位置的元素
    void removeAt(size_t index) {
        if (index >= size) {
            throw std::out_of_range("Index out of range");
        }
        // 将后面的元素向前移动
        for (size_t i = index; i < size - 1; ++i) {
            data[i] = data[i + 1];
        }
        --size;
    }

    // 获取指定位置的元素(带边界检查)
    T& at(size_t index) {
        if (index >= size) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    // 操作符[],不带边界检查
    T& operator[](size_t index) {
        return data[index];
    }

    // 清空顺序表
    void clear() {
        size = 0;
    }
    
    // 打印顺序表元素
    void print() const {
        for (size_t i = 0; i < size; ++i) {
            std::cout << data[i] << " ";
        }
        std::cout << std::endl;
    }
};

int main() {
    SequenceList<int> list;  // 创建一个存储int类型的顺序表
    
    // 添加元素
    list.pushBack(10);
    list.pushBack(20);
    list.pushBack(30);

    std::cout << "顺序表元素: ";
    list.print();

    // 插入元素
    list.insert(1, 15);
    std::cout << "在索引1处插入15后: ";
    list.print();

    // 删除元素
    list.removeAt(2);
    std::cout << "删除索引2处的元素后: ";
    list.print();

    // 访问元素
    std::cout << "索引1处的元素: " << list.at(1) << std::endl;

    return 0;
}

代码详解

  1. 构造函数与析构函数

    • SequenceList(size_t initialCapacity = 10):初始化时为顺序表分配一定的容量(默认10),并将元素个数 size 初始化为0。
    • 析构函数 ~SequenceList():释放动态分配的内存。
  2. 扩容函数 expandCapacity()

    • 当顺序表的容量不足时,将当前容量扩大一倍,并将原有数据复制到新分配的内存中。
  3. 顺序表的常用操作

    • pushBack(const T& value):向顺序表末尾添加元素。如果容量不足,自动扩容。
    • popBack():删除顺序表末尾的元素,并抛出异常以处理空表。
    • insert(size_t index, const T& value):在指定位置插入元素,并将后续元素向后移动。
    • removeAt(size_t index):删除指定位置的元素,并将后续元素向前移动。
    • at(size_t index):访问指定位置的元素,带边界检查。
    • operator[]:提供不带边界检查的元素访问操作符。
    • clear():清空顺序表。

三 参考C++ STL的stack类模板构造一个自定义的栈类模板。

 要参考 C++ STL 的 stack 类模板构造一个自定义的栈类模板,我们可以使用模板类,并通过一个底层的顺序表(例如动态数组或链表)来实现栈的基本操作。栈是一种后进先出(LIFO, Last In First Out)的数据结构,支持以下主要操作:

  • push():将元素压入栈顶。
  • pop():将栈顶元素弹出。
  • top():获取栈顶元素,但不弹出。
  • empty():判断栈是否为空。
  • size():获取栈中元素的数量。

自定义栈类模板的基本设计

  1. 使用模板使得该栈可以存储任意类型的数据。
  2. 栈的操作应支持基本的 LIFO 逻辑。
  3. 为了实现内部数据的动态存储,可以使用我们之前实现的 SequenceList 类,也可以直接使用动态数组来实现。
#include <iostream>
#include <stdexcept>

template <typename T>
class Stack {
private:
    T* data;         // 动态数组,存储栈的元素
    size_t size;     // 当前栈中的元素个数
    size_t capacity; // 当前栈的容量(分配的内存大小)

    // 辅助函数:扩容
    void expandCapacity() {
        size_t newCapacity = capacity == 0 ? 1 : capacity * 2;
        T* newData = new T[newCapacity];

        // 将旧数据拷贝到新数组
        for (size_t i = 0; i < size; ++i) {
            newData[i] = data[i];
        }

        delete[] data;
        data = newData;
        capacity = newCapacity;
    }

public:
    // 构造函数
    Stack(size_t initialCapacity = 10)
        : size(0), capacity(initialCapacity) {
        data = new T[capacity];
    }

    // 析构函数
    ~Stack() {
        delete[] data;
    }

    // 返回栈中的元素个数
    size_t getSize() const {
        return size;
    }

    // 判断栈是否为空
    bool isEmpty() const {
        return size == 0;
    }

    // 将元素压入栈顶
    void push(const T& value) {
        if (size == capacity) {
            expandCapacity();
        }
        data[size++] = value;
    }

    // 将栈顶元素弹出
    void pop() {
        if (isEmpty()) {
            throw std::out_of_range("Stack is empty");
        }
        --size;
    }

    // 获取栈顶元素,不弹出
    T& top() {
        if (isEmpty()) {
            throw std::out_of_range("Stack is empty");
        }
        return data[size - 1];
    }

    // 清空栈
    void clear() {
        size = 0;
    }

    // 打印栈元素(从栈顶到栈底)
    void print() const {
        for (size_t i = size; i > 0; --i) {
            std::cout << data[i - 1] << " ";
        }
        std::cout << std::endl;
    }
};

// 测试栈类模板
int main() {
    Stack<int> stack;

    // 压入元素
    stack.push(10);
    stack.push(20);
    stack.push(30);

    std::cout << "栈中元素: ";
    stack.print();

    // 弹出栈顶元素
    stack.pop();
    std::cout << "弹出栈顶元素后: ";
    stack.print();

    // 获取栈顶元素
    std::cout << "当前栈顶元素: " << stack.top() << std::endl;

    // 清空栈
    stack.clear();
    std::cout << "清空栈后,栈是否为空: " << (stack.isEmpty() ? "是" : "否") << std::endl;

    return 0;
}

代码详解

  1. 构造函数与析构函数

    • Stack(size_t initialCapacity = 10):初始化时为栈分配一定的容量(默认10),并将栈的大小 size 初始化为 0。
    • 析构函数 ~Stack():释放动态分配的内存。
  2. 辅助函数 expandCapacity()

    • 当栈的容量不足时,将当前容量扩大一倍,并将原有数据复制到新的数组中。
  3. 栈的基本操作

    • push(const T& value):向栈顶添加元素。如果容量不足,自动扩容。
    • pop():将栈顶元素弹出,并抛出异常处理空栈情况。
    • top():返回栈顶元素,但不弹出,并抛出异常处理空栈情况。
    • isEmpty():判断栈是否为空。
    • getSize():返回当前栈中的元素个数。
    • clear():清空栈中的所有元素。

四 参考C++ STL的queue类模板构造一个自定义的队列类模板

要参考 C++ STL 的 queue 类模板构造一个自定义的队列类模板,我们可以使用模板类并实现一个基本的队列操作。队列是一种先进先出(FIFO, First In First Out)的数据结构,主要操作包括:

  • enqueue():将元素入队。
  • dequeue():将队列前端元素出队。
  • front():获取队列前端元素,但不出队。
  • back():获取队列后端元素,但不出队。
  • empty():判断队列是否为空。
  • size():获取队列中元素的数量。

自定义队列类模板的基本设计

  1. 使用模板类来支持不同类型的数据。
  2. 内部实现可以使用动态数组或链表。为了简化,我们可以使用循环数组(环形缓冲区)作为底层数据结构。
  3. 提供基本的队列操作
#include <iostream>
#include <stdexcept>

template <typename T>
class Queue {
private:
    T* data;         // 动态数组,存储队列的元素
    size_t head;     // 队列前端的索引
    size_t tail;     // 队列后端的索引
    size_t size;     // 当前队列中的元素个数
    size_t capacity; // 当前队列的容量(分配的内存大小)

    // 辅助函数:扩容
    void expandCapacity() {
        size_t newCapacity = capacity == 0 ? 1 : capacity * 2;
        T* newData = new T[newCapacity];
        
        // 复制旧数据到新数组
        for (size_t i = 0; i < size; ++i) {
            newData[i] = data[(head + i) % capacity];
        }

        delete[] data;
        data = newData;
        head = 0;
        tail = size;
        capacity = newCapacity;
    }

public:
    // 构造函数
    Queue(size_t initialCapacity = 10)
        : head(0), tail(0), size(0), capacity(initialCapacity) {
        data = new T[capacity];
    }

    // 析构函数
    ~Queue() {
        delete[] data;
    }

    // 返回队列中的元素个数
    size_t getSize() const {
        return size;
    }

    // 判断队列是否为空
    bool isEmpty() const {
        return size == 0;
    }

    // 将元素入队
    void enqueue(const T& value) {
        if (size == capacity) {
            expandCapacity();
        }
        data[tail] = value;
        tail = (tail + 1) % capacity;
        ++size;
    }

    // 将队列前端元素出队
    void dequeue() {
        if (isEmpty()) {
            throw std::out_of_range("Queue is empty");
        }
        head = (head + 1) % capacity;
        --size;
    }

    // 获取队列前端元素,不出队
    T& front() {
        if (isEmpty()) {
            throw std::out_of_range("Queue is empty");
        }
        return data[head];
    }

    // 获取队列后端元素,不出队
    T& back() {
        if (isEmpty()) {
            throw std::out_of_range("Queue is empty");
        }
        return data[(tail - 1 + capacity) % capacity];
    }

    // 清空队列
    void clear() {
        head = 0;
        tail = 0;
        size = 0;
    }

    // 打印队列元素(从前端到后端)
    void print() const {
        for (size_t i = 0; i < size; ++i) {
            std::cout << data[(head + i) % capacity] << " ";
        }
        std::cout << std::endl;
    }
};

// 测试队列类模板
int main() {
    Queue<int> queue;

    // 入队
    queue.enqueue(10);
    queue.enqueue(20);
    queue.enqueue(30);

    std::cout << "队列中元素: ";
    queue.print();

    // 出队
    queue.dequeue();
    std::cout << "出队后: ";
    queue.print();

    // 获取队列前端和后端元素
    std::cout << "队列前端元素: " << queue.front() << std::endl;
    std::cout << "队列后端元素: " << queue.back() << std::endl;

    // 清空队列
    queue.clear();
    std::cout << "清空队列后,队列是否为空: " << (queue.isEmpty() ? "是" : "否") << std::endl;

    return 0;
}

代码详解

  1. 构造函数与析构函数

    • Queue(size_t initialCapacity = 10):初始化时为队列分配一定的容量(默认10),并将队列的头尾索引 headtail 以及元素个数 size 初始化为0。
    • 析构函数 ~Queue():释放动态分配的内存。
  2. 辅助函数 expandCapacity()

    • 当队列的容量不足时,将容量扩大一倍,并将原有数据复制到新的数组中。此时头索引 head 重置为0,尾索引 tail 更新为新的元素数量。
  3. 队列的基本操作

    • enqueue(const T& value):将元素入队。如果容量不足,自动扩容。入队时,尾索引 tail 循环移动。
    • dequeue():将队列前端元素出队,头索引 head 循环移动,并抛出异常处理空队列情况。
    • front():返回队列前端元素,但不出队,抛出异常处理空队列情况。
    • back():返回队列后端元素,但不出队,抛出异常处理空队列情况。
    • isEmpty():判断队列是否为空。
    • getSize():返回当前队列中的元素个数。
    • clear():清空队列中的所有元素,重置头尾索引和大小。
  4. 测试代码

    • main() 函数中对队列进行增删查操作,并输出操作后的结果。

队列中元素: 10 20 30 
出队后: 20 30 
队列前端元素: 20
队列后端元素: 30
清空队列后,队列是否为空: 是

Matrix 类模板中添加矩阵运算功能,包括矩阵相加、相减、相乘,以及矩阵与标量的加、减、乘、除,矩阵转置和元素反号,可以大大增强类的功能性。以下是这些运算的详细实现。 

#pragma once
#include <vector>
#include <iostream>
#include <initializer_list>
#include <stdexcept>

using namespace std;

template<class T>
class Matrix {
private:
    size_t r = 0, c = 0; // 行数和列数
    vector<T> buf; // 用一维数组保存矩阵各元素

    // 辅助函数:检查维度
    void checkDimensions(const Matrix<T>& other) const {
        if (r != other.r || c != other.c) {
            throw std::invalid_argument("Matrix dimensions must agree");
        }
    }

    // 辅助函数:检查乘法维度
    void checkMultiplicationDimensions(const Matrix<T>& other) const {
        if (c != other.r) {
            throw std::invalid_argument("Matrix dimensions must agree for multiplication");
        }
    }

public:
    Matrix() {} // 默认初始化

    // 由行数和列数初始化
    Matrix(size_t row, size_t col) : r(row), c(col) {
        buf.resize(r * c);
    }

    // 由行数和列数及指定值初始化
    Matrix(size_t row, size_t col, const T& v) : r(row), c(col) {
        buf.assign(r * c, v);
    }

    // 使用形如{{1, 2}, {3, 4}}的初始值列表初始化
    Matrix(const initializer_list<initializer_list<T>>& m) : r(m.size()), c(m.begin()->size()) {
        auto F = m.begin()->begin(), L = F + r * c;
        buf.assign(F, L);
    }

    // 元素访问
    auto operator()(size_t i, size_t j) -> decltype(buf[0]) {
        return buf[i * c + j];
    }

    auto operator()(size_t i, size_t j) const -> decltype(buf[0]) {
        return buf[i * c + j];
    }

    // 输出矩阵的所有元素
    friend ostream& operator<<(ostream& out, const Matrix<T>& m) {
        for (size_t i = 0; i < m.r; ++i) {
            for (size_t j = 0; j < m.c; ++j) {
                out << m(i, j) << ' ';
            }
            out << endl;
        }
        return out;
    }

    // 矩阵相加
    Matrix<T> operator+(const Matrix<T>& other) const {
        checkDimensions(other);
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = buf[i] + other.buf[i];
        }
        return result;
    }

    // 矩阵相减
    Matrix<T> operator-(const Matrix<T>& other) const {
        checkDimensions(other);
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = buf[i] - other.buf[i];
        }
        return result;
    }

    // 矩阵相乘
    Matrix<T> operator*(const Matrix<T>& other) const {
        checkMultiplicationDimensions(other);
        Matrix<T> result(r, other.c, T{0});
        for (size_t i = 0; i < r; ++i) {
            for (size_t j = 0; j < other.c; ++j) {
                for (size_t k = 0; k < c; ++k) {
                    result(i, j) += (*this)(i, k) * other(k, j);
                }
            }
        }
        return result;
    }

    // 矩阵与数相加
    Matrix<T> operator+(const T& value) const {
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = buf[i] + value;
        }
        return result;
    }

    // 矩阵与数相减
    Matrix<T> operator-(const T& value) const {
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = buf[i] - value;
        }
        return result;
    }

    // 矩阵与数相乘
    Matrix<T> operator*(const T& value) const {
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = buf[i] * value;
        }
        return result;
    }

    // 矩阵与数相除
    Matrix<T> operator/(const T& value) const {
        if (value == T{0}) {
            throw std::invalid_argument("Division by zero");
        }
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = buf[i] / value;
        }
        return result;
    }

    // 矩阵转置
    Matrix<T> transpose() const {
        Matrix<T> result(c, r);
        for (size_t i = 0; i < r; ++i) {
            for (size_t j = 0; j < c; ++j) {
                result(j, i) = (*this)(i, j);
            }
        }
        return result;
    }

    // 元素反号
    Matrix<T> operator-() const {
        Matrix<T> result(r, c);
        for (size_t i = 0; i < r * c; ++i) {
            result.buf[i] = -buf[i];
        }
        return result;
    }

    // 清空矩阵
    void clear() {
        buf.clear();
        r = 0;
        c = 0;
    }

    // 获取行数
    size_t rows() const {
        return r;
    }

    // 获取列数
    size_t cols() const {
        return c;
    }
};

代码详解

  1. 矩阵相加 (operator+)

    • 先检查两个矩阵的维度是否一致。
    • 遍历所有元素,计算对应位置元素的和,并存储在结果矩阵中。
  2. 矩阵相减 (operator-)

    • 检查维度一致性。
    • 遍历所有元素,计算对应位置元素的差,并存储在结果矩阵中。
  3. 矩阵相乘 (operator*)

    • 检查第一个矩阵的列数是否等于第二个矩阵的行数。
    • 计算每个元素的乘积。使用三重循环进行矩阵乘法。
  4. 矩阵与数相加 (operator+)

    • 遍历所有元素,每个元素加上标量值,存储在结果矩阵中。
  5. 矩阵与数相减 (operator-)

    • 遍历所有元素,每个元素减去标量值,存储在结果矩阵中。
  6. 矩阵与数相乘 (operator*)

    • 遍历所有元素,每个元素乘以标量值,存储在结果矩阵中。
  7. 矩阵与数相除 (operator/)

    • 遍历所有元素,每个元素除以标量值。确保标量值不为零。
  8. 矩阵转置 (transpose)

    • 创建一个新的矩阵,其行数和列数交换。将原矩阵的元素位置进行交换。
  9. 元素反号 (operator-)

    • 遍历所有元素,对每个元素取反,存储在结果矩阵中。
  10. 清空矩阵 (clear)

    • 清空矩阵的数据并重置维度。

使用示例

int main() {
    Matrix<int> m1 = { {1, 2}, {3, 4} };
    Matrix<int> m2 = { {5, 6}, {7, 8} };

    cout << "Matrix m1:" << endl << m1;
    cout << "Matrix m2:" << endl << m2;

    cout << "m1 + m2:" << endl << m1 + m2;
    cout << "m1 - m2:" << endl << m1 - m2;
    cout << "m1 * m2:" << endl << m1 * m2;
    cout << "m1 + 10:" << endl << m1 + 10;
    cout << "m1 - 10:" << endl << m1 - 10;
    cout << "m1 * 10:" << endl << m1 * 10;
    cout << "m1 / 10:" << endl <<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值