【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)); } }
运行截图:
最后那个公司员工信息管理的功能中还可以再进行完善,比如退出时候将当前数据保存到文件、启动的时候从文件读取、添加更新、删除等操作,如果有时间可以再完善下。