I am not getting desired output for a C program - c

I am doing a c program but the sample input is not giving the sample output if I use the. I think my program is not calling the function. I guess I have declared it incorrectly. Or my logic is wrong. What I am getting is a zero as output. The question is given below.
Write a C function to find the kth occurrence of an integer n in a sequence of non-negative integers, and then call your function from
main.
Your function should be according to the following declaration:
int find(int n, int k);
Input
You are given the input in two lines:
The first line contains a non-negative integer, say n, and a positive
integer k, in that order. You have to find the kth occurrence of n in
the sequence below.
The second line consists of a sequence of non-negative integers,
terminated with a -1. The -1 is not part of the sequence.
Output
If n occurs k times in the sequence, then output the index of the kth
occurrence of n in the sequence.
If n does not occur k times in the sequence, then output -1.
(For example, the second occurrence of the integer 3 in the sequence
1 1 3 2 3 -1 is at position 4 in the sequence. The first index in the
sequence is 0.)
Input:
3 2
1 1 2 3 3 -1
Output:
4
Code:
#include<stdio.h>
int check(int a,int n ,int k ){
int f;
int value;
int counter=0;
counter++;
if (a==n)
{
f++;
}
if(f==k)
{
value= counter;
}
return value;
}
int main(void)
{
int n , k,a;
int tempo;
scanf("%d",&n);
scanf("%d",&k);
while(a!=-1)
{
scanf("%d",&a);
tempo=check(a,n,k);
}
printf("%d",tempo);
return 0;
}

Your check function has numerous problems:
int check(int a,int n ,int k ){
Your prototype does not match the one in the assignment - you're only supposed to take 2 arguments, neither of which is the sequence of values you're checking against. Somehow, someway, you are supposed to access that sequence from within the body of the function, either by referencing a global array (bad), or by reading the input sequence from within the body of the function (slightly less bad, and probably the intent of the exercise1).
int f;
int value;
auto variables are not implicitly initialized in a declaration - their initial value is indeterminate (it may be 0, it may be a trap representation, it may be a valid non-zero integer value). This will cause problems later.
int counter=0;
counter++;
I think I know what you're trying to go for here, and it won't work as written2 - counter only exists for the lifetime of the function. Each time you call check, a new instance of counter is created and initialized to 0. It won't remember the value stored in it from a previous call.
if (a==n)
{
f++;
f isn't guaranteed to be 0 at this point (or any other specific value). It could be 0, or it could be any non-zero value, or even a trap representation (a bit pattern that does not correspond to a valid integer value).
}
if(f==k)
{
value= counter;
}
return value;
}
At this point, counter is only ever going to be 1 - you initialize it to 0 at function entry and immediately increment it, then you never touch it again. So value is only ever going to be indeterminate or 1.
So, how should you proceed from here and satisfy the requirements of the assignment?
The less bad option is to read the sequence from within the check (or find) function, although that's still pretty bad (again, I/O should be a separate operation, and we're assuming all input comes through stdin).
int find( int n, int k )
{
int next; // next value in the sequence
... // additional items for index, number of matches, etc.
while ( scanf( "%d", &next ) == 1 && next != -1 )
{
// update index, does next match n, is it the k'th match, etc.
}
...
}
scanf is a poor tool for interactive input, but at this point is the simpler approach.
Which, honestly, isn't any better than keeping a global array. I/O should be factored out from computation whenever possible, and if a function *is* required to read from an input stream, that stream should be specified as a parameter to the function - you shouldn't force your code to assume all input comes through stdin.
counter would need to be declared static for it to retain its value from call to call.

My solution is totally extension of what John Bode said above and as John Bode said, you are using more parameters than the preferred. You should stick to only 2 parameters. And as you have two parameters n(for search element) and K(k th occurrence) you cant pass an sequential array to that function, So you should start reading(scanning) the sequence inside the find().
As the program clearly says it terminates with -1. You can use this to end the loop in terminating the find function.
Scan function returns true as long as it reads. even for -1 it returns true so you should use the value!=-1. And inside the loop you can use your logic of matching and finding the index number.
int find(int n, int k){
int next;
int match=0;
int index=0; //for parsing the sequence
while( scanf("%d", &next) ==1 && next!=-1){
if(next == n){
match++;
if(match==k)
return index;
}
index++; //move the index
}
return -1;
}

