开发十年,就只剩下这套Java开发体系了 >>>
蛇形矩阵
输出如下类任意阶数的蛇形矩阵
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>
}
fn get_min(list:Vec) -> 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::with_capacity(size);
for _ in 0..size{
let mut temp: Vec = 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{
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{
&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类对二维数组具有完全所有权。