Related
#include<stdio.h>
int binary_search(int arr[], int size ,int element){
int low, mid, high;
low=0;
high=size-1;
//start of search
while(low<=high)
{
mid = (low + high)/2;
if(arr[mid] == element){
return mid;
}
if(arr[mid]<element){
low= mid+1;
}
else{
high = mid-1;
}
}
//end of search
return -1;
}
int main(){
int arr[20]={1,20,31,44,54,68,70,85};
int size= sizeof(arr)/sizeof(int);
int element=44;
int Si= binary_search(arr,size,element);
printf("Element was found at index: %d \n",Si);
return 0;
}
why does my code returns -1 everytime .
I tried changing arr[20] to arr[] in main function and it started working fine.
Can someone explain me the reason behind this?
This line of code creates an integer array of length 20, with all the elements after 85 being initialized to zeros.
int arr[20]={1,20,31,44,54,68,70,85};
The sizeof operator gives the size, in bytes, of the integer array arr of length 20, which causes the value of size to be 20. This causes the binary search algorithm to fail, as it does not deal with arrays that are not sorted.
Given a number N and a sorted array A, design an algorithm - using the Divide and Conquer approach - to check if there exist index i and index j such that A[i]*A[j] == N (return 1 if present, 0 if not).
I'm having a hard time proceeding in the required (recursive) way. I think I figured out only a part of one possible solution, but even there I'm not a 100% sure if it's correct: I thought that if the product between the first element and the central element of the array is greater than N, then the numbers I'm looking for (if present) are certainly in the first half of the array, so I can recursively call the function on that part, like so (I'm using C):
int productN(int A[], int i, int j, int N){
// missing base case
int m = (i+j)/2;
if(A[i]*A[m] > N){
return productN(A, i, m, N);
} else{
// do something else
}
}
int main(){
int A[]={1, 2, 3, 4, 5};
printf("%d\n", productN(A, 0, 4, 15)); // initial value for i and j are the first and last index of the array
return 0;
}
Apart from that, I'm stuck, I can't even think of a base case, so any help will be greatly appreciated, thanks.
Edit:
Based on your very helpful answers, using binary search, I think I got it:
int productN(int A[], int i, int j, int N){
int m = (i+j)/2; // central element of the current array
int x;
for(x=i; x<=m; x++){
if(N%A[x]==0 && binarySearch(A, m, j, N/A[x]))
return 1;
}
if(i!=j){
if(productN(A, i, m, N) || productN(A, m+1, j, N))
return 1;
}
return 0;
}
Is it good? Can it be better?
Edit: it's been a while now since I asked this question, but I wrote another solution, simplier to read. I'll leave it here in case anyone is interested.
int productN(int A[], int i, int j, int N, int size){
if(i==j){ // base case
if(N%A[i]==0)
return binarySearch(A, 0, size-1, N/A[i]);
else
return 0;
}
int m = (i+j)/2;
if((N%A[m])==0){
if(binarySearch(A, 0, size-1, N/A[i]))
return 1;
}
return productN(A, i, m, N, size) || productN(A, m+1, j, N, size);
}
Using Divide and Conquer, you can use an approach similar to merge sort algorithm. As the comments suggest, there are easier approaches. But if Divide and Conquer is a must, this should suffice.
(I'm not proficient in C, so I'll just write the algorithm)
def productN(arr):
x = len(arr)
left_half = arr[0:x/2]
right_half = arr[x/2:]
if productN(left_half) or productN(right_half):
return True
for i in left_half:
if N%i==0 and binary_search(right_half, N/i):
return True
return False
Question: Given two arrays of integers A[] and B[] of size N and M, the task is to check if a pair of values (one value from each array) exists such that swapping the elements of the pair will make the sum of two arrays equal.
My approach:
find sum of both arrays.
Identify array with larger sum(denote with A[]).
Sort A.
For all values in B binary search (sum(A)-sum(B)/2 + B[i]) in A, if found return true.
Return false.
code:
int sum(int a[], int n){
int s=0;
for(int i=0; i<n; i++){
s+= a[i];
}
return s;
}
int findSwapValues(int A[], int n, int B[], int m)
{
// Your code goes here
int a = sum(A, n);
int b = sum(B,m);
int t;
int *temp;
if(a<b){
temp = A;
A = B;
B = temp;
t = n;
n = m;
m = t;
t = a;
a = b;
b = t;
}
sort(A, A+n);
for(int i=0; i<m; i++){
if(binary_search(A,A+n,(a-b)/2+B[i])){
return 1;
}
}
return -1;
}
Doubt: My algorithm is failing for some test cases(not TLE). As the test cases are very large, it's difficult to reason out the problem in the algorithm. I searched online and understood other approaches. My only curiosity is why its incorrect?
I think the error in your code is that you find B[i] + (a-b)/2.
The problem with this is that if (a-b) is an odd value, division by 2 will round it down to the nearest integer and you end up finding the wrong value.
What you can instead do is check if the difference is odd before even swapping the arrays, and if it is true, straight-away return -1 because if the difference is odd, no such pair can ever exist.
I hope I cleared your doubt :).
I'm stuck trying to implement pseudocode from an algorithm book. My code compiles and prints out the correct answer, except some of the information I want to print out is not displaying correctly. Here's what the console output looks like:
Correct Solution Tested:
max_left= 7
max_right= 10
sum= 43
Failing Outputs:
curr_cross_low = 17; curr_cross_high = -1; curr_cross_sum = 38
curr_cross_low = -1; curr_cross_high = -1; curr_cross_sum = 18
curr_cross_low = 32766; curr_cross_high = -272632720; curr_cross_sum = 43
max_left_full= 32766
max_right_full= -272632512
sum_full= 43
Program ended with exit code: 0
The first three values printed are the correct results arrived by brute implementation of one part of the algorithm. In the code, this is the function "findMaxCrossingSubarray" all by itself. The second part printed out is when I execute the full algorithm "findMaximumSubarray". I believe it should be printing out results that show approaching the solution. The final answer given by the variable "sum_full" appears to be correct since it matches the brute force solution which the book says is the correct answer.
I've been trying to find how I can print the correct max_left_full and max_right_full values and not what I believe is the memory address. I'm at a point where if I change a pointer in one place it makes the solution incorrect or print out a memory address as well.
Is there a simple way to find where I may be dropping the ball?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//returns a pointer to a value equal to the set of changes
int * returnPriceChanges(int sz, int A[]){
int MAX_SIZE = 256;
static int* C;
C = malloc(MAX_SIZE *sizeof(int));
int i;
for(i=0;i<sz-1;i++){
C[i]=A[i+1]-A[i];
}
return C;
}
int findMaxCrossingSubarray(int A[], int low, int mid, int high, int* max_left, int* max_right){
double left_sum = -INFINITY;
int sum = 0;
for(int i=mid;i>=low;i--){
sum=sum+A[i];
if(sum > left_sum){
left_sum = sum;
*max_left = i;
}
}
double right_sum = -INFINITY;
sum = 0;
for(int j=mid+1; j<=high;j++){
sum=sum+A[j];
if(sum > right_sum){
right_sum = sum;
*max_right = j;
}
}
return (*max_left, *max_right, left_sum+right_sum);
}
int findMaximumSubarray(int A[], int low, int high){
int curr_left_low, curr_left_high, curr_left_sum;
int curr_right_low, curr_right_high, curr_right_sum;
int curr_cross_low, curr_cross_high, curr_cross_sum;
int mid = 0;
int* temp_max_left, temp_max_right;
if(high==low){
return(low, high, A[low]);
}
else{
mid =floor((high+low)/2);
curr_left_low, curr_left_high, curr_left_sum = findMaximumSubarray(A, low, mid);
curr_right_low, curr_right_high, curr_right_sum = findMaximumSubarray(A, mid+1,high);
curr_cross_low, curr_cross_high, curr_cross_sum = findMaxCrossingSubarray(A, low, mid, high, &temp_max_left, &temp_max_right);
if(curr_left_sum>=curr_right_sum && curr_left_sum>=curr_cross_sum){
return (curr_left_low, curr_left_high, curr_left_sum);
}
else if(curr_right_sum>= curr_left_sum && curr_right_sum>=curr_cross_sum){
return (curr_right_low, curr_right_high, curr_right_sum);
}
else{
printf("curr_cross_low = %d; curr_cross_high = %d; curr_cross_sum = %d\n", curr_cross_low, curr_cross_high, curr_cross_sum);
return (curr_cross_low, curr_cross_high, curr_cross_sum);
}
}
}
int main(){
int prices[] = {100,113,110,85,105,102,86,63,81,101,94,106,101,79,94,90,97};
int szPrices = sizeof(prices)/sizeof(prices[0]);
int changes[szPrices-1];
int *P;
P = returnPriceChanges(szPrices,prices);
//set C = to list of changes
for(int i=0; i<szPrices-1; i++){
changes[i]=*(P+i);
}
int max_left, max_right, sum;
max_left, &max_right, sum = findMaxCrossingSubarray(changes, 0, 8, 16, &max_left, &max_right);
printf("\nCorrect Solution Tested: \nmax_left= %d \nmax_right= %d \nsum= %d\n\n", max_left, max_right, sum);
printf("\nFailing Outputs:\n");
int max_left_full, max_right_full, sum_full;
max_left_full, &max_right_full, sum_full = findMaximumSubarray(changes, 0, 16);
printf("\nmax_left_full= %d \nmax_right_full= %d\nsum_full= %d\n\n", max_left_full, max_right_full, sum_full);
return 0;
}
You cannot return tuples from functions in C. When you separate values using a comma in C, the whole expression simply evaluates to the last member.
So when you write:
a, b, c = some_function();
It really means:
/* do nothing */, /* do nothing */, c = some_function();
If you want to return a composite data structure, use a struct, i.e.
struct subarray
{
int low;
int high;
int sum;
};
void findMaximumSubarray(int A[], int low, int high, struct subarray * result);
If the struct is small and you are using a modern compiler, and not running on an embedded system, then you can also return the struct by value:
struct subarray findMaximumSubarray(int A[], int low, int high);
The latter syntax simplifies usage, but it can become an issue if you start returning huge structs this way.
I'm having a problem in C when I'm trying to find the largest float of an array, but my largest int works just fine. I think I might be going past the array length but I don't see how it is possible.
int largestInt(int array[], int length){
int max = array[0];
int i;
for( i=1; i<length; i++){
if(array[i] > max){
max = array[i];
}
}
return max;
}
The above code works fine for ints, however if I change it to work with floats as follows,
float largestFloat(float array[], int length){
float max = array[0];
int i;
for( i=1; i<length; i++){
if(array[i] > max){
max = array[i];
}
}
return max;
}
Sometimes it will give me the right answer, and sometimes it will just give me a huge number not even in the original array. Which leads me to believe that I'm going past the length of the array.
float f[15] = {9.5, 45.64, 313.11, 113.89, 81.56, 250.00, 11.9, 469.98, 313.11, 4.68, 34.33, 8013.55, -10.15, 11.5, 88.0} <-- filled with 15 values
largestFloat(f,15);
This is what I would run.
Not seeing an entire example, I'd have to say that you are correct. The array size is probably wrong. First fix the return type:
float largestFloat(float array[], int length){
Next, you might want to add a guard against an empty array, since that will automatically overlflow fetching array[0]:
if (length < 1) return 0;
The rest of largestFloat() is good.
Then call with:
float f[15] = {2.3 ... 102} <-- filled with 15 values
size_t length = sizeof f / sizeof f[0];
float f_max = largestFloat(f, length);
printf("max=%g, length=%d\n", f_max, length);
That will compute (at compile time) the actual size of the array f. Look for cases where the length is not what you thought it should be. This can happen if you type a . instead of a , between values that don't already have a decimal point. That and miscounting are the only ways I know of to get 14 or fewer values from what appears to be 15.
The problem is that you find the largest float but then return the int value
int largestFloat(float array[], int length){ // return type is int
float max = array[0]; // max is float
int i;
for( i=1; i<length; i++){
if(array[i] > max){
max = array[i];
}
}
return max;
}