Second least occurring element in an array in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am currently working on a project and for one of the parts I need to determine the second least occurring element in a C array. In any case, the maximum number of elements in the array is going to be 100. I have a function written already to find the least occurring element:
int minRepeat(int arr[], int i){
int j = 0;
int l = 0;
int minimum = 100;
int minNum = 0;
for(j = 0; j < i; j++){
int m = 0;
for(l = 0; l < i; l++){
if(arr[j] == arr[l]){
m++;
}
}
if(m < minimum){
minimum = m;
minNum = arr[j];
}
}
return minNum;
}
arr[] is the inputted array and int i is the size of that array.
I am trying to create a function that will find the second least occurring element in a C array. The function is currently:
int secMin(int arr[], int i){
int j = 0;
int l = 0;
int minimum = 0;
int minNum = 0;
int q = 0;
int k = minRepeat(arr, i);
for(q = 0; q < i; q++){
if(arr[q] == k){
minimum++;
}
}
int minimum2 = 100;
for(j = 0; j < i; j++){
int m = 0;
for(l = 0; l < i; l++){
if(arr[j] == arr[l]){
m++;
}
}
if(m < minimum2){
if(m > minimum){
minimum2 = m;
minNum = arr[j];
}
}
}
return minNum;
}
I am calling the first function to find the least occurring element. Looping through that to see how many times that element occurs in the array, and then doing the same as the first function to find the least occurring, but compare it to the first least element at the end to make sure that this element is the second least occurring.
When arr[] = {1, 1, 1, 2, 2, 3, 2, 2, 4, 1}
I get the least occurring number to be 3 and the second least occurring to be 1.
Sometimes the function works with other input and sometimes it does not, such as in the case above.
Thank you for your help!

Just adjust your first example a little to also store the second least element:
if(m < minimum){
secondminimum = minimum;
secondminNum = minNum
minimum = m;
minNum = arr[j];
}
Edit: I just realised that will only work if least and seconleast element do not have the same number of appearances, but you can capture that case.

Related

Have I written the Selection Sort Algoithm in C the right way?

A question in my book explained selection sort in three lines and then asked the reader to write CODE for it in C. I have written the code here and it is working fine, but I am a little confused whether I have written it in the right way or not. Please read the code, I have even added comments and correct me if needed.
#include <stdio.h>
#define VALUESIZE 10
int main(void)
{
int temp;
int value[VALUESIZE] = {3, 5, 46, 89, 72, 42, 312, 465812, 758, 1};
// Printing array just for the user to see.
for (int k=0; k<VALUESIZE; k++)
{
printf("[");
printf("%d", value[k]);
printf("] ");
}
printf("\n");
// Sorting algo begins
for (int i=0; i < VALUESIZE - 1; i++) // This will obviously loop through each element in our array except the last element as it will automatically be sorted after n-1 steps
{
for (int j= i+1; j <= VALUESIZE; j++) // This nested loop will go through each element which appears after ith element. For e.g. If i = 2, then j will loop through entire array starting from j = 3
{
if (value[i] > value[j]) // This basic if statement will compare our ith and following jth value
{
temp = value[i]; // If the program finds any value[j] greater than value[i], then the values will be swapped.
value[i] = value[j];
value[j] = temp;
}
}
}
// Now after sorting, print the new sorted array.
for (int l=0; l<VALUESIZE; l++)
{
printf("[");
printf("%d", value[l]);
printf("] ");
}
printf("\n");
}
Select sort needs to iterate through the array to compare the ith value. At the end of this pass it will swap the 2 values. This is a reason why its not a very good sort algorithm for medium or large arrays.
I have changed your code a bit below
Untested but should work:
// Sorting algo begins
for (int i = 0; i < arr_length - 1; i++)
{
int min = i;
for (int j = i + 1; j <= arr_length; j++)
{
if (value[j] < value[min])
{
min = j;
}
}
//now swap
int cache = value[min];
value[min] = value[i];
value[i] = cache;
}

How to connect puzzles so that right edge has same length as left edge of another puzzle?

I have puzzles that looks like this:
=== ====
=== ===
=== ====
left edge has length from 0 to 10 000 and right also, middle part is from 1 to 10 000.
So the question is if i can build a rectangle? like first puzzle has length of left edge equal to 0 and the last puzzle has right edge of length 0 and in the middle they fit perfectly?
I am given the number of puzzle i have and their params like this:
6
1 9 2
0 3 1
0 4 1
8 9 0
2 9 0
1 5 0
and result can be any of that:
2
0 3 1
1 5 0
or
3
0 3 1
1 9 2
2 9 0
or
2
0 4 1
1 5 0
But if there is no result i have to printf("no result")
I have to do this in C, I thought about doing some tree and searching it with BFS where vertices would have edge lengths and edge would have middle length and when reached 0 i would go all way up and collect numbers but it's hard to code. So i decided to do recursion but im also stuck:
#include<stdio.h>
int main(){
int a;
scanf("%d", &a);//here i get how many puzzles i have
int tab[a][3];//array for puzzles
int result[][3];//result array
int k = 0;//this will help me track how many puzzles has my result array
for(int i = 0; i < a; i++){//upload puzzles to array
for(int j = 0; j < 3; j++){
scanf("%d", &tab[i][j]);
}
}
findx(0, a, tab, result, k);//start of recursion, because start has to be length 0
}
int findx(int x, int a, int *tab[], int *result[], int k){//i am looking for puzzle with length x on start
for(int i = 0; i < a; i++){
if(tab[a][0] == x){//there i look for puzzles with x length at start
if(tab[a][2] == 0){//if i find such puzzle i check if this is puzzle with edge length zero at the end
for(int m = 0; m < 3; m++){//this for loop add to my result array last puzzle
result[k][m] = tab[a][m];
}
return print_result(result, k);//we will return result go to print_result function
}
else{//if i have puzzle with x length on the left and this is not puzzle which ends rectangle i add this puzzle
//to my result array and again look for puzzle with x equal to end length of puzzle i found there
for(int m = 0; m < 3; m++){
result[k][m] = tab[a][m];
k += 1;
}
findx(tab[a][2], a, tab, result, k);
}
}
}
printf("no result");
}
int print_result(int *result[], int k){
printf("%d", &k);//how many puzzles i have
printf("\n");
for(int i = 0; i < k; i++){//printing puzzles...
for(int j = 0; j < 3; j++){
printf("%d ", &result[i][j]);
}
printf("\n");//...in separate lines
}
}
I have an error that result array can't look like this int result[][3] because of of [] but I don't know how many puzzles I'm gonna use so?... and I have implicit declaration for both of my functions. Guys please help, I dont know much about C and its super hard to solve this problem.
I'm not sure I understand the overall logic of the problem, but you definitely are in need of some variable sized containers for result AND tab. Arrays are fixed size and must be defined at compile time. The following should at least compile without warnings:
#include<stdio.h>
#include<stdlib.h>
void print_result(int (*result)[3], int k){
printf("%d", k);//how many puzzles i have
printf("\n");
for(int i = 0; i <= k; i++){//printing puzzles...
for(int j = 0; j < 3; j++){
printf("%d ", result[i][j]);
}
printf("\n");//...in separate lines
}
}
void findx(int x, int a, int (*tab)[3], int (*result)[3], int k){//i am looking for puzzle with length x on start
for(int i = 0; i < a; i++){
if(tab[i][0] == x){//there i look for puzzles with x length at start
if(tab[i][2] == 0){//if i find such puzzle i check if this is puzzle with edge length zero at the end
for(int m = 0; m < 3; m++){//this for loop add to my result array last puzzle
result[k][m] = tab[i][m];
}
print_result(result, k);//we will return result go to print_result function
return;
}
else{//if i have puzzle with x length on the left and this is not puzzle which ends rectangle i add this puzzle
//to my result array and again look for puzzle with x equal to end length of puzzle i found there
for(int m = 0; m < 3; m++){
result[k][m] = tab[i][m];
k += 1;
///** Increase size of result **/
//int (*newptr)[3] = realloc(result, (k+1) * sizeof(int[3]));
//if (newptr)
// result = newptr;
}
findx(tab[i][2], a, tab, result, k);
}
}
}
printf("no result\n");
}
int main(){
int a;
scanf("%d", &a);//here i get how many puzzles i have
int (*tab)[3] = malloc(a * sizeof(int[3]));//array for puzzles
int (*result)[3] = malloc(a * sizeof(int[3]));//array for puzzles
int k = 0;//this will help me track how many puzzles has my result array
for(int i = 0; i < a; i++){//upload puzzles to array
for(int j = 0; j < 3; j++){
scanf("%d", &tab[i][j]);
}
}
findx(0, a, tab, result, k);//start of recursion, because start has to be length 0
}
Note that I changed the tab and result types to (*int)[3]. Due to order of operations, we need parentheses here. Because they are variable size, they require dynamic memory allocations. In the interest of brevity and readability, I did not check the returned values of malloc or realloc. In practice, you should be checking that the returned pointer is not NULL. Because we are using dynamic memory allocations, we should also use free if you plan on doing anything else with this program. Otherwise, it doesn't really matter because exiting the program will free the resources anyway. You actually don't want to free. because we are passing a pointer by value to findx and the realloc can change the address, it may come back with a different address. Also, take note that I needed to include <stdlib.h> for the dynamic memory allocations.
Additional Issues
Your functions print_results and findx are not declared when you call them in main. Your function either need to be above main or have "function prototypes" above main.
In the printfs you do not need the &. You do not want to send the address of the variable to printf. You want to send what will actually be printed.
Now what?
The program still does not provide you with the correct results. It simply outputs 0 as the result every time. This should at least give you a starting point. By changing this line in print_results:
for(int i = 0; i < k; i++){//printing puzzles...
to
for(int i = 0; i <= k; i++){//printing puzzles...
I was at least able to output 0 0 0. This seems more correct because if k is 0, we don't loop at all.
#include<stdio.h>
void findx(int x, int a, int tab[a][3], int result[200000][3], int puzzlesinresult) { //i am looking for puzzle with length x on start
for (int i = 0; i < a; i++) {
if (tab[i][0] == x) { //there i look for puzzles with x length at start
if (tab[i][2] == 0) { //if i find such puzzle i check if this is puzzle with edge length zero at the end
for (int m = 0; m < 3; m++) { //this for loop add to my result array last puzzle
result[puzzlesinresult][m] = tab[i][m];
}
return print_result(result, puzzlesinresult); //we will return result go to print_result function
} else { //if i have puzzle with x length on the left and this is not puzzle which ends rectangle i add this puzzle
//to my result array and again look for puzzle with x equal to end length of puzzle i found there
while (result[puzzlesinresult - 1][2] != tab[i][0] && puzzlesinresult > 0) {
puzzlesinresult -= 1;
}
int isusedpuzzle = 0;
for (int j = 0; j < puzzlesinresult; j++) {
if (result[j][0] == tab[i][0] && result[j][1] == tab[i][1] && result[j][2] == tab[i][2]) {
isusedpuzzle = 1;
} else {
//pass
}
}
if (isusedpuzzle == 0) {
for (int m = 0; m < 3; m++) {
result[puzzlesinresult][m] = tab[i][m];
}
puzzlesinresult += 1;
findx(tab[i][2], a, tab, result, puzzlesinresult);
}
}
}
}
}
void print_result(int result[200000][3], int puzzlesinresult) {
printf("%d\n", puzzlesinresult + 1); //how many puzzles i have
for (int i = 0; i < puzzlesinresult + 1; i++) { //printing puzzles...
for (int j = 0; j < 3; j++) {
printf("%d ", result[i][j]);
}
printf("\n"); //...in separate lines
}
exit(0);
}
int main() {
int a;
scanf("%d", & a); //here i get how many puzzles i have
int tab[a][3]; //array for puzzles
int result[100][3]; //result array
int puzzlesinresult = 0; //this will help me track how many puzzles has my result array
for (int i = 0; i < a; i++) { //upload puzzles to array
for (int j = 0; j < 3; j++) {
scanf("%d", & tab[i][j]);
}
}
for (int i = 0; i < a; i++) { //here i delete puzzles that doesnt contribute anything like 1 x 1,2 x 2,..
if (tab[i][0] == tab[i][2] && tab[i][0] != 0) {
for (int p = i; p < a; p++) {
for (int j = 0; j < 3; j++) {
tab[p][j] = tab[p + 1][j];
}
}
}
}
findx(0, a, tab, result, puzzlesinresult); //start of recursion, because start has to be length 0
printf("NONE");
}
This returns sometimes correct result. If you can find when this program fails I would rly appreciate sharing those cases with me :)

How to make a C program run faster? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have to calculate the number of prime numbers in the interval from 0 to N. The problem is that the program runs very slowly when N > 100000.
int main(){
long int i, j, n,isPrime;
long int N, count;
N = 10000000;
count = 0;
for(i = 2; i <= N; i++){
isPrime = 0;
for(j = 2; j <= i/2; j++){
if(i % j == 0){
isPrime = 1;
break;
}
}
if(isPrime==0 && N!= 1)
/*printf("%d ",i);*/
if(isPrime==0 && N!= 1)
count++;
}
printf(" %li ", count);
getch();
return 0;
}
you don't have to go up to i/2 to look for the prime, just look up to the square root. Any divisors greater that the square root aren't useful: you'd have already found their counterpart before.
int sqr = int(sqrt(i)); // make sure it is computed only once
for(j = 2; j <= sqr; j++){
that should do it...
or (as suggested) compare squares to avoid computing sqrt at all
for(j = 2; j*j <= i; j++){
That method is good to find if a big number is prime. But to find a range of prime numbers, you'd be better off with a Sieve of Erathostenes algorithm (I have linked the C version).
For one thing, this line:
for(i = 2; i <= N; i++){
Starts at i=2, then goes to:
i=3
i=4
i=5
i=6
i=7
Why are you checking values like 4, 6, and 8?You can skip those immediately!
Change your line to:
for(i = 3; i <= N; i+=2){ /* Start at 3, then 5, 7, 9, 11, etc. */
Don't use the modulus operation. Use the sieve.
static unsigned char sieve[10000000] = {0};
long countprimes(long N)
{
long answer = 0;
long i;
long j = 2;
long rootN = ceil(sqrt(N));
while(j < rootN)
{
for(i=j+j;i<N;i+=j)
sieve[i] = 1;
j++;
while(sieve[j])
j++;
}
for(i=2;i<N;i++)
if(!sieve[i])
answer++;
return answer;
}

Extending inner for loop calls indefinitely [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
The following code snippet will print every 4 character long combination (without repetition) of the elements of an array.
for (int i = 0; i < len; i++)
for (int j = i + 1; j < len; j++)
for (int k = j + 1; k < len; k++)
for (int l = k + 1; l < len; l++)
printf("%c%c%c%c\n", arr[i], arr[j], arr[k], arr[l]);
My problem is I don't know how to extend this to a general function (ie print every N character long combination). How can I make a function do the same thing but be called like this:
combinationPrint(array, numberOfForLoops); // With other params if needed
The recursive version of your function would work like this:
void recur (char* arr, int i, int len, char *x, int k, int n) {
if (k==n) { // the last inner loop
x[k]=0;
printf ("%s\n", x);
}
else {
for (int j=i+1; j<len; j++) { // recursive loop
x[k]=arr[j];
recur (arr, j, len, x, k+1, n); // call recursion for an inner loop
}
}
}
In this recursion, arr and len correspond to your definition and n is the depth of the loops you want to achieve (4 in your non recursive version).
The trick is to use a null terminated array of n+1 chars, that you keep across the recursion and build the string that you want to print at the last level. i is then the starting position of the loop and k is the current level of recursion.
You would call this:
recur (arr, -1, len, out, 0, 4 );
Online demo
Without recursion, you can use this (len = length of the array) :
int i, j, w, x;
for(i=0; i<pow(len,len); i++){ //n^n possibilities / combinaisons
w = i;
for(j=0; j<len; j++){ //Show the combinaison
x = w%len; //We have juste to calculate the correct position with some modulos
printf("%c", array[x]);
w = w/len;
}
printf("\n");
}
For exemple with this implementation :
#include <stdio.h>
#include <math.h>
int main(){
int array[] = {1,2,3};
int len = 3;
int i, j, w, x;
for(i=0; i<pow(len,len); i++){
w = i;
for(j=0; j<len; j++){
x = w%len;
printf("%d", array[x]);
w = w/len;
}
printf("\n%d\n", i);
}
}
You should have :
111
211
311
121
221 [...]
133
233
333
Well, instead of N loops - you just need one. Within this main loop you have to have just two inner loops for incrementing array of indices and for printing values:
int increment(int* index, int N, int len)
{
for (int i = N - 1; i >= 0; --i)
{
++index[i];
if (index[i] < len)
return 1;
index[i] = 0;
}
return 0;
}
So - the main loop:
int index[N] = {};
do
{
// print
for (int i = 0; i < N; ++i)
printf("%c", arr[index[i]]);
printf("\n");
} while (increment(index, N, len));

Code to store indices of occurrences doesn't work

In the program that I'm writing, I currently have a for-loop that goes through an array, num[5], and checks to see if there are any 1's in that array, which looks like:
int counter = 0;
for (int i = 1; i <= 5; i++)
if (num[i] == 1)
counter++;
This works successfully, but I'm now trying to go through the array and see what the indices of the 1's in the program are. So, if I have 01001, I want to make an array that holds the positions of the 1's. The following is what I've tried so far:
int b[counter];
for (int k = 0; k <= counter; k++) {
for (i = 0; i <= 5; i++) {
if (num[i] == 1) {
b[k] = i;
}
}
}
but this doesn't produce the desired result. When I type the string in, say 1001, I get 444. Can someone tell me what I'm doing incorrectly?
For each value of k, for each occurrence of a 1, you're setting b[k] to the index of the 1. Thus each b[k] will have the index of the last 1.
Try:
int b[counter];
int k = 0;
for (i = 0; i <= 5; i++) {
if (num[i] == 1) {
b[k++] = i;
}
}
So, whenever it gets a 1, it assigns b[k] to the index and then increases k.
Then you should also use k, not counter, when trying to print out b.
The problem lies in this part of your code.
int b[counter];
for (int k = 0; k <= counter; k++) {
**for (i = 0; i <= 5; i++) {
if (num[i] == 1) {
b[k] = i;
}**
}
}
Suppose you get a 1 at the index 1 of the array as in 01001. You assign b[k] = 1;
This is perfectly valid. But as the loop continues you get another 1 at the index 4. Thus the command b[k] = 4; is again executed.
Note that your value of k is constant in both the statements and hence you get the array b as 44.
So what you need to do is break the inner for loop as soon as you get a 1.
Here is the modified code. You also need to keep a track of the iterator i and I have done that here using the variable- new_pos // new position.
int b[counter];
int new_pos=0; //to keep track of the iterator
for (int k = 0; k <= counter; k++) {
for (i = new_pos; i <= 5; i++) {
if (num[i] == 1) {
b[k] = i;
new_pos = i+1;
break;
}
}
}
The code provided by Dukeling is also perfect, but I am just giving another way to make your own code work.

Resources