【RUST程序设计语言】第八章 常见集合练习题 Pig Latin等

题目摘录:

  • 给定一系列数字,使用 vector 并返回这个列表的中位数(排列数组后位于中间的值)和众数(mode,出现次数最多的值;这里哈希 map 会很有帮助)。
  • 将字符串转换为 Pig Latin,也就是每一个单词的第一个辅音字母被移动到单词的结尾并增加 “ay”,所以 “first” 会变成 “irst-fay”。元音字母开头的单词则在结尾增加 “hay”(“apple” 会变成 “apple-hay”)。牢记 UTF-8 编码!
  • 使用哈希 map 和 vector,创建一个文本接口来允许用户向公司的部门中增加员工的名字。例如,“Add Sally to Engineering” 或 “Add Amir to Sales”。接着让用户获取一个部门的所有员工的列表,或者公司每个部门的所有员工按照字典序排列的列表。

使用的依赖:

[dependencies]
regex = "1"
lazy_static = "1.4.0"

代码:

use std::{collections::HashMap};
use lazy_static::lazy_static;
use regex::Regex;

fn main() {
    println!("Hello, world!");

    let mut nums = vec![
        4, 6, 23, 0, 20, 23, 16, 3, 11, 21, 16, 8, 12, 2, 18, 16, 10, 20, 20, 1, 17, 7, 19, 24, 24,
        5, 1, 14, 7, 19,
    ];

    nums.sort();

    println!("{:?}", nums);

    // 获取中位数
    println!("middle is: {:?}", get_middle(&nums));

    // 获取众数
    println!("get_most_num is: {:?}", get_most_num(&nums));


    // 每一个单词的第一个辅音字母被移动到单词的结尾并增加 “ay”
    let words = vec!["first", "apple", "ear"];

    for w in words {
        println!("the word ({}) => {}", w, pig_latin(w));
    }

    // 用户输入员工姓名到map,并获取员工列表
    company_peosons();
}

// 计算中位数
fn get_middle(nums: &Vec<i32>) -> i32 {
    let length = nums.len();
    
    if length % 2 == 1 {
        return nums[length / 2];
    } else {
        return (nums[length / 2 - 1] + nums[length / 2]) /2
    }
}

// 计算众数,可能会有多个众数,返回数组
fn get_most_num(nums: &Vec<i32>) -> Vec<i32> {
    let mut map = HashMap::new();

    for num in nums.iter() {
        let count = map.entry(num).or_insert(0);
        *count += 1;
    }
    // 先将map转为vec,从而对其进行排序,找出出现次数最多的那个
    let mut count_vec: Vec<_> = map.iter().collect();
    count_vec.sort_by(|a, b| a.1.cmp(b.1).reverse());
    println!("{:?}", count_vec);
    
    // 找出次数最多的数字
    let max = count_vec[0].1;
    let mut max_num:Vec<i32> = Vec::new();
    // max_num.push(**(count_vec[0].0));
    
    for one in count_vec {
        if one.1 < max {
            break;
        }

        max_num.push(**(one.0));
    }
    max_num
}

fn pig_latin(s: &str) -> String{
    let yuanyin = vec!['a', 'e', 'i', 'u'];

    let mut new_str = String::from(s);
    for (i, c) in s.chars().enumerate() {
        if i == 0 && yuanyin.contains(&c){
            new_str = format!("{}-{}", s, "hay");
            break;
        } else {
            if !yuanyin.contains(&c) {
                if i+1 < s.len() {
                    let start = &s[..i];
                    let end = &s[(i+1)..];
                    new_str = format!("{}{}-{}ay", start, end, c);
                    break;
                } else {
                    new_str = format!("{}-{}ay", &s[..i], c);
                    break;
                }
            }
        }
    }

    return new_str;
}

// 公司员工信息处理
fn company_peosons() {
    print_info();

    let default_employee_list = get_default_employee_list();
    let default_length = default_employee_list.len();

    let mut input = String::new();
    let mut employee_info:HashMap<String, Vec<String>> = HashMap::new();
    let mut index = 0;
    loop {
        if index < default_length {
            input = match default_employee_list.get(index) {
                Some(t) => t.clone(),
                None => "".to_string(),
            };
            index += 1;
        } else {
            println!("请输入你的指令(输入 help 显示帮助信息): ");
            std::io::stdin().read_line(&mut input).expect("信息输入有误,请重试!");
            // println!("input = {}", input);
        }

        let new_input = input.trim().to_lowercase();
        // println!("new_input = {}", new_input);

        match new_input.as_str() {
            "list" => print_all_employee(&employee_info, false), // 输出公司所有员工信息,升序
            "list-reverse" => print_all_employee(&employee_info, true), // 输出公司所有员工信息,降序
            "listd" => print_department_employee(&employee_info, false), // 输出公司部门员工信息,降序
            "listd-reverse" => print_department_employee(&employee_info, true), // 输出公司部门员工信息,降序
            "help" => print_info(),
            "quit" => return,
            other => {
                let y_or_n = deal_add_employee(&mut employee_info, other);
                if y_or_n {
                    println!("添加成功!");
                } else{
                    println!("添加失败!");
                }
            },
        }

        // 将上一次输入的数据清空
        input.clear();
    }
}

