Java到JavaScript类型转换算法
我想将以下函数翻译成JS(我还是JS新手,所以有一些困难): 它获取N个节点的完整图,并枚举所有唯一的对匹配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
/**
*
* @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
将这一对推到它上面。此外
删除第一个元素,但在原始代码中,它必须删除由start键控的元素,而start实际上是edges列表中的最后一个元素李>edges.splice(0,1)
映射
构造函数,您可以将其用于边缘
,因此它与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);