I have an array of 16 numbers that i need to sort in descending order, I tried sorting them this way but can't seem to make it work.
Note : I have to program an algorithm so i can't use any special functions :(
#include <stdio.h>
#include <stdlib.h>
int main() {
int i, temp1, temp2;
int string2[16] = { 0, 4, 2, 5, 1, 5, 6, 2, 6, 89, 21, 32, 31, 5, 32, 12 };
_Bool check = 1;
while (check) {
temp1 = string2[i];
temp2 = string2[i + 1];
if (temp1 < temp2) {
string2[i + 1] = temp1;
string2[i] = temp2;
i = 0;
} else {
i++;
if (i = 15) {
check = !check;
}
}
}
return 0;
}
I realize that this is pretty basic stuff for most of you but any insight is much appreciated!
There're a few problems:
_Bool is a strange thing to use in C++ (maybe this question intended for C?)
You didn't initialize i. This is called an undefined behavior. This may or may not work, depends on the computer, but it's never good to have something like that in your program.
(i=15) is an assignment. Use i==15 for comparison, as == is the comparison operator for "equal to".
Reviewed code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
int main()
{
int i = 0,temp1,temp2; //i should be initialized
int string2[16] = {0,4,2,5,1,5,6,2,6,89,21,32,31,5,32,12};
bool check=1;
while(check)
{
temp1=string2[i];
temp2=string2[i+1];
if(temp1<temp2)
{
string2[i+1]=temp1;
string2[i]=temp2;
i=0;
}
else
{
i++;
if(i==15) { check=!check; } // = -> ==
}
}
//if this is intended for C, you can ignore this bit, or use printf
for (int i = 0; i < 16; i++) { std::cout << string2[i] << " ";}
}
Output: 89 32 32 31 21 12 6 6 5 5 5 4 2 2 1 0
A few more aesthetic notes:
If you use indentation (tabs and/or space), be consistent. Others may have a hard time understanding your code, although it doesn't matter when the program compile (to anyone questioning, this is before he re-indented the code).
string2 is an irregular name of an int array. Again, it could cause confusion. A reading : https://1c-dn.com/library/rules_of_naming_variables/
You could also use std::sort with std::greater<int>() parameter:
std::sort(std::begin(string2), std::end(string2), std::greater<int>());
don't invent a bicycle except you need to learn something or you know the way how to optimize your case.
Related
What I'm trying to do
Return an integer, which would represent the number of numbers that I would need to add in order to make my array consecutive (once its sorted, first).
Sample input and output
Input: [6, 2, 3, 8].
Output: 3.
Reason: After sorting the vector to [2, 3, 6, 8], we would need 3 numbers in order to make the whole vector consecutive (4, 5, 7 need to be added to the array, hence returning 3).
Where am I at?
Took care of a base-case of 1 integer in the vector (return 0; nothing to make consecutive).
Created a counter, set to 0.
Sorted the vector, ascending.
Loop through the vector, to check:
If the difference between the value on the right and the current value != 1, then add 1 to the counter. This would mean that the next number is not consecutive, and therefore we need a number.
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdlib>
int makeArrayConsecutive2(std::vector<int> statues) {
if (statues.size() == 1) {
return 0;
}
int counter = 0;
std::sort(statues.begin(), statues.end());
for (int i = 0; i < statues.size(); i++) {
if (statues[i+1] - statues[i] != 1) {
counter += 1;
}
}
return counter;
}
So what's the issue?
4/5 of my test cases passed, except for this one:
Input: [5, 4, 6]
Expected: 0
Actual: 1
I'm having trouble understanding why this is not working for that one case. If everything else is working, how come its just this one case? I suspect its an index issue, but I tried playing around with -1 from my indexes, and still not working.
Thank you for your help.
The standard library already provides std::adjacent_difference, which can do the vast majority of the work for you:
#include <numeric>
#include <iostream>
#include <vector>
#include <algorithm>
int makeArrayConsecutive(std::vector<int> input)
{
std::sort(input.begin(), input.end());
std::vector<int> diffs;
std::adjacent_difference(input.begin(), input.end(), std::back_inserter(diffs));
std::transform(diffs.begin(), diffs.end(), diffs.begin(), [](int a) { return a - 1; });
int result = std::accumulate(diffs.begin() + 1, diffs.end(), 0);
return result;
}
int main()
{
std::cout << makeArrayConsecutive({ 6, 2, 3, 8 }) << "\n";
std::cout << makeArrayConsecutive({ 5, 4, 6 });
}
Result (as expected):
3
0
Note: I've left each operation separate for clarity. You could (for one example) pretty easily eliminate the std::transform by using a functor with std::accumulate instead:
int makeArrayConsecutive(std::vector<int> input)
{
std::sort(input.begin(), input.end());
std::vector<int> diffs;
std::adjacent_difference(input.begin(), input.end(), std::back_inserter(diffs));
int result = std::accumulate(diffs.begin() + 1, diffs.end(),
0,
[](int total, int val) { return total + val - 1; });
return result;
}
Likewise, you could eliminate the extra storage for the differences by writing the differences back into the input array, which could give a substantial reduction in storage requirements if the input was very big:
int makeArrayConsecutive(std::vector<int> input)
{
std::sort(input.begin(), input.end());
std::adjacent_difference(input.begin(), input.end(), input.begin());
int result = std::accumulate(input.begin() + 1, input.end(),
0,
[](int total, int val) { return total + val - 1; });
return result;
}
...but if you're just trying to figure out what's going on, I think the first version is probably the simplest to follow.
These are the corrected lines:
for (int i = 0; i < statues.size()-1; i++) {
if (statues[i+1] - statues[i] != 1) {
counter += statues[i+1] - statues[i] -1;
}
}
Here is my code: (C++)
#include <iostream>
#include <stdlib.h>
using namespace std;
int main(){
string sentence[9];
string word[9];
inb b[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int f = 0;
for (int i = 1; i <= 10; i += 1){
cin >> sentence[i - 1];
}
for (int a = 10; a > 1; a = a - b[f]){
b[f] = 0;
int f = rand() % 10;
b[f] = 1;
word[f] = sentence[f];
cout << world [f] << endl;
}
}
However, when I run this I get a "runtime error". That's it, no line, no further error. Nothing.
The Arrays in the bottom side of the code, like word[f] and b[f] do not work if I use f inside the "[]"'s.
When I change all the "f"'s with [1] to test the code, it works. But when I use "f"'s instead, it returns a runtime error.
Not sure if that is my compiler. But hey - I am a 2 day old C++ coder.
Your sentence is 9 "slots" big (addressed as sentence[0] to sentence[8]). You try to put something in the 10th slot (sentence[9]), which is a no-no.
(This pattern is repeated below with word.)
You most likely want to declare those arrays as 10-element ones.
That's because sentence and word contain nine units. But rand()%10 will produce 9, when you use word[f] = sentence[f], word[9] and sentence[9] are out of range. word[9] is the 10th element of array word.
There are several problems with your code. Firstly, sentence and word only have 9 entries, but you try to use 10. Array declaration is 1-based, e.g.
char foo[2];
declares two characters. However, they are numbered 0 and 1, thus
char foo[2];
foo[0] = 'a'; //valid
foo[1] = 'b'; //valid
foo[2] = 'c'; //very bad.
this problem might be obfuscated for you by the fact that you are making 'b' an auto-sized array.
The second problem is that you declare 'f' twice.
int f = 0;
for (int i = 1; i <= 10; i += 1){
and inside the loop
int f = rand() % 10;
b[f] = 1;
Your for loop, then, is broken:
for (int a = 10; a > 1; a = a - b[f]){
it uses the external 'f', which is always 0, to access element zero of b and subtract that from a.
Here is how I would write the code you're trying to write:
I honestly don't understand what your code is supposed to do, but here is how I might write a simpler version of the same thing:
#include <iostream>
#include <stdlib.h>
#include <array>
//using namespace std; <-- don't do this.
int main(){
std::array<std::string, 10> sentence; // ten strings
// populate the array of sentences.
for (size_t i = 0; i < sentence.size(); ++i) { // use ++ when ++ is what you mean.
std::cin >> sentence[i];
}
for (size_t i = 0; i < sentence.size(); ++i) {
size_t f = rand() % sentence.size(); // returns a value 0-9
std::cout << sentence[f] << " ";
}
std::cout << std::endl;
}
Requires C++11 (-std=c++11 compiler option). ideone live demo here
The output is supposed to be in this fashion
I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I
I was wondering if there is anyway to make my program shorter.
Maybe use 2 while loops or 2 for loops instead of 4.
#include<iostream>
#include<conio.h>
using namespace std;
void main()
{
char a[]={'I','N','D','I','A'};
int r,c;
for(r=1;r<=5;r++)
{
for(c=0;c<r;c++)
cout<<a[c]<<" ";
cout<<endl;
}
for(r=5;r>=0;r--)
{
for(c=0;c<r;c++)
cout<<a[c]<<" ";
cout<<endl;
}
_getch();
}
This is nice and short, if you have C++11:
#include <stdio.h>
#include <initializer_list>
int main() {
for (int i : {1,3,5,7,9,9,7,5,3,1})
printf ("%.*s\n", i, "I N D I A") ;
}
I put it on ideone at this link.
The "cheating" ;-) but very short solution is
#include <cstdio>
int main() {
puts("I\nIN\nIND\nINDI\nINDIA\nINDIA\nINDI\nIND\nIN\nI\n");
}
Yet another solution based on TonyK's beautiful idea (works in C and C++):
#include <stdio.h>
int main() {
for (int i = 1; i < 11; ++i)
printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") ;
}
Update: (After TonyK's comment):
If you want spaces, then replace the printf above with this
printf("%.*s\n", 2*(i < 6 ? i : 11 - i), "I N D I A ");
Update: A solution with no loop:
#include <stdio.h>
int main(int i, char**) {
return printf("%.*s\n", i < 6 ? i : 11 - i, "INDIA") - 1 && main(i + 1, 0);
}
Detailed explanations for the benefit of beginners follow.
The most important point is that this is an "academic" exercise. The code is obscure and one should refrain from writing serious code like this.
The standard doesn't fix a particular signature for the function main. It only says that it must return an int and the compiler must accept two particular forms:
int main();
int main(int argc, char** argv);
I'm using the second one. The more popular form int main(int argc, char* argv[]) is equivalent to (2). Indeed, in general, an array of T used as a function argument is implicitly converted to pointer to T. In this example, char* argv[] is an array of pointer to char which becomes a pointer to pointer to char. The above program is not using the second parameter though (it's either ignored or given a NULL, i.e. 0 value).
Instead of doing a loop, the program calls main recursivelly. Actually, this is illegal but the major compilers turn a blind eye to it (at most GCC gives a warning if you ask it to be pedantic with option -Wpedantic). When the program is called from the command line with no arguments the operating system calls main passing 1 (which is 1 + the number of arguments) and a pointer to pointer to char which, as said, is ignored by this program. Hence, i = 1 at the first call.
Subsequently, main potentially calls itself incrementing i each time. In summary, main is sequentially called with i being 1, 2, 3, 4, ...
It's easy to see that for this sequence of values for i, the expression i < 6 ? i : 11 - i evaluates to 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, ... (This can also be expressed by 5.5 - abs(5.5 - i) as per Drew Dorman's solution but using the ternary operator avoids the need to #include <cmath> which saves a line ;-) These numbers are the quantity of characters of "INDIA" that should be displayed at each time.
The call printf("%.s\n", j, "INDIA"), where j = i < 6 ? i : 11 - i, displays the first j characters of "INDIA" followed by a new line and returns the number of characters effectivelly printed (including the new line), i.e. j + 1. Taking away 1 yields j.
We recall now an important point of the semantics of a && b, for integers a and b. If a == 0, then b is not evaluated. Otherwise, b is evaluated. For us, a = printf("%.*s\n", j, "INDIA") - 1 (i.e. a = j) and b = main(i + 1, 0).
Now, let's put these pieces together.
1. Initially, i = 1 and j = 1. The call to printf outputs "I\n" and returns 2. Taking away 1, gives a = 1 != 0. Therefore, b = main(2, 0) is evaluated (that is, main(2, 0) is called).
2. Well, for this second call to main, we have i = 2, j = 2, printf displays "IN\n", a = 2 != 0 and b = main(3, 0) is evaluated.
Repeating this argument, at each call to main we have:
3. i = 3, j = 3, "IND\n" is printed, a = 3 != 0 and main(4, 0) is called.
4. i = 4, j = 4, "INDI\n" is printed, a = 4 != 0 and main(5, 0) is called.
5. i = 5, j = 5, "INDIA\n" is printed, a = 5 != 0 and main(6, 0) is called.
6. i = 6, j = 5, "INDIA\n" is printed, a = 5 != 0 and main(7, 0) is called.
7. i = 7, j = 4, "INDI\n" is printed, a = 4 != 0 and main(8, 0) is called.
...
10. i = 10, j = 1, "I\n" is printed, a = 1 != 0 and main(11, 0) is called.
11. i = 11, j = 0, "\n" is printed, a = 0. Now main(12, 0) is not exectued and the main returns
Notice that main in step 1 calls main in step 2, which calls main in step 3, ... which calls main in step 11. Therefore, main in step 11 returns to main in step 10, which returns to main in step 9, ..., which returns to main in step 1. Finally, main in step 1 returns to the operating system.
If you are interested in even more obfuscated code, see present and past winners of the IOCCC. Enjoy!
Shorter.
#include <iostream>
#include <cmath>
int main()
{
char a[]={'I','N','D','I','A'};
for(int r=1;r<=10;r++)
{
int c = 5.5 - std::abs(5.5 - r);
std::cout << std::string(a, 0, c) << std::endl;
}
}
You could use substr.
Additionally, if you want to add spaces between the characters (as it's in your code right now) you could do that once for the whole word and then work on that modified string:
input = "INDIA";
modifiedInput = ...; // Figure out a way to get "I N D I A " here
for (int i = 1; ...)
cout << substr(modifiedInput, 0, 2 * i) << endl;
...
smth like this:
Anyway, 2 loops is hard thing)
int i=1;
bool ind=0;
for(r=0;r<10;r++)
{
if (ind == 0){
for(c=0;c<i;c++)
cout<<a[c]<<" ";
i++; }
if (ind == 1){
for(c=0;c<i;c++) cout<<a[c]<<" ";
i--;
}
if (i % 5 == 0) ind=1;
cout<<endl;
}
Here is an example using two loops:
#include<iostream>
using namespace std;
int main()
{
char a[]={'I','N','D','I','A'};
int arr_length=5;
bool two_times=false;//if you want to output INDIA twice
for(int i=2*arr_length-1; i>=1; i--)
{
for(int j=0; j<arr_length-abs(arr_length-i); j++)
{
cout << a[j];
}
if(i==arr_length && !two_times){ two_times=true; i++;}//if you want to output INDIA twice
cout << endl;
}
return 0;
}
Output:
I
IN
IND
INDI
INDIA
INDIA
INDI
IND
IN
I
You can do like this:
void main()
{
char a[]={'I','N','D','I','A'};
int r,c;
int x = 0; // initially x is 0
int l = 5;
for(r=1;r<= 11 ;r++) //loop runs for 5*2 + 1 times
{
if(r>=6){
x = l - r % 6; //set x to remaining length
l--;
}
for(c=0;c< (r % 6) + x; c++) // add x
cout<<a[c]<<" ";
cout<<endl;
}
}
and you can find it working here.
Another solution based on TonyK's answer. You can enter your desired string.
#include <stdio.h>
#include <string.h>
int main() {
char s[100];
gets(s);
for (int i = 0; i < strlen(s) * 2; i++)
printf ("%.*s\n", i < strlen(s) ? i + 1: 2 * strlen(s) - i, s);
}
http://ideone.com/Zsg5Lu
I'm kind of a beginner with programming, but while writing a program of my own, I ran into a roadblock that I can't seem to get around.
Anyway, given a set of numbers like these in an array:
4
14
24
27
34
You can see how all of the numbers except one have a 4 in the ones place. How would I write a function that can return the number that is different in the ones place, 27 in this case? The numbers would be different every time the program is run, but due to the scenario, 4 of them will always have the same digit in the ones place. They wouldn't necessarily be in numerical order.
I couldn't seem to find a way to do it mathematically, nor was I able to find anything through search. Any ideas?
Jerry Coffin's solution is unnecessarily O(log N); it can be improved by using std::partition rather than std::sort:
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
int first = n[0]%10;
std::partition(std::next(std::begin(n)), std::end(n),
[&](int a) { return first == a%10;});
std::cout << ((first != n[1]%10) ? n.front() : n.back());
}
But that still does way too many comparisons. The problem can be solved with at most (N+1)/2 comparisons:
#include <iostream>
#include <vector>
int odd_man_out(const std::vector<int> n) {
size_t i;
for (i = 0; i + 2 < n.size(); i += 2) {
if (n[i]%10 != n[i+1]%10)
return n[i]%10 != n[i+2]%10 ? i : i + 1;
}
if (i + 2 == n.size() && n[i]%10 == n[i-1]%10)
return i + 1;
else
return i;
}
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
std::cout << n[odd_man_out(n)];
}
Here's one way to do the job. Definitely not the most efficient possible, but kind of nice anyway. This one will work for any number of inputs, as long as only one is different from the rest (in the units digit, obviously).
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
std::sort(std::begin(n), std::end(n),
[](int a, int b) { return a%10 < b%10;});
std::cout << ((n[0]%10 < n[1]%10) ? n.front() : n.back());
}
Edit: I decided to add another. While this still does more comparisons than #Rici's (very nice) solution, it's at least linear (and doesn't rearrange the original data):
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
std::vector<int> n = {4, 14, 27, 24, 34};
auto pos = std::adjacent_find(std::begin(n), std::end(n),
[](int a, int b) { return a%10 != b%10; });
if (pos != std::begin(n))
std::cout << pos[1];
else
std::cout << n[n[1]%10 != n[2]%10];
}
Write a program using % operator to take the unit place value
void check ()
{
int i, changeIndex =0;
for ( i = 0; i < 5; i++)
{
for (int k = 0; k < 5; k++)
{
if (a[i]%10 == a[k]%10)
{
changeIndex++;
}
}
if (changeIndex != 4)
{
break;
}
changeIndex = 0;
}
cout<<a[i];
}
This will work for a count of 5 and if only one of the numbers have a different unit place value
here you go... :p
works for any number of inputs... and even detects if they're all the same.
#include <iostream>
int main() {
int a[] = {4,14,24,34,27,94};
// assume a has more than 2 elements, otherwise, it makes no sense
unsigned ri = 0;
if (a[1]%10 == a[0]%10) {
for (ri = 2; (ri < sizeof(a)/sizeof(a[0])) && (a[ri]%10 == a[0]%10); ri++);
} else if (a[2]%10 == a[0]%10)
ri = 1;
if (ri < sizeof(a)/sizeof(a[0]))
std::cout << "weird number is a["<< ri <<"] = "<<a[ri] << std::endl;
else
std::cout<<"they're all the same" << std::endl;
return 0;
}
Notice that the actual work:
if (a[1]%10 == a[0]%10) {
for (ri = 2; (ri < sizeof(a)/sizeof(a[0])) && (a[ri]%10 == a[0]%10); ri++);
} else if (a[2]%10 == a[0]%10)
ri = 1;
is only 4 lines long! :p
check it out on liveworkspace
The run time is max(1,[location of the exception #]), which is O(n) where n is the size of a.
Though, I've tried to summarize the question in the title, I think it'll be better if I start off with an instance of the problem:
List of Primes = {2 3 5 7 11 13}
Factorization pattern = {1 1 2 1}
For the above input, the program should be generating the following list of numbers:
2.3.5^2.7
2.3.5^2.11
2.3.5^2.13
2.3.7^2.11
2.3.7^2.13
2.3.11^2.13
2.5.7^2.11
2.5.7^2.13
2.7.11^2.13
3.5.7^2.11
3.5.7^2.13
3.5.11^2.13
3.7.11^2.13
5.7.11^2.13
So far, I understand that since the length of the pattern is arbitrarily large (as is the list of primes), I need to use a recursive function to get all the combinations. What I'm really, really stuck is - how to formulate the function's arguments/when to call etc. This is what I've developed so far:
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
static const int factors[] = {2, 3, 5, 7, 11, 13};
vector<int> vFactors(factors, factors + sizeof(factors) / sizeof(factors[0]));
static const int powers[] = {1, 1, 2, 1};
vector<int> vPowers(powers, powers + sizeof(powers) / sizeof(powers[0]));
// currPIdx [in] Denotes the index of Power array from which to start generating numbers
// currFidx [in] Denotes the index of Factor array from which to start generating numbers
vector<int> getNumList(vector<int>& vPowers, vector<int>& vFactors, int currPIdx, int currFIdx)
{
vector<int> vResult;
if (currPIdx != vPowers.size() - 1)
{
for (int i = currPIdx + 1; i < vPowers.size(); ++i)
{
vector<int> vTempResult = getNumList(vPowers, vFactors, i, currFIdx + i);
vResult.insert(vResult.end(), vTempResult.begin(), vTempResult.end());
}
int multFactor = pow((float) vFactors[currFIdx], vPowers[currPIdx]);
for (int i = 0; i < vResult.size(); ++i)
vResult[i] *= multFactor;
}
else
{ // Terminating the recursive call
for (int i = currFIdx; i < vFactors.size(); ++i)
{
int element = pow((float) vFactors[i], vPowers[currPIdx]);
vResult.push_back(element);
}
}
return vResult;
}
int main()
{
vector<int> vNumList = getNumList(vPowers, vFactors, 0, 0);
cout << "List of numbers: " << endl;
for (int i = 0; i < vNumList.size(); ++i)
cout << vNumList[i] << endl;
}
When I'm running the above, I'm getting a incorrect list:
List of numbers:
66
78
650
14
22
26
I've somehow run into a mental block, as I can't seem to figure out how to appropriately change the last parameter in the recursive call (which I believe is the reason my program isn't working)!!
It would be really great if anyone would be good enough to tweak my code with the missing logic (or even point me to it - I'm not looking for a complete solution!). I would be really grateful if you could restrict your answer to standard C++!
(In case someone notices that I'm missing out permutations of the given pattern, which would lead to other numbers such as 2.3.5.7^2 etc - don't worry, I intend to repeat this algorithm on all possible permutations of the given pattern by using next_permutate!).
PS: Not a homework/interview problem, just a part of an algorithm for a very interesting Project Euler problem (I think you can even guess which one :)).
EDIT: I've solved the problem on my own - which I've posted as an answer. If you like it, do upvote it (I can't accept it as the answer till it gets more votes than the other answer!)...
Forget about factorization for a moment. The problem you want to solve is having two lists P and F and finding all possible pairings (p,f) for p in P and f in F. This means you'll have |P| * |P|-1 ... * |P|-(|F|-1) possible pairings (assigning one from P to the first element of F, leaves |P|-1 possibilities to match the second element etc). You might want to separate that part of the problem in your code. If you recurse that way, the last step is choosing remaining element from P to the last element of F. Does that help? I must admit I don't understand your code well enough to provide an answer tailored to your current state, but that's how I'd approach it in general.
Well, I figured out this one on my own! Here's the code for it (which I hope is self-explanatory, but I can clarify in case anyone needs more details):
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
static const int factors[] = {2, 3, 5, 7, 11, 13};
vector<int> vFactors(factors, factors + sizeof(factors) / sizeof(factors[0]));
static const int powers[] = {1, 1, 2, 1};
vector<int> vPowers(powers, powers + sizeof(powers) / sizeof(powers[0]));
// idx - The index from which the rest of the factors are to be considered.
// 0 <= idx < Factors.size() - Powers.size()
// lvl - The lvl of the depth-first tree
// 0 <= lvl < Powers.size()
// lvlProd - The product till the previous level for that index.
void generateNumList
(
vector<int>& vPowers,
vector<int>& vFactors,
vector<int>& vNumList,
int idx,
int lvl,
long lvlProd
)
{
// Terminating case
if (lvl == vPowers.size() - 1)
{
long prod = pow((float) vFactors[idx], vPowers[lvl]) * lvlProd;
vNumList.push_back(prod);
}
else
{
// Recursive case
long tempLvlProd = lvlProd * pow((float) vFactors[idx], vPowers[lvl]);
for (int i = idx + 1; i < vFactors.size(); ++i)
generateNumList(vPowers, vFactors, vNumList, i, lvl + 1,
tempLvlProd);
}
}
vector<int> getNumList(vector<int>& vPowers, vector<int>& vFactors)
{
vector<int> vNumList;
for (int i = 0; i < vFactors.size(); ++i)
generateNumList(vPowers, vFactors, vNumList, i, 0, 1);
return vNumList;
}
int main()
{
vector<int> vNumList = getNumList(vPowers, vFactors);
cout << endl << "List of numbers (" << vNumList.size() << ") : " << endl;
for (int i = 0; i < vNumList.size(); ++i)
cout << vNumList[i] << endl;
}
The output of the above code (I had to work really long to get rid of duplicate entries algorithmically! ):
List of numbers (15) :
1050
1650
1950
3234
3822
9438
5390
6370
15730
22022
8085
9555
23595
33033
55055
real 0m0.002s
user 0m0.001s
sys 0m0.001s