Wierd combination - c++

I have an array of 3 integers {1,2,3}. I need to print combinations in the form of-
1 1+2 1+3 1+2+3
2 2+3
3
for(int i = 0; i < array.size(); ++i)
{
for(int j = 0; (i + j) < array.size(); ++j)
{
sum += my[i + j];
cout << sum << " ";
c++;
}
cout << endl;
}
In above, 1+3 is being skipped.
Please help me with that.

Given a set S the power set P(S) is the set of all subsets of S. What you are trying to do is essentially enumerate all of the non-empty elements of x āˆˆ P(S). From there, you can iterate over all of the elements of each non-empty x in P(S).
What does this mean for you? Well for starters for a set S containing n elements the number of possible elements of P(S) is 2^n, so the size of the power set scales exponentially with the size of its generating set.
But, where this may be useful for small values of n (in particular n < 64) you can use unsigned long long variables to act as a kind of index. In particular, each bit corresponds to one of your array elements. Bits with a value of 0 exclude its associated element in the sum, while bits with a 1 would include the element. To do something like this try the following:
#include <vector>
#include <iostream>
void print_sum(const std::vector<int>& array, unsigned long long i) {
int sum = 0;
for (int index=0; i > 0; i=i>>1, ++index) {
if (i % 2 == 1) {
std::cout << array[index] << (i>1 ? "+" : "=");
sum += array[index];
}
}
std::cout << sum << std::endl;
}
void printer(const std::vector<int>& array) {
if (array.size() < sizeof(unsigned long long) * 8) {
unsigned long long n = 1 << array.size();
for (unsigned long long i = 1; i < n; ++i) {
print_sum(array, i);
}
}
}
int main(int argc, char** argv) {
std::vector<int> sample {1, 2, 3, 4};
printer(sample);
return 0;
}
This program has output:
1=1
2=2
1+2=3
3=3
1+3=4
2+3=5
1+2+3=6
4=4
1+4=5
2+4=6
1+2+4=7
3+4=7
1+3+4=8
2+3+4=9
1+2+3+4=10

Related

what does int numbers[n+2]; statement do?

