Related
Question -
N numbers are entered by the user (N is also given by the user). Store the numbers in
an array. Write a C function which deletes all the second largest elements and
rearranges the array. The program should appropriately print the new array and the
value of N. For e.g if N=7 and the elements are 7 11 13 11 8 7 4 the output should be
N=5 and the array is 7 13 8 7 4
My Code -
#include<stdio.h>
int secondLargest(int arr[], int n);
int indexOfSecondLargest(int arr[], int n, int max2);
void deleteElement(int arr[], int n, int index);
void deleteSecondLargest(int arr[], int n);
void printArray(int arr[], int n);
int main()
{
static int n;
printf("Enter value of n \n");
scanf("%d", &n);
int arr[100];
printf("Enter n numbers \n");
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
deleteSecondLargest(arr, n);
printf("New value of n = %d and the array is \n", n);
printArray(arr, n);
return 0;
}
int secondLargest(int arr[], int n)
{
int max1 = arr[0], max2 = arr[0];
for (int i = 0; i < n; i++)
{
if (arr[i] > max1)
{
max2 = max1;
max1 = arr[i];
}
if (arr[i] > max2 && arr[i] < max1)
{
max2 = arr[i];
}
}
return max2;
}
int indexOfSecondLargest(int arr[], int n, int max2)
{
for (int i = 0; i < n; i++)
{
if (arr[i] == max2)
{
return i;
}
}
return -1;
}
void deleteElement(int arr[], int n, int index)
{
for (int i = index; i < n - 1; i++)
{
arr[i] = arr[i+1];
}
n = n - 1;
}
void deleteSecondLargest(int arr[], int n)
{
int max2 = secondLargest(arr, n);
int index = indexOfSecondLargest(arr, n, max2);
while (index != -1)
{
deleteElement(arr, n, index);
index = indexOfSecondLargest(arr, n, max2);
}
}
void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
}
My Output -
Enter value of n
7
Enter n numbers
7 11 13 11 8 7 4
New value of n = 7 and the array is
7 13 8 7 4 4 4
Even though I am using static keyword before int n, the value of n is not getting updated to 5 in main() function. I even tried putting int n as a global variable but still it doesn't work.
Can someone help me ??
Adding static to int n; says “This n persists through all of program execution.” it does not say “This n is the only n in the whole program.” Where a parameter n is declared, as in void deleteElement(int arr[], int n, int index), that creates an n different from the n in main.
However, even if no parameter is declared with the name n, an n declared inside main is not visible in any other function. To use the same n throughout the program, you need to declare int n; or static int n; outside of any function, anywhere before the first function that uses n, and you need to not declare any other n.
That would likely solve this problem for you. However, it is bad practice to use external identifiers for objects. Instead, you should use int n; in main and modify deleteElement so that it provides main with the updated value. It could do this by returning an int instead of void, or you could modify deleteElement to take a pointer to an int instead of taking an int, by making the parameter int *n. Then you would have to use it inside the function as *n instead of n.
I am trying to write a recursive function in C,
Given an array, size of the array as well as the element int target, I want to find the index of int target's last occurence.
#include <stdio.h>
int rLookupAr(int array[], int size, int target);
int main()
{
int numArray[80];
int target, i, size;
printf("Enter array size: \n");
scanf("%d", &size);
printf("Enter %d numbers: \n", size);
for (i=0; i < size; i++)
scanf("%d", &numArray[i]);
printf("Enter the target number: \n");
scanf("%d", &target);
printf("rLookupAr(): %d", rLookupAr(numArray, size, target));
return 0;
}
int rLookupAr(int array[], int size, int target)
{
}
However, I have been stuck for hours.
I am a beginner to recursive functions and any help will be greatly appreciated!
Some examples:
Enter array size:
5
Enter 5 numbers:
2 1 3 2 4
Enter the target number:
2
rLookupAr(): 3
If you're after the last occurrence, then you can start your search at the end of the array and work backwards.
C arrays are referenced by a pointer to any element and a length or index upper-bound value, which you have.
One way of looking at recursive functions is asking "is each step of the algorithm just repeating the whole thing, just on a decreasing subset of the input data?" - consider problems like processing trees (where each child node is a tree itself) or operations like quicksort (where each pivot gives you two more sub-sections which you pivot again, and so on).
Consider that finding a value in an array of [0...N] is the same as finding the value by checking [0] and then checking [1...N], then repeating yourself all over again by checking [1] and then checking [2..N]...hopefully you're seeing a pattern emerging.
For working backwards, given the array's start and length N, you'd check [N] first, then repeat with the range [0..(N-1)], then check [N-1] then repeat with [0...(N-2)].
I hope that will enable you to come to a solution without me just giving you the answer.
You can define rLookupAr() function as following. See the complete working code here:
int rLookupAr(int array[], int size, int target)
{
if(size < 1) return -1;
size--;
if(array[size] == target) return size;
return rLookupAr(array, size,target);
}
Note: rLookupAr() function will return -1 if target value is not found in array array.
OUTPUT:
Enter array size: 5
Enter 5 numbers: 2 1 3 2 4
Enter the target number: 2
rLookupAr(): 3
Following is the complete code:
#include <stdio.h>
int rLookupAr(int array[], int size, int target);
int main()
{
int numArray[80];
int target, i, size;
printf("Enter array size: \n");
scanf("%d", &size);
printf("Enter %d numbers: \n", size);
for (i=0; i < size; i++)
scanf("%d", &numArray[i]);
printf("Enter the target number: \n");
scanf("%d", &target);
printf("rLookupAr(): %d", rLookupAr(numArray, size, target));
return 0;
}
int rLookupAr(int array[], int size, int target)
{
if(size < 1) return -1;
size--;
if(array[size] == target) return size;
return rLookupAr(array, size,target);
}
Please find the recursive function below:
int rLookupAr (int array[], int size, int target)
{
if(size<=0) return -1;
if(array[size-1] == target)
return size-1;
else
return rLookupAr (array, size-1, target); //recurse
}
basically the functions starts from the end because the last occurance is being sought. Depending on whether the target is found or not it further recurses down the array.
Complete code:
#include <stdio.h>
int rLookupAr (int array[], int size, int target);
int
main ()
{
int numArray[80];
int target, i, size;
printf ("Enter array size: \n");
scanf ("%d", &size);
printf ("Enter %d numbers: \n", size);
for (i = 0; i < size; i++)
scanf ("%d", &numArray[i]);
printf ("Enter the target number: \n");
scanf ("%d", &target);
printf ("rLookupAr(): %d", rLookupAr (numArray, size, target));
return 0;
}
int
rLookupAr (int array[], int size, int target)
{
if(size<=0) return -1;
if(array[size-1] == target)
return size-1;
else
return rLookupAr (array, size-1, target); //recurse
}
Output:
Enter array size:
5
Enter 5 numbers:
2
1
3
2
4
Enter the target number:
2
rLookupAr(): 3
Here is a solution with a single statement:
int rLookupAr(int array[], int size, int target) {
return size-- <= 0 ? -1 : array[size] == target ? size : rLookup(array, size, target);
}
Using a recursive solution for a simple case like this is only meant as an exercise. C compilers are not required to perform tail recursion optimization to convert this code to a loop, so this recursive implementation can easily cause a stack overflow for a moderately large array.
I am a beginner to recursive functions
Recursive functions get a bad name with linear reduction.
Instead break the problem in 2 to achieve a a recursive depth of log2(n).
int rLookupAr(int array[], int size, int target) {
if (size < 1) {
return -1;
}
int mid = size/2;
int right = rLookupAr(array + mid, size - mid, target);
if (right != -1) {
return right + mid;
}
int left = rLookupAr(array, mid, target);
return left;
}
int rLookupAr(int input[], int size, int x) {
/* Don't write main().
Don't read input, it is passed as function argument.
Return output and don't print it.
Taking input and printing output is handled automatically.
*/
if(size==0)
{
return -1;
}
//return -1;
int ans=lastIndex(input+1,size-1,x);
if(ans!=-1)
{
return ans+1;
}
else{
if(input[0]==x)
{
return ans+1;
}
else
{
return -1;
}
}
}
int lastIndex(int input[], int size, int x)
{
if (size == 0)
{
return -1;
}
int answer = lastIndex(input + 1, size - 1, x);
if (answer != -1)
{
return answer + 1;
}
if (input[0] == x)
{
return 0;
}
else
{
return -1;
}
}
int main()
{
int input[] = {9, 8, 10, 8};
int x = 8;
int size = 4;
cout << lastIndex(input, size, x);
return 0;
}
I am fairly new around here and this year is the first time I am learning c. I have run into a problem concerning 2D arrays and such. The question is: Write a program that finds the sum of two 2D matrixes.
I can do this fairly easily but there is a problem I'm running into. For example I'll give the first set of arrays a length of 3x3.
If my first 2D array and the second array has:
{1,2,3; 4,5,6; 7,8,9} (1st array)
{0,0,0; 0,0,0; 0,0,0} (2nd array)
I am also given a the number of rows and columns by user. (User inputs 3x2) then it should appear like
{1,2; 3,4; 5,6} (OUTPUT)
but I am getting
{1,2; 3,5; 6,8}
Another example
User inputs 2x4 OUTPUT should be {1,2,3,4; 5,6,7,8}
What am I doing wrong here?
#include <stdio.h>
#include <stdlib.h>
#define MAXROW 3
#define MAXCOL 3
int main() {
int ray1[MAXROW][MAXCOL], ray2[MAXROW][MAXCOL];
int r, c;
printf("Enter the number of ROWS: ");
scanf("%d", &r);
printf("Enter the number of COLUMNS: ");
scanf("%d", &c);
int sumRay[r][c];
printf("\n");
printf("Input integers for Array %d.\n", 1);
arrayIN(ray1);
printRay(ray1);
printf("Input integers for Array %d.\n", 2);
arrayIN(ray2);
printRay(ray2);
arraySUM(ray1, ray2, r, c, sumRay);
printSumRay(r, c, sumRay);
//printRay(sumRay);
}
void arrayIN(int ray[MAXROW][MAXCOL]) {
int r, c;
for (r = 0; r < MAXROW; r++) {
for (c = 0; c < MAXCOL; c++) {
printf("Enter Number for [ROW:%d COL:%d]: ", r, c);
scanf("%d", &ray[r][c]);
}
}
}
void arraySUM(int ray1[MAXROW][MAXCOL], int ray2[MAXROW][MAXCOL],
int r, int c, int sumRay[r][c]) {
int i, j;
int x, y;
i = j = 0;
int sum;
for (x = 0; x <= r; x++, i++) {
if (i < MAXROW) {
for (y = 0; y <= c; y++, j++) {
if (j < MAXCOL) {
sum = ray1[i][j] + ray2[i][j];
sumRay[x][y]= sum;
} else {
j = 0;
}
}
} else {
i = 0;
}
}
printf("\n");
}
void printSumRay(int r, int c, int sumRay[r][c]) {
int i, j;
for (i = 0; i < r; i++) {
printf("\n");
for (j = 0; j < c; j++) {
printf("%d\t", sumRay[i][j]);
}
}
}
void printRay(int ray[MAXROW][MAXCOL]) {
int i, j;
for (i = 0; i < 3; i++) {
printf("\n");
for (j = 0; j < 3; j++) {
printf("%d\t", ray[i][j]);
}
}
printf("\n");
}
First off, you need to put function prototypes before main(), or at least move the function definitions before main(). It is not at all clear to me why you use a VLA for sumRay[][], but arrays of constant dimensions for ray1[][] and ray2[][]. Unless you have a compelling reason for doing so, it will be better to use VLA's all around.
You should be using the size_t type for variables that hold array indices. The scanf() and printf() statements that handle the size_t variables must then be modified to use the %zu conversion specifier.
The arraySum() function iterates over two pairs of duplicate array indices for reasons which are unclear. The logic here is convoluted and overly complex. The spurious output that you reported can be traced to this function; it is difficult to read and understand, which should be a sign that it needs to be rewritten. And if your intention is to add the input arrays only partially, the name does not reflect this intention. I have simplified this function, tightening the logic and removing the duplications. See the update below for a version that does partial array addition.
The printSumRay() function seems superfluous, since the printRay() function can do the same work, so I removed it, rewriting printRay() to use VLA's and tightening the code. The original code was using the magic number 3 in the controlling expressions of the loops here, instead of taking advantage of MAXROW and MAXCOL. But, even when not using VLA's, it is better practice to pass the dimensions to any function that will work with an array.
Here is a modified version of the original code:
#include <stdio.h>
#include <stdlib.h>
void arrayIN(size_t r, size_t c, int ray[r][c]);
void arraySUM(size_t r, size_t c, int ray1[r][c], int ray2[r][c], int sumRay[r][c]);
void printRay(size_t r, size_t c, int ray[r][c]);
int main(void)
{
size_t r,c;
printf("Enter the number of ROWS: ");
scanf("%zu", &r);
printf("Enter the number of COLUMNS: ");
scanf("%zu", &c);
int ray1[r][c], ray2[r][c], sumRay[r][c];
printf("\n");
printf("Input integers for Array %d.\n", 1);
arrayIN(r, c, ray1);
putchar('\n');
printRay(r, c, ray1);
putchar('\n');
printf("Input integers for Array %d.\n", 2);
arrayIN(r, c, ray2);
putchar('\n');
printRay(r, c, ray2);
putchar('\n');
arraySUM(r, c, ray1, ray2, sumRay);
printRay(r, c, sumRay);
putchar('\n');
return 0;
}
void arrayIN(size_t r, size_t c, int ray[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
printf("Enter Number for [ROW:%zu COL:%zu]: ", i, j);
scanf("%d", &ray[i][j]);
}
}
}
void arraySUM(size_t r, size_t c, int ray1[r][c],int ray2[r][c], int sumRay[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
sumRay[i][j] = ray1[i][j] + ray2[i][j];
}
}
}
void printRay(size_t r, size_t c, int ray[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
printf("%8d",ray[i][j]);
}
putchar('\n');
}
}
As a next step, you might add some error-checking to the input code, checking the return values from the calls to scanf(). And, as it is, it is awkward to enter the numbers for the arrays, being prompted for each element. You might experiment with ways to improve this.
Update
If your true goal is to combine only the initial rows and columns of your arrays, the above code works with only minor modification. You should still use VLAs, but instead of defining the global constants MAXROW and MAXCOL, define const size_t maxrow and const size_t maxcol within the body of main(). You should be passing these array dimensions to the functions anyway, not relying on global values.
A function has been added, partArraySUM(), with a name that more closely captures its purpose. The only difference between this function and arraySUM() is that the input arrays ray1[][] and ray2[][] have different dimensions than the array sumRay[][] which holds the results. There is no need to keep separate indices for this.
#include <stdio.h>
#include <stdlib.h>
void arrayIN(size_t r, size_t c, int ray[r][c]);
void arraySUM(size_t r, size_t c, int ray1[r][c], int ray2[r][c], int sumRay[r][c]);
void partArraySUM(size_t r_sz, size_t c_sz, int ray1[r_sz][c_sz], int ray2[r_sz][c_sz], size_t r, size_t c, int sumRay[r][c]);
void printRay(size_t r, size_t c, int ray[r][c]);
int main(void)
{
const size_t maxrow = 3;
const size_t maxcol = 3;
size_t r,c;
printf("Enter the number of ROWS: ");
scanf("%zu", &r);
printf("Enter the number of COLUMNS: ");
scanf("%zu", &c);
int ray1[maxrow][maxcol], ray2[maxrow][maxcol], sumRay[r][c];
printf("\n");
printf("Input integers for Array %d.\n", 1);
arrayIN(maxrow, maxcol, ray1);
putchar('\n');
printRay(maxrow, maxcol, ray1);
putchar('\n');
printf("Input integers for Array %d.\n", 2);
arrayIN(maxrow, maxcol, ray2);
putchar('\n');
printRay(maxrow, maxcol, ray2);
putchar('\n');
partArraySUM(maxrow, maxcol, ray1, ray2, r, c, sumRay);
printRay(r, c, sumRay);
putchar('\n');
return 0;
}
void arrayIN(size_t r, size_t c, int ray[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
printf("Enter Number for [ROW:%zu COL:%zu]: ", i, j);
scanf("%d", &ray[i][j]);
}
}
}
void arraySUM(size_t r, size_t c, int ray1[r][c],int ray2[r][c], int sumRay[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
sumRay[i][j] = ray1[i][j] + ray2[i][j];
}
}
}
void partArraySUM(size_t r_sz, size_t c_sz, int ray1[r_sz][c_sz], int ray2[r_sz][c_sz], size_t r, size_t c, int sumRay[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
sumRay[i][j] = ray1[i][j] + ray2[i][j];
}
}
}
void printRay(size_t r, size_t c, int ray[r][c])
{
for(size_t i = 0; i < r; i++) {
for(size_t j = 0; j < c; j++) {
printf("%8d",ray[i][j]);
}
putchar('\n');
}
}
Sample interaction:
Enter the number of ROWS: 2
Enter the number of COLUMNS: 2
Input integers for Array 1.
Enter Number for [ROW:0 COL:0]: 1
Enter Number for [ROW:0 COL:1]: 2
Enter Number for [ROW:0 COL:2]: 3
Enter Number for [ROW:1 COL:0]: 4
Enter Number for [ROW:1 COL:1]: 5
Enter Number for [ROW:1 COL:2]: 6
Enter Number for [ROW:2 COL:0]: 7
Enter Number for [ROW:2 COL:1]: 8
Enter Number for [ROW:2 COL:2]: 9
1 2 3
4 5 6
7 8 9
Input integers for Array 2.
Enter Number for [ROW:0 COL:0]: 1
Enter Number for [ROW:0 COL:1]: 1
Enter Number for [ROW:0 COL:2]: 1
Enter Number for [ROW:1 COL:0]: 1
Enter Number for [ROW:1 COL:1]: 1
Enter Number for [ROW:1 COL:2]: 1
Enter Number for [ROW:2 COL:0]: 1
Enter Number for [ROW:2 COL:1]: 1
Enter Number for [ROW:2 COL:2]: 1
1 1 1
1 1 1
1 1 1
2 3
5 6
Just a minor change is needed. In arraySUM(), inside the else part you have re initialized
i=0 and j=0.
But after the re initialization they are incremented. So it will become 1 so while execution it will read ray[1], not ray[0].
Just re initialize them to -1.
i=-1 and j=-1
I have a function that takes array 1 and copies/manipulates it to array 2. Basically what it does is take the user input in array one, lets say (2, 3, 3) and array 2 is stored as (2, 0, 3, 0, 3). I know this works because it worked without implementing a function but sadly I have to have one. I cannot for the life of me figure out how to call the function, I believe I don't need a return since its a void and not returning a value. Below is my code any help would be appreciated.
#include <stdio.h>
void insert0(int n, int a1[], int a2[]);
int main() {
int i = 0;
int n = 0;
int a1[n];
int a2[2*n];
printf("Enter the length of the array: ");
scanf("%d",&n);
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
scanf("%d",&a1[i]);
}
insert0(); //call function which is wrong and I cannot get anything to work
for( i = 0; i < n*2; i++){ //prints array 2
printf("%d", a2[i]);
}
void insert0 (int n, int a1[], int a2[]){ //inserts 0's between each number
for(i = 0; i < n; i++){
a2[i+i] = a1[i];
a2[i+i+1] = 0;
}
}
}
Modifying n after declaraing a1 and a2 won't magically increase their size. Declare a1 and a2 after reading the size into n to use variable-length arrays.
You must pass proper arguments to call insert0.
Defining functions inside functions is GCC extension and you shouldn't do that unless it is required.
a2 should have n*2 - 1 elements, not n*2 elements.
After moving it out of main(), i is not declared in insert0, so you have to declare it.
You should check if readings are successful.
Corrected code:
#include <stdio.h>
void insert0(int n, int a1[], int a2[]);
int main() {
int i = 0;
int n = 0;
printf("Enter the length of the array: ");
if(scanf("%d", &n) != 1){
puts("read error for n");
return 1;
}
if(n <= 0){
puts("invalid input");
return 1;
}
int a1[n];
int a2[2*n-1];
printf("Enter the elements of the array: ");
for(i = 0; i < n; i++){ //adds values to first array
if(scanf("%d", &a1[i]) != 1){
printf("read error for a1[%d]\n", i);
return 1;
}
}
insert0(n, a1, a2);
for( i = 0; i < n*2-1; i++){ //prints array 2
printf("%d", a2[i]);
}
}
void insert0 (int n, int a1[], int a2[]){ //inserts 0's between each number
int i;
for(i = 0; i < n; i++){
a2[i+i] = a1[i];
if (i+1 < n){ // don't put 0 after the last element
a2[i+i+1] = 0;
}
}
}
Calculating average three by three elements and replacing those elements with the average result.
Example array [1,2,7,-2,5,0, 2,8]
After transformation [3,3,3,1,1,1,5,5]
Something is wrong, I can't get it to work.
#include <stdio.h>
int main ( ) {
int n, c[n];
int *avg;
int pom=0;
printf("Enter lenght of array\n");
scanf("%d",&n);
printf("Enter elements");
for(i = 0;i < n; i++)
scanf("%d",c[i]);
avg=Average(c , n, pom);
for(i = 0; i < n; i++)
printf("Avg elements= %d",*(avg+i))
return 0;
}
int Average(int arr[], int size, int z)
{
int k, l, m, Asum;
if (size < 0) {
return arr;
} else {
k=arr[z];
l=arr[z+1];
m=arr[z+2];
Asum=(k + l + m)/3;
arr[z]=Asum;
arr[z+1]=Asum;
arr[z+2]=Asum;
}
return Average(arr,size--,z++);
}
int n, c[n]; is a problem. n is uninitialized so the size of the array is who-knows-what? This is undefined behavior.
Instead
int main(void) {
int n;
int *avg;
int pom=0;
printf("Enter length of array\n");
if (scanf("%d",&n) != 1) return -1;
int c[n];
for(i = 0;i < n; i++)
// scanf("%d",c[i]);
scanf("%d",&c[i]); // pass the address of an `int`
Likely other issues too.
Try simple input first, imagine what happens when you enter only 1 number, what will the Average function do? Don't run the code but try to execute it in your head or with pencil and paper. If you think the program only has to work with three or more numbers, try three.
A serious program would explicitly reject invalid input.