【发布时间】:2020-05-09 14:18:32
【问题描述】:
我编写了一个代码,它从 google 工作表中提取列标题(工作表中的第一行)并将它们与对象数组进行比较。对象数组中的每个对象都有 3 个属性:“问题”、“答案”和“类别”。代码将每列的标题与数组中每个对象的“问题”属性进行比较。
如果它们相似,则应将列的索引作为键添加到某个字典中,并将其值设置为包含该问题的答案和类别的数组。无需过多解释我为什么要这样做,但我简要地构建了这个逻辑,以便能够对申请人对某些问题的回答进行评分(因此将问题的索引与其正确答案及其类别相关联)。这是代码:
for (i = 0; i<columnHeaders[0].length; i++){
for (j=0; j<questionsObjects.length; j++){
//Get the current question and convert it to lower case
question = questionsObjects[j].question.toString().toLowerCase();
//Get column header, remove any spaces and new lines from it, and convert it to lower case
columnHeader = columnHeaders[0][i].toString().toLowerCase();
if (isStringSimilar(columnHeader, question)){
//Link the column index to its corresponding question object
var catAndAnswer = [];
catAndAnswer.push (questionsObjects[j].category.toLowerCase());
catAndAnswer.push (questionsObjects[j].rightAnswer.toLowerCase());
columnsQuestionsDictionary[i] = catAndAnswer;
} else {
SpreadsheetApp.getActive().getSheetByName("log").appendRow(["no", columnHeader, question]);
}
}
}
代码运行良好,我唯一的问题是复杂性,它非常高。在某些情况下,此方法需要将近 6 分钟才能执行(对于这种情况,我有大约 40 列和 7 个问题对象)!为了解耦嵌套循环,我想到将问题值(问题对象数组中的所有对象)连接成 1 个单个字符串,在其中我在每个问题之前加上它在对象数组中的索引。
例如:
var str = "";
for (j=0; j<questionsObjects.length; j++){
str = str + j + questionsObjects[j].question.toString.toLowerCase();
}
然后,我可以通过列标题进行另一个单独的循环,将每个标题提取到一个字符串中,然后使用正则表达式exec 方法来匹配长问题字符串(str)中的那个标题,如果找到它我会得到它在 str 中的索引,然后从中减去 1 以知道它在 objects 数组中的索引。然而,事实证明,匹配正则表达式的复杂度是 O(N),其中 N 是我们搜索的字符串的长度(本例中为 str),假设这将在 columns 循环内,我看到我们仍然会得到很高的复杂度,可以达到 O(N^2)。
如何优化这些嵌套循环,使代码以最有效的方式运行?
【问题讨论】:
-
isStringSimilar在做什么?` 为什么不将columnHeader移到外循环? -
@NinaScholz isStringSimilar 比较两个字符串,它最多允许 3 个字符不匹配。因此,如果两个字符串之间的长度差大于 3,则直接返回 false。如果两个字符串都不为空且不为空,则使用 1 个循环遍历两个字符串并比较相同索引处的字符,如果发现超过 3 个不匹配,则返回 false,否则返回 true。使用的循环迭代 N 次,其中 N 是较长字符串的长度(所以 O(N))。至于移动 columnHeader,我认为这不会降低复杂性,是吗?谢谢
-
在这种情况下,您需要将每个标题与每个问题进行比较...移动
columnHeader会有所帮助,因为它只转换一次,而不是列的 n 次。 -
@NinaScholz 我明白了,你是对的,这会有所帮助。我会试试看。谢谢!
-
感谢@NinaScholz,您的提示非常有用!我发布了一个答案与大家分享结果。
标签: javascript arrays big-o nested-loops