Copying array indexes to another array - c++

I am a beginner in C++ trying to figure out how I could solve the following exercise:
Given an array of whole numbers, count how many times one element is present in the array. After that, copy the array indexes to another array and print them. In other words, apart from printing the amount of times one chosen number is present in the array, I need to print the indexes of that chosen number from a second array (by copying them from the first array to the second).
Example:
int myvect [ ] = {10, 42, 20, 10, 13, 20}
Assuming I choose the number 10 using the keyboard. The program will have to output the following:
The chosen element is present: 2 times
The chosen element is present in the following indexes: 0, 3
I don't have problems outputting how many times one element is present. I just added a counter and it works perfectly. My problem is i don't know how to select those specific indexes, copy them to another array to finally print them.
Here is my code:
#include <iostream>
#define max 20
using namespace std;
int main()
{
int vett[max],n,i,num,app=0,cont=0,pos[50];
bool flag;
cout<<"inserisci un numero massimo elementi del vettore:";
cin>>n;
cout<<endl;
flag=false;
for (i=0; i<n; i++) {
cout<<"inserisci elementi del vettore:";
cin>>vett[i];
}
cout<<"inserisci elemento da trovare: ";
cin>>num;
cout<<endl;
i=0;
for (i=0; i<n; i++) {
if(vett[i]==num) {
cout<<"trovato"<<endl;
flag=true;
app=i;
cont++;
}
}
if(flag==true) {
cout<<"elemento trovato"<<endl;
if(cont>1) {
cout<<"l'elemento e' stato trovato "<< cont<<" volte"<<endl;
}
else if(cont==1) {
cout<<"l'elemento e' stato trovato "<< cont<<" volta"<<endl;
}
cout<<"Posizioni Salvate: "<<vett[i]<<endl;
}
else {
cout<<"elemento non trovato"<<endl;
}
system("pause");
return 0;
}
As you can see, I did define a second array in the beginning. I don't know how to use it to solve the problem
Any help will be appreciated. Thank you very much

I usually make modifications to the OP's code as a part of my answer, but I cannot understand your language in the code. So, I will give you the basic algorithm to help you solve your problem keeping the structure of your attempted code intact.
Let the array of required indexes be int indexes[max];
Let k be the current index of indexes to keep track of the insertion
Each time you find the element in your i loop, insert the value of i into indexes[k] and increment the value of k
Demo:
int indexes[max], k = 0;
for (int i = 0; i < n; ++i)
{
if (vett[i] == num)
{
// Do the Part 1 of your task
// This line will help you achieve the Part 2:
indexes[k++] = i;
}
}

You could use std::find
An example:
std::array<int, 5> data{10, 2, 3, 4, 10};
std::vector<int> indices;
int num = 10;
auto it = data.begin();
while ((it = std::find(it, data.end(), num))!= data.end())
{
indices.push_back(std::distance(data.begin(), it));
it++;
}
indices then contains the indices of the elements that match your search criterion.

In your loop:
for (i=0; i<n; i++) {
if(vett[i]==num) {
cout<<"trovato"<<endl;
flag=true;
app=i;
cont++;
}
}
You are trying to test if number at index i is your desired number. Well, what about storing that i index into another array everytime the condition is true.
// create array with the same size as input array
int found_indexes[max];
size_t current_position = 0;
// now your loop
for (i=0; i<n; i++) {
if(vett[i]==num) {
cout<<"trovato"<<endl;
flag=true;
app=i;
cont++;
// save index at current position and advance by one after saving
found_indexes[current_position++] = i;
}
}
// at the end print all indexes from array
// this is done by printing all values until we meet with current_position index
if (current_position == 0)
cout << "No indexes found.\n";
else
{
// Printing spaces somewhat nicely.
cout << found_indexes[0];
for(size_t i = 1; i < current_position; i++)
cout << ' ' << found_indexes[i];
}

