Having trouble understanding the for loop - c

#include <stdio.h>
int n, a[100001], x, y;
int main() {
scanf("%d", &n);
while (n--) {
scanf("%d.%d", &x, &y);
a[x*1000+y]++;
}
for (int i = 0, c = 0; i <= 100000; i++) {
while (a[i]) {
--a[i], ++c;
printf("%d.%03d\n", i / 1000, i % 1000);
if (c == 7) return 0;
}
}
return 0;
}
This is the code that receives an integer n, then the program is expected to receive n number of double or integer variables.
The program is supposed to print out the smallest 7 variables among the input variables to 3 decimal points.
Now the question is i can't seem to figure out how this code in for loop
while (a[i]) {
--a[i], ++c; // <- specifically this part
printf("%d.%03d\n", i / 1000, i % 1000);
if (c == 7) return 0;
}
generates 7 smallest variables.
Any help would be much appreciated

Suppose 8.3 is an input, then you are storing the 8003rd index of the array to 1. i.e a[8003]=1. if 8.3 is input twice then a[8003] will be equal to 2.
So in the for loop when i=8003, a[8003] is non zero that that means there was an input 8.3. So it is considered in the top 7 smallest input values and the loop exits when count reaches 7.

As hellow mentioned, This is bad code and if you are a student, stay away from such programming style (Not just student, everyone should stay away).
What this code does is it creates sort of "Look-up" table.
Whenever a number is entered, it increases a count at that array instance.
e.g. If I input 3.2, it increments a[3002] th location. Code for this is:
scanf("%d.%d", &x, &y);
a[x*1000+y]++;
x = 3 and y = 2 so a[3*1000+2]++ --> a[3002] = 1
(Note: Code assumes that array a is initialized with 0 - another bad habit)
Now say I entered 1.9, code will increment a[1009]. If I enter 3.2 again, a[3002] will be incremented again.
This was input part.
Now code parses entire array a starting from 0. At first it will encounter 1009, code will print 1.9 and keep on parsing array.
When it finds 7 non=zero locations, loop exits.
When you enter same number again, like 3.2, while(a[i]) executes twice printing same number again.
As smaller number will be at lower location in array and array parsing starts from 0, it prints smallest 7 numbers. If you reverse the for loop, you can print 7 biggest numbers.

The answer here is how the input data is being stored.
User entered values populate array a. It does not store actual entered numbers, but a COUNT how many times the value was entered (code makes lots of assumptions about data sanity, but lets ignore that)
The data is naturally Sorted from smallest to largest, so to find 7 smallest inputs you just take first 7 values (iterations tracked by index i, c tracks how many values we already did print out) where the COUNT is not zero (a[i], non zero value indicates how many times user entered corresponding value)

Related

Array sorting using special XOR condition

I have a problem in understanding the condition of my program, I can hardly explain it in a sentence so I will explain the whole point of program.
So for my homework I got to make a program that will ask user to enter number N which will represent the number of elements in array, then user enters elements of that array (assuming that user will enter correct number of elements) program then needs compare every number from that array with a number X with XOR (^) Operator.
The task is to find a minimum value for that X in which will the resulting array have elements in ascending order. It sounds a bit complicated but this is how it should work:
You enter a number N: For example lets use 4.
Then you enter 1D array of 4 elements : Lets use 4 2 3 1
Then program needs to use a number X (do while loop) to test every number from
this array with that number and if that number is >= to the previous one, it
should continue to check the next and next until it reaches the number N
If every element is sorted in ascending(equal counts as ascending) order it
should display that number.
So for our example 4 2 3 1 when you use XOR operation with every one of them
with the X=6 you get array that looks like this 2 4 5 7 which is in ascending
order.
To explain: 4 in binary is 100 ; X in binary is 110 if you use XOR on
those you get 010 which is 2, and do as follows for the rest ( program does
everything)
So I made the program,everything works great returning good values for every example that we have for reference, my only problem is that I don't know when to stop looking for that number X, or how should I know that minimum X for that array of numbers doesn't exist. In that case my program runs forever and don't return any value,so basically an infinity loop.
I need to use code that is simple so nothing too complicated because this is a course "Introduction to programming" and they won't accept anything that was made using complex algorithms or something like that.
EDIt: The program should display -1 if there are no X.
Here is the code :
#include <stdio.h>
int main() {
int matrix[100];
int n;
int i;
int index=1;
int x=0;
int start=0;
int end=0;
printf("Enter N: ");
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&matrix[i]);
}
index=1;
x=0;
do {
start=matrix[index]^x;
if((matrix[index+1]^x) >= start)
index=index+1;
else x++;
if(index==n){
printf("X=%d",x);
end=1;
break;
}
} while(end!=1);
return 0; }

