Checking 5 ints in an array if 3 are the same - c

I have a int array that contains five random numbers. I am trying to check if three of the numbers match.
int die[5] = {2, 3, 5, 2, 1};
int kind = 0;
int score = 0;
int i = 0;
int x = 0;
for (i; i <= 4; i++) {
for (x; x <= 4; x++) {
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}
The issue I am running into is the very first case it will compare itself to itself. Which will always come back true. And if I add a +1 to the index, it will end up going out of bounds.
If I start at 1 instead of 0, then when it goes to the second digit, it will return the same once it checks itself against the 2nd number(itself).

You could check if i equals j and just continue; your loop.
for(i=0; i<=4; i++){
// you can set x=i+1 and skip some numbers
for(x=0; x<=4; x++){
if(i==x)
continue;
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}
EDIT:
There are simpler ways of doing this (checking if 3 numbers are equal), but if you just want to skip an iteration, use continue.

int die[5] = {2, 3, 5, 2, 1};
int kind = 0;
int score = 0;
for (i = 0; i < 4; i++) { // last check will be die[3] == die[4] to avoid
// die[4] == die[4]
for (x = i + 1 ; x < 5; x++) { // it always checks with the next element
if (die[i] == die[x]) {
kind++;
score += die[i];
}
}
}

Related

Missing number in array in C programming

Given an array C of size N-1 and given that there are numbers from 1 to N with one element missing, the missing number is to be found.
Input:
The first line of input contains an integer T denoting the number of test cases. For each test case first line contains N(size of array). The subsequent line contains N-1 array elements.
Output:
Print the missing number in array.
This problem is to find the missing number in a series of n integers. but, while using the below code I could not get the output as expected.
#include <stdio.h>
int main()
{
//code
int T,run,i;
scanf("%d", &T);
long N,res,C,en;
long arra[1];
for (run = 0;run <T; run++ )
{
long arra[T];
scanf("%ld", &N);
res =0;
for (i = 0; i <N-1; i++)
{
scanf("%ld",&C);
res = res + C;
}
en = ((N*(N+1))/2)- res; // subtracting the overall sum of array elements from N integers
arra[run]=en; //saving it to array
}
for(run = 0; run < T; run++)
{
printf("%ld ",arra[run]);
}
return 0;
}
I expected the below input and output:
Input:
2
5
1 2 3 5
10
1 2 3 4 5 6 7 8 10
Output:
4
9
but actual output is
1 -8719623343620674816
You re-declared the variable arra inside the for loop. So when you assign to arra[run], you're assigning to the inner array, not the one in the main() function. So you get garbage when you try to print the contents of the array at the end.
You also declared the first array with only one element, rather than T elements.
Get rid of the second declaration, and change the first one from
long arra[1];
to
long arra[T];
correct code
declare the arra before the for loop else for every iteration the arra will be re declared deleting the previous values in it
#include <stdio.h>
int main()
{
//code
int T,run,i;
scanf("%d", &T);
long N,res,C,en;
long arra[T];
for (run = 0;run <T; run++ )
{
scanf("%ld", &N);
res =0;
for (i = 0; i <N-1; i++)
{
scanf("%ld",&C);
res = res + C;
}
en = ((N*(N+1))/2)- res; // subtracting the overall sum of array elements from N integers
arra[run]=en; //saving it to array
}
for(run = 0; run < T; run++)
{
printf("%ld ",arra[run]);
}
return 0;
}
here is a self explainable simple example
public static void Main()
{
int[] ary = { 5, 11, 3, 7, 13, 15 }; //{ 3, 5, 7, 11, 13, 15 };
Array.Sort(ary);
int freq=0;
int minval = ary[0];
int[] correct = new int[ary.Length+1];
int[,] freqs = new int[(ary.Length), 2];
freqs[0, 0] = 1;
freqs[0, 1] = ary[0];
for (int i = 0; i < ary.Length-1; i++)
{
int dif = ary[i + 1] - ary[i];
int res = Search(freqs, dif);
if (res < 0)
{
freqs[i, 0] = 1;
freqs[i, 1] = dif;
}
else
{
freqs[res, 0] = freqs[res, 0] + 1;
}
};
for (int i = 0; i < freqs.GetLength(0); i++)
{
freq =freqs[i, 0] >freq? freqs[i, 1] : freq;
}
for (int i = 0; i < correct.Length;i++)
{
correct[i] = i == 0 ? minval :( correct[i - 1] + freq);
}
foreach (int i in correct.Except(ary))
{
Console.WriteLine("eksik değer="+i);
}
Console.ReadLine();
int Search(int[,] matrix, int val)
{
int hit = -99;
for (int i = 0; i < matrix.GetLength(0); i++)
{
if (val == matrix[i, 1])
return i;
}
return hit;
}
}

How to find the items in the optimal solution of the knapsack problem using dynamic programming?

I want to find which items are eventually chosen in the optimal solution of the knapsack problem using the method of dynamic programming.
This is my interpretation so far...
#include<stdio.h>
int getMax(int x, int y) {
if(x > y) {
return x;
} else {
return y;
}
}
int main(void) {
//the first element is set to -1 as
//we are storing item from index 1
//in val[] and wt[] array
int val[] = {-1, 100, 20, 60, 40};
int wt[] = {-1, 3, 2, 4, 1};
int A[] = {0,0,0,0,0};
int n = 4; //num
int W = 5;//cap
int i, j;
// value table having n+1 rows and W+1 columns
int V[n+1][W+1];
// fill the row i=0 with value 0
for(j = 0; j <= W; j++) {
V[0][j] = 0;
}
// fill the column w=0 with value 0
for(i = 0; i <= n; i++) {
V[i][0] = 0;
}
//fill the value table
for(i = 1; i <= n; i++) {
for(j = 1; j <= W; j++) {
if(wt[i] <= j) {
V[i][j] = getMax(V[i-1][j], val[i] + V[i-1][j - wt[i]]);
} else {
V[i][j] = V[i-1][j];
}
}
}
//max value that can be put inside the knapsack
printf("Max Value: %d\n", V[n][W]);
//==================================find items
int n1,c;
n1=n;
c=W;
int A2[n1][c];
while(c>0){
if(A2[n1][c]==A2[n1-1][c]){
A[n1]=0;
} else {
A[n1]=1;
}
n1=n1-1;
c=c-wt[n1];
}
printf("Final array of items: ");
for(i = 0; i < n; i++){
printf("%d",A[i]);
}
} // end of main
And this is the output:
Max Value: 140
Final array of items: 0001
This string of ones and zeros is meant to be the finally chosen items, but from the solution this seems to be wrong!
I followed this algorithm:
While the remaining capacity is greater than 0 do
If Table[n, c] = Table[n-1, c] then
Item n has not been included in the optimal solution
Else
Item n has been included in the optimal solution
Process Item n
Move one row up to n-1
Move to column c – weight(n)
So, is this algorithm wrong / not suitable for this method, or am I missing something?

Is it the efficeint program to rotate array in left direction?

#include<stdio.h>
#include<stdlib.h>
main()
{
int i,j,l,m,n;
j=0;
printf("\nenter 5 element single dimension array\n");
printf("enter shift rate\n");
scanf("%d",&n);
/* Here we take input from user that by what times user wants to rotate the array in left. */
int arr[5],arrb[n];
for(i=0;i<=4;i++){
scanf("%d",&arr[i]);
}
/* Here we have taken another array. */
for(i=0;i<=4;i++){
printf("%d",arr[i]);
}
for(i=0;i<n;i++){
arrb[j]=arr[i];
j++;
// These loop will shift array element to left by position which's entered by user.
}
printf("\n");
for(i=0;i<=3;i++){
arr[i]=arr[i+n];
}
for(i=0;i<=4;i++){
if(n==1 && i==4)
break;
if(n==2 && i==3)
break;
if(n==3 && i==2)
break;
printf("%d",arr[i]);
}
//To combine these two arrays. Make it look like single array instead of two
for(i=0;i<n;i++){
printf("%d",arrb[i]);
}
// Final sorted array will get printed here
}
Is it the efficeint program to rotate array in left direction?
Actually, very complicated, and some problems contained:
for(i = 0; i < n; i++)
{
arrb[j] = arr[i];
j++;
}
Why not simply:
for(i = 0; i < n; i++)
{
arrb[i] = arr[i];
}
There is no need for a second variable. Still, if n is greater than five, you get into trouble, as you will access arr out of its bounts (undefined behaviour!). At least, you should check the user input!
for(i = 0; i <=3 ; i++)
{
arr[i] = arr[i + n];
}
Same problem: last accessible index is 4 (four), so n must not exceed 1, or you again access the array out of bounds...
Those many 'if's within the printing loop for the first array cannot be efficient...
You can have it much, much simpler:
int arr[5], arrb[5];
// ^
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5];
This does not cover negative values of n, though.
arrb[i] = arr[(((i + n) % 5) + 5) % 5];
would be safe even for negative values... All you need now for the output is:
for(int i = 0; i < 5; ++i)
printf("%d ", arrb[i]);
There would be one last point uncovered, though: if user enters for n a value greater than INT_MAX - 4, you get a signed integer overflow, which again is undefined behaviour!
We can again cover this by changing the index formula:
arrb[i] = arr[(5 + i + (n % 5)) % 5];
n % 5 is invariant, so we can move it out of the loop:
n %= 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(5 + i + n) % 5];
Finally, if we make n positive already outside, we can spare the addition in the for loop.
n = ((n % 5) + 5) % 5;
for(int i = 0; i < 5; ++i)
arrb[i] = arr[(i + n) % 5]; // my original formula again...
Last step is especially worth considering for very long running loops.
I think you want to do something like this (you should check that 0 <= n <= 5, too):
int b[5];
int k = 0;
for(i=0; i<5; i++){
if (i < 5 - n)
b[i] = arr[i+n];
else
{
b[i] = arr[k];
k++;
}
}
Array b is used to save the rotated matrix.

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;
}

