I have a recursive function which I call acc. If a specific condition is fulfilled I call the function again. If not, I want do add a number to the variable a.
In my opinion it does not what it should. Can someone have a look on this:
double acc(v)
{
double a = 0;
for(int q=0; q<v; q++)
{
if(bf(q) < 1)
{
if(ef() == 0)
{
a += cf();
}
else
{
a += df();
}
}
else
{
return a += acc(v);
}
}
return a;
}
I tried to simplify it as good as I can. vis a variable. bf(), cf(), ef() and df() are functions which return an integer value. Now I want that a gets incremented every time a specific condition is fulfilled during the whole recursive process. Does my code what I want? I don't see it at the moment.
Your problem is that a is defined inside the recursive function. If you want to count events inside the recursion, declare a outside of acc().
Related
I am trying to refactor some code and make it easier to read. I noticed that I have some unnecessary return statements at the end of some functions. Here a conceptual example:
func someFunction(a []arr) int {
for _,v := range a {
if v == something {
// will defenitly get here at some point!
return somethingElse
}
}
return -1 // never ever happens!
}
In my opinion the return statement at the end of the function is misleading, because it suggests, that it may be reached at some point. How do I prevent it?
Please note, that I do error handling at some other point, which is why I can be sure, that someFunction will always return somethingElse.
Panic instead of returning fake value at the end of a function:
func someFunction(a []arr) int {
for _,v := range a {
if v == something {
// will defenitly get here at some point!
return somethingElse
}
}
panic("unreachable")
}
This is a common pattern in standard library.
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);
}
Sorry for the not so elusive title, but here is the piece of code I will use to explain my question!
while(motors[0].cycle <= maxcycle
&& motors[1].cycle <= maxcycle
&& motors[2].cycle <= maxcycle
&& motors[3].cycle <= maxcycle
&& motors[4], etc ...)
How can I avoid typing this very long condition for my while() loop, as I'm always checking the same parameter, only the index of my structure is changing.
How can I avoid typing this very long conditions, knowing that I'm always checking the same parameter, only the index of my structure is changing.
Add a function to do the checks and use the function in the while statement.
// MotorType is my contrived type. Use the right type.
bool doCheck(MotorType* motors, int count, int maxcycle)
{
for (int i = 0; i < count; ++i )
{
if ( !(motors[0].cycle <= maxcycle) )
{
return false;
}
}
return true;
}
while(doCheck(motors, count, maxcycle))
{
}
C++11 and above lets you fold the custom check function into a call of std::all_of using a lambda:
while (std::all_of(std::begin(motors), std::end(motors),
[=](Motor m){ return m.cycle < maxcycle; }))
{
...
Demo
Break it into a separate function and iterate through the array in the separate function and return true of it goes all the way through or false if it fails the if check.
You could do it in a loop:
while(true)
{
for(int i = 0, i < number, i++)
{
if (motors[i].cycle > maxcycle)
{
break;
}
}
//Do something
}
All the answers here which suggest an addition function do it... well, not neccessarily the best way. Here is why:
Since the loop is put into separate function, and the number of motors is not constant, compiler will most likely use the real loop and will not unroll it. Natural loops are a performance hazard when you counting nanoseconds.
However, original example didn't have that problem, as it didn't have a loop at all.
Solution: provide a function which would NOT use a loop at all, or make it easier for compiler to unroll it.
Abstract the condition into a method.
while ( allMotorsLessThanMax( motors, countMotors )) {
...
}
Then define that method with its own iteration:
bool allMotorsLessThanMax( Motor motors[], int countMotors ) {
for ( int i = 0; i < countMotors; ++i ) {
if ( maxcycle < motors[i].cycle ) {
return false;
}
}
return true;
}
Put it in a check in a lambda:
#include <algorithm>
...
void myFunction(){
auto allCycling = [&]() -> bool { // lambda function, capture by reference
return std::all_of( // for every element in the given range
motors.begin(), motors.end(), // given range is all of the motors container
[](const decltype(motors[0])& motor) -> bool {
return motor.cycle <= maxcycle; // check
});
while(allCycling()){
//do stuff
}
}
The capture by reference [&] for the lambda allows you to access all your function-wide variables in the lambda, without worrying about the costs of copying them.
I'll toss in the TMP version:
template < size_t I >
struct check_it
{
static bool call(motor_type * motors)
{
return check_it<I-1>::call(motors) && motors[I].cycles <= maxcycles;
}
}
template < >
struct check_it<0>
{
static bool call(motor_type * motors) { return motors[0].cycles <= maxcycles; }
};
while (check_it<42>::call(motors)) { ... }
Edit: I'm not necessarily recommending this, but it should optimize into exactly what you wrote. Hard to say if it's actually faster. Would depend on how many of the instructions are within the cache, etc... Maybe? You'd want to profile if it's important.
I want to Loop through the array of integers and want to remove the items in the TLToProcess list which i have stored in the array of integers
here is the code
I want to remove only the selected in the list integer
iSize.add(TLToProcess.size());
if(TLToProcess[i].Scan_In1__c==null)
{
if(TLToProcess[i].typew__c=='Pending')
{
TLForMissingHHhh.add(TLToProcess[i]);
}
}
else if ( c[i].Scan_In1__c!=null)
{
if (TLToProcess[i].typew__c=='Pending' )
{
TLToProcess[i].typew__c='Processed';
}
}
}
Now i want to remove record 1 by 1 from TLToProcess using
remove() can any body tell me how to do it.
Thanks
Anu
Not sure I understand your problem, but if what you're trying to avoid is modifying your List of integers inside a loop and getting this error: {"Collection was modified; enumeration operation may not execute."} you can create a copy of your List(.ToList()) and use it to iterate, and this way you can call Remove() safely.
List<Int32> arr = new List<Int32>();
for (int i = 0; i < 10; i++)
{
arr.Add(i);
}
foreach(var o in arr.ToList())
{
arr.Remove(o);
}
Is that the intent?
I'm not able to insert values into a Ruby array, and retrieve them later.
I put the results of different lines that I tried inside the first function. The results are:
VALUE rStraightCards;
static VALUE check_for_straight() {
stuff...
if (begin_straight != NOT_FOUND) {
for (i = begin_straight; i >= end_straight; i--) {
// this gives me a segmentation fault when I call straight_cards()
rb_ary_push(rStraightCards, i);
// these lines give me an empty ary when I call straight_cards()
// RARRAY_PTR(rStraightCards)[i] = i;
// RARRAY_PTR(rStraightCards)[INT2NUM(i)] = INT2NUM(i);
}
}
}
VALUE straight_cards() {
return rStraightCards;
}
void Init_straight_count() {
rStraightCards = rb_ary_new2(NUM_CARDS);
}
Both arguments for rb_ary_push are supposed to be of type VALUE but you're pushing an int (probably):
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
rb_ary_modify(ary);
return rb_ary_push_1(ary, item);
}
Try this:
rb_ary_push(rStraightCards, INT2NUM(i));
I think it is worth noting that VALUE will usually be defined like this:
typedef uintptr_t VALUE;
So the usual warning flags for int-to-pointer conversions won't catch this sort of error.