rust学习lab02(Comp6991)

lab02

概述

COM6991lab02
这里是COM6991有关rust的基础语法的实验,个人写完后的总结。
这个实验主要是了解rust的基本类型,常见的错误处理哲学(使用result, ?等方法处理).

实验部分

任务一 tribonacci

实现计算一个变量的tribonacci数组和他们的和,
基本样例
实现的思路就是利用rust的数组特性,并且根据公式v[i] = v[i - 1] + v[i - 2] + v[i - 3]进行实现,
因此我们可以编写如下代码

use std::env;
use std::num::ParseIntError;
// use std::result::Result;
struct TribonacciError(String);

fn main() {
    let args: Vec<String> = env::args().collect();
    let error_message = String::from("Please enter a valid size");

    let size = match args.get(1) {
        Some(s) => s.parse::<usize>(),
        None => Ok(10),
    };

    if let Err(e) = compute_tribonacci(size, error_message) {
        println!("Error: {}", e.0)
    }
}


/// Computes the tribonacci sequence of a given size
/// Prints the sequence, and its sum
fn compute_tribonacci(size: Result<usize, ParseIntError>, error_msg: String) -> Result<(), TribonacciError> {
    let mut v:Vec<u128> = vec![1_u128; 3]; // 初始化数组
    let s = size.map_err(|_|TribonacciError(error_msg))?;
    for i in 3..s {
        v.push(v[i - 1] + v[i - 2] + v[i - 3]);
    }
    println!("Values: {:?}", v);
    let sum:u128 = v.iter().sum();
    println!("\nsum:{sum}");

    Ok(())
}

这里的map_err()的作用就是将Result<T, E> 类型转换为Result<T, F>类型, ?的这个意思表示如果是Err(F)则返回,可以节约书写match的成本,我们可以使用.sum()函数对于迭代器作求和操作。

任务二 Toupper

这个任务是要将所有在字符串中的字符变成大写,这个的实现思路比较简单,只需要调用to_uppercase函数即可

fn main() {
    // try and get the first argument
    // using some iterator methods
    let arg = std::env::args().nth(1).expect("must be passed in");// get the first argument

    // the compiler suggests to "borrow here"
    // but we haven't learnt how to borrow :(
    // we have a String type, and want to get a &str
    // Try find a function that can help us using
    // the docs https://doc.rust-lang.org/stable/std/string/struct.String.html
    let upp = uppercase(&arg);
    
    println!("arg = {}", arg);
    println!("upp = {}", upp);
}

fn uppercase(src: &str) -> String {
    let mut destination = String::new();

    for c in src.chars() {
        // this doesn't work either!!
        // what type does to_uppercase return?
        // what type does push expect?
        // Food for thought, what exactly is src.chars()?
        
        for c in c.to_uppercase() {
            destination.push(c);
        }

        // destination.push(c.to_uppercase().next().expect("must be a char"));
    }

    destination
}

这里需要注意的是src.chars()和c.to_uppercase都是迭代器返回值,这里的第二个循环可以写成
destination.push(c.to_uppercase().next().expect(“must be a char”));这种形式

任务三 Collections

rust中常见的容器的API调用

use core::time;
use std::collections::{linked_list, HashMap, LinkedList, VecDeque};

const MAX_ITER: i32 = 300000;

fn main() {
    // Vectors
    vec_operations();

    // VecDeque
    vec_deque_operations();

    // TODO: your code here, for linked list insertions
    linked_list_operations();
    // TODO: your code here, for hashmap insertions
    hashmap_operations();
    // TODO: your text explanation to the questions in the spec
}

/// measure the insertion and removal
/// operations of a vector
fn vec_operations() {
    let mut vec = Vec::new();

    let time_start = std::time::Instant::now();
    for i in 0..MAX_ITER {
        vec.push(i);
    }
    let time_end = std::time::Instant::now();

    println!("==== Vector ====");
    println!("insert: {:?}", time_end - time_start);

    let time_start = std::time::Instant::now();
    for _ in 0..MAX_ITER {
        vec.remove(0);
    }
    let time_end = std::time::Instant::now();

    println!("remove: {:?}", time_end - time_start);
}

