Priority Que help Counting Letters

Pages: 12
Hello, I'm fairly new to c++ and would like some help with this code that I'm writing.
It's supposed to print out, the number of times each letter is presented, like; T=1 and t=3 as an example, I'm trying to figure out a way to make it go in order, from largest number to smallest number, also I'd like for it to not print out each letter every time, one time is enough haha. So, please please I need some help. Thank you :) Also I'm really new to programming so if you could explain why, that would be amazing too :P.
Here's what I have so far;
#include "stdafx.h"
#include <iostream>
#include <queue>
#include <string>
#include <vector>
using namespace std;

/*struct Node
{
int freq;
char val;
Node *left;
Node *right;
Node()
{
left = NULL;
right = NULL;
freq = 0;
val = 0;
}
};*/

int main()
{

char ht[] = { "There foes four near times." };

char tmp='_';
int freq=0;



for (int i = 0; i < 27; i++)
{
tmp = ht[i];
freq = 1;
for (int j = i+1; j < 27; j++)
{
if (ht[i] == ht[j])
{
freq++;
}//if
}//j
cout << tmp<< '=';
cout << freq << endl;


};//i



return 0;
}


{
public char myChar;
public int myFrequency;
public HuffNode myLeft, myRight;
}
Last edited on
closed account (48T7M4Gy)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>

using namespace std;

int main()
{
   char ht[] = { "There foes four near times." };
   int length = sizeof(ht) / sizeof(char); // <----
   char tmp = '_';
   int freq = 0;
	
   for (int i = 0; i < length; i++)
   {
      tmp = ht[i];
      freq = 1;
      for (int j = i + 1; j < 27; j++)
      {
          if (ht[i] == ht[j])
         {
             freq++;
         }//if
      }//j
      cout << tmp << '=';
      cout << freq << endl;
	
    };//i
        return 0;
}
closed account (48T7M4Gy)
What you need to do is take lines 23 and 24 out of the loop to stop them being printed so voluminously.

You need to create a vector or array for each letter of the alphabet (Hint: ASCII coding makes this very easy).
So when the loop hits an 'a' the corresponding storage is incremented by 1.

When all characters are accounted for print out separately via a separate loop all the stored values.

(Hint 2: ASCI 'A' is the number 65 so add 1 to frequency[65]
http://www.cplusplus.com/doc/ascii/?kw=ASCII )
So, how would I do that. Sorry for the probably dumb question, Im really new :/. But why don't I need the Cout's in Line's; 23 and 24? Don't I need those? How would I go about creating a vector for every letter in the sentence? Thank you for the help by the way :).
Last edited on
closed account (48T7M4Gy)
"I'm really new. So how would I do that?"
Gee where have I heard that style of question before? Just read what I wrote and give it a go. show us what you did and we'll try and help.

Gee where have you read that before?
What if I did something along the lines of;
#include <iostream>
#include <sstream>
using namespace std;

int main() {
string letters;
cout << "'T","h","e ","r","e";
getline(cin, letters);
cout << letters << endl;
}

I was looking around, what do you think about using push_back?
Im a little confused about the ASCI, but will keep studying it.
closed account (48T7M4Gy)
Hint: int alphabet[26] = {0}; to start with as the storage I referred to, and use the fact that a char is an integer.

Your code attempt indicates to me you have not read what I wrote earlier. You are going off on an unnecessary tangent. The code you already have breaks the input down into individual characters.
Last edited on
Sorry, totally confused myself. Ok Ill look into this and see if I can figure it out.
closed account (48T7M4Gy)
Excellent!
no need for pq use sort algorithm
So, apparently I cannot use the ASCII; it's considered too easy :(.
Here's what I've written so far, I am trying to turn the code into Binary, but I've run into some errors. Let me know what you guys think.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <iostream>
#include <queue>
#include <map>
#include <algorithm>

using namespace std;

const int UniqueSymbols = 1 << CHAR_BIT;
const char* SampleString = "Testing";

typedef std::vector<bool> HuffCode;
typedef std::map<char, HuffCode> HuffCodeMap;

