如何使用javascript

时间:2018-06-09 19:14:54

标签: javascript discrete-mathematics

对于我的任务,我必须找出关系集(我从二维数组得到的)是对称的还是和/和传递的.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");

2 个答案:

答案 0 :(得分:0)

您可以使用Set并删除对称对或反身对。最后检查集合的大小,如果为零,则所有项目都已分配,无论是对称的还是反身的。

&#13;
&#13;
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;
&#13;
&#13;

答案 1 :(得分:0)

在输入数组上使用两个循环执行此操作效率不高。最好先将关系的定义转换为嵌套的对象 - 值结构,这样您就可以在常量时间内检索某个对是否在关系中。

对于示例数据,对象可能如下所示:

{
    "1": {
        "3": true
    },
    "2": {
        "2": true,
        "3": true
    },
    "3": {
        "1": true,
        "2": true
    }
}

以下是如何在线性时间内创建该对象并决定对称性,也是在线性时间内:

&#13;
&#13;
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;
&#13;
&#13;

Transivity

传递性需要考虑第三个值。当以下两个关系成立时:a→b和b→c,则a→c必须保持。这需要一个额外的循环,根据与上面代码相​​同的模式:

&#13;
&#13;
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;
&#13;
&#13;

ES6版本

当然,这可以使用Map,Set和其他一些好东西更简洁地用ES6编写:

&#13;
&#13;
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;
&#13;
&#13;

及物性(ES6)

代码与上一个代码块(ES6)中的代码相同,最后一行更改为:

return r.every(([a, b]) => !rel.has(b) || [...rel.get(b)].every(c => rel.get(a).has(c)));