Change the occurrences of a value in a matrix - arrays

I was trying to solve the following problem:
Count the occurrences in each row of a required input value in a 4x4 matrix
Then, change the occurrence to the value 0 only in the lines where the value appears two or more times
For the first step I didn't have any problems, but the second is giving me a lot of trouble.
After several attempts I managed to get to this point:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 4
int main() {
int mat[N][N] = { {6, 75, 45, 6}, {30, 6, 77, 64}, {15, 35, 6, 43}, {6, 95, 47, 6} };
int val;
int i, j;
int count_occ = 0;
srand(time(NULL));
/* for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
mat[i][j] = (rand() % 99 + 1);
}
} */
printf("Matrix original: \n");
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
printf("%3d", mat[i][j]);
}
printf("\n");
}
puts("");
printf("Insert a value to search for: ");
scanf("%d", &val);
puts("");
// Counting occurrencies of a value in each row
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (mat[i][j] == val) {
count_occ++;
if (count_occ >= 2) {
mat[i][j] = 0;
}
}
}
printf("There are %d occurrencies of value %d in row %d. \n", count_occ, val, i);
count_occ = 0;
}
puts("");
printf("Matrix modified: \n");
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
printf("%3d", mat[i][j]);
}
printf("\n");
}
puts("");
}
With the following output:
Matrix original:
6 75 45 6
30 6 77 64
15 35 6 43
6 95 47 6
Insert a value to search for: 6
There are 2 occurrencies of value 6 in row 0.
There are 1 occurrencies of value 6 in row 1.
There are 1 occurrencies of value 6 in row 2.
There are 2 occurrencies of value 6 in row 3.
Matrix modified:
6 75 45 0
30 6 77 64
15 35 6 43
6 95 47 0
As you can see, only some values ​​of the rows in question are modified, but not all the necessary ones.
Could anyone give me some advice on how to do this? I'm freaking out

The simplest (and inefficient in many ways) method is to make second pair of loops.
The first pair of loops (based on yours) is now only counting occurrences and saving it to the row_occ[N] array. The second pair of loops is only replacing values. It's inefficient, but quite simple.
int row_occ[N]; // ADDED
// This loop will only count
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
}
}
printf("There are %d occurrencies of value %d in row %d. \n", count_occ, val, i);
row_occ[i] = count_occ; // ADDED
count_occ = 0;
}
// This loop will only replace
for (i = 0; i < N; i++)
{
if (row_occ[i] < 2)
continue; // we will replace only if value occurs 2 or more times.
for (j = 0; j < N; j++)
{
if (mat[i][j] == val)
{
mat[i][j] = 0; //replacing
}
}
}
Better approach (and the one you are trying to implement) is to just add a single variable that will remember index of last occurrence of the value. When you have this index, you can replace not only current occurrence, but also the previous.
for (i = 0; i < N; i++)
{
int prev_occ;
for (j = 0; j < N; j++)
{
if (mat[i][j] == val)
{
count_occ++;
if (count_occ >= 2)
{
mat[i][prev_occ] = 0;
mat[i][j] = 0;
}
prev_occ = j;
}
}
printf("There are %d occurrencies of value %d in row %d. \n", count_occ, val, i);
count_occ = 0;
}
The first approach is not as nonsense as it looks like. Imagine huge array and condition of replacement "100 or more occurrences". IMHO it will be quite ok to implement it in the first method. At last as long as it is not the challenge of the most optimized code, but rather the easiest to write, understand and maintain.

Your current algorithm is the following:
For every number in the matrix, if the number is the input value and the input value has already been encountered on that line, then set the number to 0.
This algorithm is incorrect, as it will never set the first occurrence of the input value on a line to 0.
One simple correct algorithm would be the following:
For every line in the matrix, first determine whether the input value occurs at least twice on that line. If it does not occur at least twice, then do nothing. Otherwise, go back to the start of the line and replace all occurrences of the input value to 0.
Here is a demonstration program:
#include <stdio.h>
#define N 4
void print_matrix( int matrix[N][N] );
int main( void )
{
int mat[N][N] =
{
{ 6, 75, 45, 6 },
{ 30, 6, 77, 64 },
{ 15, 35, 6, 43 },
{ 6, 95, 47, 6 }
};
int val;
//print original matrix
printf( "Matrix original:\n" );
print_matrix( mat );
//add spacing
puts( "" );
//get input from user
printf( "Insert a value to search for: " );
scanf( "%d", &val );
//add spacing
puts( "" );
//process one row per loop iteration
for ( int i = 0; i < N; i++ )
{
int count_occ = 0;
//count number of occurrences in the current row
for ( int j = 0; j < N; j++ )
{
if ( mat[i][j] == val )
{
count_occ++;
}
}
//print information about number of occurrences
printf(
"There are %d occurrences of value %d in row %d.\n",
count_occ, val, i
);
//determine whether number of occurrences on the
//current line is at least two
if ( count_occ >= 2 )
{
//replace all occurrences on the current line
//with zero
for ( int j = 0; j < N; j++ )
{
if ( mat[i][j] == val )
{
mat[i][j] = 0;
}
}
}
}
//add spacing
puts( "" );
//print modified matrix
printf( "Matrix modified:\n" );
print_matrix( mat );
//add spacing
puts( "" );
}
void print_matrix( int matrix[N][N] )
{
for ( int i = 0; i < N; i++ )
{
for ( int j = 0; j < N; j++ )
{
printf( "%3d", matrix[i][j] );
}
printf( "\n" );
}
}
This program has the following behavior:
Matrix original:
6 75 45 6
30 6 77 64
15 35 6 43
6 95 47 6
Insert a value to search for: 6
There are 2 occurrences of value 6 in row 0.
There are 1 occurrences of value 6 in row 1.
There are 1 occurrences of value 6 in row 2.
There are 2 occurrences of value 6 in row 3.
Matrix modified:
0 75 45 0
30 6 77 64
15 35 6 43
0 95 47 0
This algorithm could be made more efficient by remembering the index of the first occurrence, so that you don't have to go back to the start of the line. However, this would make the algorithm also more complicated, so this optimization would only be worthwhile for larger matrixes.

Related

How to check if elements in a row of an array is larger than previous element of a particular row

I was given a question to solve in C.
Write a C program which can four cities temperature for last five days and display in how many days for each city temperature is higher than previous day
Sample Input
20 27 28 22
12 22 12 20
22 24 25 33
33 30 30 22
Sample Output
2
2
3
0
I've been trying to compare the elements in a particular row of an 2D array. But I'm lost in between how can I compare the elements and count although I'm able to locate large and small element in a row. I'm showing my piece of code:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
int array1[100][100];
int num, row, column, maxTemp = 0, minTemp = 0, counter = 0;
printf("How many rows and columns are needed: ");
scanf("%d %d", &row, &column);
printf("\nHow many cities temperature you want to enter: ");
scanf("%d", &num);
printf("\nEnter %d cities temperature: ", num);
for(int i=0; i<row; i++)
{
for(int j=0; j<column; j++)
{
scanf("%d", &array1[i][j]);
}
printf("\n");
}
maxTemp = array1[0][0];
minTemp = array1[0][0];
int maxTempRowL, maxTempColumnL, minTempRowL, minTempColumnL;
for(int i=1; i<row-1; i++)
{
for(int j=1; j<column-1; j++)
{
if(maxTemp < array1[i+1][j])
{
maxTemp = array1[i][j];
maxTempRowL = i; //row location
maxTempColumnL = j; //column location
}
if(minTemp > array1[i-1][j])
{
minTemp = array1[i][j];
minTempRowL = i; //row location
minTempColumnL = j; //column location
}
}
if(maxTemp > minTemp)
{
counter++;
break;
}
/*if(maxTemp <= minTemp)
{
return NULL;
}*/
printf("%d\n", counter);
counter = 0;
}
return 0;
}
Basically you can take a single counter variable at the start of each row and if the previous element in the array is smaller than the current element, then you can add one to the counter variable. At the end of each row, you can display the count of the counter variable.
The loop conditions were not accurate, you were starting from 1st index instead of the 0th index. Furthermore, it should have been i <= row-1 but you wrote i < row-1, this way the last row was not processed.
Check the code below
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
int array1[100][100];
int num, row, column, maxTemp = 0, minTemp = 0, counter = 0;
printf("How many rows and columns are needed: ");
scanf("%d %d", &row, &column);
printf("\nHow many cities temperature you want to enter: ");
scanf("%d", &num);
printf("\nEnter %d cities temperature: ", num);
for(int i=0; i<=row-1; i++)
{
for(int j=0; j <= column-1; j++)
{
scanf("%d", &array1[i][j]);
}
printf("\n");
}
for(int i=0; i<=row-1; i++)
{
int counter = 0;
for(int j=1; j <= column-1; j++)
{
maxTemp = array1[i][j-1];
if ( maxTemp <= array1[i][j] )
counter++;
}
printf("%d\n", counter);
}
return 0;
}
Since you asked specifically about the comparisons, I'm going to skip the input in this answer. I'm assuming here you have a row x col matrix, witch each row representing a single city, and each column representing a single per-day-temperature-measurement.
So, if I have matrix like yours:
20 27 28 22
12 22 12 20
22 24 25 33
33 30 30 22
in order to get output like these:
2
2
3
0
I would write something like this:
for (int i = 0; i < row; i++) { // for each city
int count = 0;
for (int j = 1; j < col; j++) { // I'm starting here with i=1, because I can't compare day 0 with day -1 (day -1 doesn't exist)
if (matrix[i][j] > matrix[i][j - 1]) // If the temperature was higher than previous day
count++; // then add one to our counter
}
printf("%d\n", count); // print our count
}
and here's the whole code that I checked this solution on, in case you needed it:
#include <stdio.h>
int main() {
int row=4, col=4;
int matrix[4][4] = {
{20, 27, 28, 22},
{12, 22, 12, 20},
{22, 24, 25, 33},
{33, 30, 30, 22},
};
for (int i = 0; i < row; i++) {
int count = 0;
for (int j = 1; j < col; j++) {
if (matrix[i][j] > matrix[i][j - 1])
count++;
}
printf("%d\n", count);
}
}
Also, if you needed (I don't know why would you tho) to save this counts for later, simply create an array, like:
int counts[MAX_ARRAY_SIZE];
and instead of printing our count immediately save it in counts:
printf("%d\n", count); -> counts[i] = count;

How can we replace the higest 5 numbers in an array of 10 with 1 and smallest 5 into 0 in C programing?

Here's the question my teacher gave me
Write a C program to store 10 integers in an array of size 10 and
display the contents of the array. Replace the highest 5 numbers in the array by
1 and lowest 5 numbers by 0 and display the contents of the new array.
[For e.g.
Original Array
44 11 6 99 30 78 32 31 66 55
New Array
1 0 0 1 0 1 0 0 1 1
I have been struggling in this question whole day :(
There are a lot of ways to solve this problem. A good way would be sort the array into another array and then replace the 1st half with 0s and the second half with 1s like this:
#include<stdio.h>
int main(){
const int arraySize = 10;
int i, j;
int arr[arraySize];
int arrSorted[arraySize];
int temp;
// Get input from user
printf("Please enter 10 numbers!\n");
for (i = 0; i < arraySize; i++)
{
scanf("%d", &arr[i]);
// Copy array into another to sort it later
arrSorted[i] = arr[i];
}
// Print input
printf("Input: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
//Sort the array in ascending order
for (i = 0; i < arraySize; i++)
{
for (j = i + 1; j < arraySize; j++)
{
if(arrSorted[i] > arrSorted[j])
{
temp = arrSorted[i];
arrSorted[i] = arrSorted[j];
arrSorted[j] = temp;
}
}
}
// Start replacing procedure
for (i = 0; i < arraySize; i++)
{
for (j = 0; j < arraySize; j++)
{
if (arr[j] == arrSorted[i])
{
if (i < arraySize / 2) // Replace 1st half with 0s
{
arr[j] = 0;
}
else // Replace 2nd half with 1s
{
arr[j] = 1;
}
break;
}
}
}
// Print result
printf("Result: ");
for (i = 0; i < arraySize; i++)
{
printf("%3d ", arr[i]);
}
printf("\n");
return 0;
}
Of course, you can use the C standard library qsort() function if you don't want to sort yourself.
Another solution would be, find the median number of the array then replace any number which is less than it with 0 and any number bigger than it with 1. Although with this solution there will be some challenges regarding what to do with the median number itself and what if there are multiple median numbers (duplicated)?

Find a set of the most common numbers in a randomly filled array

Good afternoon, and I have one question to ask about programming lottery in C language.
The requirements are:
Calculate each number's chance when if there are 46 balls labeled in each number in the box and there are 10K chances to pick one ball.
Then, print the number and number's chance on each item. The printed form must be like:
Number 45: 251 times
Find six of the most found numbers and print them out. The printed form must be like:
The most found were 45, 27, 8, 10, 12, 15
So my code was:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10000
#define ballamount 6
int main(void)
{
int fq[SIZE] = {0};
int i, max = 0, maximum1 = 0, temp = 0;
for (int i = 0; i < SIZE i++)
{
++fq[rand() % 45 + 1];
}
for (i = 0; i < 45; i++)
{
printf("number %d: %d times\n", i + 1, fq[i]);
}
for (i = 0; i < ballamount i++)
{
for (int j = 0; j < 45; j++)
{
fq[j] = fq[0];
if (fq[j] > temp)
{
temp = fq[j];
max = j;
}
}
fq[i] = max;
fq[max] = 0;
printf("Maximum number is %d.\n", max);
}
return 0;
}
I cannot find the path to solve this stuff. How can I solve it? Thanks in advance.
You're almost there, fq contains the number of times a given index is randomly selected, you already have that, you just have to select the six largest values in the array, minor tweaks to your code will render you the correct result.
Your code fixed, including ; typos, in the for loops, with comments:
Live demo
#include <stdio.h>
#include <stdlib.h>
#include <time.h> // for the seed
#define SIZE 10000
#define ballamount 6
int main(void)
{
srand(time(NULL)); // add a seed for your random number generator
int fq[46] = {0}; // the array only needs 46 elements
int max = 0;
int temp = 0;
for (int i = 0; i < SIZE; i++) // was missing ;
{
++fq[rand() % 46]; // if it's from 1 to 46, use index 0 to 45
}
for (int i = 0; i < 46; i++) // index 0 to 45
{
printf("number %d: %d times\n", i + 1, fq[i]);
}
printf("The most found balls were: ");
for (int i = 0; i < ballamount; i++) // was missing ;
{
for (int j = 0; j < 46; j++)
{
if (fq[j] > temp)
{
temp = fq[j];
max = j;
}
}
printf("%d ", max + 1); // adding 1, index starts at 0
fq[max] = 0;
temp = 0; // reset temp after the loop
}
}
Possible output:
number 1: 194 times
number 2: 187 times
...
...
The most found balls were: 28 30 43 5 29 12

I couldn't handle to write a histogram

My aim is to generate a histogram for repeated numbers. The code works well until the frequency is bigger than 2.
I think I know what is wrong with the code (line 9) but I cannot find an algorithm to solve it. The problem that I have is when it writes the histogram, it separates and then gathers it again.
My Input:
5
5 6 6 6 7
Output:
6:2 6:2 6:3
but the output I need is
6:3
I kind of see the problem but I couldn't solve it.
#include <stdio.h>
int main(){
int array[25];
int i, j, num, count = 1;
scanf("%d", &num);
for (i = 0; i < num; i++) {
scanf("%d", &array[i]);
for (j = 0; j < i ; j++) {
if (array [i] == array[j]) {
count++;
printf("%d:%d ", array[i], count);
}
}
array [i] = array[j];
count = 1;
}
return 0;
}
You are trying to count occurrences before all units have been accepted, which is not possible unless you maintain a separate counter for each value, which in turn is not practical if there is no restriction on the input value range or the range is large.
You need to have obtained all values before you can report any counts. Then for each value in the array, test if the value has occurred earlier, and if not, iterate the whole array to count occurrences:
#include <stdio.h>
#include <stdbool.h>
int main()
{
// Get number of values
int num = 0 ;
scanf("%d", &num);
// Get all values
int array[25];
for( int i = 0; i < num; i++)
{
scanf("%d", &array[i]);
}
// For each value in array...
for( int i = 0; i < num ; i++)
{
// Check value not already counted
bool counted = false ;
for( int j = 0; !counted && j < i; j++ )
{
counted = array[j] == array[i] ;
}
// If current value has not previously been counted...
if( !counted )
{
// Count occurnaces
int count = 0 ;
for( int j = 0; j < num; j++ )
{
if( array[j] == array[i] )
{
count++ ;
}
}
// Report
printf("%d:%d ", array[i], count);
}
}
return 0;
}
For your example input, the result is:
5
5 6 6 6 7
5:1 6:3 7:1
It is possible to merge the two inner loops performing the counted and count evaluation:
// Count occurrences of current value,
bool counted = false ;
int count = 0 ;
for( int j = 0; !counted && j < num; j++ )
{
if( array[j] == array[i] )
{
count++;
// Discard count if value occurs earlier - already counted
counted = j < i ;
}
}
// If current value has not previously been counted...
if( !counted )
{
// Report
printf("%d:%d ", array[i], count);
}
}

How can I make a new array, by counting the no.of appearances of value and printing it next to that value?

I should make new array out of existing one (ex. 1 0 4 5 4 3 1) so that the new one contains digits already in existing array and the number of their appearances.
So, the new one would look like this: 1 2 0 1 4 2 5 1 3 1 (1 appears 2 times, 0 appears 1 time.... 3 appears 1 time; the order in which they appear in first array should be kept in new one also); I know how to count no. of times a value appears in an array, but how do I insert the no.of appearances? (C language)
#include <stdio.h>
#define max 100
int main() {
int b, n, s, i, a[max], j, k;
printf("Enter the number of array elements:\n");
scanf("%d", &n);
if ((n > max) || (n <= 0)) exit();
printf("Enter the array:\n");
for (i = 0; i < n; i++)
scanf("%d", a[i]);
for (i = 0; i < n; i++) {
for (j = i + 1; j < n;) {
if (a[j] == a[i]) {
for (k = j; k < n; k++) {
a[k] = a[k + 1];
}}}}
//in the last 5 rows i've tried to compare elements, and if they are same, to increment the counter, and I've stopped here since I realised I don't know how to do that for every digit/integer that appears in array//
If you know that the existing array consists of digits between 0 and 9, then you can use the index of the array to indicate the value that you are incrementing.
int in[12] = {1,5,2,5,6,5,3,2,1,5,6,3};
int out[10] = {0,0,0,0,0,0,0,0,0,0};
for (int i = 0; i < 12; ++i)
{
++out[ in[i] ];
}
If you provide any code snippet, its easy for the community to help you.
Try this, even you optimize the no.of loops :)
#include <stdio.h>
void func(int in[], int in_length, int *out[], int *out_length) {
int temp[10] = {0}, i = 0, j = 0, value;
//scan the input
for(i=0; i< in_length; ++i) {
value = in[i];
if(value >= 0 && value <= 9) { //hope all the values are single digits
temp[value]++;
}
}
// Find no.of unique digits
int unique_digits = 0;
for(i = 0; i < 10; ++i) {
if(temp[i] > 0)
unique_digits++;
}
// Allocate memory for output
*out_length = 2 * unique_digits ;
printf("digits: %d out_length: %d \n",unique_digits, *out_length );
*out = malloc(2 * unique_digits * sizeof(int));
//Fill the output
for(i = 0, j = 0; i<in_length && j < *out_length; ++i) {
//printf("\n i:%d, j:%d val:%d cout:%d ", i, j, in[i], temp[in[i]] );
if(temp[in[i]] > 0 ) {
(*out)[j] = in[i];
(*out)[j+1] = temp[in[i]];
temp[in[i]] = 0; //Reset the occurrences of this digit, as we already pushed this digit into output
j += 2;
}
}
}
int main(void) {
int input[100] = {1, 0, 4, 5, 4, 3, 1};
int *output = NULL, output_length = 0, i = 0;
func(input, 7, &output, &output_length );
for(i=0; i < output_length; i+=2) {
printf("\n %d : %d ", output[i], output[i+1]);
}
return 0;
}

Resources