How to check that all random array elements are different - c++

I'm trying to pass random integers (between 0 and 11) to the Numbers[] array, but i have to make sure that all 10 of its elements are different. I've tried to pass the numbers first in the array, and then check if there are any numbers that are equal but its not working this way. Here's my code:
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
int Numbers[10];
srand( time(NULL) );
for (int i = 0; i < 10; i++ )
{
Numbers[i] = rand() % 12; // First, the integers are passed
to the array (They must be between 0 and 11)
cout << Numbers[i] << endl; // and printed to the screen
}
cout << endl << endl;
for (int u = 0; u < 10; u++)
{
if(Numbers[u] == Numbers[u - 1]) // If there are two equal
numbers
{
switch (Numbers[u]) // One of them is incremented (But that
causes problems as well because it can lead to another pair of equals)
{
case 11: // In case one of them is 11
Numbers[u]--;
break;
default:
Numbers[u]++;
break;
}
}
cout << Numbers[u] << endl;
}
return 0;
}
Halp!

Just use std::vector, std::iota and std::shuffle:
std::vector<int> v( 12 );
std::iota( v.begin(), v.end(), 0 ); // initialize with values 0..11
std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()}); // make em random
v.resize( 10 ); // remove extra elements
and you do not need to validate that all elements are unique

What I understood from your question that you are trying to read random numbers till all 10 numbers are different. Have a look on code below:
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <bitset>
using namespace std;
int main()
{
int Numbers[10] ;
srand(time(NULL));
//Keep flag with all the bits '0' initially
bitset<12> flags;
flags.reset();
// keep taking input till all bits are not '1'
int i = 0;
do
{
int in_num = rand() % 12;
// check if the bit at position "in_num" is 0
if (!flags[in_num])
{
Numbers[i++] = in_num;
flags.set(in_num);// set the bit 1
}
} while (i < 10);
for (int u = 0; u < 10; u++)
{
cout << endl << Numbers[u];
}
return 0;
}

Related

