11.6 直方图(histograms)
11.6.1 直方图ADT
直方图ADT所包含的方法如下:
- Histogram(catSeq):创建直方图,catSeq为指定的分类,每一个分类的频数初始化为零;
- getCount(category):返回给定分类的频数;
- incCount(category):给定分类的频数加一;
- totalCount():返回所有分类的频数之和;
- iterator():直方图的迭代器。
从文件中读取数据,建立一个直方图。
#-*-coding: utf-8-*-
# 建立直方图
from maphist import Histogram
def letterGrade(grade):
if grade >= 90:
return 'A'
elif grade >= 80:
return 'B'
elif grade >= 70:
return 'C'
elif grade >= 60:
return 'D'
else:
return 'F'
def printChart(gradeHist):
print "\tGrade Distribution"
letterGrades = ('A', 'B', 'C', 'D', 'F')
for letter in letterGrades:
print " |"
print "%s +"
freq = gradeHist.getCount(letter)
print '*' * freq
print " |"
print " +----+----+----+----+----+----+----+----"
print " 0 5 10 15 20 25 30 35"
def main():
gradeHist = Histogram("ABCDF")
gradeFile = open('cs101grades.txt', 'r')
for line in gradeFile:
grade = int(line)
gradeHist.incCount(letterGrade(grade))
printChart(gradeHist)
if __name__ == "__main__":
main()
直方图的实现
使用散列表来实现。
#-*-coding: utf-8-*-
# 直方图的实现
from hashmap import HashMap
class Histogram(object):
def __init__(self, catSeq):
self._freqCounts = HashMap()
for cat in catSeq:
self._freqCounts.add(cat, 0)
def getCount(self, category):
assert category in self._freqCounts, "Invalid histogram category."
return self._freqCounts.valueOf(category)
def incCount(self, category):
assert category in self._freqCounts, "Invalid histogram category."
value = self._freqCounts.valueOf(category)
self._freqCounts.add(category, value+1)
def totalCount(self):
total = 0
for cat in self._freqCounts:
total += self._freqCounts.valueOf(cat)
return total
def __iter__(self):
return iter(self._freqCounts)
彩色直方图的方法:
- ColorHistogram():创建空的彩色直方图;
- getCount(red, green, blue):返回给定颜色的频数;
- incCount(red, green, blue):将给定颜色的频数加一;
- totalCount():返回所有颜色的频数;
- iterator():迭代器。
闭散列法也不是一种特别好的选择,因为再散列次数太多。开散列法,如果散列函数设计得好,则是一种较好的选择。
本例可以使用开散列法,使用二维数组作为底层数组,确定red参数和green参数,而数组中的链表结点则表示blue 参数。
对于含n像素的图像,其直方图的构造器的时间复杂度是O(n)。因为,确定底层数组的索引是O(1),但要确定blue参数,则需在链表进行搜索操作,所以时间复杂度是O(n)。
相应的遍历,可以对二维数组遍历,但效率太低。可以单独储存一个链表,用以记录当前的所有颜色。