好友关系管理 | |
描述: | 现有一个社交网站,其好友推荐策略为:用户A和用户B不是好友,当二人的共同好友数量超过好友推荐阈值m时,就向A和B分别推荐为彼此好友。 本题任务为:对设定的m值,给定一组用户及各自好友列表,对这一组用户,反复自动应用上述好友推荐策略后(假设每次推荐都被采纳),求指定用户的最终好友列表。 注:好友关系是双向的,即:如果用户A是用户B的好友,那么用户B一定也是用户A的好友。
写一个程序,在社交网络中实现: 1)初始化社交网络 2)创建用户 3)增加指定两个用户之间的好友关系 4)反复自动应用好友推荐策略后,获取某个用户的好友数量 5)反复自动应用好友推荐策略后,判断某两个用户间是否存在好友关系
说明: 1、一个用户有且只有一个名字,且不存在重名 2、自己和自己不存在好友关系 3、用户名字大小写敏感 4、用户名字字符串长度范围为[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 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();
}
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 friends = userinfo.getFriends();
Set 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 list = new ArrayList();
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++;
}
}
}
}
}
}
/**
* 根据用户名获取用户
*
* @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 getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
}
class Userinfo { // 用户,相当于节点
private String uname; // 用户名
private Set friends; // 邻接点们
public Userinfo(String uname) {
super();
this.uname = uname;
friends = null;
}
/**
* 添加好友
*
* @param friend
*/
public void addFriend(Friend friend) {
if (friends == null) {
friends = new HashSet();
}
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 getFriends() {
return friends;
}
public void setFriends(Set 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 + "]";
}
}
我的测试用例如下:
输出结果如下:
4
2
2
5
5
4
2
0
0
0
0
0
0
0
0
0
0