how to array in c++

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<double> numbers(input_number);
cout << "Enter numbers from 0 to 50: " << endl;
for (int i = 0; i < input_number; ++i) {
cin >> numbers[i];
}
unordered_map<int, int> freq;
for (int i = 0; i < numbers.size(); i++) {
freq[numbers[i]]++;
}
for (int i = 0; i < numbers.size(); i++) {
cout << freq[numbers[i]];
}
return 0;
}
When the use inputs numbers, for example 1,1,1,2 the output should be "1" because it is the most frequent number but the output here became "3,3,3,1" How to solve this problem?
You are most of the way there. Your frequencies are all stored, and you just need to search through the unordered_map now to find the item that has the largest value. Since you're already using <algorithm> you can leverage std::max_element to help:
#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <vector>
int main()
{
std::vector<int> numbers = { 1, 2, 3, 2, 3, 2, 2 };
std::unordered_map<int, int> freq;
for (int n : numbers) ++freq[n];
if (!freq.empty())
{
auto it = std::max_element(freq.begin(), freq.end(),
[](const auto& a, const auto& b) { return a.second < b.second; });
std::cout << "Most frequent is " << it->first << "\n";
}
}
Output:
Most frequent is 2
Here, a custom comparison function is supplied that tests only the frequency part of the element (otherwise the default behavior will compare the full key/value pairs which will result in finding the largest number).
Note that because the map is unordered, there won't be a predictable outcome for tie-breakers (where more than one number is the most frequent). If you need to handle that in a more predictable way, you'll need to adjust the comparison function or possibly just loop over the container yourself if it requires additional work.
One option for tie-breaking is to choose the lowest number. That could be achieved by modifying the comparison to:
return std::make_pair(a.second, b.first) < std::make_pair(b.second, a.first);
The problem is that you just output all the values in map. In a naive implementation you have to iterate through map and register the maximum value and it's frequency:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
int main()
{
using std::cin, std::cout, std::endl;
using std::vector, std::unordered_map;
int input_number = 0, max_freq = 0, max_val = 0;
cout << "How many numbers you want to input: " << endl;
cin >> input_number;
// Making input double may creates questions
vector<int> numbers(input_number);
cout << "Enter numbers from 0 to 50: " << endl;
for (int i = 0; i < input_number; ++i) {
cin >> numbers[i];
}
unordered_map<int, int> freq;
for (int i = 0; i < numbers.size(); i++) {
freq[numbers[i]]++;
}
// iterating over the map and finding max value
for (auto val : freq) {
if( val.second > max_freq) {
max_val = val.first;
max_freq = val.second;
}
}
cout << max_val;
return 0;
}
Standard maps do store values as pairs of key and value (std::pair). This can be done in easier way: you can do that right while inputting the numbers.
for (int i = 0; i < numbers.size(); i++) {
int val = numbers[i];
int curfreq = ++freq[val];
if (curfreq > max_freq) {
max_val = val;
max_freq = curfreq;
}
}
cout << max_val;
Your array freq has to proper values in it. But your logic in the print out is wrong. You are printing the numbers twice. I guess you want to print all the numbers from 0 to 50.
cout << freq[i]
Then you see which entries have values or not. Then add some logic (which doesn't exist in your code) to pick the proper value. Like the biggest count..

Copying elements from one array to another c++

I have looked and looked and am still lost on how to copy or get elements from an array and put them into new arrays ( divide and conquer is the goal).
I have an array that generates 100 random numbers. I need to split the random numbers into 4 smaller arrays obviously containing 25 elements and not have any duplicates. I have read about using pointers, but honestly I don't understand why even use a pointer. Why do I care about another variables address?
I don't know how to do this. Here is my code so far:
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
// Seed the random number generator
srand(time(NULL));
//create an array to store our random numbers in
int Orignumbers[100] = {};
// Arrays for the divide and conquer method
int NumbersA [25] = {};
int NumbersB [25] = {};
int NumbersC [25] = {};
int NumbersD [25] = {};
//Generate the random numbers
for(int i =0; i < 100; i++)
{
int SomeRandomNumber = rand() % 100 + 1;
// Throw random number into the array
Orignumbers[i] = SomeRandomNumber;
}
// for(int i = 0; i < ) started the for loop for the other arrays, this is where I am stuck!!
// Print out the random numbers
for(int i = 0; i < 100; i++)
{
cout << Orignumbers[i] << " , ";
}
}
"divide and conquer" is rather easy; when copying into NumbersA and so forth, you just have to access your Originnumbers with a proper offset, i.e. 0, 25, 50, and 75:
for(int i = 0; i < 25; i++) {
NumbersA[i] = Orignumbers[i];
NumbersB[i] = Orignumbers[i+25];
NumbersC[i] = Orignumbers[i+50];
NumbersD[i] = Orignumbers[i+75];
}
The thing about "no duplicates" is a little bit more tricky. Generating a random sequence of unique numbers is usually solved through "shuffling". Standard library provides functions for that:
#include <random>
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
std::random_device rd;
std::mt19937 g(rd());
int Orignumbers[100];
//Generate the random numbers without duplicates
for(int i =0; i < 100; i++) {
Orignumbers[i] = i+1;
}
std::shuffle(Orignumbers, Orignumbers+100, g);
// Arrays for the divide and conquer method
int NumbersA [25] = {};
int NumbersB [25] = {};
int NumbersC [25] = {};
int NumbersD [25] = {};
for(int i = 0; i < 25; i++) {
NumbersA[i] = Orignumbers[i];
NumbersB[i] = Orignumbers[i+25];
NumbersC[i] = Orignumbers[i+50];
NumbersD[i] = Orignumbers[i+75];
}
// Print out the random numbers
for(int i = 0; i < 100; i++)
{
cout << Orignumbers[i] << " , ";
}
}
Problem:
The program can't be guaranteed to have no duplicate value as the rand() function can generate any random sequence and that may include the decimal value of 99 for 99 times though probability is very low but chances are.
Example:
for(loop=0; loop<9; loop++)
printf("%d", Rand()%10);
If looped for 10 times, it may result some values like:
Output: 6,1,1,1,2,9,1,3,6,9
Compiled Successfully:
Hence, no certainity that values won't repeat
Possibly Solution:
There could be a solution where you can place the values in OriginalArray and compare the rand() generate values against the OriginalArray values.
For first iteration of loop, you can directly assign value to OriginalArray then from 2nd iteration of loop you've to compare rand() value against OriginalArray but insertion time consumption may be higher than O(NN) as rand() function may repeat values.
Possibly Solution:
#include <iostream>
#include <time.h>
#include <stdlib.h>
using namespace std;
int main()
{
int Orignumbers[100] ;
int NumbersA [25] ,
NumbersB [25] ,
NumbersC [25] ,
NumbersD [25] ;
srand(time(NULL));
for(int i =0; i < 100; i++){
Orignumbers[i] = rand() % 100+1;
for(int loop=0; loop<i; loop++) {
if(Orignumber[loop] == Orignumber[i] ) {
i--;
break;
}
}
}
//Placing in four different arrays thats maybe needed.
for(int i = 0; i <25; i++ ) {
NumbersA[i] = Orignumbers[i];
NumbersB[i] = Orignumbers[i+25];
NumbersC[i] = Orignumbers[i+50];
NumbersD[i] = Orignumbers[i+75];
}
for(int i = 0; i < 99; i++)
cout << Orignumbers[i] << " , ";
}
As you tagged your question with C++ then forget about old-fashion arrays, let's do it C++ style.
You want to split your array into 4 arrays and they should not have duplicate numbers, so you can't have a number 5 times in your original array, because then surely one of your 4 arrays will have a duplicate one, So here is the way I propose to do it :
#include <set>
#include <ctime>
#include <vector>
int main() {
std::multiset<int> allNums;
std::srand(unsigned(std::time(0)));
for (int i = 0; i < 100; ++i) {
int SomeRandomNumber = std::rand() % 100 + 1;
if (allNums.count(SomeRandomNumber) < 4) {
allNums.insert(SomeRandomNumber);
}
else {
--i;
}
}
std::vector<int> vOne, vTwo, vThree, vFour;
for (auto iter = allNums.begin(); iter != allNums.end(); ++iter) {
vOne.push_back(*iter);
++iter;
vTwo.push_back(*iter);
++iter;
vThree.push_back(*iter);
++iter;
vFour.push_back(*iter);
}
system("pause");
return 0;
}
EDIT : As you mentioned in the comments, you just want to find a number in an array, so how about this :
for (int i = 0; i < 100; ++i) {
if (origArray[i] == magicNumber) {
cout << "magicNumber founded in index " << i << "of origArray";
}
}
On some situations, even on C++, the use of arrays might be preferable than vectors, for example, when dealing with multidimensional arrays (2D, 3D, etc) that needs to be continuous and ordered on the memory. (e.g. later access by other applications or faster exporting to file using formats such as HDF5.)
Like Jesper pointed out, you may use Copy and I would add MemCopy to copy the content of an array or memory block into another.
Don't underestimate the importance of pointers, they may solve your problem without the need doing any copy. A bit like Stephan solution but without the need of the index variable "i", just having the pointers initialized at different places on the array. For a very large number of elements, such strategy will save some relevant processing time.

