How many times a digit show up - c

Please help me. I don't get why the out put is in "occurs" is "30", instead of '3'.. It's as if I'm multiplying the answer with '10', but I'm not.. Maybe the answer to my problem is right in to my code but Can someone explain why and how? please.. Thank you very much in advance..
Please take a look at my code.
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
int most;
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
occur[arr[j]]++;
if(occur[arr[j]] > max)
{
max = occur[arr[j]];
most = arr[j];
}
}
}
printf("Most frequent: %d\ occurs: %d\n", most, max);
return 0;
}
I am getting the correct answer in "Most Frequent". But the "occurs" is 30, instead of just 3 because 7 occurs 3 times.

It becomes 30 because there is an outer loop which executes 10 times.
I'm guessing that you want to get the most frequent number in the array and how many times it occurred that's why you have an outer loop. This will not work if you have a number in your array that is greater than 9 which will result in index out of bounds problem in occur array. You should change your implementation to this:
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int max = 0;
int most;
for(int i = 0; i < 10; i++)
{
int tmp = arr[i], count = 0;
// if the current number is the current max number then skip
if(tmp == max)
continue;
for(int j = 0; j < 10; j++)
{
// increment count if number in index j is equal to tmp number
count += arr[j] == tmp ? 1 : 0;
}
// [this condition will depend on the requirement.]
// replace max and most if the count of tmp number is greater than your
// current max
if(count > max){
max = count;
most = tmp;
}
}
printf("Most frequent: %d\ occurs: %d\n", most, max);
return 0;
}
This is not tested so if there are any problems, please feel free to edit.

You ARE multiplying max by 10 since you are doing everything 100 times (instead of 10) because of your totally redundant for i loop.
Specifically your problem is you are incrementing the values in occurs 10 times (instead of once). Since most doesn't use the incremented values it doesn't have problem.

The faster, O(2n-1) complexity solution
#include <stdio.h>
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
for(int i = 0; i < 10; ++i)
++occur[arr[i]];
for (int i = 1; i < 10; ++i)
if (occur[i] > occur[max])
max = i;
printf("Most frequent: %d\ occurs: %d\n", max, occur[max]);
return 0;
}
Yet faster, in O(n)... I had a feeling that..
int main(){
int arr[10] = {7, 7, 3, 2, 9, 8, 5, 1, 7, 9};
int occur[10] = {NULL};
int max = 0;
for(int i = 0; i < 10; ++i)
if (++occur[arr[i]] > occur[max])
max = arr[i];
printf("Most frequent: %d\ occurs: %d\n", max, occur[max]);
return 0;
}

