Optimize code-Maximum Element in an Array using functions - c++

i'm new to posting questions here but have been looking for answers for a long time. I've created this code to return the maximum element in the array x[]. I did get results but not all the test cases are passed. I have checked it multiple times, but got no clue ion what is to be done to correct it.
I'm doing this on part of my online training so the test case values aren't openly visible. This code generated 85.71% positive outcome. Please help me do 100%. Thank you.
The question is to create a function findMax(int n,int *a) to return the maximum element. WHERE
The first argument corresponds to the number of elements in the array.
The second argument corresponds to the pointer to an array.
#include<stdio.h>
int findMax(int n,int *a)
{
int i,max=a[0]=0;
for(i=1;i<=n;i++)
{
if(a[i]>max)
max=a[i];
}
return(max);
}
int main()
{
int i,x[16],k,max;
printf("Enter the number of elements in the array\n");
scanf("%d",&k);
printf("Enter the elements in the array\n");
for(i=1;i<=k;i++)
{
scanf("%d",&x[i]);
}
max=findMax(k,x);
printf("The maximum element in the array is %d",max);
return 0;
}
I'm a beginner in coding, so a simpler explanation might help. Thanks again

max=a[0]=0;
This sets both a[0] and max to 0.
The loop in main() populates the array starting with index 1. Setting a[0] to 0 here accomplishes absolutely nothing. That, in itself, is not a problem, but setting max to 0 is. This is because if all elements in the array that main() initializes are negative, then because max is initially set to 0, the returned maximum value will be 0 instead of the highest negative value in the array.
You should make the following changes.
1) Instead of populating x[1] through x[k], the loop in main() should populate x[0] through x[k-1]. Arrays in C and C++ are, traditionally, 0-based.
2) The loop in your function should be adjusted accordingly as well, and it should not set a[0] to 0, of course. It should simply set max=a[0].

#include<stdio.h>
int findMax(int i,int *a)
{
max=a[0]; // you were setting a[0] to zero
for(i=1;i<n;i++) // there are n numbers beginning from position 0
{
if(a[i]>max)
max=a[i];
}
return(max);
}
int main()
{
int i,x[16],k,max;
printf("Enter the number of elements in the array\n");
scanf("%d",&k);
printf("Enter the elements in the array\n");
for(i=0;i<k;i++)
{
scanf("%d",&x[i]);
}
max=findMax(k,x);
printf("The maximum element in the array is %d",max);
return 0;
}

In your code, you have set max=0. Consider the test case when all the numbers are negative, then your code will return 0 which is not correct.
Correct Approach:
Assign max to first element of array and check the condition for remaining elements.
If first element is maximum then it will be returned otherwise the updated maximum is returned (after being checked through loop).

Related

time complexity of (A[i]^x)>(A[i]&x)

'Is it possible to further optimize the time complexity this piece of calculation "(y^x)>(y&x)" in c++?(you are allowed to change the Boolean operation into other forms, for example this can also be written as log2(y)!=log2(x) and this gives the same Boolean output but this has a higher time complexity with c++ compiler)'enter code here
#include <bits/stdc++.h>
using namespace std;
int main() {
// your code goes here
int t;cin>>t;
while(t--){
int n;cin>>n;int A[n];
for(int i=0;i<n;i++){cin>>A[i];}
int q;cin>>q;
while(q--){
int l,r,x;
cin>>l>>r>>x;int count=0;
for(int i=l-1;i<r;i++){
if((A[i]^x)>(A[i]&x)){count++;}
}
cout<<count<<endl;
}
}
return 0;
}
'This is the code im trying to optimize.... Please help in any way possible (number of inputs cant be changed)'
(y^x)>(y&x) is equivalent to nlz(y) != nlz(x) where nlz is a function that returns the number of leading zeroes of its input.
Therefore in order to count how often (A[i]^x)>(A[i]&x) is true for items in the array A, we could make a small array N where N[j] is the number of elements with nlz(A[i]) == j in array A. Then the number of times that (A[i]^x)>(A[i]&x) is true is equivalent to n - N[nlz(x)].
That way there is no loop over A where it really matters. Creating the array N still requires a loop over A, but only once for each iteration of the outer loop, not for each individual x.
C++20 has the nlz function built in under the name std::countl_zero.

Can' t print position of element in an array after heapify-up C++

