比賽介紹:
http://www.sohu.com/a/309875770_796898
題目如下:
注:請首先補充sonar-project.properties配置文件中的信息,
將sonar.projectKey設置爲隊長的姓名拼音(如ZhangSan),
將sonar.projectName設置爲隊長在慕測網站註冊的郵箱(如[email protected])
項目簡介:
某公司有4類員工:管理人員、文員、程序員,會計,兩個部門:程序部(Programmer)、文員部(Editor)和會計部(Accountant),補充Worker,Manager,Programmer、Editor和Accountant5個類。要求:
- 每種員工都有姓名,年齡,薪水,部門4個屬性
- 每個員工都可以展示自己的基本屬性,如程序員的語言屬性(language)
- 語言屬性包括java和C
- 管理人員分屬程序部、文員部和會計部
- 管理人員可以查看當前部門某員工的屬性,不能跨部門查看
- 管理人員可以添加本部門員工到自己的隊伍中(不做互斥處理,不需查重)
- 管理人員可以打印當前隊伍中員工的姓名清單
- 程序員有三種類型:開發(Develop),測試(Test),UI設計(UI),每個類型的獎金結算方式不同,開發人員每月獎金爲基本工資的20%,加班一次補貼100,加班補貼上限500;測試人員每月獎金爲基本工資的15%,加班一次補貼150,上限1000;UI設計人員每月獎金爲基本工資的25%,加班一次補貼50,上限300。(保留2位小數)
- 程序員需要實現幫助隱藏用戶信息的功能
- 文員需要實現文本對齊、標題排序、熱詞搜索、相似度對比的功能
- 會計需要實現數字轉換,校驗密碼的功能
初始類:
Accountant.java
public class Accountant extends Worker {
public String password;
public Accountant() {
}
//初始化Accountant
public Accountant(String name, int age, int salary, String password) {
}
/**
* 數字轉換
* 隨着公司業務的開展,國際性業務也有相應的拓寬,
* 會計們需要一個自動將數字轉換爲英文顯示的功能。
* 編輯們希望有一種簡約的方法能將數字直接轉化爲數字的英文顯示。
*
* 給定一個非負整數型輸入,將數字轉化成對應的英文顯示,省略介詞and
* 正常輸入爲非負整數,且輸入小於2^31-1;
* 如果有非法輸入(字母,負數,範圍溢出等),返回illegal
*
* 示例:
*
* number: 2132866842
* return: "Two Billion one Hundred Thirty Two Million Eight Hundred Sixty Six Thousand Eight Hundred Forty Two"
*
* number:-1
* return:"illegal"
* @param number
*/
public String numberToWords (String number){
return password;
}
/**
* 檢驗密碼
* 由於會計身份的特殊性,對會計的密碼安全有較高的要求,
* 會計的密碼需要由8-20位字符組成;
* 至少包含一個小寫字母,一個大寫字母和一個數字,不允許出現特殊字符;
* 同一字符不能連續出現三次 (比如 "...ccc..." 是不允許的, 但是 "...cc...c..." 可以)。
*
* 如果密碼符合要求,則返回0;
* 如果密碼不符合要求,則返回將該密碼修改滿足要求所需要的最小操作數n,插入、刪除、修改均算一次操作。
*
* 示例:
*
* password: HelloWorld6
* return: 0
*
* password: HelloWorld
* return: 1
*
* @param password
*/
public int checkPassword(){
return 0;
}
}
Editor.java
import java.util.ArrayList;
public class Editor extends Worker {
public Editor() {
}
//初始化Editor
public Editor(String name, int age, int salary) {
}
/**
* 文本對齊
*
* 根據統計經驗,用戶在手機上閱讀英文新聞的時候,
* 一行最多顯示32個字節(1箇中文佔2個字節)時最適合用戶閱讀。
* 給定一段字符串,重新排版,使得每行恰好有32個字節,並輸出至控制檯
* 首行縮進4個字節,其餘行數左對齊,每個短句不超過32個字節,
* 每行最後一個有效字符必須爲標點符號
*
* 示例:
*
* String:給定一段字符串,重新排版,使得每行恰好有32個字符,並輸出至控制檯首行縮進,其餘行數左對齊,每個短句不超過32個字符。
*
* 控制檯輸出:
* 給定一段字符串,重新排版,
* 使得每行恰好有32個字符,
* 並輸出至控制檯首行縮進,
* 其餘行數左對齊,
* 每個短句不超過32個字符。
*
*/
public void textExtraction(String data){
}
/**
* 標題排序
*
* 將給定的新聞標題按照拼音首字母進行排序,
* 首字母相同則按第二個字母,如果首字母相同,則首字拼音沒有後續的首字排在前面,如 鵝(e)與二(er),
* 以鵝爲開頭的新聞排在以二爲開頭的新聞前。
* 如果新聞標題第一個字的拼音完全相同,則按照後續單詞進行排序。如 新聞1爲 第一次... 新聞2爲 第二次...,
* 則新聞2應該排在新聞1之前。
* 示例:
*
* newsList:我是誰;誰是我;我是我
*
* return:誰是我;我是誰;我是我;
*
* @param newsList
*/
public ArrayList<String> newsSort(ArrayList<String> newsList){
return newsList;
}
/**
* 熱詞搜索
*
* 根據給定的新聞內容,找到文中出現頻次最高的一個詞語,詞語長度最少爲2(即4個字節),最多爲10(即20個字節),且詞語中不包含標點符號,可以出現英文,同頻詞語選擇在文中更早出現的詞語。
*
* 示例:
*
* String: 今天的中國,呈現給世界的不僅有波瀾壯闊的改革發展圖景,更有一以貫之的平安祥和穩定。這平安祥和穩定的背後,凝聚着中國治國理政的卓越智慧,也凝結着中國公安民警的辛勤奉獻。
*
* return:中國
*
* @param newsContent
*/
public String findHotWords(String newsContent){
return newsContent;
}
/**
*
*相似度對比
*
* 爲了檢測新聞標題之間的相似度,公司需要一個評估字符串相似度的算法。
* 即一個新聞標題A修改到新聞標題B需要幾步操作,我們將最少需要的次數定義爲 最少操作數
* 操作包括三種: 替換:一個字符替換成爲另一個字符,
* 插入:在某位置插入一個字符,
* 刪除:刪除某位置的字符
* 示例:
* 中國隊是冠軍 -> 我們是冠軍
* 最少需要三步來完成。第一步刪除第一個字符 "中"
* 第二步替換第二個字符 "國"->"我"
* 第三步替換第三個字符 "隊"->"們"
* 因此 最少的操作步數就是 3
*
* 定義相似度= 1 - 最少操作次數/較長字符串的長度
* 如在上例中:相似度爲 (1 - 3/6) * 100= 50.00(結果保留2位小數,四捨五入,範圍在0.00-100.00之間)
*
*
* @param title1
* @param title2
*/
public double minDistance(String title1, String title2){
return 0;
}
}
Manager.java
import java.util.ArrayList;
import java.util.List;
public class Manager extends Worker {
private List<Worker> worker;
public Manager() {
}
//Manager類的初始化
public Manager(String name, int age, int salary, String department) {
}
// 管理人員可以查詢本部門員工的基本信息,跨部門查詢提示權限不足,提示“Access Denied!”
public String inquire(Worker e) {
return null;
}
// 管理人員給自己的隊伍添加工作人員,同一部門的工作人員可以添加,並返回true,不同部門的工作人員無法添加,返回false
public boolean lead(Worker e) {
return false;
}
// 打印自己隊伍的人員姓名,沒有打印“Empty”
public String print() {
return null;
}
}
Programmer.java
public class Programmer extends Worker {
public String language;
public String type;
public Programmer() {
}
// Programmer類的初始化
public Programmer(String name, int age, int salary, String language,
String type) {
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
// 按照規則計算當月的獎金
public String getBonus(int overtime) {
return null;
}
// 展示基本信息
public String show() {
return null;
}
/**
* 信息隱藏
*
* 爲了保護用戶的隱私,系統需要將用戶號碼和郵箱隱藏起來。 對輸入的郵箱或電話號碼進行加密。 commnet
* 可能是一個郵箱地址,也可能是一個電話號碼。
*
* 1. 電子郵箱 郵箱格式爲 str1@str2
* 電子郵箱的名稱str1是一個長度大於2.並且僅僅包含大小寫字母和數字的字符串,名稱str1後緊接符號@
* 最後是郵箱所在的服務器str2,str2中可能包含多個. 如qq.com smail.nju.edu.cn等 郵箱地址是有效的,一個正確的示例爲:
* [email protected] 爲了隱藏電子郵箱,所有的str1和str2中的字母必須被轉換成小寫的,
* 並且名稱str1的第一個字和最後一個字的中間的所有字由 5 個 '*' 代替。 如果郵箱中含有非法字符或格式不正確,則返回illegal
*
* 示例:
*
* comment: "[email protected]"
*
* return: "q*****[email protected]"
*
* 2. 電話號碼 電話號碼是一串包括數字 0-9,以及 {'+', '-', '(', ')', ' '} 這幾個字符的字符串。
* 你可以假設電話號碼包含 10 到 13 個數字。 電話號碼的最後 10 個數字組成本地號碼,在這之前的數字組成國際號碼。
* 國際號碼是可選的。我們只暴露最後 4 個數字並隱藏所有其他數字。 本地號碼有格式,並且如 "***-***-1111" 這樣顯示,
* 爲了隱藏有國際號碼的電話號碼,像 "+111 111 111 1111",我們以 "+***-***-***-1111"
* 的格式來顯示。在本地號碼前面的 '+' 號 和第一個 '-' 號僅當電話號碼中包含國際號碼時存在。 例如,一個 12 位的電話號碼應當以
* "+**-" 開頭進行顯示。 注意:像 "(",")"," " 這樣的不相干的字符以及不符合上述格式的額外的減號或者加號都應當被刪除。
* 示例1:
*
* comment: "1(234)567-890"
*
* return: "***-***-7890"
*
* 示例2:
*
* comment: "86-(10)12345678"
*
* return: "+**-***-***-5678"
*
* @param comment
*/
public String hideUserinfo(String comment) {
return comment;
}
}
Worker.java
public class Worker {
protected String name;
protected int age;
protected int salary;
protected String department;
public Worker() {
}
//要求進行工作人員初始化,當年齡小於18或工資低於2000時,進行異常提示,提示內容參閱測試用例
public Worker(String name, int age, int salary, String department) {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
//展示員工的基本信息
public String show() {
return null;
}
}
測試類:
AccountantTest.java
import static org.junit.Assert.*;
import org.junit.Test;
public class AccountantTest {
@Test
public void test1() {
Accountant a = new Accountant("p",21,8000,"IamOK");
assertEquals(3,a.checkPassword());
}
@Test
public void test2() {
Accountant a = new Accountant("p",21,8000,"Helloworld6");
assertEquals(0,a.checkPassword());
}
@Test
public void test3() {
Accountant a = new Accountant("p",21,8000,"IamOK");
assertEquals("One",a.numberToWords("1"));
}
@Test
public void test4() {
Accountant a = new Accountant("p",21,8000,"IamOK");
assertEquals("illegal",a.numberToWords("-1"));
}
}
EditorTest.java
import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class EditorTest {
String sep;
PrintStream console = null;
ByteArrayOutputStream out = null;
@Before
public void setUp() throws Exception {
out = new ByteArrayOutputStream();
console = System.out;
System.setOut(new PrintStream(out));
sep = System.getProperty("line.separator");
}
@After
public void tearDown() throws Exception {
out.close();
System.setOut(console);
}
@Test(timeout=4000)
public void test1() {
Editor s = new Editor("s",21,8000);
assertEquals("My name is s ; age : 21 ; salary : 8000 ; department : Editor.",s.show());
}
@Test(timeout=4000)
public void test2() {
Editor e = new Editor("e",21,8000);
String newsContent = "今天的中國,呈現給世界的不僅有波瀾壯闊的改革發展圖景,更有一以貫之的平安祥和穩定。這平安祥和穩定的背後,凝聚着中國治國理政的卓越智慧,也凝結着中國公安民警的辛勤奉獻。";
assertEquals("中國",e.findHotWords(newsContent));
}
@Test(timeout=4000)
public void test3() {
Editor e = new Editor("e",21,18000);
String title1 = "中國隊是冠軍";
String title2 = "我們是冠軍";
assertEquals(50.00,e.minDistance(title1, title2),0.0000001);
}
@Test(timeout=4000)
public void test4() {
Editor e = new Editor("e",21,18000);
ArrayList<String> newsList = new ArrayList<String>();
newsList.add("我是誰");
newsList.add("誰是我");
newsList.add("我是我");
ArrayList<String> finalList = new ArrayList<String>();
List list = Arrays.asList("誰是我","我是誰","我是我");
finalList.addAll(list);
assertEquals(finalList,e.newsSort(newsList));
}
@Test(timeout=4000)
public void test5() {
Editor e = new Editor("e",21,18000);
String data = "給定一段字符串,重新排版,使得每行恰好有32個字符,並輸出至控制檯首行縮進,其餘行數左對齊,每個短句不超過32個字符。";
e.textExtraction(data);
String ans = out.toString();
assertEquals(" 給定一段字符串,重新排版," + sep + "使得每行恰好有32個字符," + sep + "並輸出至控制檯首行縮進," + sep + "其餘行數左對齊," + sep + "每個短句不超過32個字符。" + sep, ans);
}
}
ManagerTest.java
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class ManagerTest {
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test(timeout=4000)
public void test1() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("age must be greater than 18 and salary must be greater than 2000.");
Manager m = new Manager("a",1,1,"Programmer");
}
@Test(timeout=4000)
public void test2() {
Manager m = new Manager("a",19,10000,"Programmer");
assertEquals("My name is a ; age : 19 ; salary : 10000 ; department : Programmer.",m.show());
}
@Test(timeout=4000)
public void test3() {
Manager m = new Manager("a",19,10000,"Programmer");
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertEquals("My name is p ; age : 21 ; language : Java ; salary : 8000.",m.inquire(p));
}
@Test(timeout=4000)
public void test4() {
Manager m = new Manager("a",19,10000,"Editor");
Programmer p = new Programmer("p",21,8000,"Java","UI");
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Access denied!");
m.inquire(p);
}
@Test(timeout=4000)
public void test5() {
Manager m = new Manager("a",19,10000,"Editor");
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertFalse(m.lead(p));
}
@Test(timeout=4000)
public void test6() {
Manager m = new Manager("a",19,10000,"Programmer");
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertTrue(m.lead(p));
}
@Test(timeout=4000)
public void test7() {
Manager m = new Manager("a",19,10000,"Programmer");
assertEquals("Empty",m.print());
}
@Test(timeout=4000)
public void test8() {
Manager m = new Manager("a",19,10000,"Programmer");
Programmer p1 = new Programmer("p1",21,8000,"Java","UI");
Programmer p2 = new Programmer("p2",34,9000,"Java","Test");
m.lead(p1);
m.lead(p2);
assertEquals("Statement for a\n - p1\n - p2",m.print());
}
}
ProgrammerTest.java
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
public class ProgrammerTest {
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test(timeout=4000)
public void test1() {
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertEquals("My name is p ; age : 21 ; language : Java ; salary : 8000.",p.show());
}
@Test(timeout=4000)
public void test2() {
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertEquals("2,250.00",p.getBonus(5));
}
@Test(timeout=4000)
public void test3() {
Programmer p = new Programmer("p",21,8000,"Java","UI");
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Overtime illegal!");
p.getBonus(-1);
}
@Test(timeout=4000)
public void test4() {
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertEquals("q*****[email protected]",p.hideUserinfo("[email protected]"));
}
@Test(timeout=4000)
public void test5() {
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertEquals("***-***-7890",p.hideUserinfo("1(234)567-890"));
}
@Test(timeout=4000)
public void test6() {
Programmer p = new Programmer("p",21,8000,"Java","UI");
assertEquals("+**-***-***-5678",p.hideUserinfo("86-(10)12345678"));
}
}
本來我都是還在考研的奮鬥旅途中的,結果被幾個實驗室的好朋友拉了過來組隊參加今天的這場比賽。我們幾個自己心裏還是覺得最後的成績不算太理想,56組測試用例只過了35組,我們幾個都是奮戰到了六點比賽結束的時候,感覺正常發揮的話我們合力應該可以過45組左右的測試用例的。
最大的原因還是我們前期準備工作做得不足吧,前幾天的訓練賽我們幾個都沒有打,導致今天我們四個的分工配合、時間把握等環節明顯做得不好,對慕測平臺上面代碼提交、本地環境配置(SonarQube)、出錯顯示等流程也不熟悉,最後也出現了本不應該出現的失誤。我們大概是到4點多才開始提交成功,之前都是過的原始的那五組數據。這麼晚的提交成功也大大影響了我們對於整個項目方向上的把握和時間的分配,前期我們幾乎看不到自己哪裏錯了,哪裏對了。所以直到最後一刻我們還在奮戰,其實感覺我們可以做得更好的。
關於南大舉辦的這次比賽,我的感覺是自己第一次參加這種類型的比賽。因爲以前不是參加ACM性質的刷題比賽就是參加服創、軟件杯這種的項目比賽,從沒參加過這種團隊性質的,有點像刷題看測試數據通過組數,又是給你一個項目似的應用背景,還要求代碼規範(評分會有一部分是看代碼規範來打分的)的比賽。所以除了有些不適應以外,更多的是一種新穎性和創新性吧。我們這些參賽者加了一個比賽羣,裏面同學們討論很激烈,也都很有見地和想法,老師們答疑也非常及時與熱心。通過這些我學到了很多東西同時發現自己也還有很多不足需要改進。最後還是爲南大的這次比賽的良好組織點贊,希望日後有更多的機會去參加這類有意義的比賽來不斷提升自己的能力和綜合素質!這次算是自己考研旅途中的小插曲吧,收拾好心情就要繼續踏上征程了!
以下是我們比賽中的一些圖片