what is wrong with the loops - c

I am solving a problem of adding the last digits of numbers lying between a range (for ex. between 'm' and 'n' where m < n).I have coded this
#include <stdio.h>
int main()
{
int t=0;
long int m=0,n=0,num=0,sum=0,lsum=0,i=0;
scanf("%d",&t);
while(t--){
scanf("%ld%ld",&m,&n);
i=m;
while(i<=n){
while(i!=0){
num=i%10;
i/=10;
}
lsum=lsum+(sum%10);
i++;
}
}
printf("\n%ld",lsum);
return 0;
}
Here t=No of Test Cases. m and n is the range. I don't know why it is running infinitely in the terminal. I am using gcc(4.3.2) compiler.How can I optimize it for speed ,or is it the case where the while conditions are never terminated, but why?

You are dividing the i: i/=10. This means that i is always set back to 1 at the end of the loop. You should use a temporary variable for the dividing.
Like this:
while(i<=n){
int temp = i;
while(temp !=0){
num=temp %10;
temp /=10;
}
lsum=lsum+(sum%10);
i++;
}
P.S. There are many other errors in your code. But they are not connected with the infinite looping.

There is an infinite loop int the code :
while(i<=n)
{
while(i!=0)
{
num=i%10;
i/=10;
}
lsum=lsum+(sum%10);
i++;
}
the first while(1<= n) is always true : the second loop makes i = 0 or i = 1 !

Related

How to stop infinite looping the output?

I have code with a function that returns the biggest digit from a number. The requirement is to enter numbers until something that is not a number is entered. When something that isn't a number is entered, the program is supposed to stop, but in my case it just starts an infinite loop that prints the last result that the function returned. Here is the code:
#include <stdio.h>
int maxDigit(int n){
int temp = n, maxDig = 0;
while(temp){
int digit = temp % 10;
if(digit > maxDig){
maxDig = digit;
}
temp /= 10;
}
return maxDig;
}
int main()
{
int n = 1, broj;
while(n){
if(scanf("%d", &broj));
printf("%d\n", maxDigit(broj));
}
return 0;
}
What might be the problem?
You can look at the return value of scanf to see if you read a valid integer, and you can use break to terminate your loop. The n variable in your main function just had a constant value so I got rid of it, and cleaned up the function in a few other ways. Here is my resulting code:
...
int main() {
while (1) {
int input;
if (scanf("%d", &input) != 1) { break; }
printf("%d\n", maxDigit(input));
}
}

How to break a while loop when it is false to a certain condition

