Why wouldn't this code run because of 1 line of code? - c

Why would this code only run if i remove the Total = 0 in the while(Total != N) loop and wouldn't run if i didn't remove it?
But the problem is i need to use that total = 0 to be able to complete a certain test case.
#include <stdio.h>
int N;
void Shift(long long B[]){
int i;
long long temp;
temp = B[N - 1];
for(i = N - 1; i > 0; i--){
B[i] = B[i - 1];
}
B[0] = temp;
}
int main() {
int j,i,Jumlah = 0,Total = 0;
scanf("%d",&N);
long long A[N],B[N];
for(i = 0; i < N; i++) {
scanf(" %lld",&A[i]);
}
for(i = 0; i < N; i++) {
scanf(" %lld",&B[i]);
if(B[i] == A[i]) {
Total++;
}
}
while(Total != N) {
Shift(B);
Jumlah++;
//Total = 0;
for(i = 0; i < N; i++) {
if(A[i] == B[i]) {
Total++;
}
}
}
printf("%d\n",Jumlah);
return 0;
}
Test Case : N = 5 First Array = 1 2 5 3 4 Second Array = 5 1 4 2 3

In this code
Total = 0;
for(i = 0; i < N; i++){
if(A[i] == B[i]){
Total++;
}
}
the variable Total will reach the value N if and only if the condition A[i] == B[i] is true for all values of i.
So when you wrap the code into a while statement like:
while (Total != N) {
Total = 0;
for(i = 0; i < N; i++){
if(A[i] == B[i]){
Total++;
}
}
}
you have an endless loop if A[i] == B[i] is false one or more times.
The shift-operation (i.e. Shift(B);) doesn't ensure that you will end in a situation where all elements in B equals all elements in A

Related

I want to store elements of maximum and minimum frequency in the arr2 array ? But not able to

I want to store elements of maximum and minimum frequency in the arr2 array if there are more than one element of same frequency then both the elements should be stored ? But it is showing wrong results and i am not able to find what is the err. Can anyone help me with this. Any kind of help would be greatly appreciated.
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
int arr2[n];
int prevcount = 0;
int k = 0;
// for finding max element
for (int i = 0; i < n; i++)
{
int count = 0;
//counting the number of times it has occured
for (int j = 0; j < n; j++)
{
if (arr[i] == arr[j])
{
count++;
}
}
// checking if the same element was not there in the new array
for (int i = 0; i < k; i++)
{
if (arr[i] == arr[k])
{
goto nextit;
}
}
//it will update the kth element if the count is greater than the prev count
if (prevcount < count)
{
arr2[k] = arr[i];
}
//if these both are same but the number is different then will iterate k by 1 and store that element as well
else if (prevcount == count)
{
k++;
arr2[k] = arr[i];
}
prevcount = count;
nextit:
}
// for finding min element
prevcount = 1000;
for (int i = 0; i < n; i++)
{
int count = 0;
for (int j = 0; j < n; j++)
{
if (arr[i] == arr[j])
{
count++;
}
}
// checking if the same element was not there in the new array if there is then go to the next iteration
for (int i = 0; i < k; i++)
{
if (arr[i] == arr[k])
{
goto nextit2;
}
}
if (prevcount > count)
{
arr2[k] = arr[i];
}
else if (prevcount == count)
{
k++;
arr2[k] = arr[i];
}
prevcount = count;
nextit2:
}
for (int i = 0; i < k; i++)
{
printf("%d ", arr2[i]);
}
return 0;
}
As #SparKot suggests, sorting the array makes the problem simple. Would you please try:
#include <stdio.h>
#include <stdlib.h>
// compare values numerically
int numeric(const void *a, const void *b)
{
return (*(int *)a < *(int *)b) ? -1 : (*(int *)a > *(int *)b);
}
int main()
{
int n, i, j;
int *arr; // input array
int *count; // count frequency: initialized to 0's by calloc
int min = 0; // minimum occurrences
int max = 0; // maximum occurrences
scanf("%d", &n);
if (NULL == (arr = malloc(n * sizeof(int)))) {
perror("malloc");
exit(1);
}
if (NULL == (count = calloc(n, sizeof(int)))) {
perror("calloc");
exit(1);
}
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
qsort(arr, n, sizeof(int), numeric);
// count the length of sequence of the same numbers
for (i = 0; i < n; i++) {
for (j = 0; i + j < n && arr[i] == arr[i + j]; j++) {
;
}
count[i] = j; // i'th element has length j
i += j - 1; // jump to next number
}
// find minimum and maximum frequencies
for (i = 0; i < n; i++) {
if (count[i]) {
if (min == 0 || count[i] < min) min = count[i];
if (max == 0 || count[i] > max) max = count[i];
}
}
// report the result
for (i = 0; i < n; i++) {
if (count[i] == min) {
printf("min frequency %d value %d\n", count[i], arr[i]);
}
if (count[i] == max) {
printf("max frequency %d value %d\n", count[i], arr[i]);
}
}
return 0;
}
Sample input (n=10):
6
1
2
5
1
2
3
1
3
6
Output:
max frequency 3 value 1
min frequency 1 value 5

arrange the array in an order such that the even values are followed by odd values in the array

this is the program I made ,if I input [13,11,10,17,18] i get the output [12,13,17,11,10]. I do not understand what mistake I am making. somebody please help me understand.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n,j,i,num,v;
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
ptr = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d",&v);
ptr[i] = v;
}
i=0;
j=0;
while(i<5){
j++;
if (ptr[j]%2==0 && i%2==0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
}
if (ptr[j]%2!=0 && i%2 !=0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
}
if (j==4){
i++;
j=0;
}
}
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
Ok, I tried to tell you how you should have written you program, but you didn't listen:
Make a https://stackoverflow.com/help/minimal-reproducible-example
A MCVE needs all the includes
No interactive stuff. You need to run and run and run your program in a debugger. You don't want to put data in manually every single time.
You want many tests, and you want to repeat them, so that when you fix one, you don't break another.
Make a function which does the job.
Free your memory!
Now to the solution: your idea of a solution was fine apart from the stuff about indexes. It's pretty similar to the one you will find down here. The only difference is that I put the odd numbers al the end to avoid checking elements multiple times.
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void evenodd(int *v, size_t n)
{
for (size_t i = 0; i < n; ++i) {
while (i < n && v[i] % 2 == 0) {
++i;
}
--n;
while (i < n && v[n] % 2) {
--n;
}
if (i < n) {
int tmp = v[i];
v[i] = v[n];
v[n] = tmp;
}
}
}
bool is_evenodd(int *v, size_t n)
{
size_t i = 0;
while (i < n && v[i] % 2 == 0) {
++i;
}
while (i < n && v[i] % 2 != 0) {
++i;
}
return i == n;
}
void main_test(const int *v, size_t n)
{
int *v1 = memcpy(malloc(n * sizeof(int)), v, n * sizeof(int));
evenodd(v1, n);
if (is_evenodd(v1, n)) {
printf("Ok!\n");
}
else {
printf("Fail!\n");
}
free(v1);
}
int main(void)
{
main_test((int[]) { 1 }, 0);
main_test((int[]) { 1 }, 1);
main_test((int[]) { 2 }, 1);
main_test((int[]) { 1, 2 }, 2);
main_test((int[]) { 1, 3 }, 2);
main_test((int[]) { 2, 1 }, 2);
main_test((int[]) { 2, 4 }, 2);
main_test((int[]) { 1, 3, 2 }, 3);
main_test((int[]) { 1, 4, 2 }, 3);
size_t n = 1000;
int *a = malloc(n * sizeof *a);
for (size_t i = 0; i < n; ++i) {
a[i] = rand();
}
main_test(a, n);
free(a);
return 0;
}
You can try the following code :
int even_index = 0; //start index
int odd_index = 4; //end index
for(int i=0;i<5;i++){
if(ptr[i] % 2 == 0){
int temp = ptr[even_index];
ptr[even_index++] = ptr[i]; //swapping values and incrementing even_index
ptr[i] = temp;
}else{
int temp = ptr[odd_index];
ptr[odd_index--] = ptr[i];
ptr[i] = temp;
}
}
or you can also count the number of even numbers in the digits during input and assign odd_value = even_num // number of even digits
ok so I solved it....
see the even numbers always end up in even indexes so we need to set a pointer on those even index(current index) and search for any even number after the current index.
if we find any(even number) we swap the current index value with the even number.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int* ptr;
int n,j,i,num,v;
printf("Enter number of elements:");
scanf("%d",&n);
printf("Entered number of elements: %d\n", n);
ptr = (int*)malloc(n * sizeof(int));
for (i = 0; i < n; ++i) {
scanf("%d", &v);
ptr[i] = v;
}
i=0;
j=0;
while(i<n && j<n){
if (ptr[j]%2==0){
num=ptr[i];
ptr[i]=ptr[j];
ptr[j]=num;
i+=2;
j=i;
}
j++;
}
printf("The elements of the array are: ");
for (i = 0; i < n; ++i) {
printf("%d, ", ptr[i]);
}
}
If this problem is to sort an array in order (descending) and then further place all even values before odd values I would recommend:
Sort the array
Swap and shift any odd numbers with the even numbers
Here's a naive implementation:
for (int i = 0; i < len - 1; i++) {
for (int j = i + 1; j < len; j++) {
if (arr[i] < arr[j]) {
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
int lastEven = 0;
for (int i = 0; i < len - 1; i++) {
if (arr[i] % 2 && (arr[i + 1] % 2 == 0)) {
tmp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = tmp;
lastEven = i;
} else if (arr[i] % 2 == 0 && lastEven-i > 1) {
for (int j = i; j > lastEven; j--) {
tmp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = tmp;
}
lastEven++;
}
}
Given the input [13,11,10,17,18] this will first sort the array ([18,17,13,11,10]) then separate the evens and odds ([18,10,17,13,11])

Inserting elements to array in C

My task is: If we look at any two neighbour values in an array, if the one on the right is two times greater than the one on the left, their average should be inserted between them and the new array consisting of old and new elements should be printed. I have a problem with moving the other elements after average.And using special functions or libraries is not allowed.I am beginner, and I hope you could help.
#include <stdio.h>
int main() {
int n, i, j;
double a[100], average;
printf("Enter the number of elements: ");
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%lf", &a[i]);
}
for (i = 0; i < n; i++) {
if ((a[i + 1] / a[i]) == 2) {
for (i = j = 0; i < n; ++i)
b[j++] = a[i];
if (a[i + 1] / a[i] == 2)
average = (a[i + 1] + a[i]) / 2;
b[j++] =average;
}
}
for (i = 0; i < j; ++i) {
printf("%lf\n", b[i]);
}
}
A simple way to solve your problem is adding double b[199];, and copying everything over:
for (i = j = 0; i < n; ++i) {
b[j++] = a[i];
if (...) b[j++] = ...; /* Append the average to b. */
}
for (i = 0; i < j; ++i) {
printf("%lf\n", b[i]);
}
If you really want to move the elements forward within a itself, then you can do it by adding an inner for loop (and an additional loop variable int k;) which copies the elements one-by-one:
for (k = n++; k > i; --k) {
a[k] = a[k - 1];
}
In order to insert an element in an array, you must copy the elements with higher index from the last one down.
Also avoid dividing by a[i] that can be zero, and properly handle 0,0 that match the criteria for inserting the average, and skip the inserted value to avoid inserting more zeros.
#include <stdio.h>
#include <stdlib.h>
int main() {
int n, i, j;
printf("Enter the number of elements: ");
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
double *a = malloc(sizeof(*a) * (2 * n - 1)); // allocate the array to the maximum size
if (a == NULL)
return 0;
for (i = 0; i < n; i++) {
if (scanf("%lf", &a[i]) != 1)
return 1;
}
for (i = 1; i < n; i++) {
if (a[i] == a[i - 1] * 2) {
for (j = n; j > i; j--)
a[j] = a[j - 1];
a[i] = (a[i - 1] + a[i]) / 2;
n++; // increase number of elements
i++; // skip the new value
}
}
for (i = 0; i < n; ++i) {
printf("%f\n", a[i]);
}
free(a);
return 0;
}
To insert an element in a specific position you would need to move the rest of the array. However doing it many times is expensive and you may prefer to use an array to store the position at which you want to insert the elements and then insert them all at once.
Alternatively you can create a new array where to copy the original plus the new values.
However there's an easier and faster way, that is adding the new values straight away, while you fill the original array. Here's a program that does that.
#include <stdio.h>
#define SIZE 100
int main() {
int i, n, avg = 0;
double a[SIZE];
while( puts("Enter the number of elements:") && (scanf("%d", &n) != 1 || n < 1 || n > SIZE) );
scanf("%lf", &a[0]);
for(i = 1; i < n+avg && i < SIZE-1 && scanf("%lf", &a[i]) == 1; i++) {
if( a[i] == a[i-1] * 2 ) {
a[i+1] = a[i];
a[i] = (a[i] + a[i-1]) / 2;
++avg;
++i;
}
}
for(i = 0; i < n+avg; i++) {
printf("%lf\n", a[i]);
}
return 0;
}

C - Remove Duplicates from an Array

I'm quite new to programming, I wrote a code to remove duplicates from an array, logically, it should work, but it doesn't.... I logically tested it multiple times and it made sense...
Here's the code:
#include <stdio.h>
int rmDuplicates(int arr[], int n)
{
int i, j;
for (i = 0; i < n; i++) {
if (arr[i] == arr[i + 1]) {
for (j = i + 1; j < n - 1; j++) {
arr[j] = arr[j + 1];
}
n--;
}
return n;
}
}
int main()
{
int n, i;
scanf("%d", &n);
int arr[n];
for (i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
n = rmDuplicates(arr, n);
for (i = 0; i < n; i++) {
printf("%d", arr[i]);
}
printf("\n%d", n);
return 0;
}
Your "return n" is in the wrong place, and returns after the first cycle.
for(i=0;i<n;i++) {
if(arr[i] == arr[i+1]) {
for(j=i+1;j<n-1;j++) {
arr[j] = arr[j+1];
}
n--;
}
return n; // <---- this
}
// <-- should be here.
As confirmation, if I move the return n; outside the loop, the code works. But it only removes consecutive duplicates, because you only check arr[i] against its consecutive, arr[i+1].
(Also, the cycle ought to stop at n-1, because otherwise arr[n-1+1] is arr[n] which is outside the array).
A final issue is that if you have, say,
n
...5,..., 5, 5, 6
i j
and you check the first 5 against the second, and find it a duplicate, then shift all that follows by one step, in the j-th position you will have a 5 again, but j will now be incremented and you will test the first 5 against the 6 instead of the third 5, not finding the duplicate:
n
...5,..., 5, 6
i j
For this reason, when you find a match, you need to rewind j by one and repeat that test:
int rmDuplicates(int arr[], int n) {
int i,j,k;
for (i=0;i<n-1;i++) {
for (j=i+1; j < n; j++) {
if(arr[i] == arr[j]) {
n--;
for (k=j;k<n;k++) {
arr[k] = arr[k+1];
}
j--;
}
}
}
return n;
}
From a performance point of view, the above algorithm is O(n^2), that is, if the array list doubles, the algorithm takes four times as long; if it trebles, it takes nine times as long.
A better algorithm would therefore be to first sort the array in-place, so that 1 3 2 7 2 3 5 becomes 1 2 2 3 3 5 7 (this has a cost of O(n log n), which grows more slowly ); then you just "compress" the array skipping duplicates, which is O(n) and gets you 1 2 3 5 7
int i, j;
for (i = 0, j = 1; j < n;) {
if (arr[i] == arr[j]) {
j++;
continue;
}
i++;
if (j != (i+1)) {
arr[i] = arr[j];
}
j++;
}
n = i+1;
size_t removeDups(int *arr, size_t size)
{
if(arr && size > 1)
{
for(size_t current = 0; current < size - 1; current++)
{
size_t original_size = size;
size_t copypos = current + 1;
for(size_t cpos = current + 1; cpos < original_size; cpos++)
{
if(arr[current] == arr[cpos])
{
if(cpos < original_size -1)
{
if(arr[current] != arr[cpos + 1])
{
arr[copypos++] = arr[cpos + 1];
cpos++;
}
}
size--;
}
else
{
arr[copypos++] = arr[cpos];
}
}
}
}
return size;
}
int main(void)
{
int arr[] = {1,1,1,2,2,3,3,4,5,6,7,1,8,8,2,2,2,2};
size_t size = sizeof(arr) / sizeof(arr[0]);
size = removeDups(arr, size);
for(size_t index = 0; index < size; index++)
{
printf("%d\n", arr[index]);
}
}

Duplicated output values

I want to display the calendar data in ascending order.
If the date appears several times I need to display it once.
The code works if the date appears five or less times in the input,
if the date appears more than five times at the output it will show up twice.
I don't see the error.
#include <stdio.h>
#include <stdlib.h>
struct date {
int zi;
int luna;
};
int main() {
int n, i, j, k = 0, l;
char c;
scanf("%d", &n);
struct date v[100];
for (i = 0; i < n; i++) {
scanf("%d %c %d", &v[i].zi, &c, &v[i].luna);
}
for (i = 0; i < n - 1; i++) {
for (j = i + 1; j < n; j++) {
if (v[i].luna > v[j].luna) {
struct date temp = v[i];
v[i] = v[j];
v[j] = temp;
} else if (v[i].luna == v[j].luna && v[i].zi > v[j].zi) {
struct date temp = v[i];
v[i] = v[j];
v[j] = temp;
}
}
}
printf("\n");
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (v[i].luna == v[j].luna && v[i].zi == v[j].zi && i != j) {
printf("\nOK\n");
for (l = j; l < n - 1; l++) {
// v[l].luna=v[l+1].luna;
// v[l].zi=v[l+1].zi;
v[l] = v[l + 1];
}
n--;
}
}
}
for (i = 0; i < n; i++) {
if (v[i].luna < 10 && v[i].zi >= 10) {
printf("%d-0%d\n", v[i].zi, v[i].luna);
} else if (v[i].zi < 10 && v[i].luna >= 10) {
printf("0%d-%d\n", v[i].zi, v[i].luna);
} else if (v[i].zi < 10 && v[i].luna < 10) {
printf("0%d-0%d\n", v[i].zi, v[i].luna);
} else
printf("%d-%d\n", v[i].zi, v[i].luna);
}
}
The problem seems to be this block:
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (v[i].luna == v[j].luna && v[i].zi == v[j].zi && i != j) {
printf("\nOK\n");
for (l = j; l < n - 1; l++) {
// v[l].luna=v[l+1].luna;
// v[l].zi=v[l+1].zi;
v[l] = v[l + 1];
}
n--;
}
}
}
When you remove a duplicate (i.e. by shifting all elements towards the start and decrementing n) you still increment j. Consequently, your loop will skip one element and you may end up with duplicates.
The solution could be as simple as decrementing j at the same time as you decrement n.
BTW: It seems strange that the j-loop start from zero. I would expect it to start from i+1

Resources