1. 程式人生 > >JAVA 程式設計題(實驗4 容器 第6題)

JAVA 程式設計題(實驗4 容器 第6題)

Professor Charles Xavier is having a tough time remembering all the different kinds of X-Men, their power and weakness. With the improvement of cerebro his mind can reach anywhere on earth. He decided to build a database of X- men so that he can find them quickly. You will be helping the great professor in this homework.

Edit: The constructor now takes an enemy list instead of just one enemy.

You’ll need to create two classes to store this information. First you’ll need to create the Xman class. It will need the following methods.

public Xman(String name, String xname, String power, String weakness,   List<String> enemy, Date birthDate, String gender, String   DNASequence) 

The constructor will need to set the appropriate instance variables.

public String getName() 

This method should return the xname and name concatenated like   xname(name).

public String getPower() 

Return the power

public String getWeakness() 

Return the weakness.

public List<Xman> getEnemy() 

Return the enemy Xmen.

public Date getBirthDate() 

Return the date of birth. You will need to import the package   java.util.date 

public String getGender() 

Return the gender.

public String getDNASequence() 

Return the DNA sequence (if you decide to use print statements for   debugging, be aware that this is a really long string).

public boolean equals(Object o) 

You need override the equals() method, such that two Xman with the same   DNA sequence are considered equal.

Because there are lots of X-men, we need a fast way look them up. We’re going to use the hash tables discussed in class to create a way of looking up records by both DNA sequence and name. Make the class XDatabase which will contain two arrays of lists:

List<Xman>[] dnaSeq;

List<Xman>[] nameIndex;

Having a list at each index of the arrays will allow us to handle collisions, by simply adding multiple Records to that spot. You can use linked list or array list whatever you like. (This can be yours/java's default LinkedList /ArrayList)

Java’s base class Object, has the method hashCode(), which returns an int based on the value of that object. It’s important to note that this can return a negative integer, so when you hash it, you’ll need to take the absolute value. So we can figure out the position a record belongs in thednaSeq array by:

int i = Math.abs(xman.getDNASequence().hashCode()) % dnaSeq.length; Because we’re going to have a large number of X-men in our database, we need to be conscious of memory usage. This means that we won’t create a list at an index, until we store something at that index.

Finally, this is the list of methods you will need to implement in your XDatabase class:

public XDatabase(int size) 

The constructor will initialize your two arrays to be of the specified   size. You will also need to keep track of the total number of items in your   database, so you should initialize a size variable to 0 in here too.

public Xman add(Xman xman) 

This method will take in a Xman, and add it both to the dnaSeq and   nameIndex arrays in the appropriate places. If a record with the same   DNASequence already exists in the database, it should get replaced, and the   previous record should be returned. Otherwise return null.

public Xman getByDNASequence(String dnaSeqence) 

This method will search for a Xman with the specified dnaSequence using   your dnaSeq list. It should return null if no record with that dnaSequence   exists.

public List<Xman> getByName(String name) 

This method will search for a Xman based on name, using the nameIndex.   Because it is possible for multiple Xman to have the same name, it will   return of list of Xman with matching names. If no records match, an empty   list should be returned.

public Xman delete(String dnaSeq) 

This method should delete the Xman with the matching dnaSeq from both   indexes, and return that record. If no record is found, it should return   null.

public int size() 

This method should return the number of Xman stored in the database.

public List<Xman> friends(String dnaSeq)

Given a dnaSeq of an Xman, find   his/her friends. An Xman A is a friend of another Xman B,   if and only if A is not in B's enemy List   and A is in the enemy list of at least one of the enemys   of B. If no friends are found, return empty list.

public List<Xman> partner(String name)

Given the name of a Xman, find his/her partner. An Xman A is   the partner of another Xman B, if and only if A is   not in B's enemy List and A is in the enemy list   of all enemies of B. If no partners are found, return empty list.   If multiple Xman are found by the same name, concatenate all their partners   in the list.

public List<Xman> archrival(String name)

Given the name of a Xman, find his/her arch rival. An Xman A is   the arch rival of another Xman B, if and only if A is   in the enemy list of Band A is in the enemy list   of all friends of B. If no arch rivals are found, return empty   list. If multiple Xman are found by the same name, concatenate all their arch   rivals in the list.

Now, instead of using java's hash code, write your own hash function. It will take a string and generate a hash code from that. Test all the methods above.

 (個人意見,僅供參考,如有錯誤,還望指出)

所有方法已進行簡單測試。

 Xman類:

import java.util.*;
public class Xman {
	private String name;
	private String xname;
	private String power;
	private String weakness;
	private List<String> enemy;
	private Date birthDate;
	private String gender;
	private String DNASequence;
	public Xman(String name, List<String> enemy, String DNASequence) {
		this.name = name;
		this.enemy = enemy;
		this.DNASequence = DNASequence;
	}
	public Xman(String name, String xname, String power, String weakness,List<String> enemy, Date birthDate, String gender, String DNASequence) {
		this.name = name;
		this.xname = xname;
		this.power = power;
		this.weakness = weakness;
		this.enemy = enemy;
		this.birthDate = birthDate;
		this.gender = gender;
		this.DNASequence = DNASequence;
	}
	public String getName() {
		return name;
	}
	public String getXname() {
		return xname;
	}
	public String getPower() {
		return power;
	}
	public String getWeakness() {
		return weakness;
	}
	public String getGender() {
		return gender;
	}
	public List<String> getEnemy() {
		return enemy;
	}
	public Date getBirthDate() {
		return birthDate;
	}
	public String getDNASequence() {
		return DNASequence;
	}
	
	public int hashCode() {
		int result = 1;
		if((DNASequence == null)) {
			result = 0;
		} else {
			result = Math.abs(DNASequence.hashCode()) % DNASequence.length();
		}
		
		return result;
	}
	
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Xman other = (Xman) obj;
		if (DNASequence == null) {
			if (other.DNASequence != null)
				return false;
		} else if (!DNASequence.equals(other.DNASequence))
			return false;
		return true;
	}
	

}

