我的回答是O(D + R)。这是对的吗?
我想弄清楚这段代码的Big-O。我正在做一个关于数据结构和算法的独立课程。
此代码取自本书" JavaScript中的数据结构和算法"我正在研究的PacktPub女士L Groiner女士。
请参阅以下内容:
function baseConverter(decNumber, base) {
var remStack = new Stack(), //instantiate class, define variable, O(1)
rem, // define var, O(1)
baseString = '', //initialize, O(1)
digits = '0123456789ABCDEF'; //initialize, O(1)
while(decNumber>0) { //loop, D times:
rem = Math.floor(decNumber % base); //modulo/Math/assignment, O(1)
remStack.push(rem); //push to stack, O(1)
decNumber = Math.floor(decNumber / base); //divide, Math, assignment, O(1)
}
while(!remStack.isEmpty()){ //loop, R times:
baseString += digits[remStack.pop()]; //pop/index/Math/addition assignment, O(1)
}
return baseString; // O(1)
}
我逐行简化每个操作,如下所示:
4 * O(1) + D * 3 * O(1) + R * O(1) =
3 * O(D) + 1 * O(R) =
O(D) + O(R) = O(D + R)
我查看了自己的网络开发笔记并查看了各种书籍。但我只能形成片段并从中推断出来。我想找到一个标准化的框架,或者至少在我的脑海中构建它,以便能够正确地说明Big-O中的运行时间。给我反馈,帮助我这样做。
答案 0 :(得分:0)
第一个循环的运行时复杂性:
while (decNumber > 0) {
rem = Math.floor(decNumber % base);
remStack.push(rem);
decNumber = Math.floor(decNumber / base);
}
此循环迭代频率decNumber
可以除以base
。因此,迭代次数大致为log_base(decNumber)
。
在每次迭代期间,执行数组推送操作。 For simplicity we assume it runs in constant time。
第二个循环的运行频率与将数组元素推送到remStack
时的频率相同,等于第一个循环的迭代次数。
因此,整体运行时复杂度与大致2 * log_base(decNumber)
成正比,等于O(log(decNumber))
。
只要decNumber
上的模运算和除法运算可以在典型硬件上以恒定时间(对于精度有限的JavaScript数字数据类型都适用)执行,就会成立。