set intersection - c++

I want to calculate the gcd of two numbers m and n by prime factorization and taking common factors
like this. Take example m = 36 n = 48
vector<int> factors1 = prime_factorization(m); // 2 2 3 3
vector<int> factors2 = prime_factorization(n); // 2 2 2 2 3
vector<int> intersection(10);
set_intersection(factors1.begin(), factors1.end(), factors2.begin(), factors2.end(), intersection.begin());
intersection is now 2 2 3 0 0 0 0 0 0 0. For this i must set the size of the vector beforehand. Also the remaining elements are set to 0. I don't want this to happen.
Is there a better way to do this? Using sets or anything else?
Also, how do i calculate the product of elements in the vector intersection (2*2*3) using stl ignoring the zeroes?

You can use a back-inserter:
vector<int> intersection;
set_intersection(..., back_inserter(intersection));
Note that there are much better ways of determining the GCD, such as Euclid's algorithm.

Oli's answer is best in the situation as you describe it. But if you were using a vector that already existed and had elements that you were writing over, and you wanted to chop off the extra numbers, you can do it a different way. By calling the vector member erase using the return value of set_intersection:
intersection.erase(
set_intersection(factors1.begin(), factors1.end(), factors2.begin(), factors2.end(), intersection.begin()),
intersection.end());

Related

Every sum possibilities of elements

From a given array (call it numbers[]), i want another array (results[]) which contains all sum possibilities between elements of the first array.
For example, if I have numbers[] = {1,3,5}, results[] will be {1,3,5,4,8,6,9,0}.
there are 2^n possibilities.
It doesn't matter if a number appears two times because results[] will be a set
I did it for sum of pairs or triplet, and it's very easy. But I don't understand how it works when we sum 0, 1, 2 or n numbers.
This is what I did for pairs :
std::unordered_set<int> pairPossibilities(std::vector<int> &numbers) {
std::unordered_set<int> results;
for(int i=0;i<numbers.size()-1;i++) {
for(int j=i+1;j<numbers.size();j++) {
results.insert(numbers.at(i)+numbers.at(j));
}
}
return results;
}
Also, assuming that the numbers[] is sorted, is there any possibility to sort results[] while we fill it ?
Thanks!
This can be done with Dynamic Programming (DP) in O(n*W) where W = sum{numbers}.
This is basically the same solution of Subset Sum Problem, exploiting the fact that the problem has optimal substructure.
DP[i, 0] = true
DP[-1, w] = false w != 0
DP[i, w] = DP[i-1, w] OR DP[i-1, w - numbers[i]]
Start by following the above solution to find DP[n, sum{numbers}].
As a result, you will get:
DP[n , w] = true if and only if w can be constructed from numbers
Following on from the Dynamic Programming answer, You could go with a recursive solution, and then use memoization to cache the results, top-down approach in contrast to Amit's bottom-up.
vector<int> subsetSum(vector<int>& nums)
{
vector<int> ans;
generateSubsetSum(ans,0,nums,0);
return ans;
}
void generateSubsetSum(vector<int>& ans, int sum, vector<int>& nums, int i)
{
if(i == nums.size() )
{
ans.push_back(sum);
return;
}
generateSubsetSum(ans,sum + nums[i],nums,i + 1);
generateSubsetSum(ans,sum,nums,i + 1);
}
Result is : {9 4 6 1 8 3 5 0} for the set {1,3,5}
This simply picks the first number at the first index i adds it to the sum and recurses. Once it returns, the second branch follows, sum, without the nums[i] added. To memoize this you would have a cache to store sum at i.
I would do something like this (seems easier) [I wanted to put this in comment but can't write the shifting and removing an elem at a time - you might need a linked list]
1 3 5
3 5
-----
4 8
1 3 5
5
-----
6
1 3 5
3 5
5
------
9
Add 0 to the list in the end.
Another way to solve this is create a subset arrays of vector of elements then sum up each array's vector's data.
e.g
1 3 5 = {1, 3} + {1,5} + {3,5} + {1,3,5} after removing sets of single element.
Keep in mind that it is always easier said than done. A single tiny mistake along the implemented algorithm would take a lot of time in debug to find it out. =]]
There has to be a binary chop version, as well. This one is a bit heavy-handed and relies on that set of answers you mention to filter repeated results:
Split the list into 2,
and generate the list of sums for each half
by recursion:
the minimum state is either
2 entries, with 1 result,
or 3 entries with 3 results
alternatively, take it down to 1 entry with 0 results, if you insist
Then combine the 2 halves:
All the returned entries from both halves are legitimate results
There are 4 additional result sets to add to the output result by combining:
The first half inputs vs the second half inputs
The first half outputs vs the second half inputs
The first half inputs vs the second half outputs
The first half outputs vs the second half outputs
Note that the outputs of the two halves may have some elements in common, but they should be treated separately for these combines.
The inputs can be scrubbed from the returned outputs of each recursion if the inputs are legitimate final results. If they are they can either be added back in at the top-level stage or returned by the bottom level stage and not considered again in the combining.
You could use a bitfield instead of a set to filter out the duplicates. There are reasonably efficient ways of stepping through a bitfield to find all the set bits. The max size of the bitfield is the sum of all the inputs.
There is no intelligence here, but lots of opportunity for parallel processing within the recursion and combine steps.