Related

How to print contact number as one by one without using looping and default conversion?

Example : My contact number is 9876543210. We will save this number as either as integer or longInt as we know. Actually i need to print my contact number as one by one without any conversion (Int -> String) and do not use looping.
If you are still stuck on how to approach a recusive function, start with understanding that every recursive function has 2-parts:
1 A Base-Case which is the condition that is checked to determine when the recursion should end; and
2 A Recursive Call (meaning the function calls itself).
In your case of extracting the digits from a number, you simply want to extracts the first digit with number % 10 which will isolate the least significant base-10 digit. Then you want to divide the number by 10 and repeat.
Where you would normally repeat by calling the modulo and division in a loop, here you want to make a separate function call passing the result of number / 10 as the new parameter to your function.
You continue until your Base-Case is satisfied, and then the recursion begins to unwind where you return from the deepest function where you reach your Base-Case back into the previous function call -- and all the way back to the original. Careful placement of your outputting of the ASCII character for that digit will allow the numbers to be printed in-order.
A very minimal recursive function to do this could look like:
#include <stdio.h>
void prnnum (int n)
{
if (n == 0) /* base-case, when n==0, stop recursion */
return;
int digit = n % 10; /* save digit to print */
prnnum (n / 10); /* make recursive call */
putchar (digit + '0'); /* output ASCII value of digit on return */
}
(thinking though what may be needed to accommodate negative values, if anything, etc.. is left to you)
You can add a short main() that lets you pass in different numbers to test, e.g.
int main (int argc, char **argv) {
int n = 54321;
if (argc > 1 && sscanf (argv[1], "%d", &n) != 1)
return 1;
prnnum (n);
putchar ('\n');
}
Example Use/Output
Running without any command line input using the default value for n = 54321;, you receive:
$ ./bin/recursiveprnnum
54321
Passing in another number as the 1st argument you could do:
$ ./bin/recursiveprnnum 9378456
9378456
And in each case the digits have been printed one digit at a time and without a loop. Look things over and let me know if you have further questions.
You can also do this with using pointers but taking modulus of number by 10 is the easiest method but it has limitations. If you have + at the start of the number then this method will not work as it only deals with digit..So my method will work for both cases.
#include <stdio.h>
// Function Prototype
void printNum(char *num);
int main(){
// Creating a pointer, pointing
// toward your number or anyother array
char *num = "9876543210";
// Calling printNum function to
// print array word by word.
printNum(num);
return 0;
}
void printNum(char *num){
/**********************************************
This function takes a pointer to an array and
call itself again and again untill it founds
null character
***********************************************/
char *pnum;
pnum = num;
printf("%c\n", *pnum); // print character on current address
if(*pnum!='\0') // This logic is used to avoid any loop
printNum(++pnum); // increment 1 byte to address and call the funtion.
}

How to print a 1 to N without using semicolon ? Explain this code

// A recursive C program to print all numbers from 1
// to N without semicoolon
#include<stdio.h>
#define N 10
int main(int num)
{
if (num <= N && printf("%d ", num) && main(num + 1))
{
}
}
How is this program working ?. Please Explain this
The code in this awful example relies on some fragile assumptions:
main is called with 2 arguments: an int representing the number of arguments, including the program name, and an array of char* containing the argument string terminated by a NULL.
The example assumes that defining main() with a single int argument will produce code compatible with this calling convention, which may or may not be valid and is explicitly described as having undefined behavior by the C Standard (J.2).
If it is valid or works by chance, the int argument received by main will be 1 if the program is called from the command line without arguments.
main() tests if this argument is <= N, is other words if the value is to be printed. If so, it invokes printf("%d ", num), which outputs the decimal representation of num to stdout and returns the number of characters produced, 2 for the first number, which is non zero, so the code goes on and invokes main recursively, passing it the next higher number.
The goes on until all numbers up to N have been printed and the first test in the last recursive call fails.
main then returns 0 (if the compiler is complies with the C99 or a later standard). Each recursive call returns 0 until the initial call returns 0 to the system.
The code is fragile because main is invoked in a non standard way. It would be slightly less ugly to write:
#include <stdio.h>
#define N 10
int main(int argc, char *argv[]) {
if (num <= N && printf("%d ", num) && main(num + 1, argv)) {}
}
Note however that calling main() recursively is generally considered bad practice.
As long as the function inside returns a value convertable to bool, it will be accepted also called.
If successful, the total number of characters written is returned. On failure, a negative number is returned.
Above is the return value of printf() function. So yeah printf("%d ", num) will always return true in this case and print at each iteration.

