Hey i am trying to print largest element in an array using function and pointers. Below is my code but its printing garbage value. Please help.
void findmax(int arr[],int,int*);
void findMax(int arr[], int n, int* pToMax)
{
if (n <= 0)
return; // no items, no maximum!
int max = arr[0];
pToMax = &arr[0];
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
max = arr[i];
pToMax = (arr+i);
}
}
}
int main()
{
int nums[4] = { 5, 3, 15, 6 };
int *ptr;
findMax(nums, 4, ptr);
printf("The maximum is at address %u\n", ptr);
printf("It's at index %d\n",ptr - nums);
printf("Its value is %d\n", *ptr);
}
With int *pToMax in findMax(int arr[], int n, int* pToMax) and
calling as findMax(nums, 4, ptr); you just pass ptr as a value.
The updated value won't be reflected after function exits.
You need to use **pToMax
to save address.
void findMax(int arr[], int n, int** pToMax)
{
if (n <= 0)
return; // no items, no maximum!
int max = arr[0];
*pToMax = &arr[0]; //Store base address
for (int i = 1; i < n; i++)
{
if (arr[i] > max)
{
max = arr[i];
*pToMax = (arr+i); //Store max address
}
}
}
call using
findMax(nums, 4, &ptr);
Related
Good day everyone,
my task is to remove all negative numbers from an array, and shorten it (return the new length as the amount of positive numbers). I tried doing that by BubbleSort all negative number to the right, and new length would be (old length - number of swap). My code simply freezes up the system.
I would be grateful if you guys could help.
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a;
int n = length;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array < 0) {
swap(a, array);
a--;
array++;
length--;
}
}
}
printialn(array, n);
return length;
};
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
printiln(remove_negatives(a, l));
return 0;
}
The while loop never stops, that's probably the reason your code freezes.
Your code only changes the address when the if statement is true. Which the array in your main() will stuck on the second (a[1]) element. So if we change change the address when the if statement is false...
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int remove_negatives(int *array, int length) {
int *a, *head;
int n = length;
head = array;
a = &array[n - 1];
for (int i = 0; i <= n - 1; i++) {
while (array < a) {
if (*array >= 0) {
array++;
continue;
}
swap(a, array);
a--;
array++;
length--;
}
}
for (int i=0; i<length; i++) {
printf("%d ", *head);
head++;
}
puts("");
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
remove_negatives(a, l);
return 0;
}
Now the while loop works, buts as #wovano said, the answer is still wrong. Your code isn't exactly a "bubble sort". you swap all the negative number to the end of the array and didn't actually sort the array.
So, let's start from the beginning.
To simplify the process, let bubble sort first, and then find the new array length.
#include<stdio.h>
#include<stdlib.h>
void swap(int *p, int *q) {
int h = *p;
*p = *q;
*q = h;
}
int bubble_sort(int *array, int length) {
int i, j;
// Bubble sort
for (i=0; i<length-1; i++) {
for (j=i+1; j<length; j++) {
if (array[i]<array[j]) swap(&array[i], &array[j]);
}
}
// Find new array length
for (i=length-1; i>=0; i--) {
if (array[i]>=0) break;
length--;
}
return length;
}
int main(void) {
int a[] = {-1, 2, 4, -8, 3, 7, -8, 9, 3};
int l = sizeof(a) / sizeof(a[0]);
l = bubble_sort(a, l);
for (int i=0; i<l; i++) printf("%d ", a[i]);
puts("");
return 0;
}
I'm really new to this. I've never done anything like this so I'm having issues with this code. I was given a template to write my code in separate functions like this, although I added the findPos one myself. I'm getting the "assignment makes integer from pointer without a cast" warning and also my max, min, sum, avg, and position of max and min are obviously not coming out to the right numbers. I was just wondering if anyone can lead me in the right direction.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int findMin(int arr[], int size);
int findMax(int arr[], int size);
int findSum(int arr[], int size);
int findPos(int arr[], int size);
int size;
int i;
int max;
int min;
int avg;
int sum;
int pos;
int main()
{
srand(time(0));
printf("Enter an integer: ");
scanf("%d", &size);
int arr[size];
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
avg = sum / size;
printf("max:%7d\tpos:%d\t\n", max, pos);
printf("min:%7d\tpos:%d\t\n", min, pos);
printf("avg:%7d\n", avg);
printf("sum:%7d\n", sum);
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
return 0;
}
int findMin(int arr[], int size)
{
min = arr[0];
for (i = 0; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
int findMax(int arr[], int size)
{
max = arr[0];
for (i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
int findSum(int arr[], int size)
{
sum = 0;
for (i = 0; i < size; i++) {
sum = sum + arr[i];
}
return sum;
}
int findPos(int arr[], int size)
{
for (i = 0; i < size; i++) {
pos = i;
}
return pos;
}
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
You're assigning function pointer, not return value, to integer variable. You have to do something like max = findMax(arr, size). Also in that case, you should assign values to arr before calling it.
There are a couple of issues with the code. Let me iterate through the same
Populating Data in Created Array
Since the data has to present the created array before performing any operations,
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
this snippet should be reordered and moved above the function calls and just after the int arr[size];
Function Calls
All your functions, namely findMax,findMin,findPos,findSum is expecting two parameters
arr - array you have created
size - the size value read from scanf()
Assuming you want to store the return value from the function in the main int variables max,min,pos,sum,avg
the statements
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
should be replaced with function calls like
max = findMax(arr, size);
min = findMin(arr, size);
pos = findPos(arr, size);
sum = findSum(arr, size);
The Final Main code will be
int main()
{
srand(time(0));
printf("Enter an integer: ");
scanf("%d", &size);
int arr[size];
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
max = findMax(arr, size);
min = findMin(arr, size);
pos = findPos(arr, size);
sum = findSum(arr, size);
avg = sum / size;
printf("max:%7d\tpos:%d\t\n", max, pos);
printf("min:%7d\tpos:%d\t\n", min, pos);
printf("avg:%7d\n", avg);
printf("sum:%7d\n", sum);
return 0;
}
I'm trying to write an effective function that receives an array the size of n and a and b.
The function should search all the numbers in the array such that b-a < array[i] and collect them to a new sorted array called incoming.
For instance, for the input 11,12,8,15,3,12,3,12 , b=15, a=8 the output would be a 6 size array that will contain the values 8,11,12,12,12,15 (anything that is higher than (b)15-(a)8 ).
This is my own code attempt:
#include<stdio.h>
#include<stdlib.h>
int* f5(int arr[], int n, int a, int b, int* p)
{
int i,min,minIndex;
int* incoming = (int*)malloc(*p*sizeof(int));
for ( i = 0; i < n; i++)
{
if (arr[i]>(b - a))
{
incoming[i] = arr[i];
(*p)++;
}
}
return *incoming;
}
void main()
{
int arr[] = { 12,3,12,3,15,8,12,11 };
int p, i;
int incoming[] = f5(arr, sizeof(arr) / sizeof(arr[0]), 8,15, &p);
printf("The size is: %d and the new marahc is: ", p);
for (i = 0; i < p; i++) {
printf("%d", incoming[i]);
}
free(incoming);
}
So I corrected your f5 function because you were not allocating your new array properly, since you were doing the malloc with (*p) before it was set to the number of elements you needed to store. After that, I ordered the incoming array in ascending order as shown in the example output with qsort. I also added the part where you take input values from the user, since in the code you've posted you were probably just trying that specific test case.
#include<stdio.h>
#include<stdlib.h>
// compare function for qsort
int mycompare (const void* a, const void* b) {
int val1 = *(const int*)a;
int val2 = *(const int*)b;
return (val1 - val2);
}
int* f5(int arr[], int n, int a, int b, int* p) {
int target = b - a;
int i;
for (i=0;i<n;i++) { // storing number of values > (a-b)
if (arr[i]>target) (*p)+=1;
}
int* incoming;
if ((incoming= malloc((*p)*sizeof(int)))==NULL); // should always check malloc errors
{
perror("malloc");
exit(EXIT_FAILURE);
}
int j = 0;
i = 0;
while (i<n && j<(*p)) { // storing values in new array
if (arr[i]>target) {
incoming[j] = arr[i];
j++;
}
i++;
}
return incoming;
}
void main() {
int n, a, b, i;
printf("Insert 'a' value: ");
scanf("%d", &a);
printf("Insert 'b' value: ");
scanf("%d", &b);
printf("Insert array size: ");
scanf("%d", &n);
int arr[n];
printf("Insert array values: \n");
for (i=0;i<n;i++) {
scanf("%d", &arr[i]);
}
int size = 0;
int *incoming = f5(arr, n, a, b, &size);
qsort(incoming, size, sizeof(int), mycompare); // sorting array
printf("The size is: %d and the new marahc is: ", size);
for (i=0; i<size;i++) {
printf("%d ", incoming[i]);
}
free(incoming);
}
In f5 you need to determine the required length to allocate. You could either do an initial pass of the arr[] contents to determine the required length, or just set the length to the upper bound n and resize it once the actual length is known.
First approach using an initial pass:
int* f5(int arr[], int n, int a, int b, int* p)
{
int i;
int j;
int* incoming;
j = 0;
for ( i = 0; i < n; i++)
{
if (arr[i]>(b - a))
{
j++;
}
}
incoming = malloc(j*sizeof(int));
if (incoming == NULL)
{
return NULL;
}
j = 0;
for ( i = 0; i < n; i++)
{
if (arr[i]>(b - a))
{
incoming[j++] = arr[i];
}
}
*p = j;
return incoming;
}
Second approach using upper bound for allocated size:
int* f5(int arr[], int n, int a, int b, int* p)
{
int i;
int j;
int* incoming = malloc(n*sizeof(int));
if (incoming == NULL)
{
return NULL;
}
j = 0;
for ( i = 0; i < n; i++)
{
if (arr[i]>(b - a))
{
incoming[j++] = arr[i];
}
}
int* resized_incoming = realloc(incoming, j*sizeof(int));
if (resized_incoming != NULL)
{
incoming = resized_incoming;
}
*p = j;
return incoming;
}
The above have been written to return NULL if malloc returns NULL.
A third approach would be to start with a small amount for incoming and reallocate to a larger amount when necessary.
In main, the variable incoming needs to be changed from an array type to a pointer:
int* incoming = f5(arr, sizeof(arr) / sizeof(arr[0]), 8,15, &p);
Since f5 can now return NULL, the return value should be checked and appropriate action taken:
if (incoming == NULL)
{
fprintf(stderr, "Failed to allocate memory!\n");
exit(EXIT_FAILURE);
}
You also need to add code to sort the filtered numbers.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
void Print_Array(int values[], int length);
void swap(int values[], int i, int j);
void Move_Max(int values[], int max_index);
void Simple_Sort(int values[], int length);
int main() {
How do I use these numbers?
Is SIZE & length one and the same thing?
int my_vals[SIZE] = {83, 89, 94, 73, 11, 33, 25, 34, 73, 41};
Print_Array(my_vals, SIZE); //<- FIRST CALL TO PRINT
Simple_Sort(my_vals, SIZE);
system("PAUSE");
}
void Simple_Sort(int values[], int length) {
int i;
So here length would be 10?
I am starting from the end of my_vals? So would I be starting at 73? Since it's 10-1 = 9? So the 9th would be 73?
for (i = length - 1; i > 0; i--)
{
Move_Max(values, i);
Print_Array(values, SIZE);
}
}
void Move_Max(int values[], int max_index) {
int max, i, maxi;
max = values[0];
maxi = 0;
for (i = 1; i <= max_index; i++)
{
if (max < values[i])
{
max = values[i];
maxi = i;
}
}
swap(values, maxi, max_index);
}
void swap(int values[], int i, int j) {
int temp;
temp = values[i];
values[i] = values[j];
values[j] = temp;
}
void Print_Array(int values[], int length) {
int i;
for ( i = 0; i < length; i++)
printf("%d", values[i]);
printf("\n");
}
When you declare an array, say you have declared int array A[4] so it means that an array A has length of 4 i.e. A[0] to A[3].
In your case, my_vals array is of 10 length i.e. my_vals[0] to my_vals[9]
my_vals[0] = 83
..
..
my_vals[9] = 41
In your for loop you are iterating from last i.e. from my_vals[9] i.e. 41
for (i = length - 1; i > 0; i--)
So the initial value of i will be 9.
But here you need to iterate till i = 0 i.e.
for (i = length - 1; i >= 0; i--)
Is is possible to find the largest sum contiguous sub array using recursion such that the function would directly return the output.
Below is my solution where I store the max subarray ending at each index and then find the largest among those in the print() function. However, I want the following
Use recursion
Use the recursive function to directly output the final result.
My code which uses a recursive function and a helper print() function to find the largest among those numbers
#include <stdio.h>
//int a[] = {-6,60,-10,20};
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int len = sizeof(a)/sizeof(*a);
int maxherearray[10];
int main(void)
{
fun(len-1);
printf("max sub array == %d\n",print(maxherearray));
printf("\n");
return 0;
}
int fun(int n)
{
if(n==0)
return a[n];
maxherearray[n] = max(a[n], a[n]+fun(n-1));
return maxherearray[n];
}
int max(int a, int b)
{
return (a > b)? a : b;
}
EDIT : Posting the print() function which I somehow missed out
//Please make sure that #include <limits.h> is added
int print(int a[])
{
int i = 0;
int largest = INT_MIN;
printf("largest == %d\n",largest);
for(i=0;i<len;i++)
{
if(a[i] > largest)
largest = a[i];
}
return largest;
}
Generally, your algorithm logic is OK. It's like,
f(0) = a(i);
f(i) = max(f(i-1) + a(i), a(i));, get the middle result array
max(0, f(1), f(2), ... , f(n-1)), get the final max_sub result
And you designed a function namedfun for #2, and a helper print() for #3.
Now, (I guess ) what you'd like is to combine #2 and #3 together, i.e., to utilise the middle results of #2 to avoid extra computing/memory space. In terms of your original algorithm logic, here are some possible ways, such as
Add a parameter in your fun to keep max_sub result
int fun(int n, int *result)// add int *result to return max_sub
{
int max_here = 0;
if(n==0){
return a[n];
}
max_here = max(a[n],a[n]+fun(n-1, result));
*result = max(*result, max_here);
return max_here;
}
//...
int main(void)
{
int result = 0;
fun(len-1, &result);
printf("max sub : %d\n", result);
}
Use a global variable (Oh!) to get max_sub in time
int g_maxhere = 0;
int fun2(int n)
{
if(n==0){
return a[n];
}
g_maxhere = max(g_maxhere, max(a[n],a[n]+fun2(n-1)));
return max(a[n], a[n]+fun2(n-1));
}
//...
int main(void)
{
fun2(len-1);
printf("max sub:%d\n",g_maxhere)
}
In fact, your original solution of using a helper function can make your algorithm more clear.
Introduce two global variables, start_idx and end_idx to track the start and end indices of the largest contiguous subarray. Update these variables accordingly in the recursive function.
#include <stdio.h>
/* int a[] = {-6,60,-10,20}; */
int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
int len = sizeof(a)/sizeof(*a);
int maxherearray[10];
int fun(int n);
int max(int a, int b);
int find_max(int a[], int len);
void print_array(int a[], int start_idx, int end_idx);
int start_idx = 0; // Start of contiguous subarray giving max sum
int end_idx = 0; // End of contiguous subarray giving max sum
#define NEG_INF (-100000)
int max_sum = NEG_INF; // The max cont sum seen so far.
int main(void)
{
start_idx = 0;
end_idx = len - 1;
maxherearray[0] = a[0];
printf("Array a[]: ");
print_array(a, 0, len-1);
printf("\n");
// Compute the necessary information to get max contiguous subarray
fun(len - 1);
printf("Max subarray value == %d\n", find_max(maxherearray, len));
printf("\n");
printf("Contiguous sums: ");
print_array(maxherearray, 0, len - 1);
printf("\n");
printf("Contiguous subarray giving max sum: ");
print_array(a, start_idx, end_idx);
printf("\n\n");
return 0;
}
int fun(int n)
{
if(n==0)
return a[0];
int max_till_j = fun(n - 1);
// Start of new contiguous sum
if (a[n] > a[n] + max_till_j)
{
maxherearray[n] = a[n];
if (maxherearray[n] > max_sum)
{
start_idx = end_idx = n;
max_sum = maxherearray[n];
}
}
// Add to current contiguous sum
else
{
maxherearray[n] = a[n] + max_till_j;
if (maxherearray[n] > max_sum)
{
end_idx = n;
max_sum = maxherearray[n];
}
}
return maxherearray[n];
}
int max(int a, int b)
{
return (a > b)? a : b;
}
// Print subarray a[i] to a[j], inclusive of end points.
void print_array(int a[], int i, int j)
{
for (; i <= j; ++i) {
printf("%d ", a[i]);
}
}
int find_max(int a[], int len)
{
int i;
int max_val = NEG_INF;
for (i = 0; i < len; ++i)
{
if (a[i] > max_val)
{
max_val = a[i];
}
}
return max_val;
}