How to find the second minimum number without using arrays or loops - c++

I tried to write a program that receive from the user 5 integers and print the second minimum number.
Here is a sample of what I've tried:
#include <iostream>
using namespace std;
int main () {
int a,b,c,d,e;
cin>>a>>b>>c>>d>>e;
if (a>b && a<c && a<d && a<e)
cout<<a<<endl;
if (b>a && b<c && b<d && b<e)
cout<<b<<endl;
if (c>a && c<b && c<d && c<e)
cout<<c<<endl;
if (d>a && d<b && d<c && d<e)
cout <<d<<endl;
if (e>a && e<b && e<c && e<d)
cout <<e<<endl;
return 0;
}
When I enter 1 2 3 4 5 it prints the second minimum, but when I enter
5 4 3 2 1 Nothing will print on the screen. What am I doing wrong with this? Is there any other way to write my program?

The problem you have with your logic is that you do not enforce yourself to print only 1 item, and at least one item.
By using the 'else' part of the if/else syntax, you will ensure that only one branch can ever be hit. You can then follow this up with just an else at the end, as you know all other conditions are false.
Once you've done this, you'll see that you print the last value, (1) rather than the expected (4). This is because your logic regarding how to find the 2nd lowest is wrong. b>a is false for the case 5,4...
Note:
Every employed engineer, ever, would make this a loop in a std::vector / std::array, and I would suggest you point your teacher to this post because encouraging loops is a good thing rather than bad.
Something like
vector<int> data;
for (int i=0; i<5; ++i) {
int t;
cin >> t;
data.push_back(t);
}
std::nth_element(data.begin(), data.begin()+1, data.end(), std::greater<int>());
cout << data[1];

There are 120 possible permutations on 5 elements. Your code should output the correct number for all of them. So a fool-proof code would use 120 repetitions of a check, like the following:
if (a > b && b > c && c > d && d > e) // the order is a>b>c>d>e
cout << d;
else if (a > b && b > c && c > e && e > d) // the order is a>b>c>e>d
cout << e;
...
else if (e > d && d > c && c > a && e > b) // the order is e>d>c>a>b
cout << a;
else // the order is e>d>c>b>a
cout << b;
This is very long, inefficient and tricky code. If you do a typo in just one variable, it will output a wrong answer in some rare cases. Also, it doesn't handle the possibility of some inputs being equal.
If the number of inputs to a sorting algorithm is a known small constant, you can use an approach called sorting networks. This is a well-defined computer science problem, which has well-known optimal solutions for small numbers of inputs, and 5 certainly is small. An optimal sorting network for 5 inputs contains 9 comparators, and is described e.g. here.
Since you don't need to sort the numbers, but only to know the second smallest input, you can reduce the size of the network further, to 7 comparators.
The full sorting network (without the reduction from 9 to 7) translated to C++:
if (b < c)
swap(b, c);
if (d < e)
swap(d, e);
if (b < d)
swap(b, d);
if (a < c)
swap(a, c);
if (c < e)
swap(c, e);
if (a < d)
swap(a, d);
if (a < b)
swap(a, b);
if (c < d)
swap(c, d);
if (b < c)
swap(b, c);
// now the order is a ≥ b ≥ c ≥ d ≥ e
cout << d;
This code is also obscure - not obvious at all how and why it works - but at least it is small and in a sense optimal. Also, it's clear that it always prints something (so it fixes the original problem) and supports the case of partially equal inputs.
If you ever use such code in a larger project, you should document where you took it from, and test it. Fortunately, there are exactly 120 different possibilities (or 32, if you use the
zero-one principle), so there is a way to prove that this code has no bugs.

