#include <stdio.h>
#define MAX_SIZE 1000 // Maximum array size
int main() {
int arr[MAX_SIZE], size, i;
int max1, max2;
scanf("%d", &size);
max1 = max2 = -99999;
/* Input array elements */
for (i = 0; i < size; i++) {
scanf("%d", &arr[i]);
}
/*
* Check for first largest and second
*/
for (i = 0; i < size; i++) {
if (arr[i] > max1) {
max2 = max1;
max1 = arr[i];
} else
if (arr[i] > max2 && arr[i] < max1) {
max2 = arr[i];
}
}
printf("%d", max2);
return 0;
}
when I used test case 20 10 40 4 100 output is correct 40,
but when I use 1 2 3 4 5 then output is max2 = -99999.
Can anyone please explain to me why I am not getting this? I traced but did not get why?
In your program, the first input is the size of the array. So, your inputs should actually be 5 20 10 40 4 100 and 5 1 2 3 4 5 (note the extra 5 in front) so they have the correct size. Your first input is correct because it read in 20 as the size and tried to read in 20 numbers, and there weren't enough numbers so it just read in 0 for the rest, and 40 was still the second-largest. For your second input, it read in 1 as the size, so there was no second-largest number, so it printed out -99999.
The output is somewhat consistent with the input, assuming the input comes from a text file:
the first number read is the number of entries to handle.
for the first case, size is read as 20 and the program tries to read 20 numbers into arr[0] through arr[19]. As you do not test the return value of scanf(), you do not detect the invalid or missing input past the last one in the file 100. scanf() fails and leaves arr[i] unchanged from index 4 on. arr is unintiialized, so the contents is undefined and so is the behavior of the program. It so happens that there are no numbers in arr[4] through arr[19] that are larger than 40. So the second largest number is printed as 40.
for the second case, size is read as 1 and only a single number is read into arr[0], the remaining input being ignored. The loop sets max1 = 2 and max2 = max1, whose initial value is -99999. Hence the output.
You should provide 5 20 10 40 4 100 and 5 1 2 3 4 5 as input to get the expected behavior consistently.
You should also be more defensive with user input and report unexpected cases:
#include <limits.h>
#include <stdio.h>
#define MAX_SIZE 1000 // Maximum array size
int main() {
int arr[MAX_SIZE], size, i;
int max1, max2, has_max;
if (scanf("%d", &size) != 1) {
printf("missing count of numbers\n");
return 1;
}
if (size < 0 || size > MAX_SIZE) {
printf("invalid count of numbers: %i\n", size);
return 1;
}
/* Input array elements */
for (i = 0; i < size; i++) {
if (scanf("%d", &arr[i]) != 1) {
printf("invalid input: got %i numbers instead of %i\n", i, size);
size = i;
break;
}
}
/*
* Check for first largest and second
*/
max1 = max2 = INT_MIN;
has_max = 0;
for (i = 0; i < size; i++) {
if (arr[i] > max1) {
max2 = max1;
max1 = arr[i];
has_max++;
} else
if (arr[i] > max2 && arr[i] < max1) {
max2 = arr[i];
has_max++;
}
}
if (has_max < 2) {
printf("no second highest value\n");
} else {
printf("%d\n", max2);
}
return 0;
}
Note the method to track if there are at least 2 different values in the array. Try and see if this improvement is sufficient for all cases...
Related
Taking a sequence of (non-empty) integers the program should first request the number of integers to read and dynamically allocate an array large enough to hold the number of values you read. You should then loop in the elements of the array. Then, your program must use malloc() to dynamically allocate two arrays, one to hold all the even numbers in the array you just read, and one to hold the odd numbers in the array. You must allocate just enough space for each array to hold odd and even numbers.
That is my test case
Please enter the number of times you want to enter the temperature:
4
Please enter the numbers:
21
40
31
50
odds are: 21
odds are: 0
evens are: 0
evens are: 40
This is my code:
#include <stdio.h>
#include<stdlib.h> // for malloc
int main(void) {
int counts = 0; // set a variable named counts recored how many of the times
printf("Please enter the number of times you want to enter the temperature: \n");
scanf("%d",&counts);
int *odd_evens;
odd_evens = malloc(sizeof(int)*(counts));
printf("Please enter the numberss: \n");
for (int i = 0; i < counts; i++) { // use for loop to read temperature
scanf("%d",&odd_evens[i]); // record the temperature
}
int odds_number = 0; // calcuate how many numbers are odds
int evens_number = 0; // calcuate how many numbers are evens
for (int i = 0; i < counts; i++) {
if (odd_evens[i] %2 == 0) {
odds_number++; // odds add one
}
else if (odd_evens[i] %2 != 0) {
evens_number++; // evens add one
}
}
int *odds;
odds = malloc(sizeof(int)*(odds_number)); // create dunamic array for odds
int *evens;
evens = malloc(sizeof(int)*(evens_number)); // create dunamic array for evens
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[j] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[j] = odd_evens[j];
}
}
for(int m = 0; m < odds_number; m++) {
printf("odds are: %d\n",odds[m]);
}
for (int n = 0; n < odds_number; n++) {
printf("evens are: %d\n",evens[n]);
}
free(odd_evens);
free(odds);
free(evens);
return 0;
}
In my limited coding experience, this usually happens with invalid subscripts, but in my test code, the odd numbers are of length 2 and the even numbers are of length 2. The array range should be correct. Why does this happen?
One major problem is this loop:
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[j] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[j] = odd_evens[j];
}
}
Here you will go out of bounds of both evens and odds (leading to undefined behavior) since you use the index for odd_evens which most likely will be larger (unless all input is only odd, or only even).
You need to keep separate indexes for evens and odds:
unsigned evens_index = 0;
unsigned odds_index = 0;
for (int j = 0; j < counts; j++) {
if (odd_evens[j] % 2 == 0) {
evens[evens_index++] = odd_evens[j];
}
else if (odd_evens[j] % 2 != 0) {
odds[odds_index++] = odd_evens[j];
}
}
Another problem is the printing of the even numbers:
for (int n = 0; n < odds_number; n++) {
printf("evens are: %d\n",evens[n]);
}
Here you use the odds_number size instead of evens_number.
I have written this C code to find a minimum number of wires required to switch on all the bulbs.
The problem is that there is x number of computers, some of which are On and some are Off and the distance between these bulb from the first bulb is given. The computer can be switched ON by connecting it to its nearby ON the bulb.
So the inputs are as follows:
X = 6 (number of bulbs)
1 0 1 1 0 1(1 means the bulb is ON and 0 means the bulb is OFF)
2 4 8 36 37 40 (distance between one bulb from the first bulb)
and the output will be:
3 (Reason: 4 - 2 = 2, 37 - 36 = 1, 2 + 1 = 3)
#include <stdio.h>
int main(){
int n,pre,post,sum = 0;
scanf("%d",&n);
int arr[n],dist[n];
for(int i =0;i<n;i++){
scanf("%d ",&arr[i]);
}
for(int i =0;i<n;i++){
scanf("%d ",&dist[i]);
}
for(int i =0;i<6;i++){
if(arr[i] == 0){
pre = dist[i]-dist[i-1];
post = dist[i+1]-dist[i];
if(pre>post){
sum +=post;
}
else{
sum+=pre;
}
}
}
printf("\n %d",sum);
}
It keeps on taking the inputs. Please tell me what is the error in this code?
Thanks in advance.
Edited: I missed that scanf("%d",n) by mistake. It was there in my original code and the problem still persists.
As Sandrin mentioned, n is not defined.
Assuming your input file is:
6
1 0 1 1 0 1
2 4 8 36 37 40
You need to add code to set n:
scanf("%d ",&n);
And, you need to insert this before the definitions of your matrix
Here's the refactored code:
#include <stdio.h>
int
main(void)
{
int n, pre, post, sum = 0;
#if 1
scanf("%d ",&n);
#endif
int arr[n], dist[n];
for (int i = 0; i < n; i++)
scanf("%d ", &arr[i]);
for (int i = 0; i < n; i++)
scanf("%d ", &dist[i]);
for (int i = 0; i < 6; i++) {
if (arr[i] == 0) {
pre = dist[i] - dist[i - 1];
post = dist[i + 1] - dist[i];
if (pre > post) {
sum += post;
}
else {
sum += pre;
}
}
}
printf("\n %d", sum);
return 0;
}
Putting a side technical errors (e.g. n not initialized), the algorithms assumes that all problems can be solved by single pass. This is not true for cases like:
1 0 0 0 0 1
0 1 3 4 6 7
Where the code will choose to connect bulbs [0,1], [2,3], and [4,5], based on pre/post distances. However, bulbs 2 and 3 will remain disconnected.
A better algorithm will attempt to find, for each sequence of off bulbs, which is the most expensive connection, and avoid it.
I have come up with this solution for my code and I have tried to consider all the test cases. If you find any test case that won't run feel free to tell.
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av){
int n,pre,post,sum = 0;
scanf("%d",&n);
int *input,*distance;
input = malloc(n * sizeof(int));
for (int i=0; i < n; i++)
{
scanf("%d", &input[i]);
}
distance = malloc(n * sizeof(int));
for (int i=0; i < n; i++)
{
scanf("%d", &distance[i]);
}
for(int i =0;i<6;i++){
if(input[i] == 0){
pre = distance[i]-distance[i-1];
if(input[i+1]==1){
post = distance[i+1]-distance[i];
input[i] =1;
if(pre>post){
sum +=post;
}
else{
sum+=pre;
}
}
else{
sum = sum+pre;
}
printf("%d.....%d....%d\n",pre,post,sum); //Debugging
}
}
printf("\n %d",sum);
free(input);
free(distance);
}
I wrote a code to find the index of the largest substring in a larger string.
A substring is found when there is an equal amount of a's and b's.
For example, giving 12 and bbbbabaababb should give 2 9, since the first appearing substring starts at index 0 and ends at index 9. 3 10 is also an answer, but since this is not the first appearing substring, this will not be the answer.
The code I made is:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
void substr(char str[], int n) {
int sum = 0;
int max = -1, start;
for (int i = 0; i < n; i++) {
if (str[i]=='a') {
str[i] = 0;
} else if(str[i]=='b') {
str[i] = 1;
}
}
// starting point i
for (int i = 0; i < n - 1; i++) {
sum = (str[i] == 0) ? -1 : 1;
// all subarrays from i
for (int j = i + 1; j < n; j++) {
(str[j] == 0) ? (sum += -1) : (sum += 1);
// sum == 0
if (sum == 0 && max < j - i + 1 && n%2==0) {
max = j - i + 1;
start = i-1;
} else if (sum == 0 && max < j - i + 1 && n%2!=0) {
max = j - i + 1;
start = i;
}
}
}
// no subarray
if (max == -1) {
printf("No such subarray\n");
} else {
printf("%d %d\n", start, (start + max - 1));
}
}
/* driver code */
int main(int argc, char* v[]) {
int n; // stores the length of the input
int i = 0; // used as counter
scanf("%d", &n);
n += 1; // deals with the /0 at the end of a str
char str[n]; // stores the total
/* adding new numbers */
while(i < n) {
char new;
scanf("%c", &new);
str[i] = new;
++i;
}
substr(str, n);
return 0;
}
It works for a lot of values, but not for the second example (given below). It should output 2 9 but gives 3 10. This is a valid substring, but not the first one...
Example inputs and outputs should be:
Input Input Input
5 12 5
baababb bbbbabaababb bbbbb
Output Output Output
0 5 2 9 No such subarray
You have several problems, many of them to do with arrays sizes and indices.
When you read in the array, you want n characters. You then increase n in oder to accomodate the null terminator. It is a good idea to null-terminate the string, but the '\0' at the end is really not part of the string data. Instead, adjust the array size when you create the array and place the null terminator explicitly:
char str[n + 1];
// scan n characters
str[n] = '\0';
In C (and other languages), ranges are defined by an inclusive lower bound, but by an exclusive upper bound: [lo, hi). The upper bound hi is not part of the range and there are hi - lo elements in the range. (Arrays with n elements are a special case, where the valid range is [0, n).) You should embrace rather than fight this convention. If your output should be different, amend the output, not the representation in your program.
(And notw how your first example, where you are supposed to have a string of five characters actually reads and considers the b in the 6th position. That's a clear error.)
The position of the maximum valid substring does not depend on whether the overall string length is odd or even!
The first pass, where you convert all "a"s and "b"s to 0's and 1's is unnecessary and it destroys the original string. That's not a big problem here, but keep that in mind.
The actual problem is how you try to find the substrings. Your idea to add 1 for an "a" and subtract one for a "b" is good, but you don't keep your sums correctly. For each possible starting point i, you scan the rest of the string and look for a zero sum. That will only work, if you reset the sum to zero for each i.
void substr(char str[], int n)
{
int max = 0;
int start = -1;
for (int i = 0; i + max < n; i++) {
int sum = 0;
for (int j = i; j < n; j++) {
sum += (str[j] == 'a') ? -1 : 1;
if (sum == 0 && max < j - i) {
max = j - i;
start = i;
}
}
}
if (max == 0) {
printf("No such subarray\n");
} else {
printf("%d %d\n", start, start + max);
}
}
Why initialize max = 0 instead of -1? Because you add +1/−1 as first thing, your check can never find a substring of max == 0, but there's a possibility of optimization: If you have already found a long substring, there's no need to look at the "tail" of your string: The loop condition i + max < n will cut the search short.
(There's another reason: Usually, sizes and indices are represented by unsigned types, e.g. size_t. If you use 0 as initial value, your code will work for unsigned types.)
The algorithm isn't the most efficient for large arrays, but it should work.
try to input 20 numbers with array and to output
the numbers in the double location only but somehow it's print
also the 0 location... please help.
#include<stdio.h>
#define n 20
int main()
{
int num[n]={0},i=0,order=1,double_locaion=0;
for(i=0;i<n;i++)
{
printf("please enter %d number\n",order);
scanf("%d",&num[i]);
order++;
}
for(i=0;i<n;i++)
{
if (i%2==0 && i!=1 && i!=0)
{
printf("%d\n",num[i]);
}
}
}
Try this, start with 2 and increase by 2 every time, the you don't have to deal with 0th element and odd element.
for (i = 2; i < n; i += 2)
{
printf("%d\n",num[i]);
}
First of all there is no way that your code is printing the 0-th location of the array. That's impossible given the condition of the if statement.
Secondly n- you don;t need to use macro expansion for that name.
/* This program takes 20 integer number from input.
* Prints the numbers entered in odd positions.(First,Third,..etc).
*/
#include<stdio.h>
#include<stdlib.h>
#define NUM 20
int main(void)
{
int numArr[NUM];
for(size_t i = 0; i < NUM; i++) {
printf("please enter %zu number\n",i+1);
if( scanf("%d",&numArr[i]) != 1){
fprintf(stderr, "%s\n","Error in input" );
exit(1);
}
}
for(size_t i = 0; i < n; i++)
{
if( i%2 == 0 )// if you want to omit the first number put the
// the condition (i%2 == 0 && i)
{
printf("%d\n",numArr[i]);
}
}
return 0;
}
What you did wrong that your code skipped 0th element?
if (i%2==0 && i!=1 && i!=0)
^^^^
i when 0 makes this condition false - and you never get to print it.
i!=1 ?
If i=1 then i%2 will be 1, so you will not even check the second conditions, the whole conditional expression will become false. So you can safely omit this logic.
Is there a better way?
Sure,
for(size_t i = 0; i < n; i += 2){
printf("%d\n",num[i]);
}
Explanation
If you consider that every time you check the modular arithmetic of 2 the elements which results to 0 remained are
0,2,4,6,8,10,...18
See the pattern? Starts with 0 and increments by 2 each time and when does it stop? Yes before reaching 20 coding it we get
for(size_t i = 0; i < n; i += 2){
/* Initialize with i=0 as first number is 0 (i=0)
* Increments by 2 (i+=2)
* Runs when less than 20 (i<n)
*/
printf("%d\n",num[i]);
}
If you want to omit the 0-th index do initialize properly
for(size_t i = 2; i < n; i += 2){
If you mean you want the numbers from array that are present at even position than you can do like this:
for (i = 2; i < n; i=i + 2) //Initialize i = 0 if 0 is consider as even
{
printf("%d\n",arr[i]);
}
I above code i is initialized to 2 and the increment in each iteration is 2 so it will access elements only at even position (2,4,6...).
I calculated difference between each pair and then stored the maximum difference pertaining to that element in the same array at that location only , for instance array is 1 2 3 , so a[0]=2 , a[1]=1 , since difference of 1 is maximum with 3 and difference of 2 is maximum with 3 , Now whatever manipulations I do I perform with the array size reduced by 1 , so Now I calculate the maximum difference value and place it in 0th index and after that I run a loop till the size of reduced array and count the no of times this maximum value appears , but this approach takes too long , can someone suggest some simple logic .Input is of the form
No of test cases is for e.g 2
no of elements in first array
maximum no of pairs in 1st array
no of elements in 2nd array
maximum no of elements in 2nd array
#include <stdio.h>
#include<math.h>
int max=0;
int main()
{
int test_no, n1,n2,i,j,a,b,count1=1,count2=1;
scanf("%d",&test_no);
printf("\n");
scanf("%d",&n1);
printf("\n");
int arr1[n1];
for(i=0;i<n1;i++)
{
scanf("%d ",&arr1[i]);
}
for(i=0;i<n1-1;i++)
{
for(j=i+1;j<=n1-1;j++)
{
a=abs(arr1[i]-arr1[j]);
if(max<=a)
max=a;
}
arr1[i]=max;
max=0;
}
int temp;
max=arr1[0];
for(i=1;i<n1-1;i++)
{
if(max<arr1[i])
{
temp=max;
max=arr1[i];
arr1[i]=temp;
arr1[0]=max;
}
}
for(i=1;i<n1-1;i++)
{
if(arr1[i]==arr1[0])
{
count1++;
}
}
printf("\n");
scanf("%d",&n2);
int arr2[n2];
max=0;
for(i=0;i<n2;i++)
{
scanf("%d ",&arr2[i]);
}
for(i=0;i<n2-1;i++)
{
for(j=i+1;j<=n2-1;j++)
{
a=abs(arr2[i]-arr2[j]);
if(max<=a)
max=a;
}
arr2[i]=max;
max=0;
}
temp=0;
max=arr2[0];
for(i=1;i<n2-1;i++)
{
if(max<arr2[i])
{
temp=max;
max=arr2[i];
arr2[i]=temp;
arr2[0]=max;
}
}
for(i=1;i<n2-1;i++)
{
if(arr2[i]==arr2[0])
{
count2++;
}
}
printf("%d \n",count1);
printf("%d",count2);
return 0;
}
Sort the array (this takes n log n time).
The maximum difference is now obviously the value of the last element minus that of the first.
To get that same difference, you need the same first element and the same end element*, so that you only need to count how many elements are equal to the first (say 4), how many elements are equal to the last (say 3), and take the lesser of the two values (here 3).
size_t i;
for (i = 1; i < arrayLength/2; i++) {
if ((sortedArray[i] != sortedArray[0])
||
(sortedArray[n-1-i] != sortedArray[n-1])) {
break;
}
}
// i is now the number you need.
To sort an array in C you also have a ready-made library function.
Or you can do this in O(N) time, by simply scanning the array:
int minVal = INT_MIN;
int maxVal = INT_MAX;
int cntMin = 0;
int cntMax = 0;
for (i = 0; i < n; i++) {
if (arr[i] < minVal) {
minVal = arr[i];
}
if (arr[i] > maxVal) {
maxVal = arr[i];
}
if (arr[i] == minVal) { cntMin++; }
if (arr[i] == maxVal) { cntMax++; }
}
if (minVal == maxVal) {
return n/2;
}
return min(cntMin, cntMax);
Example:
0 0 0 0 1 2 3 4 5 6 6 6
Maximum difference is 6 and is to be found 3 times.
0 1 2 3 4 5 6 6 6
Maximum difference is still 6, and is to be found once only.
If you want to count all possible pairs (e.g. in [ 01, 02, 61, 62, 63 ] you want to have (01,61) ... (02, 63) ), even if your note about removing elements seems to indicate otherwise, then instead of returning the minimum of cntMin and cntMax, just return their product. If they are equal, return N*(N-1) ).
--
(*) to get the same difference with two different numbers, one of them has to be either less than the minimum, or more than the maximum, of the initial range, which is contradictory. E.g. to get 6 other than from 6 and 0, you would need 7 and 1, or 5 and -1. But 7 is more than 6, and -1 is less than 0. So your array's maximum difference once it includes either 7 or -1 is no longer 6.
All you need to do is count how many times the smallest and the largest number are present in the array. When you have done that the number of pairs is found by a simple multiplications.
This can be done like:
#include <stdio.h>
#include <limits.h>
#define N 7
int main(void) {
int arr[N] = {1, 2, 1, 4, 1, 5, 5};
int max = INT_MIN;
int min = INT_MAX;
int i;
int countmax = 0;
int countmin = 0;
for (i=0; i < N; ++i)
{
if (arr[i] > max)
{
// Found new max value --> reset counter to 1
countmax = 1;
max = arr[i];
}
else if (arr[i] == max)
{
// Found same max value --> increment counter
countmax++;
}
if (arr[i] < min)
{
countmin = 1;
min = arr[i];
}
else if (arr[i] == min)
{
countmin++;
}
}
if (max == min)
{
// Special case: All elements are the same
printf("%d pairs with difference 0 found\n", N*(N-1)/2);
else
{
printf("%d pairs with difference %d found\n", countmin * countmax, abs(max-min));
}
return 0;
}
Output:
6 pairs with difference 4 found