What is wrong in the following program? Why isn't it returning smallest element as i have tried to implement. Kindly spot the errors.Please tell me the errors regarding the logic and the syntax.
#include<stdio.h>
int ArrayMinimum(int a[], size_t size);
#define SIZE 9
int main()
{
int a[SIZE];
for (int i = 0; i < SIZE; i++)
{
a[i] = 1 + rand() % 99;
printf("%d ", a[i]);
}
printf("\n\nThe smallest number of the array is %d \n", ArrayMinimum(a, SIZE));
}
int ArrayMinimum(int a[], size_t size)
{
if (size == 1)
{
return a[0];
}
for (int i = 0; i <= size ; i++)
{
if (a[i] > a[i + 1])
{
int temp = a[i + 1];
a[i + 1] = a[i];
a[i] = temp;
}
}
int b[] = { 0 };
for (int y = 0; y < size; y++)
{
b[y] = a[y];
}
ArrayMinimum(b, size -1 );
}
Your function is defined to return an int; and it will return an integer value, if and only if size == 1.
If size has another value, it will not return anything at all!
Where is a second return statement?
There are other substantial problems, such as the size of Array b is not well defined, and you overwrite memory there.
You have't put #include <stdlib.h> at the top of your file and as a result, the functions you called were assumed to accept an unknown number of arguments and return a value of type int. This causes undefined behavior.
Implicit declaration of functions srand, rand and system
Also your ArrayMinimum() is wrong.The SIZE constant is always equal to 9 and it gets passed in this method and used by the size variable.Hence it will never satisfy the 'if' condition of this method.With that the BubbleSort mechanism you have implemented is also wrong.Your code just swaps the values only once.
Use this approach to find the minimum of the array:-
minimum = array[0];
for (c = 1; c < size; c++)
{
if (array[c] < minimum)
{
minimum = array[c];
location = c+1;
}
}
Your ArrayMinimum logic is attempting to sort the array and has logical issues with no return defined if size > 1.
If the purpose is to return the minimum value, a simpler logic can be as follows.
int ArrayMinimum(int a[], size_t size)
{
int min = a[0];
if (size == 1)
{
return a[0];
}
for (int i = 1; i < size ; i++)
{
if (a[i] < min)
{
min = a[i];
}
}
return min;
}
Related
I'm having a bit of trouble with this problem. The full text of the problem is as follows : "Write a function that returns a version of the given array of non-negative integers where each zero value in the
array is replaced by the smallest odd value to the right of the zero in the array. If there is no odd value to the right of the zero,
leave the zero as a zero."
Here is my code:
#include <stdio.h>
void lowestOdd(int num[], int size) {
int i, temp;
for (i = 0; i < size; i++) {
if (num[i] % 2 != 0 && num[i] < num[i + 1]) {
temp = num[i];
}
}
for (i = 0; i < size; i++) {
if (num[i] = 0) {
num[i] = temp;
}
}
}
void printArray(int array[], int size) {
int i;
for (i = 0; i < size; i++) {
printf("%d/n", array[i]);
}
}
int main() {
int i, size;
int myarr[20];
printf("What is the size of your array? \n");
scanf("%d", &size);
for (i = 0; i < size; i++) {
scanf("%d", &myarr[i]);
}
lowestOdd(myarr[20], size);
printArray(myarr[20], size);
return 0;
}
I've tried implementing pointers in the lowestOdd function, but to no avail. I do think they're necessary here, but I'm not really that good at pointers. The warnings I get are mostly 'warning: passing argument 1 of 'lowestOdd' makes pointer from integer without a cast [-Wint-conversion]'. Also, in my code, I haven't added the statements that would check whether the number is a zero or whether there are any odd values to the right of the zero.
In the declaration
int myarr[20];
myarr is the identifier - the name used to refer to the array itself. myarr has the type int [20].
When used in this expression
lowestOdd(myarr[20], size);
[20] is the array subscript operator, accessing index 20. This is index is out of bounds, as the valid indices for the type int [20] are 0 to 19. This out of bounds access will cause Undefined Behaviour.
This warning
warning: passing argument 1 of 'lowestOdd' makes pointer from integer without a cast [-Wint-conversion]
is given because, although an invalid index to access, the expression myarr[20] evaluates to an int. lowestOdd expects an int * as its first argument.
Similar to before, in
if (num[i] % 2 != 0 && num[i] < num[i + 1])
num[i + 1] will access num[size] when i is size - 1 (again, valid indices are 0 to size - 1).
This is assignment
if (num[i] = 0)
where you want a comparison
if (num[i] == 0)
Note that
scanf("%d", &size);
for (i = 0; i < size; i++) {
scanf("%d", &myarr[i]);
risks the same out of bounds access if the user enters a value greater than 20 for size.
Ignoring the out of bounds access for a moment, lowestOdd attempts to find the last occurrence of the smaller number from each pair of numbers in the array, where the left number must be odd.
It then replaces all zeroes in the array with this value.
There is a chance temp is never assigned anything, and thus has an indeterminate value.
This is not correct.
Here is an example program (using a variable-length array).
Note that the syntax array + i is equivalent to &array[i].
? : is the conditional operator: in a ? b : c, if a is non-zero the expression evaluates to b, else it evaluates to c.
#include <stdio.h>
int min(int a, int b)
{
return a < b ? a : b;
}
int find_lowest_odd(int *base, size_t len)
{
int value = 0;
for (size_t i = 0; i < len; i++)
if (base[i] & 1) /* base[i] % 2 != 0 */
value = value ? min(value, base[i]) : base[i];
return value;
}
void mutate_array(int *a, size_t len)
{
for (size_t i = 0; i < len; i++)
if (0 == a[i]) /* search from the next position */
a[i] = find_lowest_odd(a + i + 1, len - i - 1);
}
void print_array(int *a, size_t len)
{
for (size_t i = 0; i < len; i++)
printf("%d ", a[i]);
putchar('\n');
}
int main(void) {
size_t size;
printf("What is the size of your array?: ");
if (1 != scanf("%zu", &size))
return 1;
int array[size];
for (size_t i = 0; i < size; i++) {
printf("#%zu: ", i + 1);
if (1 != scanf("%d", array + i))
return 1;
}
print_array(array, size);
mutate_array(array, size);
print_array(array, size);
}
I/O:
What is the size of your array?: 10
#1: 0
#2: 2
#3: 0
#4: 5
#5: 3
#6: 0
#7: 7
#8: 2
#9: 0
#10: 0
0 2 0 5 3 0 7 2 0 0
3 2 3 5 3 7 7 2 0 0
Once you can try this.
Here's my naive approach. For every zero in the array it is checking for the smallest odd element from that position to the last index and storing it in variable named smaller. After checking it replaces the original value of that index with smaller one.
#include<stdio.h>
void lowestOdd(int *num, int size){
int i, j;
for(i = 0; i < size - 1; i++){
if (num[i] != 0) continue;
int smaller = 99998;
for(j = i+1; j < size; j++){
if (num[j] % 2 != 0 && num[j] < smaller) smaller = num[j];
}
if (smaller != 99998) num[i] = smaller;
}
}
void printArray(int *array, int size){
int i;
for (i=0; i<size; i++){
printf("%d\n", array[i]);
}
}
int main()
{
int i, size;
int myarr[20];
printf("What is the size of your array? \n");
scanf("%d", &size);
for (i=0; i<size; i++){
scanf("%d", &myarr[i]);
}
lowestOdd(myarr, size);
printArray(myarr, size);
return 0;
}
here is my code and it always output -1 and I didn't know why. any help?
Input
The first line contains an integer t (1≤t≤104) — the number of test cases.
The first line of each test case contains an integer n (1≤n≤2⋅105) — the length of the array.
The second line of each test case contains n integers a1,a2,…,an (1≤ai≤n) — the elements of the array.
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.
Output
For each test case, print any value that appears at least three times or print -1 if there is no such value.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n, size,*arr, *frr,count,*ptr,g,s;
scanf("%d", &n);
ptr = (int*)malloc(n * sizeof(int));
for (int i = 0;i < n; i++)
{
scanf("%d",&size);
arr = (int*)malloc(size * sizeof(int));
frr = (int*)malloc(size * sizeof(int));
for(int j = 0; j < size; j++)
{
scanf("%d",arr+j);
*(frr + j) = -1;
}
if(size >= 3)
{
for (g = 0; g < size ; g++)
{
count=1;
for(s = g + 1; s < size;s++)
{
if(*(arr + g) == *(arr + s))
{
count++;
*(frr+s) = 0;
}
}
if(*(frr+g) != 0 )
{
*(frr+g) = count;
}
if(*(frr+g) >= 3)
{
*(ptr+i) = *(arr + g);
}else
{
*(ptr+i) = -1;
}
}
}else
{
*(ptr+i) = -1;
}
free(arr);
free(frr);
}
for(int j = 0;j<n;j++)
{
printf("%d\n",*(ptr+j));
}
}
The problem is that you set *(ptr+i) to -1 for each element of the array. This means that a later element of the array that is not repeated three times will reset *(ptr+i) to -1.
Change this
if(*(frr+g) >= 3)
{
*(ptr+i) = *(arr + g);
}
else
{
*(ptr+i) = -1;
}
to this
if(*(ptr+i) == -1 && *(frr+g) >= 3)
{
*(ptr+i) = *(arr + g);
}
and at the beginning add this
ptr = (int*)malloc(n * sizeof(int));
for (int i = 0;i < n; i++)
{
*(ptr + i) = -1;
But as has already been said in the comments you do not need either the ptr array or the frr array. You only run one test at a time so there is no need to keep all the test results before you print any of them out. And you only need to save the frequency of the current element you are testing, so you don't need an array for that either.
And make your code readable, change *(arr + g) to arr[g]. They both work exactly the same.
For starters this array allocation
ptr = (int*)malloc(n * sizeof(int));
does not make a sense. For each given sequence of numbers you can at once output whether the sequence contains three equal elements or not without storing this information in the allocated array.
Also allocating this auxiliary array
frr = (int*)malloc(size * sizeof(int));
makes the code unsafe and inefficient.
It does not make a sense to travers the array if an element that occurs already three times is found.
Otherwise this code snippet
if(*(frr+g) >= 3)
{
*(ptr+i) = *(arr + g);
}else
{
*(ptr+i) = -1;
}
for elements that are present in the tail of the array arr can incorrectly
set the value ptr[i] to -1 though early there was already found a preceding element that occurs three times.
Without the redundant arrays pointed to by the pointers ptr and frr the program can look the following way
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
size_t t = 0;
scanf( "%zu", &t );
while (t--)
{
size_t n = 0;
scanf( "%zu", &n );
int result = -1;
if (n)
{
int *a = malloc( n * sizeof( int ) );
for (size_t i = 0; i < n; i++)
{
scanf( "%d", a + i );
}
for (size_t i = 2; result == -1 && i < n; i++)
{
int count = 1;
for (size_t j = i; count != 3 && j-- != 0; )
{
if (a[j] == a[i]) ++count;
}
if (count == 3) result = a[i];
}
free( a );
}
printf( "%d\n", result );
}
}
I would approach the problem altogether differently. Since the range of the elements is not explicitly bounded, it is a bit tricksome to manage a frequency table. But the maximum number of elements in each test array is pretty small, so it is feasible to
declare an array large enough to hold all the elements of any test case
for each test case,
read all the elements into the (one) array
sort the array (qsort(), or roll your own insertion or selection sort)
scan the sorted array to easily detect and report values that appear at least thrice
I'm a beginner in programing so please be understanding with my code.. I'm working on a problem set where I have to implement a selection sort using recursion. I feel like it should work but I get an error message and i can't figure out why.
the problem set consists in that I use a recursive function where i have to look for the largest number in an array, store it in the last position and sort the entire array using this method.
int array[n];
printf ("enter numbers: ");
for (i = 0; i < n; i++)
{
scanf ("%i", &array[i]);
}
selection_sort(n, array);
printf ("sorted numbers: ");
for (i = 0; i < n; i++)
{
printf ("%i", array[i]);
}
return 0;
here is the recursive function that i'd like to implement.
i used curpos to store the position of the largest number,
lastpos to store the location of the last element in the array,
and a tmp variable to store the largest number.
and this is the error message that i get.
.c:67:34: error: incompatible integer to pointer conversion passing 'int' to parameter of type 'int *'; take the address with & [-Werror,-Wint-conversion]
return selection_sort(n, array[n-1]);
^~~~~~~~~~
&
if (n <= 0)
{
return 1;
}
else
{
for (i = 0; i < n; i++)
{
if (tmp <= array[i]) //look for the largest number and update it into tmp
{
tmp = array[i];
curpos = array[i]; //remember the location of the current largestnumber
}
}
lastpos = array[n-1]; // save the last element into a variable before swap
array[n-1] = tmp; // put the largest number into the last element
curpos = lastpos; // put the last element before swap into the changed location.
return selection_sort(n, array[n-1]);
}
}
I hope you can give me a hand to understand the recursion better. thank you so much in advance.
The return value is a red herring. You don't use it so your function may as well be void.
if (n <= 0)
{
return 1;
}
The second thing to notice is that you can't pass an array to a function. You are passing a pointer to the beginning of the array. This is good, because otherwise you wouldn't be able to sort it.
else
{
for (i = 0; i < n; i++)
{
Right here is an issue. You haven't initialised tmp and curpos. You need to do that before the loop.
if (tmp <= array[i]) //look for the largest number and update it into tmp
{
tmp = array[i];
curpos = array[i]; //remember the location of the current largestnumber
}
}
lastpos = array[n-1]; // save the last element into a variable before swap
array[n-1] = tmp; // put the largest number into the last element
curpos = lastpos; // put the last element before swap into the changed location.
Finally, right here you have the right idea, but the wrong notation. You want to pass the same array, but 1 less element
return selection_sort(n, array[n-1]);
Should be:
return selection_sort(n-1, array);
}
The error message means that in this call
return selection_sort(n, array[n-1]);
you are passing an element of the array of the type int with the index n-1. But the function expects a pointer of the type int *.
Moreover the value of the first parameter is always the same and equal to n.
Also the return type of the function does not make a sense. The function should be declared with the return type void.
Also you need to swap two elements if within the array there is found an element that is greater than the last element.
The function can be declared and defined the following way
void selection_sort( int a[], size_t n )
{
if (!( n < 2 ))
{
size_t i = --n;
for (size_t j = n; j-- != 0; )
{
if (a[i] < a[j]) i = j;
}
if (i != n)
{
int tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
selection_sort( a, n );
}
}
Here is a demonstration program.
#include <stdio.h>
void selection_sort( int a[], size_t n )
{
if (!( n < 2 ))
{
size_t i = --n;
for (size_t j = n; j-- != 0; )
{
if (a[i] < a[j]) i = j;
}
if (i != n)
{
int tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
selection_sort( a, n );
}
}
int main( void )
{
int a[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
const size_t N = sizeof( a ) / sizeof( *a );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
selection_sort( a, N );
for (size_t i = 0; i < N; i++)
{
printf( "%d ", a[i] );
}
putchar( '\n' );
}
The program output is
9 8 7 6 5 4 3 2 1 0
0 1 2 3 4 5 6 7 8 9
I'm trying to write a program that will sort an array of 20 random numbers by the sums of their digits.
For example:
"5 > 11" because 5 > 1+1 (5 > 2).
I managed to sort the sums but is it possible to return to the original numbers or do it other way?
#include <stdio.h>
void sortujTab(int tab[], int size){
int sum,i;
for(int i=0;i<size;i++)
{
while(tab[i]>0){//sum as added digits of an integer
int p=tab[i]%10;
sum=sum+p;
tab[i]/=10;
}
tab[i]=sum;
sum=0;
}
for(int i=0;i<size;i++)//print of unsorted sums
{
printf("%d,",tab[i]);
}
printf("\n");
for(int i=0;i<size;i++)//sorting sums
for(int j=i+1;j<=size;j++)
{
if(tab[i]>tab[j]){
int temp=tab[j];
tab[j]=tab[i];
tab[i]=temp;
}
}
for(int i=0;i<20;i++)//print of sorted sums
{
printf("%d,",tab[i]);
}
}
int main()
{
int tab[20];
int size=sizeof(tab)/sizeof(*tab);
for(int i=0;i<=20;i++)
{
tab[i]=rand()%1000;// assamble the value
}
for(int i=0;i<20;i++)
{
printf("%d,",tab[i]);//print unsorted
}
printf("\n");
sortujTab(tab,size);
return 0;
}
There are two basic approach :
Create a function that return the sum for an integer, say sum(int a), then call it on comparison, so instead of tab[i] > tab [j] it becomes sum(tab[i]) > sum (tab[j])
Store the sum into a different array, compare with the new array, and on swapping, swap both the original and the new array
The first solution works well enough if the array is small and takes no extra memory, while the second solution didn't need to repeatedly calculate the sum. A caching approach is also possible with map but it's only worth it if there are enough identical numbers in the array.
Since your numbers are non-negative and less than 1000, you can encode the sum of the digits in the numbers itself. So, this formula will be true: encoded_number = original_number + 1000 * sum_of_the_digits. encoded_number/1000 will decode the sum of the digits, and encoded_number%1000 will decode the original number. Follow the modified code below. The numbers enclosed by parentheses in the output are original numbers. I've tried to modify minimally your code.
#include <stdio.h>
#include <stdlib.h>
void sortujTab(int tab[], int size)
{
for (int i = 0; i < size; i++) {
int sum = 0, n = tab[i];
while (n > 0) { //sum as added digits of an integer
int p = n % 10;
sum = sum + p;
n /= 10;
}
tab[i] += sum * 1000;
}
for (int i = 0; i < size; i++) { //print of unsorted sums
printf("%d%c", tab[i] / 1000, i < size - 1 ? ',' : '\n');
}
for (int i = 0; i < size; i++) { //sorting sums
for (int j = i + 1; j < size; j++) {
if (tab[i] / 1000 > tab[j] / 1000) {
int temp = tab[j];
tab[j] = tab[i];
tab[i] = temp;
}
}
}
for (int i = 0; i < size; i++) { //print of sorted sums
printf("%d(%d)%c", tab[i] / 1000, tab[i] % 1000, i < size - 1 ? ',' : '\n');
}
}
int main(void)
{
int tab[20];
int size = sizeof(tab) / sizeof(*tab);
for (int i = 0; i < size; i++) {
tab[i] = rand() % 1000; // assamble the value
}
for (int i = 0; i < size; i++) {
printf("%d%c", tab[i], i < size - 1 ? ',' : '\n'); //print unsorted
}
sortujTab(tab, size);
return 0;
}
If the range of numbers doesn't allow such an encoding, then you can declare a structure with two integer elements (one for the original number and one for the sum of its digits), allocate an array for size elements of this structure, and initialize and sort the array using the digit sums as the keys.
You can sort an array of indexes rather than the array with data.
#include <stdio.h>
//poor man's interpretation of sumofdigits() :-)
int sod(int n) {
switch (n) {
default: return 0;
case 5: return 5;
case 11: return 2;
case 1000: return 1;
case 9: return 9;
}
}
void sortbyindex(int *data, int *ndx, int size) {
//setup default indexes
for (int k = 0; k < size; k++) ndx[k] = k;
//sort the indexes
for (int lo = 0; lo < size; lo++) {
for (int hi = lo + 1; hi < size; hi++) {
if (sod(data[ndx[lo]]) > sod(data[ndx[hi]])) {
//swap indexes
int tmp = ndx[lo];
ndx[lo] = ndx[hi];
ndx[hi] = tmp;
}
}
}
}
int main(void) {
int data[4] = {5, 11, 1000, 9};
int ndx[sizeof data / sizeof *data];
sortbyindex(data, ndx, 4);
for (int k = 0; k < sizeof data / sizeof *data; k++) {
printf("%d\n", data[ndx[k]]);
}
return 0;
}
I implement Sieve of eratosthenes and it works fine. But if I increase the MAX value to something like 50000 the Application crash with a unhandled win32 exception. I think this happened because of a stackoverflow.
Now my Question is how do I prevent this?
#define MAX 50000
void Sieb_des_Eratosthenes()
{
char Zahlen[MAX + 1] = {0};
int i, j, x;
for(i = 2; i <= MAX; i++)
{
if(Zahlen[i] == 0)
{
Zahlen[i] = 1;
for(j = i * i; j <= MAX; j += i)
{
Zahlen[j] = -1;
}
}
}
}
My idea was to allocate memory but this doesn't work
#define MAX 50000
int Sieb_des_Eratosthenes()
{
int i, j, x;
char *array;
array = malloc((MAX + 1) * sizeof(*array));
if (array==NULL) {
printf("Error allocating memory!\n");
return -1; //return with failure
}
for(i = 2; i <= MAX; i++)
{
if(array[i] == 0)
{
array[i] = 1;
for(j = i * i; j <= MAX; j += i)
{
array[j] = -1;
}
}
}
}
The original problem in your function failing is in this for loop.
for(j = i * i; j <= MAX; j += i)
when i gets equal or larger than 46349 the result i * i overflows and j gets the value of -2146737495 and then fails at Zahlen[j] = -1;
While all the other answers are true wrt. the actual cause (integer overflow), you simply missed some implementation details provided by the pseudo code in the wiki. The following works:
Use calloc to allocate the memory. Then, all values are initialized to 0 which means true in the sense of the wiki pseudo code.
In the outer loop, only loop until sqrt(MAX) - see the pseudo code in the wiki article.
In the inner loop, mark all multiples of i with 1 (false in the sense of the wiki pseudo code).
for(i = 2; i <= sqrt(MAX); i++) {
if(array[i] == 0) { // "true"
for(j = i*i; j <= MAX; j += i) {
array[j] = 1; // "false"
}
}
}
Then, all elements which are still 0 are prime numbers.
In addition, it is not necessary to use (signed) int - all numbers are positive, so you should use unsigned int.
With this approach, you should be able to use the whole range of an unsigned int for the MAX value (up to 4294967295 if unsigned int is 32 bit)
an int can only hold a max of -2^31 to 2^31:
http://en.wikipedia.org/wiki/Integer_(computer_science)
your overflowing the int