This should work for you. (Note that it might not be the best approach and you can minimize it with a function to calculate min and secondMin instead of the ugly copy paste of the logic but it will get you started:
#include <iostream>
using namespace std;
int main () {
int a,b,c,d,e;
int min, secondMin;
cin>>a>>b;
min = a < b ? a : b;
secondMin = a < b ? b : a;
cin>>c;
if (c < min)
{
secondMin = min;
min = c;
}
else if (c < secondMin)
{
secondMin = c;
}
cin>>d;
if (d < min)
{
secondMin = min;
min = d;
}
else if (c < secondMin)
{
secondMin = d;
}
cin>>e;
if (e < min)
{
secondMin = min;
min = e;
}
else if (e < secondMin)
{
secondMin = e;
}
cout << "min = " << min << ", secondMin = " << secondMin << endl;
return 0;
}
if you have any questions feel free to ask in the comment

#include <set>
std::set<int> values = { a, b, c, d, e }; // not an array.
int second_min = *std::next(values.begin(), 1); // not a loop

What about a recursive and more generic approach?
No arrays, no loops and not limited to just 5 integers.
The following function get_2nd_min() keeps track of the two lowest integers read from std::cin a total of count times:
#include <climits>
#include <cstddef>
#include <iostream>
int get_2nd_min(size_t count, int min = INT_MAX, int second_min = INT_MAX)
{
if (!count)
return second_min; // end of recursion
// read next value from cin
int value;
std::cin >> value;
// Does second_min need to be updated?
if (value < second_min) {
// Does min also need to be updated?
if (value < min) {
// new min found
second_min = min; // move the so far min to second_min
min = value; // update the new min
} else {
// value is lower than second_min but higher than min
second_min = value; // new second_min found, update it
}
}
// perform recursion
return get_2nd_min(count - 1, min, second_min);
}
In order to read 5 integers and obtain the 2nd lowest:
int second_min = get_2nd_min(5);

One approach is to first find the minimum number, min and then find the smallest value that isn't min. To do this first find the minimum value:
int min = std::min(a, std::min(b, std::min(c, std::min(d, e))));
Now we need to do the same again, but ignoring min. We can do this using a function called triMin which takes 3 values and discards any value that is the minimum:
int triMin(int currentMin, int left, int right)
{
if(currentMin == left) return right;
if(currentMin == right) return left;
return std::min(left, right);
}
You can now combine them to get the answer:
int a = 5, b = 4, c = 3, d = 2, e = 1;
int min = std::min(a, std::min(b, std::min(c, std::min(d, e))));
int min2 = triMin(min, a, triMin(min, b, triMin(min, c, triMin(min, d, e))));
std::cout << "Second min = " << min2 << std::endl;
This prints 2

This task can be fulfilled using one-pass algorithm. There is no need to use any collections (arrays, sets or anything).
This one-pass algorithm is memory efficient - it does not require storing all elements in collection (and wasting memory) and will work even with large number of elements when other solutions fail with out of memory.
General idea of this algorithm is like this:
take each number in order
you need two variables to store minimum and second minimum numbers from all already seen numbers.
when you get number you need to test it with current minumum to find if it is new minimum number.
if it is store it as minimum, store old minimum in second minimumnumber
otherwise check if it is less than second minimum number.
if it is store it as second minimum number.
now second minimum number contains answer for all already seen numbers.
repeat while there numbers that was not seen.
After investigating all numbers second minimum contain the answer.
Here is implementation with c++17 (link to wandbox):
#include <iostream>
#include <optional>
int main()
{
int a, b, c, d, e;
std::cin >> a >> b >> c >> d >> e;
// you can find second minimal number while going through each number once
auto find_current_answer = [minimum = std::optional<int>{}, next_to_minimum = std::optional<int>{}](int next) mutable {
// when receiving next number
// 1. check if it is new minimum
if (!minimum || minimum > next) {
// move values like this: next_to_minimum <- minimum <- next
next_to_minimum = std::exchange(minimum, next);
}
// 2. else check if it is new next_to_minimum
else if (!next_to_minimum || next_to_minimum > next) {
next_to_minimum = next;
}
// 3. return current answer
return next_to_minimum;
};
// repeat as much as you like
find_current_answer(a);
find_current_answer(b);
find_current_answer(c);
find_current_answer(d);
// store answer that is interesting to you
auto result = find_current_answer(e);
// if it has value - it is the answer
if (result) {
std::cout << "Answer: " << *result << '\n';
}
else {
std::cout << "Not enough numbers!\n";
}
}

Update
In this solution I'm using the min function:
#include <iostream>
using namespace std;
int minDifferentFromFirstMin(int x, int y, int firstMin) {
if(x < y) {
if(x != firstMin) {
return x;
}
else {
return y;
}
}
if(y < x) {
if(y != firstMin) {
return y;
}
else {
return x;
}
}
//if x & y are equals, return one of them
return x;
}
int main () {
int a,b,c,d,e;
int iter11, iter12, iter13;
int iter21, iter22, iter23;
int firstMinimum, secondMinimum;
cin>>a>>b>>c>>d>>e;
//iteration 1: find the first minimum
iter11 = min(a, b);
iter12 = min(c, d);
iter13 = min(iter11, iter12);
firstMinimum = min(iter13, e);
//iteration 2: find the second minimum
iter21 = minDifferentFromFirstMin(a, b, firstMinimum);
iter22 = minDifferentFromFirstMin(c, d, firstMinimum);
iter23 = minDifferentFromFirstMin(iter21, iter22, firstMinimum);
secondMinimum = minDifferentFromFirstMin(iter23, e, firstMinimum);
cout<<secondMinimum<<endl;
}

Related

Generating an edge graph using four values a,b,c,d in c++

I'm having a trouble solving a question which asks me to generate an edge graph using 4 random numbers a,b,c,d , so the formula is as follows , to generate the nodges of the graph we'll use variable d , if we divide d with 3 and we get a remainder of 0 then 10 nodges are generated , if d/3 = 1 then 11 nodges if d/3 = 2 then 12 nodges are generated , as for the edges we have the following formula (i,j) ∈ U <-> ((ai+bj)/c) / d ≤ 1 , basically the edge will connect the nodge of i with the nodge of j if the formula after dividing by d gives a remainder smaller or equal to 1. Can someone tell me what's the problem with the code below ?
Here is the code :
#include <iostream>
#include <vector>
using namespace std;
struct Edge {
int src, dest;
};
class Graph
{
public:
vector<vector<int>> adjList;
Graph(vector<Edge> const& edges, int N)
{
adjList.resize(N);
for (auto& edge : edges)
{
adjList[edge.src].push_back(edge.dest);
}
}
};
void printGraph(Graph const& graph, int N)
{
for (int i = 0; i < N; i++)
{
cout << i << " ——> ";
for (int v : graph.adjList[i])
{
cout << v << " ";
}
cout << endl;
}
}
int main()
{
vector<Edge> edges;
int a, b, c, d,remainder,Nodges,result;
cout << "Enter 4 values : \n";
cin >> a >> b >> c >> d;
remainder = d % 3;
if (remainder == 0)
{
Nodges = 10;
}
else if (remainder == 1)
{
Nodges = 11;
}
else if (remainder == 2)
{
Nodges = 12;
}
for (int i = 0; i < Nodges; i++)
{
for (int j = 0; j < Nodges; j++)
{
result = ((a * i + b * j) / c) % d;
if (result <= 1)
{
edges =
{
{i,j}
};
}
}
}
Graph graph(edges, Nodges);
printGraph(graph, Nodges);
return 0;
}
At first you do not handle the case of d being outside of desired range. If d is e. g. 37, then you leave Nodges uninitialised, invoking undefined behaviour afterwards by reading it. You might add a final else to catch that case, printing some representation for an empty graph or a message and then return, so that you do not meet the for loops at all.
Simpler, though:
if(remainder < 3)
{
nodes = 10 + remainder;
// your for loops here
}
If you want to create an empty graph anyway, then don't forget to initialise nodes to 0; otherwise you should include the graph code in the if block above, too.
The main point your code fails is the following, though:
edges =
{
{i,j}
};
That way, you create a new vector again and again, always containing a single element, and the old one is replaced by that.
You actually need:
edges.emplace_back(i, j);
Finally: Get used to always check the stream's state after input operation. Users tend to provide invalid input, if you do not catch that you might get inexpected and actually undefined behaviour (such as dividing by 0).
if(std::cin >> a >> b >> c >> d)
{
/* your code */
}
else
{
// handle invalid input, e. g. by printing some message
// if you want to go on reading the stream:
// clears the error flags:
std::cin.clear();
// clears the stream's buffer yet containing the invalid input:
std::cin.ignore(numeric_limits<streamsize>::max(), '\n');
}

How can I find prime reversed numbers?

I have to write a program to check if the entered number has these qualifications:
A number that is prime it self, the reverse of that number is also prime, and the number's digits are prime numbers too (Like this number: 7523).
If the needs meet, it has to show "yes" when you enter and run the program otherwise "no".
I know both codes for prime and reverse numbers but I don't know how to merge them.
This is the code:
#include <iostream>
#include <conio.h>
using namespace std;
void prime_check(int x) {
int a, i, flag = 1;
cin >> a;
for (i = 2; i <= a / 2 && flag == 1; i++) {
if (a % i == 0)
flag = 0;
}
if (flag == 1)
cout << "prime";
else
break;
}
int main() {
int a, r, sum = 0;
cin >> a;
while (a != 0) {
r = a % 10;
sum = (sum * 10) + r;
a = a / 10;
}
}
The program has to check each digit of the number entered to see if it is prime or not in every step, then show "yes", but it doesn't work.
Welcome to the site.
I don't know how to merge them.
void prime_check(int n) { /*code*/ }
I'd understand that you don't know how to use this.
It's very easy!
int main()
{
int i = 0;
prime_check(i);
}
If you are confused about how the program executes, you could use a debugger to see where it goes. But since using a debugger can be a bit hard at first, I would suggest to add debug prints to see how the program executes.
This line of code prints the file and line number automatically.
std::cout << __FILE__ << ":" << __LINE__ << "\n";
I'd suggest to add it at the start of every function you wish to understand.
One step further is to make it into a macro, just so that it's easy to use.
#define DEBUGPRINT std::cout << __FILE__ << ":" << __LINE__ << "\n";
Check a working example here:
http://www.cpp.sh/2hpam
Note that it says <stdin>::14 instead of the filename because it's running on a webpage.
I have done some changes to your code, and added comments everywhere I've made changes. Check it out:
#include <iostream>
#include <conio.h>
using namespace std;
bool prime_check(int x) { // I have changed the datatype of this function to bool, because I want to store if all the digits are prime or not
int i, flag = 1; // Removed the variable a, because the function is already taking x as input
for (i = 2; i <= x / 2 && flag == 1; i++) {
if (x % i == 0)
flag = 0;
}
return flag == 1;
}
int main() {
int a, r, sum = 0, original; // added original variable, to store the number added
bool eachDigit = true; // added to keep track of each digit
cin >> a;
original = a;
while (a != 0) {
r = a % 10;
eachDigit = prime_check(r); // Here Each digit of entered number is checked for prime
sum = (sum * 10) + r;
a = a / 10;
}
if (eachDigit && prime_check(original) && prime_check(sum)) // At the end checking if all the digits, entered number and the revered number are prime
cout << "yes";
else
cout<< "no";
}
For optimization, you can check if the entered number is prime or not before starting that loop, and also you can break the loop right away if one of the digits of the entered number is not prime, Like this:
#include <iostream>
#include <conio.h>
using namespace std;
bool prime_check(int x) { // I have changed the datatype of this function to bool, because I want to store if all the digits are prime or not
int i, flag = 1; // Removed the variable a, because the function is already taking x as input
for (i = 2; i <= x / 2 && flag == 1; i++) {
if (x % i == 0)
flag = 0;
}
return flag == 1;
}
int main() {
int a, r, sum = 0;
bool eachDigit = true, entered; // added to keep track of each digit
cin >> a;
entered = prime_check(a);
while (a != 0 && entered && eachDigit) {
r = a % 10;
eachDigit = prime_check(r); // Here Each digit of entered number is checked for prime
sum = (sum * 10) + r;
a = a / 10;
}
if (eachDigit && entered && prime_check(sum)) // At the end checking if all the digits, entered number and the revered number are prime
cout << "yes";
else
cout<< "no";
}
Suppose you have an int variable num which you want to check for your conditions, you can achieve your target by the following:
int rev_num = 0;
bool flag = true; // Assuming 'num' satisfies your conditions, until proven otherwise
if (prime_check(num) == false) {
flag = false;
}
else while (num != 0) {
int digit = num % 10;
rev_num = rev_num * 10 + digit;
// Assuming your prime_check function returns 'true' and 'false'
if (prime_check(digit) == false) {
flag = false;
break;
}
num /= 10;
}
if (prime_check(rev_num) == false) {
flag = false;
}
if (flag) {
cout << "Number satisfies all conditions\n";
}
else {
cout << "Number does not satisfy all conditions\n";
}
The problem is that each of your functions is doing three things, 1) inputting the number, 2) testing the number and 3) outputting the result. To combine these functions you need to have two functions that are only testing the number. Then you can use both functions on the same number, instead of inputting two different numbers and printing two different results. You will need to use function parameters, to pass the input number to the two functions, and function return values to return the result of the test. The inputting of the number and the outputting of the result go in main. Here's an outline
// returns true if the number is a prime, false otherwise
bool prime_check(int a)
{
...
}
// returns true if the number is a reverse prime, false otherwise
bool reverse_prime_check(int a)
{
...
}
int main()
{
int a;
cin >> a;
if (prime_check(a) && reverse_prime_check(a))
cout << "prime\n";
else
cout << "not prime\n";
}
I'll leave you to write the functions themselves, and there's nothing here to do the digit checks either. I'll leave you do to that.

