C language. How to find the maximum minimum. (2D arrays) - c

I have written code that allows you to enter one dimension of a NxN double array. It will then print random numbers in a 2D array and it finds the maximum and minimum number of each row. It then prints them and their coordinates (row and column).
ATTENTION!!!!
I have altered my code in such a way that it finds the minimum number of the maximum. I now don't know how to find it's coordinates
My code is as follows:
int N, i, j, min=1000, max, m , o;
time_t t;
int masyvas[100][100], minmax[100];
printf("Enter one dimension of a NxN array\n");
scanf("%d", &N);
srand((unsigned) time(&t));
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
{
masyvas[i][j] = rand() % 10;
printf("%4d", masyvas[i][j]);
}
printf("\n");
}
int k, l, idkeymax, idkeymin;
for(k=0; k<N; k++)
{
max=-1000;
for(l=0; l<N; l++)
{
if(max<masyvas[k][l])
{
max=masyvas[k][l];
}
}
minmax[k]=max;
}
for(m=0; m<N; m++)
{if(minmax[m]<min)
min=minmax[m];
}
printf("maziausias skaicius tarp didziausiu yra %d eiluteje %d stulpelyje %d\n",min);

Here's the pseudo code of what you need to do.
for row in grid {
row_max = max_in_row(row)
grid_min = min(grid_min, row_max)
}
Step one is to write a routine that finds the max and location in a list. You could do this as one big function, but it's much easier to understand and debug in pieces.
You also need the index where it was found. Since C can't return multiple values, we'll need a struct to store the number/index pair. Any time you make a struct, make routines to create and destroy it. It might seem like overkill for something as trivial as this, but it will make your code much easier to understand and debug.
typedef struct {
int num;
size_t idx;
} Int_Location_t;
static Int_Location_t* Int_Location_new() {
return calloc(1, sizeof(Int_Location_t));
}
static void Int_Location_destroy( Int_Location_t* loc ) {
free(loc);
}
Now we can make a little function that finds the max number and position in a row.
static Int_Location_t* max_in_row(int *row, size_t num_rows) {
Int_Location_t *loc = Int_Location_new();
/* Start with the first element as the max */
loc->num = row[0];
loc->idx = 0;
/* Compare starting with the second element */
for( size_t i = 1; i < num_rows; i++ ) {
if( row[i] > loc->num ) {
loc->num = row[i];
loc->idx = i;
}
}
return loc;
}
Rather than starting with some arbitrary max or min, I've used an alternative technique where I set the max to be the first element and then start checking from the second one.
Now that I have a function to find the max in a row, I can now loop over it, get the max of each row, and compare it with the minimum for the whole table.
int main() {
int grid[3][3] = {
{10, 12, 15},
{-50, -15, -10},
{1,2,3}
};
int min = INT_MAX;
size_t row = 0;
size_t col = 0;
for( size_t i = 0; i < 3; i++ ) {
Int_Location_t *max = max_in_row(grid[i], 3);
printf("max for row %zu is %d at %zu\n", i, max->num, max->idx);
if( max->num < min ) {
min = max->num;
col = max->idx;
row = i;
}
Int_Location_destroy(max);
}
printf("min for the grid is %d at row %zu, col %zu\n", min, row, col);
}
I used a different technique for initializing the minimum location, because getting the first maximum would require repeating some code in the loop. Instead I set min to the lowest possible integer, INT_MAX from limits.h which is highest possible integers. This allows the code to be used with any range of integers, there are no restrictions. This is a very common technique when working with min/max algorithms.

Related

Find the most frequent elements in an array of Integers

I have to find all of the elements which have the maximum frequency. For example, if array a={1,2,3,1,2,4}, I have to print as 1, also 2. My code prints only 2. How to print the second one?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define n 6
int main(){
int a[n]={1,2,3,1,2,4};
int counter=0,mostFreq=-1,maxcnt=0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
if(a[i]==a[j]){
counter++;
}
}
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
}
printf("The most frequent element is: %d",mostFreq);
}
How to print the second one?
The goal it not only to print a potential 2nd one, but all the all of the elements which have the maximum frequency.
OP already has code that determines the maximum frequency. Let us build on that. Save it as int target = mostFreq;.
Instead of printing mostFreq, a simple (still O(n*n)) approach would perform the same 2-nested for() loops again. Replace this 2nd:
if(counter>maxcnt){
maxcnt=counter;
mostFreq=a[i];
}
With:
if(counter == target){
; // TBD code: print the a[i] and counter.
}
For large n, a more efficient approach would sort a[] (research qsort()). Then walk the sorted a[] twice, first time finding the maximum frequency and the 2nd time printing values that match this frequency.
This is O(n* log n) in time and O(n) in memory (if a copy of the original array needed to preserve the original). If also works well with negative values or if we change the type of a[] from int to long long, double, etc.
The standard student solution to such problems would be this:
Make a second array called frequency, of the same size as the maximum value occurring in your data.
Init this array to zero.
Each time you encounter a value in the data, use that value as an index to access the frequency array, then increment the corresponding frequency by 1. For example freq[value]++;.
When done, search through the frequency array for the largest number(s). Optionally, you could sort it.
We can (potentially) save some effort in an approach with unsorted data by creating an array of boolean flags to determine whether we need to count an element at all.
For the array {1, 2, 3, 1, 2, 4} we do have nested for loops, so O(n) complexity, but we can avoid the inner loop entirely for repeated numbers.
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int arr[] = {1, 2, 3, 1, 2, 4};
size_t arr_size = sizeof(arr) / sizeof(*arr);
bool checked[arr_size];
for (size_t i = 0; i < arr_size; i++) checked[i] = false;
unsigned int counts[arr_size];
for (size_t i = 0; i < arr_size; i++) counts[i] = 0;
for (size_t i = 0; i < arr_size; i++) {
if (!checked[i]) {
checked[i] = true;
counts[i]++;
for (size_t j = i+1; j < arr_size; j++) {
if (arr[i] == arr[j]) {
checked[j] = true;
counts[i]++;
}
}
}
}
unsigned int max = 0;
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] > max) max = counts[i];
}
for (size_t i = 0; i < arr_size; i++) {
if (counts[i] == max)
printf("%d\n", arr[i]);
}
return 0;
}

How to find mode from an array

I have been trying to get this prototype for finding mode of an array to work but it is not returning the right thing, could someone please tell me what I am doing wrong.
int mode(int array[], int size)
{
int x;
int mode = 0;
int largest = 0;
for (x = 0; x < size; x++)
{
if (array[x] > largest)
{
largest = array[x];
mode = x;
}
}
return mode;
}
First of all if that's c++ Arrays are numbered from 0, so x should be 0 in the for. also x should be checked against < size. Other then that the code is good.
In the question you've mentioned that " prototype for finding mode of an array " ,but this program is intended to find the position of the largest number in an array, because
mode = x; // x is the value of i which in-turn is the position of element in the array
and the value of mode is returned. So the position of the largest element counting from the zero'th element's position is shown.
If you want a program to find the mode (element/number that occurs most often) in an array, here it is
#include <stdio.h>
int mode(int array[], int size);
int main()
{
int Num[100],size,ret_Val,i;
clrscr();
printf("Enter the size of the array\n");
scanf("%d",&size);
printf("%d ",size);
for(i=0;i<size;i++)
{
scanf("%d",&Num[i]);
}
ret_Val=mode(Num,size);
printf("Mode of the array is %d",ret_Val);
getch();
return 0;
}
int mode(int array[], int size)
{
int cntMde = 1;
int i;
int cnt = 1;
int num = array[0];
int mode = num;
for ( i=1; i<size; i++)
{
if (array[i] == num)
{
cnt++;
}
else
{
if (cnt > cntMde)
{
cntMde = cnt;
mode = num;
}
cnt = 1;
num = array[i];
}
}
return mode;
}
And the output is
Mode of the array is 44
I have analyzed four ways to calculate mode of the array:
If range of numbers in the array is small then use counting sort - O(N) time, (N) space but very efficient
Index elements in the array in hash table - O(N) time, O(N) space
Sort the array and then count successive equal elements - O(NlogN) time, O(1) space
Partially sort the array but skip partitions smaller than current candidate - O(NlogN) time, O(1) space but much more efficient than fully sorting the array because many partitions will be skipped
You can find source code for all four methods and performance comparison in this article: Finding Mode of an Array

How to count how many times values were used in the array C?