Finding the highest number in an array of length 5

This should be really simple, but I'm used to higher level languages and am missing something. I'm just trying to make sure the input is five numbers long, and then find the highest number. Unfortunately, something goes wrong in that second part.
#include <iostream>
#include <string>
bool isFiveDigits(int num) {
if (std::to_string(num).length() == 5) {
return true;
} else {
return false;
}
}
int highestInArr(int *nums) {
int highest = nums[0];
for (int i = 1; i < sizeof(nums); i++) {
int temp = nums[i];
if (temp > highest) {
highest = temp;
}
}
return highest;
}
int main() {
using namespace std;
int num;
int nums [5];
cout << "Enter a five digit number!\n";
cin >> num;
if (!isFiveDigits(num)) {
cout << "Not five digits, can you even count?";
return 1;
}
string numstr = to_string(num);
for (int i = 0; i < numstr.length(); i++) {
cout << numstr[i] << " ";
nums[i] = (int)numstr[i];
}
cout << "\n" << highestInArr(nums);
}
When this runs, I get:
Enter a five digit number!
12345
1 2 3 4 5
1424080487
Of course, 1,424,080,487 is not in [1, 2, 3, 4, 5].
You cannot pass a pointer into a function and get the size of it without template deduction. At runtime, all the function receives is a pointer. When you call sizeof(nums), you are not getting the size of the original array. You are simply getting the size of the pointer, which is the same as saying sizeof(int_ptr). Instead, you should be using a std::vector when using collections whose sizes are dynamic.
Now, you CAN receive the size by doing something like this:
#include <iostream>
template<typename num_t, size_t N>
num_t max_num(num_t(&arr)[N]) {
num_t m = (num_t)0;
for (size_t i = 0; i < N; ++i)
if (arr[i] > m)
m = arr[i];
return m;
}
int main(){
int foo[] = { 1, 5, 2, 4, 3 };
int m = max_num(foo);
std::cout << m << std::endl;
std::cin.get();
return 0;
}
However, this is not necessarily preferred and assumes that the array was created on the caller's stack. It does not work for dynamically allocated arrays that were created with new[]. If you do this multiple times with different sizes, you will have multiple implementations of the same function (that's what templates do). The same goes for using an std::array<int, N>. If you use N as a size_t template parameter, it will do the same thing.
There are two preferred options:
Send the size of the array into the function so that the caller is responsible for the size.
Use a different container such as std::vector so the callee is responsible for the size.
Example:
#include <vector>
#include <iostream>
#include <algorithm>
int main(){
std::vector<int> vec{ 1, 5, 2, 4, 3 };
int m = *std::max_element(std::cbegin(vec), std::cend(vec));
std::cout << m << std::endl;
std::cin.get();
return 0;
}
As for the is_5_digits, you should use the base-10 logarithm function.
#include <cmath>
// ...
int i = 12345;
size_t length = (i > 0 ? (int)log10(i) : 0) + 1;
std::cout << length << std::endl; // prints 5;
First of all, you can't simply convert a char to int just like (int)numstr[i] assuming that it will return the digit which it contains.
See, if you have a char '0', it means it's ASCII equivalent is stored, which is 48 in case of 0, 49 in case of '1' and so on.
So in order to get that digit (0,1,2,...,9), you've to substract 48 from the ASCII value.
So change this line:
nums[i] = (int)numstr[i];
to:
nums[i] = (int)numstr[i] - 48; // or nums[i] = (int)numstr[i] - '0';
And another thing, in your highestInArr function, you're getting a pointer as parameter, and in the function, you're using sizeof to determine the size of the array. You can't simply do that, the sizeof will return the size of int*, which is not the size of the array, so you've to pass size as the second argument to the function, and use it in the loop.
Like this:
int highestInArr(int *nums, int size) {
// ...
for (int i = 1; i < size; i++) {
// ...
}
// ...
}

