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

好友关系管理
描写叙述:
现有一个社交站点,其好友推荐策略为:用户A和用户B不是好友,当二人的共同好友数量超过好友推荐阈值m时,就向A和B分别推荐为彼此好友。

本题任务为:对设定的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

时间: 2024-10-12 04:56:11

华为练习题--社交好友推断的相关文章

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

好友关系管理 描述: 现有一个社交网站,其好友推荐策略为:用户A和用户B不是好友,当二人的共同好友数量超过好友推荐阈值m时,就向A和B分别推荐为彼此好友. 本题任务为:对设定的m值,给定一组用户及各自好友列表,对这一组用户,反复自动应用上述好友推荐策略后(假设每次推荐都被采纳),求指定用户的最终好友列表. 注:好友关系是双向的,即:如果用户A是用户B的好友,那么用户B一定也是用户A的好友. 写一个程序,在社交网络中实现: 1)初始化社交网络 2)创建用户 3)增加指定两个用户之间的好友关系 4)

【华为练习题】 最后一个单词的长度(初级)

[华为练习题] 最后一个单词的长度(初级) 题目 描述: 计算字符串最后一个单词的长度,单词以空格隔开. 题目类别: 字符串 输入: 一行字符串,长度小于128. 输出: 整数N,最后一个单词的长度. 样例输入: hello world 样例输出: 5 解答 #include <iostream> #include <string> using namespace std; int last_word_length(const string &s){ auto begin

【华为练习题】字符出现频率

[华为练习题]字符出现频率 题目 描述:写出一个程序,输出基准字符串中统计指定字符出现的频率 字符串仅包括英文大小写字母和空格.逗号.点号 小数点后保留2位有效数字,第三位四舍五入 举例: 输入:wo shi, yi zhi.xiao xiao niao ' '(空格) 输出:0.17 接口说明: /* 功能: 输入的基准字符串中统计指定字符出现的频率 字符串仅包括英文大小写字母和空格.逗号.点号 小数点后保留2位有效数字,第三位四舍五入 输入: String pString 输入的基准字符串

【华为练习题】乒乓球赛制

[华为练习题]乒乓球赛制 题目 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中11分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役.华华就是其中一位,他退役之后走上了乒乓球研究工作,意图弄明白11分制和21分制对选手的不同影响.在开展他的研究之前,他首先需要对他多年比赛的统计数据进行一些分析,所以需要你的帮忙. 华华通过以下方式进行分析,首先将比赛每个球的胜负列成一张表,然后分别计算在11分制和21分制下,双方的比赛结果(截至记录

【华为练习题】 爱因斯坦阶梯(初级)

[华为练习题] 爱因斯坦阶梯(初级) 题目 述: 爱因斯坦出了一道这样的数学题:有一条长阶梯,若每步跨2阶,则最最后剩一阶,若每步跨3 阶,则最后剩2阶,若每步跨5阶,则最后剩4阶,若每步跨6阶则最后剩5阶.只有每次跨7阶,最后才正好一阶不剩.请问这条阶梯共有多少阶? 分析 一个数满足除以2余1,除以3余2,除以5余4,除以6余5,那么这个数为2,3,5,6的最小公倍数减一. 解答 直接解法 #include "stdafx.h" #include <iostream> u

【华为练习题】 阿姆斯特朗数(初级)

[华为练习题] 阿姆斯特朗数(初级) 题目 如果一个正整数等于其各个数字的立方和,则该数称为阿姆斯特朗数(亦称为自恋性数),1除外,如407 = 4^3+0^3+7^3就是一个阿姆斯特朗数.试编程求n(n ≤ 65536)以内的所有阿姆斯特朗数. 原型: int CalcArmstrongNumber(int n); 输入参数: int n: n ≤ 65536 返回值: n以内的阿姆斯特朗数的数量 解答 #include <iostream> using namespace std; boo

【华为练习题】判断点是否在三角形中

[华为练习题]判断点是否在三角形中 题目 一个二维坐标系中(100*100,每一维0~99),已知三角形三个顶点的坐标A.B.C,判断坐标系中的任意点:P,是否在三角形内(在三角形边上也认为在三角形内) 请实现如下接口 /* 功能:点是否在三角形内 输入:三角形三顶点坐标:A.B.C,以及待确认的点:P 输出:无 返回:在三角形内返回true,否则返回false */ public static boolean isInTriangle(POINTA, POINTB, POINTC, POINT

【华为练习题】 求最大凸多边形(高级)

[华为练习题] 求最大凸多边形(高级) 题目 题目描述: 给定一些点,输出最大面积的凸边形.输出起始点为x轴最左边的点,按照顺时针方向输出,每个点必须是凸边形的顶点(不输出边上或凸边形内的点).输入第一个数n为坐标点个数,后面依次为n个坐标点的坐标,横坐标在前,不同坐标点用':'隔开,相同坐标点的横纵坐标用','隔开. 输入样例: 13;-4,1;-2,3;1,3;2,2;1,4;5,4;6,1;2,-4;-3,-3;1,-1;-2,-2;1,-2;-1,-1 输出样例: -4,1;-2,3;1

【华为练习题】用两个栈来模拟队列(中级)

[华为练习题]用两个栈来模拟队列(中级) 题目 栈的特点是后进先出,队列的特点是先进先出.所以,用两个栈S1和S2模拟一个队列时, 要求两个栈S1和S2的长度都是5. 要求实现以下函数: enQueue 将元素value插入队列,若入队列成功返回true,否则返回false deQueue 从队列中取出一个元素放入value,若出队列成功返回true,否则返回false. isEmptyQueue 判用队列是否为空,如果是空则返回true,如果不是空则返回false. 分析 S1作输入栈,逐个元