I think you are trying to do that
#include <iostream>
#include <stdlib.h>
#define max 20
using namespace std;
int main()
{
int vett[max],n,i,num,cont=0,pos[50];
bool flag;
cout<<"Enter how many numbers:";
cin>>n;
cout<<endl;
flag=false;
for (i=0; i<n; i++)
{
cout<<"Enter "<<i+1<<" Element:";
cin>>vett[i];
}
cout<<"\nEnter what to find: ";
cin>>num;
cout<<endl;
for (i=0; i<n; i++)
{
if(vett[i]==num)
{
flag=true;
pos[cont++]=i;
}
}
if(flag==true)
{
cout<<"The chosen element is present:"<<cont<<" times"<<endl;
cout<<"The chosen element is present in the following indexes:";
for(i=0;i<cont;i++)
cout<<pos[i]<<","; //it prints a number followed by a comma.
cout<<endl;
}
else
cout<<"No Element"<<endl;
system("pause");
return 0;
}
Output:
Enter how many numbers:6
Enter 1 Element:10
Enter 2 Element:42
Enter 3 Element:20
Enter 4 Element:10
Enter 5 Element:13
Enter 6 Element:20
Enter what to find: 10
The chosen element is present:2 times
The chosen element is present in the following indexes:0,3,
Press any key to continue . . .
Process returned 0 (0x0) execution time : 29.955 s
Press any key to continue.
Edit:
if you did not want comma after last element use this
for(i=0;i<cont;i++)
{
cout<<pos[i];
if((i+1)!=cont)
cout<<",";
}

I think that the appropriate data structure here is std::map<int, std::set<int> > which is the hash map representing the value mapped to the set of indices where this value is present. The size of set tells you the number of occurrences of the particular value. Simple implementation might look like this:
std::map<int, std::set<int> > values_to_indices;
for (int i = 0; i < input_array.size(); i++)
{
values_to_indices[input_array[i]].insert(i); // we can use operator[] because when element is not yet in the map, std::set will be default constructed
}
for (auto elem : values_to_indices)
{
std::cout << "element: " << elem.first << " is repeated " << elem.second.size() << " times\n";
// here you can also print std set of indices of that element
}
This doc explains that using operator[] on the map constructs the element if it was not present before. The values in the set are guaranteed to be unique because we iterate once from 0 to input array size.
=== EDIT ===
As suggested in the comment, instead of int you might use size_t as a type representing indices:
std::map<int, std::set<size_t> > values_to_indices;
for (size_t i = 0; i < input_array.size(); i++)
{
values_to_indices[input_array[i]].insert(i);
}
Just be aware of unsigned integer underflow if later you plan to do some things with that indices.

Related

Is there a way to count the number of ocurrences of each element of a string array?

I have the following code that does exactly what I want. The problem is that I need the sample array to compare the strings and keep the count. Is there a way to count the number of occurrences of each string on any array without a sample?
For a little bit more context, the initial problem was to read data from a .txt file including vehicles information, like:
Volkswagen Jetta
Ford Focus
Volkswagen Jetta
And count the number of vehicles of each brand. Keep in mind that this is from an introductory course for programming, and we don't know how to use vectors or maps.
#include <iostream>
#include <string>
using namespace std;
using std::string;
#define MAX 20
int main(){
int counter[MAX];
string arr[MAX]={"ABC","AOE","ADC","ABC","ADC","ADC"};
string sample[MAX]={"ABC", "AOE", "ADC"};
for(int i=0; i<=MAX; i++){
counter[i]=0;
}
for(int i=0; i<MAX;i++){
for(int j=0; j<MAX; j++){
if (sample[i]==arr[j]){
counter[i]++;
}
}
}
for(int i=0; i<3;i++){
cout<< sample[i] << "=" << counter[i]<<endl;
}
return 0;
}
All you are expected to do is keep a list (an array will do) of brand names, and an array of counts for each name:
std::string brand_names[100];
int counts[100]; // number of times each element of brand_names[] was read from file
int num_items = 0;
Each time you read a brand name from file, try to find it in the array of strings. If found, just add one to the count at the same index. If not found, add it to the end of the brand_names[] array, add 1 to the end of the counts[] array, and increment num_items.
You do not need anything more than a simple loop for this:
an outer loop to read the next brand name from file
an inner loop to try to find the brand name in the list
If you want to solve this problem without knowing the initial values of the sample array:
Create an empty sample array. When you see new elements add them to this array.
Use a variable sample_size to keep track how many samples have been seen. Below is a simple example which doesn't use std::vector or dynamic allocation.
int main()
{
std::string arr[MAX] = { "ABC","AOE","ADC","ABC","ADC","ADC" };
std::string sample[MAX];
int sample_size = 0;
int counter[MAX] = { 0 };
for (int i = 0; i < MAX; i++)
{
if (arr[i].empty()) break;
bool sample_found = false;
for (int j = 0; j < sample_size; j++)
if (arr[i] == sample[j])
{
sample_found = true;
counter[j]++;
break;
}
if (!sample_found)
{
sample[sample_size] = arr[i];
counter[sample_size]++;
sample_size++;
}
}
for (int i = 0; i < sample_size; i++)
cout << sample[i] << "=" << counter[i] << std::endl;
return 0;
}

