【问题标题】:Find separation values from a starting node从起始节点查找分隔值
【发布时间】:2016-07-23 12:59:11
【问题描述】:

我在一些在线编码练习中发现,这个看起来很酷,我想试一试。

问题陈述

Quinn 是一个非常受欢迎且非常谦虚的人。其他学生在一个名为 QDist 的单元中衡量他们的受欢迎程度。

人们可以通过找出他们自己和 Quinn 之间的分离度来计算他们的 QDist 值。例如: 如果 Quinn 和 Dave 是朋友,Dave 和 Travis 是朋友,那么 Dave 的 QDist 值为 1,而 Travis 为 2。

输出

按姓名字母顺序输入的每个人的姓名 QDist。 如果一个人无论如何都没有连接到 Quinn,则输出 name uncool

给定一个友谊列表,按字母顺序列出每个人及其 QDist 值。

示例输入/输出

10
Alden Toshiko
Che Kortney
Che Dorian
Ronda Lindell
Sharon Alden 
Dorian Quinn
Owen Sydnee
Alden Che
Dorian Tyra
Quinn Ally

输出

Alden 3
Che 2
Dorian 1
Kortney 3
Lindell uncool
Ally 1
Owen uncool
Quinn 0
Ronda uncool
Sharon 4
Sydnee uncool
Toshiko 4
Tyra 2

我的方法

首先,我不想要答案,我只是想要一个提示或一些关于我应该如何在 javascript 中解决问题的指导(因为它是我最熟悉的语言)。我的想法是将程序分解为一个对象和数组,并尝试在每个名称之间创建一个家族关系,有点像嵌套对象或数组。然后我可以使用某种递归来找出数组或对象的深度。

最好的方法是什么?

【问题讨论】:

  • “最好的方法是什么?” - 尝试一些事情并提出更具体的问题应该会有所帮助。
  • 您还需要什么详细信息?我已经给出了我尝试过的方法,但似乎并不实用并且编码过于困难。我只是在征求一些想法。

标签: javascript


【解决方案1】:

您可以根据输入创建人员列表。它可以是一个对象,其中每个键是一个人的名字,对应的值是一个名字数组,代表那个人的朋友。当然你要确保当你将 B 添加为 A 的好友时,你也必须将 A 添加为 B 的好友。

对于示例输入,上述结构如下所示:

{
  "Alden": ["Toshiko","Sharon","Che"],
  "Toshiko": ["Alden"],
  "Che": ["Kortney","Dorian","Alden"],
  "Kortney": ["Che"],
  "Dorian": ["Che","Quinn","Tyra"],
  "Ronda": ["Lindell"],
  "Lindell": ["Ronda"],
  "Sharon": ["Alden"],
  "Quinn": ["Dorian","Ally"],
  "Owen": ["Sydnee"],
  "Sydnee": ["Owen"],
  "Tyra": ["Dorian"],
  "Ally": ["Quinn"]
}

然后跟踪一个名字列表,从 Quinn 开始,还有一个距离,从 0 开始。

然后对于该列表中的每个名称,将当前距离指定为其 QDist 值。然后找到他们的朋友并将他们放在一起。删除已经收到 QDist 值的名称。

然后增加距离,并为新的名称列表重复上述操作。

不断重复,直到名称列表为空。

请注意,如果您按正确的顺序做事,您可以用 QDist 值替换好友列表。所以上面的结构在前两次迭代后会变成:

{
  "Alden": ["Toshiko","Sharon","Che"],
  "Toshiko": ["Alden"],
  "Che": ["Kortney","Dorian","Alden"],
  "Kortney": ["Che"],
  "Dorian": 1,
  "Ronda": ["Lindell"],
  "Lindell": ["Ronda"],
  "Sharon": ["Alden"],
  "Quinn": 0,
  "Owen": ["Sydnee"],
  "Sydnee": ["Owen"],
  "Tyra": ["Dorian"],
  "Ally": 1
}

算法完成后,您有:

{
  "Alden": 3,
  "Toshiko": 4,
  "Che": 2,
  "Kortney": 3,
  "Dorian": 1,
  "Ronda": ["Lindell"],
  "Lindell": ["Ronda"],
  "Sharon": 4,
  "Quinn": 0,
  "Owen": ["Sydnee"],
  "Sydnee": ["Owen"],
  "Tyra": 2,
  "Ally": 1
}

现在剩下的friends数组需要替换为“uncool”,因为显然对应的人与Quinn没有关系。列表也需要排序。

