for and if condition giving unexpected result - c

i have a problem in c like this:
I have a problem in the code below. The problem is this that i doing some addition part after both if conditions break.And that addiion is repeatative while loop until count>0 The problem is if i put braces in for loop then it repeats the the part inside the braces until it's condition is not false. Buti have to do addition which is like this:
We have an array data[i].freq={0,1,2,3,4,5} and data[i].next represents the next member to be added.Suppose i add 0 and 1 first i got"1" as a result and i put the result in last index of my array , like this ({0 1 2 3 4 5 1})now 0 and 1 cann not be added because they are already added(i don't have to repeat the addition on same elements), so next time the addition will be between the last index element and smallest element before the last element (but not those elements who are already added). so here the addition will be between the "1" in last index+ smallest element in right to it which is "2" Note here we have not taken in acount 0 and 1 because they are already added, the same way this 2 will not be added next time because it is being added this time and their addition wil be {0 1 2 3 4 5 1 3} we have to repeat the same until there left & element at last.
data[data_size].freq=data[i].freq+data[p].freq; // here i add the first 2 elements "0" and "1" in the example i given below.
int count=5;
do
{
for(i=0;data[i].next!=-1;i=data[i].next)//the problem is here if i put bracesit dont't do the ask which i expect it to do.
if(data[data[i].next].freq>data[data_size].freq && data[data[i].next].flag==0)
break;
data[data_size+1].freq= data[data_size].freq+ data[data[i].next].freq;
data[data_size].next=data[i].next;
data[i].next=data_size;
data_size++;
if(data[data[i].next].freq<data[data_size].freq && data[data[i].next].flag==0)
break;
data[data_size+1].freq= data[data_size].freq + data[i].freq
data[data_size].next=data[i].next;
data[i].next=data_size;
data_size++;
count--;
} while(count>0)
could any one please help me in desiging the code for what i want to achieve.

If you write
for(i=0 ..any condition)
if(condition1)
break;
if(condition2)
break;
you don't only have an unreadable mess, but you also have only the first if clause in the for loop.
If you want the for loop to extend over both, you must put them into {}:
for(...) {
if(condition1) break;
if(condition2) break;
}
My personal preference is to always use braces when the statements are in the next line. S don't write
if(condition1)
break;
as someone could be tempted to insert an andditional statement and be surprised that it doesn't work as it should, but either do
if(condition1) break;
in one line or
if(condition1) {
break;
}
add braces which are not needed for functionality, but for readability.

This is how the compiler sees your code:
int count=5;
do
{
for (i = 0; data[i].next != -1; i = data[i].next)
{
if (data[data[i].next].freq > data[data_size].freq && data[data[i].next].flag == 0)
break; // break out of the enclosing 'for' loop (goes to point A)
}
// Point A
data[data_size].next = data[i].next;
data[i].next = data_size;
data_size++;
if (data[data[i].next].freq < data[data_size].freq && data[data[i].next].flag == 0)
{
break; // break out of the outer 'do' loop (goes to point B)
}
data[data_size].next = data[i].next;
data[i].next = data_size;
data_size++;
count--;
} while (count > 0);
// Point B
Based on your code comments, I think your problem is that your 'break' statements are not taking you where you think they're taking you.

Related

What does it mean for loop to have a lifetime?

I was looking at some Rust code and saw something along the lines of this:
'running: loop {
// insert code here
if(/* some condition */) {
break 'running;
}
}
What does it mean to "label" the loop with a lifetime? What are the benefits and differences between just doing:
loop {
// insert code here
if(/* some condition */) {
break;
}
}
Loop labels
You may also encounter situations where you have nested loops and need
to specify which one your break or continue statement is for. Like
most other languages, Rust's break or continue apply to the innermost
loop. In a situation where you would like to break or continue for one
of the outer loops, you can use labels to specify which loop the break
or continue statement applies to.
In the example below, we continue to the next iteration of outer loop
when x is even, while we continue to the next iteration of inner loop
when y is even. So it will execute the println! when both x and y are
odd.
'outer: for x in 0..10 {
'inner: for y in 0..10 {
if x % 2 == 0 { continue 'outer; } // Continues the loop over `x`.
if y % 2 == 0 { continue 'inner; } // Continues the loop over `y`.
println!("x: {}, y: {}", x, y);
}
}