How to find the largest sum with the smallest possible path in a tetrahedron of integers?

First here is the question,
Say that an integer can be represented as a perfect sphere, in which the value of the sphere is equal to the integer it contains. The spheres are organized into a tetrahedral pyramid in which N = the length of the side, N being between 1 and 15. Pick (a possibly empty) subset of sphere's such that their sum of values is maximized. Note that the sphere can hold a negative value so it is not necessarily desirable to pick up every sphere. We do not want to disorganize the pyramid so we cannot take any one sphere without first taking the ones above it.
Input Format:
Line 1: integer N
Line 2: N(N+1)/2+1
Output Format:
Line 1: One integer, the maximum sum of values achievable
Sample Input:
3
5
-2 -7
-3
1 0 8
0 3
2
Sample Output:
8
Here is a sample solution given to my understanding so far:
The best solution is shown as bold in the diagram bellow. It is not smart to take 1 because that would require taking -2, decreasing the total. There for 8, 3, and 2 should be taken because they outweigh -3 and -7.
My question is,
How do I store the input so that I can retain the proper order? Or do i even need to? I am trying to use a queue but my program gets very lengthly because I have to find the sum for each possible path and then compare each sum to find the max. I am also having a lot of difficulty breaking the data up into the right pattern so I don't recount a number or take one out of sequence. Is there a more efficient way to do this? Can Dijkstra's algorithm be of any use in this case? If so, then how? Any help is greatly appreciated!!
I would use a 3-dimensional array. To use your example:
A[0][0][0] = 5
A[1][0][0] = -2
A[1][1][0] = -3
A[1][0][1] = -7
A[2][0][0] = 1
A[2][1][0] = 0
A[2][2][0] = 2
A[2][0][0] = 0
A[2][1][0] = 3
A[2][0][0] = 8
The "above" relationship is simply a matter of index arithmetic: [ia, ja, ka] is above [ia+1, ja, ka], [ia+1, ja+1, ka] and [ia+1, ja, ka+1].

Algorithm to get permutation from an index from the hypothetical list of all combinations?

here is what I mean:
Assuming we have X number of colours and a 4x4 grid of 16 squares, we can colour any of the squares with any colour.
Assuming you can generate a list of all possible configurations and the algorithm spits them out one after another(configuration#1, then configuration#2 and so on), is there a way to use a number i and get configuration#i right off the bat?
(since storing 1e+16 configurations is not possible on normal hardware)
And more importantly, is it possible to have an inverse of this algorithm and to instead give it a configuration, for which it will return an i that when plugged back in will return the original configuration? Something like this:
int colours[4][4] = GenerateSomeConfig(); // Gets some combination of colours
int i = GetIndex(colours); // This is the main function I was asking about
int colours2[4][4] = GetConfig(i); // This is the reverse of GetIndex()
assert(CompareGridsEqual(colours, colours2)); // This shouldn't break
Those are combinations with repetition.
Anyways. Let's simplify problem just a little bit. Let us say we have 10 colours. Numbered 0 to 9. Lets also number our squares, from 1 to 16 (or whatever. You say 4x4, your code says 16x16 but it's not important).
You can use the number of the color of the box. So you would end up with lets say:
0 9 6 3
4 7 5 1
0 2 1 7
5 2 3 4
Now you can take the grid, and make it a stripe - 0 9 6 3 4 7 5 1 0 2 1 7 5 2 3 4. Remove spaces and you have your mapping.
To use different number of colors, use different base. Different size of grid will result in different number of digits in the encoded number.
You should be able to take off from this hint. I'm not going to write a c++ implementation to match your effort =P, and I think you should be able to do it. The only technical difficulty is to deal with numbers of arbitrary base.
As I said in the comment, it is possible for every algorithm that generates the configurations to create a wrapper that converts a configuration to integer and vice versa.
The simplest and general solution would be like this:
config_t GetConfig(size_t index)
{
Generator gen;
for(size_t i = 0; i < index; ++i) gen.GetNextConfig();
return gen.GetNextConfig();
}
size_t GetIndex(const config_t & conf)
{
size_t ret = 0;
Generator gen;
while(gen.GetNext() != conf) ++ret;
return ret;
}
This is obviously not very efficient way of doing it, but it shows that it's possible. If you need to do it more efficiently you'll probably have to sacrifice generality and implement it specifically for the one generator. #luk32's answer shows you the way of doing it for a very simple generator, but of course there can be more complex generators.

