Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I can't find out the problem, it doesn't give me the right answer, for example: I put 1234567890, it gives me a series of strange number, I'm new so I cant post a picture:
#include <stdio.h>
int main()
{
int n,i;
int m[10];
while((n=getchar())!='\n') {
++m[n-'0'];
}
for(i=0;i<10;++i) {
printf("%d\n",m[i]);
}
return 0;
}
The basic problem is that you do not initialize the array
before counting digits.
int m[10] = {0};
Also you should handle non digit values so that the program
doesn't crash e.g.
while((n=getchar())!='\n')
{
if ( isdigit(n) )
{
++m[n-'0'];
}
}
( isdigit() is available if you include ctype.h )
Initialize your array contents to 0 instead of whatever randomly happens to be in memory, using:
int m[10]={0};
A few folks have already suggested including
int m[10] = {0};
This will work. Depending upon your compiler and optimization options it may not lead to the "best" code. An alternative, that I prefer is to invoke memset() to initialize the array to 0's before using it. Here is the modified program (also note that you do not need both n and i but an optimizing compiler would take care of that too):
#include <stdio.h> /* for getchar() and printf() */
#include <string.h> /* for memset() */
#include <ctype.h> /* for isdigit() */
int main(int argc, char* argv[])
{
int n, m[11];
memset(m, 0, sizeof(m)); /* initialize counters to zero's */
while ((n=getchar()) != '\n')
{
if (isdigit(n))
{
++(m[n-'0']);
}
else
{
++(m[10]);
}
}
for(n=0;n<10;n++)
printf("%c : %d\n",'0'+n, m[n]);
printf("Filtered characters: %d\n",m[10]);
return 0;
}
A sample run looks like this:
$ ./a.out
At 12:45 p.m. I ran to the 7-11 for a 48oz big gulp
0 : 0
1 : 3
2 : 1
3 : 0
4 : 2
5 : 1
6 : 0
7 : 1
8 : 1
9 : 0
Filtered characters: 42
$
As a final note, I looked at the generated assembly instructions output from gcc for different size m[]. Gcc generates inline code (sometimes looping and sometimes unrolled depending upon optimizations) for small sized arrays (say m[10] = {0};) and generates invocations of memset() as I have shown for larger sized arrays (say m[100] = {0};). A conclusion that can be drawn from this is that leaving the code as m[10] = {0}; allows the compiler to choose the best solution based upon what it knows about the target system which is almost certainly more than what you know.
Well since you didnt list what your problem is, I can only guess, but without trying to compile this, the most glaring issue is the buffer overflow on the "m" array. [Something which was wrong pointed out in the comments]
Edit
Also if you enter characters other than a number or newline, you'll overwrite memory outside the "m" array too.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
The following C code takes so long to compile and execute.
#include <stdio.h>
int main()
{
int max;
printf("Enter a value for max: ");
scanf("%d", &max);
for (int i=0; i<max; i++)
{
printf("%d\t", i);
}
return 0;
}
But, If I initialize the max variable with some number like
int max = 0;
The Compilation and execution is almost instantaneous. Can someone explain why?
Edit:
When I printed the value of the variable max before my input, it showed 2203648 (some garbage value). Instead of "int max = 0", if i assign
int max = 2203648;
the compilation and execution takes the same long time. But, as mentioned earlier, if i assign max say
int max = 200;
the compilation and execution is instantaneous. Does it have to do anything with the pre-assigned garbage value?
Also, this problem occurs only in windows computers, I tested with ubuntu, and the compilation and execution is instantaneous in both version of the code.
In Windows 10:
compilation and execution, as of "Enter a value for max: " appears on screen:
without variable initialization = around 8 seconds
with variable initialization = instantaneous
compiler - gcc
The scanf is failing. Check the return value.
i.e.
if (scanf("%d", &max) != 1) {
fprintf(stderr, "Unable to read max");
exit(1);
}
max is probably some large value hence the large amount of time
EDIT
The delay to see the prompt is that the printf is in a buffer and will not be displayed until the loop completes
I think variable initialization of max=0 doesn't make that great deal of a difference, but god knows why in ypur case its taking 8seconds. I think you should reinstall your GCC Compiler set your path variables correctly once more, and try the above code on a different IDE.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
1.
int main() { int a; a = 0; }
//OR
2.
#define ZERO 0 int main() { int a; a = ZERO; }
I think that the second one takes less execution time because it is preprocesssed.
The one liner - compilation time and execution time are different metrics altogether!!
Any program, written in mid to high level language, is not executed as-is by the system. For C, it is the compiler, which takes the source file as input and produces the binary (machine-executable code). In the process, it incorporates a lot of optimization to the code.
In this case, it's most likely, that the compiler will optimize out the statements altogether, as they are not used meaningfully. Both the snippets are likely to generate the same binary (unless you forcefully turn off the optimization). If at all, you have to check the generated binary and perform the time-measurement to check the final result.
They are equal. The compiler's preprocessor just replaces ZERO before doing anything.
Assuming it is written like this:
#define ZERO 0
int main() { int a; a = ZERO; }
The program will be transformed to
int main() { int a; a = 0; }
before it is compiled and it will not reach optimization step.
Update:
Just to clarify, sometimes you see codes like this:
#define ERROR_MEMORY_ALLOCATION_FAILED -1
char *buf = malloc(10);
if (!buf)
return ERROR_MEMORY_ALLOCATION_FAILED;
This can help code readability a lot, especially when you reuse these definitions.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Good night, what's the best way in C to count the number of possibilities of UNIQUE anagrams in a string with the maximum length of 256 without allows repetitions caused by same letters? The input would be just in uppercase and only alphabet letters are allowed, A-Z. I got stuck in the worst case of the program that got 26! a very large number that overflow even my double. I think I'm very lost here, I'm not so good in C. The program just need to shows the number of possibilities, not the anagram. Like:
LOL = 3
HOUSE = 120
OLD = 6
ABCDEFGHIJKLMNOPQRSTUVWXYZ = 403291461126605635584000000
Thank you guys very much... I tried a lot and failed in every single tried, I'm in distress with it. The way I got more closer of do it was in Pascal, but it also failed in some tests, and I can't use Pascal anyway. I'm using CodeBlocks on Windows that compiles with GCC.
You should calculate factorial of the length of the given string divided by the factorial of the occurrence of every letter.
long double logFactorial (int i) {
return i < 2 ? 0.L : (logFactorial (i-1)+log(long double (i));
}
int countLetter(const char* str, char c) {
int res = 0;
while (str && *str) {
res += *str++ == c;
}
return res;
}
long double numPermutations(const char* str) {
auto res = logFactorial (strlen(str));
for (char c = 'A'; c<='Z'; c++) {
res -= logFactorial (countLetter (str,c));
}
return exp((long double)res);
}
Pay attention!
There are several people here who were correct by saying that factorial of 26 cannot be stored even in 64bit integer.
Therefore, I changed my calculation to the logarithmic of the factorial number and store it in long double which I hope is precise enough (I think that the exp() function is not precise enough)
Nevertheless you cannot use this result as an integer value, unless you find a way to store it in 128bit integer or bigger...
You should test it too if this fits your problem.
There is a faster way to calculate the factorial for this problem by storing the results of 0! up to 26! in an array of the size of [27].
I will leave it to you for asking another question.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I start learing C programming from "Beginning Programming with C For Dummies" by Dan Gookin.
I have a problem with understanding "C Math Functions" - my question is how to use #include <stdlib.h> and abs() function. Only explanation in the book is this:
Here is a simple example:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i = -42;
int j = abs(i);
printf("i = %d, j = %d\n", i, j);
return 0;
}
LIVE DEMO
Besides the examples given above,functions work just like a mathematical function
in that y = f(x) you put in x and it returns a y(of course some dont return anything and some dont take in anything)
now what you need to do is to catch that value when it returns it by storing it into some memory location which is called a variable that you declare
its also important that you know what the return type is so that you dont truncate or lose some part of the result
for example if the result is a floating point number then you need to return the value into a float/double variable and if it is a integer you can store it in either int or double/float
also if it is a char you would probably want it to be returned to a char variable and so on and so forth
So any function that you write or that you use from somebody elses library/header is going to work like that
It takes in an argument(sometimes it can even take no arguments and you just use it by calling it with parentheses, parentheses must always be typed because otherwise it will look like a variable or something else and convention says so) and it returns some result(if it does return a result) or does something else unrelated to the calling functions variables/values
So hopefully that explains what functions are, and how you can use them
Now all of this described also applies to the functions you posted about, they have a set algorithm that they do which somebody else wrote, and you just give it the argument, and catch the return type and it will do what it says it intended to do i.e abs() gives you the absolute value, pow() returns the square of some base and so on
The line #include <stdlib.h> gives your code access to certain functions and abilities that are within that library. One of which is the abs() function.
The abs() function return the absolute value of an integer, by that we mean it will always convert it to a positive number.
Example:
#include <stdio.h> /* printf */
#include <stdlib.h> /* abs */
int main ()
{
int n,m;
n=abs(23);
m=abs(-11);
printf ("n=%d\n",n);
printf ("m=%d\n",m);
return 0;
}
Edit & Run
Output:
n=23
m=11
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I had to write a piece of code which would search a given value in an array.
I made this piece of code, which works:
#include <stdio.h>
int index_van(int searchedValue, int array[], int lengthArray)
{
int i ;
for (i = 0; i < lengthArray; i++)
{
if (array[i] == searchedValue)
{
return i;
}
}
return -1;
}
int main()
{
int array2 [] = {0, 1, 3, 4, 5, 2};
printf("%i", index_van(2, array2, 6));
}
With the correction (the teacher put up online) of this exercise the notes of my teacher were:
You have to quit the moment you have found your value ,so you can't search through the entire table if you have found your value already. A for-loop therefore isn't tolerated.
Even if the for-loop has an extra built-in condition, THIS ISN'T STYLISH!
// One small note ,she was talking in general . She hasn't seen my version of the exercise.
So my question to you guys is, is my code really 'not done' towards professionalism and 'style' ?
I think she's implying that you should use a while loop because you don't know how many iterations it will take to get you what you're looking for. It may be an issue of her wanting you to understand the difference of when to use for and while loops.
"...Even if the for-loop has an extra built-in condition..."
I think this right here explains her intentions. A for loop would need a built-in condition to exit once it's found what it's looking for. a while loop already is required to have the condition.
There is nothing wrong with your code. I have no idea if using a for loop is less stylish than using another, but stylish is a very subjective attribute.
That being said, don't go to your teacher and tell her this. Do what she says, a matter like this is not worth contradicting your teacher for. Most likely this is just a way to teach you how while loops work.
After accept answer:
I've posted this to point out sometimes there is so much discussion of "style", that when a classic algorithmic improvement is at hand, it is ignored.
Normally a search should work with a const array and proceed as OP suggest using some loop that stops on 2 conditions: if the value was found or the entire array was searched.
int index_van(int searchedValue, const int array[], int lengthArray)
But if OP can get by with a non-const array, as posted, then the loop is very simple and faster.
#include <stdlib.h>
int index_van(int searchedValue, int array[], int lengthArray) {
if (lengthArray <= 0) {
return -1;
}
int OldEnd = array[lengthArray - 1];
// Set last value to match
array[lengthArray - 1] = searchedValue;
int i = 0;
while (array[i] != searchedValue) i++;
// Restore last value
array[lengthArray - 1] = OldEnd;
// If last value matched, was it due to the original array value?
if (i == (lengthArray - 1)) {
if (OldEnd != searchedValue) {
return -1;
}
}
return i;
}
BTW: Consider using size_t for lengthArray.