I have an infinite loop, which i need to break in between, only if any three consecutive values returned from it are same. How to do it?

The code below shows the rowtotal[0], which is the return value I'm getting from an infinite loop for every iteration. I'm trying to break the loop when all three returned values from the costcheck array are the same. This is my code:
do
{
.
.
.
/*do loop body*/
.
.
costcheck[counter3]=rowtotal[0];
if(costcheck[counter3-2]==costcheck[counter3] &&
costcheck[counter3-1]==costcheck[counter3] )
{
response=1;
}
counter3++;
printf("\t\t\t Number of iterations: %d \r", stop++);
}
while(response!=1);
Just get rid of all strange, superfluous variables. You only need to save the result of the previous iteration, together with a counter which you increase each time you find a match, rather than every time in the loop.
int counter=0;
const int COUNT_N = 3;
data_t prev=FORBIDDEN; // a value that rowdata[0] can never have
while(counter != COUNT_N)
{
...
if(prev == rowdata[0])
{
counter++;
}
else
{
counter=0;
}
prev = rowdata[0];
}
just to elaborate on Lundins Answer wich is the way to go in my opinion (would have posted as a comment, but lacking reputation...)
Only thing missing is the actual loop advancement counter (counter3 in your example):
int quitCounter=0; // Counter for quiting the loop on 3 consecutive identical values
int loopCounter=0; // Your normal rowdata index
const int QUIT_COUNT_N = 3;
#define FORBIDDEN 0xffffff // or some other value that rowdata[0] can never have
data_t prev=FORBIDDEN; // a value
do
{
...
/* do loop body, provide new value for rowtotal[0] on each iteration */
/* if you need to store the consecutive values returned in rowtotal[0] in costcheck array,
make sure that it will be big enough - if you only need to break on 3 identical values,
you can skip the entire costcheck array as Lundin proposes. */
...
costcheck[counter3]=rowtotal[0];
if(prev == costcheck[counter3])
{
quitCounter++;
}
else
{
quitCounter=0;
}
prev = costcheck[counter3];
counter3++;
} while(quitCounter!= QUIT_COUNT_N )
If you really want an infinite loop, a if(costcheck[counter-1] == costcheck[counter-2] && costcheck[counter-2] == costcheck[counter-3]) will lead to failure of program, if costcheck array has less than 3 elements. You have to be sure that it does have at least 3 elemets in this array.
BUT!!!! counter does not need to be more than 3 because as far as i get it, you want to check 3 most reciently read elements. Which means for comparison, you only need to remember 3 last values that were read.
The exapmple below stores up to 3 rowtotal[0] values, and checks if they are equal. If they are, progarm exits, if not, program gets new rowtotal[0] to the "end" of costcheck array, also the oldest value: here it's costcheck[0] is lost.
I can post the code to the example which i made, to show how the logic should work.
NOTE!!! I strongly think Lundin's and Morphine's solutions are by far better than mine.
do
{
.............
if(counter < 3)
{
costcheck[counter] = rowtotal[0];
counter++;
continue;
}
else
{
if(costcheck[counter-1] == costcheck[counter-2] && costcheck[counter-2] == costcheck[counter-3])
{
response=1;
}
else
{
costcheck[counter-3] = costcheck[counter-2];
costcheck[counter-2] = costcheck[counter-1];
costcheck[counter-1] = rowtotal[0];
}
}
}
while(response!=1);
}

Given an array, find combinations of n numbers that are less than c

