So I have a program to find the total number of ways in which an integer N can be expressed as the sum of "n" integers.
For example, 10 can be expressed as a combination of 2,3 and 5 as follows-
10 = 5 + 5
10 = 5 + 3 + 2
10 = 3 + 3 + 2 + 2
10 = 2 + 2 + 2 + 2 + 2
#include<stdio.h>
#include<stdlib.h>
int ways(int,int*,int);
int main() {
int n,num; //n is number of possible integers
scanf("%d",&n);
int*curr=(int*)malloc(n*sizeof(int)); //dynamically allocated array that stores all "n" integers in array form
for(int i=0;i<n;i++) {
scanf("%d",curr+i);
}
int t,N; //t is number of test cases
scanf("%d",&t);
while(t--) {
scanf("%d",&N); //for each test case, scans the number N that needs to be expressed as a sum of combinations those "n" integers
num=ways(N,curr,n);
printf("%d\n",num);
}
return 0;
}
int ways(int N,int*p,int size) {
int flag=1;
for(int i=0;i<size;i++) {
if(N/(*(p+i))!=0) {
flag=0;
break;
}
//Above loop says that if number N is less than all of the "n" integers, it
cannot be expressed as their sum. Hence, 0 will be returned if flag is 1
}
if(flag==1)
return 0;
if(N==0)
return 1;
int num=0,temp;
for(int i=0;i<size;i++) {
temp=*(p+i);
num=num+ways(N-temp,p,size); //GETTING RUNTIME ERROR AT THIS LINE
}
return num;
}
The program is getting SIGSEGV error at the recursive function call even for very small depth of recursion
In the first i loop in ways, you seem to be looking for a value in
array p that is smaller than N (though division is a horribly
inefficient way to test). Having found one, you do other things, then
use another i loop, losing the value of i you found in the first
one, and call ways recursively.
Now, note that you do no testing in the second loop. It’s entirely
possible to subtract something from N that is larger than N, get a
negative result, and pass that. This would cause infinite recursion, no?
A SIGSEGV error is a Segmentation fault error, which means that you are trying to access a memory location out of your programs reach.
This is most common due to de-referencing a null pointer or going over in your for loop. Try checking the logic of your code.
I think when you are typing *(p + 1), you are going out of bounds at some point. Try debugging with breakpoints or by outputting the value of *(p+1) in the for loop.
Related
I was making a program in C Language that determines the most frequently appeared number in an array, and also outputting the smallest most frequently appeared number, however I am encountering a bug and I was not sure which part I did wrong.
Here is the example of the program input
2
8
1 1 2 2 3 4 5 5
8
5 5 4 3 2 2 1 1
The number 2 means to create 2 different arrays, the number 8 determines the size of the array. the number afterwards determine the numbers to be put inside of the array, and the program repeats itself by inputting the size of an array etc.
Here is the expected output :
Case #1: 2
1
Case #2: 2
1
The "Case #1: 2" means that the most frequently appeared number appeared 2 times in the array (number 1 2 and 5, each appeared twice in the array), while it prints number 1 because number 1 is the smallest number in the most frequently appeared. and the same goes on for case #2
However, in my program, when I input the second case, it does not properly print the smallest number, and instead just prints nothing. But weirdly enough, if I input a different number in the second array (instead of just the first array in reverse order) it prints the correct smallest number. Here is the example output that my program creates
Case #1: 2
1
Case #2: 2
Here is the code that I made :
#include <stdio.h>
int main(){
long long t, n;
scanf("%lld",&t); //masukkin berapa kali mau bikin array
for(int x=0;x<t;x++) {
scanf("%lld",&n); // masukkin mau berapa angka per array
long long arr[200000]={0};
long long i, count, freq=0, test=0;
for(i=0; i<n; i++){
scanf("%lld", &count); //masukkin angka ke dalem array
arr[count]++;
}
for(i=0; i<200000; i++){
if(arr[i]>0 && arr[i]>=freq){
freq=arr[i];
}
}
printf("Case #%d: %lld\n",x+1,freq);
int min;
for(i=0; i<200000; i++){
if (arr[i] > min){
min = arr[i];
printf("%lld",i);
test=1;
}
}
printf("\n");
}
return 0;
}
Your problem is here:
int min;
min is not initialized so when you do if (arr[i] > min){ you have no idea what value min has.
So do
int min = INT_MIN;
That said, you don't really need min. The first arr[i] that equals freq will tell you that i is the smallest number.
Further notice that
long long arr[200000]={0};
is a bad idea. Huge arrays should never be defined as local variables as it may lead to stack overflow. Make it a global variable or use dynamic allocation.
And you should change
arr[count]++;
to
if (count >= 200000)
{
// Too big - add error handling
...
}
else
{
arr[count]++;
}
And you don't need an extra loop for finding freq. Find freq when you get the input.
In an interview they asked me to find out the missing number from an array.
array will be having number from 1 to N.
My Approach:
int main()
{
int ar[20];
int sum = 0;
int n;
printf("enter numb of elements\n");
scanf("%d", &n);
printf("enter array numbers\n");
for(int i = 0; i<n;i++){
scanf("%d", &ar[i]);
sum +=ar[i];
}
printf("missing num=%d", ((n*(n+1))/2)-sum);
}
But interviewer did not call back after first round of interview.
I don't know what is wrong with my approach.
Some issues with your code:
The algorithm is wrong (off by one): If the array contains all numbers from 1 to N except for one missing number, then it has N-1 elements. Your code reads N elements. (Alternatively, if the array actually has N elements, then the target sum is (N + 1) * (N + 2) / 2 (sum of numbers from 1 to N+1), not N * (N + 1) / 2.)
Includes are missing (in particular, #include <stdio.h>). That means the calls to printf / scanf have undefined behavior.
int main() should be int main(void).
None of the scanf calls check their return value. That means your code doesn't realize when reading input fails, producing garbage output.
If n is bigger than 20, your code silently writes outside the bounds of ar. That's a classic buffer overflow.
The previous point is especially unfortunate because your code doesn't even need the array. All you do with the input numbers is to add them up in sum, which doesn't require a separate array.
Your formatting is inconsistent in for(int i = 0; i<n;i++){. Why is there no space in for(int and i<n;i++){, but there are spaces around i = 0;?
Depending on how big N is, n*(n+1) could overflow.
The last line of output produced by your code is missing its terminating newline: printf("missing num=%d\n", ...);
I am a beginner to C language and also computer programming. I have been trying to solve small problems to build up my skills. Recently, I am trying to solve a problem that says to take input that will decide the number of series it will have, and add the first and last number of a series. My code is not working and I have tried for hours. Can anyone help me solve it?
Here is what I have tried so far.
#include<stdio.h>
int main()
{
int a[4];
int x, y, z, num;
scanf("%d", &num);
for (x = 1; x <= num; x++) {
scanf("%d", &a[x]);
int add = a[0] + a[4];
printf("%d\n", a[x]);
}
return 0;
}
From from your description it seems clear that you should not care for the numbers in between the first and the last.
Since you want to only add the first and the last you should start by saving the first once you get it from input and then wait for the last number. This means that you don't need an array to save the rest of the numbers since you are not going to use them anyway.
We can make this work even without knowing the length of the series but since it is provided we are going to use it.
#include<stdio.h>
int main()
{
int first, last, num, x = 0;
scanf("%d", &num);
scanf("%d", &first);
last = first; //for the case of num=1
for (x = 1; x < num; x++) {
scanf("%d", &last);
}
int add = first + last;
printf("%d\n", add);
return 0;
}
What happens here is that after we read the value from num we immediately scan for the first number. Afterwards, we scan from the remaining num-1 numbers (notice how the for loop runs from 1 to num-1).
In each iteration we overwrite the "last" number we read and when the for loop finishes that last one in the series will actually be the last we read.
So with this input:
4 1 5 5 1
we get output:
2
Some notes: Notice how I have added a last = first after reading the first number. This is because in the case that num is 1 the for loop will never iterate (and even if it did there wouldn't be anything to read). For this reason, in the case that num is 1 it is reasonably assumed that the first number is also the last.
Also, I noticed some misconceptions on your code:
Remember that arrays in C start at 0 and not 1. So an array declared a[4] has positions a[0], a[1], a[2] and a[3]. Accessing a[4], if it works, will result in undefined behavior (eg. adding a number not in the input).
Worth noting (as pointed in a comment), is the fact that you declare your array for size 4 from the start, so you'll end up pretending the input is 4 numbers regardless of what it actually is. This would make sense only if you already knew the input size would be 4. Since you don't, you should declare it after you read the size.
Moreover, some you tried to add the result inside the for loop. That means you tried to add a[0]+a[3] to your result 4 times, 3 before you read a[3] and one after you read it. The correct way here is of course to try the addition after completing the input for loop (as has been pointed out in the comments).
I kinda get what you mean, and here is my atttempt at doing the task, according to the requirement. Hope this helps:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int first, last, num, x=0;
int add=0;
printf("What is the num value?\n");//num value asked (basically the
index value)
scanf("%d", &num);//value for num is stored
printf("What is the first number?\n");
scanf("%d", &first);
if (num==1)
{
last=first;
}
else
{
for (x=1;x<num;x++)
{
printf("Enter number %d in the sequence:\n", x);
scanf("%d", &last);
}
add=(first+last);
printf("Sum of numbers equals:%d\n", add);
}
return 0;
}
I have some problem with that. I am trying to learn C programming. Please help me
#include<stdio.h>
int main()
{
int a, factorial;
printf("Please enter a value :" );
scanf("%d", &a);
for (int i = 1; i<=a; i++)
{
a = (a - 1)*a;
}
printf("%d", factorial);
return 0;
}
Well in your code line a = (a - 1)*a; you actually changed your input for getting the factorial. It also will blow your loop. See your for loop will continue as long as your i is less than a, lets say you choose a=3 after first iteration the a itself will become 6, so the for loop will continue until it reach the integer limit and you will get overflow error.
What you should do?
First of all you should use a second variable to store the factorial result, you introduced it as factorial, the way that #danielku97 said is a good way to write a factorial since if you present 0 as input it will also give the correct result of 1. so a good code is:
factorial = 1;
for (int i = 1; i<=a; i++)
{
factorial *= i;
}
But lets say you insist of subtraction, the way you just tried to use, then you need to change the code like:
scanf("%d", &a);
if (a==1 || a==0){
printf("1");
return 0;
}
factorial = a;
for (int i = 1; i<a; i++)
{
factorial *= (a - i)*factorial;
}
You can see that the code just got unnecessarily longer. An if included to correct the results for 1 and 0. Also you need to make sure that i never become like i =a since in that case a-i will be equal to zero and will make the factorial result equal to zero.
I hope the explanations can help you on learning C and Algorithm faster.
Your for loop is using your variable 'a' instead of the factorial variable and i, try something like this
factorial = 1;
for (int i = 1; i<=a; i++)
{
factorial *= i;
}
You must initialize your factorial to 1, and then the for loop will keep multiplying it by 'i' until 'i' is greater than 'a'.
You are modifying the input a rather than factorial and also wrong (undefined behaviour) because you are using factorial uninitialized. You simply need to use the factorial variable you declared.
int factorial = 1;
...
for (int i = 1; i<=a; i++) {
factorial = i*factorial;
}
EDIT:
Also, be aware that C's int can only hold limited values. So, beyond a certain number (roughly after 13! if sizeof(int) is 4 bytes), you'll cause integer overflow.
You may want to look at GNU bugnum library for handling large factorial values.
This is a code I submitted at sphere online judge for generating prime numbers but I'm getting a segmentation fault. The objective is to generate prime numbers between the given range m to n (with n > m). This is implemented using the Sieve of Eratosthenes algorithm. Please tell me where im going wrong. Thanks :)
#include <stdio.h>
#include <math.h>
int main(){
long int m,n,c1,c2,c3;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&m,&n);
//create prime list
short int *prime;
prime = (short int*)malloc((n-m)*sizeof(short int));
//fill list with 0 - prime
for(c1 = 2; c1 <= n; c1++){
prime[c1] = 1;
}
//set 1 and 0 as not prime
prime[0]=0;
prime[1]=0;
//find primes then eliminate their multiples (0 = prime, 1 = composite)
for(c2 = 2;c2 <= (int)sqrt(n)+1;c2++){
if(prime[c2]){
c1=c2;
for(c3 = 2*c1;c3 <= n; c3 = c3+c1){
prime[c3] = 0;
}
}
}
//print primes
for(c1 = m; c1 <=n; c1++){
if(prime[c1]) printf("%d\n",c1);
}
}
return 0;
}
c3 can go up to n in the innermost loop, but you only may allocate less than n slots in your array. In fact, even if you allocated n slots, index n would be one more than the number of slots you allocated. At worst, you'd just corrupt some memory past the end of the array and hopefully not trash the stack. At best, I guess you get a segfault. You probably want to change your X <= n to X < n or allocate one more element in your array. In fact, you probably should just allocate (n + 1) * sizeof(short) bytes for your array.
Also, you never set t and you never never validate the user input. The latter may be okay if this is for a competition which would have constraints on input. Also, you never free the prime array, so you have a memory leak.
Of course it will you are allocating a memory which is (n-m) & you are acessing
prime[n] ,
Probably want to avoid this when prime is only 1 element long:
//set 1 and 0 as not prime
prime[0]=0;
prime[1]=0;
You malloc(n-m), but in the following loop you initialize prime[2..n]. n-m is at most 1E5, but n itself could be 1E9 (which is rather huge number). Your simple idea probably can not be implemented, because malloc(1E9) will probably fail. You need a smarter algorithm.