1. 程式人生 > >華為練習題--社交好友推斷

華為練習題--社交好友推斷

out 問題 關系 peter over 管理 import align --

好友關系管理
描寫敘述:

現有一個社交站點,其好友推薦策略為:用戶A和用戶B不是好友,當二人的共同好友數量超過好友推薦閾值m時,就向AB分別推薦為彼此好友。

本題任務為:對設定的m值。給定一組用戶及各自好友列表,對這一組用戶,重復自己主動應用上述好友推薦策略後(如果每次推薦都被採納),求指定用戶的終於好友列表。

註:好友關系是雙向的,即:假設用戶A是用戶B的好友,那麽用戶B一定也是用戶A的好友。

寫一個程序,在社交網絡中實現:

1)初始化社交網絡

2)創建用戶

3)添加指定兩個用戶之間的好友關系

4)重復自己主動應用好友推薦策略後。獲取某個用戶的好友數量

5)重復自己主動應用好友推薦策略後,推斷某兩個用戶間是否存在好友關系

說明:

1、一個用戶有且僅僅有一個名字,且不存在重名

2、自己和自己不存在好友關系

3、username字大寫和小寫敏感

4、username字字符串長度範圍為[1..20]

5、用戶總數小於100個

執行時間限制: 無限制
內存限制: 無限制
輸入:

五個整數,好友推薦閾值P創建用戶數量m,添加指定兩個用戶之間的好友關系數量M,查詢

某個用戶的好友數量n,查詢指定兩個用戶是否是好友N字符串,每一個數據一行,按到上面的順序依次輸入數據,共m+M+n+N行字符串

字符串。每一個一行,共m+M+n+N行字符串

輸出:

輸出用戶的好友數量,共n個,每一個一行。假設用戶不存在,輸出-1。否則輸出好友數量。例子中的用戶Jack、Peter、Tom的好友數量都是2個。


輸出指定兩個用戶是否是好友。共N個,每一個一行,假設是輸出0。否則輸出-1。例子中的用戶Jack與Peter、Peter與Tom、Jack與Tom都是好友關系,全部輸出0。

例子輸入:
2 3 3 3 3 //好友推薦閾值2。用戶數量為3,添加知道兩個用戶之間的好友關系數量M,
 //查詢某個用戶的好友數量3,查詢指定兩個用戶是否是好友N字符串
 Jack 
 Peter 
 Tom //輸入了三個用戶
 Jack Peter 
 Peter Tom 
 Jack Tom //添加了三個好友關系
 Jack
 Peter 
 Tom //查詢了這三個用戶的好友數量
 Jack Peter 
 Peter Tom 
 Jack Tom //查詢了這三個好友關系是否存在
 例子輸出: 

例子輸出:
2 //Jack幾個好友,這裏就用到了閾值
2 //Peter幾個好友
2 
0 //Jack Peter是否好友
0 //Peter Tom是否好友
0 //Jack Tom是否好友

這道題,我的思路全然錯誤,問題在於沒有看明確閾值究竟是什麽,題目中說道“用戶A和用戶B不是好友,當二人的共同好友數量超過好友推薦閾值m時。就向A和B分別推薦為彼此好友”,而我推斷的卻是兩個人之間隔著幾個人。

爭取今晚之前實現。

2014-8-6萬 8:40

事實上這個好友關系跟圖非常像,鄰接點在這裏就是用戶,邊在這裏就是公共好友數目。這樣問題自然就迎刃而解了。另外就是當這個社交網絡裏面加入了新關系時。就要又一次更新一下這個社交網絡裏面用戶之間的公共好友個數,以免新添關系導致的新好友遺落。

package hw.test;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Scanner;
import java.util.Set;

/**
 * @author 劉利娟 [email protected]
 * @version 創建時間:2014年8月6日 下午9:05:28 類說明:
 */

