print condition while integer overflow not working - c++

#include <iostream>
using namespace std;
int getFectorial(int n)
{
int ans = 1;
for (int i = n; i >= 1; i--)
{
ans = ans * i;
}
return ans;
}
int printNcr(int n, int r)
{
if (getFectorial(n) > INT_MAX)
{
return 0;
}
return (getFectorial(n)) / ((getFectorial(r)) * (getFectorial(n - r)));
}
int main()
{
int n = 14;
for (int row = 0; row < n; row++)
{
for (int col = 0; col < row + 1; col++)
{
cout << printNcr(row, col) << " ";
}
cout << endl;
}
return 0;
}
When I give value of n more than 13th I want integer overflow condition should be working that given in printNcr() function, but it's not working and all line after 13th are printing wrong values instead of returning false.
How to make given INT_MAX condition work?

int oveflow cannot be reliably detected after it happens.
One way to detect upcoming int overflow in factorial:
int getFactorial(int n) {
if (n <= 0) {
return 1; // and maybe other code when n < 0
}
int limit = INT_MAX/n;
int ans = 1;
for (int i = 2; i <= n; i++) {
if (ans >= limit) {
return INT_MAX; // Or some other code
}
ans = ans * i;
}
return ans;
}
Another way is at startup, perform a one-time calculation for maximum n. With common 32-bit int, that limit is 12.
int getFactorial(int n) {
if (n > getFactorial_pre_calculated_limit) {
return INT_MAX;
}
...

You can detect overflow by watching for negative value
int getFectorial(int n)
{
int ans = 1;
for (int i = n; i >= 1; i--)
{
ans = ans * i;
if (ans < 0) <<<<======
return -1;
}
return ans;
}
then
int printNcr(int n, int r)
{
if (getFectorial(n) < 0)
{
return 0;
}
return (getFectorial(n)) / ((getFectorial(r)) * (getFectorial(n - r)));
}
Please note though that strictly speaking this is undefined behavior. It would be better to simply fail if you know the result is going to be too big (Ie n > 13)
Or better do it like this
int getFectorial(int n)
{
long long ans = 1; <<<====
for (int i = n; i >= 1; i--)
{
ans = ans * i;
if (ans >INT_MAX) <<<<======
return -1;
}
return (int)ans;
}
or you could throw std::overflow_error
BTW the word is factorial not fectorial

Related

Listing down permutations of digit in integer form in C++ using 2 for loops, by only switching 2 digits

I need to make a code to switch 2 digits in a number and make it into a new integer
For example
12-->21
123 becomes
213(1,2 switch)
312(1,3 switch)
132 (2,3 switch)
for up to 8 digits of numbers
this is what I came up so far
#include <iostream>
#include <iomanip>
using namespace std;
int digitcount(int n) {
int count=0;
if (n == 0)
return 1;
while (n != 0) {
n = n / 10;
count++;
}
return count;
}
int pow(int num,int n) {
int x = 1;
if (n == 0) {
return 1;
}
for (int i = 0; i < n; i++) {
x = x * num;
}
return x;
}
int a[8];
int main() {
int input;
int newnum = 0;
cout << "Input an integer: ";
cin >> input;
int b = input;
int digit = digitcount(input);
for (int i = digit-1; i>=0; i--) {
a[i] = b % 10;
b = b / 10;
}
for (int i = 0; i < digit - 1; i++) {
newnum = 0;
for (int j = i+1; j < digit; j++) {
if (a[j] == a[i]) {
continue;
}
newnum = a[i] * pow(10, digit - j - 1) + a[i] * pow(10, digit);
}
}
}

prime seive algorithm giving a runtime error

I am trying to implement the Sieve of Eratosthenes algorithm but it giving a runtime error.
didn't get any output though. after providing the input,
#include<iostream>
using namespace std;
//Sieve Approach - Generate an array containing prime Numbers
void prime_sieve(int *p) {
//first mark all odd number's prime
for (int i = 3; i <= 10000; i += 2) {
p[i] = 1;
}
// Sieve
for (long long int i = 3; i <= 10000; i += 2) {
//if the current number is not marked (it is prime)
if (p[i] == 1) {
//mark all the multiples of i as not prime
for (long long int j = i * i; j <= 10000; j = j + i ) {
p[j] = 0;
}
}
}
//special case
p[2] = 1;
p[1] = p[0] = 0;
}
int main() {
int n;
cin >> n;
int p[10000] = {0};
prime_sieve(p);
//lets print primes upto range n
for (int i = 0; i <= n; i++) {
if (p[i] == 1) {
cout << i << " ";
}
}
return 0;
}
compiler didn't throwing any error also it is not providing the output also
program freezes for some seconds and then terminates
As mentioned in the comments, you are going out of bound.
There is also some confusion about the meaning of p[].
In addition, you are not using the value of n in the function, which leads to unnecessary calculations.
Here is a tested programme (up to n = 10000):
#include <iostream>
#include <vector>
#include <cmath>
//Sieve Approach - Generate an array containing prime Numbers less than n
void prime_sieve(std::vector<int> &p, long long int n) {
//first mark all odd number's prime
for (long long int i = 4; i <= n; i += 2) {
p[i] = 0;
}
// Sieve
for (long long int i = 3; i <= sqrt(n); i += 2) {
//if the current number is not marked (it is prime)
if (p[i] == 1) {
//mark all the multiples of i as not prime
for (long long int j = i * i; j <= n; j = j + i ) {
p[j] = 0;
}
}
}
//special cases
p[1] = p[0] = 0;
}
int main() {
long long int n;
std::cout << "Enter n: ";
std::cin >> n;
std::vector<int> p (n+1, 1);
prime_sieve(p, n);
//lets print primes upto range n
for (long long int i = 0; i <= n; i++) {
if (p[i] == 1) {
std::cout << i << " ";
}
}
return 0;
}

Improve on binary converting algorithm (include negative numbers)

I'm doing some C++ array homework. The goals is to convert decimal to binary (include negative numbers). Here's my code, it gets the job done, but I would like to see if anything can be improved, or any better algorithm (using binary shift maybe?).
#include <iostream>
using namespace std;
// doi tu thap phan sang nhi phan
void decToBinary(int n, int nhiphan[])
{
for (int i=0; i < 16; i++)
{
// to binary
nhiphan[i] = n % 2;
n = n / 2;
}
// inverse array
for (int i = 0, j = 15; i < j; i++, j--)
{
int temp = nhiphan[i];
nhiphan[i] = nhiphan[j];
nhiphan[j] = temp;
}
}
void reverse(int& a)
{
if (a == 0)
a++;
else a--;
}
void outArr(const int a[], int size) {
for (int i = 0; i < size; ++i)
cout << a[i];
}
int main()
{
int nhiphan[16];
int n;
do {
cout << "Nhap so (-255 <= n <= 255) chuyen doi sang nhi phan (16 bit): ";
cin >> n;
} while (n > 255 || n < -255);
if (n < 0) {//check negative
n *= -1;
decToBinary(n, nhiphan);
for (int i = 0; i < 16; i++)// 1's complement
reverse(nhiphan[i]);
// +1
if (nhiphan[15] == 0)//2's complement
nhiphan[15] = 1;
else
{
nhiphan[15] = 0;
int i = 15;
do {
reverse(nhiphan[i-1]);
i--;
} while (nhiphan[i-1] == 0);
}
}
else decToBinary(n, nhiphan);
outArr(nhiphan, 16);
return 0;
}

LAP algorithm not working with large numbers

include
#include <fstream>
#include <algorithm>
using namespace std;
long int lenghtOfLongestAP(long int set[],long int n)
{
if (n <= 2) return n;
long int L[n][n];
long int llap = 2;
for (long int i = 0; i < n; i++)
L[i][n-1] = 2;
for (long int j=n-2; j>=1; j--)
{
int i = j-1, k = j+1;
while (i >= 0 && k <= n-1)
{
if (set[i] + set[k] < 2*set[j])
k++;
else if (set[i] + set[k] > 2*set[j])
{ L[i][j] = 2, i--; }
else
{
L[i][j] = L[j][k] + 1;
llap = max(llap, L[i][j]);
i--; k++;
}
}
while (i >= 0)
{
L[i][j] = 2;
i--;
}
}
return llap;
}
int main()
{
ofstream cout("Output.txt");
ifstream cin("cablecar-sub4-attempt3.txt");
int ab;
cin >> ab;
for (long int z = 0; z < ab; z++)
{
long int bs;
cin >> bs;
long int array[bs];
for(long int h = 0; h<bs; h++)
cin >> array[h];
sort(array, array + bs);
cout << "Case #" << z+1 << ": " << lenghtOfLongestAP(array, bs) << endl;
}
return 0;
}
This is my code. It is a LAP (Largest arithmetic progression) algorithm, so it finds the largest progression in an sorted array. I have the following set of data:
pastebin.com/77meKfKW
Strangely, the program crashes after case 30, which it shouldn't. What kind of problem might it be and how can I fix it?
This is probably a stack overflow. You are allocating your array on the stack with 267*267 entries which uses a lot of memory.
Try allocating the memory on the heap instead, or simply changing the array from being local to being global (with a fixed maximum value of n).
e.g.
change
long int lenghtOfLongestAP(long int set[],long int n)
{
if (n <= 2) return n;
long int L[n][n];
to
long int L[1000][1000]; // or whatever your maximum n might be
long int lenghtOfLongestAP(long int set[],long int n)
{
if (n <= 2) return n;

Optimizing a program C++

I have to create a program, which counts bursted baloons, like from ZUMA. If I have a line with 3 or more baloons with the same color this sequence will burst. So in input, I have number of ballons (3 <= N <= 10^5) , and line with numbers (line with baloons color (1 <= сi <= 100) ), with 1 sequence for sure. I have to output number of bursted baloons. I have a programm, but it is working longer than 4000msv sometimes. How can I make it working faster?
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int Fmax(int n, const string& f){
int max;
vector<int> k(n);
int i, j, p = 0;
for (i = 0; i <= n; i++)
{
k[i] = 0;
}
for (i = 0; i <= n; i++)
{
for (j = i; j <= n; j++)
{
if (f[i] == f[j])
{
k[p]++;
}
else break;
}
p++;
}
max = k[0];
for (i = 0; i <= p; i++){ if (max <= k[i]){ max = k[i]; } }
return max;
}
string pog(int n){
int d;
string doa;
for (int i = 1; i <= n; i++){
cin >> d;
doa += (char)d;
}
return doa;
}
void main(){
int i, sc = 1, bf = 1;
string f;
int len;
cin >> i;
f = pog(i);
len = i;
while (Fmax(f.length(), f) >= 3){
for (int c = 1; c <= f.length(); c++){
if (f[c] == f[c - 1]){
if (sc == 1){ bf = c - 1; }
sc++;
}
else{
if (sc >= 3){ f.erase(bf, sc); sc = 1; break; }
sc = 1;
}
}
}
cout << len - f.length() << endl;
}
Any help is warmly welcome.
You are leaking memory. Use vectors to avoid that.
Why do you need to create array? Why not use the string directly?
Pass strings which aren't modified by const reference to avoid copies.
Use constant variables for the lengths:
const unsigned int f_length = f.length();
while (Fmax(f_length, f) >= 3){
for (int c = 1; c <= f_length ; c++){
This helps the compiler reduce the number of calls to the length method.