Why we can't compare a int variable with int return type function in c?

I tried to compare int variable with the function in two ways:
storing the int function return value in a variable then comparing with another
in value.
Directly comparing the int variable and the function call.
Here I got the answer for the first one but not for the second one.
Why does this happen?
My code:
#include < stdio.h >
int count = 0;
int countDigits(int);
int main() {
int i;
int result = countDigits(435);
for (i = 0; i < result; i++) {
printf("id %d\n", 3);
}
for (i = 0; i < countDigits(435); i++) {
printf("i =%d\n", i);
}
}
int countDigits(int n) {
if (n == 0) {
return count;
} else {
countDigits(n / 10);
count++;
}
}
We can.
It's just that your function has a logical error. Debug it, and you will be fine.
Enabling compiler warnings would have helped you. For example with GCC and Wall flag, you get:
prog.c: In function 'countDigits':
prog.c:32:1: warning: control reaches end of non-void
function [-Wreturn-type]
}
^
Tip: Think of what your function does if n us different than zero.
count is a global variable.
The function countDigits(n) adds the number of decimal digits in n to count and
If n is zero it returns 1.
If n is non-zero the return value is undefined.
Since countDigits(435) has an undefined value, anything can happen and no further analysis is necessary.
Let's assume that this obvious error is corrected by inserting return count; after count++;. In this case, the function returns the incremented count.
So we have this nice sequence:
Set result to countDigits(435).
countDigits(435) adds 3 to count and returns 3.
Set i to 0 and compare to countDigits(435).
countDigits(435) adds 3 to count and returns 6. 0 is less than 6, so the for loop continues.
Now i is 1, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 9. 1 is less than 9, so the for loop continues.
Now i is 2, and we compare it to countDigits(435).
countDigits(435) adds 3 to count and returns 12. 2 is less than 12, so the for loop continues.
... And so on.
Morality:
Beware of side effects. Never use and modify global variables unless you have a good reason to.
When you must use side effects, keep them prominent in your mind.
It is possible to compare a variable directly with the output of a function. However, your function countDigits has several problems.
Not all code paths return a value - you're missing a return statement in the else block. This alone makes the output of the function undefined.
It's not algorithmically correct. Have you tried debugging it? Just start with printing the output for different inputs and you'll see.
Modifying and returning a global variable count inside that function is a really bad practice - it should be local to the function. When it's global, every call to the function modifies a [possibly] already modified variable.
Others have already addressed the problem here with globals, so I will not go into details about that. Instead, here is a solution without globals:
int countDigits(int n) {
int count = 0;
while(n>0) {
n/=10;
count++;
}
return count;
}
I guess you could be philosophical about whether 0 has 0 or 1 digit, but your code implied that you wanted it to be 0. If you want it to be 1 instead, just change the first row to int count = 1.

Array index of smallest number greater than a given number in a sorted array using C

Need to find the index of a number, that may or may not be present in the array. I tried the below code:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void *lhs, const void *rhs){
return ( *(long long*)lhs - *(long long*)rhs );
}
int main(){
int size = 9;
long long a[] = {16426799,16850699,17802287,18007499,18690047,18870191,18870191,19142027,19783871};
long long x = 17802287;
long long *p = (long long *)bsearch(&x, a, size, sizeof(long long), cmp);
if (p != NULL)
printf("%lld\n", p - a);
return 0;
}
The above code works if the number, in this case 17802287 is present in the array a, but fails if the number is not present in a, e.g. doesn't give any output for x=18802288, I would like to get the index i=5 in that case 5th element onwards the elements are greater than 18802288.
Also the actual array size will have number of elements more than 4 million, would the same code work?
Thanks for the help.
From the man page for bsearch:
The bsearch() function returns a pointer to a matching member of
the array, or NULL if no match is found. If there are multiple
elements that match the key, the element returned is unspecified.
So the function will return NULL if the element in question is not found. If you want to find the first element greater than or equal to the number in question, you'll need to roll your own function to do that.
One of the possible solution can be:
int i, outcome = -1;
for( i = 0; i < size; i++ )
{
if( x == a[i] )
{
outcome = i;
break;
}
}
printf("%d\n", outcome);
You need to write a function that does approximately this:
bsearch_geq (number array low high)
if low is equal to high return high
let halfway be average of low and high
if array[halfway] is equal to number then return halfway
if array[halfway] is greater than number then
return result of "bsearch_geq number array low halfway"
else
return result of "bsearch_geq number array halfway high"
That'll get you 99% of the way, I think, but I'll leave it as an exercise to the reader to figure out the corner cases. The main one I can see is what happens when you get down to just two numbers because the naive "average" may cause infinite recursion.
If you can have multiple occurrences of the same number in the array then you'll need to drop the if array[halfway] is equal]" line.
You should ensure your solution uses tail-recursion for efficiency, but it's not too critical as 4m data-entries only amounts to about 15 recursive calls.