fn print_info() {
    println!("\n");
    println!("公司员工信息记录");
    println!("你可以输入:Add name to job 这种格式的文本来添加员工到指定职位,例如:");
    println!("Add Sally to Engineering   将Sally添加到Engineering职位下");
    println!("Add Amir to Sales   将Amir添加到Sales职位下");
    println!("输入 list 指令可以获取公司当前所有员工信息-升序"); 
    println!("输入 list-reverse 指令可以获取公司当前所有员工信息-降序"); 
    println!("输入 listd 指令可以获取公司一个部门所有员工信息-升序");
    println!("输入 listd-reverse 指令可以获取公司一个部门所有员工信息-降序");
    println!("输入 quit 指令退出当前程序");
    println!("输入 help 指令可以获取帮助信息");
    println!("\n");
}

// 设置一批默认的公司员工数据
fn get_default_employee_list() -> Vec<String> {
    vec![
        String::from("Add Sally anny to Engineering"),
        String::from("Add Wade to Engineering"),
        String::from("Add Seth to Engineering"),
        String::from("Add Dave to Engineering"),
        String::from("Add Gilbert to Engineering"),
        String::from("Add Brian to Engineering"),
        String::from("Add Liam to Engineering"),
        String::from("Add Claude to Engineering"),
        String::from("Add Harvey to Engineering"),

        String::from("Add Amir to Sales"),
        String::from("Add Connor to Sales"),
        String::from("Add Kingston to Sales"),
        String::from("Add Harold to Sales"),
        String::from("Add Eli to Sales"),
        String::from("Add Carlos to Sales"),
        String::from("Add Paul to Sales"),
        String::from("Add Ricardo to Sales"),

        String::from("Add Jessie to Manager"),
        String::from("Add Wiley to Manager"),
        String::from("Add Clark to Manager"),
        String::from("Add Marshall to Manager"),
        String::from("Add Marion to Manager"),
        String::from("Add Benjamin to Manager"),
        String::from("Add Terry to Manager"),
        String::from("Add Joe to Manager"),
        String::from("Add Christopher to Manager"),
    ]
}

// 处理添加的员工信息
fn deal_add_employee(employee_info: &mut HashMap<String, Vec<String>>, new_input: &str) -> bool {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"([Aa][Dd]{2}) +(.+?) +([Tt][Oo]) +(\w+)?").unwrap();
    }

    for cap in RE.captures_iter(new_input) {
        // println!("{:?}", &cap);
        let s1 = match &cap.get(1).as_mut() {
            Some(t) => t.as_str().to_lowercase(),
            None => "".to_string(),
        };
        let s2 = match &cap.get(2).as_mut() {
            Some(t) => t.as_str().to_lowercase(),
            None => "".to_string(),
        };
        let s3 = match &cap.get(3).as_mut() {
            Some(t) => t.as_str().to_lowercase(),
            None => "".to_string(),
        };
        let s4 = match &cap.get(4).as_mut() {
            Some(t) => t.as_str().to_lowercase(),
            None => "".to_string(),
        };
        if s1 == "add" && s3 == "to" {
            let vector = employee_info.entry(s4.clone())
            .or_insert(Vec::new());
            vector.push(s2.clone());

            return true;
        }
    }

    return false;
}

// 将公司中所有的员工合并到一起并排序
fn print_all_employee(employee_info: &HashMap<String, Vec<String>>, reverse: bool) {
    let mut all_emp = Vec::new();

    for emp_list in employee_info.values() {
        all_emp.extend(emp_list.iter());
    }

    sort_vect_list(&mut all_emp, reverse);

    println!("{:?}", all_emp);
}

fn print_department_employee(employee_info: &HashMap<String, Vec<String>>, reverse: bool) {
    // 先获取部门值并排序
    let mut department_keys = Vec::new();
    for key in employee_info.keys() {
        department_keys.push(key);
    }
    sort_vect_list(&mut department_keys, reverse);

    for department in department_keys {
        println!("department name: {}", department);

        let mut peosons = Vec::new();
        match employee_info.get(department) {
            Some(value) => {
                for p in value {
                    peosons.push(p);
                }
            },
            None => {},
        };

        sort_vect_list(&mut peosons, reverse);
        println!("{:?}", peosons);
        println!("");
    }
}

// 对vect数组进行排序
fn sort_vect_list(sort_list: &mut Vec<&String>, reverse: bool) {
    if reverse {
        sort_list.sort_by(|a,b| a.cmp(b).reverse());
    } else {
        sort_list.sort_by(|a,b| a.cmp(b));
    }
}

运行截图:

 

 

最后那个公司员工信息管理的功能中还可以再进行完善,比如退出时候将当前数据保存到文件、启动的时候从文件读取、添加更新、删除等操作,如果有时间可以再完善下。

posted @ 2023-02-03 15:14  newAdmin  阅读(162)  评论(0编辑  收藏  举报