Find the duplicate elements in a two-dimensional array

I need to find the duplicate elements in a two dimensional array.
route_ptr->route[0][1] = 24;
route_ptr->route[0][2] = 18;
route_ptr->route[1][1] = 25;
route_ptr->route[2][1] = 18;
route_ptr->route[3][1] = 26;
route_ptr->route[3][2] = 19;
route_ptr->route[4][1] = 25;
route_ptr->route[4][2] = 84;
Those are my data; the duplicate entries of route[2][1] (duplicate of route[0][2]) and route[4][1] (duplicate of route[1][1]) has to be found.
The solution is the duplicate 'i' value of route[i][j] which is 2 & 4 from this example.
please guide me.
#include <stdio.h>
struct route{
int route[6][6];
int no_routes_found;
int count_each_route[6];
};
int main() {
struct route *route_ptr, route_store;
route_ptr=&route_store;
int i,j,k;
// the data
route_ptr->route[0][1] = 24;
route_ptr->route[0][2] = 18;
route_ptr->route[1][1] = 25;
route_ptr->route[2][1] = 18;
route_ptr->route[3][1] = 26;
route_ptr->route[3][2] = 19;
route_ptr->route[4][1] = 25;
route_ptr->route[4][2] = 84;
route_ptr->count_each_route[0]=3;
route_ptr->count_each_route[1]=2;
route_ptr->count_each_route[2]=2;
route_ptr->count_each_route[3]=3;
route_ptr->count_each_route[4]=3;
route_ptr->no_routes_found=5;
//// process
for (i = 0; i <(route_ptr->no_routes_found) ; i++)
{
for (j = 1; j < route_ptr->count_each_route[i]; j++)
{
printf("\nroute[%d][%d] = ", i, j);
printf("%d",route_ptr->route[i][j]);
}
}
}
The solution expected is:
route[0][1] is compared by route [0][2] i.e [24 !=18]
route[0][1] and route [0][2] is compared by route[1][1] i.e [24 && 18 !=25]
route[0][1] and route[0][2] and route[1][1] is compared by route[2][1] i.e [ 24&&18&&25 is compared by 18, there is a matching element,
save the newcomer 'i' value which matches to the existence and drop it for next checking]
break the 'i' loop
route[0][1], route[0][2], route[1][1] is now compared route[3][1]
route[0][1], route[0][2], route[1][1] ,[3][1] is now compared route[3][2]
route[0][1], route[0][2], route[1][1] ,[3][1] ,[3][2] is now compared to route [4][1] i.e [ now there is a match to route[1][1], so save the newcomer 'i' value and break the 'i' loop
So i values [2 and 4] are duplicate, and that is my expected result of my code.
Got something against index zero, zero?
I also don't see the point of the pointer shenanigans.
It's a general safety thing to initialize all your data. You know, to zero or something.
The algorithm you suggest in your solution is rather hard to be faithful to, but this will find your duplicates. You have to walk through the entire array, in both dimensions, twice.
This will also match all the zeroes in your data, so you could add an exception to ignore routes values of zero.
//Cycling through the array the first time.
for (i = 0; i < 6 ; i++)
{
for (j = 0; j < 6; j++)
{
//Cycling through the array the second time
for (x = 0; x < 6 ; x++)
{
for (y = 0; y < 6; y++)
{
if(i==x && j==y)
continue;
if(routestore.route[i][j] == routestore.route[x][y])
printf("You have a match [%d][%d] = [%d][%d]", i, j, x,y);
}
}
}
}
Ok, so if you only want to see matches once, ie [0][2] == [2][1] but not [2][1] == [0][2], then you can do something like what I have below. This one made me scratch my head. Usually, when it's a simple list of items, you initialize the inner loop to the value of the outer loop, plus one. But you can't quite do that when it's a 2D array. So I gave up and made a super-lame hack-job. I'm a big fan of brute forcing things when possible. I'd normally tell you not to use pointers like this.
Now... this will still have multiple hits if you have three similar values. If that irks you then you need to start building a list and comparing hits against that as you walk through the data.
#include <stdio.h>
#include <string.h>
struct route{
int route[6][6];
int no_routes_found;
int count_each_route[6];
};
int lameAddOneAlternative(int *i, int *j)
{
if((*j)<6)
{
(*j)++;
return 1;
}
else if (*i<6)
{
(*i)++;
(*j) = 0;
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
struct route routeStore;
int i,j,x,y;
memset(routeStore.route,0,sizeof(int)*36);
// the data
routeStore.route[0][1] = 24;
routeStore.route[0][2] = 18;
routeStore.route[1][1] = 25;
routeStore.route[2][1] = 18;
routeStore.route[3][1] = 26;
routeStore.route[3][2] = 19;
routeStore.route[4][1] = 25;
routeStore.route[4][2] = 84;
//Cycling through the array the first time.
for (i = 0; i < 6 ; i++)
{
for (j = 0; j < 6; j++)
{
x=i;
y=j;
//Cycling through the array the second time
while(lameAddOneAlternative(&x,&y))
{
if(routeStore.route[i][j] == 0 )
continue;
if(routeStore.route[i][j] == routeStore.route[x][y])
printf("You have a match [%d][%d], [%d][%d] == %d\n", i, j, x,y, routeStore.route[i][j] );
}
}
}
}
for (i = 0; i <(route_ptr->no_routes_found) ; i++)
{
for (j = 1; j < route_ptr-> count_each_route[i]; j++)
{
for (x = 0; x < (route_ptr->no_routes_found) ; x++)
{
for (y = 0; y < route_ptr-> count_each_route[x]; y++)
{
if(i==x && j==y)
continue;
if(route_ptr->route[i][j] == route_ptr->route[x][y])
printf("You have a match [%d][%d] = [%d][%d]\n", i, j, x,y);
}
}
}

Resources