why < is much faster than !=?

Problem : Consider the following algorithm to generate a sequence of
numbers. Start with an integer n. If n is even, divide by 2. If n is
odd, multiply by 3 and add 1. Repeat this process with the new value
of n, terminating when n = 1. The input will consist of a series of
pairs of integers i and j, one pair of integers perline. All integers
will be less than 1,000,000 and greater than 0.
For each pair of
input integers i and j, output i, j in the same order in which they
appeared in the input and then the maximum cycle length for integers
between and including i and j. These three numbers should be separated
by one space, with all three numbers on one line and with one line of
output for each line of input.
sample input :
1 10
sample output:
1 10 20
so i wrote this :
#include <stdio.h>
#include <string.h>
struct line{int in1;int in2;int result;};
int cycle(int in);
int main(int argc, char *argv[]) {
int cycle(int in);
char c;
int firstIn=0;
struct line l[500] ;
int pointer=0;
while(2<3){
l[pointer].in1=0;
l[pointer].in2=0;
scanf("%u %u",&l[pointer].in1,&l[pointer].in2);
if(l[pointer].in1<1||l[pointer].in2<1){
break;
}
int maxCyc=0;
int j,m;
int min,max;
if(l[pointer].in1>l[pointer].in2){
max=l[pointer].in1;
min=l[pointer].in2;
}
else{
max=l[pointer].in2;
min=l[pointer].in1;
}
for(j=min;j<=max;j++){
m = cycle(j);
if(m>maxCyc)
maxCyc=m;
}
l[pointer].result=maxCyc;
printf("%d %d %d\n",l[pointer].in1,l[pointer].in2,l[pointer].result);
pointer++;
}
}
int cycle(int in){
int cyc = 1;
while(in>1){
if(in%2==0){
cyc++;
in=in/2;
}
else{
cyc++;
in=in*3+1;
}
}
return cyc;
}
Its completly ok but when you change while(in>1) in cycle method to while(in!=1) it gets much more slower. my question is why?!
Time when its while(in>1) : 0.683 sec
and when its while(in!=1) : I waited more than 5 min nothing
happened yet :)
for input : 1 1000000
there is no infinite loop or something because in cant get below 1 at all(for that it must be already 1) .
Best regards
When you call cycle with the input value 113383, the process eventually sets n to
827370449, and 3*827370449+1 is 2482111348, which is greater than the maximum signed int and is interpreted as -1812855948. So there's your first negative number where there should be no negative number.
If this process then eventually sets n to -2, it will loop infinitely between -2 and -1 from then on. There may be other loops I haven't considered.
If you were to use an unsigned int, there is a possibility (I haven't checked) that this too will overflow eventually, which will not result in a negative value but will result in an incorrect value, invalidating your results.
No matter what integer representation you use, it would probably be a good idea to compare n with (maximum-1)/3 at the top of each loop, where maximum is the largest possible positive value of your integer type, just to be sure you do not overflow.
As you told me it was a simple overflow problem thx everyone.
max int value is 2,147,483,647; So when i changed int cycle(int in) to int cycle(long long int in) my problem was solved.
i also figured it out that my first answer with while(in>1) was wrong.
When an integer overflow occurs,the value will go below 0 .That was the reason while(in!=1) was an infinte loop.
I was really tired that i didn't figure it out by myself. sorry for that :)

Resources