剧透警告!

这是一个有效的 sn-p:

// Get input as text
var input = `10
Alden Toshiko
Che Kortney
Che Dorian
Ronda Lindell
Sharon Alden 
Dorian Quinn
Owen Sydnee
Alden Che
Dorian Tyra
Quinn Ally`;

// Build persons list with friends list
var persons = 
    // Take the input string
    input
    // Split it by any white-space to get array of words
    .split(/\s+/)
    // Skip the word at position 0: we don't need the line count
    .slice(1)
    // Loop over that array and build an object from it 
    .reduce(
        // Arguments: obj = result from previous iteration
        //            name = current name in names array
        //            i = index in that array
        //            names = the whole array being looped over
        (obj, name, i, names) => (
               // Get the list of friends we already collected for this name.
               // Create it as an empty array if not yet present.
               obj[name] = (obj[name] || [])
               // Add to that list the previous/next name, depending
               // whether we are at an odd or even position in the names array
               .concat([names[i%2 ? i-1 : i+1]])
               // Use the updated object as return value for this iteration
               , obj)
        // Start the above loop with an empty object
        , {});

// Now we have a nice object structure: 
//    { [name1]: [friendName1,friendName2,...], [name2]: ... }
// Start with Quinn as the only person we currently look at.
var friends = ['Quinn'];
// Increment the distance for each "generation" of friends 
// until there are none left.
for (var i = 0; friends.length; i++) {
    // Replace the friends list with a new list, 
    // while giving the friends in the current list a distance
    friends = 
        // Start with the current list of friends
        friends
        // Loop over these friends. 
        // Only keep those that still have a friends array (object) assigned to them,
        // since the others were already assigned a distance number.
        .filter(friend => typeof persons[friend] === "object")
        // Loop over those friends again, building a new list of friends
        .reduce((friends, friend, k) => [
                // Add this friends' friends to the new list
                friends.concat(persons[friend]),
                // ... and then replace this friends' friend list 
                // by the current distance we are at.
                persons[friend] = i
                // Return the first of the above two results (the new list)
                // for the next iteration.
                ][0]
            // Start with an empty array for the new friends list
            , []);
}

// Now we have for each person that connects to Quinn a number: 
//    { [name1]: number, ... }

// Convert this to a format suitable to output
var result = 
    // Get list of names from the object (they are the keys)
    Object.keys(persons)
    // Sort that list of names
    .sort()
    // Loop over these names to format them
    .map(name =>
        // Format as "name: distance" or "name: uncool" depending on whether there
        // still is an array of friends (object) in this entry
        name + ': ' + (typeof persons[name] == 'object' ? 'uncool' : persons[name]));

// Output the result in the console
console.log(result);

还有一个更冗长但更容易理解的版本:

// Get input as text
var input = `10
Alden Toshiko
Che Kortney
Che Dorian
Ronda Lindell
Sharon Alden 
Dorian Quinn
Owen Sydnee
Alden Che
Dorian Tyra
Quinn Ally`;

// Build persons list with friends list
// Take the input string
var persons = input;
// Split it by any white-space to get array of words
persons = persons.split(/\s+/)
// Skip the word at position 0: we don't need the line count
persons = persons.slice(1)
// Loop over that array and build an object from it 
var obj = {}; // Start loop with an empty object
for (var i = 0; i < persons.length; i++) {
    var name = persons[i]; // name = current name in names array
    // Get the list of friends we already collected for this name.
    // Create it as an empty array if not yet present.
    if (obj[name] === undefined) obj[name] = [];
    // Add to that list the previous/next name, depending
    // whether we are at an odd or even position in the names array
    obj[name].push(persons[i%2 === 1 ? i-1 : i+1]);
}
// Assign result to persons
persons = obj;
// Now we have a nice object structure: 
//    { [name1]: [friendName1,friendName2,...], [name2]: ... }
// Start with Quinn as the only person we currently look at.
var friends = ['Quinn'];
// Increment the distance for each "generation" of friends 
// until there are none left.
for (var i = 0; friends.length !== 0; i++) {
    // Loop over those friends, building a new list of friends
    // Start with an empty array for the new friends list
    var newFriends = [];
    for (var k = 0; k < friends.length; k++) {
        var friend = friends[k];
        // Only consider those that still have a friends array (object) assigned to them,
        // since the others were already assigned a distance number.
        if (typeof persons[friend] === "object") {
            // Add this friends' friends to the new list
            newFriends = newFriends.concat(persons[friend]);
            // ... and then replace this friends' friend list 
            // by the current distance we are at.
            persons[friend] = i;
        }
    };
    // Make the new list the current list:
    friends = newFriends;
}

