20-CS-122-001 Computer Science II Spring 2012
Hamming's sequence

Virtual functions, classes, inheritance, lists, queues, stacks, applications

Prev     Next     Lectures     hamming.cc     ham_stream.cc

```#include <iomanip>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include "bigint.h"
using namespace std;

// Stream declaration
class Stream {
public:
bool isNull;
BigInt *first;
virtual Stream *rest () { return NULL; }
Stream () { isNull = true; }
};

// successor declaration
class Successor : public Stream {
public:
Successor (BigInt *num) {
first = num;
isNull = false;
}

Successor *rest () {
}
};

// Inputs: two streams of integers in increasing order
// Output: a stream in increasing order consisting of exactly those
// numbers in the input streams (assume only infinite streams).
class Merge : public Stream {
Stream *s1, *s2;

public:
Merge (Stream *a, Stream *b) {
isNull = false;
if (!a->isNull && (b->isNull || a->first->lessThan(b->first))) {
s1 = a;
s2 = b;
} else if (!b->isNull && (a->isNull || b->first->lessThan(a->first))) {
s1 = b;
s2 = a;
}
else {
isNull = true;
}
if (!isNull) first = s1->first;
}

Stream *rest () { return new Merge(s1->rest(), s2);  }
};

// Inputs: an integer n and a Stream s of numbers
// Output: the Stream of all tokens of s multiplied by n
class Times : public Stream {
Stream *s1;  BigInt *multiplier;

public:
Times (BigInt *n, Stream *s) {
isNull = s->isNull;
s1 = s;
multiplier = n;
if (!isNull) first = s->first->multiply(n);
}

Times *rest() { return new Times (multiplier, s1->rest()); }
};

// Finite size array of objects as a stream
class Array : public Stream {
BigInt **array;
int n;

public:
Array (BigInt **a, int m) {
if (m < 1 || a == NULL) isNull = true;
else { isNull = false; first = a[0]; }
n = m;
array = a;
}

Array *rest () { return new Array(&array[1], n-1); }
};

// p is a list of prime numbers in increasing order
// + is concatenate, * is streams times
// hamming(p) =
//    if (p == null) return null;
//    return first(p) + merge(first(p)*hamming(p), hamming(rest(p));
//
/* Note: "this" replaces "new Hamming(primes)" in "Stream *rest()" */
class Hamming : public Stream {
Array *primes;

public:
Hamming (Array *primes) {
isNull = primes->isNull;
first = primes->first;
this->primes = primes;
}

Merge *rest () {
return new Merge(new Hamming(primes->rest()),
new Times(primes->first, this));
}
};

// Hamming
int main(int argc, char **argv) {
if (argc == 1) {
cout << "Usage: " << argv[0] << " <1|2|3> <number> ...\n";
cout << "  where 1 for successor demo,\n";
cout << "        2 for successor and times demo,\n";
cout << "        3 for hamming sequence demo\n";
exit(0);
}
if (atoi(argv[1]) == 1) {  // Successor
if (argc < 3) {
cout << "Usage: " << argv[0] << " 1 <start-number>\n";
exit(0);
}
cout << "Successor:\n";
cout << "----------\n";
Stream *s = new Successor(new BigInt(argv[2]));
for (int i=0 ; i < 10 ; i++) {
cout << s->first << " ";
s = s->rest();
}
cout << "\n";
} else if (atoi(argv[1]) == 2) {  // Successor and Times
if (argc < 4) {
cout << "Usage: " << argv[0] << " 2 <start-number> <multiplier>\n";
exit(0);
}
cout << "Successor and Times:\n";
cout << "--------------------\n";
Stream *s = new Times(new BigInt(argv[3]),
new Successor(new BigInt(argv[2])));
for (int i=0 ; i < 10 ; i++) {
cout << s->first << " ";
s = s->rest();
}
cout << "\n";
} else if (atoi(argv[1]) == 3) {  // Hamming sequence
if (argc < 3) {
cout << "Usage: " << argv[0] << " 3 <prime-number> ...\n";
exit(0);
}
cout << "Hamming sequence given primes 3,5,11:\n";
cout << "-------------------------------------\n";
BigInt **primes = new BigInt*[argc-2];
for (int i=2 ; i < argc ; i++) primes[i-2] = new BigInt(argv[i]);

Stream *s = new Hamming(new Array(primes, argc-2));
for (int i=0 ; i < 10000 ; i++, s = s->rest())
cout << i+1 << ": " << s->first << "\n";
cout << "\n\n";
} else {
cout << "Usage: " << argv[0] << " <1|2|3> <number> ...\n";
exit(0);
}
}
```