华为练习题--社交好友推断

Posted jhcelue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了华为练习题--社交好友推断相关的知识,希望对你有一定的参考价值。

好友关系管理
描写叙述:

现有一个社交站点,其好友推荐策略为:用户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

以上是关于华为练习题--社交好友推断的主要内容,如果未能解决你的问题,请参考以下文章

社交网站如何计算好友更新?

社交网站的好友表

用图技术搞定附近好友时空交集等 7 个典型社交网络应用

WWW2021基于图神经网络的社交好友排序

图的表示:如何存储微博、微信等社交网络中的好友关系?

社交网络好友列表、朋友圈、帖子分享的数据库设计[关闭]