Data update
This commit is contained in:
parent
5150844a7d
commit
4bb20c9b71
7735 changed files with 38060 additions and 199180 deletions
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
|
||||
@interface HuffmanTree : NSObject {
|
||||
int freq;
|
||||
int freq;
|
||||
}
|
||||
-(instancetype)initWithFreq:(int)f;
|
||||
@property (nonatomic, readonly) int freq;
|
||||
|
|
@ -11,34 +11,34 @@
|
|||
@implementation HuffmanTree
|
||||
@synthesize freq; // the frequency of this tree
|
||||
-(instancetype)initWithFreq:(int)f {
|
||||
if (self = [super init]) {
|
||||
freq = f;
|
||||
}
|
||||
return self;
|
||||
if (self = [super init]) {
|
||||
freq = f;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
const void *HuffmanRetain(CFAllocatorRef allocator, const void *ptr) {
|
||||
return (__bridge_retained const void *)(__bridge id)ptr;
|
||||
return (__bridge_retained const void *)(__bridge id)ptr;
|
||||
}
|
||||
void HuffmanRelease(CFAllocatorRef allocator, const void *ptr) {
|
||||
(void)(__bridge_transfer id)ptr;
|
||||
(void)(__bridge_transfer id)ptr;
|
||||
}
|
||||
CFComparisonResult HuffmanCompare(const void *ptr1, const void *ptr2, void *unused) {
|
||||
int f1 = ((__bridge HuffmanTree *)ptr1).freq;
|
||||
int f2 = ((__bridge HuffmanTree *)ptr2).freq;
|
||||
if (f1 == f2)
|
||||
return kCFCompareEqualTo;
|
||||
else if (f1 > f2)
|
||||
return kCFCompareGreaterThan;
|
||||
else
|
||||
return kCFCompareLessThan;
|
||||
int f1 = ((__bridge HuffmanTree *)ptr1).freq;
|
||||
int f2 = ((__bridge HuffmanTree *)ptr2).freq;
|
||||
if (f1 == f2)
|
||||
return kCFCompareEqualTo;
|
||||
else if (f1 > f2)
|
||||
return kCFCompareGreaterThan;
|
||||
else
|
||||
return kCFCompareLessThan;
|
||||
}
|
||||
|
||||
|
||||
@interface HuffmanLeaf : HuffmanTree {
|
||||
char value; // the character this leaf represents
|
||||
char value; // the character this leaf represents
|
||||
}
|
||||
@property (readonly) char value;
|
||||
-(instancetype)initWithFreq:(int)f character:(char)c;
|
||||
|
|
@ -47,16 +47,16 @@ CFComparisonResult HuffmanCompare(const void *ptr1, const void *ptr2, void *unus
|
|||
@implementation HuffmanLeaf
|
||||
@synthesize value;
|
||||
-(instancetype)initWithFreq:(int)f character:(char)c {
|
||||
if (self = [super initWithFreq:f]) {
|
||||
value = c;
|
||||
}
|
||||
return self;
|
||||
if (self = [super initWithFreq:f]) {
|
||||
value = c;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
@interface HuffmanNode : HuffmanTree {
|
||||
HuffmanTree *left, *right; // subtrees
|
||||
HuffmanTree *left, *right; // subtrees
|
||||
}
|
||||
@property (readonly) HuffmanTree *left, *right;
|
||||
-(instancetype)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r;
|
||||
|
|
@ -65,86 +65,86 @@ CFComparisonResult HuffmanCompare(const void *ptr1, const void *ptr2, void *unus
|
|||
@implementation HuffmanNode
|
||||
@synthesize left, right;
|
||||
-(instancetype)initWithLeft:(HuffmanTree *)l right:(HuffmanTree *)r {
|
||||
if (self = [super initWithFreq:l.freq+r.freq]) {
|
||||
left = l;
|
||||
right = r;
|
||||
}
|
||||
return self;
|
||||
if (self = [super initWithFreq:l.freq+r.freq]) {
|
||||
left = l;
|
||||
right = r;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
||||
|
||||
HuffmanTree *buildTree(NSCountedSet *chars) {
|
||||
|
||||
CFBinaryHeapCallBacks callBacks = {0, HuffmanRetain, HuffmanRelease, NULL, HuffmanCompare};
|
||||
CFBinaryHeapRef trees = CFBinaryHeapCreate(NULL, 0, &callBacks, NULL);
|
||||
|
||||
// initially, we have a forest of leaves
|
||||
// one for each non-empty character
|
||||
for (NSNumber *ch in chars) {
|
||||
int freq = [chars countForObject:ch];
|
||||
if (freq > 0)
|
||||
CFBinaryHeapAddValue(trees, (__bridge const void *)[[HuffmanLeaf alloc] initWithFreq:freq character:(char)[ch intValue]]);
|
||||
}
|
||||
|
||||
NSCAssert(CFBinaryHeapGetCount(trees) > 0, @"String must have at least one character");
|
||||
// loop until there is only one tree left
|
||||
while (CFBinaryHeapGetCount(trees) > 1) {
|
||||
// two trees with least frequency
|
||||
HuffmanTree *a = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
|
||||
CFBinaryHeapRemoveMinimumValue(trees);
|
||||
HuffmanTree *b = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
|
||||
CFBinaryHeapRemoveMinimumValue(trees);
|
||||
|
||||
// put into new node and re-insert into queue
|
||||
CFBinaryHeapAddValue(trees, (__bridge const void *)[[HuffmanNode alloc] initWithLeft:a right:b]);
|
||||
}
|
||||
HuffmanTree *result = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
|
||||
CFRelease(trees);
|
||||
return result;
|
||||
CFBinaryHeapCallBacks callBacks = {0, HuffmanRetain, HuffmanRelease, NULL, HuffmanCompare};
|
||||
CFBinaryHeapRef trees = CFBinaryHeapCreate(NULL, 0, &callBacks, NULL);
|
||||
|
||||
// initially, we have a forest of leaves
|
||||
// one for each non-empty character
|
||||
for (NSNumber *ch in chars) {
|
||||
int freq = [chars countForObject:ch];
|
||||
if (freq > 0)
|
||||
CFBinaryHeapAddValue(trees, (__bridge const void *)[[HuffmanLeaf alloc] initWithFreq:freq character:(char)[ch intValue]]);
|
||||
}
|
||||
|
||||
NSCAssert(CFBinaryHeapGetCount(trees) > 0, @"String must have at least one character");
|
||||
// loop until there is only one tree left
|
||||
while (CFBinaryHeapGetCount(trees) > 1) {
|
||||
// two trees with least frequency
|
||||
HuffmanTree *a = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
|
||||
CFBinaryHeapRemoveMinimumValue(trees);
|
||||
HuffmanTree *b = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
|
||||
CFBinaryHeapRemoveMinimumValue(trees);
|
||||
|
||||
// put into new node and re-insert into queue
|
||||
CFBinaryHeapAddValue(trees, (__bridge const void *)[[HuffmanNode alloc] initWithLeft:a right:b]);
|
||||
}
|
||||
HuffmanTree *result = (__bridge HuffmanTree *)CFBinaryHeapGetMinimum(trees);
|
||||
CFRelease(trees);
|
||||
return result;
|
||||
}
|
||||
|
||||
void printCodes(HuffmanTree *tree, NSMutableString *prefix) {
|
||||
NSCAssert(tree != nil, @"tree must not be nil");
|
||||
if ([tree isKindOfClass:[HuffmanLeaf class]]) {
|
||||
HuffmanLeaf *leaf = (HuffmanLeaf *)tree;
|
||||
|
||||
// print out character, frequency, and code for this leaf (which is just the prefix)
|
||||
NSLog(@"%c\t%d\t%@", leaf.value, leaf.freq, prefix);
|
||||
|
||||
} else if ([tree isKindOfClass:[HuffmanNode class]]) {
|
||||
HuffmanNode *node = (HuffmanNode *)tree;
|
||||
|
||||
// traverse left
|
||||
[prefix appendString:@"0"];
|
||||
printCodes(node.left, prefix);
|
||||
[prefix deleteCharactersInRange:NSMakeRange([prefix length]-1, 1)];
|
||||
|
||||
// traverse right
|
||||
[prefix appendString:@"1"];
|
||||
printCodes(node.right, prefix);
|
||||
[prefix deleteCharactersInRange:NSMakeRange([prefix length]-1, 1)];
|
||||
}
|
||||
NSCAssert(tree != nil, @"tree must not be nil");
|
||||
if ([tree isKindOfClass:[HuffmanLeaf class]]) {
|
||||
HuffmanLeaf *leaf = (HuffmanLeaf *)tree;
|
||||
|
||||
// print out character, frequency, and code for this leaf (which is just the prefix)
|
||||
NSLog(@"%c\t%d\t%@", leaf.value, leaf.freq, prefix);
|
||||
|
||||
} else if ([tree isKindOfClass:[HuffmanNode class]]) {
|
||||
HuffmanNode *node = (HuffmanNode *)tree;
|
||||
|
||||
// traverse left
|
||||
[prefix appendString:@"0"];
|
||||
printCodes(node.left, prefix);
|
||||
[prefix deleteCharactersInRange:NSMakeRange([prefix length]-1, 1)];
|
||||
|
||||
// traverse right
|
||||
[prefix appendString:@"1"];
|
||||
printCodes(node.right, prefix);
|
||||
[prefix deleteCharactersInRange:NSMakeRange([prefix length]-1, 1)];
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
|
||||
NSString *test = @"this is an example for huffman encoding";
|
||||
|
||||
// read each character and record the frequencies
|
||||
NSCountedSet *chars = [[NSCountedSet alloc] init];
|
||||
int n = [test length];
|
||||
for (int i = 0; i < n; i++)
|
||||
[chars addObject:@([test characterAtIndex:i])];
|
||||
|
||||
// build tree
|
||||
HuffmanTree *tree = buildTree(chars);
|
||||
|
||||
// print out results
|
||||
NSLog(@"SYMBOL\tWEIGHT\tHUFFMAN CODE");
|
||||
printCodes(tree, [NSMutableString string]);
|
||||
|
||||
NSString *test = @"this is an example for huffman encoding";
|
||||
|
||||
// read each character and record the frequencies
|
||||
NSCountedSet *chars = [[NSCountedSet alloc] init];
|
||||
int n = [test length];
|
||||
for (int i = 0; i < n; i++)
|
||||
[chars addObject:@([test characterAtIndex:i])];
|
||||
|
||||
// build tree
|
||||
HuffmanTree *tree = buildTree(chars);
|
||||
|
||||
// print out results
|
||||
NSLog(@"SYMBOL\tWEIGHT\tHUFFMAN CODE");
|
||||
printCodes(tree, [NSMutableString string]);
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue