while loop replicating a for loop - c

Hi im trying to do a disk scheduling algorithm (C-SCAN).I have a for loop with an if statement that works, however im trying to change it to a while loop or another option to remove the break statement.
for(i=0;i<n;i++)
{
if(initial<RQ[i])
{
index=i;
break;
}
}
while ( initial>RQ[i] )
{
index =i;
i++;
}
The above for loop is what im trying to replicate as seen in my while loop. however it is not working the same way.
any help will be much appreciated

A for loop of the form
for (initialization; condition; repetition) {
// body code
}
is equivalent to:
initialization;
while (condition) {
// body code
repetition;
}
So your loop would be rewritten as:
i = 0;
while (i < n) {
if (initial < RQ[i]) {
index = i;
break;
}
i++;
}

One possibility of removing the break statement would be to introduce an additional flag variable which gets set when the loop should be terminated.
#include <stdbool.h>
[...]
bool terminate = false;
for( i=0; i<n && !terminate ; i++ )
{
if(initial<RQ[i])
{
index=i;
terminate = true;
}
}
However, I personally consider it better to use a break statement.

Related

Algorithm not getting into if condition (Sherlock and the Valid String)

I am basically trying to solve this challenge. This is my code:
int arr[26]={0};
int freq=0;
int deletion=0;
for(int i=0;i!='\0';i++)
{
arr[s[i]-'a']++;
}
freq=arr[0];
for(int i=1;i<26;i++)
{
if(freq!=arr[i])
{
deletion++;
return "HAHA";
}
}
if(deletion>1)
{
return "NO";
}
else
{
return "YES";
}
I realized it wasn't getting into the deletion++, and then I used a return "HAHA" to make sure of it.
For some reason, the condition freq!=arr[i] never gets satisfied, even when the content of the freq and arr[i] are different. I guess I am getting trapped in a very silly mistake here.
This line has a problem:
for(int i=0;i!='\0';i++)
\0 is actually a null-terminator. Probably you meant this:
for(int i = 0; i != size_of_array_s; i++)
OR:
for(int i = 0; s[i] != '\0'; i++)
this line is a problem in line
for(int i=0;i!='\0';i++)

while loop condition not fullfiled

