Calculating OR in function calls - c++
I am trying to solve a question on LeetCode.com:
Given an integer array nums, find the maximum possible bitwise OR of a subset of nums and return the number of different non-empty subsets with the maximum bitwise OR. The bitwise OR of an array a is equal to a[0] OR a[1] OR ... OR a[a.length - 1] (0-indexed). For Input: nums = [3,1], Output: 2.
The code I have is as follows:
class Solution {
public:
int counter;
void helper(vector<int>& nums, int val, int i, int maxval) {
if(val==maxval) counter++;
if(i>=nums.size()) return;
helper(nums, val|nums[i], i+1, maxval);
helper(nums, val, i+1, maxval);
}
int countMaxOrSubsets(vector<int>& nums) {
int maxval=accumulate(begin(nums), end(nums), 0, bit_or<int>());
counter=0;
helper(nums, 0, 0, maxval);
return counter;
}
};
This produces wrong output on the given example [3,1]. However, if I change the helper as below:
void helper(vector<int>& nums, int val, int i, int maxval) {
if(i>=nums.size()) return;
int currval=val|nums[i];
if(currval==maxval) counter++;
helper(nums, currval, i+1, maxval);
helper(nums, val, i+1, maxval);
}
It gives the right answer and gets ACed. I used print statements, but I do not exactly understand: aren't I doing the same thing in both cases? Why does the first one produce wrong output?
Thanks!
Related
C++ - How to return index of minimum element in range query?
I am trying to implement range queries on a segment tree (a binary tree). I am trying to modify the query function so that it can return the index of the minimum value over a range instead of the actual minimum value (which it is currently returning). Tree, update and query functions: int length; // This is the length of the array I am querying int tree[1000000]; // This is a binary tree // You call update at the start with the index you want to change and the value you want to change it to void update(int index, int value, int position = 1, int currentL = 0, int currentR = length-1) { if (currentL == currentR) { tree[position] = value; return; } int mid = (currentL+currentR)/2; if (index <= mid) { update(index, value, position*2, currentL, mid); } else { update(index, value, position*2+1, mid+1, currentR); } tree[c] = min(tree[position*2], tree[position*2+1]); } // You call query with the range you want to query over int query(int qL, int qR, int c = 1, int cL = 0, int cR = length-1) { if (qL <= cL && cR <= qR) { return tree[c]; } int mid = (cL+cR)/2; int ans = 10005; if (qL <= mid) { ans = min(ans, query(qL, qR, 2*c, cL, mid)); } if (qR > mid) { ans = min(ans, query(qL, qR, 2*c+1, mid+1, cR)); } return ans; } Is there a way to change the query function so that it returns not just the minimum value of a range in the array, but also the index of that value?
You can save index together with the value in segment tree by using, e.g., std::pair<int, int> as tree node. If at the leafs we define the pair to be { value, index } for corresponding array element, other nodes should contain pairs { minimal value, its leftmost index } for corresponding range. Since comparison operators for std::pair are defined as lexicographical over constituents, using std::min (which is based on operator< if comparator is not explicitly provided) the same way as in your code will lead to choosing, for each node/range, minimal of child-nodes/subrange minimums together with its index (smaller one will be chosen if minimums are equal, because second pair element is used for comparison then), so it will produce desired accumulation of ranges. Code: std::pair<int, int> tree[1000000]; void update(int index, int value, int position = 1, int currentL = 0, int currentR = length-1) { if (currentL == currentR) { tree[position] = { value, index }; return; } int mid = (currentL+currentR)/2; if (index <= mid) { update(index, value, position*2, currentL, mid); } else { update(index, value, position*2+1, mid+1, currentR); } tree[c] = min(tree[position*2], tree[position*2+1]); } std::pair<int, int> query(int qL, int qR, int c = 1, int cL = 0, int cR = length-1) { if (qL <= cL && cR <= qR) { return tree[c]; } int mid = (cL+cR)/2; std::pair<int, int> ans = { std::numeric_limits<int>::max(), std::numeric_limits<int>::max() }; if (qL <= mid) { ans = min(ans, query(qL, qR, 2*c, cL, mid)); } if (qR > mid) { ans = min(ans, query(qL, qR, 2*c+1, mid+1, cR)); } return ans; } Of course, to make code more readable custom struct with proper data member names may be used, but then you have to define comparison operator(s) yourself (or pass comparators to std::min). Also note that that I used std::numerical_limits (doc) for initial ans value since it's more generic and idiomatic.
Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted. I tried to find it but still can't find where i got out of bounds array
what was i trying to do is a recursion of first 40 fibonacci numbers, when tried to launch a program, it's stopped at return 0;. #include <stdio.h> #define SIZE 40 void sum(int arr[], int n1, int n2, int offset); int main(void) { int arr[SIZE] = { 0, 1 }; printf("%d\n", arr[0]); printf("%d\n", arr[1]); sum(arr, 0, 1, 2); return 0; } void sum(int arr[], int n1, int n2, int offset) { if (offset > SIZE) return; arr[offset] = arr[n1] + arr[n2]; printf("%d\n", arr[offset]); sum(arr, n1 + 1, n2 + 1, offset + 1); }
Look at this check: if (offset > SIZE) return; That means if offset is equal to SIZE, it passes. arr[offset] with offset being equal to SIZE refers to the 41 nth element. This array only have 40 element, hence the corruption. If you run your program in a debugger, it should stop at the crash and you would be able to look at the value of offset that caused the crash. A solution for this would be to change the check to if (offset >= SIZE).
Is there a way to improve the speed of these lines?
I am trying to optimise some code which runs unreasonably slowly for what is required. The top answer here describes the method I am trying (although I am not 100% sure I am implementing it correctly). Only a few lines show up repeatedly on the top of the call stack as I pause the program randomly, however I do not know how I could increase the codes performance given these lines. The essential function of the code is updating a lattice of points repeatedly using the values of the points surrounding a given point. The relevant code for the first line that comes up: The class definition: template<typename T> class lattice{ private: const unsigned int N; //size std::vector<std::vector<T>> lattice_points = std::vector<std::vector<T>>(N,std::vector<T>(N)); //array of points protected: static double mod(double, double) ; public: lattice(unsigned int); lattice(const lattice&); lattice& operator=(const lattice&); ~lattice() {}; T point(int, int) const; void set(int, int, T); unsigned int size() const; }; These lines show up quite often: template <typename T> T lattice<T>::point(int x, int y) const { return (*this).lattice_points[x % N][y % N]; //mod for periodic boundaries }; template <typename T> void lattice<T>::set(int x, int y, T val) { this->lattice_points[x % N][y % N] = val; //mod for periodic boundaries }; They are used here: angle_lattice update_lattice(const angle_lattice& lat, const parameters& par, double dt) { std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> dis(-0.5,0.5); double sqrtdt = sqrt(dt); angle_lattice new_lat(lat.size()); int N = lat.size(); for(int i=0; i < N; i++) { for(int j=0; j < N; j++) { double val = lat.point(i,j)+ dt*(-par.Dx*( sin_points(lat, i, j, i+1, j) + sin_points(lat, i, j, i-1, j) ) -par.Dy*( sin_points(lat, i, j, i, j+1) + sin_points(lat, i, j, i, j-1) ) -par.Lx/2*( cos_points(lat, i, j, i+1, j) + cos_points(lat, i, j, i-1, j) -2) -par.Ly/2*( cos_points(lat, i, j, i, j+1) + cos_points(lat, i, j, i, j-1) -2)) +sqrtdt*2*M_PI*par.Cl*dis(gen); new_lat.set(i,j,val); } } return new_lat; }; double sin_points(const angle_lattice& lat, int i1, int j1, int i2, int j2) { return sin(lat.point(i1, j1) - lat.point(i2, j2)); }; double cos_points(const angle_lattice& lat, int i1, int j1, int i2, int j2) { return cos(lat.point(i1, j1) - lat.point(i2, j2)); }; here angle_lattice is just a lattice where the template parameter is a angle. The set function is overloaded so that the angle is mod 2pi. The only other two functions that appear in the call stack are cos_points and sin_points , as well as generating the random number, but I assume the latter cannot be helped. Is there anything that can be done? Help would be appreciated. Edit: I changed the code following some of the suggestions and now the cosine and sine calculation are the highest. I am not sure what
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.
Recursion function to find power of number
I'm writing a recursion function to find the power of a number and it seems to be compiling but doesn't output anything. #include <iostream> using namespace std; int stepem(int n, int k); int main() { int x, y; cin >> x >> y; cout << stepem(x, y) << endl; return 0; } int stepem(int n, int k) { if (n == 0) return 1; else if (n == 1) return 1; else return n * stepem(n, k-1); } I tried debugging it, and it says the problem is on this line : return n * stepem(n, k-1); k seems to be getting some weird values, but I can't figure out why?
You should be checking the exponent k, not the number itself which never changes. int rPow(int n, int k) { if (k <= 0) return 1; return n * rPow(n, --k); } Your k is getting weird values because you will keep computing until you run out of memory basically, you will create many stack frames with k going to "-infinity" (hypothetically). That said, it is theoretically possible for the compiler to give you a warning that it will never terminate - in this particular scenario. However, it is naturally impossible to solve this in general (look up the Halting problem).
Your algorithm is wrong: int stepem(int n, int k) { if (k == 0) // should be k, not n! return 1; else if (k == 1) // this condition is wrong return 1; else return n * stepem(n, k-1); } If you call it with stepem(2, 3) (for example), you'll get 2 * 2 * 1 instead of 2 * 2 * 2 * 1. You don't need the else-if condition: int stepem(int n, unsigned int k) // unless you want to deal with floating point numbers, make your power unsigned { if (k == 0) return 1; return n * stepem(n, k-1); }
Didn't test it but I guess it should give you what you want and it is tail recursive. int stepemi(int result, int i int k) { if (k == 0 && result == i) return 1; else if (k == 0) return result; else return stepem(result * i, i, k-1); } int stepem(int n, int k) { return stepemi(n, n, k); } The big difference between this piece of code and the other example is that my version could get optimized for tail recursive calls. It means that when you call stepemi recursively, it doesn't have to keep anything in memory. As you can see, it could replace the variable in the current stack frame without having to create a new one. No variable as to remain in memory to compute the next recursion. If you can have optimized tail recursive calls, it also means that the function will used a fixed amount of memory. It will never need more than 3 ints. On the other hand, the code you wrote at first creates a tree of stackframe waiting to return. Each recursion will add up to the next one.
Well, just to post an answer according to my comment (seems I missed adding a comment and not a response :-D). I think, mainly, you have two errors: you're checking n instead of k and you're returning 1 when power is 1, instead of returning n. I think that stepem function should look like: Edit: Updated to support negative exponents by #ZacHowland suggestion float stepem(int n, int k) { if (k == 0) return 1; else return (k<0) ?((float) 1/n) * stepem(n, k+1) :n * stepem(n, k-1); }
// Power.cpp : Defines the entry point for the console application. // #include <stream> using namespace std; int power(int n, int k); void main() { int x,y; cin >>x>>y; cout<<power(x,y)<<endl; } int power(int n, int k) { if (k==0) return 1; else if(k==1) // This condition is working :) // return n; else return n*power(n,k-1); }
your Program is wrong and it Does not support negative value given by user, check this one int power(int n, int k){ 'if(k==0) return 1; else if(k<0) return ((x*power(x,y+1))*(-1)); else return n*power(n,k-1); }
sorry i changed your variable names but i hope you will understand; #include <iostream> using namespace std; double power(double , int);// it should be double because you also need to handle negative powers which may cause fractions int main() { cout<<"please enter the number to be powered up\n"; double number; cin>>number; cout<<"please enter the number to be powered up\n"; int pow; cin>>pow; double result = power(number, pow); cout<<"answer is "<<result <<endl; } double power( double x, int n) { if (n==0) return 1; if (n>=1) /*this will work OK even when n==1 no need to put additional condition as n==1 according to calculation it will show x as previous condition will force it to be x; try to make pseudo code on your note book you will understand what i really mean*/ if (n<0) return x*power(x, n-1); return 1/x*power(x, n+1);// this will handle negative power as you should know how negative powers are handled in maths }
int stepem(int n, int k) { if (k == 0) //not n cause you have to vary y i.e k if you want to find x^y return 1; else if (k == 1) return n; //x^1=x,so when k=1 it should be x i.e n else return n * stepem(n, k-1); }