XDatabase類:

import java.util.*;

public class XDatabase {

	private List<Xman>[] dnaSeq;
	private List<Xman>[] nameIndex;
	private int num;// Xman的數量
	private int length;//陣列長度
	//length是陣列的長度,可能某個元素為null
	//num值Xman的數量,相當於length去掉null的數量之後的個數

	/*
	 * 建構函式,傳入size,為List分配記憶體,初始化num、和length;
	 */
	public XDatabase(int size) {

		dnaSeq = new ArrayList[size];
		nameIndex = new ArrayList[size];
		for(int i=0;i<size;i++) {
			dnaSeq[i] = new ArrayList();
			nameIndex[i] = new ArrayList();
		}
		num = 0;
		length = 0;
	}

	/*
	 * 新增Xman
	 */
	public Xman add(Xman xman) {
		int pos=-1;//為了減少記憶體的浪費,設定pos用來檢查是否有已分配記憶體但未使用的位置。
		for (int i = 0; i < length; i++) {//遍歷檢查dnaSeq中是否已存在此xman,若已存在,則更新,否則直接新增。
			if(dnaSeq[i].size()==0) {
				pos=i;
			}
			if (dnaSeq[i].contains(xman)) {
				Xman prexman = dnaSeq[i].get(0);
				dnaSeq[i].clear();
				dnaSeq[i].add(xman);
				nameIndex[i].clear();
				nameIndex[i].add(xman);
				return prexman;
			}
		}
		if(pos==-1) {
			nameIndex[length].add(xman);
			dnaSeq[length++].add(xman);
			num++;
		} else {
			nameIndex[pos].add(xman);
			dnaSeq[pos].add(xman);
			num++;
		}
		
		return null;
	}

	/*
	 * 根據DNA序列查詢Xman
	 */
	public Xman getByDNASequence(String dnaSeqence) {
		for (int i = 0; i < length; i++) {
			if (dnaSeq[i].size() == 0)//如果這個位置沒有xman,直接跳過
				continue;
			if (dnaSeq[i].get(0).getDNASequence().equals(dnaSeqence)) {//比較DNA序列
				return dnaSeq[i].get(0);
			}
		}
		return null;
	}

