Comparing numbers inside of an array - c

Values are entered into an array by the user and then i have this For Loop to compare the numbers once they have all been entered. What i'm trying to do is find the first larger number in the array.
i = 0;
next = a[++i];
for (i = 0; i < len; i++)
{
if (a[i] > a[next])
{
++next;
if (a[i] < a[next])
{
printf("%d is the first larger number.", a[i]);
}
}
}
When I debug my program I see that when "i" is being compared to a[next] its not taking the value of the number inside that position "i" of the array. i've attempted using "i" instead of a[i] when starting my If statements but that doesn't seem to fix the issue.
Here is my Corrected code. made a few more minor changes just for practice
#include <stdio.h>
int main(int argc, const char * argv[])
{
const int len = 4;
int a[len];
int i;
int j = a[i-1];
for (i = 0; i < len; i++) {
printf("Enter a number:");
scanf("%d", &a[i]);
}
i = 0;
for (i = 1; i < len; i++) {
if (a[i] > a[j])
{
printf("%d is the first larger number.", a[i]);
break;
}
}
}

I think you're looking for the first place where the array is not decreasing; i.e., the index of the first element i such that a[i] > a[i-1].
for (i = 1; i < len; i++) {
if (a[i] > a[i-1]) {
printf("%d is the first larger number", a[i]);
break;
}
}
A new version, printing out the first part of the sequence:
for (i = 1; i < len; i++) {
if (a[i] > a[i-1]) {
printf("\n%d is the first larger number", a[i]);
break;
}
printf("%d ", a[i]);
}

Whatever what you are trying to achieve!! you never say:
next = a[++i];
than
a[i] > a[next] !! a[next] can be beyond the size of your array
EX:
A[] = {0, 7, 2, 3, 1}
next = A[1] = 7
A[next] = A[7] = !! //what u think it is?

Assuming that you are looking for the first local maximum, one solution is to declare a variable called best to keep track of the largest number seen so far. Set best to the first element of the array a[0]. Then check for the first element of the array that is less than best.
best = a[0];
for ( i = 1; i < len; i++ )
{
if ( a[i] > best )
best = a[i];
else if ( a[i] < best )
break;
}
printf( "%d is the first larger number.\n", best );

Related

Remove the last comma from c loop

i have the belowo loop in c that print the prime number
for(int i = 2; i<=arraySize; i++)
{
//If arraySize is not 0 then it is prime
if (numbers[i]!=0)
printf("%d,",numbers[i]);
}
the out put after enter 50 for example is
2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,
i want to to not print the last comma how i can do it
i tried this code but not working
printf("%d%s", numbers[i], (i !=arraySize-1) ? "," : "");
Instead of printing a comma after each number, print it before. Then you can use a variable to tell if this is the first number being printed, and not print the comma.
first=true;
for(int i = 2; i<=arraySize; i++)
{
//If numbers[i] is not 0 then it is prime
if (numbers[i]!=0) {
printf("%s%d", (first ? "" : ","), numbers[i]);
first = false;
}
}
I like both the other answers but just want to throw in this error prone variant on the same theme.
_Bool first = true;
for (int i = 2; i <= arraySize; i++) {
if (numbers[i] != 0) {
printf(",%d" + first, numbers[i]);
first = false;
}
}
If first is true the actual formatting string will become "%d". If it's false it'll become ",%d".
Simple: Use a pointer to the "prefix" string, printed AHEAD of the next value:
char *sep = "";
for(int i = 2; i <= arraySize; i++ ) {
if( numbers[i] ) {
printf( "%s%d", sep, numbers[i] );
sep = ", "; // I added a SP, too
}
}
Here's an alternative that uses a "limited scope" variable to index a static string. For clarity in this example, the array boundaries have been adjusted.
int main( void ) {
int numbers[] = { 1, 1, 4, 8, 9, 0, 7 };
int arraySize = sizeof numbers/sizeof numbers[0];
for( int i = 0, out = 0; i < arraySize; i++ )
if( numbers[i] )
printf("%s%d", &","[!out++], numbers[i] );
return 0;
}
The negated boolean post-incrementing value of out provides the address of the '\0' to the first instance, then the address of "," in subsequent instances.
1,1,4,8,9,7
The answers already here are fine, but I'd like to add a "simpler" solution. Simpler in that it doesn't require any further logic or extra variables. It does, however, require that you know that the first number is non-zero.
printf("%d", numbers[2]);
for (int i = 3; i < arraySize; i++)
{
if (numbers[i] != 0)
printf(",%d", numbers[i]);
}
I think the other answers overcomplicates things. I don't see any reason to have a test for every iteration in the loop. Instead, I'd simply do the special case first:
printf("%d", numbers[2]);
for (int i = 3; i <= arraySize; i++) {
if (numbers[i]!=0)
printf(",%d", numbers[i]);
}
This will however need some additional code to correctly handle the case where arraySize is lower than 3.
But I would choose another approach from the beginning, and that is writing a good function for printing an array. Could look like this:
void printArray(const int *array, int size) {
putchar('['); // Of course this is optional
if(size > 0) {
printf("%d", array[0]);
for(int i=1; i<size; i++)
printf(",%d", array[i]);
}
putchar(']'); // And this too
}
and then something like this:
int convertArray(const int *numbers, int *array, int size) {
int ret = 0;
for(int i=0; i<size; i++) {
if(number[i] != 0) {
array[ret] = numbers[i];
ret++;
}
}
return ret;
}

How to stop the loop after printing one?

So here is the problem: Write a program that accept an integer n, print out the largest number but smaller or equal n that is the product of two consecutive even number. Example: Input: 12, Output: 8 ( 2x4 )
Here is my code :
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d ", i);
break;
}
}
}
return 0;
}
So if i input 20, it will print out 8 and 0 instead of 8, if i input 30, it will print out 24,8 and 0 instead of just 24. How do i make it stop after printing out the first number that appropriate ?
You need to stop an outer loop from processing, for example by using a boolean flag (meaning "solution found, we finish work") or a goto statement.
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int solutionFound = 0;
for (int i = n; i >= 0; i--) {
// this could also be put into for's condition i.e. "i >= 0 && !solutionFound"
if (solutionFound) {
break;
}
for (int j = 0; j <= n; j = j + 2) {
if ( i == j * (j+2) ) {
printf("%d ", i);
solutionFound = 1;
break;
}
}
}
return 0;
}
EDIT: immediate return as noted in the comments is also a nice idea, if you don't need to do anything later.
Your problem is that you are nested - in a for loop which is inside another for loop - when you want to stop processing.
Some languages would let you code break 2; to indicate that you want to break out of 2 loops. Alas, C i snot such a language.
I would recommend that you code a function. That would serve a few porpoises: 1) your main should be "lean & mean" 2) as your programs get larger, you will learn the benefits of putting individual coding tasks into functions 3) you can use return; instead of break; and it will exit the function immediately.
Something like this:
#include <stdio.h>
void FindNeighbouringDivisors(int n)
{
for (int i = n; i >= 0; i--)
{
for (int j = 0; j <= n; j = j + 2)
{
if ( i == j * (j+2) )
{
printf("%d times %d = %d", j, j + 2, i);
return;
}
}
}
printf("There are no two adjacent even numbers which can be multiplied to give %d", n);
}
int main()
{
int n;
scanf("%d", &n); /* could get from comamnd line */
FindNeighbouringDivisors(n);
return 0; /* should be EXIT_SUCCESS */
}
Btw, when you have a problem with your code, ask a question here. When you have it working, consider posting it at our code review site where more experienced programmers can give you advice on how to improve it. It's a great way to learn
Break only breaks you out of immediate loop, so either use flags or just use return to terminate the execution. Or you can even use following code:
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
for (int j = 0; j <= n; j = j + 2)
{
if ( n < j * (j+2) )
{
printf("%d ", j*(j-2));
break;
}
}
return 0;
}

Checking monotonic sequences - C programming

I am doing a problem about checking monotonic sequences. The problem is inputting a sequence and then print "YES" if it is monotonic, "NO" if it is not.
This is my code:
#include <stdio.h>
int main()
{
//Inputting the sequence
int n;
scanf("%d", &n);
int a[n];
for (int i = 1; i <= n; i++)
{
scanf("%d ", &a[i]);
}
//Checking monotonic sequence
for (int i = 1; i <= n; i++)
{
if ((a[i] > a[i-1]) && (a[i] > a[i+1]))
{
printf("NO");
return;
}
else if ((a[i] < a[i-1]) && (a[i] < a[i+1]))
{
printf("NO");
return;
}
}
printf("YES");
return 0;
}
I have failed 2 test case with sequences [1, 2, 3] and [10, 6, 4, 2, 1, -100]; and passed one test case with [1, 2, 3, 3, 2, 1]. Can anyone please point out the problem in my code? I would truly appreciate that. Thank you.
Remove trailing " ". It obliges additional input (or end-of-file) after the number is entered before scanf() returns.
// scanf("%d ", &a[i]);
scanf("%d", &a[i]);
In addition to index problems in 2 places, code needs to look for overall monotonic and not just local monotonic behavior.
bool up = true;
bool down = true;
// for (int i = 1; i <= n; i++)
for (int i = 1; i < n; i++) {
if (a[i] > a[i-1]) down = false;
if (a[i] < a[i-1]) up = false;
}
printf((up || down) ? "YES" : "NO");
Additional code to short-circuit loop.
// for (int i = 1; i < n; i++) {
for (int i = 1; i < n && (up || down); i++) {
Further there is lack of the coding goal clarity on tie cases. May need
if (a[i] >= a[i-1]) down = false;
if (a[i] <= a[i-1]) up = false;
a has indices from 0 to n-1; you code references a[0] (which never gets assigned to) and a[n] (which is outside the bounds of the array).
You are checking with invalid array index. here you are declaring an array size of n but you are checking with i+1 that means n+1 for the last case. This is out of bound for your array. First of all you are storing data in array from 1 to n . But when you declare a array size n then it has index from 0 to n-1.so you can store data from 0 to n and start the check from 1 and end in n-1.
this one will work for you:
#include <stdio.h>
int
main ()
{
//Inputting the sequence
int n;
scanf ("%d", &n);
int a[n];
for (int i = 0; i < n; i++)
{
scanf ("%d", &a[i]);
}
int inc = 0;
int dec = 0;
//Checking monotonic sequence
for (int i = 1; i < n ; i++)
{
if (a[i] > a[i - 1])
{
inc = 1;
}
else if (a[i] < a[i - 1])
{
dec = 1;
}
}
if (inc == 1 && dec == 1)
{
printf ("NO");
}
else
{
printf ("YES");
}
return 0;
}

how to detect duplicates in arrays & print non duplicates?

void main ()
{
int x[19]={0}, i=0, y=0, u=0, p;
while (i<=19)
{
scanf("%d",&x[i]);
i=i+1;
}
for (i=u;i<=19;i++)
{
if (x[y]!=x[i+1])
p=x[y];
else
{
u++;
y++;
}
}
printf("%d",p);
}
So I used this to check for duplicates & it should print non duplicates, but as you can see this works if all are duplicates but one, as in
x[0]=1 x[1]=1 x[3]=9 x[4]=1 ... x[19]=1;
prints
9
So how to print non duplicates ? Any help ?
This would be the easiest solution, simply nest an additional for-loop. However, this takes O(n^2). Depending on the size of the array, it could be beneficial to look at a fast sort.
void main() {
int x[4] = { 1, 3, 2, 1 };
size_t i, j;
for (i = 0; i < sizeof(x) / sizeof(int); i ++) {
// Note that we only have to go to the last value before i.
for (j = 0; j < i; j ++) {
// We break if the value is a duplicate.
if (x[i] == x[j])
break;
}
// Check if the inner loop was break'ed (j < i) or not (j == i).
if (j == i)
printf("Unique: %i\n", x[i]);
}
}
One more thing: only use sizeof(x) / sizeof(int) if the size of x is known during compilation. This is the case here, but don't use it with malloc.
One of the simplest ways is to sort the array to group the duplicates together. Then, as you go through the array you only print a number if its different from the number that came before.
// Print the unique elements of a sorted array:
for(int i=0; i<N; i++){
if (i-1 >= 0 && arr[i] == arr[i-1]) { continue; }
if (i+1 < N && arr[i] == arr[i+1]) { continue; }
printf("%d\n", arr[i]);
}
To sort the array you can use the qsort function
void main ()
{
int num[20]={0}, i=0, n=0, index_num=0, init_incr=0, unique=0, n_uniq=1, temp, check=0;
while (i<=19)
{
printf("%02d- ",i+1);
scanf("%d",&num[i]);
i=i+1;
}
for (index_num=0;index_num<19;index_num++)
{
for (n=init_incr+index_num;n<19;n++)
{
if (num[index_num]!=num[index_num+1] && num[index_num]!=num[index_num-1])
{
check++;
temp=num[index_num];
unique=temp;
for (;n_uniq<=check;n_uniq++)
printf("\tunique %02d = %d\n", n_uniq, unique);
break;
}
}
}
}

array bucket sort in C

I am trying to read list of numbers from txt file and then sort them with Bucket sort.
so here is my code:
void bucketSort(int array[],int *n)
{
int i, j;
int count[*n];
for (i = 0; i < *n; i++)
count[i] = 0;
for (i = 0; i < *n; i++)
(count[array[i]])++;
for (i = 0, j = 0; i < *n; i++)
for(; count[i] > 0; (count[i])--)
array[j++] = i;
}
int main(int brArg,char *arg[])
{
FILE *ulaz;
ulaz = fopen(arg[1], "r");
int array[100];
int i=0,j,k,n;
while(fscanf(ulaz, "%d", &array[i])!=EOF)i++;
fclose(ulaz);
n=i;
for (j = 0; j<i; j++)
{
printf("Broj: %d\n", array[j]);
}
BucketSort(array,&n);
for (k = 0; k<i; k++)
printf("%d \n", array[i]);
return 0;
}
There are no errors in code,but when i call my function instead of sorted array i get array length random numbers(example: 2 3 5 4,after sorting i get 124520 124520 124520 124520 or some other random number) since i am a beginner,could someone help me with my code and what i did wrong? (sorry for bad english)
As Cool Guy correctly pointed out you have issues with memory access but on top of it the code does not sort anything. First you should read how Bucket Sort actually works.
In general:
You divide the input data among buckets by some criteria that guarantees that the buckets will not mess up the input order
Sort each bucket either using some other sorting method or recursively with bucket sort
Concatenate the sorted data (this is why the first point has the restriction of not messing up the input order)
Here is an example of your original code, I tried to adjust it as little as possible you it is easier for you to understand. This code divides a predefined input array among 3 buckets by range:
[-infinity][-1] -> first bucket
[0;10] -> second bucket
[11;infinity] -> third bucket
then performs Quicksort on each bucket and concatenates the result. I hope this helps to understand how this algorithm works.
#include <stdio.h>
#include <stdlib.h>
struct bucket
{
int count;
int* values;
};
int compareIntegers(const void* first, const void* second)
{
int a = *((int*)first), b = *((int*)second);
if (a == b)
{
return 0;
}
else if (a < b)
{
return -1;
}
else
{
return 1;
}
}
void bucketSort(int array[],int n)
{
struct bucket buckets[3];
int i, j, k;
for (i = 0; i < 3; i++)
{
buckets[i].count = 0;
buckets[i].values = (int*)malloc(sizeof(int) * n);
}
// Divide the unsorted elements among 3 buckets
// < 0 : first
// 0 - 10 : second
// > 10 : third
for (i = 0; i < n; i++)
{
if (array[i] < 0)
{
buckets[0].values[buckets[0].count++] = array[i];
}
else if (array[i] > 10)
{
buckets[2].values[buckets[2].count++] = array[i];
}
else
{
buckets[1].values[buckets[1].count++] = array[i];
}
}
for (k = 0, i = 0; i < 3; i++)
{
// Use Quicksort to sort each bucket individually
qsort(buckets[i].values, buckets[i].count, sizeof(int), &compareIntegers);
for (j = 0; j < buckets[i].count; j++)
{
array[k + j] = buckets[i].values[j];
}
k += buckets[i].count;
free(buckets[i].values);
}
}
int main(int brArg,char *arg[]) {
int array[100] = { -5, -9, 1000, 1, -10, 0, 2, 3, 5, 4, 1234, 7 };
int i = 12,j,k,n;
n=i;
for (j = 0; j<i; j++)
{
printf("Broj: %d\n", array[j]);
}
bucketSort(array, n);
for (k = 0; k<i; k++)
printf("%d \n", array[k]);
return 0;
}
Your code exhibits Undefined Behavior as you try to write into memory location which are not owned by your program.
for (i = 0; i < *n; i++)
(count[array[i]])++;
The above loop is causing the problem. You say that i is 4 which means that *n is also 4 and array contains 2 3 5 4. In the above code,count is an array of *n elements(in this case 4 elements) and the valid indices for the array are count[0],count[1],count[2] and count[3]. Doing
count[array[i]]
when i is zero is okay as it is same as count[2]. This is the same when i is 1 as it would be count[3] . After that ,when i is 4 and 5,count[4] and count[5] are wrong as you try to write to a invalid memory location.
Also,your code dosen't sort the values.

Resources