Happy New Year.
I'm working on a C++ project, which goes something like this:
for(s=1; s<=n; s++){
for (k=2; k<=n; k++) {
den[k] = 0;
den[k] = sqrt((abs(a[1][1][x]))*(abs(a[1][1][x])) + (abs(a[k][1][x]))*(abs(a[k][1][x])));
....Some magic happens here
}
}
What I cannot figure out is how to make the a[y][y][x] array add one to the third cell (i.e. it becomes a[y][y][x+1]) every time the inner loop takes place.
So, for example, let's say n = 3.
Then after the inner for loops takes place once, then add 1 to x. After it takes place again, add 1 again to x. Then the outer loop will take place, and the inner loop will start again; I want to just add another +1 again to the x. So in total, I want to add six 1's (since the inner loop will run 6 times- one for each time).
Thanks in advance.
I'm not 100% sure what you're asking, but I think you're looking for this:
int xDelta = 0;
for(s=1; s<=n; s++){
for (k=2; k<=n; k++, xDelta++) {
den[k] = 0;
den[k] = sqrt((abs(a[1][1][x + xDelta]))*(abs(a[1][1][x + xDelta])) + (abs(a[k][1][x + xDelta]))*(abs(a[k][1][x + xDelta])));
....Some magic happens here
}
}
Or if you're looking to actually modify the x variable itself...
for(s=1; s<=n; s++){
for (k=2; k<=n; k++, x++) {
You can use the command
++x;
to increment the value of the variable x.
it looks easy or maybe I didn't get the
for(s=1; s<=n; s++){
int myX = x;
for (k=2; k<=n; k++) {
den[k] = 0;
den[k] = sqrt((abs(a[1][1][x]))*(abs(a[1][1][myX])) + (abs(a[k][1][myX]))*(abs(a[k][1][myX])));
....Some magic happens here
myX++;
}
}
Related
I'm trying to compare two decks of cards, yet every time I try another method of doing it, I get the same result... Everything before the code outputs, and it just freezes as soon as it hits the comparison code, as if it's stuck in an infinite loop.
I've tried for loops, static variables, do-while loops, etc. This is my first time leaving the loop at the client code.
The code that supposedly throws the program into an infinite loop.
while (repeatLoop == false)
{
deck1.shuffleDeck();
counter++;
repeatLoop = deck1.compareDecks();
}
compareDecks function.
bool deck::compareDecks()
{
int deckCount = 0;
suitType tempOriginalSuit;
suitType tempShuffleSuit;
rankType tempOriginalRank;
rankType tempShuffleRank;
while (index < 52)
{
tempOriginalSuit = originalCardDeck[index].getSuit();
tempShuffleSuit = shuffledCardDeck[index].getSuit();
if (int(tempOriginalSuit) == int(tempShuffleSuit))
{
tempOriginalRank = originalCardDeck[index].getRank();
tempShuffleRank = shuffledCardDeck[index].getRank();
if (int(tempOriginalRank) == int(tempShuffleRank))
{
deckCount++;
if (deckCount == 52)
return true;
}
}
else
{
return false;
index++;
}
}
}
The shuffleDeck function
(This function pushes back the first card from the first half of the deck and the first card from the second half of the deck towards the end until all 52 cards have been pushed in this pattern. This makes the deck have 52 x 2 cards (with the second half of the deck being the perfect shuffle), so I delete the first half of the cards using .erase as it is not needed)
void deck::shuffleDeck()
{
for (int a = 0, b = 2; a < 2 && b < 4; a++, b++)
{
for (int i = 2; i < 15; i++)
{
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(a),
static_cast<cardSpace::rankType>(i) });
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(b),
static_cast<cardSpace::rankType>(i) });
}
}
shuffledCardDeck.erase(shuffledCardDeck.begin(),
shuffledCardDeck.begin() + (shuffledCardDeck.size() / 2));
}
The two decks initialized by this constructor.
deck::deck()
{
for (int i = 0; i < 4; i++)
{
for (int j = 2; j < 15; j++)
{
originalCardDeck.push_back(card{ static_cast<cardSpace::suitType>(i),
static_cast<cardSpace::rankType>(j) });
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(i),
static_cast<cardSpace::rankType>(j) });
}
}
}
Also note that I've done a perfect shuffle on the shuffledCardDeck vector in another function. I'm trying to repeat the perfectShuffle function until it reaches it's original state and output how many times it took to do this.
I get an infinite loop.
EDIT: I've decided to add the return false; statement in the compareDecks function into the if-else. Also, I think what's causing the problem is that my index i is reset to zero everytime it is called again. Are there any solutions you guys could propose to this? I've tried using static variables, but they just would not increment in the for loop.
EDIT 2: I enclosed my if statements within the curly braces, per users' request, as it's a flaw in my code.
EDIT 3: After commenting out
deck1.shuffleDeck()
The compareDecks function returned true, stating that the decks are equal, which isn't supposed to happen... This caused the loop to end after only one loop.
I was expecting you to actually shuffle the deck.
Your code was pushing a specific, newly synthesized card onto the end of the deck:
shuffledCardDeck.push_back(card{ static_cast<cardSpace::suitType>(a),
static_cast<cardSpace::rankType>(i) });
For example, the first card it will push is always the 2 of 0's (Whatever the 0th suit is). That's not what you want. You actually want to push a copy of the card that is at a specific position index in the deck. For example, loop index from 0 to 25 and then push shuffledCardDeck[index] and shuffledCardDeck[26 + index].
Then you can still wrap up by using your technique of erasing the first half of the deck.
void deck::shuffleDeck()
{
for (int index = 0; index < 26; ++index) {
shuffledCardDeck.push_back(shuffledCardDeck[index]);
shuffledCardDeck.push_back(shuffledCardDeck[26 + index]);
}
shuffledCardDeck.erase(shuffledCardDeck.begin(),
shuffledCardDeck.begin() + 52);
}
You are not modifying the value in the loop, you're using a double equals sign:
repeatLoop == deck1.compareDecks();
That would explain your observed behavior.
I have a code block as following, where the inner for loop code remains the same but only the loop condition changes based on the reverseFlag. Is there a better way to code this without having to copy paste the content of the for loop twice ?
bool reverseFlag=false;
if (reverseFlag)
{
for(int i = 1; i < TotalFrames; i++)
{...}
}
else
{
for(int i = TotalFrames-1; i >0; i--)
{...}
}
Yes, you can do it in a single for loop, like this:
int from, to, step;
if (reverseFlag) {
from = TotalFrames-1;
to = -1;
step = -1;
} else {
from = 0;
to = TotalFrames;
step = 1;
}
for (int i = from ; i != to ; i+= step) {
...
}
A single conditional ahead of the loop prepares loop's parameters - i.e. its starting and ending values and the step, and then the loop uses these three values to iterate in the desired direction.
There are several options. You can:
Use two loops but put the loop body in a separate function/object/lambda.. to avoid duplication.
Use an increasing loop and calculate the real index within the loop:
j = reverseFlag ? TotalFrames - i : i;
Pre-calculate the loop conditions as #dasblinkenlight suggested.
Note that if you have a performance critical loop, some of these methods could hurt performance. If in doubt, check what your compiler does and measure the elapsed time.
I'm trying to work out what the equivalent a[++j]=*pr++; in the following code (which comes from a MatLab mex file) is in Python. I've found out that 'pr' is a pointer to the first element of the input array, but I can't get my head around what is happening to j. Can someone explain what is happening there in simple terms without pointers etc?
rf3(mxArray *array_ext, mxArray *hs[]) {
double *pr, *po, a[16384], ampl, mean;
int tot_num, index, j, cNr;
mxArray *array_out;
tot_num = mxGetM(array_ext) * mxGetN(array_ext);
pr = (double *)mxGetPr(array_ext);
array_out = mxCreateDoubleMatrix(3, tot_num-1, mxREAL);
po = (double *)mxGetPr(array_out);
j = -1;
cNr = 1;
for (index=0; index<tot_num; index++) {
a[++j]=*pr++;
while ( (j >= 2) && (fabs(a[j-1]-a[j-2]) <= fabs(a[j]-a[j-1])) ) {
ampl=fabs( (a[j-1]-a[j-2])/2 );
switch(j)
{
case 0: { break; }
case 1: { break; }
case 2: {
mean=(a[0]+a[1])/2;
a[0]=a[1];
a[1]=a[2];
j=1;
if (ampl > 0) {
*po++=ampl;
*po++=mean;
*po++=0.50;
}
break;
}
default: {
mean=(a[j-1]+a[j-2])/2;
a[j-2]=a[j];
j=j-2;
if (ampl > 0) {
*po++=ampl;
*po++=mean;
*po++=1.00;
cNr++;
}
break;
}
}
}
}
for (index=0; index<j; index++) {
ampl=fabs(a[index]-a[index+1])/2;
mean=(a[index]+a[index+1])/2;
if (ampl > 0){
*po++=ampl;
*po++=mean;
*po++=0.50;
}
}
/* you can free the allocated memeory */
/* for array_out data */
mxSetN(array_out, tot_num - cNr);
hs[0]=array_out;
}
Here's what happens:
Increment j by 1
assign to a[j] value pointed at by pr
increment pr.
In this order.
You specifically asked about:
a[++j]=*pr++;
j is being incremented before the assignment. In python the left hand side would be:
a[j+1]
and you would also then need to increment j before you use it next:
j += 1
The right hand side simply accesses the current position and then increments the position in the array. In python you would probably just use an iterator for your array.
BTW, you might find it difficult to do a line-by-line 'translation' of the code. I would suggest writing down the steps of the algorithm and then tackling it fresh in python, if that is what you need.
In Python, there aren't pointers, so how you translate this will depend on how you decide to represent pr. If you think of the pointer as a copy of the list pr = array_ext[:], the line you've highlighted would be something like
j = j + 1
a[j] = pr.pop(0)
For greater efficiency (and a closer parallel to what the C code is doing), you could use pr as an index into the list array_ext, starting it at 0. Then, the line you highlighted does this:
j = j + 1
a[j] = array_ext[pr]
pr = pr + 1
Sorry for this very simple looking problem, but I have no idea what causes it:
In a C++ project I have a loop in a loop in a loop and have to leave the inner two so I have a variable for a query. In the first iteration it works fine, but in the second the assign from dtime to abbruch does not work. In the Debugger dtime has correctly the value "1" and abbruch "0" but this stays after the assignment. Both are of type long.
for (sect = 0; sect <= sections; sect++)
{
abbruch = 0;
for(line = 0; line < maxlines ; line ++)
{
abbruch = dtime[sect][0];
if(abbruch != 0)
{
break;
}
for (index = 0; index < 30; index ++)
{
if (complicated query)
{
dtime[sect][0] = DiffTime[maxlines * sect + line];
break;
}
}
}
}
I use VS2012 Ultimate.
Has anyone an idear how this can happen ot how to solve it?
Did you maybe mean to put this?
abbruch = dtime[sect][line];
(line instead of 0)
But also what Bathseba said is true. A break will only break one for-loop.
break will only take you out of the current for loop. In your case, the loop over index will not be called following a break when abbruch != 0 as that break will take you out of the loop over line. The other break statement will take you out of the loop over index.
That's the rationale, but, by far the best thing to do is to step through with a debugger. I wouldn't use break statements in this way as it's too confusing. Consider breaking the triple loop structure into function calls using return statements in place of breaks.
Also, it's a good idea to localise the interating variables in the for loops, e.g.
for (int sect = 0; sect <= sections; sect++)
How do you Make A Repeat-Until Loop in C++? As opposed to a standard While or For loop. I need to check the condition at the end of each iteration, rather than at the beginning.
do
{
// whatever
} while ( !condition );
When you want to check the condition at the beginning of the loop, simply negate the condition on a standard while loop:
while(!cond) { ... }
If you need it at the end, use a do ... while loop and negate the condition:
do { ... } while(!cond);
You could use macros to simulate the repeat-until syntax.
#define repeat do
#define until(exp) while(!(exp))
Just use:
do
{
//enter code here
} while ( !condition );
So what this does is, it moves your 'check for condition' part to the end, since the while is at the end. So it only checks the condition after running the code, just like how you want it
For an example if you want to have a loop that stopped when it has counted all of the people in a group. We will consider the value X to be equal to the number of the people in the group, and the counter will be used to count all of the people in the group. To write the
while(!condition)
the code will be:
int x = people;
int counter = 0;
while(x != counter)
{
counter++;
}
return 0;
Repeat is supposed to be a simple loop n times loop... a conditionless version of a loop.
#define repeat(n) for (int i = 0; i < n; i++)
repeat(10) {
//do stuff
}
you can also also add an extra barce to isolate the i variable even more
#define repeat(n) { for (int i = 0; i < n; i++)
#define endrepeat }
repeat(10) {
//do stuff
} endrepeat;
[edit]
Someone posted a concern about passing a something other than a value, such as an expression. just change to loop to run backwards, causing the expression to be evaluated only once
#define repeat(n) { for (int i = (n); i > 0; --i)
This can also work
int repeat;
repeat = 0;
//to repeat once
do {
....
repeat + 1;
} while(repeat < 1);
This is of course assuming you want to only repeat once, so you can change the value of repeat, not the amount of it's increase from the variable amount from the while(); condition. This code works for C++ 17, but I am not sure for other versions.