This is a tough one, at least for my minimal c skills.
Basically, the user enters a list of prices into an array, and then the desired number of items he wants to purchase, and finally a maximum cost not to exceed.
I need to check how many combinations of the desired number of items are less than or equal to the cost given.
If the problem was a fixed number of items in the combination, say 3, it would be much easier with just three loops selecting each price and adding them to test.
Where I get stumped is the requirement that the user enter any number of items, up to the number of items in the array.
This is what I decided on at first, before realizing that the user could specify combinations of any number, not just three. It was created with help from a similar topic on here, but again it only works if the user specifies he wants 3 items per combination. Otherwise it doesn't work.
// test if any combinations of items can be made
for (one = 0; one < (count-2); one++) // count -2 to account for the two other variables
{
for (two = one + 1; two < (count-1); two++) // count -1 to account for the last variable
{
for (three = two + 1; three < count; three++)
{
total = itemCosts[one] + itemCosts[two] + itemCosts[three];
if (total <= funds)
{
// DEBUG printf("\nMatch found! %d + %d + %d, total: %d.", itemCosts[one], itemCosts[two], itemCosts[three], total);
combos++;
}
}
}
}
As far as I can tell there's no easy way to adapt this to be flexible based on the user's desired number of items per combination.
I would really appreciate any help given.
One trick to flattening nested iterations is to use recursion.
Make a function that takes an array of items that you have selected so far, and the number of items you've picked up to this point. The algorithm should go like this:
If you have picked the number of items equal to your target of N, compute the sum and check it against the limit
If you have not picked enough items, add one more item to your list, and make a recursive call.
To ensure that you do not pick the same item twice, pass the smallest index from which the function may pick. The declaration of the function may look like this:
int count_combinations(
int itemCosts[]
, size_t costCount
, int pickedItems[]
, size_t pickedCount
, size_t pickedTargetCount
, size_t minIndex
, int funds
) {
if (pickedCount == pickedTargetCount) {
// This is the base case. It has the code similar to
// the "if" statement from your code, but the number of items
// is not fixed.
int sum = 0;
for (size_t i = 0 ; i != pickedCount ; i++) {
sum += pickedItems[i];
}
// The following line will return 0 or 1,
// depending on the result of the comparison.
return sum <= funds;
} else {
// This is the recursive case. It is similar to one of your "for"
// loops, but instead of setting "one", "two", or "three"
// it sets pickedItems[0], pickedItems[1], etc.
int res = 0;
for (size_t i = minIndex ; i != costCount ; i++) {
pickedItems[pickedCount] = itemCosts[i];
res += count_combinations(
itemCosts
, costCount
, pickedItems
, pickedCount+1
, pickedTargetCount
, i+1
, funds
);
}
return res;
}
}
You call this function like this:
int itemCosts[C] = {...}; // The costs
int pickedItems[N]; // No need to initialize this array
int res = count_combinations(itemCosts, C, pickedItems, 0, N, 0, funds);
Demo.
This can be done by using a backtracking algorithm. This is equivalent to implementing a list of nested for loops. This can be better understood by trying to see the execution pattern of a sequence of nested for loops.
For example lets say you have, as you presented, a sequence of 3 fors and the code execution has reached the third level (the innermost). After this goes through all its iterations you return to the second level for where you go to the next iteration in which you jump again in third level for. Similarly, when the second level finishes all its iteration you jump back to the first level for which continues with the next iteration in which you jump in the second level and from there in the third.
So, in a given level you try go to the deeper one (if there is one) and if there are no more iterations you go back a level (back track).
Using the backtracking you represent the nested for by an array where each element is an index variable: array[0] is the index for for level 0, and so on.
Here is a sample implementation for your problem:
#define NUMBER_OF_OBJECTS 10
#define FORLOOP_DEPTH 4 // This is equivalent with the number of
// of nested fors and in the problem is
// the number of requested objects
#define FORLOOP_ARRAY_INIT -1 // This is a init value for each "forloop" variable
#define true 1
#define false 0
typedef int bool;
int main(void)
{
int object_prices[NUMBER_OF_OBJECTS];
int forLoopsArray[FORLOOP_DEPTH];
bool isLoopVariableValueUsed[NUMBER_OF_OBJECTS];
int forLoopLevel = 0;
for (int i = 0; i < FORLOOP_DEPTH; i++)
{
forLoopsArray[i] = FORLOOP_ARRAY_INIT;
}
for (int i = 0; i < NUMBER_OF_OBJECTS; i++)
{
isLoopVariableValueUsed[i] = false;
}
forLoopLevel = 0; // Start from level zero
while (forLoopLevel >= 0)
{
bool isOkVal = false;
if (forLoopsArray[forLoopLevel] != FORLOOP_ARRAY_INIT)
{
// We'll mark the loopvariable value from the last iterration unused
// since we'll use a new one (in this iterration)
isLoopVariableValueUsed[forLoopsArray[forLoopLevel]] = false;
}
/* All iterations (in all levels) start basically from zero
* Because of that here I check that the loop variable for this level
* is different than the previous ones or try the next value otherwise
*/
while ( isOkVal == false
&& forLoopsArray[forLoopLevel] < (NUMBER_OF_OBJECTS - 1))
{
forLoopsArray[forLoopLevel]++; // Try a new value
if (loopVariableValueUsed[forLoopsArray[forLoopLevel]] == false)
{
objectUsed[forLoopsArray[forLoopLevel]] = true;
isOkVal = true;
}
}
if (isOkVal == true) // Have we found in this level an different item?
{
if (forLoopLevel == FORLOOP_DEPTH - 1) // Is it the innermost?
{
/* Here is the innermost level where you can test
* if the sum of all selected items is smaller than
* the target
*/
}
else // Nope, go a level deeper
{
forLoopLevel++;
}
}
else // We've run out of values in this level, go back
{
forLoopsArray[forLoopLevel] = FORLOOP_ARRAY_INIT;
forLoopLevel--;
}
}
}