Sorting program query

I came across a sorting code in quora and I was very confused with some of the lines of code, if someone explains it to me then it will be a big help.
The code is as follows:
#include <stdio.h>
int array[1000001] = {0};
int main(){
int i,j;
scanf("%d",&j);
int x;
for (i=0;i<j;i++){
scanf("%d",&x);
array[x]++;
}
for (i=0;i<1000001;i++){
while(array[i]>0){
printf("%dn",i);
array[i]--;
}
}
return 0;
}
Can someone explain what is happening in
for(i=0;i<j;i++)
{
scanf("%d",&x);
array[x]++;
}
and here
for (i=0;i<1000001;i++)
{
while(array[i]>0)
{
printf("%dn",i);
array[i]--;
}
}
and what does this dn stands for?
This is by far the best reason not to copy anything from quora or other sources without understanding what it is doing.
No matter what, it doesn't ensure if any of the inputs is right or not.
for(i=0;i<j;i++)
{
scanf("%d",&x);
// Are you sure that 'x' is always a valid int value and is less than your array size?
// No, if a monkey enters 200000 here, kabooom!
array[x]++;
}
In this for loop, which will iterate for j times, an input of type int is taken, and value at that index will be incremented, to know what value was entered by marking that index as 1.
for (i=0;i<1000001;i++)
{
while(array[i] > 0)
{
printf("%dn",i);
array[i]--;
}
}
Its bad by design, because if I have entered only 3 numbers to sort, it still iterates for 1000001 times.
But, it works for an expected/deliberately bounded input values.
For example, lets say user entered 6 values: 4, 2, 7, 0, 6, 8
So, j = 6, and contents of array would be all zeroes except for 4th, 2nd, 7th , 0th, 6th and 8th index.
Now this while loop does a job: it checks if ith index is set, i.e. if that index was entered by user not not. So the code inside while loop will only be executed for 4th, 2nd, 7th , 0th, 6th and 8th indexes.
To explain how the value is printed, lets dry run the code, Initially i is 0.
// Is ith index 1?
while (array[i] > 0) // i is 0
{
// Yes it is,
printf("%d ", i);
// See above, Prints 0 - not 1!
// Printing 'i' is the trick, instead of printing array[i]..
array[i]--; // Note, makes it zero!
}
for next iteration, i is 1
// Is ith index 1? - No, so move on to next index
while (array[i] > 0) // i is 1
{
//
}
lets say iteration has reached 7th index,
// Is ith index 1?
while (array[i] > 0) // i is 7
{
// Yes it is,
printf("%d ", i);
// See above, Printing 'i' is the trick,
// instead of printing array[i]..
array[i]--; // Note, makes it zero!
}
This will sort the numbers, without a doubt, but with some predefined constaints.
Additionally, you can/should add some implementation to get the sorted values in an array, based on if your are required to do it or not.
Finally, "%dn" is not a format specifier. It was probably meant to be "%d\n".
If it is kept unchanged the way it is, it will append n as a character after every number it prints, pointless.
This attempts to read in a number and ingores that the reading might fail.
scanf("%d",&j);
Afterwards j is therefor potentially uninitialised.
This makes a loop, which will do j steps, i.e. potentially an uninitialised number of loops.
for(i=0;i<j;i++)
This attempts to read a number once per loop, without caring about potential failures.
scanf("%d",&x);
It then uses the potentially uninitialised or non-updated number x to access an array.
array[x]++;
In case x is inconsitently for any reason, the access may well be beyond the array, which introduces potential undefined behaviour.
Should it however succeed, the array entry is increased by one.
Most of the array entries are implicitly initialised by the way, not because of the {0}.
So the array entry at the index which matches the read number is counted up.
In total, the number of occurrences of each number in the hopefully correctly formatted input is counted.
Nothing is sorted.
Yet.
This loops over all entries in the array, starting at the lower indexes, i.e. at the lower values of occurred values in the input.
for (i=0;i<1000001;i++)
If an entries in the array is not 0, the index/value is printed and the count is decreased until the entry is zero.
{
printf("%dn",i);
array[i]--;
}
I.e. the current index/value is printed as often as it has been seen in the input.
Implicitly, any value which did not occur in the input is not printed.
Concerning the "%dn" have a look here:
Is %dn a format string?
The most plausible explanation why the "n" does not occur in output, while the output does contain otherwise unexplained newlines, is that the "n" is actually an "\n" in the code which produced the shown output but got lost when posting the code.
(I agree with #WedaPashi that the code will have trouble with negative numbers in input on top of all the other vulnerabilities. Well spotted.)
I believe that the apparent speed of the solution for low values is sabotaged by looping over many empty entries for high values. It gives misleadingly fast output, while taking a long time doing nothing to reach the end of the array before actually being finished.

Display number in vertical format [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm new to C. I have a class assignment to display a number in a vertical format. If the user enters 5678, the instructor want it to display vertically to the screen in a single column as:
8
7
6
5
Second part of assignment is to find the largest divisor of the same number.
I'm totally lost. I'm getting the NUM value from another function. formula seems to work on even numbers, but on odd.
int divisor (int NUM)
{
int index, count=0;
for(index=2;index<=(NUM/2);index=index+1)
{
if(NUM%index==0)
count++;
}
printf("\n\nThe largest divisor of %d is %d\n",NUM, index-1);
return(index);
}
To display the number vertically:
1. get least significant digit,
2. print it and print new line,
3. shift number to the right by one digit
4. goto 1
Algorithm terminates when the number is zero. Call the input number n; getting the least significant (rightmost) digit can be done with n % 10. Right shift can be done with n = n / 10.
For the second part, observe that the largest divisor cannot be more than n/2 (because n = 2 * n/2). So try all number from n/2 down to 1 and break once you find a divisor. You will find the largest divisor because you are considering numbers in decreasing order. To check that x divides y use y % x == 0.
A second way it to check numbers from sqrt(n) down to 1. If m divides n, we can write n = m * k for some k. Now you take max(m, n/m) and continue.
Hope this helps :)
For the first part, there are many ways to approach this. But, without using too many of the standard library functions which seems to be a level appropriate for the question, I think the easiest way would be to take the numbers as a character array. Then access each value through it's index in the character array. This requires only the stdio.h header file. Some quick notes: simply use printf to print the value contained at each index, and throw the newline \n character at the end. If you wanted convert the string to an integer, you can do that very easily using the function atoi() which can be found in stdlib.h. If you want to print out backward, you can simply traverse the array backward.
void displayvert(char str[])
{
int i;
for (i = 0; str[i] != '\0'; ++i) {
printf("%c\n", str[i]);
}
}
Also many ways to approach the second, but in this case for the second question I think I'd use the modulus operator and track the highest value where the result is zero. In order for this to work with the single user provided input, I actually needed atoi() which is in the stdlib.h header. Basically, starting from the value one you'll increase the value up the integer just below the value of 'num' itself. And, if the remainder is zero when you when you divide by it (the purpose of using the modulus operator) then you know it's divisible. Because we're ascending from 1 to the number itself, the last value to return a remainder of zero is the greatest common divisor.
void getgcd(int num)
{
int i, gcd;
// remember, you can't do x % 0!
for (i = 1; i < num; i++) {
if ((num % i) == 0 ) {
gcd = i;
}
}
printf("The greatest common divisor is: %d\n", gcd);
}
Main function and prototypes here so you can see how it all tied together. A couple of quick notes (1) 11 digits was arbitrary; but it's important to note that we used 10 digits for the total input value (you can add checks to this to enforce) and reserved the 11th (at index 10) to allow space for the null terminating character \0. (2) Use scanf to grab input; note that because character arrays do not require the address operator & because it defaults to that.
#include <stdio.h>
#include <stdlib.h>
void displayvert(char str[]);
void getgcd(int num);
int main()
{
char input[11]; // additional character added for \0
printf("Please enter a value up to 10 digits: ");
scanf("%s", input);
displayvert(input);
getgcd(atoi(input));
return 0;
}

Sucessive integers using C programming

Example input: 20 10 5 20 2 20 20 20 2 2 0
Output:
(20*5)
(10*1)
(5*1)
(2*3)
I just started programming this semester and need help on a project. I apologize if my question is unclear.
So basically I have to input positive integers till I enter "0" would end the program. I'm not allowed to use arrays(whatever that means).
#include <stdio.h>
int main ()
{
int number, count=0
while(1)
{
scanf("%d",&number);
if (number!=0)
{
count++; continue;
}
else
{
printf("%d*%d",number,count);
break;
}
return 0;
}
How do I store these multiple numbers so that I wouldn't overlap the previous number and to increment duplicate numbers by 1 every time it's entered? I can't ask my professor for help; he just tells me to google it.
"A certain engineering apparatus is controlled by the input of successive numbers (integers).
If there is a run of the same number, the apparatus can optimize its performance. Hence we
would like to arrange the data so as to indicate that a run is coming. Write a C program that
reads a sequence of numbers and prints out each run of numbers in the form (n∗m) where
m is the number repeated n times. Note that a run can consist of just a single number. The
input numbers are terminated by a zero, which halts the apparatus."
This assignment seems to be based on half-baked knowledge of run length encoding (RLE). Anyway, here's a pseudo-code which does what it asks.
in = read next number from input
current_num = in // let the 1st number in list be current_num
count = 1
loop
in = read next number from input
if (in == 0) break // we are done, get out of loop
else if (in == current_num) count += 1
else // run has ended, print it and start new run
print current_num * count
current = in
count = 1
end loop
print current_num * count // we exited the loop before printing the last run
// so do it outside the loop
You can implement it in code and then "optimize" it to remove repeated code, and take care of corner cases (such as "empty" input, single number input, etc.)
Edit Just to be clear, the assignment asks for a 'run' of numbers, but the sample output shows a 'count' of numbers. These two are not the same.

Why am I getting outputs of huge numbers with this program?

I am trying to make a program that allows the user to input a positive integer, and the program will output the sum of each digit added together. For example, if the user inputs 54, the program will output 9. For some reason, the program is outputting outrageously huge numbers. When 54 is the input, the output will read something like 5165451 or 2191235. I'm new to C programming, but I don't see a single thing wrong with this code..
//This program takes a positive integer
//from the user, and adds all the digits
//of the number together.
#include <stdio.h>
int main() {
system("clear");
int given, add, hold, i;
printf("Enter a positive integer (up to 10 digits): ");
scanf("%d", &given); //User input
for (i = 0; i < 10; i++) { //Loop to add digits
hold = (given % 10);
given = (given / 10);
add = (add + hold);
}
printf("Sum of the digits is %d\n", add); //Output
}
int given, add, hold, i;
You haven't initialized add, so it contains unspecified data, aka garbage. Using its value while it is unspecified is undefined behaviour.
Insert add = 0; before the loop to see if that helps.
I think the for loop is wrong
The loop will run 10 times whereas scanf will only take the input upto the limit of int data type i.e 32768.
You should make given a long data type.
and make the for loop as
for(;given!=0;)
{
hold = (given % 10);
given = (given / 10);
add = (add + hold);
}
and of course initialize add to zero.

Resources