Issue when generate random vectors with limits on matlab

I have a problem, I want to generate a table of 4 columns and 1 line, and with integers in the range 0 to 9, without repeating and are random each time it is run.
arrives to this, but I have a problem I always generates a 0 in the first element. And i dont know how to put a limit of 0-9
anyone who can help me?
Code of Function:
function [ n ] = generar( )
n = [-1 -1 -1 -1];
for i = 1:4
r=abs(i);
dig=floor((r-floor(r))*randn);
while find (n == dig)
r=r+1;
dig=dig+floor(r-randn);
end
n(i)=dig;
end
end
And the results:
generar()
ans =
0 3 9 6
generar()
ans =
0 2 4 8
I dont know if this post is a duplicate, but i need help with my specific problem.
So assuming you want matlab, because the code you supplied is matlab, you can simply do this:
randperm(10, 4) - 1
This will give you 4 unique random numbers from 0-9.
Another way of getting there is randsample(n, k) where n is an integer, then a random sample of size k will be drawn from the population 1:n (as a column vector). So for your case, you would get the result by:
randsample(10, 4)' - 1
It draws 4 random numbers from the population without replacement and all with same weights. This might be slower than randperm(10, 4) - 1 as its real strength comes with the ability to pass over population vectors for more sophisticated examples.
Alternatively one can call it with randsample(pop, k) where pop is the population-vector of which you want to draw a random sample of size k. So for your case, one would do:
randsample(0:9, 4)
The result will have the same singleton dimension as the population-vector, which in this case is a row vector.
Just to offer another solution and get you in touch with randsample().

Position of elements in vector

I have several elements in a vector type that are read from cin and then i perfrom some calculations on the vector and it's order of elements gets changed. The problem is that I need to print the positions of the vector elements after the calculations. I don't know how to explain this well that's why i'll give an example:
10 1 100 1000
and 10 is 1st element, 1 is 2nd, 100 is 3rd etc. After the calculations the vector changes in :
100 10 1 1000
so I should print
3 1 2 4
because 100 is the 3rd element of the input, 10 is the 1st etc. etc.
I tried with an array[1000] (because there aren't numbers larger than 1000 in the input), but it won't work because there can be multiple numbers with the same value, like:
10 10 10 100
and the output can be 1 2 3 4 or 2 3 1 4 or 3 1 2 4 etc. but here i need to output 1 2 3 4 because it's the 'smallest'.
I tried with array f[1001] and f[10] = 1, f[100] = 2, f[1] = 3 - if the numbers from the input are 10 100 1. But in case there are multiple numbers with the same value like 10 10 100, then my idea's not working. Please help me in any possible way.
Sounds like you need to store both the value and the initial position. You should be able to do this with an array of structs:
struct UserInput
{
unsigned int initialPosition;
int userInputValue;
};
int main()
{
userInput theUserInput[100];
// increment a counter, starting at 1, and place it in
// "initialPosition" in the struct as user input is read
}
I'll leave the rest up to you... as it is after all homework :) good luck.
Use an associative array if you know what it is.
Use linear search to determine the index if the number of input is limited.
Consider using log10 (or strlen) to transform the 1, 10, 100, 1000, etc. into 0, 1, 2, 3, etc.
From your description of such example:
10(3) 10(2) 10(1) 100(4)
What we have to output is 1 2 3 4, instead of 3 2 1 4.
So I don't think your requirement is just print the initial position directly. You've to make the position sequences as small as possible.
Following is my solution:
Use a direct-mapping hash table to store all the initial positions for specified element. All the initial positions for the same element is sorted. So if you want output the smallest position sequence, you only need to read the initial positions for this specified element from first to last.
The detailed implementation is left to you, since it's a homework.