Counting number of letters in array

Pages: 12
So I need to write a function called duplicate to find the number of times a user entered a given string within the bounds they gave. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  Enter 10 words:
  aa
  bb
  cc
  cc
  cc
  aa
  aa
  bb
  bb
  cc
  Enter a lower bound and an upper bound:
  0 8
  You entered 'aa' 3 times.
  You entered 'bb' 3 times.
  You entered 'cc' 3 times.

Here is the function I have declared. I am trying to do this in a basic way not using code like cin.get or anything like that. I believe I need to use a for loop but I am not sure how.
1
2
3
void duplicate(const string source[], int low, int high) {
	int counter=0
        for(int i=low; i<=high; i++) {
what do the lower and upper bounds represent? length?
Last edited on
Yes, the lower and upper bounds the user enters represents the part of the array you will be counting. here is how far I have gotten but this isn't quite working

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void duplicate(const string source[], int low, int high) {
	int counter=1;
	int j=low;
	int i=low;
	int s=0;
	for(int i=low; i<=high; i++) {
		while(j<=high) 
		{
			if(source[i]==source[high-s])
			{
				counter++;
			}
			j++;
			s++;
		}
		cout<<"You entered '"<<i<<"' "<<counter<<" times.\n";
	}
}
Sorry, I think this will be a lot easier if you include all the code so I can figure out what is actually being passed in and what the user is inputting as I see a few things that could be potentially problematic depending on the input.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void duplicate(const string source [], int low, int high)
{
	int counter = 1;
	int j = low;
	int i = low;
	int s = 0;
	for (i = low; i <= high; i++) // (int i = low; i <= high; i++) change this to take out the redeclaration of i
		// this is also problematic as input may cause you to run off the end of the array.
		// when iterating arrays, generally you will start at 0 and iterate over to 1 < length of array.
	{
		while (j <= high)
		{
			if (source [i] == source [high - s])
			{
				counter++;
			}
			j++;
			s++;
		}
		cout << "You entered '" << i << "' " << counter << " times.\n";
	}
}


The input is also a string array which means each element is going to be another array of chars. Thus the high and low need to take this into account for each word. A two dimensional array of type char may indeed be a better choice but I cannot determine this without the whole code.

Okay so I am trying to only count the CONSECUTIVE letters which is where I think I partly went wrong. Here is my whole code.

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
#include <iostream>
#include <string>

using namespace std;
void duplicate(const string source[], int low, int high);
int main()
{
    string source[10];
    int low;
    int high;
    int i;
    cout<<"Enter 10 words:\n";
    for(i=0;i<=9;i++) {
        cin>>source[i];
    }
    cout<<"Enter lower and upper bound:\n";
    cin>>low;
    cin>>high;
    duplicate(source,low,high);
    return 0;
}

void duplicate(const string source[], int low, int high) {
	int counter=0;
	int j=low;
	int i=low;
	
	int s=0;
	for(int i=low; i<=high; i++) {
		while(j<=high) 
		{
			if(source[i]==source[i+1])
			{
				counter++;
			}
			j++;
			s++;
		}
		cout<<"You entered '"<<source[i]<<"' "<<counter<<" times.\n";
		j=low;
		s=0;
		counter=0;
	}
}
Here is my revised duplicate function. When I test it it works perfect except for the last test where it just stops working and doesn't print out anything.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void duplicate(const string source[], int low, int high) {
	int counter=1;
	int i;
	for(i=low; i<=high+1; i++) {
		counter=1;
	    while(source[i]==source[i+1]) 
		{
			counter++;
			i++;
			
		}
		cout<<"'"<<source[i]<<"'"<<" appeared "<<(counter)<<" times.\n";
		
	}
}
Here is code I have modified to produce what I think you are after.
I have removed the high and low input as I don't understand why you need them. Also when dealing with arrays giving your control of these parameters to the user could make them read off the end of the array, if they don't understand the limits.

If this is not what you are after or you have questions about why I put a particular thing in the code or removed something you had, please ask.


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
#include <iostream>
#include <string>

using namespace std;

void duplicate(const string source []);

int main()
{
	string source [10];
	int i;
	cout << "Enter 10 words:\n";
	for (i = 0; i < 10; i++)
	{
		cin >> source [i];
	}
	duplicate(source);
	return 0;
}


void duplicate(const string source [])
{
	int counter = 0;

	for (int i = 0; i < 10 ; i++)
	{
		counter = 0;

		for (int j = 0; j < 10; j++)
		{
			if (source [i].length() == source [j].length()) // strings are not equal in length jump to
				                                        // end of block and increment j
			{
				if (( source [i] == source [j] ) && ( j < i ))
				{
					// exit inner loop so i will be incremented as string has already been counted
					break;
				}
				else if (source [i] == source [j])
				{
					counter++;
				}
			}
		}
		
		if (counter != 0)
		{
			cout << "'" << source [i] << "'" << " appeared " << ( counter ) << " times.\n";
		}
	}
}

1
2
3
for(i=low; i<=high+1; i++) {
		counter=1;
	    while(source[i]==source[i+1]) 


On a side not I found these lines problematic as you are reading off the end of the array and you only seem to be counting strings that are next to each other in the array.

1
2
3

for (i=low; i<=high+1; i++)


For clarification, declaring an array of size ten, the elements are
0,1,2,3,4,5,6,7,8,9

if low = 0 (the start of the array)
if high = 9 (the most you have allocated space for)

then the line above reads
1
2
3
4
5
 for (i = 0; 0 <= 10; i++)
// looping up to and including 10, loops more times than they have array 
// elements. 11 times assuming that input was as above. if user put another 
// number higher than your array maximum index you will be accessing
// memory far beyond what you have allocated. 


1
2
3

while(source[i]==source[i+1])


if I = 9 the maximum array index you have specified then

source[9] == source [10] // <-- source 10 does not exist thus accessing memory you haven't allocated
Last edited on
you know, for arrays with pre-determined sizes, sizeof will return the size of the array...

http://en.cppreference.com/w/cpp/language/sizeof
you know, for arrays with pre-determined sizes, sizeof will return the size of the array...


Yes it will determine the size of the array in bytes, not elements.
Last edited on
No, it returns the number of elements. If you're using a dynamic array, then it will return the number of bytes the pointer consumes (which is completely unrelated to how much memory the entire array actually takes up)

With that, CodeGoggles, I will refer you to the reference book:

http://en.cppreference.com/w/cpp/language/sizeof

It isn't that difficult to figure out, then:

1
2
int lots_of_nums[20] = { /* ... */};
cout<< "Number of elements: "<< (sizeof(lots_of_nums) / sizeof(int))<< '\n';


I did a small test to prove it:

1
2
3
4
5
6
int testarr[20];
for(int x = 0; x < 20; x++) testarr[x] = x;
cout<< "sizeof int: "<< sizeof(int)<< '\n';
cout<< "sizeof testarr: "<< sizeof(testarr)<< '\n';
cout<< "sizeof(testarr) / sizeof(int) = "<< (sizeof(testarr) / sizeof(int))<< '\n';
cout<< "worked: "<< (((sizeof(testarr) / sizeof(int)) == 20) ? "true" : "false")<< '\n';


Output:

sizeof int: 4
sizeof testarr: 80
sizeof(testarr) / sizeof(int) = 20
worked: true


Well, there you have it: so, you can find the number of elements in a finite-size array using sizeof().
Last edited on
Yes it will determine the size of the array in bytes, not elements.


My post was for clarification purposes to the thread poster, as sizeof() does indeed return size in bytes. And yes you can use the sizeof() the data type to divide with the sizeof() the array. That was not disputed.

If you came to this thread to prove a point to me don't bother. I'm simply here to help the poster and you are just confusing matters. He is using a string type for one. Which is a variable data size and array in itself. Thus it is better for me to use the array syntax to point to the required element as I am not making assumptions on what they do or do not know. Otherwise I would need to confuse him further by making him study pointers before he gets an answer.

So thanks for the above post, but it was indeed not required.

No, it returns the number of elements. If you're using a dynamic array, then it will return the number of bytes the pointer consumes (which is completely unrelated to how much memory the entire array actually takes up)


And you are wrong it does return the size of the array in bytes because the array is made up of pointers thus the array will return the size of the combined pointers in the array. And those pointers point to the start of other arrays. And on top of that it can only be interpreted as the size of element if the arithmetic actually makes the calculation.
Last edited on
With that, IWishIKnew please take you misleading and inaccurate statements like :


you know, for arrays with pre-determined sizes, sizeof will return the size of the array...


then it will return the number of bytes the pointer consumes (which is completely unrelated to how much memory the entire array actually takes up)


elsewhere.

Last edited on
I tested what I said: it is fact. You perform the tests yourself. If you can;t handle a little common sense to put the pieces together, then please get confused and fail the course: we don't need slackers programming.

CodeGoggles said:
He is using a string type for one. Which is a variable data size and array in itself.

LOL. you don't use Sizeof for that then, you use string's member function: .size(), which will return the number of characters in the string. Also, it doesn't use an array, it uses a pointer. Also known as a "dynamic array", but it's just a pointer to the first element.
Last edited on
LOL you are mad and now you are getting confused, did you even read it properly? I wonder. BURN THE TROLL.
Last edited on
Also, it doesn't use an array, it uses a pointer. Also known as a "dynamic array", but it's just a pointer to the first element.


Way to contradict yourself. An array is just a consecutive allocation of memory.

A string is a consecutive allocation of chars.

Do you see a pattern?

EDIT: and just for your clarification a pointer holds a memory address and is certainly not a dynamic array.

then please get confused and fail the course


Did you even take a course? I wouldn't like to see your results if you did.
std::cout << 'F';
Last edited on
I wonder if you two could stop taking potshots at each other?

Way to contradict yourself. An array is just a consecutive allocation of memory.

Presumably you meant to say an array is a contiguous area of memory in which individual elements are consecutively stored.

If we're going to be pedantic, also be precise.


A string is a consecutive allocation of chars.

Prior to C++11 it was not required to be.


Do you see a pattern?

Yes. Confrontational posting. I'd like to see an end to that particular pattern.
I wonder if you two could stop taking potshots at each other?


I do like how that was all directed at me :).

especially after

If you can;t handle a little common sense to put the pieces together, then please get confused and fail the course: we don't need slackers programming.


Confrontational much?
CodeGoggles wrote:
I do like how that was all directed at me :).


For clarity:
The second and third comments were addressed only to you. The first and last were directed to you and IWishIKnew as one might infer from the fact that I mentioned "you two" in the first, and the pattern mentioned in the last clearly encompasses more than just your posts.
@cire
I do realise that but the fact you used quotes only from me infers a bias. Not to mention:

If we're going to be pedantic, also be precise.


Let me ask, who do you think was more precise? In the explanations and arguments.


by IWishIKnew
Also, it doesn't use an array, it uses a pointer. Also known as a "dynamic array", but it's just a pointer to the first element.


That is not only not precise, its blatantly wrong.
But forgive me for being pedantic.
Last edited on
Pages: 12