class ZNode
{
public:
	const int j;

	virtual ~ZNode() {}

protected:
	ZNode(int j) : j(j) {}
};

class InternalNode : public ZNode
{
public:
	ZNode *const left;
	ZNode *const right;

	InternalNode(ZNode* c0, ZNode* c1) : ZNode(c0->j + c1->j), left(c0), right(c1) {}
	~InternalNode()
	{
		delete left;
		delete right;
	}
};

class LeafNode : public ZNode
{
public:
	const char c;

	LeafNode(int j, char c) : ZNode(j), c(c) {}
};

struct NodeCmp
{
	bool operator()(const ZNode* lhs, const ZNode* rhs) const { return lhs->j > rhs->j; }
};

ZNode* BuildTree(const int(&frequencies)[UniqueSymbols])
{
	std::priority_queue<ZNode*, std::vector<ZNode*>, NodeCmp> trees;

	for (int i = 0; i < UniqueSymbols; ++i)
	{
		if (frequencies[i] != 0)
			trees.push(new LeafNode(frequencies[i], (char)i));
	}
	while (trees.size() > 1)
	{
		ZNode* childR = trees.top();
		trees.pop();

		ZNode* childL = trees.top();
		trees.pop();

		ZNode* parent = new InternalNode(childR, childL);
		trees.push(parent);
	}
	return trees.top();
}

void GenerateCodes(const ZNode* node, const HuffCode& prefix, HuffCodeMap& outCodes)
{
	if (const LeafNode* lf = dynamic_cast<const LeafNode*>(node))
	{
		outCodes[lf->c] = prefix;
	}
	else if (const InternalNode* in = dynamic_cast<const InternalNode*>(node))
	{
		HuffCode leftPrefix = prefix;
		leftPrefix.push_back(false);
		GenerateCodes(in->left, leftPrefix, outCodes);

		HuffCode rightPrefix = prefix;
		rightPrefix.push_back(true);
		GenerateCodes(in->right, rightPrefix, outCodes);
	}

int main()

int frequencies[UniqueSymbols] = { 0 };
const char* ptr = SampleString;
while (*ptr != '\0')
++frequencies[*ptr++];

ZNode* root = BuildTree(frequencies);

HuffCodeMap codes;
GenerateCodes(root, HuffCode(), codes);
delete root;

for (HuffCodeMap::const_iterator it = codes.begin(); it != codes.end(); ++it)
{
	std::cout << it->first << " ";
	std::copy(it->second.begin(), it->second.end(),
		std::ostream_iterator<bool>(std::cout));
	std::cout << std::endl;
}

{
	char ht[] = { "There foes four near times." };
	int length = sizeof(ht) / sizeof(char); // <----
	char tmp = '_';
	int freq = 0;

	for (int i = 0; i < length; i++)
	{
		tmp = ht[i];
		freq = 1;
		for (int j = i + 1; j < 27; j++)
		{
			if (ht[i] == ht[j])
			{
				freq++;
			}//if
		}//j
		cout << tmp << '=';
		cout << freq << endl;

	};//i
	return 0;
}


I was told using Huffman Coding would be good to use to make it into Binary.
Thanks for the help :)
closed account (48T7M4Gy)
I think the simplest way to address this is your current code won't compile until you fix up your errors.

line 8 is producing an error - << etc is causing it
line 94 is producing an error but it is because you don't have an opening brace at the end of line 93

there are probably more compiler errors to be fixed
Ok I fixed the small errors but It's not printing out my phrase in Binary code. Any ideas why? It's only printing out all random letters in the alphabet and thier Binary.
closed account (48T7M4Gy)
Have you got code that compiles?
Yeah but it's only printing out the first lettering, being F and then a row of Binary.
closed account (48T7M4Gy)
Any ideas why?
Have you got code that compiles?
Yeah

Well that clears that up!
Oh I really thought I posted the new code D:
I re wrote it, it seems easier this way. Tell me what you think.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include<queue>
#include<vector>
#include<algorithm>
#include <iostream>;
using namespace std;