Can someone help me with the code in c++ below?
#include <iostream>
#include <fstream>
using namespace std;
int PARENT(int i)
{
return (i/2);
}
int Heapify_up(int arra[], int i)
{
int j,k;
if (i>1){
j = PARENT(i);
if (arra[i]<arra[j]){
k=arra[i];
arra[i]=arra[j];
arra[j]=k;
Heapify_up(arra, j);
}
}
return j;
}
int main()
{
int array3[15];
int i,p,array_length;
ifstream inputFile1("Heapfile.txt");
if (inputFile1.good()){
int current_number = 0;
i=1;
while (inputFile1>> current_number)
array3[i++] = current_number;
inputFile1.close();
}
array_length = i;
cout<<"Please, enter an integer: ";
cin>>p;
array3[array_length+1]=p;
int pos=Heapify_up(array3, array_length+1);
for (i=1; i<15; i++){
cout<<array3[i]<<" ";
}
cout<<"The position is "<<pos;
}
Let me explain you that have an array in a txt file. After i insert a random integer and with the heapify-up algorith I'm sorting this random number to the array. I want to print the new sorted array(I' have done that) and the new position of the random element that i have entered. Any idea?
thanks in advance!
P.S. I am new here and i find it somehow difficult to post my code correctly... still learning! XD
Okay, there are multiple problems with your code.
You make no effort to ensure you don't blow past the size of your
static array.
You skip a spot in the array when appending your manually-added
value
Your array length is wrong
You aren't initializing your variables
Let's start with the last one. Please do something like this:
int i{0}, p, array_length;
This ensures the i variable is properly initialized to zero.
Next, your code does this:
array3[i++] = current_number;
This means that at any given time, i is the length of the array.
But later you do this:
array_length = i;
array3[array_length+1]=p;
Frankly, I would drop variable i entirely and use array_length instead. There is no need for both.
But even without that, you're setting array_length correctly, but then you're inserting to a point AFTER that, so you might start with:
[ 1, 2, 3, 4, 5 ]
At this point, i == 5. Input a 6 and have:
[ 1, 2, 3, 4, 5, 0, 6 ]
Because you put it at index i+1 not at index i.
At this point, array_length is no longer an accurate length. But you do this:
int pos=Heapify_up(array3, array_length+1);
So it kind of works.
I don't know why Heapify_up is returning j -- it's just the midpoint of the array. That's not a useful value.
Furthermore, I don't really know what your heapify thing is trying to accomplish.. It certainly isn't a heap-sort. If the middle and end numbers are in sorted order, it doesn't actually do a thing.
This URL might help you with some code:
Heap sort at Geeks for Geeks
As for using a fix-length array -- that's problematic, too, but using std::vector is probably a bit much for you. I'd make sure that your input loop doesn't run into issues or start with a much longer beginning array.

Is there a way to find the INDEX of the minimum value in an array using a recursive function? C++