/// measure the insertion and removal
/// operations of a VecDeque
fn vec_deque_operations() {
    let mut vec_deque = VecDeque::new();

    let time_start = std::time::Instant::now();
    for i in 0..MAX_ITER {
        vec_deque.push_back(i);
    }
    let time_end = std::time::Instant::now();

    println!("==== VecDeque ====");
    println!("insert: {:?}", time_end - time_start);

    let time_start = std::time::Instant::now();
    for _ in 0..MAX_ITER {
        vec_deque.pop_front();
    }
    let time_end = std::time::Instant::now();

    println!("remove: {:?}", time_end - time_start);
}
fn linked_list_operations() {
    let mut linked_list: LinkedList<i32> = LinkedList::new();
    let time_start = std::time::Instant::now();
    for i in 0..MAX_ITER {
        linked_list.push_back(i);
    }
    
    let time_end = std::time::Instant::now();
    println!("===LinkedList===");
    println!("Insert:{:?}", time_end - time_start);
    let time_start = std::time::Instant::now();
    for _ in 0..MAX_ITER {
        linked_list.pop_front();
    }
    let time_end = std::time::Instant::now();
    println!("Remove:{:?}", time_end - time_start);
}
fn hashmap_operations() {
    let mut hashmap:HashMap<i32, i32> = HashMap::new();
    let time_start = std::time::Instant::now();
    for i in 0..MAX_ITER {
        hashmap.insert(i, i);
    }
    let time_end = std::time::Instant::now();
    println!("Insert: {:?}", time_end - time_start);
}

任务四 data analysis

分析出一个学校到底有多少学生,最受欢迎的课程是什么,最不受欢迎的课程是什么。

const ENROLMENTS_PATH: &str = "enrolments.psv";
use csv::{Position, ReaderBuilder};
use serde::Deserialize;
use std::{collections::HashMap, fs::File, hash::Hash};

// 定义一个结构体来映射 PSV 文件中的列
#[derive(Debug, Deserialize)]
struct Record {
    // 根据你的 PSV 文件结构定义字段
    course_code:String, 
    student_number:String,
    name:String,
    program:String,
    plan:String,
    wam:f64,
    session:String,
    birthday:String,
    sex:String
}
fn main() {
    let file = File::open(ENROLMENTS_PATH).expect("open the file");
    let mut reader = ReaderBuilder::new().delimiter(b'|').has_headers(false).from_reader(file);
    let mut students:HashMap<String, Record> = HashMap::new();
    for result in reader.deserialize::<Record>() {
        let record = result.expect("一条记录");
        // println!("{:?}\n", record);
        
        students.insert(record.student_number.clone(), record);
    }
    println!("the students:{:?}", students.len());
    
    let mut courses:HashMap<String, i32> = HashMap::new();

    reader.seek(Position::new()).unwrap();
    for result in reader.deserialize::<Record>() {
        let record = result.expect("一条记录");
        courses.entry(record.course_code)
               .and_modify(|x|(*x += 1))
               .or_insert(1);

    }
    let (course, number) = courses.iter().max_by_key(|(course_id, number)|*number).expect("the courses not null");
    
    let (course2, number2) = courses.iter().min_by_key(|(key, value)|*value).expect("this courses not null");

    println!("the least common course {}, the number is {}", course2, number2);
    println!("the most common course {}, the number is {}", course, number);

    let total_wam = students.values().map(|student| student.wam).sum::<f64>();
    let average_wam = total_wam / students.len() as f64;
println!("the average wam is {:.02}\n", average_wam);
    // println!("Hello, world!");
}

这个任务主要是让我们熟悉如何使用函数命令实现rust中一些功能而不是使用for loop 循环
其中对于hashmap而言,map.len()返回key的数量,map.values()返回map容器中值的迭代器
map.entry(key).and_modify(|value|*value+1).or_insert(1);这种做法类似于c++中的hashmap
map.iter().max_by_key(|(key, val)|*val).expect(“the map not null”)返回按照值排列的最大(key, val)
map.iter().map(|(key, value)|key+value).sum() 返回所有Key和value的和。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值