Find indexes of duplicated (repeated) numbers in an array

I have 2 arrays in which arr1 stores a number (the salary) and arr2 stores a string (the employee's name). Since the two arrays are linked, I cannot change the order of arr1, or sort it. I am looking for a more efficient way to solve the problem which is to find if there are any duplicates in the array. It might be more than one duplicate, but if no are found it should print "no duplicates found".
int count = 0;
for (int i = 0;i<arr_size ;i++)
{
for (int j = 0; j < arr_size && i != j; j++)
{
if (arr[i] == arr[j])
{
cout << arr2[i] << " " << arr1[i] << endl;
cout << arr2[j] << " " << arr1[j] << endl;
count ++;
}
}
}
if (count == 0)
{
cout << "No employee have same salaries"<<endl;
}
I don't want to use such an inefficient way to solve the problem. Is there any better suggestion? Thanks for the help :)
And the question also requires me to print out all the duplicated employee and salaries pair
You can use an unordered_set which has an average constant time insertion and retrieval:
#include <unordered_set>
// ...set up arr
int count = 0;
std::unordered_set<int> salaries;
for (int i = 0; i < arr_size; i ++) {
if (salaries.count(arr[i]) > 0) {
// it's a duplicate
}
salaries.insert(arr[i]);
}
// do more stuff
Create a Haspmap using unordered_map and store salaries and index of the salary .
Now if the same salary exist then increase count
You can reduce the time complexity of the algorithm to O(n) by using unordered_set on the expense of using additional space.
#include<unordered_set>
int main(){
// Initialise your arrays
unordered_set<string> unique;
bool flag = false;
for(int i=0;i<arr_size;i++){
// Since unordered_set does not support pair out of the box, we will convert the pair to string and use as a key
string key = to_string(arr1[i]) + arr2[i];
// Check if key exists in set
if(unique.find(key)!=unique.end())
unique.push(key);
else{
// mark that duplicate found
flag = true;
// Print the duplicate
cout<<"Duplicate: "+to_string(arr1[i])+"-"+arr2[i]<<endl;
}
}
if(!flag){
cout<<"No duplicates found"<<endl;
} else cout<<"Duplicates found"<<endl;
return 0;
}

Count Number of Digits in an array (c++)

let's say I have an array
arr[5]={5,2,3,2,5} and i wrote following program for it
#include <iostream>
using namespace std;
int main()
{
int n;
cout<<"Enter Length of Elements= ";
cin>>n;
int arr[50];
for(int i=0;i<n;i++)
{
cout<<"Enter Number=";
cin>>arr[i];
}
for(int i=0;i<n;i++)
{
int countNum=1;
for(int j=i+1;j<n;j++)
{
if(arr[i]==arr[j])
{
if(i>0)
{
int countNum2=0;
for(int k=0;k>i;k++)
{
//bool repeat=false;
if(arr[i]==arr[k])
{
//repeat=false;
}
else
{
countNum2++;
}
}
if(countNum2==i)
{
countNum++;
}
}
else
{
countNum++;
}
}
else
{
for(int k=0;k<i;k++)
{
if(arr[k]==arr[i])
{
}
else
{
countNum=1;
}
}
}
}
cout<<arr[i]<<" has appeared "<<countNum<< "Times"<<endl;
}
return 0;
}
but why I am getting
5 has appeared 2 Times
2 has appeared 1 Time
3 has appeared 1 Time
2 has appeared 1 Time
5 has appeared 1 Time
instead of
5 has appeared 2 Times
2 has appeared 2 Times
3 has appeared 1 Times
so how to fix my program
help!
That's what you exactly need (amount of each number in array):
// we'll store amounts of numbers like key-value pairs.
// std::map does exactly what we need. As a key we will
// store a number and as a key - corresponding counter
std::map<int, size_t> digit_count;
// it is simpler for explanation to have our
// array on stack, because it helps us not to
// think about some language-specific things
// like memory management and focus on the algorithm
const int arr[] = { 5, 2, 3, 2, 5 };
// iterate over each element in array
for(const auto elem : arr)
{
// operator[] of std::map creates default-initialized
// element at the first access. For size_t it is 0.
// So we can just add 1 at each appearance of the number
// in array to its counter.
digit_count[elem] += 1;
}
// Now just iterate over all elements in our container and
// print result. std::map's iterator is a pair, which first element
// is a key (our number in array) and second element is a value
// (corresponding counter)
for(const auto& elem : digit_count) {
std::cout << elem.first << " appeared " << elem.second << " times\n";
}
https://godbolt.org/z/_WTvAm
Well, let's write some basic code, but firstly let's consider an algorithm (it is not the most efficient one, but more understandable):
The most understandable way is to iterate over each number in array and increment some corresponding counter by one. Let it be a pair with the first element to be our number and the second to be a counter:
struct pair {
int number;
int counter;
};
Other part of algorithm will be explained in code below
// Say that we know an array length and its elements
size_t length = // user-defined, typed by user, etc.
int* arr = new int[length];
// input elements
// There will be no more, than length different numbers
pair* counts = new pair[length];
// Initialize counters
// Each counte will be initialized to zero explicitly (but it is not obligatory,
// because in struct each field is initialized by it's default
// value implicitly)
for(size_t i = 0; i < length; i++) {
counts[i].counter = 0;
}
// Iterate over each element in array: arr[i]
for(size_t i = 0; i < length; i++)
{
// Now we need to find corresponding counter in our counters.
size_t index_of_counter = 0;
// Corresponding counter is the first counter with 0 value (in case when
// we meet current number for the first time) or the counter that have
// the corresponding value equal to arr[i]
for(; counts[index_of_counter].counter != 0 && counts[index_of_counter].number != arr[i]; index_of_counter++)
; // Do nothing here - index_of_counter is incrementing in loop-statement
// We found an index of our counter
// Let's assign the value (it will assign a value
// to newly initialized pair and won't change anything
// in case of already existing value).
counts[index_of_counter].number = arr[i];
// Increment our counter. It'll became 1 in case of new
// counter, because of zero assigned to it a bit above.
counts[index_of_counter].counter += 1;
}
// Now let's iterate over all counters until we reach the first
// containing zero (it means that this counter and all after it are not used)
for(size_t i = 0; i < length && counts[i].counter > 0; i++) {
std::cout << counts[i].number << " appeared " << counts[i].counter << " times\n";
}
// correctly delete dynamically allocated memory
delete[] counts;
delete[] arr;
https://godbolt.org/z/hN33Pn
Moreover it is exactly the same solution like with std::map (the same idea), so I hope it can help you to understand, how the first solution works inside
The problem with your code is that you don't remove the duplicates or assign an array which effectively stores the count of each unique element in your array.
Also the use of so many loops is completely unnecessary.
You just need to implement two loops, outer one going through all the elements and the inner one checking for dupes first (using an array to check frequency/occurence status) and counting appearance of each element seperately with a variable used as a counter.
Set a counter array (with the corresponding size of your taken array) with a specific value (say zero) and change that value when same element occurs while traversing the array, to trigger not to count for that value again.
Then transfer the count value from the counter variable to the counter array (the one which we set and which distinguishes between duplicates) each time the inner loop finishes iterating over the whole array. (i.e. place it after the values are counted)
With a little bit of modification, your code will work as you would want it to:
#include <iostream>
using namespace std;
int main()
{
int n;
cout<<"Enter Length of Elements = ";
cin>>n;
int arr[50];
for(int i=0;i<n;i++)
{
cout<<"Enter Number = ";
cin>>arr[i];
}
int counter[50];
for(int i=0; i<n; i++)
counter[i]=0;
// Our counter variable, but counts will be transferred to count[] later on:
int tempcount;
for(int i=0; i<n; i++)
{ // Each distinct element occurs once atleast so initialize to one:
tempcount = 1;
for(int j=i+1; j<n; j++)
{
// If dupe is found:
if(arr[i]==arr[j])
{
tempcount++;
// Ensuring not to count frequency of same element again:
counter[j] = 1;
}
}
// If occurence of current element is not counted before:
if(counter[i] != 1)
counter[i] = tempcount;
}
for(int i=0; i<n; i++)
{
if(counter[i] != 0)
printf("%d has appeared %d times.\n", arr[i], counter[i]);
}
return 0;
}
I used a variable tempcount to count occurence of each element and a zero-initialized array count to get the dupes checked (by setting it to 1 for a duplicate entry, and not counting it if it qualifies as 1) first. Then I transferred the counted occurence values to counter[] from tempcount at each outer loop iteration. (for all the unique elements)

Zeros when printing out an array which is declared on the heap. C++

I want to make a program that lets the user insert some numbers to the array and the print it out afterwards. Problem is when I try to do that (lets say the size of my array is 100) then:
What it should do: Inserted- 1,2,3,4,5 -> should print 1,2,3,4,5
But instead it prints -> 1,2,3,4,5,0,0,0,0,0,0, .... up to the size of my array.
Is there any way I can get rid of those zeros?
Code:
int SIZE = 100;
int main()
{
int *numbers;
numbers = new int[SIZE];
int numOfElements = 0;
int i = 0;
cout << "Insert some numbers (! to end): ";
while((numbers[i] != '!') && (i < SIZE)){
cin >> numbers[i];
numOfElements++;
i++;
}
for(int i = 0; i < numOfElements; i++){
cout << numbers[i] << " ";
}
delete [] numbers;
return 0;
}
You increase numOfElements no matter what the user types. Simply do this instead:
if(isdigit(numbers[i]))
{
numOfElements++;
}
This will count digits, not characters. It may of course still be too crude if you want the user to input numbers with multiple digits.
Get numOfElements entered from user beforehand. For example
int main() {
int n;
cin >> n;
int * a = new int[n];
for (int i = 0; i < n; ++i)
cin >> a[i];
for (int i = 0; i < n; ++i)
cout << a[i] << endl;
delete[] a;
}
Input
4
10 20 30 40
Output
10 20 30 40
Since you declared array size, all indices will be zeros.
User input changes only the first x indices from zero to the value entered (left to right).
All other indices remains 0.
If you want to output only integers different from 0 (user input) you can do something like that:
for(auto x : numbers){
if(x!=0)cout<<x<<" ";
}
You can use vector and push_back the values from user input to get exactly the
size you need without zeros, then you can use this simple code:
for(auto x : vectorName)cout<<x<<" ";
Previous solutions using a counter is fine.
otherwise you can (in a while... or similar)
read values in a "temp" var
add if temp non zero
exit loop if counter >= SIZE-1 (you reach max slots)
increment counter
when You will print, form 0 to counter, you will get only non zero values.

C++ How do I print elements of an array but leave out repeats? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
My assignment is to have the user type in how many elements are in an array then enter integer number to be put in the array. I then have to sort through the array and find the largest number and print out the elements of the array but if there is a repeat then only print that number one time. I also have to print out the number of times each element in the array occurs. For example if the user types in that there is 5 elements then enters 2, 1, 2, -3, 2 then it should print -3 with 1 count, 1 with 1 count, and 2 with 3 count. So far I have it so it will print out the elements and delete the repeats but I cant get it to print out the correct number of occurrences for each element. This is my code so far.
void findRepeats(int numbers[], int num)
{
int instances = 0;
cout << "Number" << " " << "Occurrences" << endl;
for (int i = 0; i < num; i++)
{
bool matching = false;
instances = 1;
for (int j = 0; (j < i); j++)
{
if (numbers[i] == numbers[j])
{
instances++;
matching = true;
}
}
if (!matching)
cout << numbers[i] << " " << instances << endl;
}
}
Right now its saying all number occur only 1 time
One approach that you could take, is to sort the numbers first, before deciding how many duplicates there are. That way, it will be easier to avoid printing results for the same number more than once, and you also won't have to loop through the entire array for each number.
void findRepeats(int numbers[], int num);
int main(){
int array[] = {2, 1, 2, -3, 2};
findRepeats(array,5);
}
void findRepeats(int numbers[], int num) {
//sort the array first
std::sort(numbers, numbers + num);
int last = numbers[0];
int count = 0;
cout << "Number of Occurrences\n";
for (int i = 0; i < num; i++) {
if (last == numbers[i]) {
++count;
} else {
cout << last << " " << count << '\n';
count = 1;
}
last = numbers[i];
}
if (count > 0) {
cout << last << " " << count << '\n';
}
}
prints:
Number of Occurrences
-3 1
1 1
2 3
I would use map or unordered_map to, well..., map the integer to the number of it's occurrences. It makes things quite simple, as it basically takes care of the duplicates for you.
#include <iostream>
#include <unordered_map>
using namespace std;
void reportCounts(const int numbers[], const size_t size){
unordered_map<int, unsigned int> counts;
//unfortunately range-for here would a little PIA to apply
//or at least I don't know convenient way
for(size_t i = 0; i < size; ++i) {
counts [ numbers[i] ]++; //increase `count` of i-th number
}
//print results
for(auto count : counts ){
cout << count.first << ' ' << count.second << endl;
}
}
int main(){
int array[] = {2, 1, 2, -3, 2};
reportCounts(array,5);
}
Since it's an assignment I am leaving figuring out the c++ shenaningans to you and http://cppreference.com. Keywords are map, map::iterator and maybe associative container which map in an example of.
I do understand that it might be harder to understand than plain implementation of some algorithm, but this is probably close to optimal solution in modern c++, and putting effort into understanding how and why it works should prove beneficial. One should notice how much less of code had to be written, and no algorithm had to be invented. Less implementation time, less place to make mistakes, less testing.
Search your array. For every integer, either record it, or increment your count of it. Repeat process till done, then print it.
How? you say? One approach would be to use parallel arrays to store the unique integers found, and another to store the count of integers. Then print the unique integers and their counts.
Code example of simple search algorithm:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
void print(vector<int> valueArray,vector<int> countArray){
for(unsigned int i = 0; i < valueArray.size(); ++i){
cout<<"Found value "<<valueArray[i]<<": "<<countArray[i]<<" times."<<endl;
}
}
void findRepeats(vector<int> testArray,vector<int> &valueArray,vector<int> &countArray){
for(unsigned int i = 0; i < testArray.size(); ++i){
if(valueArray.size() == 0){
valueArray.push_back(testArray[i]);
countArray.push_back(1);
}else{
bool newEntry = true;
for(unsigned int j = 0; j < valueArray.size(); ++j){
if(testArray[i] == valueArray [j]){
countArray[j]++;
newEntry = false;
break;//After find, break out of j-for-loop to save time.
}
}
if(newEntry){
valueArray.push_back(testArray[i]);
countArray.push_back(1);
}
}
}
}
int main(){
vector<int> testArray; //To store all integers entered.
vector<int> valueArray; //To store non-copied integers, dynamically, else handle it yourself.
vector<int> countArray; //To count increments of numbers found, dynamically, else handle it yourself.
testArray = {0,2,5,4,1,3,6,2,5,9,8,7,4,1,2,6,5,4,8,3,2,1,5,8,6,9,8,7,4,4,5,6,8,2,1,3,0,0,1,2,0,2,5,8};//Dummy data.
findRepeats(testArray,valueArray,countArray);//Function to find statistics on testArray.
cout<<"\nPrinting found characters, and number of times found: "<<endl;
print(valueArray,countArray);
return 0;
}
Output would be something like:
Printing found characters, and number of times found:
Found value 0: 4 times.
Found value 2: 7 times.
Found value 5: 6 times.
Found value 4: 5 times.
Found value 1: 5 times.
Found value 3: 3 times.
Found value 6: 4 times.
Found value 9: 2 times.
Found value 8: 6 times.
Found value 7: 2 times.
In the above, I used vectors for simplicity, but if you must do so with c-style arrays, one approach would be to create all three vectors the same size, and keep one integer counter for number of indices used in the valueArray and countArray; they should share, since they're related 1 to 1. And you will need to pass it to the findRepeats function as well.
Having arrays of the same size will ensure that your values and counts will fit in your array; this would happen if every number entered was unique.