MST

星途 面试题库

面试题:Rust复杂特征多重实现及泛型关联类型应用

假设有一系列结构体`Matrix2D`、`Matrix3D`等表示不同维度的矩阵,还有特征`MatrixTrait`。`MatrixTrait`有一个关联类型`Element`表示矩阵元素类型,同时有方法`transpose`用于转置矩阵。此外,还有一个特征`NumericTrait`用于对矩阵元素进行数值操作。现在要求在`Matrix2D`和`Matrix3D`上多重实现`MatrixTrait`和`NumericTrait`,并且要处理好不同矩阵维度下元素类型的泛型关联,写出完整的代码框架并解释关键部分。
41.0万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义NumericTrait,用于对矩阵元素进行数值操作
trait NumericTrait<T> {
    fn add(&self, other: &T) -> T;
    fn subtract(&self, other: &T) -> T;
}

// 定义MatrixTrait,关联类型Element表示矩阵元素类型,transpose方法用于转置矩阵
trait MatrixTrait {
    type Element;
    fn transpose(&mut self);
}

// Matrix2D结构体,泛型参数T表示矩阵元素类型
struct Matrix2D<T> {
    data: Vec<Vec<T>>,
    rows: usize,
    cols: usize,
}

// Matrix3D结构体,泛型参数T表示矩阵元素类型
struct Matrix3D<T> {
    data: Vec<Vec<Vec<T>>>,
    depth: usize,
    rows: usize,
    cols: usize,
}

// Matrix2D实现MatrixTrait
impl<T> MatrixTrait for Matrix2D<T> {
    type Element = T;
    fn transpose(&mut self) {
        let mut new_data = vec![vec![Default::default(); self.rows]; self.cols];
        for i in 0..self.rows {
            for j in 0..self.cols {
                new_data[j][i] = self.data[i][j].clone();
            }
        }
        self.data = new_data;
        std::mem::swap(&mut self.rows, &mut self.cols);
    }
}

// Matrix3D实现MatrixTrait,这里假设3D矩阵的转置是交换第一维和第二维
impl<T> MatrixTrait for Matrix3D<T> {
    type Element = T;
    fn transpose(&mut self) {
        let mut new_data = vec![vec![vec![Default::default(); self.rows]; self.cols]; self.depth];
        for d in 0..self.depth {
            for i in 0..self.rows {
                for j in 0..self.cols {
                    new_data[d][j][i] = self.data[d][i][j].clone();
                }
            }
        }
        self.data = new_data;
        std::mem::swap(&mut self.rows, &mut self.cols);
    }
}

// Matrix2D实现NumericTrait
impl<T: NumericTrait<T>> NumericTrait<T> for Matrix2D<T> {
    fn add(&self, other: &Matrix2D<T>) -> Matrix2D<T> {
        assert!(self.rows == other.rows && self.cols == other.cols);
        let mut result = Matrix2D {
            data: vec![vec![Default::default(); self.cols]; self.rows],
            rows: self.rows,
            cols: self.cols,
        };
        for i in 0..self.rows {
            for j in 0..self.cols {
                result.data[i][j] = self.data[i][j].add(&other.data[i][j]);
            }
        }
        result
    }
    fn subtract(&self, other: &Matrix2D<T>) -> Matrix2D<T> {
        assert!(self.rows == other.rows && self.cols == other.cols);
        let mut result = Matrix2D {
            data: vec![vec![Default::default(); self.cols]; self.rows],
            rows: self.rows,
            cols: self.cols,
        };
        for i in 0..self.rows {
            for j in 0..self.cols {
                result.data[i][j] = self.data[i][j].subtract(&other.data[i][j]);
            }
        }
        result
    }
}

// Matrix3D实现NumericTrait
impl<T: NumericTrait<T>> NumericTrait<T> for Matrix3D<T> {
    fn add(&self, other: &Matrix3D<T>) -> Matrix3D<T> {
        assert!(self.depth == other.depth && self.rows == other.rows && self.cols == other.cols);
        let mut result = Matrix3D {
            data: vec![vec![vec![Default::default(); self.cols]; self.rows]; self.depth],
            depth: self.depth,
            rows: self.rows,
            cols: self.cols,
        };
        for d in 0..self.depth {
            for i in 0..self.rows {
                for j in 0..self.cols {
                    result.data[d][i][j] = self.data[d][i][j].add(&other.data[d][i][j]);
                }
            }
        }
        result
    }
    fn subtract(&self, other: &Matrix3D<T>) -> Matrix3D<T> {
        assert!(self.depth == other.depth && self.rows == other.rows && self.cols == other.cols);
        let mut result = Matrix3D {
            data: vec![vec![vec![Default::default(); self.cols]; self.rows]; self.depth],
            depth: self.depth,
            rows: self.rows,
            cols: self.cols,
        };
        for d in 0..self.depth {
            for i in 0..self.rows {
                for j in 0..self.cols {
                    result.data[d][i][j] = self.data[d][i][j].subtract(&other.data[d][i][j]);
                }
            }
        }
        result
    }
}

关键部分解释

  1. 特征定义
    • NumericTrait定义了对矩阵元素进行数值操作(如加法和减法)的方法。泛型参数T表示元素类型,要求T自身也实现NumericTrait,以便在矩阵操作中对元素进行相应运算。
    • MatrixTrait定义了矩阵的通用行为,关联类型Element表示矩阵元素类型,transpose方法用于转置矩阵。
  2. 结构体定义
    • Matrix2DMatrix3D结构体分别表示二维和三维矩阵,使用泛型参数T表示矩阵元素类型。Matrix2D使用Vec<Vec<T>>存储数据,Matrix3D使用Vec<Vec<Vec<T>>>存储数据,并记录矩阵的维度信息。
  3. 特征实现
    • MatrixTrait实现
      • Matrix2DMatrix3D都实现了MatrixTrait。在transpose方法中,根据矩阵维度的不同,重新排列矩阵数据以实现转置。对于Matrix2D,常规地交换行和列的数据;对于Matrix3D,这里假设转置是交换第一维和第二维。
    • NumericTrait实现
      • Matrix2DMatrix3D实现NumericTrait时,要求矩阵元素类型T实现NumericTraitaddsubtract方法分别对两个同维度矩阵的对应元素进行加法和减法操作,并返回新的矩阵。在操作前先检查两个矩阵维度是否相同,以确保操作的有效性。