count number of times a character appears in an array? - c++

i've been thinking for a long time and havent got anywhere with the program. i dont know where to begin. The assignment requires use of single function main and only iostream library to be used.
the task is to Declare a char array of 10 elements. Take input from user. Determine if array contains any values more than 1 times . do not show the characters that appears 1 time only.
Sample output:
a 2
b 4
..
a an b are characters. and 2 and 4 represents number of times they appear in the array B.
i tried to use nested loop to compare a character with all the character in array and incrementing a counter each time similer character id sound but unexpected results are occuring.
Here is the code
#include <iostream>
using namespace std;
void main()
{
char ara[10];
int counter=0;
cout<<"Enter 10 characters in an array\n";
for ( int a=0; a<10; a++)
cin>>ara[a];
for(int i=0; i<10; i++)
{
for(int j=i+1; j<10; j++)
{
if(ara[i] == ara[j])
{
counter++;
cout<<ara[i]<<"\t"<<counter<<endl;
}
}
}
}

Algorithm 2: std::map
Declare / define the container:
std::map<char, unsigned int> frequency;
Open the file
read a letter.
find the letter: frequency.find(letter)
If letter exists, increment the frequency: frequency[letter]++;
If letter no exists, insert into frequency: frequency[letter] = 1;
After all letters processed, iterate through the map displaying the letter and its frequency.

