rust--打印蛇形矩阵

蛇形矩阵

输出如下类任意阶数的蛇形矩阵

1 2    1 2 3        01 02 03 04

4 3    8 9 4        12 13 14 05

         7 6 5        11 16 15 06

                         10 09 08 07

方案

根据蛇形赋值顺序,可以通过当前赋值的点坐标(i,j)计算出下一个应该赋值的点。

实现

lib.rs

#[derive(Debug)]
pub struct Matrix {
    matrix: Vec<Vec<usize>>
}

fn get_min(list:Vec<usize>) -> usize{
    let mut min_num = list[0];
    for num in list.iter(){
        if num < &min_num{
            min_num = *num;
        }
    }
    return min_num;
}

impl Matrix {
    pub fn new(size:usize) -> Matrix{
        let mut matrix: Vec<Vec<usize>> = Vec::with_capacity(size);
        for _ in 0..size{
            let mut temp: Vec<usize> = Vec::with_capacity(size);
            for _ in 0..size {
                temp.push(0);
            }
            matrix.push(temp);
        }
        let mut snake_matrix = Matrix{
            matrix,
        };
        (&mut snake_matrix).generate(size);
        return snake_matrix;
    }

    pub fn size(&self) -> usize{
        self.matrix.len()
    }

//计算出当前所在的圈数
    fn get_loop(&self,point: &(usize,usize)) ->usize{
        get_min(vec![point.0,point.1,self.size()-point.0-1,self.size()-point.1-1])
    }

    pub fn get(&self,i:usize,j:usize) -> Result<usize,&str>{
        let size = self.matrix.len();
        if i >= size || j >= size{
            Err("the index is out of range")
        }else{
            Ok(self.matrix[i][j])
        }
    }
//当前节点赋值,并计算出下一个需要赋值的节点坐标
    fn next(&mut self,point:&mut (usize,usize),num:usize){
        let &mut(i,j) = point;
        self.matrix[i][j] = num;
        let loop_count = self.get_loop(&point);
        if j>=i && i < self.size()-loop_count-1{
            if j < self.size()-loop_count-1{
                point.1 = j+1;
            }else{
                point.0 = i+1;
            }
        }else {
            if j > loop_count{
                point.1=j-1;
            }else if i > loop_count+1{
                point.0=i-1;
            }else{
                point.1=j+1;
            }
        }

    }

    fn generate(&mut self,size:usize) {
        let last_num = size * size;
        let mut point = (0,0);
        for num in 1..last_num+1 {
            self.next(&mut point,num);
        }
    }

    fn get_list(&self,index:usize)-> &Vec<usize>{
        &self.matrix[index]
    }

    pub fn print_matrix(&self){
        for i in 0..self.size() {
            println!("{:?}",self.get_list(i));
        }
    }

}

main.rs

extern crate snakematrix;

fn main() {
    let matrix = snakematrix::Matrix::new(5);
    matrix.print_matrix();
}

ps:如果想搞成外部输入矩阵阶数,可以再参考我的另一篇文章(rust控制台整数读取 )

算法详解

~bla bla bla~

note

rust在比较和模式匹配时需要注意引用类型,不会自动解引用。之所以不在二维数组中存放vec的引用,而是直接存放vec,是由于,Matrix类对二维数组具有完全所有权。

猜你喜欢

转载自my.oschina.net/u/3703365/blog/1789941