// Now we have for each person that connects to Quinn a number: 
//    { [name1]: number, ... }

// Convert this to a format suitable to output
// Get list of names from the object (they are the keys)
var result = Object.keys(persons);
// Sort that list of names
result.sort();
// Loop over these names to format them
for (var i = 0; i < result.length; i++) {
    var name = result[i];
    // Format as "name: distance" or "name: uncool" depending on whether there
    // still is an array of friends (object) in this entry
    if (typeof persons[name] == 'object') {
        result[i] = name + ': uncool';
    } else {
        result[i] = name + ': ' + persons[name];
    }
}

// Output the result in the console
console.log(result);

【讨论】:

  • 我应该输入什么来了解 /\s+/?我以前见过类似的东西,人们操纵字符串,但我从来没有真正学会过。不过,我会尝试您的方法,然后查看您的解决方案。非常感谢
  • 我很难理解 var Persons 的过程我要写我认为它的作用,你能纠正我吗
  • /\s+/regular expression。我在 sn-p 中的代码中添加了许多 cmets,将每个语句分成几行:希望它可以帮助您了解代码的作用。
【解决方案2】:

如果我必须解决这个问题,

首先,我将创建一个数组,并通过查找行(元素)studentX ←→ Quinn 与 Quinn 为 1 的学生初始化它在原始数组中。

然后我会通过查找行 studentX ←→ student(n-1)FromQuinn 递归搜索与 quinn 级别为 n 的人/p>

【讨论】:

  • 嗯,是的,这可能是最好的选择。似乎非常具有挑战性。今天晚些时候我会试一试。
  • 一些使用java的解决方案使用hashmaps和一些数据结构。不幸的是我最近才开始学习java。不过我会试试你的方法
  • grr 在实现这一点时遇到了一些麻烦,我已经尝试了一段时间,您能否提供更多提示?
【解决方案3】:

我试图理解

var persons = input.split(/\s+/).slice(1).reduce(function(obj,name,i,names){
    return (obj[name] = (obj[name] || []).concat([names[i%2 ? i-1 : i+1]]), obj);

},{});

First input.split(/\s+/).slice(1) 给我们一个包含所有名字的数组。 现在

(obj[name] = (obj[name] || []).concat([names[i%2 ? i-1 : i+1]]), obj);

obj 根据reduce方法属性默认设置为由于{}

name 是当前值,基本上从Alden 一直到Allyi 将来自 1-10names 是数组

现在我们说设置obj[name] = obj[name].concat([names[i%2 ? i-1 : i+1]]),obj); 如果这是可能的。如果这不可能设置obj[name] = [].concat([names[i%2 ? i-1 : i+1]]),obj);。这是我阅读||

的解释

示例迭代

第一个obj = {},名称将是Alden 所以类型 Alden 即 persons = { Alden: ..} 将是 obj[Alden].concat(names[2],obj),它将是 2,因为没有达到 1 mod 2。

现在我有点困惑……,obj 到底在做什么……?我解释得对吗?

【讨论】:

  • 你解释得很好。 ( .... ,obj) 部分使用 comma operator:我有它,因为我需要将对象返回给 reduce 实现。代替逗号,我可以创建一个语句块,首先是{ obj[name] = ...;,然后是return obj; }。但我喜欢简短,所以我避免使用语句块,只执行( ....., obj),这是一个计算结果为obj 的表达式,同时仍执行... 部分。
  • 关于模数:索引从 0 开始。name[0]name[1] 作为朋友。然后在索引 1 处建立反向关系:name[1]name[0] 作为朋友。所以它继续。所以纠正你的说法:它是obj['Alden'].concat(names[1])。后面的,obj 部分不是concat 的参数,而是comma 运算符的下一个表达式。
  • 好的,当i = 0时,它去i+1,但是当i =1时,它不应该也去i+1,而不是去i-1吗?因为 1 不能被 2 整除
  • 是的,这是暗示的。 i%2 是 i 模 2,只能有两个结果:0 或 1。对于 JavaScript,0 是假的,1 是真的,所以不需要这样做 i%2===1,这在选择时会产生完全相同的效果要评估的部分。
  • 好的,我正在尝试。顺便说一句,我自己解决了这个问题,没有查看您的解决方案并得到了它!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多