I need to find the Index of the minimum number in an array using a recursive function in c++ the function can only get 2 parameters: the pointer to the array and the size of it.
int smallest(int arr[], int num);
I managed to do this but with a helper variable that is static and declared outside the function here is what I got:
static int flag = 0;
int smallest(int* arr, int num) {
if (flag == num - 1)
return flag;
if (arr[num - 1] > arr[flag]) {
return smallest(arr, num - 1);
} else {
flag++;
return smallest(arr, num);
}
}
Now my question is can I do this without the static variable or any other variable other than the num? here is what I got so far:
int smallest(int arr[], int num) {
if (arr != &arr[num - 1])
if (*arr < arr[num - 1])
smallest(arr, num - 1);
else
smallest(arr + 1, num);
return num - 1;
}
It doesn't return the index of the minimum value but it does get to its adress, the function ends when the array pointer address is the same as the address of the minimum value. how can I get it to return the index?
I'm a student and I'm pretty new to C++ I appreciate the help! thanks!
===
edit:
this is originally from a homework assignment but the constraint to not use external help variables or functions is mine! and I'm curious to know if its even possible.
Because this is obviously homework, I'm not going to reveal the ACTUAL answer in entirety, but I'll give some (hopefully) good advice.
With recursion, think first of what your end condition is. That should be an array of 1 element. You return the index 0 in that case because of the array you have, it's the only element, so return the index of it.
if(num == 1)
{
return 0;
}
So then how is that useful to you? Compare it to exactly one other element. That's how you break this down. Your array turns into "one element and MANY" or "It's just one element." If it's just one, return the only value. If it's many, call yourself recursively from the second element (index 1) onward:
int restOfArraySmallest = smallest(arr+1, num-1) + 1;
You need the +1 because you've offset where it starts from. But you know the value in restOfArraySmallest is the index into YOUR arr of the smallest value of everything except the first element. Because your recursive calls don't include the first element, just the rest.
Hopefully that's enough to get you the rest of the way.
Edit: Because the OP has responded and said it wasn't essential to their homework assignment, here's the entire function:
// Recursively finds the index of the smallest element of the passed-in array
int smallest(int* arr, int num)
{
if(num <= 1)
{
return 0; // If we're in the last element, the smallest is the only element
}
// More than one element, so find the least element in all the elements
// past the first element of the array
// Note: the index returned is offset from our current view of the array,
// so add +1 to any returned result so we can index directly from it
int restOfArraySmallest = smallest(arr+1, num-1) + 1;
// Compare the first element in the array to the smallest of the entire rest
// of the array:
if(arr[0] < arr[restOfArraySmallest])
{
// The first element is smaller, it's the smallest, so return that index
return 0;
}
else
{
// The element already found is smaller, so return that index. It's already
// correctly offset
return restOfArraySmallest;
}
}
And that's it. If there's duplicate entries for smallest, it will favor the LAST one.
The trick with recursion is to NOT keep external variables. What you pass as the arguments and RETURN BACK are all the information you have. For some algorithms, it's enough.
Note, if you use recursive functions with datasets big enough, you will eventually get a Stack Overflow. Not the website, the crash type. This algorithm is pretty light in that only one extra variable and the two arguments themselves get allocated each pass, but it adds up eventually.

Adding/Removing Elements in an Array Inside a Function Using Pointers

I am trying to figure this problem out. This is for a project and our instructor requires this header. I got the check function working properly but adding when adding to the array we must use a pointer. My understanding is that we should copy this array to another array and replace the pointer. For example Array1 {1,2,3} then copy it to Array2 {1,2,3,4} then add 4 to expand the array. Unfortunately everything I have found researching.. vectors and other functions would be better suited for this task but we are required to only use the pointer and the size to resize and add the element.
// returns the index of the element in "arrayPtr" of "size"
// that corresponds to the element holding "number"
// if number is not in the array, returns -1
int check(int *arrayPtr, int number, int size);
// adds "number" to the array pointed to by "arrayPtr" of "size".
// if the number is not already there, if "number" is there - no action
// Note, the size of the array is thus increased.
void addNumber(int *& arrayPtr, int number, int &size);
// removes a "number" from the "arrayPtr" of "size".
// if "number" is not there -- no action
// note, "size" changes
void removeNumber(int *& arrayPtr, int number, int &size);
I have this so far:
// returns the index of the element in "arrayPtr" of "size"
// that corresponds to the element holding "number"
// if number is not in the array, returns -1
int check(int *arrayPtr, int number, int size) {
for (int i = 0; i < size; i++) {
if (arrayPtr[i] == number) {
return i;
}
}
return -1;
}
// adds "number" to the array pointed to by "arrayPtr" of "size".
// if the number is not already there, if "number" is there - no action
// Note, the size of the array is thus increased.
void addNumber(int *& arrayPtr, int number, int &size) {
if (check(arrayPtr, number, size)==-1) {
//add the element to the end of the array
}
//did not run if -1
}
// removes a "number" from the "arrayPtr" of "size".
// if "number" is not there -- no action
// note, "size" changes
void removeNumber(int *& arrayPtr, int number, int &size) {
}
Any hints or tips or suggestions on how to proceed would be appreciated!
To be more clear what you are trying to build is an Set like data structure (because you are avoiding duplicates).
Another thing from you code is you have big chunck of memory allocated for this purpose and you are just access it with the arrayPtr and size.
If this is the case You might be maintaining a MAX_MEMORY_SIZE.
something like
#define MAX_MEMORY_SIZE 1000000
Have this assumption,
Algorithm for addNumber:
If size+1 >= MAX_MEMORY_SIZE return an 'overflow or max memory' exception
Check for existence of new element
If found, do nothing and simply return
If not found, copy the new element # arrayPtr[size] (arrayPtr[size] = number). (You may choose to keep them in some order so that your search can be effective as well. For that your check function and implementation has to be different)
Increase the size
Algorithm for removeNumber:
Check for existence of given element
If not found, do nothing and simply return
If found, loop the all the elements array and shift 1 position left. A code like below.
Decrease the size
Hope this will take you to next level.
position = check(arrayPtr, number, size);
for (i = position; i < size-1; i++) {
arrayPtr[i] = arrayPtr[i+1];
}