	/*
	 * 根據name查詢Xman,可能有多個相同name的Xman,所以存在List<Xman>中
	 */
	public List<Xman> getByName(String name) {
		List<Xman> xmans = new ArrayList<Xman>();//分配記憶體
		
		for (int i = 0; i < length; i++) {
			if (nameIndex[i].size() == 0)
				continue;
			if (nameIndex[i].get(0).getName().equals(name)) {//姓名相同,就存入xmans中
				xmans.add(nameIndex[i].get(0));
			}
		}
		return xmans;
	}

	/*
	 * 根據DNA序列刪除Xman
	 */
	public Xman delete(String dnaSeq) {
		for (int i = 0; i < length; i++) {
			if (this.dnaSeq[i].size() == 0)
				continue;
			if (this.dnaSeq[i].get(0).getDNASequence().equals(dnaSeq)) {//DNA序列相同則進行刪除操作
				Xman xman = this.dnaSeq[i].get(0);
				this.dnaSeq[i].clear();
				this.nameIndex[i].clear();
				num--;//這裡就是num和length的區別,num可能會減少,但length只能增加
				return xman;
			}
		}
		return null;
	}

	public int size() {
		return num;
	}

	/*
	 * 根據DNA查詢friends
	 */
	public List<Xman> friends(String dnaSeq) {
		Xman xmanB = getByDNASequence(dnaSeq);//待查詢的Xman
		List<Xman> xfriends = new ArrayList<Xman>();
		if(xmanB==null) {
			return xfriends;
		}
		for (int i = 0; i < length; i++) {
			if (this.dnaSeq[i].size() == 0)
				continue;
			Xman xmanA = this.dnaSeq[i].get(0);//待檢查的Xman
			//如果A不在B的敵人列表中
			if (xmanB.getEnemy().contains(xmanA.getDNASequence()) == false) {

				//A在B的敵人中的至少一個的敵人列表中
				for (int j = 0; j < xmanB.getEnemy().size(); j++) {
					Xman xmanC = getByDNASequence(xmanB.getEnemy().get(j));
					if(xmanC==null) {
						continue;
					}
					if (xmanC.getEnemy().contains(xmanA.getDNASequence())) {
						xfriends.add(xmanA);
						break;
					}
				}
			}
		}
		return xfriends;

	}

	/*
	 * 根據name查詢partner
	 */
	public List<Xman> partner(String name){
		List<Xman> xmanBs = getByName(name);
		List<Xman> xpartners = new ArrayList<Xman>();
		for(int k=0;k<xmanBs.size();k++) {//待檢查的Xman
			Xman xmanB = xmanBs.get(k);
			
			for (int i = 0; i < length; i++) {
				
				if (this.dnaSeq[i].size() == 0)
					continue;
				Xman xmanA = this.dnaSeq[i].get(0);
				//A不在B的敵人列表中
				if (xmanB.getEnemy().contains(xmanA.getDNASequence()) == false) {

					boolean is=true;
					//A在B的所有敵人的敵人列表中時
					for (int j = 0; j < xmanB.getEnemy().size(); j++) {
						Xman xmanC = getByDNASequence(xmanB.getEnemy().get(j));
						if (xmanC.getEnemy().contains(xmanA.getDNASequence()) == false) {
							is=false;
							break;
						}
					}
					
					if(is==true)
						xpartners.add(xmanA);
				}
			}
		}
		
		return xpartners;
	}

	/*
	 * 根據name查詢arch rival
	 */
	public List<Xman> archrival(String name) {
		List<Xman> xmanBs = getByName(name);
		List<Xman> xarchrivals = new ArrayList<Xman>();
		for(int k=0;k<xmanBs.size();k++) {
			Xman xmanB = xmanBs.get(k);
			for (int i = 0; i < length; i++) {
				if (this.dnaSeq[i].size() == 0)
					continue;
				Xman xmanA = this.dnaSeq[i].get(0);
				//A在B的敵人列表中
				if (xmanB.getEnemy().contains(xmanA.getDNASequence()) == false) {

					boolean is=true;
					List<Xman> bxfriends = friends(xmanB.getDNASequence());
					//A在B的所有朋友的敵人列表中
					for (int j = 0; j < bxfriends.size(); j++) {
						Xman xmanC = bxfriends.get(j);
						if (xmanC.getEnemy().contains(xmanA.getDNASequence())==false) {
							is=false;
							break;
						}
					}
					if(is==true)
						xarchrivals.add(xmanA);
				}
			}
		}
		return xarchrivals;
	}

}