I was trying to make a program where if I enter an integer, the program would find out the bigger number and subtract it by the smaller number. This part, I got it.
The problem is, the infinite loop part.
I tried to get type in two integers keep on printing with the while loop, and break when at least one character is typed in.
For example, if I type in 2 #, it would break.
But I couldn't find the write place to get the break; within the code and therefore whenever I enter a character it would keep on creating an infinite loop.
Is there any way to create a break in this code? I humbly ask for advice...
The following is the code which I couldn't put the break
(By the way, the reason I did the condition in while as sizeof(i)==4 || sizeof(j)==4 was to make it so it would only enter an integer, since the size of an integer is 4)
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i){
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
The bottom code is the one I tried to put break but failed (it kept creating an infinite loop)...
int main()
{
int i, j;
int result;
while (sizeof(i)==4 || sizeof(j)==4){
if (sizeof(i) == 4 || sizeof(j) == 4) {
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
else
break;
}
return 0;
}
and here's a code where I got rid of the sizeof and used while(1), though there wasn't much change in the fact that the break didn't work...
int main()
{
int i, j;
int result;
while (1){
printf("type in two integers : ");
scanf("%d %d", &i, &j);
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
You can't use sizeof(i) to do run-time checks! This is a compile-time constant that, in your case (32-bit integers) will always evaluate to 4.
In order to check that two valid integers have been given, you can check the return value of the scanf function (it gives the number of fields successfully scanned):
#include <stdio.h>
int main()
{
int i, j;
int result;
while (1) {
printf("type in two integers : ");
if (scanf("%d %d", &i, &j) != 2) break; // Break here if we didn't get two integers
if (i < j) {
result = j - i;
}
else if (j < i) {
result = i - j;
}
printf("%d\n", result);
}
return 0;
}
Feel free to ask fir further clarification and/or explanation.
Drop the whole concept of endless loop with break inside if.
Make a condition for the loop based on the return value of scanf(), that is practically what it is designed for.
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
printf("type in two integers : ");
while (2==scanf("%d %d", &i, &j))
{
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
printf("%d\n", result);
printf("type in two integers : ");
}
return 0;
}
I'd probably actually use do {...} while (...) with a variable storing the return value of scanf()for being used in the loop condition. I'd consider it more elegant for not having to copy the print, but I kept it closer to your code structure.
More comments on your code:
as explained in comments, sizeof() works differently than you seem to think; it is static and does not change at runtime and hence cannot be used in a loop condition
with while (sizeof(i)==4 || sizeof(j)==4){if (sizeof(i) == 4 || sizeof(j) == 4){/* a */} else {/* b */}, b cannot ever be reached, because the conditions of while and if are identical
check the possible outcomes of the if conditions inside the loop, you are leaving the one with i==j undefined and return an uninitialised value
always init all variables as a habit
for a good MRE include the include lines
On your request, here is a proposal for the do-while alternative:
#include <stdio.h>
int main()
{
/* always init everything */
int i=0, j=0;
int result=0;
int iScanned=0;
do
{
printf("type in two integers : ");
iScanned=scanf("%d %d", &i, &j); /* keep the return value for loop */
if (i < j) {
result = j - i;
}
else /* removed second if, to have a meaningful result for i==j */
{
result = i - j;
}
if(2==iScanned) printf("%d\n", result); /* if to avoid awkward last output */
} while (2==iScanned);
return 0;
}

Time Complexity (Terminated due to timeout 2s at Hackerrank)

Suggest some ways to reduce the time complexity of this following code.
The problem is:
This is question
This is sample input output
This code is working fine except two cases (terminated due to time limit 2s)
#include<stdio.h>
#include<string.h>
int main()
{
unsigned char str[1000000];
unsigned long int l;
int i,j,t,k,c=0;
scanf("%d",&t);
for(k=0;k<t;k++)
{
c=0;
scanf("%lu",&l);
scanf("%s",str);
for(i=0;i<l-1;i++)
{
for(j=i+1;j<l;j++)
if(str[i]=='S' && str[j]=='A')
c++;
}
printf("%d\n",c);
}
return 0;
}
I'd use the following algorithm to solve:
Traverse the string :
a variable count which will store number of S's before a currently found A and total which is the total substrings found yet.
int total=0,count=0;
for(int j=0; j < s.length(); ++j){ //s.length or till wherever you want to find
if(s[j] == 'A') total+=count;
else if(s[j]=='S') count++;
}

how the continue statement works in for loop in C?

I have the following code in C:
#include <stdio.h>
int main()
{
int i = 1;
while(i)
{
int index = 0;
printf("while begin\n");
for(index = 0; index < 10; index++)
{
if(index == 2)
{
continue;
}
printf("within for\n");
}
printf("while end\n");
}
printf("returned from while");
}
does the continue effect the for loop or the while loop directly? looks like once the continue is called, for loop will start to run from the beginning, should not the while loop start to run from the beginning?
continue will cause the remaining portion of the enclosing for or while loop body to be skipped. In your case, the for is the "enclosing" loop of continue and the while loop is the "enclosing" scope of the for loop.
According to (unofficial) documentation
The continue statement causes a jump, as if by goto to the end of the
loop body (it may only appear within the loop body of for, range-for,
while, and do-while loops).
To understand what continue is you should know what break does too.
So the following peace of code shows you how break and continue works:
#include <stdio.h>
int main(void){
int hours = 10;
int i=0;
for(i=0;i<hours;i++){
if(i==5){
break;
}
printf("%d ",i);
}
return 0;
}
Output:
0 1 2 3 4
As you can see, when i reaches 5 (i==5) the loop breaks.
Now let's take a look of what does continue if we replace break using the same code:
#include <stdio.h>
int main(void){
int hours = 10;
int i=0;
for(i=0;i<hours;i++){
if(i==5){
continue;
}
printf("%d ",i);
}
return 0;
}
Output:
0 1 2 3 4 6 7 8 9
As you can see it doesn't leave the loop (like when using break), instead when i reach 5 (i==5) ignore the rest of the body making the loop to start over from the point where i was last time seen.
The number 5 *is missing.
The simplest way to think about it is to say : "it goes back to the top of the loop" anything AFTER the continue won't be processed.

a c iterations while skipping given values in a do while loop

I have a very simple problem in C. I am trying to write a simple program that outputs multiples of 10 between 10 and 100, inclusive (ie: on the closed interval [10,100]) that skips 30 and 70 and outputs the values vertically.
Here is my code:
#include<stdio.h>
main()
{
int i=10;
do {
if(i==30||i==70)
continue;
printf("\n %d",i);
i++;
} while(i<100);
return 0;
}
The program stops at 29 skips 30 and continues into a never ending loop. What is wrong?
The problem is that when you hit the if statement, you are now skipping the increment of i. So you never reach 100!
#include<stdio.h>
main()
{
int i=10;
do {
if(i==30||i==70)
continue; //!!!! This will skip the i increment
printf("\n %d",i);
i++;
} while(i<100);
return 0;
}
I recommend a for loop:
main()
{
for (i = 10; i < 100; i++) {
if(i==30||i==70)
continue; // The for loop will do the i++ on the "continue"
printf("\n %d",i);
}
return 0;
}
mbratch correctly pointed out your problem, but you might want to consider a for loop for this sort of thing. It would have prevented this particular problem, since the increment is automatic.
I won't do the whole thing for you, since you're obviously trying to learn, but this ought to get you started:
for (i=0; i<100; i+= 1)
You'll have to change some of the numbers in that line, but hopefully you'll understand what they mean when you change them.
When i reaches 30 the continue statements moves back to the start of the loop.
And so the loop continues endlessly as i is not incremented from this point.
Your code's doing exactly what it's written to do. The continue skips the increment instruction, so the value hits 30 and gets stuck there. Move the increment to the start of the loop body, or better yet, use a for instead of a while.
Don't use continue. Instead print out the value as long as != to 30 and 70. Also iterate by 10 instead of 1 to output multiples 10.
#include<stdio.h>
main()
{
int i = 10;
do
{
if (i != 30 && i != 70)
printf("\n %d", i);
i += 10;
}
while (i <= 100); // if you want to print 100
return 0;
}
Output:
10
20
40
50
60
80
90
100
Use while (i <= 100); if you need to also print 100.
It loops forever because you continue but don't increment i.
if(i==30||i==70) {
i++;
continue;
}
or you could use a for loop like so,
#include<stdio.h>
int main()
{
int i=10;
for (; i < 100; i++)
{
if(i==30 || i==70) {
continue;
}
printf("\n %d",i);
}
return 0;
}
The reason is that i is never incremented after 30 inside the body of do..while. You'd need to increment it.
if (i == 30 || i == 70){
i++;
continue;
}

Resources