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

#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].

Related

Index size of an array

If I have an array like a[100] and I start from 1 or 0. When I declare int a[100], how long is my array?
It always starts counting from 0? If yes it will be an array with 101 spaces.
#include <iostream>
using namespace std;
int main()
{
float time[20]; //
int a, first = 20, y, x;
for (x = 1; x < 21; x++) {
cout << "Enter the time of the person number " << x << " : ";
cin >> time[x];
}
for (y = 1; y < 20; y++) {
if (time[y] < first) {
first = time[y];
a = y;
}
}
getchar();
cout << "The person " << a << " was the faster.";
cout << time[1];
getchar();
return 0;
}
Here it starts from 1.
And if I change it will start from 0.
for (x=0;x<21;x++)
for (y=0;y<20;y++)
And why is much better to start from 0?
C++ uses 0-indexing, so, for int a[20]; valid indexes are 0, .., 19.
a[20] does out of bound access, leading to UB.
"When I declare int a[100] , how long is my array"
It is 100 elements in size.
The valid indices are a[0] through a[99] (both inclusive). Index a[100] is past the end of the array (out of bounds).
In c++ arrays always start from 0 index and the number you passed in the brackets is the size of array.
If you write, int A[10] ... It means you can store 10 element in the array, but the indexing begins from 0 and goes up to 9.

C++ Program abruptly ends after cin

