摊销分析是指确定序列(而不是单个)操作的时间平均运行时间。它与平均案例分析不同,因为在这里,我们不假定数据像我们进行快速排序的平均案例分析那样以平均(不是很差)的方式排列。也就是说,摊销分析是最坏的情况分析,但是对于一系列操作而不是单个操作。它适用于由操作顺序组成的方法,在该方法中,大多数操作很便宜,但有些操作很昂贵。可以在下面实现的二进制计数器的帮助下将其可视化。
让我们通过在C中实现一个增量计数器来了解这一点。首先,让我们看看计数器增量是如何工作的。
让变量i包含值0,我们执行i ++很多次。由于在硬件上,所有操作都以二进制形式执行。让二进制数存储在8位中。因此,值是00000000。让我们增加很多次。因此,我们发现的模式为:
00000000、00000001、00000010、00000011、00000100、00000101、00000110、00000111、00001000等…..
脚步 :
1.从最右边进行迭代,并将全为零,直到找到第一个零。
2.迭代后,如果index大于或等于零,则使该位置上的零位于一。
C++
#include
using namespace std;
int main()
{
char str[] = "10010111";
int length = strlen(str);
int i = length - 1;
while (str[i] == '1') {
str[i] = '0';
i--;
}
if (i >= 0)
str[i] = '1';
printf("% s", str);
}
Java
import java.util.*;
class GFG{
public static void main(String args[])
{
String st = "10010111";
char[] str = st.toCharArray();
int lengthh = st.length();
int i = lengthh - 1;
while (str[i] == '1')
{
str[i] = '0';
i--;
}
if (i >= 0)
str[i] = '1';
System.out.print( str);
}
}
// This code is contributed by sanjoy_62
输出:
10011000
简单地看程序或算法,其运行成本看起来与位数成正比,但实际上,它与位数不成比例。让我们看看如何!
假设递增操作执行了k次。我们看到,在每个增量中,其最右边的位都在翻转。因此,LSB的翻转次数为k。因为,最右边的第二个在间隙之后翻转,即以2增量递增1次。最右边的第3个– 1次,以4为增量。最右边的第4位-1次,以8为增量。因此,翻转数是最右边的第二位为k / 2,最右边的第三位为k / 4,最右边的第四位为k / 8,依此类推……
总费用将是翻转的总次数,即
C(k)= k + k / 2 + k / 4 + k / 8 + k / 16 +……
C(k)
因此,C(k)/ k <2
因此,我们发现一次增加一个计数器的平均成本是恒定的,并且不取决于位数。我们得出结论,增加计数器是恒定成本操作。
参考 :
- http://www.cs.cornell.edu/courses/cs3110/2013sp/supplemental/recitations/rec21.html
- http://faculty.cs.tamu.edu/klappi/csce411-s17/csce411-amortized3.pdf