Here's my problem
If certain number has been entered into an array I need that number to be displayed and occurrence of that number in the array.
for example if user enters number 5 three times then "The number 5 has been entered 3 times so far" and so on
Here's my code so far:
int i,j;
int num_count = 0;
for(i=0;i<6;i++) {
num_count = 0;
for(j=1;j<43;j++) {
if( *(num + i) == j) {
printf("The number %d has been used %d times\n",j,num_count);
}//end if
}//end inner for
}//end outer for
I will like to suggest you a very time efficient method for this, but it needs some extra memory.
Assume the upper limit of numbers inside array is 'MAX_NUM_IN_ARRAY',
so you should create array (say counter) of size 'MAX_NUM_IN_ARRAY+1' and initialize it to 0.
int counter[MAX_NUM_IN_ARRAY+1]={0};
now scan the input array from first to last element,
for each number:
//say number is num
counter[num]++;
and at the end you have to just scan that counter array from index 1 to MAX_NUM_IN_ARRAY.
Sample code:
Suppose input array is a[],
number of elements in array is n,
maximum limit of number inside array is MAX_LIMIT
int counter[MAX_LIMIT]={0};
int i;
for(i=0; i<n; i++)
{
counter[a[i]]++;
}
for(i=0; i<MAX_LIMIT; i++)
{
printf("Number %d is appeared for %d times\n", i, counter[i]);
}
============EDIT
You could write a series of functions that handle your collection. the collection could be a 2 dimentional array like so numbers[][] where numbers[n][0] is your number, and numbers[n][1] is the number of times it occurred... and the gold would be in your add() function
add() does a few things, a user passes a value to add(),
first checks if number exists in numbers[n][0]
if the value exists at numbers[n][0]
numbers[n][1]++;
if it doesn't already exist,
check if the array is full
if it is full, copy all the data to a new, larger array
add it to the end of the array.. this is how to do it.
==OR
just design a 1 dimentional array numbers[] that holds all of your numbers.. and the add() function only:
if(it is full){copies to larger array}
adds number to the end;
and modify the code I wrote earlier (Below).. to print the most common number and it's occurrence count
============EDIT
I'm a Java guy so you'll need to translate (shouldn't be too hard..)
This is going to be just like a sorting algorithm with a little bit of extra logic (later search for Selection Sort)
int[] temp = {4,3,2,4,4,5};
////// find the most commonly occuring value
int times;
int moreTimes = 1;
int value = temp[0];
for(int i = 0; i < temp.length; i++) {
times = 1;
for(int j = i+1; j < temp.length; j++) {
if(temp[i] == temp[j])
times++;
}
if(times > moreTimes) {
moreTimes = times;
value = temp[i];
}
}
/////// count the most common value
int count = 0;
for(int i = 0; i < temp.length; i++) {
if(temp[i] == value)
count++;
}
System.out.println("number: " + value + ", count: " + count);

C Sorting an array by integer

So, I have to sort an array of integers so that every lesser number than some scanf'd integer is on the left, this set variable is in the middle, and every greater numbers on the right. I've got left and right part covered, but I am not sure how to make it so the variable is in the middle.. any ideas?
#include <stdio.h>
int main()
{
int y, i, k, temp;
printf("give integer\n");
scanf("%d", &y);
int x[10] = {5,8,9,4,2,3,2,4,5,6};
i=0;
k=1;
while(i<10)
{
while(x[i]>y&&k<10)
{
temp=x[k];
x[k]=x[i];
x[i]=temp;
k++;
}
i++;
k=i+1;
}
for(i=0; i<10; i++)
{
printf("x[%d]=%d\n", i, x[i]);
}
}
Example input/output:
input: x[i]={5,2,1,6,7,3,2,4,5,6} y=5
output: x[i]={2,1,4,3,2,5,5,7,6,6}
Instead of using one array you could use two arrays for reducing your code complexity.
Search for the numbers those are less than y and then store them in an array. Let's say A[ ]
Again search for the numbers those are greater than y and then store them in another array B[ ]
Like so..
Now you've got all of them. You could store them in another array which can be called as the sorted array. Or if you just want to print them, then
print all the elements of first array A[ ]
then print y
finally print the elements of second array B[ ]
That's all. Hope this idea will help you to code and solve this quickly.
You are looking for an algorithm similar to "partition" as in the quicksort algorithm. The idea is to have 2 indexes i and j where i is used to iterate through the array whereas j is the index of the first item that is greater or equal to y.
After that first loop, you have the numbers that are lesser than y on the left and the other numbers on the right. However, you actually want to group the values equal to y and have only the number greater than y on the right. So I'm suggesting to do the same on the interval [j,n] but now I'm also moving when it's equal.
// Function to exchange the values of 2 integer variables.
void swap(int *a, int *b) {
int buf = *a;
*a = *b;
*b = buf;
}
// Do the job, in place.
void partition(int *tab, int n, int y) {
// This first part will move every values strictly lesser than y on the left. But the right part could be "6 7 5 8" with y=5. On the right side, numbers are greater or equal to `y`.
int j = 0; // j is the index of the position of the first item greater or equal to y.
int i;
for (i = 0; i < n; i++) {
if (tab[i] < y) {
// We found a number lesser than y, we swap it with the first item that is greater or equal to `y`.
swap(&tab[i], &tab[j]);
j++; // Now the position of the first value greater or equal to y is the next one.
}
}
// Basically the same idea on the right part of the array.
for (i = j; i < n; i++) {
if (tab[i] <= y) {
swap(&tab[i], &tab[j]);
j++;
}
}
}
int main() {
int y;
printf("give integer\n");
scanf("%d", &y);
int x[10] = {5,8,9,4,2,3,2,4,5,6};
partition(x, 10, y);
int i;
for(i=0; i<10; i++)
{
printf("x[%d]=%d\n", i, x[i]);
}
return 0;
}
This code gives, with x = {5,2,1,6,7,3,2,4,5,6}; and y = 5:
x[0]=2
x[1]=1
x[2]=3
x[3]=2
x[4]=4
x[5]=5
x[6]=5
x[7]=7
x[8]=6
x[9]=6
The first 5 elements are lower than 5 and the others are greater or equal to 5.
This is a simple, straight forward way to sort the array x into another array y by partition. The numbers are sorted <= partition on left, and > partition on right:
[EDIT] to illustrate method according to OP clarification:
if array has 2 elements that are equal to p, then it should be arranged like this: xxxxxppyyyy where xp and p can't be mixed with either x's or y's.
Except that the example: xxxxxppyyyy is too long for the array, so I assume you meant xxxxppxxxx (10 elements, not 11).
int * partitionArr(int *z, int p);
int main(void)
{
int i, x[10] = {5,8,9,4,2,3,2,4,5,6};
//int i, x[10] = {3,3,3,3,3,8,8,8,8,8};
int *y;
int partition;
printf("enter a number from 0 to 10\n");
scanf("%d", &partition);
y = malloc(sizeof(int) * sizeof(x)/sizeof(x[0])+1); //+1 for inserting partition
y = partitionArr(x, partition);
printf("Partition is: %d\n\n", partition);
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
printf("y[%d] == %d\n", i, y[i]);
}
getchar();
getchar();
return 0;
}
int * partitionArr(int *z, int p)
{
int i=0,j=0;
int x[10];
//load y with x
for(i=0;i<sizeof(x)/sizeof(x[0]);i++) x[i] = z[i];
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]<p)
{
z[j] = x[i];
j++;
}
}
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]==p)
{
z[j] = x[i];
j++;
}
}
for(i=0;i<sizeof(x)/sizeof(x[0]);i++)
{
if(x[i]>p)
{
z[j] = x[i];
j++;
}
}
return z;
}
OUTPUT for following conditions: x < P; x== P; x< p (the only way to ensure P is in middle)
Simple algorithm, in case you want to work this through yourself:
partition entire array as [min..y][y+1..max], and take note of where the split is.
re-partition the first part only as [min..y-1][y..y].
Array should now be partitioned [min..y-1][y..y][y+1..max].
Simplest is to have a partition_helper function which does the partitioning and returns position of the split. Then the primary partition function calls this function twice, with right arguments.
You could also partition the other way, [min..y-1][y..max] first and then the re-partition the last part as [y..y][y+1..max], end result should be the same.