I am writing code to get the last digit of very large fibonacci numbers such as fib(239), etc.. I am using strings to store the numbers, grabbing the individual chars from end to beginning and then converting them to int and than storing the values back into another string. I have not been able to test what I have written because my program keeps abruptly closing after the std::cin >> n; line.
Here is what I have so far.
#include <iostream>
#include <string>
using std::cin;
using std::cout;
using namespace std;
char get_fibonacci_last_digit_naive(int n) {
cout << "in func";
if (n <= 1)
return (char)n;
string previous= "0";
string current= "1";
for (int i = 0; i < n - 1; ++i) {
//long long tmp_previous = previous;
string tmp_previous= previous;
previous = current;
//current = tmp_previous + current; // could also use previous instead of current
// for with the current length of the longest of the two strings
//iterates from the end of the string to the front
for (int j=current.length(); j>=0; --j) {
// grab consectutive positions in the strings & convert them to integers
int t;
if (tmp_previous.at(j) == '\0')
// tmp_previous is empty use 0 instead
t=0;
else
t = stoi((string&)(tmp_previous.at(j)));
int c = stoi((string&)(current.at(j)));
// add the integers together
int valueAtJ= t+c;
// store the value into the equivalent position in current
current.at(j) = (char)(valueAtJ);
}
cout << current << ":current value";
}
return current[current.length()-1];
}
int main() {
int n;
std::cin >> n;
//char& c = get_fibonacci_last_digit_naive(n); // reference to a local variable returned WARNING
// http://stackoverflow.com/questions/4643713/c-returning-reference-to-local-variable
cout << "before call";
char c = get_fibonacci_last_digit_naive(n);
std::cout << c << '\n';
return 0;
}
The output is consistently the same. No matter what I enter for n, the output is always the same. This is the line I used to run the code and its output.
$ g++ -pipe -O2 -std=c++14 fibonacci_last_digit.cpp -lm
$ ./a.exe
10
There is a newline after the 10 and the 10 is what I input for n.
I appreciate any help. And happy holidays!
I'm posting this because your understanding of the problem seems to be taking a backseat to the choice of solution you're attempting to deploy. This is an example of an XY Problem, a problem where the choice of solution method and problems or roadblocks with its implementation obfuscates the actual problem you're trying to solve.
You are trying to calculate the final digit of the Nth Fibonacci number, where N could be gregarious. The basic understanding of the fibonacci sequence tells you that
fib(0) = 0
fib(1) = 1
fib(n) = fib(n-1) + fib(n-2), for all n larger than 1.
The iterative solution to solving fib(N) for its value would be:
unsigned fib(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value;
}
return current;
}
which is all well and good, but will obviously overflow once N causes an overflow of the storage capabilities of our chosen data type (in the above case, unsigned on most 32bit platforms will overflow after a mere 47 iterations).
But we don't need the actual fib values for each iteration. We only need the last digit of each iteration. Well, the base-10 last-digit is easy enough to get from any unsigned value. For our example, simply replace this:
current = value;
with this:
current = value % 10;
giving us a near-identical algorithm, but one that only "remembers" the last digit on each iteration:
unsigned fib_last_digit(unsigned n)
{
if (n <= 1)
return n;
unsigned previous = 0;
unsigned current = 1;
for (int i=1; i<n; ++i)
{
unsigned value = previous + current;
previous = current;
current = value % 10; // HERE
}
return current;
}
Now current always holds the single last digit of the prior sum, whether that prior sum exceeded 10 or not really isn't relevant to us. Once we have that the next iteration can use it to calculate the sum of two single positive digits, which cannot exceed 18, and again, we only need the last digit from that for the next iteration, etc.. This continues until we iterate however many times requested, and when finished, the final answer will present itself.
Validation
We know the first 20 or so fibonacci numbers look like this, run through fib:
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:13
8:21
9:34
10:55
11:89
12:144
13:233
14:377
15:610
16:987
17:1597
18:2584
19:4181
20:6765
Here's what we get when we run the algorithm through fib_last_digit instead:
0:0
1:1
2:1
3:2
4:3
5:5
6:8
7:3
8:1
9:4
10:5
11:9
12:4
13:3
14:7
15:0
16:7
17:7
18:4
19:1
20:5
That should give you a budding sense of confidence this is likely the algorithm you seek, and you can forego the string manipulations entirely.
Running this code on a Mac I get:
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: basic_string before callin funcAbort trap: 6
The most obvious problem with the code itself is in the following line:
for (int j=current.length(); j>=0; --j) {
Reasons:
If you are doing things like current.at(j), this will crash immediately. For example, the string "blah" has length 4, but there is no character at position 4.
The length of tmp_previous may be different from current. Calling tmp_previous.at(j) will crash when you go from 8 to 13 for example.
Additionally, as others have pointed out, if the the only thing you're interested in is the last digit, you do not need to go through the trouble of looping through every digit of every number. The trick here is to only remember the last digit of previous and current, so large numbers are never a problem and you don't have to do things like stoi.
As an alternative to a previous answer would be the string addition.
I tested it with the fibonacci number of 100000 and it works fine in just a few seconds. Working only with the last digit solves your problem for even larger numbers for sure. for all of you requiring the fibonacci number as well, here an algorithm:
std::string str_add(std::string a, std::string b)
{
// http://ideone.com/o7wLTt
size_t n = max(a.size(), b.size());
if (n > a.size()) {
a = string(n-a.size(), '0') + a;
}
if (n > b.size()) {
b = string(n-b.size(), '0') + b;
}
string result(n + 1, '0');
char carry = 0;
std::transform(a.rbegin(), a.rend(), b.rbegin(), result.rbegin(), [&carry](char x, char y)
{
char z = (x - '0') + (y - '0') + carry;
if (z > 9) {
carry = 1;
z -= 10;
} else {
carry = 0;
}
return z + '0';
});
result[0] = carry + '0';
n = result.find_first_not_of("0");
if (n != string::npos) {
result = result.substr(n);
}
return result;
}
std::string str_fib(size_t i)
{
std::string n1 = "0";
std::string n2 = "1";
for (size_t idx = 0; idx < i; ++idx) {
const std::string f = str_add(n1, n2);
n1 = n2;
n2 = f;
}
return n1;
}
int main() {
const size_t i = 100000;
const std::string f = str_fib(i);
if (!f.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << f[f.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}
Try it with first calculating the fibonacci number and then converting the int to a std::string using std::to_string(). in the following you can extract the last digit using the [] operator on the last index.
int fib(int i)
{
int number = 1;
if (i > 2) {
number = fib(i - 1) + fib(i - 2);
}
return number;
}
int main() {
const int i = 10;
const int f = fib(i);
const std::string s = std::to_string(f);
if (!s.empty()) {
std::cout << "fibonacci of " << i << " = " << f << " | last digit: " << s[s.size() - 1] << std::endl;
}
std::cin.sync(); std::cin.get();
return 0;
}
Avoid duplicates of the using keyword using.
Also consider switching from int to long or long long when your numbers get bigger. Since the fibonacci numbers are positive, also use unsigned.

Wierd combination

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

Sum two Dynamic Arrays

I'm doing a homework problem where I have two take input from a user in the form of two dynamic char arrays (max of 100 characters each) and returning their sum.
I'm struggling with coming up with a sum function that works correctly when the two numbers are of different length or when the answer is less than 100 digits. When the numbers are of different length, they get added as if they were the same (e.g. 100 + 1000 becomes 1000+1000). When the result is less than 100 digits, the full arrays is printed anyway (so there are dozens of trailing zeros). (EDIT: Fixed, see below).
I know that there is no way to tell the actual size of a dynamic array, and I can't figure out any way to place some sort of sentinel value that stops the program from processing farther. I'm not allowed to use vectors or traditional arrays, which would give me a clear path to the solution. EDIT: This has been fixed by checking for '\0'.
I know SO doesn't want to do people's homework for them (nor am I asking that), but I do need some guidance as to how I can solve this problem. I've been working for hours and still can't think of a solution.
My program is as follows:
#include <iostream>
#include <algorithm>
int* sum(char*, char*);
int main() {
char * arr = new char[100];
char * arr2 = new char[100];
std::cout << "Enter value 1: ";
std::cin >> arr;
std::cout << "Enter value 2: ";
std::cin >> arr2;
int * result = sum(arr, arr2);
std::cout << "Result: ";
for (int i = 0; i < 100 && result[i] != '\0'; i++) {
std::cout << result[i];
}
std::cout << std::endl;
return 0;
}
int* sum(char * num1, char* num2) {
std::reverse(num1, num1 + 100);
std::reverse(num2, num2 + 100);
bool carryOver = false;
int* retarr = new int[100]; //Array to return to user
for (int i = 0; i < 100; i++) {
//Numerical value is char - 48, unless
//char value is zero, then int val is zero
int val1 = std::max(num1[i] - 48, 0);
int val2 = std::max(num2[i] - 48, 0);
int carry = (carryOver)? 1 : 0;
carryOver = false; //Reset carryOver var
int t = val1 + val2 + carry;
if (t >= 10) {
t = t % 10;
carryOver = true;
}
retarr[99 - i] = t;
}
return retarr;
}

Save sub Integer in Array in c++

I want to save an integer type value in array.
Here is a code.
int a,arr[5];
cout<<"Enter a Number ";
cin >> a;
Suppose user enter the value 73972 This value save in arr like this.
arr[0] = 7;
arr[1] = 3;
.. .. .. ..
.. .. .. ..
arr[4] = 2;
How can I do that.???
Iterate reversely on the array and each time divide the number by 10 and store the reminder on the array.
for(int i=4; i>=0; i--)
{
arr[i] = a % 10;
a /= 10;
}
Read a string and break it into digits.
First of all integer values can have more than 5 digits.
You can get the number of digits that an object of type int can contain by using expression
std::numeric limits<int>::digits10 + 1
class std::numeric_limits is declared in header <limits>
Also take into account that if a number contains less digits than the size of the array then you need some mark that will determine the end of the number in the array.
I would advice you to use a character array instead of an array of integers in which the terminating zero will determine the end of the number.
If you want to use an integer array then the code could look the following way
#include <iostream>
#include <algorithm>
#include <limits>
int main()
{
int arr[std::numeric_limits<int>::digits10 + 1];
int a;
std::cout << "Enter a Number ";
std::cin >> a;
int n = 0;
do
{
arr[n++] = a % 10;
} while ( a /= 10 );
std::reverse( arr, arr + n );
for ( int i = 0; i < n; i++ ) std::cout << arr[i] << ' ';
std::cout << std::endl;
}