double randomx,randomy,randomz,dia;
#define DROP_RAD 60
#define particleradi 3
for (i = 0; i<30; i++)
{
{
randomx=2*((float)rand()/RAND_MAX)-1;
randomy=2*((float)rand()/RAND_MAX)-1;
randomz=2*((float)rand()/RAND_MAX)-1;
randomx=randomx*(DROP_RAD -2*particleradi);
randomy=randomy*(DROP_RAD -2*particleradi);
randomz=randomz*(DROP_RAD -2*particleradi);
dia=randomx*randomx+randomy*randomy+randomz*randomz;
dia=sqrt(dia);
} while(dia>DROP_RAD);
printf(" id=%d, x=%lf, y=%lf, z=%lf , dia=%lf\n ",i,randomx,randomy,randomz,dia);
I'm getting values for dia greater than DROP_RAD even though the while condition is supposed to this. Kindly help.
I think you need a do-while-loop here. It will execute the block of code at least once, and then either repeatedly execute the block, or stop executing it, depending on the boolean condition at the end of the block.
do {
/* here goes your code */
} while (dia > DROP_RAD);
If you don't want the block to be executed at all when the condition is false, you have to move the condition to the beginning of the block.
while (dia > DROP_RAD) {
/* here goes your code */
}
Your code snippet is equivalent to the following
for (i = 0; i<30; i++)
{
{
randomx=2*((float)rand()/RAND_MAX)-1;
randomy=2*((float)rand()/RAND_MAX)-1;
randomz=2*((float)rand()/RAND_MAX)-1;
randomx=randomx*(DROP_RAD -2*particleradi);
randomy=randomy*(DROP_RAD -2*particleradi);
randomz=randomz*(DROP_RAD -2*particleradi);
dia=randomx*randomx+randomy*randomy+randomz*randomz;
dia=sqrt(dia);
}
while(dia>DROP_RAD);
printf(" id=%d, x=%lf, y=%lf, z=%lf , dia=%lf\n ",i,randomx,randomy,randomz,dia);
//...
That is you have a compound statement
{
randomx=2*((float)rand()/RAND_MAX)-1;
// ...
}
followed by a separate while statement
while(dia>DROP_RAD);
So either you have an infinite while loop
while(dia>DROP_RAD);
if dia is greater than DROP_RAD or the loop is interrupted at once if the condition is not satisfied.
It seems you mean a do-while loop like
do {
randomx=2*((float)rand()/RAND_MAX)-1;
randomy=2*((float)rand()/RAND_MAX)-1;
randomz=2*((float)rand()/RAND_MAX)-1;
randomx=randomx*(DROP_RAD -2*particleradi);
randomy=randomy*(DROP_RAD -2*particleradi);
randomz=randomz*(DROP_RAD -2*particleradi);
dia=randomx*randomx+randomy*randomy+randomz*randomz;
dia=sqrt(dia);
} while(dia>DROP_RAD);

How to simplify compound negated logic

Lets say I have array of boolean values B[], or I am figuring out true/false using function. How can I simplify this code, it there are many values (maybe tens of them)? Here is pseudocode:
if(!B[0]){
doTask1;
}
if(!B[0] && !B[1]){
doTask1;
doTask2;
}
if(!B[0] && !B[1] && !B[2]){
doTask1;
doTask2;
doTask3;
}
...
Edit 1: I forgot to mention, that I want doTask1 etc. happen only once (if any of there ifs is true), not doing it multiple times(if for example 1.st if is true, second one is true too, i still need to happen it only once)
You can use array of function pointers.
typedef void *(* funcPtr)(void);
funcPtr arrayFunPtr[N];
Then store the functions into the array.
arrayFunPtr[0]= task1;
arrayFunPtr[1]= task2;
....
arrayFunPtr[N-1]= taskN;
Then loop the bool array and call respective index function.
for(int i=0;i<N;i++)
{
if(!B[i]) arrayFunPtr[i]();
}
#Edit.
If you want to stop calling tasks function once you hit B[i]=true use the below code.
for(int i=0;i<N && !B[i] ;i++)
{
arrayFunPtr[i]();
}
(Assuming you don't want to make the same task more than once, even though your original code will)
Make a function doTask() which will take the number of the task to do (or just make an array of function pointers). And then:
for(i=0; i < numberOfTasks; i++)
{
if (!B[i])
doTask(i);
else
break;
}
Or more concisely:
for(i=0; i < numberOfTasks && !B[i]; i++)
{
doTask(i);
}
Function pointers is the way to go here.
If you do not like function pointer you might use the switch construct as shown below:
switch(i) {
case 3:
if(!B[0] && !B[1] && !B[2]) doTask3();
case 2:
if(!B[0] && !B[1]) doTask2();
case 1:
if(!B[0]) doTask1();
}
Or you can do :
You can write a method :
simplify(int[] B, int l) {
for (int i =0 ; i < l, i++) {
// write the code using &&
}
}
Then can call this method as :
if(simplify(B, 1){
doTask1;
}
if(simplify(B, 2){
doTask1;
doTask2;
}
etc.

Changing the if statement into a while statement

I'm trying to change an if statement into a while statement.
For example
int A=1; if(A==1){};
is similar to int A=1 while(A!=1).
My If statement has no codes, I just need it to do nothing in order to avoid the else-if statements.
My If statement is inside 1 While statement and 1 If statement.
So I want the program to do the same thing in the while statement rather than going in 1 While statement and 1 If statement with an If statement with no code.
Original codes something like this
while(C1)
{
if(C2)
{
if( h->data[temp] < h->data[temp*2] && h->data[temp] < h->data[temp*2+1] )
{
break;
}
else if(C4)
{
DO();
}
}
}
I've changed it to
while( C1 && h->data[temp] > h->data[temp*2] && h->data[temp] > h->data[temp*2+1] )
{
if(C2)
{
if(C4)
{
DO();
}
}
}
and the result is different. The original code gives the correct result but the changed code gives an incorrect result. I've only changed the location to if to while and also changed the direction of the < operator to the > operator.
The total code seems like I've spent less effort in it, making down votes. So I'm posting the code somewhat like a pseudo code.
For example int A=1; if(A==1){}; is similar to int A=1 while(A!=1).
As already mentioned, your loop is breaking. The above statement is also incorrect.
int a = 1;
if(a == 1) {} //this is true, and will happen once
BUT
int a = 1;
while(a != 1) {} //false on entry, skip loop ( never entered )
You could also consider a switch / case if you can isolate the condition.
This might achieve your goal of removing the ifs, and make the code more readable.
e.g
int a = 1;
while(a)
{
switch(a)
{
case 1: ++a; continue;
case 2: do();
default: break; //end loop
}
}
In the original code, if (for example) h->data[temp]>h->data[temp*2] were false, DO() wouldn't be executed, but the loop would continue. In the new version, the loop would stop.
As others said, there is no reason to obfuscate the code with an extra while statement; the original is perfectly clear. There is also no need for the else in your original:
while(C1)
{
if(C2)
{
if( h->data[temp] < h->data[temp*2] && h->data[temp] < h->data[temp*2+1] )
{
break;
}
if(C4)
{
DO();
}
}
}

How can I break out of two nested for loops in Objective-C?

I have two for loops nested like this:
for(...) {
for(...) {
}
}
I know that there is a break statement. But I am confused about if it breaks both loops or just the one in which it was called? I need to break both ones as soon as I see that it doesn't make sense to iterate more times over.
If using goto simplifies the code, then it would be appropriate.
for (;;)
{
for (;;)
{
break; /* breaks inner loop */
}
for (;;)
{
goto outer; /* breaks outer loop */
}
}
outer:;
break breaks out of one loop, but you can add a check to the outer loop which breaks when the inner breaks.
bool dobreak = false;
for ( ..; !dobreak && ..; .. ) {
for ( ... ) {
if (...) {
dobreak = true;
break;
}
}
}
The break statement only gets you out of the innermost loop. If you don't want the added overhead in code, memory and performance of a dedicated state variable, I recommend refactoring the code out into a function or method of its own, and using return to get out of all the loops:
void do_lots_of_work(void)
{
int i, j;
for(i=0; i<10 ; i++)
{
for(j=0;j< 10; j++)
{
..
..
if(disaster_struck())
return; /* Gets us out of the loops, and the function too. */
}
}
}
Other than the already mentioned flag variable or goto you could throw an Objective-C exception:
#try {
for() {
for() {
#throw ...
}
}
}
#catch{
...
}
Others have mentioned how you can set a flag or use a goto, but I'd recommend refactoring your code so that the inner loop is turned into a separate method. That method can then return some flag to indicate that the outer loop should break. If you name your methods appropriately, this is much more readable.
for (int i = 0; i < 10; i++) {
if (timeToStop(i)) break;
}
-(bool) timeToStop: (int) i {
for (int j = 0; j < 10; j++) {
if (somethingBadHappens) return true;
}
return false;
}
Pseudocode, not tested, but you get the idea.
The break statement will only break out of the loop in scope, which is the parent loop. If you want to break out of the second loop as well you could use a boolean variable which is in scope of both loops
bool isTerminated = false;
for (...)
{
if (!isTerminated)
{
for(...)
{
...
isTerminated = true;
break;
}
}
else
{
break;
}
}
Change top loop's counter before break
for(i=0; i<10 ; i++)
for(j=0;j< 10; j++){
..
..
i = 10;
break;
}
Probably the easiest way is to use a "flag" variable
for(i=0; i<10 && (done==false); i++)
for(j=0;j< 10; j++){
..
..
if(...){done=true; break;}
}
Another solution is to factor out the second loop in a function:
int i;
for(i=0; i<10 ; i++){
if !innerLoop(i) {
break;
}
}
bool innerLoop(int i)
int j;
for(j=0;j< 10; j++){
doSomthing(i,j);
if(endcondtion){
return false;
}
}
}
The break statement breaks out of the innermost loop. An additional test and break statement would be needed to break out of the outer loop.
If a break is executed from within a set of nested loops, only the innermost loop in which the break is executed is terminated. (Just like standard C)
Exactly like the last ones are, generally like this:
for(i=0;i<a;i++){
for(j=0;j<a;j++){
if(Something_goes_wrong){
i=a;
break;
}
}
}
Just for grins, how about changing this true/false check into a method and using return statements:
- (bool) checkTrueFalse: parameters{
for ( ...) {
for ( ... ) {
if (...) {
return true;
}
}
}
return false;
}

Resources