Automatically enter while loop

I am having trouble with the while loop in my code. The instructions say to "Set a loop-control variable to a value that automatically enters the loop for the first time". Any suggestions on how I can do this? Any input will be appreciated. Thank you!
}//end main
I will assume you don't know what most of these terms mean.
A while loop assumes the following syntax (I'll do it in C# since I'm not sure what language you're coding in; update your original post and I'll change my samples):
while (/* loop control/condition here */)
{
// Code here
}
This evaluates like this in english (pseudocode):
while the loop control is true
do this
when it equals false leave the while
So what you want to do is initialize a variable (I'm using type bool here for clarity's sake) and put it in between the parenthesis as the "loop control."
Here's a small sample:
bool daytime = true; // This is the loop control.
int i = 0;
while (daytime == true) // We are seeing if it's day out.
{
System.out.println("It is daytime.");
if (i == 6) {daytime = false;} // If our counter hits 6:00 it's nighttime.
i = i + 1; // Increment our counter.
}
Anyway hope that helps you. Good luck!
Edit: Do-While
I may have misunderstood your original question a bit, this is what a do-while loop looks like:
Syntax:
do
{
// Code here
} while (/* loop control/condition here */);
Pseudocode:
do this code
keep repeating code until the condition is false
Sample:
bool daytime = true; // This is the loop control.
int i = 0;
do
{
System.out.println("It is daytime.");
if (i == 6) {daytime = false;} // If our counter hits 6:00 it's nighttime.
i = i + 1; // Increment our counter.
} while (daytime == true) // We are seeing if it's day out.

My strcmp doesn't return 0 when it should

Context : I'm searching for all the words contained in a 2d array (horizontally,vertically and diagonaly).
So what I do is I get all the possible words, check if they're in the given dictionary and if they are store them in an array. The thing is, I don't want it to have duplicates.
Here's a snippet of the code:
for (i=l-1;i>=0;i--){
palavra[aux]=mat[i][caux];
for (j=i;j>=0;j--){
palavra[aux]=mat[j][caux];
palavra[aux+1]='\0';
for (it=0;encontradas[it]!=NULL;it++){
if (strcmp(palavra,encontradas[it])==0)flag=1;
else flag=0;
}
if (flag==0) {
r = palavra_existe(dic,palavra);
if (r!=0) {
found[auxenc]=mystrdup(palavra);
auxenc++;
}
}
flag=0;
aux++;
}
aux=0;
}
The
if (strcmp(palavra, found[it])==0)flag=1
line is there to check if the formed worded has been found already, to avoid creating a duplicate. The problem is it doesn't work, duplicates appear anyway (as the flag variable never takes the value 1).
What could I be missing here?
The flag variable does get the value 1, but then it turns back to 0 again in the next iteration.
Set flag to zero before the loop, and when you find a match you set it to 1 and exit the loop:
flag = 0;
for (it = 0; encontradas[it] != NULL; it++) {
if (strcmp(palavra,encontradas[it]) == 0) {
flag=1;
break;
}
}
(Exiting the loop isn't needed for the logic to work, but there is no point in looping through the rest of the items once you have found a match.)

Resources