#include<iostream>
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
int main() {
int n;
std::cout << "Enter a Number";
std::cin >> n;
int result = fastFibonacci(n);
std::cout << result << "\n";
return 0;
}
in this code when i enter input 0 or 1 get correct answer. But the problem is that when i replace int numbers[n+2]; with the commented part it start giving me wrong answer when input is 0 or 1. why? anyone please explain me.
In this function
int fastFibonacci(int n)
{
int numbers[n+2]; // int numbers[n].
numbers[0] = 0;
numbers[1] = 1;
for (int i = 2; i <= n; i++)
{
numbers[i] = numbers[i - 1] + numbers[i - 2];
}
return numbers[n];
}
there is used a variable length array with n + 2 elements declared in this line
int numbers[n+2]; // int numbers[n].
Variable length arrays is not a standard C++ feature. It can be implemented as own language extension of a C++ compiler.
Using the variable length array makes the function very unsafe because there can occur a stack overflow.
As within the function there is explicitly used two elements of the array
numbers[0] = 0;
numbers[1] = 1;
then the array shall have at least two elements even when the parameter has a value less than 2.
To calculate the n-th Fibonacci number there is no need to declare an array of such a size.
Apart from this the function argument shall have an unsigned integer type. Otherwise the function can invoke undefined behavior if the user passes a negative number.
Also for big values of n there can be an integer overflow for the type int.
The function can be implemented in various ways.
Here is one of possible its implementations.
#include <iostream>
#include <functional>
unsigned long long fibonacci( unsigned int n )
{
unsigned long long a[] = { 0, 1 };
while ( n-- )
{
a[1] += std::exchange( a[0], a[1] );
}
return a[0];
}
int main()
{
const unsigned int N = 10;
for ( unsigned int i = 0; i < N; i++ )
{
std::cout << i << ": " << fibonacci( i ) << '\n';
}
return 0;
}
The program output is
0: 0
1: 1
2: 1
3: 2
4: 3
5: 5
6: 8
7: 13
8: 21
9: 34
int numbers[n+2]; is the declaration of an array of ints with space for n + 2 ints, this is a variable lenght array and is not part of C++ standard, though some compilers allow it it's not somenthing you should use.
If you need a variable lenght array use std::vector.
With int numbers[n+2]; if n is equal to 0 you still have space for 2 ints, if you have int numbers[n]; the array will have space for 0 ints, so the code will fail because you are trying to access memory that does not exist with numbers[0] and numbers[1].
There are several good ways to implement the Fibonacci sequence, in the site you can find many questions regarding this matter in several programming languages, here is one of them Fibonacci series in C++
Edit
So I've seen your comments about using a vector, for making the sequence you wouldn't need the vector just two variables to store the two numbers to add, to store the sequence in a vactor, you can do somenthing like:
#include <iostream>
#include <vector>
#include <iomanip>
//passing the vector by reference
void fastFibonacci(unsigned long long n, std::vector<unsigned long long>& sequence) {
unsigned long long first = 0;
unsigned long long second = 1;
sequence.push_back(first); //add first values to the vector
sequence.push_back(second); //add first values to the vector
for (unsigned long long i = 0, value = 0; i < n && value <= LLONG_MAX ; ++i) {
value = first + second;
first = second;
second = value;
sequence.push_back(value); //adding values to the vector
}
}
int main() {
unsigned long long limit; //number of values in the sequence
int num = 1;
std::vector<unsigned long long> sequence; //container for the sequence
std::cout << "Enter upper limit: ";
std::cin >> limit;
fastFibonacci(limit, sequence);
//print the sequence in a range based loop formatted with <iomanip> library
for(auto& i : sequence){
std::cout << std::setw(4) << std::left << num++ << " " << i << std::endl;
}
return 0;
}
If you want to print just one of the numbers in the sequence, just use, for instance:
std::cout << sequence[10];
Instead of the whole vector.
The code you post in the comment to the other answer won't work because the access to the vector is out of bounds in numbers[i] = numbers[i - 1] + numbers[i - 2];, if for instance i = 5, your vector only has 2 nodes but you are accessing the 6th node numbers[5].

How to produce random numbers so that their sum is equal to given number?

I want to produce X random numbers, each from the interval <0; Y> (given Y as a maximum of each number), but there is restriction that the sum of these numbers must be equal to Z.
Example:
5 Randoms numbers, each max 6 and the sum must be equal to 14, e.g: 0, 2, 6, 4, 2
Is there already a C/C++ function that could do something like that?
Personally I couldn't come up with more than some ugly if-else-constucts.
Since you don't need the generated sequence to be uniform, this could be one of the possible solutions:
#include <iostream>
#include <vector>
#include <cstdlib>
int irand(int min, int max) {
return ((double)rand() / ((double)RAND_MAX + 1.0)) * (max - min + 1) + min;
}
int main()
{
int COUNT = 5, // X
MAX_VAL = 6, // Y
MAX_SUM = 14; // Z
std::vector<int> buckets(COUNT, 0);
srand(time(0));
int remaining = MAX_SUM;
while (remaining > 0)
{
int rndBucketIdx = irand(0, COUNT-1);
if (buckets[rndBucketIdx] == MAX_VAL)
continue; // this bucket is already full
buckets[rndBucketIdx]++;
remaining--;
}
std::cout << "Printing sequence: ";
for (size_t i = 0; i < COUNT; ++i)
std::cout << buckets[i] << ' ';
}
which just simply divides the total sum to bunch of buckets until it's gone :)
Example of output: Printing sequence: 4 4 1 0 5
NOTE: this solution was written when the question specified a "MAX SUM" parameter, implying a sum of less than that amount was equally acceptable. The question's now been edited based on the OP's comment that they meant the cumulative sum must actually hit that target. I'm not going to update this answer, but clearly it could trivially discard lesser totals at the last level of recursion.
This solution does a one-time population of a vector<vector<int>> with all the possible combinations of numbers solving the input criterion, then each time a new solution is wanted it picks one of those at random and shuffles the numbers into a random order (thereby picking a permutation of the combination).
It's a bit heavy weight - perhaps not suitable for the actual use that you mentioned after I'd started writing it ;-P - but it produces an even-weighted distribution, and you can easily do things like guarantee a combination won't be returned again until all other combinations have been returned (with a supporting shuffled vector of indices into the combinations).
#include <iostream>
#include <vector>
#include <algorithm>
using std::min;
using std::max;
using std::vector;
// print solutions...
void p(const vector<vector<int>>& vvi)
{
for (int i = 0; i < vvi.size(); ++i)
{
for (int j = 0; j < vvi[i].size(); ++j)
std::cout << vvi[i][j] << ' ';
std::cout << '\n';
}
}
// populate results with solutions...
void f(vector<vector<int>>& results, int n, int max_each, int max_total)
{
if (n == 0) return;
if (results.size() == 0)
{
for (int i = 0; i <= min(max_each, max_total); ++i)
results.push_back(vector<int>(2, i));
f(results, n - 1, max_each, max_total);
return;
}
vector<vector<int>> new_results;
for (int r = 0; r < results.size(); ++r)
{
int previous = *(results[r].rbegin() + 1);
int current_total = results[r].back();
int remaining = max_total - current_total;
for (int i = 0; i <= min(previous,min(max_each, remaining)); ++i)
{
vector<int> v = results[r];
v.back() = i;
v.push_back(current_total + i);
new_results.push_back(v);
}
}
results = new_results;
f(results, n - 1, max_each, max_total);
}
const vector<int>& once(vector<vector<int>>& solutions)
{
int which = std::rand() % solutions.size();
vector<int>& v = solutions[which];
std::random_shuffle(v.begin(), v.end() - 1);
return v;
}
int main()
{
vector<vector<int>> solutions;
f(solutions, 5, 6, 14);
std::cout << "All solution combinations...\n";
p(solutions);
std::cout << "------------------\n";
std::cout << "A few sample permutations...\n";
for (int n = 1; n <= 100; ++n)
{
const vector<int>& o = once(solutions);
for (int i = 0; i < o.size() - 1; ++i)
std::cout << o[i] << ' ';
std::cout << '\n';
}
}
#include<iostream>
#include <cstdlib> //rand ()
using namespace std;
void main()
{
int random ,x=5;
int max , totalMax=0 , sum=0;
cout<<"Enter the total maximum number : ";
cin>>totalMax;
cout<<"Enter the maximum number: ";
cin>>max;
srand(0);
for( int i=0; i<x ; i++)
{
random=rand()%max+1; //range from 0 to max
sum+=random;
if(sum>=totalMax)
{
sum-=random;
i--;
}
else
cout<<random<<' ';
}
cout<<endl<<"Reached total maximum number "<<totalMax<<endl;
}
I wrote this simple code
I tested it using totalMax=14 and max=3 and it worked with me
hope it's what you asked for
LiHo's answer looks pretty similar to my second suggestion, so I'll leave that, but here's an example of the first. It could probably be improved, but it shouldn't have any tragic bugs. Here's a live sample.
#include <algorithm>
#include <array>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
constexpr int MAX = 14;
constexpr int LINES = 5;
int sum{};
int maxNum = 6;
int minNum{};
std::array<int, LINES> nums;
for (int i = 0; i < LINES; ++i) {
maxNum = std::min(maxNum, MAX - sum);
// e.g., after 0 0, min is 2 because only 12/14 can be filled after
int maxAfterThis = maxNum * (LINES - i - 1);
minNum = std::min(maxNum, std::max(minNum, MAX - sum - maxAfterThis));
std::uniform_int_distribution<> dist(minNum, maxNum);
int num = dist(gen);
nums[i] = num;
sum += num;
}
std::shuffle(std::begin(nums), std::end(nums), gen);
Creating that ditribution every time could potentially slow it down (I don't know), but the range has to go in the constructor, and I'm not one to say how well distributed these numbers are. However, the logic is pretty simple. Aside from that, it uses the nice, shiny C++11 <random> header.
We just make sure no remaining number goes over MAX (14) and that MAX is reached by the end. minNum is the odd part, and that's due to how it progresses. It starts at zero and works its way up as needed (the second part to std::max is figuring out what would be needed if we got 6s for the rest), but we can't let it surpass maxNum. I'm open to a simpler method of calculating minNum if it exists.
Since you know how many numbers you need, generate them from the given distribution but without further conditions, store them, compute the actual sum, and scale them all up/down to get the desired sum.

Computing Combinations on basis of number of bits set

I need to compute all possible combinations of n things selected r at a time where 0<=r<=n, One method to do so is generating the numbers up to 0 to 2^n-1. But I need to generate these numbers such that the numbers should be sorted on the basis of the number of bits set in that number. for n=3:
0 // numbers with 0 bits set
1 2 4 // numbers with 1 bits set
3 5 6 // numbers with 2 bits set
7 // numbers with 3 bits set
I need to know how to generate the numbers such that they are sorted in increasing/decreasing order of bits set?
Implement regular algorithm to generate the combinations, but also hold an additional array where you store the numbers sorted accoding to the 1-bits set. Then for each combination generated replace the numbers with the numbers sitting in the corresponding position minus one in the array sorted as I described.
Iterating over all combinations of some some number of items is covered nicely by quant_dev here.
Here is a simple way function that counts the number of bits set in a number's representation:
// Counts how many bits are set in the representation of the input number n
int numOfBitsSet(int n)
{
int cnt = 0;
while (n != 0)
{
cnt += (n & 1);
n = n >> 1;
}
return cnt;
}
And here is how you could use it in a (C++11) program that does what you want:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
int main()
{
// For instance...
int n = 3;
// Fill up a vector of 2^n entries (0 .. 2^(n - 1))
vector<int> v(1 << n);
iota(begin(v), end(v), 0);
// For each number of bits...
for (size_t i = 0; i <= n; i++)
{
cout << "Numbers with " << i << " bits set: ";
// Find the first number with i bits set...
auto it = find_if(begin(v), end(v), [i] (int x) {
return (numOfBitsSet(x) == i);
});
while (it != end(v))
{
cout << *it << " ";
// Find the next number with i bits set...
it = find_if(next(it), end(v), [i] (int x) {
return (numOfBitsSet(x) == i);
});
}
cout << endl;
}
}
If C++11 is not an option for you, you will have to use functors instead of lambdas, and replace std::iota with a manual loop:
#include <algorithm>
#include <vector>
#include <iostream>
#include <iterator>
using namespace std;
struct bit_count_filter
{
bit_count_filter(int i) : _i(i) { }
bool operator () (int x) const { return numOfBitsSet(x) == _i; }
int _i;
};
int main()
{
// For instance...
int n = 3;
// Fill up a vector of 2^n entries (0 .. 2^(n - 1))
vector<int> v(1 << n);
for (size_t i = 0; i < v.size(); i++)
{
v[i] = i;
}
// For each number of bits...
for (size_t i = 0; i <= n; i++)
{
cout << "Numbers with " << i << " bits set: ";
// Find the first number with i bits set...
auto it = find_if(begin(v), end(v), bit_count_filter(i));
while (it != end(v))
{
cout << *it << " ";
// Find the next number with i bits set...
it = find_if(next(it), end(v), bit_count_filter(i));
}
cout << endl;
}
}
You could do it recursively:
void setnbits(unsigned int cur, int n, int toset, int max)
{
if(toset == 0)
{
printf("%d ", cur >> (n + 32 - max) , n);
return;
}
toset--;
for(int i = 1 ; i <= n-toset ; i++)
{
setnbits((cur >> i) | 0x80000000, n-i, toset , max);
}
}
Could be called like:
for(int z = 0 ; z < 4 ; z++)
{
printf("%d bits: ", z);
setnbits(0, 3, z, 3);
printf("\n");
}
prints:
0 bits: 0
1 bits: 1 2 4
2 bits: 3 5 6
3 bits: 7
The numbers are not guaranteed to be in numerical order.
That's pretty easy.
There are two cases:
1) Last 1-bit has 0-bit before:
000111001001 -> 000111001010.
You should just move it to the left
2) There is a chain of 1-bits:
000110111100 -> 000111000111
Then you should move last 1-bit to the nearest 0-bit on the left(before the chain), and move all another bits of that chain to the right.
You'll get this way all needed numbers in increasing order.