Access number that corresponds to string

Let's say I have the following variables:
int number1 = 2;
int number2 = 4;
...
int numbern = 43;
Now what I want is to access these elements in a for loop over number 'i', so something like the following:
for (int i = 0; i < n; i++)
{
if(number1 == someFunc("number" + to_string(i)))
{
// do stuff
}
}
Here 'someFunc' should make sure that it recognizes that I want to use the number that the string corresponds to. How could I do this?
For using std::map you can do something like this:
#include <iostream>
#include <stdlib.h>
#include <map>
#include <string>
using namespace std;
int main (void)
{
map<string,int> mymap;
mymap["number1"] = 2;
mymap["number2"] = 4;
/* ... */
char number[2];
number[1] = '\0';
for(int ii=1; ii<=2; ii++)
{
number[0] = (char)(ii+48);
cout << string("number")+string(number) << ": ";
mymap[string("number")+string(number)] += 1;
cout << mymap[string("number")+string(number)] << endl;
}
return 0;
}
Here is the string the key through which you can access the actual number. In this example I didn't ensure that the key actually exists anyway this should be done normally.
If the number of numbers is not big then you can write
int i = 0;
for ( int x : { number1, number2, /* other numbers */ numbern } )
{
if ( x == someFunc( "number" + to_string( i ) ) )
{
// do stuff
}
++i;
}
Otherwise you should place the numbers in some container.
I can think of the following two options:
Use an array.
int numbers[] = {/* Put the initialization data*/};
....
if(number1 == someFunc(numbers[i]))
Use a map. This option is useful if the size of the array is open to change or the key is expected to not follow the usual array index values.
std::map<int, int> numbers;
// Add code to initialize the map.
....
if(number1 == someFunc(numbers[i]))

Find in array the biggest multiple and write it vica versa

I was given a task:
it is given an array of five numbers
First - Find all numbers that are multiples of four
Second - Find the biggest of them and write it vice versa.
I have written a code.
#include <iostream>
#include <iomanip>
using namespace std;
#define size 12
int main()
{
int new_max=0;
int a1, a2;
int i=0, j=0;
int a, b, c=0;
int u[size]={38,12,36,45,16,46,14,19,54,53,95, 98};
int max=0;
cout<<"Array: \n";
for(i=0; i<size; i++)
cout<<u[i]<<" \n";
for (int i=0; i<size; i++)
{
if (u[i]%4==0)
{
cout<<"array "<<u[i]<<" \n";
for (int j=0; j<size; j++)
{
if(max<u[i])
{
max=u[i];
}}}}
cout<<"max "<<max<<endl;
while(max > 0)
{
new_max = new_max*10 + ( max % 10);
max = max/10;
}
cout << new_max << endl;
return 0;
}
#include <iostream>
#include <algorithm>
#include <string>
#include <array>
int main() {
std::array<int, 5> input = { 36, 12, 38, 45, 16 };
auto validRangeEnd = std::remove_if(std::begin(input),
std::end(input),
[](int i){ return i % 4 != 0; });
// Now std::begin(input) -> validRangeEnd contain the ones divisible by 4
auto max = std::max_element(std::begin(input), validRangeEnd);
// Max contains the max number from the filtered range
auto stringMax = std::to_string(*max);
std::reverse(std::begin(stringMax), std::end(stringMax));
// Reverse reverses the max number
std::cout << stringMax;
}
By no means optimal but I feel it's useful for educational purposes :).
(Both remove_if and max_elements do a pass so I'll re-examine some stuff that I don't need to but this is a good algorithmic representation of the problem anyway. Also, no loops, look! :))