I am trying to solve a problem and I've run into a bit of an issue.
I have to find the running average of a series of numbers.
Example:
input 4 2 7
output 4 3 4.3333
Now here's the problem although I get the answer, it is not the precise answer.
Accepted Output: accuracy difference shown in the image
290.6666666667
385.4000000000
487.8333333333
477.4285714286
496.4444444444
...
523.8571166992
506.0454406738
495.3043518066
I can't find whats wrong. Some help would be highly appreciated.
#include<stdio.h>
main(){
int n;
printf("set:");
scanf("%d",&n);
float arr[n+1],resarr[n+1];
float sum=0;
for(int i=1; i<=n; i++){
scanf("%f",&arr[i]);
sum=arr[i]+sum;
float res= sum/(float)i;
resarr[i]=res;
}
int i=1;
while(i<=n) {
printf("%0.10f\n",resarr[i]);
i++;
}
return 0;
}
Here
for(int i=1; i<=n; i++){ }
you are trying to access out of bound array elements, this certainly causes undefined behavior as let's assume if n is 5 then you are accessing arr[5] also which doesn't exist.
C doesn't perform array boundary condition check, its programmer responsibility to not to access out of bound elements else it causes UB.
In C array index starts from 0 not from 1. So better start rotating loop from 0 to n. For e.g
for(int i=0; i<n; i++) {
scanf("%f",&arr[i]);
/* some code */
}
Code fails to achieve the desired accuracy as it is using float rather than double. #Some programmer dude
Typical float is precise to 1 part in 223. For printing to 0.0000000001, better to use double which is typically precise to 1 part in 253.
#include<stdio.h>
int main(void) {
//float arr[n + 1], resarr[n + 1];
//float sum = 0;
double arr[n + 1], resarr[n + 1];
double sum = 0;
...
// scanf("%f", &arr[i]);
scanf("%lf", &arr[i]);
...
// float res = sum / (float) i;
double res = sum / i; // cast not needed as `sum` is `double`
...
}
Iterating from 1 is not idiomatic in C. More common to iterate starting at 0.
size_t is best for array sizing and indexing. int may be too narrow. Of course with small arrays, it makes scant difference.
#include<stdio.h>
int main(void) {
printf("set:");
size_t n;
scanf("%zu", &n);
double arr[n], resarr[n];
double sum = 0;
for (size_t i = 0; i < n; i++) {
scanf("%lf", &arr[i]);
sum = arr[i] + sum;
double res = sum / (i+1);
resarr[i] = res;
}
for (size_t i = 0; i < n; i++) {
printf("%0.10f\n", resarr[i]);
}
return 0;
}
More robust code would check the input from the user it insure it is valid, allocate rather than use a VLA if n is allowed to be large, flush output before reading, etc.
Note that array arr[] is not needed, just a single double for the input and sum.
Related
#include <stdio.h>
int sumofArrayNum(int numList[]);
int main(){
int result,numList[]={23,32,54,23,54,32,3,35};
result = sumofArrayNum(numList);
printf("sum= %d", result);
return 0;
}
int sumofArrayNum(int numList[]){
int sum = 0;
for(int i = 0; i < 10; ++i){
sum += numList[i];
}
return sum;
}
Output is different each time I build and run it.
E.g. output is sum = 1032918821
Expected output I would like is sum = 256
Parameters like int numList[] is the same as int* numList, compiler will not know elements count of it if it was not explicitly defined. By the way, int numList[8] is also the same as int* numList. C language does not check the range of array.
There are some ways to get and check the array size.
size/count parameter
int sumofArrayNum(int numList[], int listSize){
int sum = 0;
for(int i = 0; i < listSize; ++i){
sum += numList[i];
}
return sum;
}
Here listSize should be the count of elements.
And you can use macro to hide the count parameter:
#define sumofArray(array) sumofArrayNum((array), sizeof(array)/sizeof(*array))
point to the whole array
int sumofArrayNum(int (*numList)[8]){
int sum = 0;
for(int i = 0; i < sizeof(*numList)/sizeof(**numList); ++i){
sum += (*numList)[i];
}
return sum;
}
Call it by sending pointer of array:
result = sumofArrayNum(&numList);
Compiler(such as gcc) can do a weak check for this: give a warning if you send an array which are not int (*)[8].
Note that you have to ensure validity of array, and array size must be constant.
Besides,
Output is different each time I build and run it.
It is because only 8 elements has been defined, index range is 0〜7. numList[8] and numList[9] is undefined, mean any value is possible. Maybe used, changed by other process, random and dangerous.
In numlist there are 8 element that means for loop must execute code 8 times.
Your code must be:
for(int i = 0; i < 8; ++i)
{
sum += numList[i];
}
This code iterate until i=7, when i=8 it will end the loop.
Information on for loop
I am trying to sort an array of structs (A SJF Scheduler). I am using the qsort library function to sort the structs in increasing order according to the attribute bursttime. However, the output is not correct. I've checked some SO questions about the same but they served no use.
struct job
{
int jobno;
int bursttime;
};
typedef struct job job_t;
int mycompare(const void* first, const void* second)
{
int fb = ((job_t*)first)->bursttime;
int sb = ((job_t*)second)->bursttime;
return (fb - sb);
}
int main()
{
int n;
printf("Enter number of jobs: ");
scanf("%d", &n);
job_t* arr = (job_t*)malloc(sizeof(job_t) * n);
for(int i = 1; i <= n; ++i)
{
printf("Enter Burst time for Job#%d: ",i);
scanf("%d", &(arr[i].bursttime));
arr[i].jobno = i;
}
printf("\n");
printf("Order of the Jobs before sort:\n");
for(int i = 1; i <= n; ++i)
{
printf("%d\t", arr[i].jobno);
}
qsort(arr, n, sizeof(job_t), mycompare);
printf("\n");
printf("Order of the Jobs after sort:\n");
for(int i = 1; i <= n; ++i)
{
printf("%d\t", arr[i].jobno);
}
printf("\n");
printf("\n");
return 0;
}
This is my inputfile:
4
7
2
9
4
The output I'm getting is:
Order of the Jobs before sort:
1 2 3 4
Order of the Jobs after sort:
2 1 3 4
The expected order should be: 2,4,1,3. Am I missing anything?
At least this problem
for(int i = 1; i <= n; ++i) // bad
Use zero base indexing.
for(int i = 0; i < n; ++i)
You could change the indexing scheme to start from zero, as others have suggested, and this would certainly be the idiomatic way to do it.
But if you want to use 1-based indexing, you'll need to allocate an extra place in the array (position 0 that will never be used):
job_t* arr = (job_t*)malloc(sizeof(job_t) * (n + 1));
Then you'll need to start your sort at position 1 in the array:
qsort(&arr[1], n, sizeof(job_t), mycompare);
And, of course, you'll have to write your code to index from 1 -- but you've already done that.
The problem is that so many standard functions in C use zero-based indexing that doing anything else is inexpressive. That's a bigger problem than wasting one array position. But, for better or worse, I've had to convert to C a load of code from Fortran, so I've gotten used to working both ways.
i am a beginner in coding ,i am trying to make a program where i input 'n' number of elements in array and find out what percentage of number are positive,negative and zeros.the output is not what i am expecting it is all 'zeros'.Where i input n=3,so the percentage should be .3,.3,.3 when i input numbers one positive,one negative and one zero.
#include <math.h>
#include <stdio.h>
int main()
{
int n;
float per1, per2, per3;
scanf("%d", &n);
int arr[n];
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
int sum1 = 0;
int sum2 = 0;
int sum3 = 0;
for (int i = 0; i <= n - 1; i++)
{
if (arr[i] < 0)
{
int sum1 = sum1 + 1;
}
if (arr[i] > 0)
{
sum2 = sum2 + 1;
}
else
{
sum3 = sum3 + 1;
}
}
per1 = sum1 / n;
per2 = sum2 / n;
per3 = sum3 / n;
printf("%.6f\n%.6f\n%.6f\n", per1, per2, per3);
return 0;
}
output
3
1
-2
0
0.000000
0.000000
0.000000
the last three numbers should be .3,.3,.3 but it is giving zeros.
I think this code is a little bit better. I've used the function malloc() instead of the "scattered" declaration int arr[n] (in this case I prefer the old C style).
People already said you the problem relevant to the variable types and some ways to solve the problem. Here there's another way similar to the others you just saw between the answers.
#include <math.h>
#include <stdio.h>
#include <malloc.h>
#define STR_ORD_SUFFIX(i) (i>3)?"th":(i==0)?"--":(i==1)?"st":(i==2)?"nd":"rd"
int main()
{
int n, *arr=NULL;
float per1,per2,per3;
int sum1=0;
int sum2=0;
int sum3=0;
printf("How many number you have to insert? ");
scanf("%d",&n);
if (n<=0)
return 1;
arr=malloc(n*sizeof(*arr));
if (arr==NULL)
return 2;
printf("Insert %d number%c\n",n,(n!=1)?'s':'\x0');
for(int i = 0; i < n; i++){
printf("%4d%s: ",i+1,STR_ORD_SUFFIX(i+1));
scanf("%d",&arr[i]);
}
for(int i=0;i<=n-1;i++)
{
if(arr[i]<0){
sum1=sum1+1;
} else if(arr[i]>0){
sum2=sum2+1;
} else {
sum3=sum3+1;
}
}
per1=sum1; per1/=n; per1*=100.0;
per2=sum2; per2/=n; per2*=100.0;
per3=sum3; per3/=n; per3*=100.0;
printf("\n<0 %.6f%%\n>0 %.6f%%\n=0 %.6f%%\n",per1,per2,per3);
if (arr!=NULL)
free(arr);
return 0;
}
Do floating point arithmetic like this
per1=sum1/(1.0*n);
per2=sum2/(1.0*n);
per3=sum3/(1.0*n);
How do you calculate percentage of some value? Your answers shouldn't be 1,1,1 but 33%, 33%, 33% for input you have. So your code should instead of this
per1=sum1/n;
be like this
per1=sum1*100.0/n;
And you have also got wrong your if conditions. The else part is tied only to second if. So every number less or equal to 0 is counted into sum3 which is not what you probably meant. So your
if (arr[i] > 0)
should have been
else if (arr[i] > 0)
And one last thing. On this line you are creating completely new variable sum1 that will live only to the end of the if statement and thus will not appear in the final calculation. I will leave it to you how to fix it.
int sum1 = sum1 + 1;
I don't know what environment you are using for development, but you should learn how to use debugger from the beginning. You can then peek into flow of your code to see what is going on and when it went wrong. With simple programs like this it is really easy. If you are on Visual Studio, they have really nice debugger integrated. Just set breakpoint and run Debug. If you are on Linux, there is gdb which might come pretty rough for beginners, but there are also graphical tools like ddd.
Since both sum1 and n are integers, the result of sum1/n is also an integer. This means that if sum1 is less than n, then the result of sum1 / n is 0.
To get a floating point result, at least one of the operands has be be float or double. I suggest you declare your sum variables to be double instead of int.
Ok, so I'm new to both programming and posting on this site and my question is kind of complicated, but I'm going to attempt to articulate my situation. I'm trying to write a code to read a file (a list of polar coordinates) of unknown size, store the values in an array, then perform a conversion and get out a new array with the converted data (technically I'm using this new array in a predesigned function to graph the data in C++, but this is not important since it's part of the assignment and certainly not the source of error).
I'm having 2 major issues, the first of which is the variable array size. In the code following, you can see that there's no constraint on my x and y arrays, so the loop goes on to convert values up to x[999] even if there's nothing in r[] beyond r[40]. I can constrain the size of my r and theta arrays because I can code to stop reading values when the fscanf function reaches the end of the file, but I don't know the analogy for my x and y arrays. (Also, I'd greatly appreciate it if someone could explain why my character array doesn't have this issue, even though it's defined to be up to 128 characters. It might give me the insight I need)
Secondly, the conversion doesn't quite match up. So when I print the converted values, the function converts them correctly, but stores the value converted from r[i] and theta[i] to x[i+1] and y [i+1]. I really have no idea what is causing this problem.
I certainly hope my issues make sense. Any help would be appreciated! If anything is unclear, please let me know and I'll do my best to explain. Thank you!
#include <stdio.h>
#include <math.h>
#define ARRAYSIZE 1000
#define FILENAMESIZE 128
float convertx(float r[], float theta[], int numPoints);
float converty(float r[], float theta[], int numPoints);
int cmain() {
int i;
float r[ARRAYSIZE], theta[ARRAYSIZE], x[ARRAYSIZE], y[ARRAYSIZE];
char filename[FILENAMESIZE];
FILE *InputFile;
printf("Type the data file name: ");
scanf("%s", filename);
InputFile = fopen(filename,"r");
if(InputFile == NULL){
printf("Error, could not open file: %s.\n",filename);
return 1;
}
for(i=0; i < ARRAYSIZE; i++){
if(fscanf(InputFile,"%f %f", &r[i], &theta[i]) == EOF) break;
printf("Value %d is %f\n",i+1,r[i]);
}
fclose(InputFile);
for(i=0; i < ARRAYSIZE; i++){
x[i] = convertx(r,theta,i);
printf("Value %d is %f\n",i+1,x[i]);
}
for(i=0; i < ARRAYSIZE; i++){
y[i] = converty(r,theta,i);
}
return 0;
}
float convertx(float r[], float theta[], int numPoints){
int i;
float x;
for(i=0; i < numPoints; i++)
x = r[i]*cos(theta[i]);
return x;
}
float converty(float r[], float theta[], int numPoints){
int i;
float y;
for(i=0; i < numPoints; i++)
y = r[i]*sin(theta[i]);
return y;
}
EDIT: Requested was a snippet of the input file. Here's the first few points (there are no commas in the file, just white space. Unfortunately, my formatting skills on this site are awful):
60, 3.9269875
60, 0.7853975
0, 0
1, 0.25
2, 0.5
For your first issue, the reason that your for-loop for r and theta stops at the end of the file is because you have a break; that exits the for-loop when you detect EOF. You don't have that in your x and y for-loops.
To fix that, instead of using your ARRAYSIZE constant, EDIT: { save the Final i value in your r and theta for-loops, it will be either the numbers of lines or +1, and use that for the end value in your x and y for-loop. Like this:
for(i=0; i < ARRAYSIZE; i++){
if(fscanf(InputFile,"%f %f", &r[i], &theta[i]) == EOF) {
int final = i;
break;
}
printf("Value %d is %f\n",i+1,r[i]);
}
fclose(InputFile);
for(i=0; i < final; i++){
x[i] = convertx(r,theta,i);
printf("Value %d is %f\n",i+1,x[i]);
}
I previously said you can use the size of the array for r or theta: for (i=0; i < r.size(); i++) {, but since you initialized its length to 1000 that won't work. }
For your 2nd issue: I think if you get rid of the for-loop in your convertx and converty functions, that will solve the problem. That's because only the last value of x or y calculated is returned, so your calculations from i=0 to i=(numPoints-2) are being thrown away.
I was trying to do an exercise in Hacker Rank but found that my code(which is below) is too linear. To make it better I want to know if it is possible to break an array in to little arrays of a fixed size to complete this exercise.
The Exersise on HackerRank
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
int N, M, Y, X;
scanf("%d %d %d %d", &N, &M, &Y, &X);
int max = 0;
int total = 0;
int data[N][M];
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
scanf("%d",&(data[i][j]));
}
}
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
total = 0;
for(int l = 0; (l < Y) && (i + Y) <= N; l++)
{
for(int k = 0; (k < X) && (j + X <= M); k++)
{
total += data[i+l][j+k];
}
if(total > max)
max = total;
}
}
}
printf("%d",max);
return 0;
}
While "breaking" it into pieces implies that we'd be moving things around in memory, you may be able to "view" the array in such a way that is equivalent.
In a very real sense the name of the array is simply a pointer to the first element. When you dereference an element of the array an array mapping function is used to perform pointer arithmetic so that the correct element can be located. This is necessary because C arrays do not natively have any pointer information within them to identify elements.
The nature of how arrays are stored, however, can be leveraged by you to treat the data as arbitrary arrays of whatever size you'd like. For example, if we had:
int integers[] = {1,2,3,4,5,6,7,8,9,10};
you could view this as a single array:
for(i=0;i!=10;i++){ printf("%d\n", integers[i]); }
But starting with the above array you could also do this:
int *iArray1, *iArray2;
iArray1 = integers;
iArray2 = integers + (5 * sizeof(int));
for(i=0;i!=5;i++){ printf("%d - %d\n", iArray1[i], iArray2[i]);}
In this way we are choosing to view the data as two 5 term arrays.
The problem is not in the linear solution. The main problem is in your algorithm complexity. As it's written it's O(N^4). Also I think your solution is not correct since:
The ceulluar tower can cover a regtangular area of Y rows and X columns.
It does not mean exactly Y rows and X columns IMHO you could find a solution where the are dimension is less than X, Y.
The problems like that are solvable in reasonable time using dynamic programming. Try to optimize your program using dynamic programming to O(N^2).