简体   繁体   English

列出两个给定好友之间的所有好友链接

[英]List all link of friends between two given Friends

It is said that all people on average are six, or fewer, social connections away from each other.据说所有人之间的社交联系平均只有六个或更少。 Create an app that helps you find the degree of separation between any two people.创建一个应用程序,帮助您找到任何两个人之间的分离程度。 Think of it as selecting two users on Facebook and trying to see how these two people are connected.把它想象成在 Facebook 上选择两个用户并试图了解这两个人是如何联系在一起的。

If you select any two people, you should be able to see the degrees of separation between them.如果您选择任意两个人,您应该能够看到他们之间的分离程度。 For example, if you have the following relationships added into your system...例如,如果您将以下关系添加到您的系统中...

  • Sameer is a Friend of Aayushi Sameer 是 Aayushi 的朋友
  • Aayushi is a Friend of Bhaskar Aayushi 是 Bhaskar 的朋友
  • Sameer is a Friend of Kamalnath Sharma Sameer 是 Kamalnath Sharma 的朋友
  • Kamalnath Sharma is a Friend of Shanti Kumar Saha Kamalnath Sharma 是 Shanti Kumar Saha 的朋友
  • Shanti Kumar Saha is a Friend of Bhaskar Shanti Kumar Saha 是 Bhaskar 的朋友

If you select two people, let's say Sameer and Bhaskar, the application should show the degree of separation as follows.如果您选择两个人,比如 Sameer 和 Bhaskar,应用程序应显示如下分离程度。

  • Sameer > Aayushi > Bhaskar Sameer > Aayushi > Bhaskar
  • Sameet > Kamalnath Sharma > Shanti Kumar Saha > Bhaskar Sameet > Kamalnath Sharma > Shanti Kumar Saha > Bhaskar

I have to implement this logic in Node.js application!我必须在 Node.js 应用程序中实现这个逻辑! I tried different methods using graph linklist but can't find the solution to implement this.我使用图形链接列表尝试了不同的方法,但找不到实现这一点的解决方案。

I used recursion I tried DFS but I was not able to implement it我使用了递归我尝试了 DFS 但我无法实现它

  var ok = true;
  while(ok){
  for(var i in Data){
   if(Data[i].name == value1){
       for(var j in Data[i].friends){
            if(Data[i].friends[j] == value2){
               path.push(Data[i].friends[j])
               ok = false;
               }else{
                        find(Data[i].friends[j],value2,path)
                    }
                }
            }
        }
        }
    }

Reading the answer you posted (in the future you could probably just edit your post), you pretty much got it.阅读您发布的答案(将来您可能只是编辑您的帖子),您几乎明白了。 You could make the DFS more efficient by preprocessing your JSON into an adjacency list Graph, and you could avoid infinite loops by keeping track of which friends you've visited before (so you don't visit them multiple times and loop around infinitely).您可以通过将您的 JSON 预处理为邻接列表图来提高 DFS 的效率,并且您可以通过跟踪您之前访问过哪些朋友来避免无限循环(这样您就不会多次访问他们并无限循环)。

An adjacency list Graph is just a representation of a Graph where you store in an object a list of vertices as keys, and a list of all other vertices they're adjacent (connected) to as the values.邻接列表 Graph 只是 Graph 的一种表示,其中您将顶点列表作为键存储在对象中,并将它们相邻(连接)到的所有其他顶点的列表作为值存储。 For example, the Graph would have the key "sameer" mapped to the list ["aayushi", "kamalnath"] .例如,图表会将键"sameer"映射到列表["aayushi", "kamalnath"] This makes it so that every time you call find , you don't have to loop over all of Data to find value1 .这使得每次调用find ,您不必遍历所有Data来查找value1 You could just find the friends of value1 by doing Graph[value1] .您可以通过执行Graph[value1]找到value1的朋友。 (I renamed value1 to source and value2 to target along with a few other variable name changes in the code below for clarity). (为了清楚起见,我将value1重命名为source ,将value2重命名为target ,并在下面的代码中对其他一些变量名称进行了更改)。

As for avoiding loops, you can track friends you've already visited in a simple javascript Object (or set), initialized as empty and added to as you visit each new friend at the start of the recursive call, then just pass this Object down each recursive call.至于避免循环,您可以在一个简单的 javascript 对象(或集合)中跟踪您已经访问过的朋友,将其初始化为空并在递归调用开始时在您访问每个新朋友时添加,然后将此对象向下传递每次递归调用。 You check it at the start of each call to make sure you aren't entering into a loop.您在每次调用开始时检查它以确保您没有进入循环。 This isn't necessary for DFS/BFS searches you perform on trees (which are by definition acyclic Graphs), but it's needed for general Graphs which might have loops/cycles.这对于您在树(根据定义为非循环图)执行的 DFS/BFS 搜索不是必需的,但对于可能具有循环/循环的一般图是必需的。

One other minor thing is when you find your target value/friend, you have另一件小事是当你找到你的目标价值/朋友时,你有

if(Data[i].friends[j] == value2){
  path.push(Data[i].friends[j])
  break;
}

You're right not to recurse in this case, but you probably don't want to break if you want to be able to continue to search the other friends you're looping over for alternate paths (rather than just breaking and returning the first path you find).在这种情况下不递归是对的,但是如果您希望能够继续搜索正在循环的其他朋友以寻找替代路径(而不仅仅是中断并返回第一个),您可能不想中断你找到的路径)。

Also, I'm not sure if this is intentional, but in the example data it looks like friendships are one-way (eg shanti is a friend of bhaskar, but bhaskar has no listed friends).另外,我不确定这是否是故意的,但在示例数据中,友谊似乎是单向的(例如 shanti 是 bhaskar 的朋友,但 bhaskar 没有列出朋友)。 If they're meant to be 2 way you would probably change how you preprocess the connections list into a Graph slightly.如果它们是 2 种方式,您可能会稍微更改将连接列表预处理为 Graph 的方式。 Anyways, here is code with all the changes I mentioned.无论如何,这是我提到的所有更改的代码。 If it's not clear let me know:如果不清楚,请告诉我:

 // preprocess a JSON list of connections to an adjacency list Graph function connectionsListToGraph(connections) { const Graph = {} for (let { name, friends } of connections) { Graph[name] = friends // allow fast lookup of a given person's friends } return Graph } // return the list of connections between source and target function getConnections(source, target, connections) { const Graph = connectionsListToGraph(connections) const connectionPaths = [] function findConnectionsDFS(source, target, path = [source], visited = {}) { // Don't search/visit the same friend twice (to avoid infinite loops) if (visited[source]) return; // mark that we've searched the current source friend visited[source] = true; for (let friend of Graph[source]) { if (friend === target) { connectionPaths.push(path.concat(target)); } else { findConnectionsDFS(friend, target, path.concat(friend), visited) } } } findConnectionsDFS(source, target); return connectionPaths; } let connections = [ { "name": "sameer", "friends": ["aayushi", "kamalnath"] }, { "name": "aayushi", "friends": ["bhaskar"] }, { "name": "kamalnath", "friends": ["shanti"] }, { "name": "shanti", "friends": ["bhaskar"] } ] console.log('Sameer to Bhaskar:', getConnections('sameer', 'bhaskar', connections)) console.log('Kamalnath to Bhaskar:', getConnections('kamalnath', 'bhaskar', connections))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM