2- combination c++ - c++

I have an array of n elements, I need to put all 2- combination of them into arrays of length 2. for example:
suppose comb is a 2 dimensional array.
n = 1,2,3
I need to put all 2- combinations to comb[i][j] like that:
comb[0][0] = {1}
comb[0][1] = {2}
comb[1][0] = {1}
comb[1][1] = {3}
comb[2][0] = {2}
comb[2][1] = {3}
I do not know how to write the code!
Thanks
My Answer:
The O(n!) answer: n = total number m= total possible answer
int m = 0;
for (int i = 0; i < n - 1; i++){
int first = a[i];
for(int j = i+1 ; j < n ; j++){
int second = a[j];
comb[m][0] = first;
comb[m][1] = second;
++m;
}
}

Can think of the following N^2 approach:
// Resulting combinations
vector<pair<int,int> > comb;
// Copy n into a double-ended queue - best would be for n to already be a deque
deque<int> Q(a.size());
copy(a.begin(), a.end(), Q.begin());
sort(Q.begin(), Q.end());
while(!Q.empty())
{
// Get first element, remove it and equivalent elements
int a = Q.front();
while(Q.front() == a)
Q.pop_front();
// Find all unique combinations with first element
int last=a;
for(deque<int>::iterator it = Q.begin(); it != Q.end(); ++it)
{
if(*it != last)
comb.push_back(pair<int,int>(a,*it));
last = *it;
}
}
Probably easy to optimize this further.

One easy way is using the next_permutation function available in the STL library in order to generate all the possible permutations of your numbers, and then pick the first two elements of each one. Note that the sequence must be first sorted, as if not the previous permutations will be skipped.
int nums[] = {1, 2, 3, 4};
while (next_permutation(nums, nums + 4)) {
cout << nums[0] << ", " << nums[1] << endl;
}
Remember that you must #include <algorithm> to use this function.

For each element in n indexed ith put every elements in n except the ith indexed jth in cell comb[length(n) - i][j].

Related

I don't understand how to calculate the sum of the sums of every possible sub-array using nested loops

The question the homework asks is:
Write a function, secondSmallestSum that when passed an int array of any length greater than 1 will calculate the sum of the elements of every possible sub-array and then return the second smallest sum found. It is possible for the smallest and second smallest sums to have the same value.
Sub-arrays are contiguous ranges of elements within an array. For example, if you have an array of length 4, {1,2,3,4}, then the complete set of sub-arrays is:
{1}, {1,2}, {1,2,3}, {1,2,3,4}, {2}, {2,3}, {2,3,4}, {3}, {3,4}, {4}
the sum of each sub-array is then:
1, 3, 6, 10, 2, 5, 9, 3, 7, 4
The main function for this problem must call your readNumbers function, then pass the new array to your secondSmallestSum function, display the second smallest sum found and finally delete the array.
My code so far prints numbers that the user inputs.
#include <iostream>
int *readNumbers(int n)
{
int *a = new int[n];
for (int i = 0; i < n; i++){
std::cin >> a[i];
}
return a;
}
int main()
{
int length = 5;
int *ptr = readNumbers(length);
printNumbers(ptr, length);
return 0;
}
I expect this array (AN EXAMPLE) {4,0,9} to output the sub-arrays of {4}, {4,0}, {4,0,9}, {0}, {0,9} and {9}. The sums for each array would output as: 4,4,13,0,9 and 9. The total sum is 39.
With a first look, it definitely occurs that let's run a double loop till the end of the array for each element and find the sums of element along with it.
That gives you the complexity of O(n2) roughly speaking
Now, do you want to add 3+4 for the 2nd iteration (when you're looping for 2) while you have already calculated for 1st iteration? I wouldn't...
So instead I would save those incremental additions like this:
for (int *i = ptr + l - 2; i >= ptr; i--) {
*i = *i + *(i+1);
}
This would give me {1,2,3,4} -> {10,9,7,4}
Now run the double loop:
for (int *i = ptr; i < ptr + l; i++) {
cout << *i << " ";
for (int *j = i+1; j < ptr + l; j++) {
cout << *i - *j << " ";
}
}
Now you have all the sums. and you can do all the required operations. For your example the second smallest: You can add the following code in that double loop
if (secondsmallest >= x) {
if (smallest >= x) {
secondsmallest = smallest;
smallest = x;
}else{
secondsmallest = x;
}
}
Find the correct place to add it and replace x with suitable notation :)
Cheers...
If you find this answer helpful - consider upvoting :)

Sorting ques how to access the private vector values

I am doing this problem on sorting which I think can be sorted either by Heap sort or Quick sort.
There is an array A of integers of size n which cannot directly be accessed. However, you can get true or false response to queries of the form A[i] < A[j].
It is given that A has only one duplicate pair, and rest all the elements are distinct. So it has n-1 distinct elements and 1 element which is same as one of the n-1 elements. Your task is to identify the indices of the two identical elements in A.
class hiddenVector {
private:
vector <int> data; // you cannot directly access this in your code since this is a private element
public:
int getSize();// it returns a non-negative integer equal to the size of the class member data.
bool iLessThanj(int i, int j); // returns true if and only if data[i] is strictly less than data[j]
};
You can create a new vector which contains indexes of hidden vector, then sort it using public method iLessThanj() of hidden vector. Finally, look through sorted indexes to find a pair of equal elements, they are adjacent after sorting and iLessThanj(i, i+1) == false for them and only them.
This has O(nlogn) complexity in time and O(n) in memory.
hiddenVector a; // {1, 3, -2, -4, 3, 7} for example
// construct indexes array
std::vector<int> a_ind (a.getSize ());
for (int i = 0; i < a.getSize(); i++)
a_ind[i] = i;
// now a_ind = {0, 1, 2, 3, 4, 5}
// sort it
std::sort(begin(a_ind), end(a_ind),
[&a] (int i, int j) { return a.iLessThanj(i, j); }
);
// now a_ind = {3, 2, 0, 1, 4, 5}
// and it is equal to sequence of indexes in sorted hidden vector
// finally, compute an answer to your problem
std::pair<int, int> res = {};
for (int k = 0; k < a_ind.size()-1; k++) {
int i = a_ind[k];
int j = a_ind[k+1];
if (!a.iLessThanj(i, j)) {
res.first = i;
res.second = j;
break;
}
}
// now res = {1, 4}
PS
Speedtest results for discussion in comments (compiled & run with -O3):
N squared_algo sublinear_algo
10 2.259e-07 1.1653e-06
100 4.8259e-06 8.5859e-06
1000 0.000218602 0.000118063
10000 0.0138744 0.000718756
100000 0.913739 0.00876182
Full speedtest coded is here
It is given that A has only one duplicate pair, and rest all the elements are distinct. So it has n-1 distinct elements and 1 element which is same as one of the n-1 elements. Your task is to identify the indices of the two identical elements in A.
you do not need to access the elements, the indexes a and b are the solution when iLessThanj(a, b) returns false and iLessThanj(b, a) returns false too (of course with b != a)
so something like :
hiddenVector v;
... initialization of v
int n = v.getSize();
for (int a = 0; a < n; ++a) {
int b;
for (b = a+1; b < n; ++b) {
if (!v.iLessThanj(a, b) && !v.iLessThanj(b, a)) {
std::cout << "element is the same at indexes " << a << " and " << b << std::endl;
break;
}
}
if (b < n)
break;
}
P.S. the complexity is O(n^2), look at the other answer, more complicated but with a lower complexity

Find order of an array using minimum memory and time

Let's say i have an array of 5 elements. My program knows it's always 5 elements and when sorted it's always 1,2,3,4,5 only.
As per permutations formula i.e n!/(n-r)! we can order it in 120 ways.
In C++ using std::next_permutation I can generate all those 120 orders.
Now, my program/routine accepts an input argument as a number in the range of 1 to 120 and gives the specific order of an array as output.
This works fine for small array sizes as i can repeat std::next_permutation until that matches input parameter.
The real problem is, How can i do it in less time if my array has 25 elements or more? For 25 elements, the number of possible orders are : 15511210043330985984000000.
Is there a technique that I can easily find the order of numbers using a given number as input?
Thanks in advance :)
This is an example c++ implementation of the algorithm mentioned in this link:
#include <vector>
#define ull unsigned long long
ull factorial(int n) {
ull fac = 1;
for (int i = 2; i <= n; i++)
fac *= i;
return fac;
}
std::vector<int> findPermutation(int len, long idx) {
std::vector<int> original = std::vector<int>(len);
std::vector<int> permutation = std::vector<int>();
for (int i = 0; i < len; i++) {
original[i] = i;
}
ull currIdx = idx;
ull fac = factorial(len);
while (original.size() > 0) {
fac /= original.size();
int next = (currIdx - 1) / fac;
permutation.push_back(original[next]);
original.erase(original.begin() + next);
currIdx -= fac * next;
}
return permutation;
}
The findPermutation function accepts the length of the original string and the index of the required permutation, and returns an array that represents that permutation. For example, [0, 1, 2, 3, 4] is the first permutation of any string with length 5, and [4, 3, 2, 1, 0] is the last (120th) permutation.
I have had a similar problem where I was storing lots of row in a Gtk TreeView and did not want to go over all of them every time I want to access a row by its position and not by its reference.
So, I created a map of the positions of the row so I could easily identify them by the parameter I needed.
So, my suggestion to this is you go over all permutations once and map every std::permutation in an array (I used a std::vector), so you can access it by myVector[permutation_id].
Here is my way I have done the mapping:
vector<int> FILECHOOSER_MAP;
void updateFileChooserMap() {
vector<int> map;
TreeModel::Children children = getInterface().getFileChooserModel()->children();
int i = 0;
for(TreeModel::Children::iterator iter = children.begin(); iter != children.end(); iter++) {
i++;
TreeModel::Row row = *iter;
int id = row[getInterface().getFileChooserColumns().id];
if( id >= map.size()) {
for(int x = map.size(); x <= id; x++) {
map.push_back(-1);
}
}
map[id] = i;
}
FILECHOOSER_MAP = map;
}
So in your case you would just iterate over the permutations like this and you can map them in a way that allows you accesing them by their id.
I hope this helps you :D
regards, tagelicht

Suitor elimination

I am trying to teach myself C++ and I came across this program project in my book I am working from:
In an ancient land, the beautiful princess Eve had many suitors. She decided on the following procedure to determine which suitor she would marry. First, all of the suitors would be lined up one after the other and assigned numbers.
The first suitor would be number 1, the second number 2, and so on up to the last suitor,number n. Starting at the first suitor she would then count three suitors down the line (because of the three letters in her name) and the third suitor would be eliminated from winning her hand and removed from the line. Eve would then continue, counting three more suitors, and eliminating every third suitor. When she reached the end of the line she would continue counting from the beginning.
For example, if there were six suitors then the elimination process would proceed as follows:
123456 initial list of suitors, start counting from 1
12456 suitor 3 eliminated, continue counting from 4
1245 suitor 6 eliminated, continue counting from 1
125 suitor 4 eliminated, continue counting from 5
15 suitor 2 eliminated, continue counting from 5
1 suitor 5 eliminated, 1 is the lucky winner
Write a program that uses a vector to determine which position you should stand in to marry the princess if there are n suitors. You will find the following function from the Vector class useful:
v.erase(iter);
// Removes element at position iter
For example, to use this function to erase the fourth element from the beginning of a vector variable named theVector , use
theVector.erase(theVector.begin( ) + 3);
The number 3 is used because the first element in the vector is at index position 0.
I have some preliminary code written, but I am having a hard time figuring out how to tell the program after the first suitor (i.e the 3rd suitor) is eliminated to start counting from the fourth suitor, and so on. Perhaps a nested loop would work? I have found solutions online that use a class but it is difficult for me to understand and I feel like there is a simpler way of solving this problem, any help would be greatly appreciated.
#include <iostream>
#include <vector>
using namespace std;
int main ()
{
int n;
vector<int> vec;
cout << "Enter the number of suitors: " << endl;
cin >> n;
// set some values (from 1 to n)
for(int i = 0; i <= n; i++){
vec.push_back(i);
}
// erase third suitor
vec.erase(vec.begin()+2);
// print vector with erased suitor
for(unsigned i = 0; i <= vec.size(); i++){
cout << vec[i] << endl;
}
}
First of all, there are two bugs in your program: you're initially putting [0, n] in the vector, which should be [1, n], and when printing the contents of the vector, you use <= where it should be <.
Now for the actual question. We want to iterate over the vector with steps of size 2 (the second person to the right of the current person):
for (int i = 0; i < vec.size(); i += 2)
However, when we reach the end of the array, we want to continue counting from the front. For this, we can use the modulo operator %:
for (int i = 0; i < vec.size(); i = (i + 2) % vec.size())
This will restrict i to the range [0, vec.size() - 1]. As such, our loop condition is now useless. Instead, we need to take care to terminate the loop when the vector's size is 1:
for (int i = 0; vec.size() > 1; i = (i + 2) % vec.size())
Putting it together, we get the following:
for (int i = 0; vec.size() > 1; i = (i + 2) % vec.size())
vec.erase(vec.begin() + i + 2);
Or equivalently:
for (int i = 2; vec.size() > 1; i = (i + 2) % vec.size())
vec.erase(vec.begin() + i);
The only element that is in the vector when this loop terminates is the number of the lucky suitor.
EDIT: To print out the contents of the vector after each elimination, try this:
for (int i = 2; vec.size() > 1; i = (i + 2) % vec.size())
{
vec.erase(vec.begin() + i);
for (int j = 0; j < vec.size(); j++)
cout << vec[j];
cout << endl;
}
Use relative positioning and take advantage of vec.erase()'s return value.
newpos = vec.erase(pos);
Here 'newpos' is pointing to the element that followed the erased one. Meaning, earsing '3' from {1, 2, 3, 4, 5, 6} gets you pointed to '4'. You can then do
pos = vec.begin();
while (pos != vec.end()) {
erasePos = // compute erasing position relative to 'pos'
// e.g. pos + 2, within bounds
pos = vec.erase(erasePos);
}
You need to do this in a loop.
For that use case where you simply iterate until the end and loop back to the beginning, I would use a list instead of a vector. The program could be :
#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> l;
int n;
int i;
cout << "Enter the number of suitors: ";
cin >> n;
for (i=0; i<n; i++) l.push_back(i);
int delta = 3; // want to remove every third
i = delta;
list<int>::iterator it = l.begin();
while (l.size() > 1) { // loop until only one left
if (--i == 0) { // is it third ?
list<int>::iterator it2 = it++; // move pointer one step further (erase would destroy it)
l.erase(it2); // remove it
i = delta; // rearm counter
}
else it++; // was not third, simply goes on
if (it == l.end()) it = l.begin(); // if at end, go back to begin
}
cout << "Winner is number : " << l.front() + 1 << endl; // add one as our list was 0,1,...n-1
return 0;
}

Find the biggest 3 numbers in a vector

I'm trying to make a function to get the 3 biggest numbers in a vector. For example:
Numbers: 1 6 2 5 3 7 4
Result: 5 6 7
I figured I could sort them DESC, get the 3 numbers at the beggining, and after that resort them ASC, but that would be a waste of memory allocation and execution time. I know there is a simpler solution, but I can't figure it out. And another problem is, what if I have only two numbers...
BTW: I use as compiler BorlandC++ 3.1 (I know, very old, but that's what I'll use at the exam..)
Thanks guys.
LE: If anyone wants to know more about what I'm trying to accomplish, you can check the code:
#include<fstream.h>
#include<conio.h>
int v[1000], n;
ifstream f("bac.in");
void citire();
void afisare_a();
int ultima_cifra(int nr);
void sortare(int asc);
void main() {
clrscr();
citire();
sortare(2);
afisare_a();
getch();
}
void citire() {
f>>n;
for(int i = 0; i < n; i++)
f>>v[i];
f.close();
}
void afisare_a() {
for(int i = 0;i < n; i++)
if(ultima_cifra(v[i]) == 5)
cout<<v[i]<<" ";
}
int ultima_cifra(int nr) {
return nr - 10 * ( nr / 10 );
}
void sortare(int asc) {
int aux, s;
if(asc == 1)
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] > v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = aux;
s = 1;
}
} while( s == 1);
else
do {
s = 0;
for(int i = 0; i < n-1; i++)
if(v[i] < v[i+1]) {
aux = v[i];
v[i] = v[i+1];
v[i+1] = v[i];
s = 1;
}
} while(s == 1);
}
Citire = Read
Afisare = Display
Ultima Cifra = Last digit of number
Sortare = Bubble Sort
If you were using a modern compiler, you could use std::nth_element to find the top three. As is, you'll have to scan through the array keeping track of the three largest elements seen so far at any given time, and when you get to the end, those will be your answer.
For three elements that's a trivial thing to manage. If you had to do the N largest (or smallest) elements when N might be considerably larger, then you'd almost certainly want to use Hoare's select algorithm, just like std::nth_element does.
You could do this without needing to sort at all, it's doable in O(n) time with linear search and 3 variables keeping your 3 largest numbers (or indexes of your largest numbers if this vector won't change).
Why not just step through it once and keep track of the 3 highest digits encountered?
EDIT: The range for the input is important in how you want to keep track of the 3 highest digits.
Use std::partial_sort to descending sort the first c elements that you care about. It will run in linear time for a given number of desired elements (n log c) time.
If you can't use std::nth_element write your own selection function.
You can read about them here: http://en.wikipedia.org/wiki/Selection_algorithm#Selecting_k_smallest_or_largest_elements
Sort them normally and then iterate from the back using rbegin(), for as many as you wish to extract (no further than rend() of course).
sort will happen in place whether ASC or DESC by the way, so memory is not an issue since your container element is an int, thus has no encapsulated memory of its own to manage.
Yes sorting is good. A especially for long or variable length lists.
Why are you sorting it twice, though? The second sort might actually be very inefficient (depends on the algorithm in use). A reverse would be quicker, but why even do that? If you want them in ascending order at the end, then sort them into ascending order first ( and fetch the numbers from the end)
I think you have the choice between scanning the vector for the three largest elements or sorting it (either using sort in a vector or by copying it into an implicitly sorted container like a set).
If you can control the array filling maybe you could add the numbers ordered and then choose the first 3 (ie), otherwise you can use a binary tree to perform the search or just use a linear search as birryree says...
Thank #nevets1219 for pointing out that the code below only deals with positive numbers.
I haven't tested this code enough, but it's a start:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> nums;
nums.push_back(1);
nums.push_back(6);
nums.push_back(2);
nums.push_back(5);
nums.push_back(3);
nums.push_back(7);
nums.push_back(4);
int first = 0;
int second = 0;
int third = 0;
for (int i = 0; i < nums.size(); i++)
{
if (nums.at(i) > first)
{
third = second;
second = first;
first = nums.at(i);
}
else if (nums.at(i) > second)
{
third = second;
second = nums.at(i);
}
else if (nums.at(i) > third)
{
third = nums.at(i);
}
std::cout << "1st: " << first << " 2nd: " << second << " 3rd: " << third << std::endl;
}
return 0;
}
The following solution finds the three largest numbers in O(n) and preserves their relative order:
std::vector<int>::iterator p = std::max_element(vec.begin(), vec.end());
int x = *p;
*p = std::numeric_limits<int>::min();
std::vector<int>::iterator q = std::max_element(vec.begin(), vec.end());
int y = *q;
*q = std::numeric_limits<int>::min();
int z = *std::max_element(vec.begin(), vec.end());
*q = y; // restore original value
*p = x; // restore original value
A general solution for the top N elements of a vector:
Create an array or vector topElements of length N for your top N elements.
Initialise each element of topElements to the value of your first element in your vector.
Select the next element in the vector, or finish if no elements are left.
If the selected element is greater than topElements[0], replace topElements[0] with the value of the element. Otherwise, go to 3.
Starting with i = 0, swap topElements[i] with topElements[i + 1] if topElements[i] is greater than topElements[i + 1].
While i is less than N, increment i and go to 5.
Go to 3.
This should result in topElements containing your top N elements in reverse order of value - that is, the largest value is in topElements[N - 1].