public class Network {
	private Set<Userinfo> users; // 該社交網絡中的全部用戶
	int P;// 好友推薦閾值P
	int m;// 創建用戶數量m
	int M;// 添加指定兩個用戶之間的好友關系數量M
	int n;// 查詢某個用戶的好友數量n
	int N;// 查詢指定兩個用戶是否是好友N字符串

	public Network() {
		users = null;
	}

	public static void main(String[] args) {
		Network network = new Network();
		network.initial();
	}

	public void initial() {
		Scanner scan = new Scanner(System.in);
		P = scan.nextInt();
		m = scan.nextInt();
		M = scan.nextInt();
		n = scan.nextInt();
		N = scan.nextInt();
		for (int i = 0; i < m; i++) {// 加入了m個用戶
			String uname = scan.next();
			addUserinfo(new Userinfo(uname));
		}
		for (int i = 0; i < M; i++) {// 加入了M個用戶關系
			String r1 = scan.next();
			String r2 = scan.next();
			addRelation(findByName(r1), findByName(r2));
		}
		initialCount();
		// print();
		// check();
		print();
		int[] nn = new int[n]; // 存儲好友數量
		for (int i = 0; i < n; i++) {// n個用戶的好友數量
			String uname = scan.next();
			nn[i] = findByName(uname).getFriendCount();
		}
		int[] nN = new int[N];
		for (int i = 0; i < N; i++) {// 推斷這幾組是否好友
			String s1 = scan.next();
			String s2 = scan.next();

		}
		for (int i = 0; i < n; i++) {
			System.out.println(nn[i]);
		}
		for (int i = 0; i < N; i++) {
			System.out.println(nN[i]);
		}
	}

	/**
	 * 加入用戶
	 * 
	 * @param userinfo
	 */
	public void addUserinfo(Userinfo userinfo) {
		if (users == null) {
			users = new HashSet<Userinfo>();
		}
		users.add(userinfo);
	}

	/**
	 * 加入好友關系
	 * 
	 * @param userinfo
	 * @param userinfo2
	 */
	public void addRelation(Userinfo userinfo, Userinfo userinfo2) {
		userinfo.addFriend(new Friend(userinfo2));
		userinfo2.addFriend(new Friend(userinfo));
	}

	/**
	 * 獲取兩個用戶之間公共好友數目
	 * 
	 * @param userinfo
	 * @param userinfo2
	 * @return
	 */
	public int getCommonCount(Userinfo userinfo, Userinfo userinfo2) {
		int count = 0;
		Set<Friend> friends = userinfo.getFriends();
		Set<Friend> friends2 = userinfo2.getFriends();
		//System.out.println(friends2+"\n"+friends);
		//System.out.println("-----------------------------------------------");
		if (friends != null && friends != null)
			for (Friend friend : friends) {
				// System.out.println(userinfo2.getUname()+"的好友們"+friends2+"包括"+friend+":"+friends2.contains(friend));
				if (friends2.contains(friend)) {
					count++;
				}
			}
		return count;
	}

	/**
	 * 初始化好友之間的公共好友數目
	 */
	public void initialCount() {
		List<Userinfo> list = new ArrayList<Userinfo>();
		for (Userinfo userinfo : users) {
			list.add(userinfo);
		}
		int countP = 1;
		while (countP != 0) {//僅僅要在循環裏面加入了關系都要又一次從頭更新一遍
			countP = 0;
			for (int i = 0; i < list.size() - 1; i++) {
				for (int j = i + 1; j < list.size(); j++) {
					Userinfo userinfo = list.get(i);
					Userinfo userinfo2 = list.get(j);
					int commonCount = getCommonCount(userinfo, userinfo2);
					//System.out.println(userinfo2.getUname() + ","
					//		+ userinfo.getUname() + "公共好友:" + commonCount);

					if (commonCount >= P) {
						if (isFriend(userinfo, userinfo2) != 0) {// 不是朋友的時候
							addRelation(userinfo, userinfo2);
							countP++;
						}
					}
				}
			}
			

		}

	}

