Compare commits
2 Commits
46efbdbd2d
...
71210dfdac
Author | SHA1 | Date |
---|---|---|
william | 71210dfdac | |
william | f8d1608036 |
51
src/main.rs
51
src/main.rs
|
@ -1,3 +1,50 @@
|
||||||
fn main() {
|
use std::cmp::min;
|
||||||
println!("Hello, world!");
|
use std::io;
|
||||||
|
use crate::matrix::Matrix;
|
||||||
|
|
||||||
|
mod matrix;
|
||||||
|
|
||||||
|
const ADD_VAL: i32 = 1;
|
||||||
|
const MATCH_VAL: i32 = 0;
|
||||||
|
|
||||||
|
fn main() -> io::Result<()> {
|
||||||
|
let str_a = "String A";
|
||||||
|
let str_b = "String B";
|
||||||
|
|
||||||
|
let mut diff_mat = Matrix::new(str_a.len(), str_b.len(), 0i32);
|
||||||
|
|
||||||
|
for col in 1..diff_mat.col_count {
|
||||||
|
let previous = diff_mat.get(0, col - 1).unwrap();
|
||||||
|
diff_mat.set(previous + ADD_VAL, 0, col).expect("Failed to initialize diff matrix");
|
||||||
|
}
|
||||||
|
|
||||||
|
for row in 1..diff_mat.row_count {
|
||||||
|
let previous = diff_mat.get(row - 1, 0).unwrap();
|
||||||
|
diff_mat.set(previous - ADD_VAL, row, 0).expect("Failed to initialize diff matrix");
|
||||||
|
}
|
||||||
|
|
||||||
|
for row in 1..diff_mat.row_count {
|
||||||
|
for col in 1..diff_mat.col_count {
|
||||||
|
let char_a = str_a.chars().nth(row).unwrap();
|
||||||
|
let char_b = str_b.chars().nth(col).unwrap();
|
||||||
|
|
||||||
|
let add_from = diff_mat.get(row, col - 1).unwrap();
|
||||||
|
let sub_from = diff_mat.get(row - 1, col).unwrap();
|
||||||
|
let substitute_from = diff_mat.get(row - 1, col - 1).unwrap();
|
||||||
|
|
||||||
|
let add = add_from + ADD_VAL;
|
||||||
|
let sub = sub_from - ADD_VAL;
|
||||||
|
let substitute = substitute_from + if char_a == char_b {
|
||||||
|
MATCH_VAL
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
|
let val = min(add, min(sub, substitute));
|
||||||
|
diff_mat.set(val, row, col).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff_mat.print();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,161 @@
|
||||||
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
use std::ops;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Matrix<T> {
|
||||||
|
pub row_count: usize,
|
||||||
|
pub col_count: usize,
|
||||||
|
default_val: T,
|
||||||
|
rows: Vec<Vec<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum MatrixError {
|
||||||
|
RowIndexOutOfBound(usize),
|
||||||
|
ColIndexOutOfBound(usize),
|
||||||
|
IncompatibleSize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Matrix<T> where
|
||||||
|
T: Copy {
|
||||||
|
pub fn new(row_count: usize, col_count: usize, default_val: T) -> Self {
|
||||||
|
let rows = vec![vec![default_val; col_count]; row_count];
|
||||||
|
Matrix { row_count, col_count, default_val, rows }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_with_size(matrix: &Self) -> Self {
|
||||||
|
Matrix::new(matrix.row_count, matrix.col_count, matrix.default_val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, row: usize, col: usize) -> Option<&T> {
|
||||||
|
if row >= self.row_count || col >= self.col_count {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(&self.rows[row][col])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, val: T, row: usize, col: usize) -> Result<(), MatrixError> {
|
||||||
|
if row >= self.row_count {
|
||||||
|
return Err(MatrixError::RowIndexOutOfBound(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
if col >= self.col_count {
|
||||||
|
return Err(MatrixError::ColIndexOutOfBound(col));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.rows[row][col] = val;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size_equal(&self, other: &Self) -> bool {
|
||||||
|
self.row_count == other.row_count && self.col_count == other.col_count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Matrix<T> where
|
||||||
|
T: Display, T: Copy {
|
||||||
|
pub fn print(&self) {
|
||||||
|
for row in 0..self.row_count {
|
||||||
|
for col in 0..self.col_count {
|
||||||
|
let val = self.rows[row][col];
|
||||||
|
print!(" {val} ");
|
||||||
|
}
|
||||||
|
|
||||||
|
print!("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Add<Matrix<T>> for Matrix<T> where
|
||||||
|
T: ops::Add<Output=T>, T: Copy {
|
||||||
|
type Output = Result<Matrix<T>, MatrixError>;
|
||||||
|
|
||||||
|
fn add(self, rhs: Matrix<T>) -> Self::Output {
|
||||||
|
if !&self.size_equal(&rhs) {
|
||||||
|
return Err(MatrixError::IncompatibleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result_matrix = Matrix::new_with_size(&self);
|
||||||
|
|
||||||
|
for row in 0..self.row_count {
|
||||||
|
for col in 0..self.col_count {
|
||||||
|
// Since the sizes of the matrices are known, we can ignore errors
|
||||||
|
let val = self.rows[row][col] + rhs.rows[row][col];
|
||||||
|
result_matrix.set(val, row, col).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result_matrix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Sub<Matrix<T>> for Matrix<T> where
|
||||||
|
T: ops::Sub<Output=T>, T: Copy {
|
||||||
|
type Output = Result<Matrix<T>, MatrixError>;
|
||||||
|
|
||||||
|
fn sub(self, rhs: Matrix<T>) -> Self::Output {
|
||||||
|
if !&self.size_equal(&rhs) {
|
||||||
|
return Err(MatrixError::IncompatibleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result_matrix = Matrix::new_with_size(&self);
|
||||||
|
|
||||||
|
for row in 0..self.row_count {
|
||||||
|
for col in 0..self.col_count {
|
||||||
|
// Since the sizes of the matrices are known, we can ignore errors
|
||||||
|
let val = self.rows[row][col] - rhs.rows[row][col];
|
||||||
|
result_matrix.set(val, row, col).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result_matrix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Mul<T> for Matrix<T> where
|
||||||
|
T: ops::Mul<Output=T>, T: Copy {
|
||||||
|
type Output = Matrix<T>;
|
||||||
|
|
||||||
|
fn mul(self, rhs: T) -> Self::Output {
|
||||||
|
let mut result_matrix = Matrix::new_with_size(&self);
|
||||||
|
|
||||||
|
for row in 0..self.row_count {
|
||||||
|
for col in 0..self.col_count {
|
||||||
|
let val = self.rows[row][col] * rhs;
|
||||||
|
result_matrix.set(val, row, col).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result_matrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ops::Mul<Matrix<T>> for Matrix<T> where
|
||||||
|
T: ops::Add<Output=T>, T: ops::Mul<Output=T>, T: Copy {
|
||||||
|
type Output = Result<Matrix<T>, MatrixError>;
|
||||||
|
|
||||||
|
fn mul(self, rhs: Matrix<T>) -> Self::Output {
|
||||||
|
if self.col_count != rhs.row_count {
|
||||||
|
return Err(MatrixError::IncompatibleSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result_matrix = Matrix::new(self.row_count, rhs.col_count, self.default_val);
|
||||||
|
|
||||||
|
for row in 0..result_matrix.row_count {
|
||||||
|
for col in 0..result_matrix.col_count {
|
||||||
|
let mut val = self.default_val;
|
||||||
|
|
||||||
|
for i in 0..self.col_count {
|
||||||
|
let val_i = self.rows[row][i];
|
||||||
|
let val_j = rhs.rows[i][col];
|
||||||
|
val = val + val_i * val_j;
|
||||||
|
}
|
||||||
|
|
||||||
|
result_matrix.set(val, row, col).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result_matrix)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue