Implementation was a bit tough.
main.cpp
#include <iostream>
using namespace std;
#include <fstream>
#include "TLList.h"
void digits(int&,int*);
void printDigit(int*);
int main()
{
int n;
//input method: istream
cout << "How many integers do you want to enter? ";
cin >> n;
int *num = new int[n];
cout << "Please enter the integers:" << endl;
for(int i=0; i<n; i++)
cin >> num[i];
int digit[10];
TLList<int> T;
for(int i=0; i<n; i++) {
digits(num[i],digit);
T.add(num[i],digit);
}
T.print();
return 0;
}
void digits(int& num, int* digit)
{
for(int i=0; i<10; i++) digit[i] = 0;
if(num == 0) {
digit[0] = 1;
}
else {
int powoften = 1, i=1;
while(num>powoften*10) {
powoften*= 10;
i++;
}
int prod, j=0, numc=num;
while(j<i) {
prod = numc / powoften;
digit[prod]++;
numc = numc - prod * powoften;
powoften/= 10;
j++;
}
}
}
void printDigit(int* digit)
{
for(int i=0; i<10; i++)
cout << digit[i];
}
- Defined an array "digit" of 10 integers: this array is used to store the count of every digit for a particular integer
- Implemented a function "digits" to break down the number into separate digits and store digit counts in the "digit" array
- Implemented a function "printDigit" to print the "digit" array
Link.h
// Singly-linked list node
template <class T>
class Link
{
public:
T num; // Value for this node
Link *down; // Pointer to next node in list
Link( T numval ); // 1st Constructor
};
// 1st Constructor
template <class T>
Link<T>::Link( T numval )
{
num = numval;
down = NULL;
}
For some reason that I couldn't figure out, setting the pointers to NULL without using a class template resulted in an error. Therefore I kept the class template even though I am strictly using the "int" datatype.
This is a Link class to be used for composition in another class "TLList". Has data and a pointer to another Link.
triLink.h
#include "Link.h"
// Tri-linked list header node
template <class T>
class triLink
{
public:
T digit[10]; // Value for this node
triLink *next; // Pointer to next node in list
Link<T> *down;
Link<T> *downtail;
triLink( T* digitval );
triLink();
};
// 1st Constructor
template <class T>
triLink<T>::triLink( T* digitval )
{
for(int i=0; i<10; i++)
digit[i]= digitval[i];
next = NULL;
down = downtail = NULL;
}
//2nd constructor
template <class T>
triLink<T>::triLink()
{
next = NULL;
down = downtail = NULL;
}
So I modified the standard Link a bit. This link has two pointers, a "next" pointer to another triLink and a "down" pointer to a normal Link. Reason for this is that I plan to use these triLinks as header links, each containing a "digit" array and pointing "down" to a linked list of integers that have that same digit count.
TLList.h
#include "triLink.h"
template <class T>
class TLList
{
private:
triLink<T> *head;
triLink<T> *fence;
public:
TLList();
void add(int,int*);
void print();
friend bool digitComp(int*,int*);
friend void printDigit(int*);
};
template <class T>
TLList<T>::TLList()
{
fence = head = new triLink<int>;
}
template <class T>
void TLList<T>::add(int num, int* digit)
{
if(head->next == NULL) {
fence = head->next = new triLink<int>(digit);
fence->downtail = fence->down = new Link<int>(num);
return;
}
fence = head;
while(fence->next != NULL) {
fence = fence->next;
if(digitComp(digit,fence->digit)) {
fence->downtail = fence->downtail->down = new Link<int>(num);
return;
}
}
fence = fence->next = new triLink<int>(digit);
fence->downtail = fence->down = new Link<int>(num);
}
template <class T>
void TLList<T>::print()
{
fence = head;
Link<T>* fence2;
while(fence->next != NULL) {
fence = fence->next;
printDigit(fence->digit);
cout << ": ";
fence2 = fence->down;
while(fence2 != NULL) {
cout << fence2->num << " ";
fence2 = fence2->down;
}
cout << endl;
}
}
bool digitComp(int* digit1, int* digit2)
{
for(int i=0; i<10; i++)
if(digit1[i] != digit2[i]) return false;
return true;
}
- If there is no data yet, create a new triLink, store the "digit" array, then go "down" and create a new Link and store the integer there.
- If there is data, then use a friend function "DigitComp" to compare the "digit" arrays present in triLinks to the "digit" array for the integer to be added to the TLList.
- If DigitComp returns TRUE, then insert the integer at the pointer "downtail" of the corresponding triLink.
- If DigitComp returns FALSE, then create a new triLink, then insert the integer at the pointer downtail = down of the new triLink.
-Rinse and repeat.
-After the integers are added, call a print function that traverses the triLinks one by one, then goes "down" and prints the integers for each corresponding triLink.
Input:
6 123 321 432 443 213 234
Output:
0111000000: 123 321 213
0011100000: 432 234
0001200000: 443
One good idea I had after I finished this code and posted was to have the triLinks sorted, making searching and comparing faster and organizing the groups of integers. Also, sorting the integers themselves might be a good idea but would be more costly than simply appending the integer at the end of each linked list.