I will not argue that your O(n^2) operations algorithm is not the ideal way to do the task.
But moving one line of code will fix your code.
Your loop:
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
occur[arr[j]]++;
Fix:
for(int i = 0; i < 10; i++)
{
occur[arr[i]]++;
for(int j = 0; j < 10; j++)
{
I'll let you figure out how you can do this in O(2n) operations or less...

Related

How to check if two arrays have the same set of digits in C?

I want to check if two integer type arrays have the same set of digits. For example, if array 1 is 5 1 2 3 3 4 6 1, and array 2 is 1 2 3 4 5 6, the program returns 1. If any number from either array isn't in the second one, the program returns a 0.
I tried doing something like this, but I can't get it to work:
#include <stdio.h>
int main()
{
int i, j, a[8]={5, 1, 2, 3, 3, 4, 6, 1}, b[6]={1, 2, 3, 4, 5, 6}, x=0;
for(i=0; i<6; i++)
{
for(j=0; j<8; j++)
{
if(a[j]==b[i])
{
x=1;
continue;
}
else
{
x=0;
break;
}
}
}
return x;
}
EDIT:
Thank you Some programmer dude
#include <stdio.h>
void sort(int arr[], int n)
{
int i, j, a;
for (i=0; i<n; i++)
{
for (j=i+1; j<n; j++)
{
if (arr[i]>arr[j])
{
a=arr[i];
arr[i]=arr[j];
arr[j]=a;
}
}
}
}
int main()
{
int i, j, k;
int a[8]={5, 1, 2, 3, 3, 4, 6, 1};
int b[6]={1, 2, 3, 4, 5, 6};
int na=8, nb=6;
for(i=0; i<na; i++) // removing duplicates from a
{
for(j=i+1; j<na; j++)
{
if(a[i]==a[j])
{
for(k=j; k<na; k++)
{
a[k]=a[k+1];
}
na--;
j--;
}
}
}
for(i=0; i<nb; i++) // removing duplicates from b
{
for(j=i+1; j<nb; j++)
{
if(b[i]==b[j])
{
for(k=j; k<nb; k++)
{
b[k]=b[k+1];
}
nb--;
j--;
}
}
}
sort(a, na);
sort(b, nb);
if(na!=nb)
return 0;
for(i=0; i<na; i++)
{
if(a[i]!=b[i])
return 0;
}
return 1;
}
You have several ways you can approach this, you can use two sets of nested loops swapping the order you loop over the two arrays validating each element is found in the other. Two full sets of nested loops are needed as you have a 50/50 chance any single outlier will be contained in either of the arrays. This is the brute-force method and has the potential worst-case number of iterations.
Since an outlier is what drove the need for looping with one arrays as outer and the other inner and then swapping a repeating, e.g. to catch 5, 1, 2, 3, 3, 4, 6, 1 and 1, 2, 3, 4, 5, 6, 7, if you can catch the outlier with another method that requires fewer iterations you can make your algorithm more efficient.
An outlier would be detected in a comparison of the min and max from each array, and to find min and max only requires a single linear traversal of each array. Much better than the worst-case nested loop over all elements.
The min and max check provide a way to shorten your work, but do not eliminate the need to press forward with a second set of nested loops if the result is inconclusive at that point. Why? Consider the following sets, where the min and max are equal, but one element within the range is not included in both arrays, e.g.:
int a[] = { 5, 1, 2, 3, 3, 4, 6, 112 },
b[] = { 1, 2, 3, 4, 5, 6, 7, 112 };
The only way the 7 will be detected is by nested loop with the array containing 7 being the outer loop.
So you could write a short function to test for the common set as:
#include <stdio.h>
#include <limits.h>
int commonset (int *a, int *b, int sza, int szb)
{
int maxa = INT_MIN, maxb = INT_MIN,
mina = INT_MAX, minb = INT_MAX;
for (int i = 0; i < sza; i++) { /* find max/min of elements of a */
if (a[i] > maxa)
maxa = a[i];
if (a[i] < mina)
mina = a[i];
}
for (int i = 0; i < szb; i++) { /* find max/min of elements of b */
if (b[i] > maxb)
maxb = b[i];
if (b[i] < minb)
minb = b[i];
}
if (maxa != maxb || mina != minb) /* validate max & mins equal or return 0 */
return 0;
for (int i = 0; i < sza; i++) { /* compare of each element between arrays */
int found = 0;
for (int j = 0; j < szb; j++)
if (a[i] == b[j]) {
found = 1;
break;
}
if (!found)
return 0;
}
for (int i = 0; i < szb; i++) { /* compare of each element between arrays */
int found = 0;
for (int j = 0; j < sza; j++)
if (a[j] == b[i]) {
found = 1;
break;
}
if (!found)
return 0;
}
return 1;
}
Adding a short example program:
int main (void) {
int a[] = { 5, 1, 2, 3, 3, 4, 6, 1 },
sza = sizeof a / sizeof *a,
b[] = { 1, 2, 3, 4, 5, 6 },
szb = sizeof b / sizeof *b,
result;
result = commonset (a, b, sza, szb);
if (result)
puts ("arrays have common set of numbers");
else
puts ("arrays have no common set of numbers");
return result;
}
Example Use/Output
$ ./bin/arr_commonset
arrays have common set of numbers
$ echo $?
1
With b[] = { 1, 2, 3, 4, 5, 6, 7 }:
$ ./bin/arr_commonset
arrays have no common set of numbers
$ echo $?
0
With a[] = { 5, 1, 2, 3, 3, 4, 6, 112 } and b[] = { 1, 2, 3, 4, 5, 6, 7, 112 }:
$ ./bin/arr_commonset
arrays have no common set of numbers
$ echo $?
0
There are probably even ways to combine the two and shave off a few iterations, and, if you have a guaranteed range for your input sets, you can use a simple frequency array for each and then two simple linear iterations would be needed to increment the element that corresponds to the index for each value in the array, and then a third linear iteration over both frequency arrays comparing that like indexes either both are non-zero or both are zero to confirm the common set -- that is left to you.
Look things over and let me know if you have any further questions.

Program to find a pair with the given number in array

#include <stdio.h>
int main() {
int num[] = { 6, 8, 4, -5, 7, 9 };
int sum = 0;
for (int i = 0; i < 6; i++) {
for (int j = i + 1; j < 6; j++) {
sum = num[i] + num[j];
if (sum == 15) {
printf("%d\n%d", num[i], num[j]);
}
}
}
return 0;
}
I'm trying to find a pair of numbers in the array with a sum of 15. The expected output is 6 & 9. But I'm getting output as 6, 98, 7. What is wrong?
EDIT: The issue was not giving a new line after the first result. Sorry.
The issue was not giving a new line after the first result.
replace
printf("%d\n%d",num[i],num[j]);
by
printf("%d,%d\n",num[i],num[j]);
i find nothing wrong here 9+6=15 and 8+7=15
and also in printf instead of
printf("%d\n%d",num[i],num[j]);
use
printf("%d %d\n",num[i],num[j]);
you will get well suited output

Iterate an array from the middle then the beginning

I want to iterate through any array starting at an index that's close to the middle, go to the end then go to the beginning.As an example:
#include <stdio.h>
int main(){
int a[]= {1, 2, 3, 4, 5, 6, 7,};
int i = 0;
for (i = 2; i < 6; i++){
if (i == 6){
i = 0;
}
printf("%d\n", a[i]);
}
return 0;
}
How can I "reassign" the index to be zero when it reaches the end (index 6)
Here is a simple write-up. Not tested so adjust as needed. The idea is have the counter start at 0 and add the value of start each time using modulus to make it relative.
int a[]= {1, 2, 3, 4, 5, 6, 7};
int length = sizeof(a)/sizeof(a[0]);
int start = length/2;
for (int i = 0; i < length; i++)
{
printf("%d\n", a[(i+start)%length]);
}
And props to #SouravGhosh for pointing out modulus in the comments before I got this answer up.
If I well understood the question you want two for loops, one starting from the middle of your array and going to the end of the array and the second starting from the middle (minus one) and decreasing to the beginning of the array.
This is the code you can use, it is quite easy and works fine for me:
#include <stdio.h>
int main() {
int a[] = { 1, 2, 3, 4, 5, 6, 7, };
int max = (int)(sizeof(a)/sizeof(a[0]));
int middle = (int)(max / 2);
int i;
for (i = middle; i < max ; i++) {
printf("%d\n", a[i]);
}
for (i = middle - 1; i >= 0; i--) {
printf("%d\n", a[i]);
}
}

Finding largest 2x2 "square" of values in array C

For my assignment I have to take in an array of values, save them to a second array and print out a "square" of the 4 highest values. This means the "square" for which the sum of its elements is the greatest in the array.
Example: Given the array 1 2 3 4
5 6 7 8
9 10 11 12
the output should be 7 8
11 12
I was originally trying to use sets of nested for loops to find and store each of the subsequent largest values into the second array, but can't seem to figure out the proper algorithm. What I have so far just gives me the same value (in this example's case, 12). Also, I have come to realize that this way won't allow me to keep the formatting the same in the second array.
What I mean is that if I'm saving the largest number found into array b[0][0], it will be in the wrong spot, and my square would be off, looking something like:
12 11
10 9
Here's what I have so far:
int main(){
int og[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}}, new[2][2]={}, rows;
int columns, i, high,j,high2,high3,high4;
high = new[i][0];
high2= high - 1;
high3= high2 - 1;
high4= high3 - 1;
rows = 3;
columns = 4;
for (i=0; i<=rows; i++){
for(j=0; j<=columns; j++){
if (high < og[j][i])
high = og[j][i];
}
}
for(i=1;i<=rows;i++){
for(j=1;j<=columns;j++){
if(high2 < og[j][i])
high2= og[j][i];
}
}
printf("max = %d, %d\n", high, high2);
//return high;
system("pause");
return 0;
The logic should go roughly as follows (I dont have a compiler atm to test it, so let me know in the comments if i made a derpy error):
int i = 0;
int j = 0;
int max = 0;
int sum = 0;
int i_saved = 0;
int j_saved = 0;
for(i = 0; i < rows - 1; i++){
for(j =0; j < columns -1; j++){
sum = og[i][j] + og[i][j+1] + og[i+1][j] + og[i+1][j+1]; //sum the square
if (sum > max){
max = sum;
i_saved = i;
j_saved = j;
}
}
}
Since OP is asking for the values used in order to save to another array, all you have to do is retrieve the values again! We have the indices saved already, so this should be relatively trivial.
int [][] arr = [2][2];
arr[0][0] = og[i_saved][j_saved];
arr[0][1] = og[i_saved][j_saved+1];
arr[1][0] = og[i_saved+1][j_saved];
arr[1][1] = og[i_saved+1][j_saved+1];
The same way we summed them, we can also use that logic pattern to extract them!
I created this solution:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int Mat[3][4]={{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}};
int maximum = 0;
int Max_2x2[2][2] = {{1, 2},
{5, 6}};
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 3; j++) {
maximum = max(Mat[i][j]+Mat[i][j+1]+Mat[i+1][j]+Mat[i+1][j+1], maximum);
if(maximum == Mat[i][j]+Mat[i][j+1]+Mat[i+1][j]+Mat[i+1][j+1]) {
Max_2x2[0][0] = Mat[i][j];
Max_2x2[0][1] = Mat[i][j+1];
Max_2x2[1][0] = Mat[i+1][j];
Max_2x2[1][1] = Mat[i+1][j+1];
}
}
}
cout << maximum << endl;
for(int i = 0; i < 2; i++) {
for(int j = 0; j < 2; j++) {
cout << Max_2x2[i][j] << " ";
}
cout << endl;
}
return 0;
}
which gives the following output:
38 // maximum solution
7 8 // output array
11 12
This is obviously not a general solution, but it works for your example.
int new[2][2]={}
I'm not sure this is valid. You might need to specify a 0 value for each cell. Even it it's not required, it's good practice.
high = new[i][0];
I don't see where i has been initialized.

Generate "In-Range" Random Numbers in C

I need to generated random numbers in the range [0, 10] such that:
All numbers occur once.
No repeated results are achieved.
Can someone please guide me on which algorithm to use?
The algorithm in Richard J. Ross's answer is incorrect. It generates n^n possible orderings instead of n!. This post on Jeff Atwood's blog illustrates the problem: http://www.codinghorror.com/blog/2007/12/the-danger-of-naivete.html
Instead, you should use the Knuth-Fisher-Yates Shuffle:
int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
srand(time(NULL));
for (int i = 10; i > 0; i--)
{
int n = rand() % (i + 1);
int temp = values[n];
values[n] = values[i];
values[i] = temp;
}
Try out this algorithm for pseudo-random numbers:
int values[11] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
srand(time(NULL));
for (int i = 0; i < 11; i++)
{
int swap1idx = rand() % 11;
int swap2idx = rand() % 11;
int tmp = values[swap1idx];
values[swap1idx] = values[swap2idx];
values[swap2idx] = tmp;
}
// now you can iterate through the shuffled values array.
Note that this is subject to a modulo bias, but it should work for what you need.
Try to create a randomize function, like this:
void randomize(int v[], int size, int r_max) {
int i,j,flag;
v[0] = 0 + rand() % r_max; // start + rand() % end
/* the following cycle manages, discarding it,
the case in which a number who has previously been extracted, is re-extracted. */
for(i = 1; i < size; i++) {
do {
v[i]= 0 + rand() % r_max;
for(j=0; j<i; j++) {
if(v[j] == v[i]) {
flag=1;
break;
}
flag=0;
}
} while(flag == 1);
}
}
Then, simply call it passing an array v[] of 11 elements, its size, and the upper range:
randomize(v, 11, 11);
The array, due to the fact that it is passed as argument by reference, will be randomized, with no repeats and with numbers occur once.
Remember to call srand(time(0)); before calling the randomize, and to initialize int v[11]={0,1,2,3,4,5,6,7,8,9,10};

Resources