I'm having some trouble with this non recursive Fibonacci function. I am using this array of numbers and passing it to FiboNR, however I am getting large negative values and Access Violation errors.
int n[15] = { 1,5,10,15,20,25,30,35,40,45,50,55,60,65,70 };
int FiboNR(int n) // array of size n
{
int const max = 100;
int F[max];
F[0] = 0; F[1] = 1;
for (int i = 2; i <= n; i++) {
F[n] = F[n - 1] + F[n - 2];
}
return (F[n]);
}
The function was one provided by the instructor and I assume its correct if he's giving it out but with these memory errors I don't fully understand what's going on. The only way I'm calling the in a loop to go through the array and outputting the answer like cout << FiboNR(n[i]);
First of all, your trouble is in loop. Replace:
F[n] = F[n - 1] + F[n - 2];
with:
F[i] = F[i - 1] + F[i - 2];
Because i is your iterator and n is only the limit.
Just FYI, the braces ( ) in return statement are not needed, you can ignore them.
I am using this array of numbers and passing it to FiboNR
You are not supposed to do that since FiboNR() excepts its argument to be an integer (one, not an array of integers). So you should pass only one number to your function, like: FiboNR(n[2]).
You get a negative numbers due to int overflow for int array (n > 46).
Change array type from int to long long.
Other solutions: change array type to float/double type with less precision of the results or use long arithmetic.
Type | Typical Bit Width | Typical Range
int | 4bytes| -2147483648 to 2147483647
Link: C++ Data Types
Example of code below.
#include <iostream>
long long FiboNR(int n);
long long FiboNR(int n) {
int const max = 100;
long long F[max];
if (n > max) {
n = max;
}
F[0] = 0;
F[1] = 1;
for (int i = 2; i <= n; i++){
F[i] = F[i - 1] + F[i - 2];
}
return (F[n]);
}
int main() {
for (int i=0; i < 100; i++) {
std::cout << "i = " << i << " : " << FiboNR(i) << std::endl;
}
return 0;
}
Related
This question already has answers here:
initialize array with stackoverflow error [duplicate]
(2 answers)
Finding out nth fibonacci number for very large 'n'
(24 answers)
Finding the fibonacci number of large number
(1 answer)
Closed 2 years ago.
I'm solving a CSES problem in which I've to find the sum of first 'n' Fibonacci numbers. The code:
#pragma GCC optimize("Ofast")
#include <iostream>
using namespace std;
int main()
{
unsigned long long int n;
scanf("%llu", &n);
unsigned long long int seq[n];
seq[0] = 0;
seq[1] = 1;
unsigned long long int mod = 1000000000 + 7;
for (unsigned long long int i = 2; i < n + 1; i++) {
seq[i] = (seq[i - 1] + seq[i - 2]) % mod;
}
cout << seq[n];
}
The problem specifies that the value of n can get upto 10^18 and therefore I have used unsigned long long int to initialize n. The problem also instructs to give the modulo 7 answer. The code is working fine for values of n upto 4 digits but breaks when the value of n rises to the upper ceiling of 10^18.It gives a (0xC00000FD) error and does not return anything. Please help me understand the problem here and how to deal with it. Any other suggestions would also be appreciated.
When doing modular addition, you need to apply your mod to each value you're adding.
For example, (a + b) % c = (a % c + b % c) % c.
That means in your code:
seq[i] = (seq[i - 1] % mod + seq[i - 2] % mod) % mod;
Otherwise, the addition of seq[i - 1] and seq[i - 2] will result in an overflow.
Read more about modular arithmetic here.
In this problem
F[i] -> i th Fibonacci number. MOD = 1e9 + 7. n < 1e18
F[n] % MOD = ?
F[n] = F[n-1] + F[n-2]
if you calculate this with loop you get TL
that`s way you can optimize this solution
now you calculate F[n] with recursion
F[2*n] = - F[n] * F[n] + 2 * F[n] * F[n+1]
F[2*n+1] = F[n] * F[n] + F[n+1] * F[n+1]
here is my solution
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll MOD = 1e9+7;
void fib(ll n ,ll &a , ll &b){
if(n == 0){
a = 0;
b = 1;
return;
}
ll x, y;
if(n%2==1){
fib(n-1 ,x,y);
a = y;
b = (x+y)%MOD;
return;
}
fib(n/2 , x , y);
a = (x*(2*y +MOD -x)%MOD)%MOD;
b = ((x*x)%MOD+(y*y)%MOD)%MOD;
return;
}
int main(){
ll N , a, b;
cin >> N;
fib(N , a, b);
cout << a;
}
I think the problem with this code is that you are creating an array seq[n] of size n, which can lead to a SEGFAULT on Linux and STATUS_STACK_OVERFLOW (0xc00000fd) on Windows for large numbers, which refers to stack exhaustion.
Below I give an improved version of your algorithm, which uses a fixed memory size, and for modulo addition, I use the sum_by_modulo function, for avoiding overflow in (a + b) % m operation, the principle of which is described here.
#pragma GCC optimize("Ofast")
#include <iostream>
typedef unsigned long long int ullong;
ullong sum_by_modulo(ullong a, ullong b, ullong m){
ullong sum;
a %= m;
b %= m;
ullong c = m - a;
if (b==c)
sum = 0;
if (b<c)
sum = a + b;
if (b > c)
sum = b-c;
return sum;
}
int main()
{
ullong n;
ullong t1 = 0, t2 = 1, nextTerm = 0;
ullong modulo = 1000000000 + 7;
std::cout << "Enter the number of term: ";
std::cin >> n;
for (ullong i = 1; i <= n; ++i)
{
if(i == 1)
continue;
if(i == 2)
continue;
nextTerm = sum_by_modulo(t1, t2, modulo);
t1 = t2;
t2 = nextTerm;
}
std::cout << nextTerm << " ";
return 0;
}
I have a problem. I want from a given number to get each digit as an element in the same array.
But when I compile, if I extend the range from one iteration above the size of the given number, I get a corrupted data exception from Visual Studio in Debug mode as an exception.
I thought first that was because the int type is only 4 digit max length as a 4 bytes entity because I used to get only one digit for greater number above 9999. But I noticed that my number starts at an iteration value one too late...which makes it impossible to show the last digit.
If I add a zero to my given number, I can manually offset in the opposite direction, but that doesn't work with my original number.
But, I can't find out how to fix that...Here is my code.
Before asking for help, here is a screenshot explaining the principle which is used to convert the number into an array: math theory formula
I wish to solve it with the number type only because the char type involves another way managing the memory with buffers...which I don't really know how to handle right know.
Can someone help me to complete the debugging please ?
#include <iostream>
#include <math.h>
//method to convert user number entry to array of digits
long long numToArray(double num,double arrDigits[], const long long n) {
//instanciate variables
//array of with m elements
arrDigits[n];
double* loopValue = new double(0);
//extract the digits and store them into arrDigits array
for (long long i = 0; i < n; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0);
*loopValue = floor(num / pow(10, n - i)) - temp;
arrDigits[i] = *loopValue;
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
return 0;
}
//main program interacting with the user
int main()
{
std::cout << "please type an integer: ";
double num;
const long long n = sizeof(num);
double array[n]{};
std::cin >> num;
//call the method to test if all values are in the array
numToArray(num, array, n);
return 0;
}
Explaining the troubleshoot
Note : Visual Studio shows error if I extend from n to n+1. If I let the type int or long, sizeof(num) is all the time 4...
Then, I had to set it as double and to extract it from the main scope, which makes it ...double...
People asking to remove pointer, it is impossible to run the program if I do so.
I want from a given number to get each digit as an element in the same array.
If you want to simply get each number into an array, it takes only a few lines of code to convert the decimal to a string, remove the decimal point (if it exists), and then copy the string to a buffer:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iomanip>
int main()
{
double d = 1.45624234;
std::ostringstream strm;
strm << std::setprecision(12);
// copy this to a string using the output stream
strm << d;
std::string s = strm.str();
// remove the decimal point
s.erase(std::remove(s.begin(), s.end(), '.'), s.end());
// Now copy each digit to a buffer (in this case, vector)
std::vector<int> v;
std::transform(s.begin(), s.end(), std::back_inserter(v), [&](char ch) { return ch - '0';});
// output the results
for (auto c : v )
std::cout << c;
}
Output:
145624234
All of the work you were doing is already done for you by the standard library. In this case the overloaded operator << for double when streamed to a buffer creates the string. How it does it? That is basically what your code is attempting to do, but obviously safely and correctly.
Then it's just a matter of transforming each digit character into an actual integer that represents that digit, and that is what std::transform does. Each digit character is copied to the vector by subtracting the character 0 from each char digit.
#include <iostream>
#include <math.h>
#include <list>
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
//counting the number of digits
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum/10;
++count;
}
std::cout << "number of digits compositing your natural integer: " << count<<std::endl;
//process the value for conversion to list of digits, so you can
//access each digits by power and enhance your calculus operations
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - count;//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
//print the converted list
std::cout << "array converted to list: ";
for (double j : listDigits) {
std::cout << j << " ";
}
std::cout << std::endl;
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
std::cout << "removed zero element to the list\n";
for (double i : listDigits) {
std::cout << i << " ";
}
std::cout << "natural integer successfully converted into list digits data\n";
return 0;
}
an example on debug mode in Visual Studio 2019
I finally encapsulated the whole code into two functions. But I have an extra value at first and last iteration...
The answer is almost complete, just need to solve the offset from inside the main moved to it's owned function. I finally added a new array variable with the exact size I want from the two new functions, so we get the array which will be possible to manipulate so far away.
#include <iostream>
#include <math.h>
#include <list>
int CountNumberDigits(int num) {
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum / 10;
++count;
}
return count;
}
double* NumToArray(double num) {
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - CountNumberDigits(num);//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
for (double j : listDigits) {
std::cout << j << " ";
}
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
//convert list to array
double* arrOutput = new double[listDigits.size()]{};
std::copy(listDigits.begin(), listDigits.end(), arrOutput);
double* ptrResult = arrOutput;
return ptrResult;
}
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
int count = CountNumberDigits(num);
std::cout << "number of digits compositing your natural integer: " << count << std::endl;
double* ptrOutput = NumToArray(num);
//reduce the array to the num size
double* shrinkArray = new double[CountNumberDigits(num)];
for (int i = 0; i < CountNumberDigits(num); i++) {
*(shrinkArray+i) = ptrOutput[i];
std::cout << *(shrinkArray+i) << " ";
}
this is my first time posting a question. I was hoping to get some help on a very old computer science assignment that I never got around to finishing. I'm no longer taking the class, just want to see how to solve this.
Read in an integer (any valid 64-bit
integer = long long type) and output the same number but with commas inserted.
If the user entered -1234567890, your program should output -1,234,567,890. Commas
should appear after every three significant digits (provided more digits remain) starting
from the decimal point and working left toward more significant digits. If the number
entered does not require commas, do not add any. For example, if the input is 234 you
should output 234. The input 0 should produce output 0. Note in the example above
that the number can be positive or negative. Your output must maintain the case of the
input.
I'm relatively new to programming, and this was all I could come up with:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long n;
cout << "Enter an integer:" << endl;
cin >> n;
int ones = n % 10;
int tens = n / 10 % 10;
int hund = n / 100 % 10;
int thous = n / 1000 % 10;
int tthous = n / 10000 % 10;
cout << tthous << thous << "," << hund << tens << ones << endl;
return 0;
}
The original assignment prohibited the use of strings, arrays, and vectors, so please refrain from giving suggestions/solutions that involve these.
I'm aware that some sort of for-loop would probably be required to properly insert the commas in the necessary places, but I just do not know how to go about implementing this.
Thank you in advance to anyone who offers their help!
Just to give you an idea how to solve this, I've maiden a simple implementation. Just keep in mind that is just a simple example:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
long long n = -1234567890;
if ( n < 0 )
cout << '-';
n = abs(n);
for (long long i = 1000000000000; i > 0; i /= 1000) {
if ( n / i <= 0 ) continue;
cout << n / i ;
n = n - ( n / i) * i;
if ( n > 0 )
cout << ',';
}
return 0;
}
http://coliru.stacked-crooked.com/a/150f75db89c46e99
The easy solution would be to use ios::imbue to set a locale that would do all the work for you:
std::cout.imbue(std::locale(""));
std::cout << n << std::endl;
However, if the restraints don't allow for strings or vectors I doubt that this would be a valid solution. Instead you could use recursion:
void print(long long n, int counter) {
if (n > 0) {
print(n / 10, ++counter);
if (counter % 3 == 0) {
std::cout << ",";
}
std::cout << n%10;
}
}
void print(long long n) {
if (n < 0) {
std::cout << "-";
n *= -1;
}
print(n, 0);
}
And then in the main simply call print(n);
A small template class comma_sep may be a solution, the usage may be as simple as:
cout << comma_sep<long long>(7497592752850).sep() << endl;
Which outputs:
7,497,592,752,850
Picked from here:
https://github.com/arloan/libimsux/blob/main/comma_sep.hxx
template <class I = int, int maxdigits = 32>
class comma_sep
char buff[maxdigits + maxdigits / 3 + 2];
char * p;
I i;
char sc;
public:
comma_sep(I i, char c = ',') : p(buff), i(i), sc(c) {
if (i < 0) {
buff[0] = '-';
*++p = '\0';
}
}
const char * sep() {
return _sep(std::abs(i));
}
private:
const char * _sep(I i) {
I r = i % 1000;
I n = i / 1000;
if (n > 0) {
_sep(n);
p += sprintf(p, "%c%03d", sc, (int)r);
*p = '\0';
} else {
p += sprintf(p, "%d", (int)r);
*p = '\0';
}
return buff;
}
};
The above class handles only integeral numbers, float/double numbers need to use a partial specialized version:
template<int maxd>
class comma_sep<double, maxd> {
comma_sep<int64_t, maxd> _cs;
char fs[64];
double f;
public:
const int max_frac = 12;
comma_sep(double d, char c = ',') : _cs((int64_t)d, c) {
double np;
f = std::abs(modf(d, &np));
}
const char * sep(int frac = 3) {
if (frac < 1 || frac > max_frac) {
throw std::invalid_argument("factional part too too long or invalid");
}
auto p = _cs.sep();
strcpy(fs, p);
char fmt[8], tmp[max_frac+3];
sprintf(fmt, "%%.%dlf", frac);
sprintf(tmp, fmt, f);
return strcat(fs, tmp + 1);
}
};
The two above classes can be improved by adding type-traits like std::is_integral and/or std::is_floating_point, though.
For empty vector Fun1 returns 0. Function Fun2, which should be equivalent to Fun1 (only one small change, see below), crashes with error vector subscript out of range. Any ideas why is that?
Code run in Visual Studio 2017
int Fun1(vector<int> service_times) {
sort(service_times.begin(), service_times.end());
int sum = 0;
int sumi = 0;
int st = service_times.size() - 1;//condition stired in variable
for (int i = 0; i < st; i++)
{
sumi += service_times[i];
sum = sum + sumi;
}
return sum;
}
int Fun2(vector<int> service_times) {
sort(service_times.begin(), service_times.end());
int sum = 0;
int sumi = 0;
for (int i = 0; i < (service_times.size() - 1); i++)//condition
//directly written
{
sumi += service_times[i];
sum = sum + sumi;
}
return sum;
}
Since service_times is an empty vector, service_times.size() ought to return 0, no?
No. It returns size_t(0), which is an unsigned type. Therefore, service_times.size() - 1 is a unsigned - signed operation, where the signed value (1) is "promoted" to unsigned type. Therefore, 0 - 1 is actually numeric_limits<size_t>::max().
In the first function, you saved it by storing it again in an int variable: it becomes -1 again. Therefore, i < st is i < -1, which worked incidentally. However, in the second function, i < st is actually i < <some ultra big value>, which, LOL.
I am trying to solve a problem, a part of which requires me to calculate (2^n)%1000000007 , where n<=10^9. But my following code gives me output "0" even for input like n=99.
Is there anyway other than having a loop which multilplies the output by 2 every time and finding the modulo every time (this is not I am looking for as this will be very slow for large numbers).
#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
int main()
{
unsigned long long gaps,total;
while(1)
{
cin>>gaps;
total=(unsigned long long)powf(2,gaps)%1000000007;
cout<<total<<endl;
}
}
You need a "big num" library, it is not clear what platform you are on, but start here:
http://gmplib.org/
this is not I am looking for as this will be very slow for large numbers
Using a bigint library will be considerably slower pretty much any other solution.
Don't take the modulo every pass through the loop: rather, only take it when the output grows bigger than the modulus, as follows:
#include <iostream>
int main() {
int modulus = 1000000007;
int n = 88888888;
long res = 1;
for(long i=0; i < n; ++i) {
res *= 2;
if(res > modulus)
res %= modulus;
}
std::cout << res << std::endl;
}
This is actually pretty quick:
$ time ./t
./t 1.19s user 0.00s system 99% cpu 1.197 total
I should mention that the reason this works is that if a and b are equivalent mod m (that is, a % m = b % m), then this equality holds multiple k of a and b (that is, the foregoing equality implies (a*k)%m = (b*k)%m).
Chris proposed GMP, but if you need just that and want to do things The C++ Way, not The C Way, and without unnecessary complexity, you may just want to check this out - it generates few warnings when compiling, but is quite simple and Just Works™.
You can split your 2^n into chunks of 2^m. You need to find: `
2^m * 2^m * ... 2^(less than m)
Number m should be 31 is for 32-bit CPU. Then your answer is:
chunk1 % k * chunk2 * k ... where k=1000000007
You are still O(N). But then you can utilize the fact that all chunk % k are equal except last one and you can make it O(1)
I wrote this function. It is very inefficient but it works with very large numbers. It uses my self-made algorithm to store big numbers in arrays using a decimal like system.
mpfr2.cpp
#include "mpfr2.h"
void mpfr2::mpfr::setNumber(std::string a) {
for (int i = a.length() - 1, j = 0; i >= 0; ++j, --i) {
_a[j] = a[i] - '0';
}
res_size = a.length();
}
int mpfr2::mpfr::multiply(mpfr& a, mpfr b)
{
mpfr ans = mpfr();
// One by one multiply n with individual digits of res[]
int i = 0;
for (i = 0; i < b.res_size; ++i)
{
for (int j = 0; j < a.res_size; ++j) {
ans._a[i + j] += b._a[i] * a._a[j];
}
}
for (i = 0; i < a.res_size + b.res_size; i++)
{
int tmp = ans._a[i] / 10;
ans._a[i] = ans._a[i] % 10;
ans._a[i + 1] = ans._a[i + 1] + tmp;
}
for (i = a.res_size + b.res_size; i >= 0; i--)
{
if (ans._a[i] > 0) break;
}
ans.res_size = i+1;
a = ans;
return a.res_size;
}
mpfr2::mpfr mpfr2::mpfr::pow(mpfr a, mpfr b) {
mpfr t = a;
std::string bStr = "";
for (int i = b.res_size - 1; i >= 0; --i) {
bStr += std::to_string(b._a[i]);
}
int i = 1;
while (!0) {
if (bStr == std::to_string(i)) break;
a.res_size = multiply(a, t);
// Debugging
std::cout << "\npow() iteration " << i << std::endl;
++i;
}
return a;
}
mpfr2.h
#pragma once
//#infdef MPFR2_H
//#define MPFR2_H
// C standard includes
#include <iostream>
#include <string>
#define MAX 0x7fffffff/32/4 // 2147483647
namespace mpfr2 {
class mpfr
{
public:
int _a[MAX];
int res_size;
void setNumber(std::string);
static int multiply(mpfr&, mpfr);
static mpfr pow(mpfr, mpfr);
};
}
//#endif
main.cpp
#include <iostream>
#include <fstream>
// Local headers
#include "mpfr2.h" // Defines local mpfr algorithm library
// Namespaces
namespace m = mpfr2; // Reduce the typing a bit later...
m::mpfr tetration(m::mpfr, int);
int main() {
// Hardcoded tests
int x = 7;
std::ofstream f("out.txt");
m::mpfr t;
for(int b=1; b<x;b++) {
std::cout << "2^^" << b << std::endl; // Hardcoded message
t.setNumber("2");
m::mpfr res = tetration(t, b);
for (int i = res.res_size - 1; i >= 0; i--) {
std::cout << res._a[i];
f << res._a[i];
}
f << std::endl << std::endl;
std::cout << std::endl << std::endl;
}
char c; std::cin.ignore(); std::cin >> c;
return 0;
}
m::mpfr tetration(m::mpfr a, int b)
{
m::mpfr tmp = a;
if (b <= 0) return m::mpfr();
for (; b > 1; b--) tmp = m::mpfr::pow(a, tmp);
return tmp;
}
I created this for tetration and eventually hyperoperations. When the numbers get really big it can take ages to calculate and a lot of memory. The #define MAX 0x7fffffff/32/4 is the number of decimals one number can have. I might make another algorithm later to combine multiple of these arrays into one number. On my system the max array length is 0x7fffffff aka 2147486347 aka 2^31-1 aka int32_max (which is usually the standard int size) so I had to divide int32_max by 32 to make the creation of this array possible. I also divided it by 4 to reduce memory usage in the multiply() function.
- Jubiman