C++ program to compute lcm of numbers between 1 to 20 (project euler )

as the title explains this is a program to find lcm of numbers between 1 to 20. i found an algorithm to do this, here's the link
http://www.cut-the-knot.org/Curriculum/Arithmetic/LCM.shtml
there is a java applet on the webpage that might explain the algorithm better
Problem: i wrote the code compiler shows no error but when i run the code the program goes berserk, i guess may be some infinite loopig but i can't figure it out for the life of me. i use turbo c++ 4.5 so basically if anyone can look at the code and help me out it would be great . thanks in advance
Algorithm:
say we need to find lcm of 2,6,8
first we find the least of the series and add to it the number above it, i.e the series become
4,6,8
now we find the least value again and add to it the intitial value in the column i.e 2
6,6,8
so the next iteration becomes
8,6,8
8,12,8
10,12,8
10,12,16
12,12,16
14,12,16
14,18,16
16,18,16
18,18,16
18,18,24
20,18,24
20,24,24
22,24,24
24,24,24
as you can see at one point all numbers become equal which is our lcm
#include<iostream.h>
/*function to check if all the elements of an array are equal*/
int equl(int a[20], int n)
{
int i=0;
while(n==1&&i<20)
{
if (a[i]==a[i+1])
n=1;
else
n=0;
i++;
}
return n;
}
/*function to calculate lcm and return that value to main function*/
int lcm()
{
int i,k,j,check=1,a[20],b[20];
/*loading both arrays with numbers from 1 to 20*/
for(i=0;i<20;i++)
{
a[i]=i+1;
b[i]=i+1;
}
check= equl(a,1);
/*actual implementation of the algorith*/
while(check==0)
{
k=a[0]; /*looks for the least value in the array*/
for(i=0;i<20;i++)
{
if(a[i+1]<k)
{
k=a[i+1]; /*find the least value*/
j=i+1; /*mark the position in array */
}
else
continue;
}
a[j]=k+b[j]; /*adding the least value with its corresponding number*/
check= equl(a,1);
}
return (a[0]);
/*at this point all numbers in the array must be same thus any value gives us the lcm*/
}
void main()
{
int l;
l=lcm();
cout<<l;
}
In this line:
a[j]=k+b[j];
You use j but it is unitialized so it's some huge value and you are outside of the array bounds and thus you get a segmentation fault.
You also have some weird things going on in your code. void main() and you use cout without either saying std::cout or using namespace std; or something similar. An odd practice.
Also don't you think you should pass the arrays as arguments if you're going to make lcm() a function? That is int lcm(int a[], int b[]);.
You might look into using a debugger also and improving your coding practices. I found this error within 30 seconds of pasting your code into the compiler with the help of the debugger.
Your loop condition is:
while(n==1&&i<20)
So your equl function will never return 1 because if n happens to be 1 then the loop will just keep going and never return a 1.
However, your program still does not appear to return the correct result. You can split the piece of your code that finds the minimum element and replace it with this for cleanliness:
int least(int a[], int size){
int minPos = 0;
for(int i=0; i<size ;i++){
if (a[i] < a[minPos] ){
minPos = i;
}
}
return minPos;
}
Then you can call it by saying j = least(a, 20);. I will leave further work on your program to you. Consider calling your variables something meaningful instead of i,j,k,a,b.
Your equl function is using array indices from 0-20, but the arrays only have 1-19
j in lcm() is uninitialized if the first element is the smallest. It should be set to 0 at the top of the while loop
In the following code, when i=19, you are accessing a[20], which is out of the bounds of the array. Should be for(i=0;i<19;i++)
for(i=0;i<20;i++) {
if(a[i+1]<k)
You are not actually using the std namespace for the cout. this should be std::cout<<l
Your are including iostream.h. The standard is iostream without the .h, this may not work on such an old compiler tho
instead of hard-coding 20 everywhere, you should use a #define. This is not an error, just a style thing.
The following code does nothing. This is the default behavior
else
continue;