Array function doesn't seem to be finding the highest value - c++
I have a piece of code which is supposed to return the highest integer from a set of arrays each containing three integers. Currently my code isn't working. Can someone help me find my bug?
This is my code below:
#include <iostream>
using namespace std;
void HighestScore(int[], int[], int[]);
int main() {
const int SIZE = 3;
int Stu1[SIZE] = {70, 80, 90},
Stu2[SIZE] = {71, 81, 91},
Stu3[SIZE] = {72, 82, 92},
Stu4[SIZE] = {73, 83, 93},
Stu5[SIZE] = {74, 84, 94};
HighestScore(Stu1,Stu2,Stu3);
return 0;
}
void HighestScore(int St1[], int St2[], int St3[])
{
const int SIZE =3;
int count;
int high1 = St1[0];
int high2 = St2[0];
int high3 = St3[0];
int highest =0;
for (count=1;count<SIZE;count++)
{
if(St1[count] > high1)
{high1 = St1[count];}
if(St2[count] >high2)
{high2 = St2[count];}
if(St3[count] >high3)
{high3 = St3[count];}
}
if(high1>high2)
{highest=high1;}
else if (high1>high3)
{highest=high1;}
else if (high2>high1)
{highest=high2;}
else if (high2>high3)
{highest=high2;}
else if (high3>high1)
{highest=high3;}
else if (high3>high2)
{highest=high3;}
else
{highest=-1;}
cout << highest;
return;
}
Since the array sizes are the same, you need not process each highest separately.
Let highest store the highest at the moment and get overwritten by the next highest.
Why not just:
int HighestScore(int St1[], int St2[], int St3[])
{
const int SIZE =3;
int count;
//make sure you have #include <limits.h> in the beginning
int highest = INT_MIN; //---lowest value of an integer in C;
for (count=0;count<SIZE;count++)
{
if(St1[count] > highest)
highest = St1[count];
if(St2[count] > highest)
highest = St2[count];
if(St3[count] > highest)
highest = St3[count];
}
cout << highest;
return highest;
}
For the initial value of highest, take the lowest possible value of an integer, so that an overwrite is guaranteed.
Lowest possible value of an integer is also avaiable as INT_MIN in limits.h.
At least one problem is in this big if part
if(high1>high2)
{highest=high1;}
else if (high1>high3)
{highest=high1;}
else if (high2>high1)
{highest=high2;}
else if (high2>high3)
{highest=high2;}
else if (high3>high1)
{highest=high3;}
else if (high3>high2)
{highest=high3;}
else
{highest=-1;}
Suppose high1 = 3, high2 = 2, high3 = 10, the if part chooses high1 as highest value because of the following branch although the highest should be high3
if(high1>high2)
{highest=high1;}
A better approach would be making a helper function find_max that return the max of an array, then using it to find the max of 3 arrays
The pseudo code should be
int find_max(int a[]);
int HighestScore(int st1[], int st2[], int st3[]){
int tmp[] = {find_max(st1), find_max(st2), find_max(st3)};
return find_max(tmp);
}
And I would suggest using vector instead of array.
Do the following;
Replace all "else if" statement with "if" statement, and remove the last "else" statement.
or,
replace your function with this,
void HighestScore(int St1[], int St2[], int St3[])
{
const int SIZE =3;
int count;
int high1 = St1[0];
int high2 = St2[0];
int high3 = St3[0];
int highest;
for (count=1;count<SIZE;count++)
{
if(St1[count] > high1)
{high1 = St1[count];}
if(St2[count] >high2)
{high2 = St2[count];}
if(St3[count] >high3)
{high3 = St3[count];}
}
highest=high1;
if(high2>highest)
{highest=high2;}
if (high3>highest)
{highest=high3;}
cout << highest;
return;
}
With std, you may simply do:
const auto highest = std::max({
*std::max_element(std::begin(Stu1), std::end(Stu1)),
*std::max_element(std::begin(Stu2), std::end(Stu2)),
*std::max_element(std::begin(Stu3), std::end(Stu3)),
});
std::cout << highest << std::endl;
Demo
I wrote a function which returns the highest number in an array. All you have to do is run that function on all of your arrays, save the highest from each array and run the function again.
#include <iostream>
using namespace std;
int HighestScore(int Stu[], int length);
int main() {
const int SIZE = 3;
int Stu1[SIZE] = {70, 80, 90};
int Stu2[SIZE] = {71, 81, 91};
int Stu3[SIZE] = {72, 82, 92};
int highestArr[3];
int highest;
highestArr[0] = HighestScore(Stu1, SIZE);
highestArr[1] = HighestScore(Stu2, SIZE);
highestArr[2] = HighestScore(Stu3, SIZE);
highest = HighestScore(highestArr, 3);
cout << highest << std::endl;
return 0;
}
int HighestScore(int Stu[], int length) {
int highest = 0; // Init to 0 since mark can't be lower than 0
for(int i = 0; i < length; i++) {
if(highest < Stu[i]) {
highest = Stu[i];
}
}
return highest;
}
Related
Variable Length Arrays: How to create a buffer with variable size in C++
I am currently writing a moving average class. The goal is to be able to specify the buffer size as part of the constructor when a new object of class Running_Average is created. #include <iostream> #include "Complex.h" #include <cmath> #include<stdio.h> #include<stdlib.h> #include <windows.h> using namespace std; class Running_Average { public: double sum = 0; double average = 0; int i; double Average(void); // Member functions declaration void AddSample(double); Running_Average(int); }; Running_Average::Running_Average(int size) { int buffersize = size; double buffer[buffersize] = { 0 }; } void Running_Average::AddSample(double val) //Add new values to buffer { for (i = 9; i>0; i--) { buffer[i] = buffer[i-1]; } buffer[0] = val; } double Running_Average::Average(void) //Calculate Average of current values in buffer { for (i = 0; i<buffersize; i++) { cout << buffer[i] << endl; sum += buffer[i]; } average = sum / buffersize; sum = 0; return average; } int main() { double value; int i; int f = 0; Running_Average test; for (i = (40); i < (50); i++) { test.AddSample(i); } while (1) { i = rand() % 100; test.AddSample(i); value = test.Average(); cout << endl; cout << value << endl; cout << endl; Sleep(1000); } } However, the constructor is giving me grief: Running_Average::Running_Average(int size) { int buffersize = size; double buffer[buffersize] = { 0 }; } Specifically: buffer[buffersize] throws an error in visual studio saying: expression must have a constant size. I want the user to specify what buffer size they want to work with when they create a new object by passing their value to the constructor. How can I make this work without it throwing an error? Thanks for your help! EDIT: SOLVED! Thank you everyone for your assistance! I managed to get the function working by using the std::vector to define a variable sized array.
There are plenty of ways to do this. The ones that come to mind from best to worst are : 1 Use std::vector int buffersize = size; std::vector<double> buffer(buffersize); 2 Built-in unique pointer or shared pointer (depending on usage) int buffersize = size; auto buffer = make_unique<double[]>(buffersize) // C++14 int buffersize = size; auto buffer = make_shared<double[]>(buffersize) // C++14 3 Allocate manually int buffersize = size; double *buffer = new double[buffersize]; // delete [] buffer, must be called later 4 Allocate on the stack (not advised, and platform dependent) int buffersize = size; double *buffer = alloca(buffersize * sizeof(*buffer)); Note that in all these cases you could index buffer just like an array.
Standard C++ doesn't have variable length arrays. (Why?) The size of an array must be a constant expression. Some compilers have non-standard extensions that allow VLAs, but you shouldn't rely on them. Use std::vector when you need an array which can have a variable length and can be resized.
Variable length arrays are valid in C but not in C++. In C++ you're better off using a vector collection since that allows you to better represent the intent, a varying array size, without having to maintain the current size separately. The following complete program gives you a baseline to work from, including test harness code: #include <iostream> #include <vector> class RunningValues { public: RunningValues(size_t size = 50); void Add(double val); double Sum(); double Average(); private: std::vector<double> dataBuffer; size_t sizeLimit; double sum; }; // Constructor: store limit and zero sum (vector is already empty). RunningValues::RunningValues(size_t size): sizeLimit(size), sum(0.0) {} // Add a sample. void RunningValues::Add(double val) { // Zero size, disallow adds. if (sizeLimit == 0) return; // If we would exceed limit, remove earliest. if (dataBuffer.size() == sizeLimit) { sum -= dataBuffer[0]; dataBuffer.erase(dataBuffer.begin()); } // Add value to end. sum += val; dataBuffer.push_back(val); } // Get the average (zero if nothing yet added) or sum. double RunningValues::Average() { if (dataBuffer.size() == 0) return 0.0; return sum / dataBuffer.size(); } double RunningValues::Sum() { return sum; } // Test harness. int main() { RunningValues test(10); std::cout << "Ave = " << test.Average() << ", sum = " << test.Sum() << '\n'; for (int i = 40; i < 50; ++i) { test.Add(i); std:: cout << "Add " << i << ", ave = " << test.Average() << ", sum=" << test.Sum() << '\n'; } for (int i = 0; i < 20; ++i) { int val = rand() % 100; test.Add(val); std:: cout << "Add " << val << ", ave = " << test.Average() << ", sum=" << test.Sum() << '\n'; } } A sample run, which shows the averages and sums at various points, is shown below: Ave = 0, sum = 0 Add 40, ave = 40, sum=40 Add 41, ave = 40.5, sum=81 Add 42, ave = 41, sum=123 Add 43, ave = 41.5, sum=166 Add 44, ave = 42, sum=210 Add 45, ave = 42.5, sum=255 Add 46, ave = 43, sum=301 Add 47, ave = 43.5, sum=348 Add 48, ave = 44, sum=396 Add 49, ave = 44.5, sum=445 Add 83, ave = 48.8, sum=488 Add 86, ave = 53.3, sum=533 Add 77, ave = 56.8, sum=568 Add 15, ave = 54, sum=540 Add 93, ave = 58.9, sum=589 Add 35, ave = 57.9, sum=579 Add 86, ave = 61.9, sum=619 Add 92, ave = 66.4, sum=664 Add 49, ave = 66.5, sum=665 Add 21, ave = 63.7, sum=637 Add 62, ave = 61.6, sum=616 Add 27, ave = 55.7, sum=557 Add 90, ave = 57, sum=570 Add 59, ave = 61.4, sum=614 Add 63, ave = 58.4, sum=584 Add 26, ave = 57.5, sum=575 Add 40, ave = 52.9, sum=529 Add 26, ave = 46.3, sum=463 Add 72, ave = 48.6, sum=486 Add 36, ave = 50.1, sum=501 If you would rather have a solution which avoids vector (it's a bit wasteful to have all that extra functionality when the vector goes from size 0 up to N and then stays there), you can just use a naked array on the heap as a circular buffer. The code for that is a slight variation (sans main since it hasn't changed): #include <iostream> class RunningValues { public: RunningValues(size_t size = 50); ~RunningValues(); void Add(double val); double Sum(); double Average(); private: size_t count, next, limit; double sum, *data; }; RunningValues::RunningValues(size_t size) : count(0), next(0), limit(size) , sum(0.0), data(new double[size]) {} RunningValues::~RunningValues() { delete[] data; } void RunningValues::Add(double val) { // Zero size, disallow adds. if (limit == 0) return; // If we would exceed limit, remove earliest. if (count == limit) { sum -= data[next]; --count; } // Add value to end. data[next] = val; sum += val; ++count; next = (next + 1) % limit; } // Get the average (zero if nothing yet added) or sum. double RunningValues::Average() { if (count == 0) return 0.0; return sum / count; } double RunningValues::Sum() { return sum; } The changes from the vector-based solution are fairly minor: The constructor no longer has a vector (obviously). Instead it has a fixed size array to use as a circular buffer, along with the count and next variables to manage it. You now need a destructor to clean up the buffer (before, the vector managed itself). the adding of items now uses count and next (rather than the vector) to figure out how to adjust the sum and keep a tally of the relevant data. the calculations of average now uses count rather than the vector size. Other than that, it's actually very similar to the vector-based code above.
Based on the way you use buffer I would suggest using an std::list<double> for it. Add this to the beginning of Running_Average: class Running_Average { private: list<double> buffer; const size_t MaxBufferSize; public: ... The constructor : Running_Average::Running_Average(size_t size) : MaxBufferSize(size) { } AddSample() and Average() : void Running_Average::AddSample(double val) { if (buffer.size() == MaxBufferSize) { buffer.pop_back(); } buffer.push_front(val); } double Running_Average::Average() { double sum = 0; for (auto a : buffer) { cout << a << endl; sum += a; } return sum / buffer.size(); } I would also remove the sum, average and i member variables and instead declare them where they are used (if needed).
expression must have a constant size double buffer[buffersize] = { 0 }; First, buffersize isn't a constexpr. It is a variable that changes during runtime. When specifying a size for an array, as per the standard definition of array: The constant expression specifies the bound of (number of elements in) the array. If the value of the constant expression is N, the array has N elements numbered 0 to N-1, Sample declaration of an array with 5 elements of type double should be like: double buffer[5]; // 5 is a literal constexpr int size = 5; double buffer[size]; // size is constexpr Second, buffer is a variable-length array (VLA). VLAs are partly supported in some compilers as an extension. How can I make this work without it throwing an error? If you need the length to be variable, use std::vector and initialize it in your constructor: class Running_Average { Running_Average(int size): buffer(size, 0) {} std::vector<double> buffer; }
Why would this code give a segfault only for some cases?
I am trying to code a Word-RAM version of the subset sum. (It is a basic dp algorithm, and the algo itself should not be important to determine the problem with the code). This is the minimum code needed to reproduce the error I think: #include <stdio.h> #include <stdlib.h> #include <math.h> // get bit #bitno from num. 0 is most significant. unsigned int getbit(unsigned int num, int bitno){ unsigned int w = sizeof(int)*8; //for regular word. int shiftno = w-bitno-1; unsigned int mask = 1<<shiftno; unsigned int maskedn = num&mask; unsigned int thebit = maskedn>>shiftno; return thebit; } /* No boundary array right shift */ unsigned int* nbars(unsigned int orig[], unsigned int x){ int alength = sizeof(orig)/sizeof(orig[0]); unsigned int b_s = sizeof(int)*8; unsigned int * shifted; shifted = new unsigned int[alength]; int i; for(i=0;i<alength;i++){ shifted[i] = 0; } unsigned int aux1 = 0; unsigned int aux2 = 0; int bts = floor(x/b_s); int split = x%b_s; i = bts; int j = 0; while(i<alength){ aux1 = orig[j]>>split; shifted[i] = aux1|aux2; aux2 = orig[j]<<(b_s-split); i++;j++; } return shifted; } /* Returns true if there is a subset of set[] with sum equal to t */ bool isSubsetSum(int set[],int n, int t){ unsigned int w = sizeof(int)*8; //for regular word. unsigned int wordsneeded = ceil(double(t+1)/w); unsigned int elements = n; //Create table unsigned int table[elements][wordsneeded]; int c,i; //Initialize first row for(i=0;i<wordsneeded;i++){ table[0][i] = 0; } table[0][0] = 1<<(w-1); //Fill the table in bottom up manner int es,ss,ai; for(c=1;c<=elements; c++){ unsigned int *aux = nbars(table[c-1],set[c-1]); for(i=0;i<wordsneeded;i++){ table[c][i] = table[c-1][i]|aux[i]; } } if((table[elements][wordsneeded-1]>>((w*wordsneeded)-t-1))&1 ==1){ return true; }return false; } int main(){ int set[] = {81,80,43,40,30,26,12,11,9}; //int sum = 63; int sum = 1000; int n = sizeof(set)/sizeof(set[0]); if (isSubsetSum(set,n,sum) == true) printf("\nFound a subset with given sum\n"); else printf("\nNo subset with given sum\n"); return 0; } Ok. so If I run the example with a target sum of 63, it works just fine. gives the right answer , True, and if I run code to print the subset it prints the right subset. however, if I change the sum to a larger one, say 1000 like in the code, I get the following error: Program received signal SIGSEGV, Segmentation fault. 0x0000000000400af1 in isSubsetSum (set=0x0, n=0, t=0) at redss.cpp:63 63 unsigned int *aux = nbars(table[c-1],set[c-1]); from gdb. I really don't understand why it would fail only for larger sums, since the process should be the same... am I missing something obvious? Any help would be great!!!
median of two sorted arrays of different size
i was solving this problem from geeks for geeks http://www.geeksforgeeks.org/median-of-two-sorted-arrays-of-different-sizes/ but when i implemented the same code ,then for input A[] = {1,2,3} B[] = {3,6,9,12} it is giving wrong output as 6 but it should be 3 ,someone please tell me the problem with my code? //code #include<iostream> #include<cmath> using namespace std; float single_median(int arr[],int size)//method to find median in an arr { if(size == 0) return -1; else if(size%2==0) return (arr[size/2] + arr[size/2 -1])/2.0; else return arr[size/2]; } float medianOf2(int a,int b)//median of two numbers { return ((a+b)/2.0); } int medianOf3(int a,int b,int c)//median of 3 numbers { int maximum = max(a,max(b,c)); int minimum = min(a,min(b,c)); return ((a+b+c) - maximum - minimum); } int medianOf4(int a, int b,int c,int d)//median of 4 numbers { int maximum = max(a,max(b,max(c,d))); int minimum = min(a,min(b,min(c,d))); return ((a+b+c+d) - maximum - minimum); } int find_median(int A[],int m,int B[],int n) { if(m<n)//here we will keep in mind that A is larger than B else we swap return find_median(B,n,A,m); if(n==0)//if smaller array has no element just find the median of larger array return single_median(A,m); if(n==1)//if smaller array has one element { if(m==1) return (A[0]+B[0])/2.0;//if both has one element just return the average else if(m&1)//when larger array has odd elements return medianOf2(medianOf3(B[0],A[m/2 - 1],A[m/2 + 1]),A[m/2]); else//for e return medianOf3(B[0],A[m/2],A[m/2 -1]); } if(n==2) { if(m==2) return medianOf4(A[0],B[0],A[1],B[1]); else if(m&1) return medianOf3(max(B[0],A[m/2 -1]),min(B[1],A[m/2 +1]),A[m/2]); else return medianOf4(max(B[0],A[m/2 -2]),min(B[1],A[m/2 +1]),A[m/2],A[m/2 -1]); } int mid_m = (m-1)/2; int mid_n = (n-1)/2; if(A[mid_m]<B[mid_n]) find_median(A + mid_m,m/2 +1 ,B,n - mid_n); else find_median(A,n/2 +1, B + mid_n, n/2 + 1); } int main() { int B[] = {1,2,3}; int A[] = {3,6,9,12}; cout<<find_median(A,4,B,3); return 0; }
You simply forgot to divide the result by 2.0 in the medianOf4 function before returning the result as so: int medianOf4(int a, int b,int c,int d)//median of 4 numbers { int maximum = max(a,max(b,max(c,d))); int minimum = min(a,min(b,min(c,d))); return ((a+b+c+d) - maximum - minimum) / 2.0; # <-- forgot to add "/ 2.0" } Hope this helps!
public class Solution { public double FindMedianSortedArrays(int[] nums1, int[] nums2) { if(nums1== null || nums1.Length<1) return result(nums2); else if(nums2== null || nums2.Length<1) return result(nums1); int[] merged = new int[nums1.Length + nums2.Length]; int num1Ind=0; int num2Ind=0; int currInd = 0; while(num1Ind<nums1.Length && num2Ind<nums2.Length){ if(nums1[num1Ind]< nums2[num2Ind]) merged[currInd++]=nums1[num1Ind++]; else merged[currInd++]=nums2[num2Ind++]; } if(num2Ind<nums2.Length) for(int i=num2Ind; i<nums2.Length; i++) merged[currInd++]=nums2[i]; else if(num1Ind<nums1.Length) for(int i=num1Ind; i<nums1.Length; i++) merged[currInd++]=nums1[i]; return result(merged); } private double result(int[] merged){ if(merged.Length==1) return merged[0]; if((merged.Length)%2 !=0) return (double)merged[merged.Length/2]; return (double)(merged[merged.Length/2-1] + merged[merged.Length/2])/2; } }
Having problems with ctime, and working out function running time
I'm having trouble working out the time for my two maxsubarray functions to run. (right at the bottom of the code) The output it gives me: Inputsize: 101 Time using Brute Force:0 Time Using DivandCon: 12 is correct for the second time I use clock() but for the first difference diff1 it just gives me 0 and I'm not sure why? Edit: Revised Code. Edit2: Added Output. #include <iostream> #include <cmath> #include <cstdlib> #include <ctime> #include <limits.h> using namespace std; int Kedane(int a[], int size) { int max_so_far = 0, max_ending_here = 0; int i; for(i = 0; i < size; i++) { max_ending_here = max_ending_here + a[i]; if(max_ending_here < 0) max_ending_here = 0; if(max_so_far < max_ending_here) max_so_far = max_ending_here; } return max_so_far; } int BruteForce(int array[],int n) { int sum,ret=0; for(int j=-1;j<=n-2;j++) { sum=0; for(int k=j+1;k<+n-1;k++) { sum+=array[k]; if(sum>ret) { ret=sum; } } } return ret; } //------------------------------------------------------ // FUNCTION WHICH FINDS MAX OF 2 INTS int max(int a, int b) { return (a > b)? a : b; } // FUNCTION WHICH FINDS MAX OF 3 NUMBERS // CALL MAX FUNCT FOR 2 VARIS TWICE! int max(int a, int b, int c) { return max(max(a, b), c); } // WORKS OUT FROM MIDDLE+1->RIGHT THE MAX SUM & // THE MAX SUM FROM MIDDLE->LEFT + RETURNS SUM OF THESE int maxCrossingSum(int arr[], int l, int m, int h) { int sum = 0; // LEFT OF MID int LEFTsum = INT_MIN; // INITIALLISES SUM TO LOWEST POSSIBLE INT for (int i = m; i >= l; i--) { sum = sum + arr[i]; if (sum > LEFTsum) LEFTsum = sum; } sum = 0; // RIGHT OF MID int RIGHTsum = INT_MIN; for (int i = m+1; i <= h; i++) { sum = sum + arr[i]; if (sum > RIGHTsum) RIGHTsum = sum; } // RETURN SUM OF BOTH LEFT AND RIGHT SIDE MAX'S return LEFTsum + RIGHTsum; } // Returns sum of maxium sum subarray in aa[l..h] int maxSubArraySum(int arr[], int l, int h) { // Base Case: Only one element if (l == h) return arr[l]; // Find middle point int m = (l + h)/2; /* Return maximum of following three possible cases a) Maximum subarray sum in left half b) Maximum subarray sum in right half c) Maximum subarray sum such that the subarray crosses the midpoint */ return max(maxSubArraySum(arr, l, m), maxSubArraySum(arr, m+1, h), maxCrossingSum(arr, l, m, h)); } // DRIVER int main(void) { std::srand (time(NULL)); // CODE TO FILL ARRAY WITH RANDOMS [-50;50] int size=30000; int array[size]; for(int i=0;i<=size;i++) { array[i]=(std::rand() % 100) -50; } // TIMING VARI'S clock_t t1,t2; clock_t A,B; clock_t K1,K2; volatile int mb, md, qq; //VARYING ELEMENTS IN THE ARRAY for(int n=101;n<size;n=n+100) { t1=clock(); mb=BruteForce(array,n); t2=clock(); A=clock(); md=maxSubArraySum(array, 0, n-1) ; B=clock(); K1=clock(); qq=Kedane(array, n); K2=clock(); cout<< n << "," << (double)t2-(double)t1 << ","<<(double)B-(double)A << ","<<(double)K2-(double)K1<<endl; } return 0; } 101,0,0,0 201,0,0,0 301,1,0,0 401,0,0,0 501,0,0,0 601,0,0,0 701,0,0,0 801,1,0,0 901,1,0,0 1001,0,0,0 1101,1,0,0 1201,1,0,0 1301,0,0,0 1401,1,0,0 1501,1,0,0 1601,2,0,0 1701,1,0,0 1801,2,0,0 1901,1,1,0 2001,1,0,0 2101,2,0,0 2201,3,0,0 2301,2,0,0 2401,3,0,0 2501,3,0,0 2601,3,0,0 2701,4,0,0 2801,4,0,0 2901,4,0,0 3001,4,0,0 3101,4,0,0 3201,5,0,0 3301,5,0,0 3401,6,0,0 3501,5,0,0 3601,6,0,0 3701,6,0,0 3801,8,0,0 3901,7,0,0 4001,8,0,0 4101,7,0,0 4201,10,1,0 4301,9,0,0 4401,8,0,0 4501,9,0,0 4601,10,0,0 4701,11,0,0 4801,11,0,0 4901,11,0,0 5001,12,0,1 5101,11,1,0 5201,13,0,0 5301,13,0,0 5401,15,0,0 5501,14,0,0 5601,16,0,0 5701,15,0,0 5801,15,1,0 5901,16,0,0 6001,17,0,0 6101,18,0,0 6201,18,0,0 6301,19,0,0 6401,21,0,0 6501,19,0,0 6601,21,1,0 6701,20,0,0 6801,22,0,0 6901,23,0,0 7001,22,0,0 7101,24,0,0 7201,26,0,0 7301,26,0,0 7401,24,1,0 7501,26,0,0 7601,27,0,0 7701,28,0,0 7801,28,0,0 7901,30,0,0 8001,29,0,0 8101,31,0,0 8201,31,1,0 8301,35,0,0 8401,33,0,0 8501,35,0,0 8601,35,1,0 8701,35,0,0 8801,36,1,0 8901,37,0,0 9001,38,0,0 9101,39,0,0 9201,41,1,0 9301,40,0,0 9401,41,0,0 9501,42,0,0 9601,45,0,0 9701,45,0,0 9801,44,0,0 9901,47,0,0 10001,47,0,0 10101,48,0,0 10201,50,0,0 10301,51,0,0 10401,50,0,0 10501,51,0,0 10601,53,0,0 10701,55,0,0 10801,54,0,0 10901,56,0,0 11001,57,0,0 11101,56,0,0 11201,60,0,0 11301,60,0,0 11401,61,1,0 11501,61,1,0 11601,63,0,0 11701,62,1,0 11801,66,1,0 11901,65,0,0 12001,68,1,0 12101,68,0,0 12201,70,0,0 12301,71,0,0 12401,72,0,0 12501,73,1,0 12601,73,1,0 12701,76,0,0 12801,77,0,0 12901,78,1,0 13001,79,1,0 13101,80,0,0 13201,83,0,0 13301,82,0,0 13401,86,0,0 13501,85,1,0 13601,86,0,0 13701,89,0,0 13801,90,0,1 13901,90,0,0 14001,91,0,0 14101,97,0,0 14201,93,0,0 14301,96,0,0 14401,99,0,0 14501,100,0,0 14601,101,0,0 14701,101,0,0 14801,103,1,0 14901,104,0,0 15001,107,0,0 15101,108,0,0 15201,109,0,0 15301,109,0,0 15401,114,0,0 15501,114,0,0 15601,115,0,0 15701,116,0,0 15801,119,0,0 15901,118,0,0 16001,124,0,0 16101,123,1,0 16201,123,1,0 16301,125,0,0 16401,127,1,0 16501,128,1,0 16601,131,0,0 16701,132,0,0 16801,134,0,0 16901,134,1,0 17001,135,1,0 17101,139,0,0 17201,139,0,0 17301,140,1,0 17401,143,0,0 17501,145,0,0 17601,147,0,0 17701,147,0,0 17801,150,1,0 17901,152,1,0 18001,153,0,0 18101,155,0,0 18201,157,0,0 18301,157,1,0 18401,160,0,0 18501,160,1,0 18601,163,1,0 18701,165,0,0 18801,169,0,0 18901,171,0,1 19001,170,1,0 19101,173,1,0 19201,178,0,0 19301,175,1,0 19401,176,1,0 19501,180,0,0 19601,180,1,0 19701,182,1,0 19801,184,0,0 19901,187,1,0 20001,188,1,0 20101,191,0,0 20201,192,1,0 20301,193,1,0 20401,195,0,0 20501,199,0,0 20601,200,0,0 20701,201,0,0 20801,209,1,0 20901,210,0,0 21001,206,0,0 21101,210,0,0 21201,210,0,0 21301,213,0,0 21401,215,1,0 21501,217,1,0 21601,218,1,0 21701,221,1,0 21801,222,1,0 21901,226,1,0 22001,225,1,0 22101,229,0,0 22201,232,0,0 22301,233,1,0 22401,234,1,0 22501,237,1,0 22601,238,0,1 22701,243,0,0 22801,242,1,0 22901,246,1,0 23001,246,0,0 23101,250,1,0 23201,250,1,0 23301,254,1,0 23401,254,0,0 23501,259,0,1 23601,260,1,0 23701,263,1,0 23801,268,0,0 23901,266,1,0 24001,271,0,0 24101,272,1,0 24201,274,1,0 24301,280,0,1 24401,279,0,0 24501,281,0,0 24601,285,0,0 24701,288,0,0 24801,289,0,0 24901,293,0,0 25001,295,1,0 25101,299,1,0 25201,299,1,0 25301,302,0,0 25401,305,1,0 25501,307,0,0 25601,310,1,0 25701,315,0,0 25801,312,1,0 25901,315,0,0 26001,320,1,0 26101,320,0,0 26201,322,0,0 26301,327,1,0 26401,329,0,0 26501,332,1,0 26601,339,1,0 26701,334,1,0 26801,337,0,0 26901,340,0,0 27001,341,1,0 27101,342,1,0 27201,347,0,0 27301,348,1,0 27401,351,1,0 27501,353,0,0 27601,356,1,0 27701,360,0,1 27801,361,1,0 27901,362,1,0 28001,366,1,0 28101,370,0,1 28201,372,0,0 28301,375,1,0 28401,377,1,0 28501,380,0,0 28601,384,1,0 28701,384,0,0 28801,388,1,0 28901,391,1,0 29001,392,1,0 29101,399,1,0 29201,399,0,0 29301,404,1,0 29401,405,0,0 29501,409,1,0 29601,412,2,0 29701,412,1,0 29801,422,1,0 29901,419,1,0
The return values from BruteForce and maxSubArraySum are never used, and this gives the compiler a lot of lattitude when it comes to optimizing them. On my machine for example, using clang -O3 reduces the call to BruteForce to a vector copy and nothing else. One method for forcing the evaluation of these functions is to write their results to volatile variables: volatile int mb, md; // ... mb = BruteForce(array, n); // ... md = maxSubArraySum(array, 0, n-1); As the variables are volatile, the value given by the right-hand side of the assignments must be stored, despite the absence of any other side-effects, which prevents the compiler from optimising the computation away.
Printing (Factorial of 2^n)/(2^n -1)mod m in C++
How can we store and print factorial(2^n) / (2^n -1))mod1000000009 in C++.Here n can be as large as 20. When I try to print this using the following code, it shows segmentation fault for n=20 #include #include using namespace std; long int factorial(int n) { if(n<=1){return 1;} else return (n%1000000009)*(factorial(n-1))%1000000009; } int main() { int K; long long int numofmatches=0; long long int denominator=0; long long int factor=0; long long int times=0; long long int players=0; cin>>K; if(K==1) { cout<<2<<endl<<2<<endl; return 0; } else { denominator=pow(2,K); cout<<"Denominator="<<denominator<<endl; numofmatches=factorial(denominator)%1000000009; denominator-=1; cout<<"numberofmatches="<<numofmatches<<endl; cout<<"Denominator="<<denominator<<endl; factor=numofmatches/denominator; cout<<"Factor="<<factor<<endl; while(times<=denominator) { cout<<(times*factor)<<endl; ++times; } } return 0; }
First of all, note that (2^n)! / (2^n-1) is equal to (2^n-2)! x 2^n. Now, (2^20-2)! by itself is already an extremely large number to calculate. What you can do instead, is to modulo the intermediate result with 1000000009 after every multiplication: #define MAX ((1<<20)-2) unsigned long long res = 1; for (unsigned int i=1; i<=MAX; i++) res = (res*i)%1000000009; res = (res*(MAX+2))%1000000009; If you want to iterate all values of n between 1 and 20, then you can use: #define MAX_N 20 unsigned int arr[MAX_N+1] = {0}; void Func() { unsigned int i = 1; unsigned long long res = 1; for (int n=1; n<=MAX_N; n++) { unsigned int max = (1<<n)-2; for (; i<=max; i++) res = (res*i)%1000000009; arr[n] = (unsigned int)((res*(max+2))%1000000009); } } BTW, for any n larger than 29 the result will simply be 0, as (2^30-2) is larger than 1000000009. So (2^30-2)! is divisible by 1000000009, and therefore, (2^30-2)! mod 1000000009 equals 0.