How would i do first and second parts? - arrays

Consider we have to choose a Leader from n people. For this purpose, we create an
array of size n. We assign every candidate a number (1, 2, 3, 4, 5,….,n) and store it in array in
ascending order. We apply dancing chair (People struggle to get the chair!!! After stopping the
music, in each iteration one chair and one man is eliminated. The Final remaining one is the
winner) method. Suppose we start from index 0 then we have to skip 3 indexes and we will reach
at index 3. Set its value to zero and start again from index 4 and skip 3 indexes and we will reach at index 7. Repeat the same step and so on.
(1) When we reach at last index we will proceed to index 0 again (for example the last index is 19, we start the count from index 18 and skip 3 indexes then we will reach at 1 and set it to zero).
(2) If the reached element value is already 0 than set the next element to zero. Do the same process till only one element remaining?
We implement it by using array and function. Write a function SelectLeader () which takes array
as input and return the Leader.
#include <stdio.h>
int SelectLeader() {
int n, i;
int leader = 0;
printf("Enter total number of people to choose a Leader from: ");
scanf("%d", &n);
int array[n];
for (i = 0; i < n; i++) {
array[i] = i + 1;
}
for (i = 0; i <= n; i = (i + 3) % n) {
if (array[i] == 0) {
array[(i + 1) % n] = 0;
} else
array[i] = 0;
}
for (i = 0; i < n; i++) {
if (array[i] != 0) {
leader = i;
}
}
return leader;
}
int main() {
int L;
L = SelectLeader();
printf("Leader is the candidate with the index number %d\n", L);
}

You can use the following pesudo code
Suppose n= 10 , for easy understanding
I am creating a boolean flag array to check whether number is selected or not.
jump = 3
i = 0
for (int cnt=0;cnt<10;) {
if(flag[i%10] === false) {
flag[i%10]=true;
cnt+=1;
i+=jump;
}
else {
i+=1;
}
}
The index element remaining with flag false is ans.
However this approach is both space and time expensive.

Related

Finding the second Max in an unsorted dynamic array

I share with my solution of the algorithm to find the second maximum in a given unsorted array, is there a better way to do it? (I found complexity O(2n))
int PositionDuSecondMax(int *T, int n) {
// this function look for the index of the second maximum ( the number just under the maximum ) in a given array
// exemple : T[] = {10,100,14,49] ---> this function returns 3
// we have T a dynamic array and n the number of elements in T
// the given array in unsorted
int iMax = 0; // we suppose iMax == 0
int iSecMax;
// we go through the array and compare T[iMax] with the current element in the current index
// so we can find the index of the max in the array
for (int i = 0; i < n; i++) {
if (T[iMax] < T[i]) {
iMax = i;
}
}
// this if statement is to max sure that iMax is different from iSecMax
if (iMax == 0) {
iSecMax = 1;
} else {
iSecMax = iMax - 1;
}
// we loop through the array and compare each element with T[iSecMax] , we must specify that T[iSecMax] != T[iMax]
for (int i = 0; i < n; i++) {
if (T[iSecMax] < T[i] && T[iSecMax] == T[iMax]) {
iSecMax = i;
}
}
return iSecMax;
}
Your approach has multiple problems:
if the max is at offset 0 with a duplicate at offset 1 or if the max is at offset iMax - 1, the initial value of iSecMax is that of the maximum so you will not find the second max.
the test T[iSecMax] == T[iMax] to avoid select a duplicate of the max value is incorrect, it should be T[i] != T[iMax].
Here is a modified version:
int PositionDuSecondMax(const int *T, int n) {
// this function returns the index of the second maximum (the number just under the maximum) in a given array
// example: T[] = {10,100,14,49} --> this function returns 3
// arguments: T points to an unsorted array of int,
// n is the number of elements in T.
int iMax = 0;
int iSecMax = -1;
// we go through the array and compare T[iMax] with the
// element in the current index so we can find the index
// of the max in the array
for (int i = 1; i < n; i++) {
if (T[iMax] < T[i]) {
iMax = i;
}
}
// we loop through the array, ignoring occurrences of T[iMax] and
// compare each element with T[iSecMax]
for (int i = 0; i < n; i++) {
if (T[i] != T[iMax] && (iSecMax < 0 || T[iSecMax] < T[i])) {
iSecMax = i;
}
}
return iSecMax;
}
Notes:
the above function will return -1 if the array is empty or has all entries with the same value, ie: no second max value.
the complexity is O(n). O(2n) and O(n) are the same thing: O(n) means asymptotically proportional to n.
You could modify the code to perform a single scan with a more complicated test, and it would still be O(n).
If the array is unsorted, all elements must be tested so O(n) is the best one can achieve.
If the array was sorted, finding the second max would be O(1) on average (if the second to last element differs from the last), with a worst case of O(log n) (using binary search when the max has duplicates).
If you want to find second largest element in one traverse, you can follow below approach.
if (arrSize < 2)
{
printf(" Invalid Input ");
return;
}
first = second = INT_MIN;
for (i = 0; i < arrSize; i++)
{
/* If current element is greater than first
then update both first and second */
if (arr[i] > first)
{
second = first;
first = arr[i];
}
/* If arr[i] is in between first and
second then update second */
else if (arr[i] > second && arr[i] != first)
second = arr[i];
}
if (second == INT_MIN) printf("There is no second largest element\n");
else printf("The second largest element is %d\n", second);
The best approach is to visit each element of an array to find the second highest number in array with duplicates. The time complexity of this approach is O(n).
Algorithm :
i) Declare two variables max and second max and initialize them with integer minimum possible value.
ii) Traverse an array and compare each element of an array with the value assigned to max variable. If current element is greater than the value assigned at max variable. Then do two things –
a) In second max variable, assign the value present at max variable.
b) In max variable, assign the current index value.
iii) We have to do one more comparison that if current index value is less than max and greater than the value assigned at second max. Then, assign current index value at second max variable.
After complete iteration print the second max element of an array.
#include<stdio.h>
int secondLargest(int arr[], int len) {
//Initialize
int max = 0;
int second_max = 0;
for(int i = 0; i < len; i++) {
if(arr[i] > max) {
second_max = max;
max = arr[i];
}
if(max > arr[i] && arr[i] > second_max) {
second_max=arr[i];
}
}
return second_max;
}
int main(void) {
int arr[] = {70, 4, 8, 10, 14, 9, 7, 6, 5, 3, 2};
int len = 11;
printf("Second highest element is %d\n",secondLargest(arr,len));
return 0;
}

Function that produces first index of ''3 in a row number occurrence''

i want to create a function that take the inputs of an array and its number of values. The function should look through the array and as soon as it sees a ''3 in a row''(e.g { 1 2 3 4 5 5 5 6 7 8}), in this case 5. The function should print the index of the first 5. Im new to coding so im finding it difficult how to begin. Ive made an attempt but dont know how to proceed.
int NewFunction(int array, int numValues){
int i;
int j;
for(i=0;i<numValues;i++){
for(j=i+1;j<numValues;j++){
if(
First of all, you might want to go with a more descriptive name than NewFunction. Also, the array shouldn't be of type int, you're probably looking for a pointer to an int.
Furthermore, you don't need a nested loop like that:
for(i=0;i<numValues;i++){
for(j=i+1;j<numValues;j++){
Imagine doing this by hand, getting a list of about 1000 numbers, trying to find three in a row. How often would you pass through the list? A maximum of once, right? You wouldn't go through the list a thousand times, so neither should your algorithm, therefore you don't need a nested loop here.
What you're looking for is something like this:
int threeInARow(int* array, int numValues) {
int count = 1; // how many numbers in a row were found
int current = array[0]; // the number that we're looking for
int i = 1;
for (; i < numValues; i++) {
if (array[i] == current) {
if (++count == 3) return i - 2;
}
else { // a different number is found: start over
count = 1;
current = array[i];
}
}
return -1; // return a value indicating that no result was found
}
Start with a variable: where have you first seen the last value you saw. Let's call it last, and initialise it at 0. Then iterate index from 1 to the length of the array. If the difference between index and last is 3, return last as the index of the repeating value. If not, check whether index is at length. If so, the search failed. Otherwise, if the value at the current index is different from the value at last, set last to the current index.
Another approach.
#include <stdio.h>
#define ELEMENT 14
int three_in_a_row(int arr[], int n) {
int i, index, count = 0, max = 0;
i = -1;
do {
i = i + 1;
if (arr[i] == arr[i + 1]) {
index = i-1; //because we want the first occurrence
count++;
if (count > max) max = count; // 3 elements in a row means that max must be 3-1
} else
count = 0;
} while (i < n - 2 && max != 3 - 1);
return (max == 2 ? index : -1);// -1 indicates no result
}
int main(void) {
int array[] = {1,10,1,4,4,8,8,8,7,8,8,9,9,2}, index3;
index3 = three_in_a_row(array, ELEMENT);
printf("%d\n", index3);
return (0);
}

How do I record the frequency of numbers inputted by a user using functions in C

Hey there i'm currently developing a lotto type game and one of my requirements is to record the frequency of the numbers inputted by the user and then display them if the users wishes to see them. The program also must be modular hence the functions.
My problem is that i can't seem to figure out how to keep track of the numbers I tried numerous things and this is the closest I've gotten...
void num_free(int *picked_nums)
{
static int elements[MAX] = { 0 };
int i;
for (i = 0; i < MAX; i++)
if (*(picked_nums + i) == i)
{
elements[i]++;
}
for (i = 0; i < MAX; i++)
{
if (elements[i] != 0)
{
printf("\nThe amount of times you chose %d is %d", i, elements[i]);
}
}
printf("\nEnter any key to return to main menu");
getchar();
}
The output of this every time i run it no matter the input is
"The amount of times you chose 11 is 1"
I'm really clueless as to what to do next so any and all help would be appreciated. Thanks in advance!
EDIT: The user can play multiple rounds and thats how the frequency of the numbers can add up.
I think the main problem in your code is here:
if (*(picked_nums + i) == i)
{
elements[i]++;
}
you actually check if the i-th number the user chose equals to i. That means that increment is done only in that case - which is not what you want (if I got you right).
I think you should give up the if statement, and, assuming that the user chooses only non-negative numbers (and that the elements array is properly zeroed at the beginning), do this:
elements[picked_nums[i]]++;
Namely, you increment the array cell matching the chosen number (and the i is only the index you use to iterate the picked_num array).
The problem is how you count and store the numbers:
if (*(picked_nums + i) == i)
{
elements[i]++;
}
Your i is moving and at the same time the element chosen from picked_nums is moving. This loop will not count or store properly.
The provided solution assumes that picked numbers are stored in the numbers array. I assumed that numbers are in 1 to 64 range. You can adjust program to your needs. Test provided:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void num_free(int picked_nums[], int size )
{
static int elements[65] = { 0 }; // numbers can be from 1 to 64 range
int i;
for (int j = 0; j < size; j++)
{
int n = picked_nums[j];
for (i = 1; i < 65; i++) // numbers can be from 1 to 64 range
{
if ( n == i)
{
elements[i] = elements[i]+1;
}
}
}
for (i = 0; i < 65; i++)
{
if (elements[i] != 0)
{
printf("\nThe amount of times you chose %d is %d", i, elements[i]);
}
}
// printf("\nEnter any key to return to main menu");
// getchar();
}
// array of entered numbers:
int numbers[] = { 2, 2, 2, 40, 7, 7, 8, 9, 40 };
int main(void) {
num_free(numbers, 9); // call with sizeof numbers
return 0;
}
Test:
The amount of times you chose 2 is 3
The amount of times you chose 7 is 2
The amount of times you chose 8 is 1
The amount of times you chose 9 is 1
The amount of times you chose 40 is 2

Custom iteration through array in C printing every nth value

I'm currently working on a homework assignment and what I have to do is ask for the size of the array and what I would like to loop through it (how many things I should skip through). Example (I bolded what would be the users response)
How large is the array?
10
How would you like to iterate through it?
3
Conditions:
Then it should loop through every third item and then start over looping through the items that haven't been picked until the last one. I must also start on the first item (0) which you can see in my code that I provided.
This is what I thought I could do...
int amount=0, often=0, counter=0, x;
printf("Size of Array? ");
scanf("%d", &amount);
printf("iteration size? ");
scanf("%d", &often);
// sets the array (1 means it exists)
int[] array[amount];
for(x=0; x<amount; x++)
array[x] = 1;
// the part that I'm confused on
// supposed to iterate through everything
for(x=0; x<amount; x++){
if(array[0] == 1){
printf("#0\n");
array[0]=0;
}
if(array[x]==1)
counter++;
if(counter == often){
printf("#%d\n", x);
array[x]=0;
counter=0;
}
return 0;
}
However, I need to continuously loop through until the entire array is done except for the last one. Mine stops after I loop through the array once. This is the output I have verse the output I want.
My output:
0
3
6
9
Wanted output:
0
3
6
9
4
8
5
2
7
Notice how the the wanted output loops through it again picking the third number that hasn't been picked yet. That is where I'm confused and how to fix this problem. Any guidance or information would be great, thanks.
You need to keep looping until all numbers have been printed,
for instance like this:
int total = amount;
counter = often - 1;
while (total > 0) {
for(x=0; x<amount; x++){
if(array[x]==1)
counter++;
if(counter == often){
printf("#%d\n", x);
array[x]=0;
counter=0;
total--;
}
}
}
Edit: The entire program:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int amount=0, often=0, counter=0, x;
printf("Size of Array? ");
scanf("%d", &amount);
printf("iteration size? ");
scanf("%d", &often);
// sets the array (1 means it exists)
int array[amount]; // Fixed typo in declaration
for(x=0; x<amount; x++)
array[x] = 1;
// the part that I'm confused on
// supposed to iterate through everything
int total = amount;
counter = often - 1;
while (total > 0) {
for(x=0; x<amount; x++){
if(array[x]==1)
counter++;
if(counter == often){
printf("#%d\n", x);
array[x]=0;
counter=0;
total--;
}
}
}
return 0;
}
Compilation:
gcc -std=c99 -Wall a.c -o a
Running the program:
Size of Array? 10
iteration size? 3
#0
#3
#6
#9
#4
#8
#5
#2
#7
#1
Let's start out with a loop which skips every three numbers:
for(int i = 0; i < amount; i += 3)
{
print(i);
array[i] = 0;
}
Now, this only seems to work for 0, 3, 6, 9.
We want to be able to start at the first existing value, and repeat this process until nothing remains.
So let's put another loop on the outside, to count how many items remain:
int total = amount;
while(total > 0)
{
for(int i = 0; i < amount; i += 3)
{
print(i);
array[i] = 0;
total--;
}
}
Good so far, but we still start at 0 every time. We want to start at a particular value, and skip until the 3rd number is reached.
int total = amount;
while(total > 0)
{
for(int i = getStartingIndex(array, 3); i < amount; i += 3)
{
while(array[i] == 0 && i < amount)
i++;
print(i);
array[i] = 0;
total--;
}
}
Let's define our getStartingIndex function:
int getStartingIndex(int array[], int skipCount)
{
int index = 0;
for(int i = 0; i < skipCount; i++)
{
while(array[index] == 0)
index++;
index++;
}
return index - 1;
}
Now, we start at the value specified, and print numbers until we reach amount. And then we go back to the beginning, but we start at the third unused number.
We need to keep the current step size, it will run from zero to the desired step size and each time we visit an index and mark it as visited we will reset that counter to zero. Our main loop will iterate over the array one by one, until there are no unvisited indices left. We make sure the index does not run out of bounds of the array, so when index hits the length of the array, we reset it to zero.
If you don't want the last element to be printed, just change the while loop's conditional to while (visited_count < total_length - 1)
int main() {
int array[10] = { 0 };
int total_length = 10;
int visited_count = 0;
int index = 0;
int step_size = 3;
int current_step = 3;
while (visited_count != total_length) /* while there are unvisited elements */
{
if (!array[index] && current_step == step_size) /* array[index] has value zero, and we are at the desired step count, so print that element and mark it as visited */
{
array[index] = 1;
visited_count++;
printf("%d\n", index);
current_step = 0; /* resetting the step counter */
}
index++; /* this is how we iterate over the array, incrementing it at each iteration */
if (index == total_length) /* checking for out-of-bounds of the array, if we hit the total length, the index should be reset. */
{
index = 0;
}
if (!array[index]) /* now that we have stepped through the array, we increment the step counter if that element is not visited. */
{
current_step++;
}
}
return 0;
}

Finding an element repeating n times in 2n size array. Will this solution work?

I have an array which has 2n elements where n elements are same and remaining n elements are all different. There are lot of other complex algorithms to solve this problem.
Question: Does this approach give the same result or I am wrong somewhere?
#include<stdio.h>
main()
{
int arr[10],i,res,count=0;
printf("Enter the array elements:\t");
for(i=0;i<10;i++)
scanf("%d",&arr[i]);
for(i=0;i<8;i++)
{
if(arr[i]==arr[i+1] || arr[i]==arr[i+2])
{
res=arr[i];
break;
}
else if(arr[i+1]==arr[i+2])
{
res=arr[i+1];
break;
}
}
for(i=0;i<10;i++)
if(arr[i]==res)
count++;
if(count==5)
printf("true, no. repeated is:\t%d",res);
else printf("false");
return 0;
}
In addition to failing for the trivial 2 element case, it also fails for 4 elements in this case:
a b c a
I think the easiest way to solve this problem is to solve the majority element problem on a[1] ... a[2*N-1], and if no majority is found, then it must be a[0] if a solution exists at all.
One solution to the majority element problem is to scan through the array counting up a counter whenever the majority candidate element is encountered, and counting down the counter when a number different from the candidate is encountered. When the counter is 0, the next element is automatically considered the new candidate.
If the counter is positive at the end of the scan, the candidate is checked with another scan over the array. If the counter is 0, or the second scan fails, there is no majority element.
int majority (int a[], int sz) {
int i, count1 = 0, count2 = 0;
int candidate = -1;
for (i = 0; i < sz; ++i) {
if (count1 == 0) candidate = i;
count1 += ((a[candidate] == a[i]) ? 1 : -1);
}
if (count1 > 0) {
for (i = 0; i < sz; ++i)
count2 += (a[candidate] == a[i]);
}
if (count2 <= sz/2) candidate = -1;
return candidate;
}
Your algorithm will fail when the array has only 2 elements. It does not handle trivial case

Resources