How to find size of largest subset of a sub-sequence equal to a sum

I have this problem from hackerearth
Given an array of N integers, C cards and S sum. Each card can be used
either to increment or decrement an integer in the given array by 1.
Find if there is any subset (after/before using any no.of cards) with
sum S in the given array.
Input Format
First line of input contains an integer T which denotes the no. of
testcases. Each test case has 2 lines of input. First line of each
test case has three integers N(size of the array), S(subset sum) and
C(no. of cards). Second line of each test case has N integers of the
array(a1 to aN) seperated by a space.
Constraints
1<=T<=100 1<=N<=100 1<=S<=10000 0<=C<=100 1<=ai<=100
Output Format
Print TRUE if there exists a subset with given sum else print FALSE.
So this is basically a variation of the subset sum problem, but instead of finding out whether a given subset with a sum S exists, we need to find the largest subset from sequence index to N-1 that has a value of s and compare it's length with our C value to see if it is greater. If it is, then we have enough elements to modify the sum using our C cards, and then we print out our answer. Here is my code for that
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int N, S, C;
int checkSum(int index, int s, vector<int>& a, vector< vector<int> >& dP) {
if (dP[index][s] != -1)
return dP[index][s];
int maxNums = 0; // size of maximum subset array
for (int i = index; i < N; i++) {
int newSum = s - a[i];
int l = 0;
if (newSum == 0) {
l = 1;
} if (newSum > 0) {
if (i < (N-1)) { // only if we can still fill up sum
l = checkSum(i + 1, newSum, a, dP);
if (l > 0) // if it is possible to create this sum
l++; // include l in it
} else {
// l stays at 0 for there is no subset that can create this sum
}
} else {
// there is no way to create this sum, including this number, so skip it;
if (i == (N-1))
break; // don't go to the next level
// and l stays at 0
}
if (l > maxNums) {
maxNums = l;
}
}
dP[index][s] = maxNums;
return maxNums;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> N >> S >> C;
vector<int> a(N);
for (int i = 0; i < N; i++)
cin >> a[i];
vector< vector<int> > dP(N, vector<int>(S + C + 2, -1));
bool possible = false;
for (int i = 0; i <= C; i++) {
int l = checkSum(0, S-i, a, dP);
int m = checkSum(0, S+i, a, dP);
if ( (l > 0 && l >= i) || (m > 0 && m >= i) ) {
cout << "TRUE" << endl;
possible = true;
break;
}
}
if (!possible)
cout << "FALSE" << endl;
}
return 0;
}
So basically, 0 means it's not possible to create a subset equal to s from elements index to N-1, and -1 means we haven't computed it yet. And any other value indicates the size of the largest subset that sums up to s. This code isn't passing all the test cases. What's wrong?
You miss an else in following line
} if (newSum > 0) {
This make your program has an unexpected early break before updating maxNums by l in some cases.
For example, N=1, S=5, C=0, a={5}
Potential logic problem
You have limited the no. of card to be used to not exceed the subset size while the question never state you cannot apply multiple cards to same integers.
I mean l >= i and m >= i in
if ( (l > 0 && l >= i) || (m > 0 && m >= i) ) {
Seems you have logic flaw.
You need to find the shortest subset (with sum in range S-C..S+C) and compare it's size with C. If subset is shorter, it is possible to make needed sum.

Can't print Fibonacci series

I was writing a small snippet to get a Fibonacci number sequence depending on the user input. If the user supplies 4 as an input, it should return him the first N members of the Fibonacci sequence.
#include <iostream>
using namespace std;
int main (){
int a = 0;
int b = 1;
int c;
int n = 3;
n -= 2;
if (n == 1){
cout << a << endl;
} else {
cout << a << b << endl;
for (int i=0;i<n;i++){
c = b + a;
cout << c << endl;
a = b;
b = c;
}
}
}
However, I end up getting a 0 as an output for whatever number I supply. I have this working in PHP and I kinda miss where I've blundered. I guess I don't actually render input and output properly.
int a =0;
int n = 3;
n -= 2;
if (n == 1){
cout << a << endl;
}
You have n equal to 3, you subtract 2, thus n equal to 1, so, you enter the if body and output a, which is zero.
[EDIT]
You don't seem to get any input -as stated in a comment- in your program (you could use std::cin or std::getline() for this), but you probably mean that you have the input hard-coded, by changing the value of n by hand.
You may want to check how the Fibonacci series program is expected to work:
Fib. at Rosseta page.
Fib. with recursion
Non-recursive Fib.
After reading the links I provided above, you should be able to see that your code should be changed to this:
#include <iostream>
using namespace std;
int main (){
int a = 1;
int b = 0;
int c;
int n = 10; // "input" is 10
if (n == 0 || n == 1) { // 0 and 1 case
cout << n << endl;
} else {
for (int i = 2; i <= n; ++i) { // here you want to reach n
c = a + b;
b = a;
a = c;
}
cout << c << endl;
}
return 0;
}
However, the code above outputs only the result. You should slightly modify it to get the terms of the sequence, but I'll leave you have some fun too.
In order to really let the user input the number, change:
int n = 10;
to
int n;
std::cout << "Please, input.\n";
std::cin >> n;
However, letting user inputting must be followed by validation of the input. You see users can, by accident or not, provide input in your program, that can cause undefined behaviour.
The sequence you want is 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...
As I pointed out in a comment to another answer, your code does not produce a correct Fibonacci sequence. F(3) isn't the problem with your code; the problem is that you get confused between all the variables, a, b, c and use them to mean different things at once.
You also incorrectly decrement n: your code does it in the wrong place, and even if you move it to the right place, it wouldn't help as the operation would make n go negative.
Your existing Code
Let's walk through your code a bit:
int a = 0;
int b = 1;
int c;
int n = 3;
n -= 2;
Well, this is weird. We set n to 3 then immediately subtract 2, making it 1. This means that if you try to set n to 0, 1, or 2 you end up with n being a negative number. If you set it to 3, you end up with n being 1.
if (n == 1){
cout << a << endl;
}
We're in trouble right here. Remember that you subtract 2 from n which means that for n==3 you will return whatever is in a which is wrong. But even if you meant this to special-case F(1) that code is still wrong because F(1)=1.
else {
cout << a << b << endl;
for (int i=0;i<n;i++){
Remember, that we can get here with n zero or negative. Obviously in the case of n <= 0 this loop will never execute, so c will never be printed.
c = b + a;
cout << c << endl;
Here, we seem to calculate and output the next Fibonacci number by adding the two previous numbers. This should be fine.
a = b;
b = c;
And here, we keep the new Fibonacci number and its predecessor for the next loop iteration, if any.
The problems with this code are, of course, fixable. But the problem is that the existing code is confusing. It outputs all sorts of different values, and it's unclear what variable is supposed to represent.
Looking at this problem, your first instinct would be to make a function which accepts as input a number n and returns F(n) - you could call it fib or somesuch.
Reworking this
So, how to go about writing such a function? Here's a simple recursive implementation that you can use:
int fib(int n)
{
if ((n == 0) || (n == 1))
return n;
return fib(n-1) + fib(n-2);
}
Notice how this function is short, sweet and to the point. There's no need for a ton of variables, no need for complicated control structures or storing state. It almost reads like a text-based description of the Fibonacci algorithm.
Of course, it's not super-efficient and ends up redoing a lot of work. That's a legitimate criticism, but it's unlikely that there performance considerations here.
Still, perhaps you just don't like recursion. Many people think of recursion as a dirty word, and avoid it with a passion. So how about a non-recursive implementation instead? It's possible, but it's a bit more difficult to understand.
int fib (int n)
{
/* F(0) = 0 */
if (n == 0)
return 0;
int a = 0;
int b = 1;
for (int i = 2; i < n; i++)
{
int c = a + b;
a = b;
b = c;
}
/* F(n) = F(n-2) + F(n-1) */
return a + b;
}
This is a little bit more efficient and not that much more difficult to understand.
I hope that this helped.
Try this which would give you the list you needed.
#include <iostream>
using namespace std;
int fib(int num){
int ans;
if (num >2) {
ans = fib(num-1) + fib(num-2);
}
else
ans = 1;
return ans;
}
int main()
{
int num, x=1;
cin >> num;
while (num >= x) {
cout << fib(x) <<" ";
x++;
}
return 0;
}

Using one-dimesional array in recursion

Recently I've been working on partition problem. I've done a research and I found that it can be solved using an algorithm on wiki page. Here's the pseudo algorithm:
INPUT: A list of integers S
OUTPUT: True if S can be partitioned into two subsets that have equal sum
1 function find_partition( S ):
2 N ← sum(S)
3 P ← empty boolean table of size (\lfloor N/2 \rfloor + 1) by (n + 1)
4 initialize top row (P(0,x)) of P to True
5 initialize leftmost column (P(x, 0)) of P, except for P(0, 0) to False
6 for i from 1 to \lfloor N/2 \rfloor
7 for j from 1 to n
8 P(i, j) ← P(i, j-1) or P(i-S[j-1], j-1)
9 return P(\lfloor N/2 \rfloor , n)
Using recursion you can calculate if certain sum from integers in array can be reached, if it can be reached it returns true. I start with sumOfTheIntegers/2 and I go back to 0, until I find a solution. When I found the biggest possible sum of the integers that is lower or equal to the average I calculate the difference between the the 2 groups of integers with (average-lowestSumLowerorEqualtoAverage)*2.
But then I confront with problem how can I include one dimensional array in the recursion?
Here's the code, it should probably work, but I haven't tested it yet, because of the problem. So maybe the code contains small errors. But that's not the problem, I'll fix it later.
#include <iostream>
#include <cmath>
using namespace std;
bool matrix (int a, int b)
{
if(b == -1) return true;
else if (a == -1) return false;
else if(matrix(a-1, b) == true) return true;
else if(matrix(a-1,b-numbers[a-1]) == true) return true;
else return false;
}
int main()
{
int number, sum = 0;
cin >> number;
int numbers[number];
for(int i = 0; i<number; i++)
{
cin >> numbers[i];
sum += numbers[i];
}
double average = sum/2.0;
for(int i = floor(sum/2); i!= 0; i--)
{
if(matrix(number+1, i) == true)
{
cout << abs(average-i)*2;
break;
}
}
return 0;
}
The easiest (but certainly not the best) way is to introduce a global variable:
#include <vector>
std::vector<int> numbers;
/* ... */
int main(){
int number;
cin >> number;
numbers.resize(number);
/* ... */
}
Another possibility is to use an additional parameter:
bool matrix (int a, int b, const std::vector<int>& numbers)
{
if(b == -1) return true;
else if (a == -1) return false;
else if(matrix(a-1, b,numbers) == true) return true;
else if(matrix(a-1,b-numbers[a-1],numbers) == true) return true;
else return false;
}
Note that int numbers[number] is actually using a compiler-specific extension (VLA) and is not part of the C++ standard (see Does C++ support Variable Length Arrays? and Why aren't variable-length arrays part of the C++ standard?).
Pass it as an argument to the function
bool matrix (int a, int b, int num_arr[])
{
...
matrix(a-1,b,num_arr);
...
}