class huffman
{

	struct node
	{
		char elem;
		int freqN;
		node * left;
		node * right;
	};



public:
	node *t;
	vector<node *> my_list;


	void build_list()
	{

		char huffman[] = { 'T', 'h', 'e', ' ', 't', 'o', ' ', 'r', 'a', 'n', ' ', 'r', 'o', 'c', 'k', 'e', 't', '.' };

		char letter = '_';

		int frequency = 0;

		bool check = true;

		for (int i = 0; i < 18; i++) 
		{



			for (int c = 0; c < i; c++) 
			{

				if (huffman[c] == huffman[i])
				{

					check = false;

				}

				if (check == false)
				{

					i++;
					while (huffman[i] == huffman[i - 1] || huffman[i] == huffman[i - 2])
					{

						i++;

					}

					check = true;

				}

				if (i <= 17)
				{



				}


			}

			letter = huffman[i]; 
			frequency = 1; 

			for (int j = i + 1; j < 18; j++)
			{


				if (huffman[i] == huffman[j]) 
				{
					frequency++; 

				}
			}

			cout << letter; cout << frequency << endl;

			t = new node;
			t->elem = letter;
			t->freqN = frequency;
			t->left = NULL;
			t->right = NULL;
			//-----------allocate the memory
			my_list.push_back(t);

		}

	}

	
	void print_list()
	{
		//node *ss;
		while (my_list.size() > 0)
		{
			char ss = my_list.back()->elem;
			int aa = my_list.front()->freqN;
			cout << ss << "" << aa;
			my_list.pop_back();
		}


	}

	huffman::huffman()
	{
	}

	huffman::~huffman()
	{
	}
};

int _tmain(int argc, _TCHAR* argv[]){

	huffman obj;
	obj.build_list();
	obj.print_list();


}
Last edited on
closed account (48T7M4Gy)
I don't know what your plans are for your program but, so far this is what I see (we'll leave what I think to later):
1. after <iostream> has to go
2. t_char etc is a pain, use char, the sky's not going to fall in despite waht the taliban might say.
3. better still, can't it be main()? That's what I,m looking at in my test. If you don't need the parameters then scrap them.
closed account (48T7M4Gy)
and put return 0; at the end (or some other int)
closed account (48T7M4Gy)
A few small changes that might be of interest.

But I think your's looks good. Cheers :)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <vector>
#include <iostream>

using namespace std;

class huffman
{
	struct node
	{
		char elem;
		int freqN;
		node * left;
		node * right;
	};

public:
	node *t;
	vector<node *> my_list;

	void build_list()
	{
		char huffman[] = "The quick brown fox jumps over the lazy dog";
		char letter = '_';
		int frequency = 0;

		bool check = true;

		int size = sizeof(huffman) / sizeof(char) - 1;

		for (int i = 0; i < size; i++)
		{
			for (int c = 0; c < i; c++)
			{
				if (huffman[c] == huffman[i])
					check = false;

				if (check == false)
				{
					i++;
					while (huffman[i] == huffman[i - 1] || huffman[i] == huffman[i - 2])
						i++;
					check = true;
				}

				if (i <= 17) {}
			}

			letter = huffman[i];
			frequency = 1;

			for (int j = i + 1; j < 18; j++)
			{
				if (huffman[i] == huffman[j])
					frequency++;
			}

			cout << letter; cout << frequency << endl;

			t = new node;
			t->elem = letter;
			t->freqN = frequency;
			t->left = NULL;
			t->right = NULL;
			//-----------allocate the memory
			my_list.push_back(t);
		}
	}

	void print_list()
	{
		//node *ss;
		while (my_list.size() > 0)
		{
			char ss = my_list.back()->elem;
			int aa = my_list.front()->freqN;
			cout << ss << "" << aa;
			my_list.pop_back();
		}
		cout << endl;
	}

	huffman(){}

	~huffman(){}
};

int main()
{
	huffman obj;
	obj.build_list();
	obj.print_list();
	
	return 0;
}
Last edited on
Pages: 12