- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有很多元素(表示为复选框)具有一些不同的关系。例如:
编辑:答案中出现了 3 个问题,我想在这里定义:
问:默认、禁止或需要的是什么?答:都没有。如果2个元素之间没有关系,它们可以独立行动(只要与一个共同的元素没有关系就可以说否则)。
问:如果 A 禁止 B,那么 B 是否会自动禁止 A?答:是的。猫(A)说,你不能和狗(B)一起吃。就算是狗不关心猫,你不能把它们结合起来,因为猫不会喜欢的。
问:如果 A 需要 B,那么 B 是否自动需要 A? A: 不,如果你想要阅读 stackoverflow (A),您需要浏览器 (B)。但如果你想要使用浏览器 (B),您不需要 stackoverflow (A)。
编辑:我想举一个更简单的例子。比方说,您可以使用复选框配置汽车。有一些规则。例如,如果选择黑色油漆,则不能选择白色内饰颜色(禁止)。如果选择真皮座椅,只能与座椅加热(需要)和真皮方向盘(需要)组合使用,不能与电动座椅调节(禁止)组合使用。白色内饰无法加热座椅(禁止),而白色车顶需要白色内饰。因此,即使没有定义,你也不能有带座椅加热的白色屋顶(由于与公共(public)元素的关系而被禁止)。
因此,如果有人激活了复选框 A,那么复选框 B 和 C 也需要被激活,而复选框 D 需要被禁用。由于 A 需要 B 而 B 不能与 E 组合,因此也需要禁用复选框 E。因为C需要F,所以需要激活F。由于 F 不能与 G 组合,因此 G 也需要停用。
反过来说:如果有人激活了E,那么B就需要去激活,因为B不能和E结合。但是D不需要激活,因为D需要E而E不需要必然需要D。
现在的大问题是:
问题是递归。每个 Action 都会导致更多 Action ,而更多 Action 会(可能)导致更多 Action 。
以下逻辑适用于“A”被激活的示例:
关系的当前定义(可以更改):
var relations = {
'A': {
'B': 'needed',
'C': 'needed',
'D': 'prohibited'
},
'B': {
'E': 'prohibited'
},
'D': {
'E': 'needed'
},
'C': {
'F': 'needed'
},
'F': {
'G': 'prohibited'
},
'S': {
'B': 'prohibited'
},
'T': {
'D': 'prohibited'
},
'U': {
'S': 'needed'
}
}
当前的理论方法:
假设点击“A”:
foreach (relations['A'] as related, relation) {
if (relation === 'needed') {
// take action
activateRelated(related);
} else if (relation === 'prohibited') {
// take action
disableRelated(related);
}
}
但这只是第一次迭代。从理论上讲,这可能是一个在执行每个操作后递归调用自身的函数。但是,比方说有很多关系的 300 个元素,它会无限循环。好吧,如果采取一项操作,激活一个复选框,它就可以正常工作。在更现实的场景中,有 30% 到 50% 的复选框处于事件状态,并且关系的检查需要一直向上和向下。
第二个问题是:如果用户再次禁用复选框 A,则需要再次检查所有关系 - 对于所有仍处于事件状态的复选框也是如此。
最佳答案
也许这有帮助。如果与表单下方的提示一起使用。
编辑:现在可以简单地检查循环引用。相互影响的选中项首先被取消选中。
编辑 2:现在禁用/启用复选框。
var relation = [
{ name: 'A', needed: ['B', 'C'], prohibited: ['D'] },
{ name: 'B', needed: [], prohibited: ['E'] },
{ name: 'C', needed: ['F'], prohibited: [] },
{ name: 'D', needed: ['E'], prohibited: [] },
{ name: 'E', needed: [], prohibited: [] },
{ name: 'F', needed: [], prohibited: ['G'] },
{ name: 'G', needed: [], prohibited: [] },
{ name: 'S', needed: [], prohibited: ['B'] },
{ name: 'T', needed: [], prohibited: ['D'] },
{ name: 'U', needed: ['S'], prohibited: [] }
];
void function () {
var div = document.createElement('div'),
form = document.createElement('form'),
loop;
div.id = 'out';
form.name = 'boxes';
relation.forEach(function (a) {
var br = document.createElement('br'),
input = document.createElement('input'),
label = document.createElement('label');
input.type = 'checkbox';
input.name = a.name;
input.addEventListener('change', check);
label.textContent = a.name;
label.for = a.name;
label.appendChild(input);
label.appendChild(document.createTextNode((a.needed.length ? ' needed: ' + a.needed.join(', ') : '') + (a.prohibited.length ? ' prohibited: ' + a.prohibited.join(', ') : '')));
form.appendChild(label);
form.appendChild(br);
});
form.appendChild(div);
document.body.appendChild(form);
do {
loop = false;
relation.forEach(function (a) {
a.needed.forEach(function (aa) {
relation.forEach(function (b) {
b.prohibited.forEach(function (bb) {
if (aa === bb) {
if (!~a.prohibited.indexOf(b.name)) {
a.prohibited.push(b.name);
loop = true;
}
if (!~b.prohibited.indexOf(a.name)) {
b.prohibited.push(a.name);
loop = true;
}
}
});
});
});
});
} while (loop);
}();
function check() {
function getBox(l) { return document.boxes[l].checked; }
function setBox(l, v) { return document.boxes[l].checked = v; }
function setBoxDisabled(l, v) { return document.boxes[l].disabled = v; }
var disabled, msg, loop;
do {
disabled = [];
msg = [];
loop = false;
relation.forEach(function (a) {
if (getBox(a.name)) {
a.needed.forEach(function (b) {
if (!getBox(b)) {
msg.push('With ' + a.name + ', ' + b + ' is required');
setBox(b, true);
loop = true;
}
});
a.prohibited.forEach(function (b) {
if (getBox(b)) {
msg.push('With ' + a.name + ', ' + b + ' is prohibited');
setBox(b, false);
loop = true;
}
setBoxDisabled(b, true);
!~disabled.indexOf(b) && disabled.push(b);
});
}
});
relation.forEach(function (a) {
if (!getBox(a.name)) {
a.prohibited.forEach(function (b) {
!~disabled.indexOf(b) && setBoxDisabled(b, false);
});
}
});
msg.length && out(msg.join('<br>') + '<hr>');
} while (loop);
}
function out(s) {
var node = document.createElement('div');
node.innerHTML = s + '<br>';
document.getElementById('out').appendChild(node);
}
奖励:一种略有不同的方法,具有递归风格和适当的更改消息。
var relation = [
{ name: 'A', needed: ['B', 'C'], prohibited: ['D'] },
{ name: 'B', needed: [], prohibited: ['E'] },
{ name: 'C', needed: ['F'], prohibited: [] },
{ name: 'D', needed: ['E'], prohibited: [] },
{ name: 'E', needed: [], prohibited: [] },
{ name: 'F', needed: [], prohibited: ['G'] },
{ name: 'G', needed: [], prohibited: [] },
{ name: 'S', needed: [], prohibited: ['B'] },
{ name: 'T', needed: [], prohibited: ['D'] },
{ name: 'U', needed: ['S'], prohibited: [] }
], object = {};
void function () {
var div = document.createElement('div'),
form = document.createElement('form');
div.id = 'out';
form.name = 'boxes';
relation.forEach(function (a) {
var br = document.createElement('br'),
input = document.createElement('input'),
label = document.createElement('label');
input.type = 'checkbox';
input.name = a.name;
input.addEventListener('change', function (l) { return function () { checkBox(l); } }(a.name));
//input.addEventListener('change', function () { checkBox(a.name); });
label.textContent = a.name;
label.for = a.name;
label.appendChild(input);
label.appendChild(document.createTextNode((a.needed.length ? ' needed: ' + a.needed.join(', ') : '') + (a.prohibited.length ? ' prohibited: ' + a.prohibited.join(', ') : '')));
form.appendChild(label);
form.appendChild(br);
object[a.name] = a;
});
form.appendChild(div);
document.body.appendChild(form);
}();
function checkBox(l) {
function getBox(l) { return document.boxes[l].checked; }
function setBox(l, v, x) {
if (document.boxes[l].checked !== v) {
v ? out('With ' + x + ' option ' + l + ' is necessary.') : out('Without ' + x + ' option ' + l + ' is not valid.');
document.boxes[l].checked = v;
}
}
function setBoxDisabled(l, v, x) {
if (document.boxes[l].disabled !== v) {
v ? out('With ' + x + ' option ' + l + ' is not available.') : out('Without ' + x + ' option ' + l + ' is now available.');
document.boxes[l].disabled = v;
}
}
if (getBox(l)) {
object[l].prohibited.forEach(function (p) {
setBox(p, false, l);
setBoxDisabled(p, true, l);
relation.forEach(function (a) {
if (~a.needed.indexOf(p)) {
setBox(a.name, false, p);
setBoxDisabled(a.name, true, p);
checkBox(a.name);
}
});
checkBox(p);
});
object[l].needed.forEach(function (p) {
setBox(p, true, l);
checkBox(p);
});
} else {
var allProhibited = [];
relation.forEach(function (a) {
if (getBox(a.name)) {
a.prohibited.forEach(function (b) {
!~allProhibited.indexOf(b) && allProhibited.push(b);
});
}
});
object[l].prohibited.forEach(function (p) {
if (!~allProhibited.indexOf(p)) {
setBox(p, false, l);
setBoxDisabled(p, false, l);
}
relation.forEach(function (a) {
if (~a.needed.indexOf(p)) {
setBox(a.name, false, p);
setBoxDisabled(a.name, false, p);
checkBox(a.name);
}
});
checkBox(p);
});
relation.forEach(function (a) {
if (~a.needed.indexOf(l)) {
setBox(a.name, false, l);
checkBox(a.name);
}
});
}
}
function out(s) {
var node = document.createElement('div');
node.innerHTML = s + '<br>';
document.getElementById('out').appendChild(node);
}
关于javascript - 在javascript中遍历递归关系矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33671842/
在本教程中,您将借助示例了解 JavaScript 中的递归。 递归是一个调用自身的过程。调用自身的函数称为递归函数。 递归函数的语法是: function recurse() {
我的类(class) MyClass 中有这段代码: public new MyClass this[int index] { get {
我目前有一个非常大的网站,大小约为 5GB,包含 60,000 个文件。当前主机在帮助我将站点转移到新主机方面并没有做太多事情,我想的是在我的新主机上制作一个简单的脚本以 FTP 到旧主机并下载整个
以下是我对 AP 计算机科学问题的改编。书上说应该打印00100123我认为它应该打印 0010012但下面的代码实际上打印了 3132123 这是怎么回事?而且它似乎没有任何停止条件?! publi
fun fact(x: Int): Int{ tailrec fun factTail(y: Int, z: Int): Int{ if (y == 0) return z
我正在尝试用c语言递归地创建线性链表,但继续坚持下去,代码无法正常工作,并出现错误“链接器工具错误 LNK2019”。可悲的是我不明白发生了什么事。这是我的代码。 感谢您提前提供的大力帮助。 #inc
我正在练习递归。从概念上讲,我理解这应该如何工作(见下文),但我的代码不起作用。 请告诉我我做错了什么。并请解释您的代码的每个步骤及其工作原理。清晰的解释比只给我有效的代码要好十倍。 /* b
我有一个 ajax 调用,我想在完成解析并将结果动画化到页面中后调用它。这就是我陷入困境的地方。 我能记忆起这个功能,但它似乎没有考虑到动画的延迟。即控制台不断以疯狂的速度输出值。 我认为 setIn
有人愿意用通俗易懂的语言逐步解释这个程序(取自书籍教程)以帮助我理解递归吗? var reverseArray = function(x,indx,str) { return indx == 0 ?
目标是找出数组中整数的任意组合是否等于数组中的最大整数。 function ArrayAdditionI(arr) { arr.sort(function(a,b){ return a -
我在尝试获取 SQL 查询所需的所有数据时遇到一些重大问题。我对查询还很陌生,所以我会尽力尽可能地描述这一点。 我正在尝试使用 Wordpress 插件 NextGen Gallery 进行交叉查询。
虽然网上有很多关于递归的信息,但我还没有找到任何可以应用于我的问题的信息。我对编程还是很陌生,所以如果我的问题很微不足道,请原谅。 感谢您的帮助:) 这就是我想要的结果: listVariations
我一整天都在为以下问题而苦苦挣扎。我一开始就有问题。我不知道如何使用递归来解决这个特定问题。我将非常感谢您的帮助,因为我的期末考试还有几天。干杯 假设有一个包含“n”个元素的整数数组“a”。编写递归函
我有这个问题我想创建一个递归函数来计算所有可能的数字 (k>0),加上数字 1 或 2。数字 2 的示例我有两个可能性。 2 = 1+1 和 2 = 2 ,对于数字 3 两个 poss。 3 = 1+
目录 递归的基础 递归的底层实现(不是重点) 递归的应用场景 编程中 两种解决问题的思维 自下而上(Bottom-Up) 自上而下(Top-
0. 学习目标 递归函数是直接调用自己或通过一系列语句间接调用自己的函数。递归在程序设计有着举足轻重的作用,在很多情况下,借助递归可以优雅的解决问题。本节主要介绍递归的基本概念以及如何构建递归程序。
我有一个问题一直困扰着我,希望有人能提供帮助。我认为它可能必须通过递归和/或排列来解决,但我不是一个足够好的 (PHP) 程序员。 $map[] = array("0", "1", "2", "3")
我有数据 library(dplyr, warn.conflicts = FALSE) mtcars %>% as_tibble() %>% select(mpg, qsec) %>% h
在 q 中,over 的常见插图运算符(operator) /是 implementation of fibonacci sequence 10 {x,sum -2#x}/ 1 1 这确实打印了前 1
我试图理解以下代码片段中的递归调用。 static long fib(int n) { return n <= 1 ? n : fib(n-1) + fib(n-2); } 哪个函数调用首先被
我是一名优秀的程序员,十分优秀!