一、單選題
1、下列關於繼承的描述錯誤的是( )
A. 在Java中允許定義一個父類的引用,指向子類對象
B. 在Java中繼承是通過extends關鍵字來描述的,而且只允許繼承自一個直接父類
C. 在Java中抽象類之間也允許出現繼承關系
D. 在Java中一個子類可以繼承多個抽象類,在extends關鍵字后一次列出,用逗號隔開
參考答案:D
語法層面上抽象類和接口的區別
1)抽象類可以提供成員方法的實現細節,而接口中只能存在public abstract方法;
2)抽象類中的成員變量可以是各種類型的,而接口中的成員變量只能是public static final類型的;
3)接口中不能含有靜態代碼塊以及靜態方法,而抽象類可以有靜態代碼塊和靜態方法;
4)一個類只能繼承一個抽象類,而一個類卻可以實現多個接口。
2、以下關於接口的說法錯誤的是( )
A. 接口中的成員變量和成員方法只能是Public(或者缺省不寫)
B. Java中的接口(interface)也繼承了Object類
C. 實現接口的類必須全部實現接口中的方法
D. 接口中的方法只能有方法原型,不能有方法主體
參考答案:B
3、在一個請求分頁系統中,采用NUR頁面置換算法時,假如一個作業的頁面走向為1,2,1,5,4,2,4,3,2,4。當分配給該作業的物理塊數為3時,訪問過程中命中的次數為( )
A. 3
B. 4
C. 5
D. 6
參考答案:B
主要的頁面置換算法有:OPT、LRU、LFU、NUR以及FIFO。
FIFO:先進先出算法。
OPT:最佳置換算法。
LRU:最近最久未使用算法。
LFU:最近最少使用算法。
NUR:最近未使用算法。
4、下列程序的執行結果是( )
Public class Test
{
Public static void main(String[] args)
{
Stytem.out.prinln(“ “ + ‘b’ +1);
}
}
A. 99
B. 981
C. 198
D. b1
參考答案:D
5、TCP套接字函數中( )不會產生阻塞。
A. accept
B. bind
C. write
D. Read
參考答案:B
6、下面關於二叉排序樹的說法錯誤的是( )
A. 在二叉排序樹中,完全二叉樹的查找效率最低
B. 對二叉排序樹進行中序遍歷,必定得到節點關鍵字的有序序列
C. 二叉排序樹的平均查找長度是O(log2n)
D. 二叉排序樹的查找效率與二叉樹的樹形有關
參考答案:A
解析:在二叉排序樹中,完全二叉樹的查找效率最高
7、多線程與多進程的主要區別之一就是共享資源,多線程是通過互斥訪問來協調共享資源,在Windows系統中使用什么對象使多線程之間對資源互斥訪問( )
A. SysTherad
B. InitTherad
C. Mutex
D. Select
參考答案:C
8、在FTP服務器上FTP主進程打開的端口為( )
A. 23
B. 20
C. 21
D. 22
參考答案:C
9、咖啡店銷售系統具體需求為:咖啡店店員在賣咖啡時,可以根據顧客的要求加入各種配料,並根據加入配料價格的不同來計算總價。若要設計該系統可以應該采用( )進行設計
A. 裝飾模式
B. 單例模式
C. 原型模式
D. 組合模式
參考答案:A
10、下列程序的執行結果是( )
int num = 17;
while(num>0)
{
System.out.print(num ++ %5 + “\t”);
num /=5;
}
A. 2 4
B. 3 4
C. 2
D. 2 3
參考答案:D
11、解決哈希沖突的鏈地址算法中,關於插入新的數據項的時間表述正確的是( )
A. 和數組已占用單元的百分比成正比
B. 和鏈表數目成正比
C. 和哈希表中項數成正比
D. 隨裝填因子線性增長
參考答案:D
散列表的裝填因子定義為:α=填入表中的元素個數/散列表的長度
α是散列表裝滿程度的標志因子。由於表長是定值,α與“填入表中的元素個數”成正比,所以,α越大,填入表中的元素較多,產生沖突的可能性就越大;α越小,填入表中的元素較少,產生沖突的可能性就越小。
12、下列關於Object類的說法,正確的是( )
A. 如果一個類顯示地繼承了其他類,則該類不再繼承Object類
B. Error類不是從Object類派生出來的
C. 如果一個類是從Object類派生出來的,那么必須重寫toString()和equals()方法
D. 一個類如果定義為abstract的,依然繼承自Object類
參考答案:D
13、( )是調用者發出消息后,必須等待消息處理結束返回后,才能進行后續操作
A. 同步消息
B. 返回消息
C. 異步消息
D. 簡單消息
參考答案:A
14、假設下列字符碼中有奇偶校驗位,但沒有數據錯誤,采用偶校驗的字符碼是( )
A. 11010110
B. 11000001
C. 11001011
D. 11001001
參考答案:D
由於干擾,可能使位變為1,(為什么不變0?)這種情況,我們稱為出現了“誤碼”。我們把如何發現傳輸中的錯誤,叫“檢錯”。發現錯誤后,如何消除錯誤,叫“糾錯”。最簡單的檢錯方法是“奇偶校驗”,即在傳送字符的各位之外,再傳送1位奇/偶校驗位。可采用奇校驗或偶校驗。
奇校驗:所有傳送的數位(含字符的各數位和校驗位)中,“1”的個數為奇數,如:
1 0110,0101
0 0110,0101
偶校驗:所有傳送的數位(含字符的各數位和校驗位)中,“1”的個數為偶數,如:
1 0100,0101
0 0100,0101
奇偶校驗能夠檢測出信息傳輸過程中的部分誤碼(奇數位誤碼能檢出,偶數位誤碼不能檢出),同時,它不能糾錯。在發現錯誤后,只能要求重發。但由於其實現簡單,仍得到了廣泛使用。有些檢錯方法,具有自動糾錯能力。如循環冗余碼(CRC)檢錯等。
15、下列各序列中不是堆的是( )
A. (9,8,5,3,4,2,1)
B. (9,4,5,8,3,1,2)
C. (9,5,8,4,3,2,1)
D. (9,8,5,4,3,1,2)
參考答案:B
解析:堆要求父節點的元素值必須全部大於或者小於子節點的元素值,A、C和D都是符合條件的大根堆,B的第三層的元素8大於第二層的父元素值4,不符合堆的條件,故而本題答案為B選項。
16、在Java中,以下哪個可以與函數public int A()(…)構成重載( )
A. public void A()(…)
B. public int A(int m)(…)
C. public void A(int n)(…)
D. public static int A()(…)
參考答案:B
17、現有如下代碼段:
x = 2;
while(x<n/2)
x = 2*x;
假設n>=0,則其時間復雜度應為( )
A. O(log2n)
B. O(nlog2n)
C. O(n)
D. O(n^2)
參考答案:A
18、下列程序輸出的結果為( )
int i =11,j = 5;
switch(i /j)
{
case 3;
j += i;
case 2;
j += 4;
case 4;
j += 5;
case 1;
j += 1;
break;
}
System.out.println(j);
A. 9
B. 14
C. 5
D. 15
參考答案:D
j=5+4+5+1=15
19、有關構造方法,下列敘述正確的是( )
A. 默認的構造方法可以具有參數
B. 假如一個類缺少沒有參數的構造方法,但是有其它的構造方法,,則編譯器生成一個缺省的構造方法
C. 編譯器總會給每一個類生成一個無參的缺省構造方法
D. 默認的構造方法初始化了在類中聲明的實例變量
參考答案: D
解析:
A、默認構造方法可以沒有參數,也可以有參數,但是每個參數都必須有默認值。
B、有了就不會再生成缺省的了。
C、如果沒有默認的構造方法,編譯器才會為類生成一個無參的缺省構造方法,不是總是生成的,是有條件的。
D、默認的構造方法不初始化變量
20、在UML中,( )體現了一種contains-a的關系
A. 聚合關系
B. 實現關系
C. 組合關系
D. 關聯關系
參考答案:C
UML定義的關系主要有六種:依賴、類屬、關聯、實現、聚合和組合。
組合也是關聯關系的一種特例,他體現的是一種contains-a的關系,這種關系比聚合更強,也稱為強聚合;他同樣體現整體與部分間的關系,但此時整體與部分是不可分的,整體的生命周期結束也就意味着部分的生命周期結束;比如你和你的大腦;表現在代碼層面,和關聯關系是一致的,只能從語義級別來區分。
21、一個上下文無關文法一般是由一組非終結符號、一組終結符號,一個開始符號和一組產生式構成,那么產生式是用於定義( )的一種規則
A. 邏輯推理
B. 語義成分
C. 詞法成分
D. 語法成分
參考答案:D
二、多選題
1、可唯一確定一棵二叉樹的是( )
A. 給定一棵二叉樹的后序和中序遍歷序列
B. 給定一棵二叉樹的先序和后序遍歷序列
C. 給定一棵二叉樹的先序和中序遍歷序列
D. 給定先序、中序和后序遍歷序列中的任意一個即可
參考答案:A、C
2、下面哪些是使用分治法的前提條件( )
A. 該問題具有最優子結構性質
B. 原問題和子問題求解方法相同
C. 子問題必須是一樣的
D. 子問題之間不包含公共的子問題
參考答案:ABD
3、下面關於Java的說法正確的是( )
A. 一個類只能定義一個構造函數
B. 類中的構造函數不可省略
C. 構造函數必須與類同名
D. 普通類方法可以與類同名
參考答案:C、D
4、有關單例模式的說法中正確的是( )
A. 用戶無法通過new方式實例化單例類
B. 單例模式屬於創建型模式
C. 單例模式用於多線程應用程序
D. 違背了單一職責原則
參考答案:A、B、C
5、下面的存儲過程實現用戶驗證功能,如果不成功,返回0,成功則返回1.
CREATE PROCEDURE VALIDATE @USERNAME CHAR,@PASSWORD CHAR,@LEGAL BIT OUTPUT AS IF EXISTS(SELECT*FROM REN WHERE SNAME = @USERNAME AND PWD = @PASSWORD)
SELECT @LEGAL = 1
ELSE
SELECT @LEGAL = 0
該用戶的用戶名和密碼分別是’Tom’和’123’,執行該存儲過程語句和結果正確的是:( )
A. declare @LEGAL bit
exec dbo.validate’Tom’,’123’,@LEGAL OUTPUT
SELECT @LEGAL
結果:1
B. declare @LEGAL bit
exec dbo.validate’TomCat’,’123’,@LEGAL OUTPUT
SELECT @LEGAL
結果:1
C. declare @LEGAL bit
exec dbo.validate’Tom’,’123’,@LEGAL OUTPUT
SELECT @LEGAL
結果:0
D. declare @LEGAL bit
exec dbo.validate’TomCat’,’123’,@LEGAL OUTPUT
SELECT @LEGAL
結果:0
參考答案:A、D
6、Spring有哪三個核心組件( )
A. Beans
B. Context
C. IOC
D. Core
參考答案:A、B、D
7、下列關於視圖的說法中正確的是( )
A. 對視圖的使用與表一樣,也可以進行插、查、刪、改操作
B. 視圖與表一樣,也存儲着數據
C. 對視圖的操作,是最終都要轉化成對基本表的操作
D. 可以根據數據庫表和自由表建立視圖
參考答案:C、D
8、關於wait()和sleep()說法正確的是( )
A. wait()和sleep()都會釋放鎖
B. sleep()可以在任何地方使用
C. wait()只能在方法或者語句塊中使用
D. wait()和sleep()都是Thread類的方法
參考答案:B、C
sleep()方法(休眠)是線程類(Thread)的靜態方法,調用此方法會讓當前線程暫停執行指定的時間,
將執行機會(CPU)讓給其他線程,但是對象的鎖依然保持,因此休眠時間結束后會自動恢復(線程回到就緒狀態,請參考第66題中的線程狀態轉換圖)。
wait()是Object類的方法,調用對象的wait()方法導致當前線程放棄對象的鎖(線程暫停執行),進入對象的等待池(wait pool),只有調用對象的notify()方法(或notifyAll()方法)時才能喚醒等待池中的線程進入等鎖池(lockpool),如果線程重新獲得對象的鎖就可以進入就緒狀態。
9、下列等價類的敘述中正確的是( )
A. 若輸入條件為一個布爾變量,則可以確定一個有效等價類和一個無效等價類
B. 若輸入條件為一個邏輯量,則可為每一個輸入值確定一個有效等價類,並針對這組值確定一個無效等價類
C. 若輸入條件規定了“必須如何”的條件,則可以確定一個有效等價類和兩個無效等價類
D. 若輸入條件規定了取值的上下限,則可以確定一個有效等價類和兩個無效等價類
參考答案:A、B、D
划分等價類的6條原則:
(1)在輸入條件規定了取值范圍或值的個數的情況下,可以確立一個有效等價類和兩個無效等價類
(2)在輸入條件規定了輸入值的集合或者規定了“必須如何”的條件的情況下,可以確立一個有效等價類和一個無效等價類
(3)在輸入條件是一個布爾量的情況下,可確定一個有效等價類和一個無效等價類
(4)在規定了輸入數據的一組值(假定n個),並且程序要對每一個輸入值分別處理的情況下,可確立n個有效等價類和一個無效等價類
(5)在規定了輸入數據必須遵守的規則的情況下,可確立一個有效等價類(符合規則)和若干個無效等價類(從不同角度違反規則)
(6)在確知已划分的等價類中,各元素在程序處理中的方式不同的情況下,則再將該等價類進一步地划分為更小的等價類
三、簡答題
等價類划分法應如何取值?與邊界值法取值有何不同?
【解析】
1、有效等價類
(1)等價類划分法和邊界值法都是軟件測試中基於輸入域的方法。等價類划分法中的等價類是指某個輸入域的一個特定的子集合,在該子集合中各個輸入數據對於揭露程序中的錯誤都是等效的。等價類划分法確定有效等價類和無效等價類。有效等價類是指輸入完全滿足程序輸入的規格說明、有意義的輸入數據所構成的集合,利用有效等價類可以檢驗程序是否滿足規格說明所規定的功能和性能,而無效等價類可以檢驗程序是夠滿足規格說明所規定的功能和性能。
(2)如何確定有效等價類和無效等價類,可以有下面的情形:
- 輸入條件規定取值范圍或者個數的情況。如輸入條件大於10,小於100,那么有效等價類為10,無效等價類為x<10和x>100。
- 輸入條件規定了輸入域的集合或者規定了“必須如何”的情況。如輸入x=10,有效等價類為x=10,無效等價類為x!=10。
- 輸入條件是一個布爾量的情況。如x=true,那么有效等價類是x=true,無效等價類是x=false。
- 輸入條件規定 了一組數據。如x取值與{1,2,3},那么等價類是x屬於{1,2,3},無效等價類是x不屬於{1,2,3};
- 輸入條件有必須遵守的條件。如郵箱格式@,有效等價類是包含@的字符串,無效等價類是不包含@的字符串。
2、邊界值取值
(1)邊界值分析法就是在某個輸入輸出范圍的邊界上,驗證系統功能是否正常運行的測試方法。
(2)邊界值的情況有如下:
- 如果輸入條件規定了值的范圍,則取剛剛達到這個范圍的邊界值,以及剛剛超過這個范圍邊界的值。如輸入條件是2000~6000,那么測試用例取1999、2000、6000、6001。
- 如果輸入條件規定了值的個數,則取最大個數、最小個數、比最大個數多一個、比最小個數少一個等作為測試用例。如值的個數是2~5,則測試用例取2個數字、3個數字、5個數字、6個數字。
四、編程題
時間限制:C/C++語言2000MS;其他語言4000MS
內存限制:C/C++語言65536KB;其他語言589824KB
題目描述:
有n 個人排成了一行隊列,每個人都有一個站立的方向:面向左或面向右。由於這n 個人中每個人都很討厭其他的人,所以當兩個人面對面站立時,他們會發生爭吵,然后其中一個人就會被踢出隊列,誰被踢出隊列都是有可能的。
我們用字符L 來表示一個面向左站立的人,用字符R 來表示一個面向右站立的人,那么這個隊列可以用一個字符串描述。比如RLLR 就表示一個四個人的隊列,其中第一個人和第二個人是面對面站立的。他們發生爭吵后隊列可能會變成LLR,也可能變成RLR;若變成RLR,則第一個人與第二個人還會發生爭吵,隊列會進一步變成LR 或者RR。
若在某個時刻同時可能有很多的爭吵會發生時,接下來只會發生其中的一個,且任意一個都是有可能發生的。
你想知道經過一系列的爭吵后,這個隊列最少會剩下多少人?
輸入
第一行包含一個有字符L 和R 構成的字符串。
1 ≤字符串長度≤ 105
輸出
輸出隊列中最少會剩下多少人。
樣例輸入
LRRLRL
樣例輸出
2
Hint
一種可能的變化情況是這樣的:
LRRLRL -> LRLRL -> LRRL -> LRL -> LR
【解答】
(1)c++版本
#include <iostream> #include <string> using namespace std; int main() { string s; cin >> s; int left = -1; int right = -1; for (int i = 0; i < s.size(); i++) { if (s[i] == 'R') { left = i; break; } } for (int i = s.size() - 1; i >= 0; i--) { if (s[i] == 'L') { right = i; break; } } if (right == -1 || left == -1) cout << s.size() << endl; else if (left > right) cout << s.size() << endl; else cout << s.size() - (right - left) << endl; return 0; }
(2)java版本
import java.util.Scanner; /** * 科大訊飛的吵架問題 */ public class Quarrel { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { String s = sc.nextLine(); result(s); } sc.close(); } public static void result(String s) { int left = -1; int right = -1; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == 'R') { left = i; break; } } for (int i = s.length() - 1; i >= 0; i--) { if (s.charAt(i) == 'L') { right = i; break; } } if (right == -1 || left == -1) System.out.println(s.length()); else if (left > right) System.out.println(s.length()); else System.out.println(s.length() - (right - left)); } }
2、球賽
時間限制:C/C++語言1000MS;其他語言3000MS
內存限制:C/C++語言65536KB;其他語言589824KB
題目描述:
大學生足協決定舉辦全國性的大學生足球賽,由每個學校派遣一支隊伍代表該校參賽。比賽分區分為幾個賽區進行,最終的總決賽中,將有不超過n支隊伍參加。經過激烈的角逐,有機會參與總決賽的隊伍已經決出。
協會對比賽的規則進行了調整,以便使得比賽更具有觀賞性。
1. 總決賽的參賽隊伍為n支,n為偶數;
2. 進入前1/2的隊伍才有資格進入淘汰賽;
3. 隊伍按積分排名,具體規則為:勝一場積3分;平一場積1分;負一場積0分。隊伍首先按積分降序排列,積分相同按凈勝球數降序排列,仍然相同的按進球數降序排列。
4. 基於上述規則,尚未出現有排名歧義的情況發生。
隨着賽程的進行,目前各個隊伍對戰的結果已經確定了,小B負責確定進入淘汰賽的名單,她向你求助,你能幫她嗎?
輸入
測試數據有多組,每組測試數據的第一行為一個整數n(1=< n <=50),為參與總決賽的球隊數,隨后的n行為球隊的名字,由不超過30個的大小寫拉丁字母構成。隨后的n*(n-1)/2行為賽事的開展情況,每行的格式為name1-name2 num1:num2,表示兩支隊伍的比分情況(1=<num1, num2<=100)。確保不會有兩支隊伍同名,也不會出現隊伍自己通自己比賽的情況,且每場比賽僅出現一次。
輸出
對每組測試數據,輸出n/2行,為按字母序排列的進入淘汰賽的n/2支隊伍的名單,每個名字在單獨的行中輸出。
樣例輸入
4
A
B
C
D
A-B 1:1
A-C 2:2
A-D 1:0
B-C 1:0
B-D 0:3
C-D 0:3
2
a
A
a-A 2:1
樣例輸出
A
D
a
【解答】
(1)c++版本
#include<iostream> #include<vector> #include<algorithm> #include<string> #include<stdlib.h> using namespace std; bool myComp(const vector<int>& a, const vector<int>& b) { if (a[1] > b[1]) return true; else if (a[1] < b[1]) return false; if (a[2] > b[2]) return true; else if (a[2] < b[2]) return false; if (a[3] > b[3]) return true; else if (a[3] < b[3]) return false; else return true; } int main(void) { int n; while (cin >> n) { vector<string> names; vector<vector<int>> datas; for (int i = 0; i < n; i++) { vector<int> t; for (int j = 0; j < 4; j++) { t.push_back(0); } datas.push_back(t); } for (int i = 0; i < n; i++) { datas[i][0] = i; } for (int i = 0; i < n; i++) { string t; cin >> t; names.push_back(t); } for (int i = 0; i < n * (n - 1) / 2; i++) { string t; cin >> t; int ind = t.find('-'); string name1 = t.substr(0, ind); string name2 = t.substr(ind + 1, t.size() - ind - 1); auto iter = find(names.begin(), names.end(), name1); int team1 = iter - names.begin(); iter = find(names.begin(), names.end(), name2); int team2 = iter - names.begin(); cin >> t; ind = t.find(':'); string s1 = t.substr(0, ind); string s2 = t.substr(ind + 1, t.size() - ind - 1); int score1 = atoi(s1.c_str()); int score2 = atoi(s2.c_str()); if (score1 > score2) { datas[team1][1] += 3; } else if (score1 == score2) { datas[team1][1] += 1; datas[team2][1] += 1; } else { datas[team2][1] += 3; } datas[team1][2] += (score1 - score2) > 0 ? (score1 - score2) : 0; datas[team2][2] += (score2 - score1) > 0 ? (score2 - score1) : 0; datas[team1][3] += score1; datas[team2][3] += score2; } sort(datas.begin(), datas.end(), myComp); vector<int> res; for (int i = 0; i < n / 2; i++) { int team = datas[i][0]; res.push_back(team); } sort(res.begin(), res.end()); for (int i = 0; i < n / 2; i++) { cout << names[res[i]] << endl; } } return 0; }
3、課程沖突
時間限制:C/C++語言2000MS;其他語言4000MS
內存限制:C/C++語言65536KB;其他語言589824KB
題目描述:
小明是一名學生,又到了學校的選課時間,他想選一些課程學習,已知課程開課時間都在每周一到周五之內,早上4講課,下午4講課,晚上2講課。
小明擔心選課時間上有所沖突。所以他希望可以對課程時間進行檢查。
輸入
首先輸入一個整數n(0<n<=100),表示小明選課總數。
之后輸入n行選課信息,每行選課信息有2個數字。
第一個數字表示開課時間,開課時間用2位數表示,前一位用0到4表示周一至周五,后一位用0到9表示從早到晚順序第幾講課,如12表示禮拜二第三講課。01表示禮拜一第二講課。
每行第二個數字表示課程代碼,如:204521。課程代碼為6位數字。輸入課程代碼均不重復。
輸出
如果沒有沖突課程,輸出YES。
如果有沖突課程,也就是同一個時間多於一節課,輸出所有沖突的課程。輸出有多行,如果多個不同的上課時間都有課程沖突,按照周一到周五,早上到晚上時間先后,按行輸出沖突信息。在同一行內,先輸出沖突時間,之后輸出這一時間的所有課程,輸出課程的順序為輸入中這些課程出現的順序,課程之間以空格分隔,不要在行末輸出多余的空格。
樣例輸入
5
01 204521
23 204523
22 204526
01 204528
22 204527
樣例輸出
01 204521 204528
22 204526 204527
Hint
Input Sample 2
3
11 204521
23 204522
43 204531
Output Sample 2
YES
【解答】
(1)c++版本
#include <iostream> #include <vector> using namespace std; vector<int> course[50]; int main() { int n; cin >> n; for (int i = 0; i < n; i++) { int time, id; cin >> time >> id; course[time].push_back(id); } bool flag = true; for (int i = 0; i <= 49; i++) { if (course[i].size() >= 2) { flag = false; if (i <= 9) cout << 0; cout << i; for (int j = 0; j < course[i].size(); j++) { cout << " " << course[i][j]; } cout << endl; } } if (flag) cout << "YES" << endl; return 0; }
(2)java版本
package cn; /** * 科大訊飛選課問題 * Created by Administrator on 2018/3/12. */ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Scanner; public class ConflictCourse { public static void main(String[] args) { Scanner in = new Scanner(System.in); int num = in.nextInt(); in.nextLine(); String[] str = new String[num]; for (int i = 0; i < num; i++) { str[i] = in.nextLine(); } String[] str1 = new String[num]; String[] str2 = new String[num]; for (int i = 0; i < num; i++) { String[] arr = str[i].split(" "); str1[i] = arr[0]; str2[i] = arr[1]; } List<List<String>> list = new ArrayList<>(); for (int i = 0; i < num; i++) { if (str1[i] == null) continue; List<String> list1 = new ArrayList<>(); list1.add(str1[i]); for (int j = i + 1; j < num; j++) { if (str1[i].equals(str1[j])) { str1[j] = null; list1.add(str2[i]); list1.add(str2[j]); } } list.add(list1); } List<List<String>> retList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { if (list.get(i).size() >= 3) { retList.add(list.get(i)); } } // 無課程沖突 if (retList.size() == 0) { System.out.println("YES"); return; } // 按時間排序 Collections.sort(retList, new Comparator<List<String>>() { @Override public int compare(List<String> o1, List<String> o2) { return (o1.get(0)).compareTo(o2.get(0)); } }); for (int i = 0; i < retList.size(); i++) { for (int j = 0; j < retList.get(i).size() - 1; j++) { System.out.print(retList.get(i).get(j) + " "); } System.out.println(retList.get(i).get(retList.get(i).size() - 1)); } } }
------------------------------------------
參考鏈接:
1、https://www.nowcoder.com/discuss/67684?type=0&order=0&pos=7&page=1
2、http://blog.csdn.net/debbie_wxg/article/details/78005347#t3