	/**
	 * 依據username獲取用戶
	 * 
	 * @param uname
	 * @return
	 */
	public Userinfo findByName(String uname) {
		for (Userinfo userinfo : users) {
			if (userinfo.getUname().equals(uname)) {
				return userinfo;
			}
		}
		return null;
	}

	/**
	 * 推斷兩用戶是否好友
	 * 
	 * @param u1
	 * @param u2
	 * @return
	 */
	public int isFriend(String u1, String u2) {
		return isFriend(findByName(u1), findByName(u2));
	}

	/**
	 * 推斷兩用戶是否好友
	 * 
	 * @param userinfo
	 * @param userinfo2
	 * @return
	 */
	public int isFriend(Userinfo userinfo, Userinfo userinfo2) {
		return userinfo.isFriend(userinfo2);
	}

	public void print() {
		for (Userinfo userinfo : users) {
			System.out.println(userinfo);
		}
	}

	public Set<Userinfo> getUsers() {
		return users;
	}

	public void setUsers(Set<Userinfo> users) {
		this.users = users;
	}

}

class Userinfo { // 用戶,相當於節點
	private String uname; // username
	private Set<Friend> friends; // 鄰接點們

	public Userinfo(String uname) {
		super();
		this.uname = uname;
		friends = null;
	}

	/**
	 * 加入好友
	 * 
	 * @param friend
	 */
	public void addFriend(Friend friend) {
		if (friends == null) {
			friends = new HashSet<Friend>();
		}
		friends.add(friend);
	}

	/**
	 * 獲取好友數量
	 * 
	 * @return
	 */
	public int getFriendCount() {
		if (this.friends != null)
			return this.friends.size();
		return -1;
	}

	/**
	 * 當前用戶與userinfo是否為好友
	 * 
	 * @param userinfo
	 * @return
	 */
	public int isFriend(Userinfo userinfo) {
		for (Friend friend : friends) {
			if (friend.getUserinfo().equals(userinfo)) {
				return 0;
			}
		}
		return -1;
	}

	public Set<Friend> getFriends() {
		return friends;
	}

	public void setFriends(Set<Friend> friends) {
		this.friends = friends;
	}

	public String getUname() {
		return uname;
	}

	public void setUname(String uname) {
		this.uname = uname;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Userinfo))
			return false;
		Userinfo user = (Userinfo) obj;
		if (!user.getUname().equals(this.uname))
			return false;
		return true;
	}

	@Override
	public int hashCode() {
		int length = this.uname.length();
		for (int i = 0; i < this.uname.length(); i++) {
			char ch = this.uname.charAt(i);
			length = length + i * (int) ch;
		}
		return length;
	}

	@Override
	public String toString() {
		return "Userinfo [" + uname + ", " + friends + "]";
	}

}

class Friend {
	private Userinfo userinfo; // 與userinfo的關系
	private int count; // 公共好友個數

	public Friend(Userinfo u2) {
		this.userinfo = u2;
		this.count = 0;
	}

	public Userinfo getUserinfo() {
		return userinfo;
	}

	public void setUserinfo(Userinfo userinfo) {
		this.userinfo = userinfo;
	}

	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((userinfo == null) ?

0 : userinfo.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; Friend other = (Friend) obj; if (!userinfo.equals(other.userinfo)) return false; return true; } @Override public String toString() { return "Friend [" + userinfo.getUname() + ", " + count + "]"; } }

我的測試用比例如以下:
3 7 10 7 10
Andy
Coco
Bill
Dance
Ella
Feifei
Grace
Andy Coco
Andy Dance
Andy Ella
Bill Dance
Bill Ella
Feifei Coco
Feifei Dance
Feifei Ella
Grace Dance
Grace Ella
Andy Bill Coco Dance Ella Feifei Grace
Andy Feifei
Dance Ella
Andy Ella
Andy Grace
Bill Feifei
Bill Grace
Bill Coco
Grace Coco
Dance Ella
Andy Dance

輸出結果例如以下:

4
2
2
5
5
4
2
0
0
0
0
0
0
0
0
0
0

華為練習題--社交好友推斷