Unexpected out - Finding Maximum and Second Maximum - c

I am trying to implement a simple tournament in C.
#include <stdio.h>
int main(void) {
int tourn[100], n, i;
printf("Give n:");
scanf("%d", &n);
printf("\n n = %d \n", n);
for(i = n; i <= (2*n)-1; i++)
scanf("%d", &tourn[i]);
build(tourn, n);
printf("\n Max = %d \n",tourn[1]);
printf("\n Next Max = %d \n",nextmax(tourn, n));
}
void build(int tourn[], int n) {
int i;
for(i = 2*n-2; i > 1; i = i-2)
tourn[i/2] = max(tourn[i], tourn[i+1]);
}
int nextmax(int tourn[],int n) {
int i = 2;
int next;
next = min(tourn[2], tourn[3]);
while(i <= 2*n-1) {
if(tourn[i] > tourn[i+1]) {
next = max(tourn[i+1], next);
i = 2*i;
}
else {
next = max(tourn[i], next);
i = 2*(i+1);
}
}
return(next);
}
int max(int i,int j) {
if(i > j)
return i;
else
return j;
}
int min(int i,int j) {
if(i < j)
return i;
else
return j;
}
The output for n = 5 and
1 2 3 4 5
is
Max = 4195048
Next Max = 32588
and this output varies each time by a small amount!
if I place a test printf command before the build function, it doesn't execute.
Can someone find the error/explain the output?
Thanks :)

Your code seems pretty broken to me. you don't mind to address beyond your array boundaries, which is a good way of producing random results:
while(i <= 2*n-1){
if(tourn[i]>tourn[i+1]){
next = max(tourn[i+1],next);
i=2*i;
} else {
next = max(tourn[i],next);
i=2*(i+1);
}
}
Your (logical) array is of size 2n. if i reaches the "highest" value, you test tourn[i + 1], which is tourn[2n].

Related

The fastest and most efficient way to find the number of distinct elements of a 1D array

So I'm very new to programming and the C language, and I would like to find the simplest, fastest, and most efficient way to count all the distinct elements of a 1D array. This was actually for a school assignment, but I've been stuck on this problem for days, since my program was apparently too slow for the online judge and it got a TLE. I've used regular arrays and dynamically allocated arrays using malloc, but neither worked.
Anyways, here's the latest code of it(using malloc):
#include <stdio.h>
#include <stdlib.h>
int distinct(int *arr, int N){
int j, k, count = 1;
for(j = 1; j < N; j++){
for(k = 0; k < j; k++){
if(arr[j] == arr[k]){
break;
}
}
if(j == k){
count++;
}
}
return count;
}
int main(){
int T, N, i = 0;
scanf("%d", &T);
do{
scanf("%d", &N);
int *arr;
arr = (int*)malloc(N * sizeof(int));
for(int j = 0; j < N; j++){
scanf("%d", &arr[j]);
}
int count = distinct(arr, N);
printf("Case #%d: %d\n", i + 1, count);
i++;
}while(i < T);
return 0;
}
The most efficient way depends on too many unknown factors. One way is to sort the array and then to count distinct elements in there, skipping the duplicates as you go. If you have sorted the array and gotten this:
1 1 1 1 2 2 2 2 3 3
^ ^ ^
+-skip--+-skip--+-- end
... you can easily see that there are 3 distinct values in there.
If you don't have a favourite sorting algorithm handy, you could use the built-in qsort function:
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
Example:
#include <stdio.h>
#include <stdlib.h>
int compar(const void *l, const void *r) {
const int* lhs = l;
const int* rhs = r;
if(*lhs < *rhs) return -1; // left side is less than right side: -1
if(*lhs > *rhs) return 1; // left side is greater than right side: 1
return 0; // they are equal: 0
}
int distinct(int arr[], int N){
// sort the numbers
qsort(arr, N, sizeof *arr, compar);
int count = 0;
for(int i=0; i < N; ++count) {
int curr = arr[i];
// skip all numbers equal to curr as shown in the graph above:
for(++i; i < N; ++i) {
if(arr[i] != curr) break;
}
}
return count;
}
int main() {
int T, N, i = 0;
if(scanf("%d", &T) != 1) return 1; // check for errors
while(T-- > 0) {
if(scanf("%d", &N) != 1) return 1;
int *arr = malloc(N * sizeof *arr);
if(arr == NULL) return 1; // check for errors
for(int j = 0; j < N; j++){
if(scanf("%d", &arr[j]) != 1) return 1;
}
int count = distinct(arr, N);
free(arr); // free after use
printf("Case #%d: %d\n", ++i, count);
}
}

"assignment makes integer from pointer without a cast"?

I'm really new to this. I've never done anything like this so I'm having issues with this code. I was given a template to write my code in separate functions like this, although I added the findPos one myself. I'm getting the "assignment makes integer from pointer without a cast" warning and also my max, min, sum, avg, and position of max and min are obviously not coming out to the right numbers. I was just wondering if anyone can lead me in the right direction.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int findMin(int arr[], int size);
int findMax(int arr[], int size);
int findSum(int arr[], int size);
int findPos(int arr[], int size);
int size;
int i;
int max;
int min;
int avg;
int sum;
int pos;
int main()
{
srand(time(0));
printf("Enter an integer: ");
scanf("%d", &size);
int arr[size];
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
avg = sum / size;
printf("max:%7d\tpos:%d\t\n", max, pos);
printf("min:%7d\tpos:%d\t\n", min, pos);
printf("avg:%7d\n", avg);
printf("sum:%7d\n", sum);
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
return 0;
}
int findMin(int arr[], int size)
{
min = arr[0];
for (i = 0; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
int findMax(int arr[], int size)
{
max = arr[0];
for (i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
int findSum(int arr[], int size)
{
sum = 0;
for (i = 0; i < size; i++) {
sum = sum + arr[i];
}
return sum;
}
int findPos(int arr[], int size)
{
for (i = 0; i < size; i++) {
pos = i;
}
return pos;
}
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
You're assigning function pointer, not return value, to integer variable. You have to do something like max = findMax(arr, size). Also in that case, you should assign values to arr before calling it.
There are a couple of issues with the code. Let me iterate through the same
Populating Data in Created Array
Since the data has to present the created array before performing any operations,
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
this snippet should be reordered and moved above the function calls and just after the int arr[size];
Function Calls
All your functions, namely findMax,findMin,findPos,findSum is expecting two parameters
arr - array you have created
size - the size value read from scanf()
Assuming you want to store the return value from the function in the main int variables max,min,pos,sum,avg
the statements
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
should be replaced with function calls like
max = findMax(arr, size);
min = findMin(arr, size);
pos = findPos(arr, size);
sum = findSum(arr, size);
The Final Main code will be
int main()
{
srand(time(0));
printf("Enter an integer: ");
scanf("%d", &size);
int arr[size];
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
max = findMax(arr, size);
min = findMin(arr, size);
pos = findPos(arr, size);
sum = findSum(arr, size);
avg = sum / size;
printf("max:%7d\tpos:%d\t\n", max, pos);
printf("min:%7d\tpos:%d\t\n", min, pos);
printf("avg:%7d\n", avg);
printf("sum:%7d\n", sum);
return 0;
}

How can I pass values from one function to another?

I have created a program that takes in input "n" numbers that the user chooses and then prints the most repeated one, but I have a problem with passing the values between the functions so it gives me 0 as a result. How can I solve it?
void most_present_number(int array[]);
int read_numbers(int array[]);
int main() {
int array[400];
most_present_number(array);
return 0;
}
void most_present_number(int array[]){
read_numbers(array);
int i = 0;
int Max = 0;
int Current_number = vettore[0];
int Current_number_counter = 0;
int most_present_number = 0;
int most_present_number_counter = 0;
while (i < Max) {
if (array[i] == Current_number) {
Current_number_counter++;
i++;
} else {
if (Current_number_counter > most_present_number_counter){
most_present_number = Current_number;
most_present_number_counter = Current_number_counter;
}
Current_number = array[i];
Current_number_counter = 1;
i++;
}
}
printf("The most present number is %d which is repeated %d times\n", most_present_number,
most_present_number_counter);
}
int read_numbers(int array[]){
int Max = 0;
int i = 0;
printf("Insert the array lenght\n");
scanf("%d", &Max);
while (i < Max) {
printf("Insert the numbers\n");
scanf("%d", &array[i]);
i++;
}
return Max;
}
You have Max = 0 in most_present_number(), so the while loop stops immediately.
read_numbers() returns Max, so you can use this to initialize Max in most_present_number().
void most_present_number(int array[], int Max);
int read_numbers(int array[]);
int main() {
int array[400];
int size;
most_present_number(array);
return 0;
}
void most_present_number(int array[]){
int Max = read_numbers(array);
int i;
int Current_number = array[0];
int Current_number_counter = 0;
int most_present_number = 0;
int most_present_number_counter = 0;
for (i = 0; i < Max; i++) {
if (array[i] == Current_number) {
Current_number_counter++;
} else {
if (Current_number_counter > most_present_number_counter){
most_present_number = Current_number;
most_present_number_counter = Current_number_counter;
}
Current_number = array[i];
Current_number_counter = 1;
}
}
printf("The most present number is %d which is repeated %d times\n", most_present_number,
most_present_number_counter);
}
int read_numbers(int array[]){
int Max = 0;
int i = 0;
printf("Insert the array lenght\n");
scanf("%d", &Max);
while (i < Max) {
printf("Insert the numbers\n");
scanf("%d", &array[i]);
i++;
}
return Max;
}
Note also that your algorithm assumes that all the equal numbers will be together in the array. If they can be mixed up, you need a very different design. You need another array where you keep the counts of each number. Then at the end you find the entry in this array with the highest count.

Dynamic Programming - Minimum Coin caching

Earlier I posted a question about the coin vending machine problem (the minimum number of coins required). Turns out the issue was a typo in a for loop, so now the program works. The original question was this:
As the programmer of a vending machine controller your are required to compute the minimum number of coins that make up the required change to give back to customers. An efficient solution to this problem takes a dynamic programming approach, starting off computing the number of coins required for a 1 cent change, then for 2 cents, then for 3 cents, until reaching the required change and each time making use of the prior computed number of coins. Write a program containing the function ComputeChange(), that takes a list of valid coins and the required change. This program should repeatedly ask for the required change from the console and call ComputeChange() accordingly. It should also make use of “caching”, where any previously computed intermediate values are retained for subsequent look-up.
The issue is that the code makes use of recursion, so it takes quite a long time to evaluate large values. Making use of caching should improve the issue, but I have no idea how to go about it. The code can be found below.
#include <stdio.h>
#include <limits.h>
int computeChange(int[],int,int);
int min(int[],int);
int main(){
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(cur)/sizeof(int);
int v;
printf("Enter a value in euro cents: ");
scanf("%d", &v);
printf("The minimum number of euro coins required is %d", computeChange(cur, v, n));
return 0;
}
int computeChange(int cur[], int v, int n){
if(v < 0)
return INT_MAX;
else if(v == 0)
return 0;
else{
int possible_mins[n], i;
for(i = 0; i < n; i++){
possible_mins[i]=computeChange(cur, v-cur[i], n);
}
return 1+min(possible_mins, n);
};
}
int min(int a[], int n){
int min = INT_MAX, i;
for(i = 0; i < n; i++){
if((a[i]>=0) && (a[i]< min))
min = a[i];
}
return min;
}
With your existing code:
#include <stdio.h>
#include <limits.h>
int computeChange(int[],int,int);
int min(int[],int);
void initChange ();
int change [MAX]; //used for memoization
int main(){
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(cur)/sizeof(int);
int v;
initChange ();
printf("Enter a value in euro cents: ");
scanf("%d", &v);
printf("The minimum number of euro coins required is %d", computeChange(cur, v, n));
return 0;
}
void initChange () {
int i =0;
for (i = 0; i < MAX; i++) {
change[i] = INT_MAX;
}
}
int computeChange(int cur[], int v, int n){
if(v < 0)
return INT_MAX;
else if(v == 0)
return 0;
else{
if (change[v] == INT_MAX) {
int possible_mins[n], i;
for(i = 0; i < n; i++){
possible_mins[i]=computeChange(cur, v-cur[i], n);
}
change[v] = 1 + min(possible_mins, n); // memoization
}
return change[v];//you return the memoized value
};
}
int min(int a[], int n){
int min = INT_MAX, i;
for(i = 0; i < n; i++){
if((a[i]>=0) && (a[i]< min))
min = a[i];
}
return min;
}
I already posted a solution using loops in your previous question. I will post it again here:
So the below is the code snippet for your problem using memoization and dynamic programming. The complexity is O(Val*numTypesofCoins).
In the end, change[val] will give you the min number of coins for val.
int main (void) {
int change [MAX];
int cur[]={1,2,5,10,20,50,100,200};
int n = sizeof(a)/sizeof(int);
int val; //whatever user enters to get the num of coins required.
printf("Enter a value in euro cents: ");
scanf("%d", &val);
for (i=0; i <= val; i++) {
change[i] = INT_MAX;
}
for (i=0; i < n; i++) { // change for the currency coins should be 1.
change[cur[i]] = 1;
}
for (i=1; i <= val; i++) {
int min = INT_MAX;
int coins = 0;
if (change[i] != INT_MAX) { // Already got in 2nd loop
continue;
}
for (j=0; j < n; j++) {
if (cur[j] > i) { // coin value greater than i, so break.
break;
}
coins = 1 + change[i - cur[j]];
if (coins < min) {
min = coins;
}
}
change[i] = min;
}
}

Recursive selectionsort algorithm exiting, why?

I got the task to write a recursive selectionsort algorithm, which i did.
The algorithm works fine until i increase the array size to more than 150 elements.
After i increased the elements, the algorithm stops working and exits with a "strange" (-1073741571 (0xC00000FD)) exit code.
I guess that somewhere i exceed the data range. But even after staring an hour at my code i cannot find where. Using the debugging fuction does not give me any hint.
Can someone help me why this code isn't working with more than 150 elements?
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define MAX 500
// print the array and count the number of reoccurring characters and print it.
void ausgabe(int *array, size_t size)
{
int i;
int prev_char = INT_MAX, cur_char, count = 0;
for (i = 0; i < size; i++)
{
cur_char = array[i];
if (cur_char == prev_char)
{
printf("%c", array[i]);
prev_char = cur_char;
count++;
}
else
{
printf(" Count = %i\n%c", count, array[i]);
prev_char = cur_char;
count = 0;
}
}
printf(" Count = %i", count);
}
//Fill the array with characters from A to Z and start over
void fill_field(int *array, size_t size)
{
int i, j = 0;
for (i = 0; i < size; i++)
{
if ( j > 25)
j = 0;
array[i] = 65 + j++;
}
}
//Recursive selectionsort algorithm.
void selection_sort(int *source, size_t size)
{
static int min = INT_MAX, position = 0, start_pos = 0, temp, found;
if ( position < size)
{
if (min > source[position])
{
min = source[position];
found = position;
}
position++;
selection_sort(source, size);
}
else
{
temp = source[start_pos];
source[start_pos] = min;
source[found] = temp;
position = start_pos + 1;
start_pos++;
min = INT_MAX;
if ( position < size )
selection_sort(source, size);
}
}
int main(void)
{
int array[MAX];
fill_field(array, MAX);
ausgabe(array, MAX);
selection_sort(array, MAX);
ausgabe(array, MAX);
return 0;
}

Resources