Here's one possible way you can solve this. I'm not giving you full code; it's considered bad to just give full implementations for other people's homework.
First, fill a new array with only unique characters. For example, if the input was:
abacdadeff
The new array should only have:
abcdef
That is, every character should appear only once in it. Do not forget to \0-terminate it, so that you can tell where it ends (since it can have a length smaller than 10).
Then create a new array of int (or unsigned, since you can't have negative occurrences) values that holds the frequency of occurence of every character from the unique array in the original input array. Every value should be initially 1. You can achieve this with a declaration like:
unsigned freq[10] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
Now, iterate over the unique array and every time you find the current character in the original input array, increment the corresponding element of the frequencies array. So at the end, for the above input, you would have:
a b c d e f (unique array)
3 1 1 2 1 2 (frequencies array)
And you're done. You can now tell how many times each characters appears in the input.

Here, I'll tell you what you should do and you code it yourself:
include headers ( stdio libs )
define main ( entry point for your app )
declare input array A[amount_of_chars_in_your_input]
write output requesting user to input
collect input
now the main part:
declare another array of unsigned shorts B[]
declare counter int i = 0
declare counter int j = 0
loop through the array A[] ( in other words i < sizeof ( A ); or a[i] != '\0' )
now loop as much as there is different letters in the array A
store the amount of letters in the B[]
print it out
Now there are some tricks applying this but you can handle it

Try this:
unsigned int frequency[26] = {0};
char letters[10];
Algorithm:
Open file / read a letter.
Search for the letters array for the new letter.
If the new letter exists: increment the frequency slot for that
letter: frequency[toupper(new_letter) - 'A']++;
If the new letter is missing, add to array and set frequency to 1.
After all letters are processed, print out the frequency array:
`cout << 'A' + index << ": " << frequency[index] << endl;

Related

Does anyone know how to solve problems on variable length arrays?

Input Format
The first line contains two space-separated integers denoting the respective values of (the number of variable-length arrays) and (the number of queries).
Each line of the subsequent lines contains a space-separated sequence in the format k a[i]0 a[i]1 … a[i]k-1 describing the -element array located at.
Each of the subsequent lines contains two space-separated integers describing the respective values of (an index in the array ) and (an index in the array referenced by ) for a query.
Output Format-
For each pair of and values (i.e., for each query), print a single integer denoting the element located at an index of the array referenced by. There should be a total of lines of output.
Sample Input
2 2
3 1 5 4
5 1 2 8 9 3
0 1
1 3
Sample Output
5
9
Somebody has solved this problem by -
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n,q; //n number of variable lenght arrays
// q no of queries asked
cin >>n >>q;
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j];
for (int y=0;y<j;y++)
cin>>Vectors[i][y];
}
int q1,q2;
for (int i=0;i<q;i++)
{
cin >>q1 >> q2;
cout<<Vectors[q1][q2]<<endl;
}
return 0;
}
Can somebody explain me this code? Or if anyone has a better approach to solve this problem. Then please explain it in detail.
This shouldn't be hard to understand, that code is basically initializing dynamic 2D array at run time then inserting values to the 2D array and then accessing it by giving index:
int ** Vectors = new int *[n];//no of length of var. arrays
int j;
for (int i=0;i<n;i++)
{
cin>>j;
Vectors[i] = new int [j]; // initialzing inner array.. consider it as 2D array with n rows and j columns
for (int y=0;y<j;y++)
cin>>Vectors[i][y]; // insert element at specified index
}
cout<<Vectors[q1][q2]<<endl; // access element from 2D array
What you might want to use is a Matrix class.
Using
vector<vector<int>>
should do it.
Alternatively the snipet code should be refactored into a Matrix class with a constructor and a destructor.
The example you give present a memory leak since the allocated memory is not freed.

I am trying my sorting method, which works well with data with no repeates entries, but am getting random numbers in place of repeated numbers?

I have been trying a sorting method in which I subtract each number stored in an array by other elements in the same array. Then, I saw a pattern that the number of differences which come to be negative, is the rank or position of element in the Sorted one. But, things go wrong when I am using repeated entries.
My basic method is :
Take every element of the SampleArray.
subtract it from every element of the SampleArray
check if the difference comes to be negative.
if it is then, increase a variable called counter.
And use this counter as the position of element in sorted array.
For example: lets take (5,2,6,4)
first take 5, subtract it from each of the numbers which will give results (0,-3,1,-1), so counter will become 2, which will be the index of 5 in the sorted Array. And repeat it for each of the elements.
for 5, counter will be 2.
for 2, counter will be 0.
for 6, counter will be 3.
for 4, counter will be 1.
And hence the sorted Array will be {2,4,5,6}.
First, see the code :
#include <iostream>
using namespace std;
void sorting(int myArray[], int sizeofArray);
int main()
{
int checkArray[] = {5,4,2,20,12,13,8,6,10,15,0}; //my sample Arry
int sized;
sized=sizeof checkArray/sizeof(int);//to know the size
cout << sized << endl;
sorting(checkArray, sized);
}
void sorting(int myArray[], int sizeofArray)
{
int tempArray[sizeofArray];
for (int i=0; i<sizeofArray; i++)
{
int counter=0;
for (int j=0;j<sizeofArray; j++ )
{
int checkNum = myArray[j]-myArray[i];
if (checkNum<0)
counter++; //to know the numbers of negatives
else
counter+=0;
}
tempArray[counter]=myArray[i];
}
for (int x=0;x<sizeofArray; x++)
{
cout << tempArray[x] << " " ;
}
}
Now, if we run this program with entries with no repetitions then, it sorts out the array, But if we use repeated entries like
int checkArray[] = {8,2,4,4,6}
the tempArray gets its first element as 2 as counter will be zero.
the tempArray gets its second element as 4 as counter will be 1.
but, the tempArray can't get its third one as counter will be still 1, and thus prints some randomNo in place of this. (here the things go wrong).
Can you please suggest a method to solve this?
This is an odd way of writing insertion sort, https://en.wikipedia.org/wiki/Insertion_sort
I would assume you can change your condition to:
if (checkNum<0 || (checkNum==0 && j<i))
But I would suggest using a proper sorting routine instead
The idea is to separate duplicates by saying that if the values are the same we sort according to their order in the sequence; as if the sequence was a pair of the value and the sequence number (0, 1, 2, 3, 4, 5, ...).
The issue here is that for any 2 equally sized numbers the nested loop will return the same counter value. Thus for such a counter value tempArray[counter + 1] will never be initialized.
The way to solve this would be to maintain a vector<bool> denoting what each position had been written and write to the next valid position if that is the case.
But supporting a second vector is just going to make your O(n2) code slower. Consider using sort instead:
sort(begin(checkArray), end(checkArray))

Incorrect output using array as counter

I'm trying to teach myself programming by attempting problems from codeabbey.com.
I'm not getting the correct output on this question.
Question:
Here is an array of length M with numbers in the range 1 ... N, where N is less than or equal to 20. You are to go through it and count how many times each number is encountered.
Input data contain M and N in the first line.
The second (rather long) line will contain M numbers separated by spaces.
Answer should contain exactly N values, separated by spaces. First should give amount of 1-s, second - amount of 2-s and so on.
Data input:
10 3
1 2 3 2 3 1 1 1 1 3
Correct Output:
5 2 3
My Output:
7 3 4
You can check here
My Code:
#include <iostream>
using namespace std;
int main()
{
int arrayLength,range,a;
cin>>arrayLength>>range;
int array[20];
array[20]={0};
for(int i=0; i<arrayLength; i++)
{
cin>>a;
++array[a-1];
}
for(a=0; a<range; a++)
{
cout<<array[a]<<" ";
}
return 0;
}
There aren't any error messages or warnings. Also, if you have any suggestions for improving the code, that'd be nice.
int array[20];
array[20]={0};
is wrong, since it leave the array un-initialized and tries to initialize the 21st element (which is undefined behaviour btw, since your array has only 20 elements, remember that indexing starts from 0). Use
int array[20] = {0}; // this will initialize all elements to 0
and your code will work as expected. See here for more details regarding aggregate initialization in C++.
array[20]={0}; initializes the 21st element(non-existing) to 0.
So you have to use int array[20] = {0}; which will initialize all 20 elements to zero.
Also from your code, you are not storing the elements to an array. You are just incrementing the corresponding count when an input is read. If so, what is the need of initializing an array to max limit. Just declare the array as you need it. In your case,
int array[range] = {0};
It will initialize an array of three (range =3 here) elements.

how to find consecutive numbers in a sequence

im trying to a write a program that accepts 10 random integers and checks whether there are three consecutive numbers in the sequence or not.The consecutive numbers can be in ascending or descending order.
here are some examples to help you understand better:
order. Examples:
2 9 8 3 20 15 9 6 4 24
Yes, 2 3 and 4 are consecutive
16 21 3 8 20 6 3 9 12 19
Yes, 21 20 and 19 are consecutive
I can't figure out whats wrong with my code.
here is my code so far:
#include <iostream>
using namespace std;
int main()
{
int a[10];
int i,n;
int count=0;
cout << "Enter 10 numbers between 1 and 25" << endl;
for (i = 0; i < 10; i++)
{ cin >> a[i];
}
for (n=0; n<10; n++)
{
for (i=1; i<10; i++)
{
if (a[i]==a[n]+1)
{cout<<endl<<a[i]<<endl;
count++;}
}
}
}
Your code is currently O(N2), and to get it to work it'll be O(N3).
I'd rather use an algorithm that's O(N) instead.
Given that you only care about 25 values, you can start with a 32-bit word, and set the bit in that word corresponding to each number that was entered (e.g., word |= 1 << input_number;).
Then take a value of 7 (which is three consecutive bits set) and test it at the possible bit positions in that word to see if you have three consecutive bits set anywhere in the word. If so, the position at which they're set tells you what three consecutive numbers you've found. If not, then there weren't three consecutive numbers in the input.
for (int i=0; i<32-3; i++) {
int mask = 7 << i;
if (word & mask == mask)
// three consecutive bits set -> input contained i, i+1 and i+2
}
Your logic is wrong. What your current code does is that it checks if there are any two consecutive integers. To check for three, you should introduce another nested loop. This would make the time complexity O(n^3).
Another possible way to check this is to first sort the array, and then check for consecutive elements. This would make the running time O(nlogn). You can use the inbuilt sort function for sorting.
The algorithm needs to be reworked. As it is, what you are doing is saying:
For each array element x
See if another array element is x+1
print out the array element that is x+1
Stick in more cout lines to see what is going on, like
if (a[i]==a[n]+1)
{cout<<endl<<a[n]<<","<<a[i]<<endl;
count++;}
A possible, although slow, algorithm would be
For each array element x
See if another array element is x+1
See if another array element is x+2
print out x, x+1, and x+2

C++ Check the length of an array with Zeros and nulls

I have an int array, of let say... 1000 elements. The user enters 128 and it fills the array as 821. Before it gets said, let me say, it has to be backwards for simplicity of other functions. To get the length I use
int count = 0;
for (int i = 0; array1[i] != '\0'; ++i)
{
count++;
}
this works great. Until they enter a number with a 0 in it, such as 0, or 100.
The array is filled as 001, but the test stops it immediately since 0 is equal to '\0'
I cant use sizeof(array1)/sizeof(*array1) because then when I go to print the array I get tons of zeros followed by the number. It does print correctly, but its not what I want.
Any solutions?
I think a better way is to fill the whole array with an invalid value (such as -1) before you use it. By saying "invalid" it can be anything except 0-9 according to your description.
memset(array1, -1, sizeof(array1));
// doing things
And why don't you just save the numbers as characters since they are from user input? Just use '0' instead of '\0' to represent the zero, so you don't have the issue. You even can use strlen to get the length directly if you guarantee that there is always '\0' in the end of array:
// array size is 1001 instead of 1000 to reserve a '\0' in the end
char array1[1001] = {'8', '2', '1'}
size_t count = strlen(array1);
What you need to do is convert the digits to corresponding characters.
Lets say, you have 1230. In your array you actually store 1 + '0', 2 + '0', 3 + '0' and '0'. '0' being the ASCII value of the key that has 0 printed on it.
That way you will never confuse '0' with \0.
you could dertermine the amount of digits your number has and then dynamically allocate the array with the calculated size.
There are two approaches I can think of:
You increase the size after each element the user inputs
You mark the end with a number the user will never input
For example on the first case:
char array1[1000];
int count = 0;
while(!the_end)
{
std::cin >> array1[count++]
}
// From now, every time you add elements to the array, increase the "size" variable
std::cout << "Size: " << count << std::endl;
For the second case, there are some methods, but what I think which would be the best for you, is by fulfilling the array with the invalid value before you start to get the input from the user:
char array1[1000] = {-1};
// Start getting the input...
int count = 0;
for(int i = 0; array1[i] != -1; ++i)
{
count++;
}
std::cout << "Size: " << count << std::endl;
Note: if you're stuck on this, then your code probably has some design flaws. For the design to be good, you'd be using the first approach I suggested and not trying to find the size afterwards. Or better, you could be using std::vector as suggested in the commentaries, or at least could have some type of "tracking" for the elements you input to the array.