zoukankan      html  css  js  c++  java
  • 华为练习题--社交好友推断

    好友关系管理
    描写叙述:

    现有一个社交站点,其好友推荐策略为:用户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 刘利娟 liulijuan132@gmail.com
     * @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+"
    "+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

  • 相关阅读:
    Python之路【第十六篇】:冒泡排序、斐波那契数列、用户登陆程序
    Python之路【第十五篇】:文件操作
    Python之路【第十四篇】:Python的内置函数
    Python之路【第十三篇】:isinstance()函数与lambda表达式及函数参数的传递方式
    Python之路【第十二篇】:函数
    Python之路【第十一篇】:三目运算、不同数据类型的存储方式及深浅拷贝(copy模块)、列表推导式
    Python之路【第十篇】:索引与切片的不同
    Python之路【第九篇】:字符串与字节的相互转换以及2.7与3输出方式的不同
    Python之路【第八篇】:enumerate、range与xrange
    scala学习之类和对象
  • 原文地址:https://www.cnblogs.com/jhcelue/p/7223950.html
Copyright © 2011-2022 走看看