missing numbers

Given an array of size n. It contains numbers in the range 1 to n. Each number is present at
least once except for 2 numbers. Find the missing numbers.
eg. an array of size 5
elements are suppose 3,1,4,4,3
one approach is
static int k;
for(i=1;i<=n;i++)
{
for(j=0;j<n;j++)
{
if(i==a[j])
break;
}
if(j==n)
{
k++;
printf("missing element is", a[j]);
}
if(k==2)
break;}
another solution can be..
for(i=0;i
Let me First explain the concept:
You know that sum of natural numbers 1....n is
(n*(n+1))/2.Also you know the sum of square of sum of first n natural numbers 1,2....n is n*(n+1)*(2n+1)/6.Thus you could solve the above problem in O(n) time using above concept.
Also if space complexity is not of much consideration you could use count based approach which requires O(n) time and space complexity.
For more detailed solution visit Find the two repeating elements in a given array
I like the "use array elements as indexes" method from Algorithmist's link.
Method 5 (Use array elements as index)
Thanks to Manish K. Aasawat for suggesting this method.
traverse the list for i= 1st to n+2 elements
{
check for sign of A[abs(A[i])] ;
if positive then
make it negative by A[abs(A[i])]=-A[abs(A[i])];
else // i.e., A[abs(A[i])] is negative
this element (ith element of list) is a repetition
}
The only difference is that here it would be traversing 1 to n.
Notice that this is a single-pass solution that uses no extra space (besides storing i)!
Footnote:
Technically it "steals" some extra space -- essentially it is the counter array solution, but instead of allocating its own array of ints, it uses the sign bits of the original array as counters.
Use qsort() to sort the array, then loop over it once to find the missing values. Average O(n*log(n)) time because of the sort, and minimal constant additional storage.
I haven't checked or run this code, but you should get the idea.
int print_missing(int *arr, size_t length) {
int *new_arr = calloc(sizeof(int) * length);
int i;
for(i = 0; i < length; i++) {
new_arr[arr[i]] = 1;
}
for(i = 0; i < length; i++) {
if(!new_arr[i]) {
printf("Number %i is missing\n", i);
}
}
free(new_arr);
return 0;
}
Runtime should be O(2n). Correct me if I'm wrong.
It is unclear why the naive approach (you could use a bitfield or an array) of marking the items you have seen isn't just fine. O(2n) CPU, O(n/8) storage.
If you are free to choose the language, then use python's sets.
numbers = [3,1,4,4,3]
print set (range (1 , len (numbers) + 1) ) - set (numbers)
Yields the output
set([2, 5])
Here you go. C# solution:
static IEnumerable<int> FindMissingValuesInRange( int[] numbers )
{
HashSet<int> values = new HashSet<int>( numbers ) ;
for( int value = 1 ; value <= numbers.Length ; ++value )
{
if ( !values.Contains(value) ) yield return value ;
}
}
I see a number of problems with your code. First off, j==n will never happen, and that doesn't give us the missing number. You should also initialize k to 0 before you attempt to increment it. I wrote an algorithm similar to yours, but it works correctly. However, it is not any faster than you expected yours to be:
int k = 0;
int n = 5;
bool found = false;
int a[] = { 3, 1, 4, 4, 3 };
for(int i = 1; i <= n; i++)
{
for(int j = 0; j < n; j++)
{
if(a[j] == i)
{
found = true;
break;
}
}
if(!found)
{
printf("missing element is %d\n", i);
k++;
if(k==2)
break;
}
else
found = false;
}
H2H
using a support array you can archeive O(n)
int support[n];
// this loop here fills the support array with the
// number of a[i]'s occurences
for(int i = 0; i < n; i++)
support[a[i]] += 1;
// now look which are missing (or duplicates, or whatever)
for(int i = 0; i < n; i++)
if(support[i] == 0) printf("%d is missing", i);
**
for(i=0; i < n;i++)
{
while((a[i]!=i+1)&&(a[i]!=a[a[i]-1])
{
swap(a[i],a[a[i]-1]);
}
for(i=0;i< n;i++)
{
if(a[i]!=i+1)
printf("%d is missing",i+1); }
this takes o(n) time and o(1) space
========================================**
We can use the following code to find duplicate and missing values:
int size = 8;
int arr[] = {1, 2, 3, 5, 1, 3};
int result[] = new int[size];
for(int i =0; i < arr.length; i++)
{
if(result[arr[i]-1] == 1)
{
System.out.println("repeating: " + (arr[i]));
}
result[arr[i]-1]++;
}
for(int i =0; i < result.length; i++)
{
if(result[i] == 0)
{
System.out.println("missing: " + (i+1));
}
}
This is an interview question: Missing Numbers.
condition 1 : The array must not contain any duplicates.
The complete solution is :
public class Solution5 {
public static void main(String[] args) {
int a[] = { 1,8,6,7,10};
Arrays.sort(a);
List<Integer> list = new ArrayList<>();
int start = a[0];
for (int i = 0; i < a.length; i++) {
int ch = a[i];
if(start == ch) {
start++;
}else {
list.add(start);
start++;
//must do this
i--;
}
}//for
System.out.println(list);
}//main
}

Resources