Java 和 JavaScript 中的逻辑相似,但 DFS 的结果不同
Similar logic in Java and JavaScript, but different results for DFS
我正在尝试解决 java脚本中的 DFS 问题,问题是确定给定的图形是否具有给定源和目标之间的路径。
这是java
中的解决方案
import java.io.*;
import java.util.*;
public class Main {
static class Edge {
int src;
int nbr;
int wt;
Edge(int src, int nbr, int wt){
this.src = src;
this.nbr = nbr;
this.wt = wt;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int vtces = Integer.parseInt(br.readLine());
ArrayList<Edge>[] graph = new ArrayList[vtces];
for(int i = 0; i < vtces; i++){
graph[i] = new ArrayList<>();
}
int edges = Integer.parseInt(br.readLine());
for(int i = 0; i < edges; i++){
String[] parts = br.readLine().split(" ");
int v1 = Integer.parseInt(parts[0]);
int v2 = Integer.parseInt(parts[1]);
int wt = Integer.parseInt(parts[2]);
graph[v1].add(new Edge(v1, v2, wt));
graph[v2].add(new Edge(v2, v1, wt));
}
int src = Integer.parseInt(br.readLine());
int dest = Integer.parseInt(br.readLine());
boolean visited[] = new boolean[vtces];
boolean ans = hasPath(graph , src, dest,visited);
System.out.println(ans);
}
static boolean hasPath( ArrayList<Edge> graph[] ,int src,int dest, boolean[] visited){
if(src == dest){
return true;
}
visited[src] = true;
for(Edge edge : graph[src]){
if( visited[edge.nbr] ){
continue;
}
boolean nbrHasPath = hasPath(graph, edge.nbr, dest, visited);
if(nbrHasPath){
return true;
}
}
return false;
}
}
这是 JavaScript 解决方案
'use strict';
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', (inputStdin) => {
inputString += inputStdin;
});
process.stdin.on('end', (_) => {
inputString = inputString
.trim()
.split('\n')
.map((string) => {
return string.trim();
});
main();
});
function readline() {
return inputString[currentLine++];
}
function readIntArray() {
return readline()
.split(' ')
.map((num) => parseInt(num));
}
function readFloatArray() {
return readline()
.split(' ')
.map((num) => parseFloat(num));
}
/*=====================START CODING HERE=====================*/
class Edge {
constructor(source, neighbour, weight){
this.source = source
this.neighbour = neighbour
this.weight = weight
}
}
function main() {
const vertices = parseInt(readline());
const edges = parseInt(readline());
const graph = new Array(vertices).fill([])
for(let i = 0 ; i < edges; i++){
let [s, d, w] = readIntArray()
graph[s].push(new Edge(s,d,w))
graph[d].push(new Edge(d,s,w))
}
const source = parseInt(readline());
const destination = parseInt(readline());
let visited = new Array(vertices).fill(false)
console.log(hasPath( graph, source, destination,visited ))
}
function hasPath(graph, source, dest, visited){
if(source === dest){
return true
}
visited[source] = true
for(let i = 0; i < graph[source].length; i++){
let edge = graph[source][i]
if( visited[edge.neighbour] ){
continue;
}
let nbrHasPath = hasPath(graph, edge.neighbour, dest , visited)
if(nbrHasPath){
return true
}
}
return false
}
函数 haspath
是这里的兴趣点,java 解决方案通过了所有测试用例,但是 javascript 解决方案在一个测试用例中失败了:
7
7
0 1 10
1 2 10
2 3 10
0 3 10
4 5 10
5 6 10
4 6 10
0
6
函数需要return一个boolean值,对于上述测试用例,java方案returns false
而js方案returns true
我无法弄清楚我在 JavaScript 中做错了什么,感谢您的帮助。
这一行有一个细微的错误:
const graph = new Array(vertices).fill([]);
这只创建了两个数组。 new Array(vertices)
创建第一个新数组,然后 .fill([])
创建第二个并 用对第二个的引用填充第一个 。
所以 graph
中的每个数组实际上都是同一个数组。试试 运行 这个代码看看:
const graph = new Array(5).fill([]);
graph[0].push('hello');
console.log(graph[0][0]); // prints "hello";
console.log(graph[1][0]); // also prints "hello";
console.log(graph[2][0]); // also prints "hello";
console.log(graph[3][0]); // also prints "hello";
console.log(graph[4][0]); // also prints "hello";
你可以这样做来解决这个问题:
const graph = new Array(vertices).fill().map(() => []);
可能还有其他问题,但这正是我突然想到的。
我正在尝试解决 java脚本中的 DFS 问题,问题是确定给定的图形是否具有给定源和目标之间的路径。
这是java
中的解决方案import java.io.*;
import java.util.*;
public class Main {
static class Edge {
int src;
int nbr;
int wt;
Edge(int src, int nbr, int wt){
this.src = src;
this.nbr = nbr;
this.wt = wt;
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int vtces = Integer.parseInt(br.readLine());
ArrayList<Edge>[] graph = new ArrayList[vtces];
for(int i = 0; i < vtces; i++){
graph[i] = new ArrayList<>();
}
int edges = Integer.parseInt(br.readLine());
for(int i = 0; i < edges; i++){
String[] parts = br.readLine().split(" ");
int v1 = Integer.parseInt(parts[0]);
int v2 = Integer.parseInt(parts[1]);
int wt = Integer.parseInt(parts[2]);
graph[v1].add(new Edge(v1, v2, wt));
graph[v2].add(new Edge(v2, v1, wt));
}
int src = Integer.parseInt(br.readLine());
int dest = Integer.parseInt(br.readLine());
boolean visited[] = new boolean[vtces];
boolean ans = hasPath(graph , src, dest,visited);
System.out.println(ans);
}
static boolean hasPath( ArrayList<Edge> graph[] ,int src,int dest, boolean[] visited){
if(src == dest){
return true;
}
visited[src] = true;
for(Edge edge : graph[src]){
if( visited[edge.nbr] ){
continue;
}
boolean nbrHasPath = hasPath(graph, edge.nbr, dest, visited);
if(nbrHasPath){
return true;
}
}
return false;
}
}
这是 JavaScript 解决方案
'use strict';
process.stdin.resume();
process.stdin.setEncoding('utf-8');
let inputString = '';
let currentLine = 0;
process.stdin.on('data', (inputStdin) => {
inputString += inputStdin;
});
process.stdin.on('end', (_) => {
inputString = inputString
.trim()
.split('\n')
.map((string) => {
return string.trim();
});
main();
});
function readline() {
return inputString[currentLine++];
}
function readIntArray() {
return readline()
.split(' ')
.map((num) => parseInt(num));
}
function readFloatArray() {
return readline()
.split(' ')
.map((num) => parseFloat(num));
}
/*=====================START CODING HERE=====================*/
class Edge {
constructor(source, neighbour, weight){
this.source = source
this.neighbour = neighbour
this.weight = weight
}
}
function main() {
const vertices = parseInt(readline());
const edges = parseInt(readline());
const graph = new Array(vertices).fill([])
for(let i = 0 ; i < edges; i++){
let [s, d, w] = readIntArray()
graph[s].push(new Edge(s,d,w))
graph[d].push(new Edge(d,s,w))
}
const source = parseInt(readline());
const destination = parseInt(readline());
let visited = new Array(vertices).fill(false)
console.log(hasPath( graph, source, destination,visited ))
}
function hasPath(graph, source, dest, visited){
if(source === dest){
return true
}
visited[source] = true
for(let i = 0; i < graph[source].length; i++){
let edge = graph[source][i]
if( visited[edge.neighbour] ){
continue;
}
let nbrHasPath = hasPath(graph, edge.neighbour, dest , visited)
if(nbrHasPath){
return true
}
}
return false
}
函数 haspath
是这里的兴趣点,java 解决方案通过了所有测试用例,但是 javascript 解决方案在一个测试用例中失败了:
7
7
0 1 10
1 2 10
2 3 10
0 3 10
4 5 10
5 6 10
4 6 10
0
6
函数需要return一个boolean值,对于上述测试用例,java方案returns false
而js方案returns true
我无法弄清楚我在 JavaScript 中做错了什么,感谢您的帮助。
这一行有一个细微的错误:
const graph = new Array(vertices).fill([]);
这只创建了两个数组。 new Array(vertices)
创建第一个新数组,然后 .fill([])
创建第二个并 用对第二个的引用填充第一个 。
所以 graph
中的每个数组实际上都是同一个数组。试试 运行 这个代码看看:
const graph = new Array(5).fill([]);
graph[0].push('hello');
console.log(graph[0][0]); // prints "hello";
console.log(graph[1][0]); // also prints "hello";
console.log(graph[2][0]); // also prints "hello";
console.log(graph[3][0]); // also prints "hello";
console.log(graph[4][0]); // also prints "hello";
你可以这样做来解决这个问题:
const graph = new Array(vertices).fill().map(() => []);
可能还有其他问题,但这正是我突然想到的。