create an array such that it contains elements from 0 to N in binary

I need a fast algorithm which will generate all possible numbers upto a given number N in binary into an array.
e.g N=3
Then the array should be {0,0,0},{0,0,1}.....{1,1,1}
N<=17.
I have tried this so far which is a recursive solution.
void print_digits(int n, std::string const& prefix = "") {
if (!n) {
printf("%s,",prefix.c_str());
return;
}
print_digits(n-1, prefix + '0');
print_digits(n-1, prefix + '1');
}
i need a better algorithm.
All the integers in C++ are stored directly in memory as their binary representation. Thus, if you just want to store N numbers, you should just write them directly into an array "as-is"
std::vector<unsigned> Numbers;
// if N is length of the number, calculate the maximum as 2^N - 1
long long Max = 1 << N - 1;
for (unsinged i = 0; i < Max; ++i)
Numbers.push_back(i);
If you want to write them in the binary representation, it's also pretty straightforward, even if you want to code it all by yourself. (Please excuse me, as this is just an simple example implementation)
void PrintAsBits(unsigned value) {
for (int i = sizeof(unsigned) * 8 - 1; i >= 0; --i)
cout << ((1 << i) & value) ? 1 : 0;
cout << '\n';
}
Just in case anyone cares anymore, the following code implements the original spec, which calls for a way to populate a 2-dimensional array where each value is represented as a numeric array whose elements correspond to its value's binary digits, in big-endian order.
#include <iostream>
static const int DIGIT_COUNT = 10;
static const int VALUE_COUNT = 1 << DIGIT_COUNT;
unsigned char g_binarray[VALUE_COUNT][DIGIT_COUNT];
void Populate() {
for(int i=0; i<VALUE_COUNT; ++i) {
unsigned char (&curr)[DIGIT_COUNT] = g_binarray[i];
for(int di=0; di<DIGIT_COUNT; ++di) {
curr[di] = unsigned char((i >> (DIGIT_COUNT - 1 - di)) & 1);
}
}
}
void DumpArray() {
static const char *digits = "01";
for(int i=1; i<VALUE_COUNT; ++i) {
for(int di=0; di<DIGIT_COUNT; ++di) {
std::cout << digits[!!g_binarray[i][di]];
}
std::cout << " " << i << std::endl;
}
}
int main(int argc, char* argv[]) {
Populate();
DumpArray();
return 0;
}
As I wrote in 1 post:
Example: If you need of length 4, then you must have 2^4 = 16 different arrays.
You can use this simple Java code to generate all arrays:
for (int i=0; i < 16; i++) {
System.out.println(Integer.toBinaryString(i));
}
The output of this:
0 1 10 11 100 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111

