对于我的任务,我必须找出关系集(我从二维数组得到的)是对称的还是和/和传递的.Below是关系的二维数组,R = {(1,3) ,(2,2),(2,3),(3,2),(3,1)} //当我从用户输入中取值时,这个关系可能会改变。
var r = new Array(5);
r[0] = [1,3];
r[1] = [2,2];
r[2] = [2,3];
r[3] = [3,2];
r[4] = [3,1];
所以我想知道的是如何根据这个数组进行识别。我已经做了对称但它仍然没有显示正确的结果。根据数组,它应该输出“IT IS SYMMETRIC”。我仍然找不到对称因此我无法继续发现它是否具有传递性。
for(var i = 0; i < 5; i++){ //row
for(var j = 1; j < 5; j++){
if(r[i][1] == r[j][0])
{
if(r[i][0] == r[j][1])
{
symmetric = symmetric + 1;
}
}
else if (r[i][0] == r[i][1])
{
symmetric = symmetric + 1;
}
else
{
symmetric = -1;
}
}
//j= j + 1;
}
if(symmetric > 0)
{
alert("IT IS SYMMETRIC");
}
else
alert("IT IS NOT SYMMETRIC");
答案 0 :(得分:0)
您可以使用Set
并删除对称对或反身对。最后检查集合的大小,如果为零,则所有项目都已分配,无论是对称的还是反身的。
var r = [[1, 3], [2, 2], [2, 3], [3, 2], [3, 1]],
pairs = new Set(r.map(a => a.toString()));
r.forEach(([x, y]) => {
if (x === y) {
pairs.delete([x, y].toString());
return;
}
pairs.delete([x, y].toString()) && pairs.delete([x, y].toString());
});
console.log(!pairs.size);
&#13;
答案 1 :(得分:0)
在输入数组上使用两个循环执行此操作效率不高。最好先将关系的定义转换为嵌套的对象 - 值结构,这样您就可以在常量时间内检索某个对是否在关系中。
对于示例数据,对象可能如下所示:
{
"1": {
"3": true
},
"2": {
"2": true,
"3": true
},
"3": {
"1": true,
"2": true
}
}
以下是如何在线性时间内创建该对象并决定对称性,也是在线性时间内:
var r = [[1,3], [2,2], [2,3], [3,2], [3,1]];
function isSymmetric(r) {
// convert to object
var rel = {}
for (var i = 0; i < r.length; i++) {
if (!(r[i][0] in rel)) rel[r[i][0]] = {};
rel[r[i][0]][r[i][1]] = true;
}
// Test to see if opposite relation is in object
for (var a in rel) {
for (var b in rel[a]) {
if (!rel[b] || !rel[b][a]) return false;
}
}
return true;
}
console.log(isSymmetric(r));
&#13;
传递性需要考虑第三个值。当以下两个关系成立时:a→b和b→c,则a→c必须保持。这需要一个额外的循环,根据与上面代码相同的模式:
var r = [[1,3], [2,2], [2,3], [3,2], [3,1]];
function isTransitive(r) {
// convert to object
var rel = {}
for (var i = 0; i < r.length; i++) {
if (!(r[i][0] in rel)) rel[r[i][0]] = {};
rel[r[i][0]][r[i][1]] = true;
}
// Test to see if opposite relation is in object
for (var a in rel) {
for (var b in rel[a]) {
if (!rel[b]) continue;
for (var c in rel[b]) {
if (!rel[a][c]) return false;
}
}
}
return true;
}
console.log(isTransitive(r));
&#13;
当然,这可以使用Map,Set和其他一些好东西更简洁地用ES6编写:
const r = [[1,3], [2,2], [2,3], [3,2], [3,1]];
function isSymmetric(r) {
// convert to Map
var rel = new Map(r.map(pair => [pair[0], new Set]));
r.forEach(([a, b]) => rel.get(a).add(b));
// Test to see if opposite relation is in Map
return r.every(([a, b]) => rel.has(b) && rel.get(b).has(a));
}
console.log(isSymmetric(r));
&#13;
代码与上一个代码块(ES6)中的代码相同,最后一行更改为:
return r.every(([a, b]) => !rel.has(b) || [...rel.get(b)].every(c => rel.get(a).has(c)));