所以有几件事(缺乏问题根源)。
但是,这是您可以使用的一种方法。
在这里,地图用于存储边和顶点之间的关系。使用它,我们可以通过分组来构建顶点之间的关系。
为了方便使用,我们首先使用promise-based问题函数。这可以使用以下方法完成
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
// Convert question function from cb to promise.
const question = (query) =>
new Promise((resolve, _) => {
rl.question(query, (input) => resolve(input));
});
接下来,我们创建一个 main 函数来封装我们的逻辑。
async function main() {}
现在,让我们创建一个为我们提取维数的函数
async function getDimensions() {
// # of Vertices x # of Edges
return (await question("Matrix N and M: ")).split(" ").map(x => +x)
}
完成后,我们可以创建两个辅助函数。
第一个,它接受预期顶点的数量。
第二个,它采用最终的incidentMap和预期顶点的数量(所以我们不必计算它)。
async function createIncidenceMap(N) { }
async function convertToAdjacencyMatrix(incidenceMap, N) { }
要实现createIncidentMap,我们可以使用下面的
// Create an Incidence Map for Quick Look Up
async function createIncidenceMap(N) {
const incidentMatrix = [];
// Read in the relationships between edges (columns) and vertices (rows).
for (let i = 0; i < N; i++) {
const result = (
await question(`Row: ${i}, enter numbers separated by spaces: `)
)
.split(" ")
.map((x) => +x);
incidentMatrix.push(result);
}
// Group vertices by edges.
return incidentMatrix.reduce((incidentMap, incidentPair, M) => {
const incidentSubset = incidentPair.reduce(
(subsetMap, connected, N) => (
{
...subsetMap,
[N]: [
...(subsetMap[N]?.length ? subsetMap[N] : []),
...(connected ? [M] : []),
],
}
),
{}
);
// Join previous vertices connected to the same edge.
return Object.keys(incidentSubset).reduce((map, edge, index) => ({
...map,
[edge]: new Set([
...(incidentMap[edge] ?? []),
...incidentSubset[edge]
]).values(),
}), {});
}, {});
};
这将减少 convertToAdjacencyMatrix 的工作量
function convertToAdjacencyMatrix(incidenceMap, M) {
const connectedPairs = Object.values(incidenceMap).map(x => [...x])
// (M x M)
const adjacencyMatrix = new Array(M)
.fill(0).map(_ => new Array(M).fill(0));
connectedPairs.forEach(pair => {
const [n1, n2] = pair
// A vertice always has a relationship with itself.
adjacencyMatrix[n1][n1] = 1
adjacencyMatrix[n2][n2] = 1
// Mark the relationship between the vertices sharing the same edge.
adjacencyMatrix[n1][n2] = 1
adjacencyMatrix[n2][n1] = 1
})
return adjacencyMatrix
};
最后我们结合main中的逻辑得到
async function main() {
try {
const[N,M] = await getDimensions()
// Create incidentMatrix for faster conversion.
const incidenceMap = await createIncidenceMap(N);
// Convert.
const adjacencyMatrix = convertToAdjacencyMatrix(incidenceMap, N)
console.log(adjacencyMatrix)
rl.close();
} catch (err) {
console.log(`Error found when reading ${err}`);
}
}
使用您提供的输入调用 main 将产生
// [ [ 1, 1, 0 ], [ 1, 1, 1 ], [ 0, 1, 1 ] ]
main()
正如预期的那样。
一个完整的例子可以在这个demo中找到