How can we find second maximum from array efficiently?

Is it possible to find the second maximum number from an array of integers by traversing the array only once?
As an example, I have a array of five integers from which I want to find second maximum number. Here is an attempt I gave in the interview:
#define MIN -1
int main()
{
int max=MIN,second_max=MIN;
int arr[6]={0,1,2,3,4,5};
for(int i=0;i<5;i++){
cout<<"::"<<arr[i];
}
for(int i=0;i<5;i++){
if(arr[i]>max){
second_max=max;
max=arr[i];
}
}
cout<<endl<<"Second Max:"<<second_max;
int i;
cin>>i;
return 0;
}
The interviewer, however, came up with the test case int arr[6]={5,4,3,2,1,0};, which prevents it from going to the if condition the second time.
I said to the interviewer that the only way would be to parse the array two times (two for loops). Does anybody have a better solution?
Your initialization of max and second_max to -1 is flawed. What if the array has values like {-2,-3,-4}?
What you can do instead is to take the first 2 elements of the array (assuming the array has at least 2 elements), compare them, assign the smaller one to second_max and the larger one to max:
if(arr[0] > arr[1]) {
second_max = arr[1];
max = arr[0];
} else {
second_max = arr[0];
max = arr[1];
}
Then start comparing from the 3rd element and update max and/or second_max as needed:
for(int i = 2; i < arr_len; i++){
// use >= n not just > as max and second_max can hav same value. Ex:{1,2,3,3}
if(arr[i] >= max){
second_max=max;
max=arr[i];
}
else if(arr[i] > second_max){
second_max=arr[i];
}
}
The easiest solution would be to use std::nth_element.
You need a second test:
for(int i=0;i<5;i++){
if(arr[i]>max){
second_max=max;
max=arr[i];
}
else if (arr[i] > second_max && arr[i] != max){
second_max = arr[i];
}
}
Your original code is okay, you just have to initialize the max and second_max variables. Use the first two elements in the array.
Here you are:
std::pair<int, int> GetTwoBiggestNumbers(const std::vector<int>& array)
{
std::pair<int, int> biggest;
biggest.first = std::max(array[0], array[1]); // Biggest of the first two.
biggest.second = std::min(array[0], array[1]); // Smallest of the first two.
// Continue with the third.
for(std::vector<int>::const_iterator it = array.begin() + 2;
it != array.end();
++it)
{
if(*it > biggest.first)
{
biggest.second = biggest.first;
biggest.first = *it;
}
else if(*it > biggest.second)
{
biggest.second = *it;
}
}
return biggest;
}
Quickselect is the way to go with this one. Pseudo code is available at that link so I shall just explain the overall algorithm:
QuickSelect for kth largest number:
Select a pivot element
Split array around pivot
If (k < new pivot index)
perform quickselect on left hand sub array
else if (k > new pivot index)
perform quickselect on right hand sub array (make sure to offset k by size of lefthand array + 1)
else
return pivot
This is quite obviously based on the good old quicksort algorithm.
Following this algorithm through, always selecting element zero as the pivot every time:
select 4th largest number:
1) array = {1, 3, 2, 7, 11, 0, -4}
partition with 1 as pivot
{0, -4, _1_, 3, 2, 7, 11}
4 > 2 (new pivot index) so...
2) Select 1st (4 - 3) largest number from right sub array
array = {3, 2, 7, 11}
partition with 3 as pivot
{2, _3_, 7, 11}
1 < 2 (new pivot index) so...
3) select 1st largest number from left sub array
array = {2}
4) Done, 4th largest number is 2
This will leave your array in an undefined order afterwards, it's up to you if that's a problem.
Step 1. Decide on first two numbers.
Step 2. Loop through remaining numbers.
Step 3. Maintain latest maximum and second maximum.
Step 4. When updating second maximum, be aware that you are not making maximum and second maximum equal.
Tested for sorted input (ascending and descending), random input, input having duplicates, works fine.
#include <iostream>
#define MAX 50
int GetSecondMaximum(int* data, unsigned int size)
{
int max, secmax;
// Decide on first two numbers
if (data[0] > data[1])
{
max = data[0];
secmax = data[1];
}
else
{
secmax = data[0];
max = data[1];
}
// Loop through remaining numbers
for (unsigned int i = 2; i < size; ++i)
{
if (data[i] > max)
{
secmax = max;
max = data[i];
}
else if (data[i] > secmax && data[i] != max/*removes duplicate problem*/)
secmax = data[i];
}
return secmax;
}
int main()
{
int data[MAX];
// Fill with random integers
for (unsigned int i = 0; i < MAX; ++i)
{
data[i] = rand() % MAX;
std::cout << "[" << data[i] << "] "; // Display input
}
std::cout << std::endl << std::endl;
// Find second maximum
int nSecondMax = GetSecondMaximum(data, MAX);
// Display output
std::cout << "Second Maximum = " << nSecondMax << std::endl;
// Wait for user input
std::cin.get();
return 0;
}
Other way to solve this problem, is to use comparisons among the elements. Like for example,
a[10] = {1,2,3,4,5,6,7,8,9,10}
Compare 1,2 and say max = 2 and second max = 1
Now compare 3 and 4 and compare the greatest of them with max.
if element > max
second max = max
element = max
else if element > second max
second max = element
The advantage with this is, you are eliminating two numbers in just two comparisons.
Let me know, if you have any problem understanding this.
Check this solution.
max1 = a[0];
max2 = a[1];
for (i = 1; i < n; i++)
{
if (max1 < a[i])
{
max2 = max1;
max1 = a[i];
}
if (max2 == max1) max2 = a[i + 1];
if (max2 == a[n])
{
printf("All numbers are the same no second max.\n");
return 0;
}
if (max2 < a[i] && max1 != a[i]) max2 = a[i];
}
Here is something which may work ,
public static int secondLargest(int[] a){
int max=0;
int secondMax=0;
for(int i=0;i<a.length;i++){
if(a[i]<max){
if(a[i]>secondMax){
secondMax=a[i];
}
continue;
}
if(a[i]>max){
secondMax=max;
max=a[i];
}
}
return secondMax;
}
The upper bound should have be n+log2ā”nāˆ’2, but it bigger than O(n) in case of random selection algorithm, but in worst case it much smaller. The solution might be
build a tree like to find the MAX element with n - 1 comparisons
max(N)
/ \
max(N/2) max(N/2)
remove the MAX and find the MAX again log2n - 1 comparison
PS. It uses additional memory, but it faster than random selection algorithm in worst case.
Can't we just sort this in decreasing order and take the 2nd element from the sorted array?
How about the following below.
make_heap is O(n) so this is efficient and this is 1-pass
We find the second max by taking advantage that it must be one of the heap children of the parent, which had the maximum.
#include <algorithm>
#include <iostream>
int main()
{
int arr[6]={0,1,2,3,4,5};
std::make_heap(arr, arr+6);
std::cout << "First Max: " << arr[0] << '\n';
std::cout << "Second Max: " << std::max(arr[1], arr[2]) << '\n';
return 0;
}
int max,secondMax;
max=secondMax=array[0];
for(int i=0;i<array.length;i++)
{ if(array[i]>max) { max=array[i]; }
if(array[i]>secondMax && array[i]<max) {
secondMax=array[i]; }
}
#include <iostream>
using namespace std;
int main() {
int max = 0;
int sec_Max = 0;
int array[] = {81,70,6,78,54,77,7,78};
int loopcount = sizeof(array)/sizeof(int);
for(int i = 0 ; i < loopcount ; ++i)
{
if(array[i]>max)
{
sec_Max = max;
max = array[i];
}
if(array[i] > sec_Max && array[i] < max)
{
sec_Max = array[i];
}
}
cout<<"Max:" << max << " Second Max: "<<sec_Max<<endl;
return 0;
}
// Set the first two different numbers as the maximum and second maximum numbers
int max = array[0];
int i = 1;
//n is the amount of numbers
while (array[i] == max && i < n) i++;
int sec_max = array[i];
if( max < sec_max ) {
tmp = sec_max;
sec_max = max;
max = tmp;
}
//find the second maximum number
for( ; i < n; ++i ) {
if( array[i] > max ) {
sec_max = max;
max = array[i];
} else if( array[i] > sec_max && array[i] != max ) {
sec_max = array[i];
}
}
printf("The second maximum number is %d\n", sec_max);