Java到JavaScript类型转换算法

Java到JavaScript类型转换算法,javascript,java,algorithm,graph,Javascript,Java,Algorithm,Graph,我想将以下函数翻译成JS(我还是JS新手,所以有一些困难): 它获取N个节点的完整图,并枚举所有唯一的对匹配 /** * * @param nodes The nodes still to be added to our edge list. * @param edges The current edge list. This is mutated, so always return a clone! */ public static <N> List<Map<N,N&g

我想将以下函数翻译成JS(我还是JS新手,所以有一些困难):

它获取N个节点的完整图,并枚举所有唯一的对匹配

/**
*
* @param nodes The nodes still to be added to our edge list.
* @param edges The current edge list. This is mutated, so always return a clone!
*/
public static <N> List<Map<N,N>> enumerateEdges(List<N> nodes,Map<N,N> edges){
  if(nodes.isEmpty()) // No more nodes to create edges from, so return our current edge list in a new list.
    return Collections.singletonList(new HashMap<>(edges));


  N start = nodes.get(0); //The start node of our next pair.

  List<Map<N,N>> acc = new LinkedList<>(); //The accumulation of the EdgeLists

  for(int i = 1; i<nodes.size(); ++i){
    N end = nodes.get(i); //The end node of our pair
    edges.put(start,end); //Add this pair to our edge list

    List<N> unused = new ArrayList<>(nodes); // The nodes not used in our edge list.
    unused.remove(i);
    unused.remove(0);

    acc.addAll(enumerateEdges(unused,edges));

    edges.remove(start); //Remove this pair from our edge list.
  }

  return acc;
}
将其称为:

let nodes = [1,2,3,4];
let edges = [];
enumerateEdges(nodes, edges);
有人有什么想法吗?非常感谢。

主要问题是:

  • 递归的结束点(当
    nodes.length==0
    时)不应返回空数组,而应返回边数组的副本
  • edges=[{start,end}]
    完全覆盖
    edges
    之前的内容。您需要
    将这一对推到它上面。此外
  • edges.splice(0,1)
    删除第一个元素,但在原始代码中,它必须删除由start键控的元素,而start实际上是edges列表中的最后一个元素
请注意,JavaScript有一个
映射
构造函数,您可以将其用于
边缘
,因此它与Java代码的工作方式非常相似。但在这种情况下,我发现它的用途有些过分:数组可以正常工作。我在第二个代码段中添加了使用Map的版本

Edit:我还建议将条件
length==0
更改为
length<2
,这样在传递奇数个节点时不会出现问题

函数枚举边(节点、边){
if(nodes.length<2)返回[…边];//返回副本
让开始=节点[0];
设acc=[];
for(设i=1;i
.as控制台包装{max height:100%!important;top:0;}
主要问题是:

  • 递归的结束点(当
    nodes.length==0
    时)不应返回空数组,而应返回边数组的副本
  • edges=[{start,end}]
    完全覆盖
    edges
    之前的内容。您需要
    将这一对推到它上面。此外
  • edges.splice(0,1)
    删除第一个元素,但在原始代码中,它必须删除由start键控的元素,而start实际上是edges列表中的最后一个元素
请注意,JavaScript有一个
映射
构造函数,您可以将其用于
边缘
,因此它与Java代码的工作方式非常相似。但在这种情况下,我发现它的用途有些过分:数组可以正常工作。我在第二个代码段中添加了使用Map的版本

Edit:我还建议将条件
length==0
更改为
length<2
,这样在传递奇数个节点时不会出现问题

函数枚举边(节点、边){
if(nodes.length<2)返回[…边];//返回副本
让开始=节点[0];
设acc=[];
for(设i=1;i

.as控制台包装{max height:100%!important;top:0;}
.splice()
不能替代
.remove()
,因为它不修改数组;它返回一个新数组。感谢你的提示,但我注意到,
acc.push.apply(acc,Enumeratedges(unused,edges))
实际上并没有将边推到
acc
@Pointy,
splice
会像
remove
那样对数组进行变异。@cyberkronos,
push.apply
有效,但是函数结果总是一个空数组,因为这是您在第一个
if
语句中返回的(错误)。@trincot oops您是对的;我在考虑
.slice()
:)一个小“p”。
.splice()
不能代替
。remove()
,因为它不会修改数组;它返回一个新数组。感谢你的提示,但我注意到,
acc.push.apply(acc,Enumeratedges(unused,edges))
实际上并没有将边推到
acc
@Pointy,
splice
会像
remove
那样对数组进行变异。@cyberkronos,
push.apply
有效,但是函数结果总是一个空数组,因为这是您在第一个
if
语句中返回的(错误)。@trincot oops您是对的;我在想
.slice()
:)一个小“p”。谢谢你的详细解释!帮助很大。我有一个后续问题。这是否可以扩展到100个节点而不是4个节点。你可以使用映射函数吗?我添加了一个使用映射的代码段。我认为这对缩放没有多大关系。我还调整了
length==0
的测试,这在图的节点数为奇数时会有问题。然而,我确实感到奇怪:输出将所有找到的边放在一个平面阵列中,而不按配置对它们进行分组。从我对Java代码的理解来看,Java版本也是如此(
addAll
)。您可能需要更改。谢谢您的详细解释!帮助
function enumerateEdges(nodes, edges) {
  if (nodes.length == 0) return [];

  let start = nodes[0];

  let acc = [];

  for(let i = 1; i < nodes.length; i++) {
    let end = nodes[i];

    edges = [ {start,end} ];

    let unused = nodes.slice(0);
    unused.splice(i,1);
    unused.splice(0,1);

    acc.push.apply(acc, enumerateEdges(unused,edges));

    edges.splice(0, 1);
  }
  return acc;
}
let nodes = [1,2,3,4];
let edges = [];
enumerateEdges(nodes, edges);