How to avoid too much embedded if-else? [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
like this:
if(...){
if(...){
}else{
...
}
}else if(...){
if(...){
}else{
...
}
}else{
...
}
in coding always meet with that situation, it looks so terrible. how to avoid it?

There's no general rule. but, two common cases are:
When a switch/case could help you reduce the amount of code.
When you should have designed your code with a state machine instead.
Depending on you needs and codes these might be a better solution.

Assumption: you want to call some function depending upon result checked inside if-else ladder.
if you have a come with some index calculated with values you are checking inside the if-else condition, then having static array of function pointers could benefit you lot if ladder is too big.
eg.
uint8_t x;
uint8_t y;
if(x == 1)
{
if (y == 1)
call11();
else if (y==2)
call12();
}
else if( x == 2)
{
if (y == 1)
call21();
else if (y==2)
call22();
.
.
.
}
else if(x ==3)
.
.
.
Above code could be replaced as below
typedef void (*FuncPtr)();
FunPtr array[65535];
//intialize at once with some function
void initFunArray()
{
array[1*256 + 1] = call11;
array[1*256 + 2] = call12;
....
array[2*256 + 1] = call21;
array[2*256 + 2] = call22;
....
array[3*256 + 1] = call31;
array[3*256 + 2] = call32;
....
// Others will be set to null as array is static
}
uint8_t x;
uint8_t y;
index = x*256 + y;
array[index](); // calling appropriate call.

Generally when I see code like that I tend to wince a little. The worst case was a single file, 22 thousand lines long and only three functions - that made me sob.
The fact that at the lowest level you have a series of conditions which generally means some sort of type is involved.
So your code will look a bit like:
If (...) {
OnTypeConditionOne(...);
Else if (...) {
OnTypeConditionTwo(...);
Else {
OnTypeConditionThree(...);
}
Obviously you pass through whatever variables are needed to perform the subclauses. You then do the same to those subclauses until you have lots of small files. It is important to name the files something logical otherwise you might get lost in similar sounding names.

Related

Declare int variable aux a.length = (); Or use o.length () in all loops? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I wonder which is faster: Say I'm working with some text (30 characters), which would be better? And with a lot of text which would be better?
1-
int tam = text.length();
for(int i=0;i<tam;i++)
{
//something here//
}
2-
for(int i=0;i<a.length();i++)
{
//something here//
}
and also comparing these two:
1-
for (int i = 0; i < b.length(); i++)
{
aux = a.find(b[i]);
if (aux == -1)
{
sucess = 0;
break;
}
else
{
a.erase(aux,1);
}
}
2-
for (int i = 0; i < b.length(); i++)
{
if (a.find(b[i]) == -1)
{
sucess = 0;
break;
}
else
{
a.erase(a.find(b[i]),1);
}
}
Both first are the better approach.
On the first example you are checking if i<a.length() is true on every cycle. That means that you are going to execute a.length() for every iteration. If the variable a is not changed, it is unnecessary and the better approach is to calculate before and use that value.
Note that if the variable a is changed inside, placing i<a.length() might be the correct approach. It depends on your problem.
On the second example it is the same basics. You avoid useless calculations because you won't need to calculate a.find(b[i]) again inside the else.
As a general rule of thumb, as computations get bigger, more complex, and more frequent you want to minimize your unnecessary calculations. This means that storing something that needs to be calculated in a variable may speed up the process.
In both of your examples, for extremely large numbers,
int scratch = big.length();
for(int i=0;i<scratch;i++){
//body//
}
is usually faster.
In the future, general questions like this tend to belong in something like the Code Review Stack Exchange.

Does using function in programs speed up execution? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I just wanted to know If using function in the programs speeds up execution time?
Say, I have simple binary search Program
#include <stdio.h>
int main()
{
int c, first, last, middle, n, search, array[100];
scanf("%d",&n);
for ( c = 0 ; c < n ; c++ )
scanf("%d",&array[c]);
scanf("%d",&search);
first = 0;
last = n - 1;
middle = (first+last)/2;
while( first <= last )
{
if ( array[middle] < search )
first = middle + 1;
else if ( array[middle] == search )
{
printf("%d found at location %d.\n", search, middle+1);
break;
}
else
last = middle - 1;
middle = (first + last)/2;
}
if ( first > last )
printf("Not found! %d is not present in the list.\n", search);
return 0;
}
And Same Program using function.
I have just added the function
int binarysearch(int *array,int m,int n)
{
int l,u,mid;
l=0,u=n-1;
while(l<=u)
{
mid=(l+u)/2;
if(m==a[mid])
{
c=1;
break;
}
else if(m<a[mid])
{
u=mid-1;
}
else
l=mid+1;
}
return mid;
}
Code is just for understanding purpose!
Now Which will run faster? Program using Function or Iterative Programs? I'm talking in general not about any specific program.
Functions CAN make code faster by coding logic once instead of repeating several times and thus reducing code size and resulting in better CPU cache usage. Functions CAN make code slower by copying parameters and hiding info from the optimization. Certain functions can be inlined to undo these disadvantages. There are just so many variables you really cannot make a generalization.
Use functions when they help to make the code readable, maintainable and reusable.
Now Which will run faster?
You can find out by measuring... But don't bother. The more relevant questions you should ask yourself are "Which is more readable?" and "Which is easier to maintain?". Consider that you might need to do a binary search in more than one place in your code.

Is if statement over complicated? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
This is the part that brakes, zod1 zod2 zodA are vectors. In vectors I store int. Cant tell why it crashes cause it gives no error
if(zod1[u]+zod2[y]==zodA[t] || (zod1[u]+zod2[y])%10==zodA[t])
Questions:
1 Is if statement over complicated
2 Can I use vectors like that for solving math in if statement (sorry can't explain better)
3 If 2 question is true how should I solve it
Explanations:
variable names are in my own language (sorry if it looks weird)
Values are zero for all (ex zod1[u]=0)
added whole function (variables going to the function are passed correctly and I know I use some unnecessary thing)
void calc(vector<char> zodis1, vector<char> zodis2, vector<char> zodisAts,int zo1,int zo2,int zoA)
{int i,keliamas=0;
int k =0;
vector<int> zod1(0);
vector<int> zod2(0);
vector<int> zodA(0);
for(i=0;i<zodis1.size();i++)
{
zod1.push_back(0);
}
for(i=0;i<zodis2.size();i++)
{
zod2.push_back(0);
}
for(i=0;i<zodisAts.size();i++)
{
zod2.push_back(0);
}
int u=zodis1.size()-1;
int y=zodis2.size()-1;
int t=zodisAts.size()-1;
if(zod1[u]+zod2[y]==zodA[t] || (zod1[u]+zod2[y])%10==zodA[t])
{//if((zod1[u]+zod2[y])/10==1)
{
keliamas=1;
}
if(u==0||y==0||t!=0)
{
if(keliamas==1)
{
}
}
u--;
y--;
t--;
}
else
{if(zod1[u]!=9)
zod1[u]=zod1[u]+1;
else
{ if(u!=zodis1.size()-1)
u++;
else
{
cout<<"something wrong man";
}
}
}
}
EDIT:
Error is here:
for(i=0;i<zodisAts.size();i++)
{
zod2.push_back(0); // should be zodA
}
Is if statement over complicated
No, I think it is very simple with just one 'or'. However, if zodA[t] is always less than 10, then your if condition can be written as:
if ( (zod1[u]+zod2[y])%10==zodA[t] )
Can I use vectors like that for solving math in if statement (sorry
can't explain better)
Yes you can.
If 2 question is true how should I solve it
If it compiles but then crashes, then probably you are accessing out of bounds indices. Check that your indices are less than the vector sizes.

C++ total beginner needs guidance [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
yesterday,we had to solve problems at the codeforces contest
I couldn't solve this problem since I am a total beginner.
http://codeforces.com/contest/353/problem/A
I used this algorithm, but something is wrong with it. I think it should print s or f, however it prints nothing. it just auto closes. Even when I added an input to stop instant close
#include <cstdlib>
#include <iostream>
using namespace std;
int main(){
int y=0;
int x=0;
int f;
int a;
cin >> a;
int s;
s = 0;
int number [a][a];
for(int i = 0;i<a;i++){
cin >> number[i][0] >> number[i][1];
x += number[i][0];
y += number[i][1];
}
for(int i = 0;i<a;i++){
if(x%2==0 && y%2==0){
return s;
}else if(y%2!=0 && x%2==0){
f = -1;
return f;
}else if(y%2==0 && x%2!=0){
f = -1;
return f;
}else{
y+= number[i][0];
x+= number[i][1];
s++;
}
}
int g;
if(f!=-1){
cout << s;
}else{
cout << f;
}
}
As Angew said, the return statements are incorrect and causing you to exit your main. You want to replace this by a break; to exit the loop but not the function.
I have not spent effort in trying to understand your algorithm, but at first glance it looks more complicated than it should be.
From my understanding of the problem, there are 3 possibilities:
the totals of the upper halves and the lower halves are already even (so nothing needs to be done)
the totals of the upper halves and the lower halves cannot be made even (so no solution exists)
just one Domino needs to be rotated to get the totals of the upper halves and the lower halves to be even (so the time needed is 1 second)
I base this on the fact that adding only even numbers always gives an even result, and adding an even number of odd numbers also always gives an even result.
Based on this, instead of having a 2-dimensional array like in your code, I would maintain 2 distinct arrays - one for the upper half numbers and the other for the lower half numbers. In addition, I would write the following two helper functions:
oddNumCount - takes an array as input; simply returns the number of odd numbers in the array.
oddAndEvenTileExists - takes 2 arrays as input; returns the index of the first tile with an odd+even number combination, -1 if no such tile exists.
Then the meat of my algorithm would be:
if (((oddNumCount(upper_half_array) % 2) == 0) && ((oddNumCount(lower_half_array) % 2) == 0))
{
// nothing needs to be done
result = 0;
}
else if (((oddNumCount(upper_half_array) - oddNumCount(lower_half_array)) % 2) == 0)
{
// The difference between the number of odd numbers in the two halves is even, which means a solution may exist.
// A solution really exists only if there exists a tile in which one number is even and the other is odd.
result = (oddAndEvenTileExists(upper_half_array, lower_half_array) >= 0) ? 1 : -1;
}
else
{
// no solution exists.
result = -1;
}
If you wanted to point out exactly which tile needs to be rotated, then you can save the index that "oddAndEvenTileExists" function returns.
You can write the actual code yourself to test if this works. Even if it doesn't, you would have written some code that hopefully takes you a little above "total beginner".

For loop variable going to hell for seemingly no reason? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have run into what seems to be a very obscure bug. My program involves looping some code for a long time, and eventually running some functions in the loop. Weirdly, after I run a specific function, my for loop variable, 'z', jumps from 3200 to somewhere around 1059760811 (it changes every time). The function does not naturally use the loop variable, so I honestly have no idea what is happening here.
The entire code is too long to paste here, so I will try to paste only the important parts, with the relevant functions first and the for loop after:
void enterdata(float dpoint,int num){
autodata[num] += dpoint;
}
float autocorr(){
float autocorrelation = 0;
for(int a = 0; a<SIZEX; a++)
{
for(int b = 0; b<SIZEY; b++)
{
if(grid[a][b] == reference[a][b]){autocorrelation++;}
}
}
autocorrelation /= SIZEX*SIZEY;
autocorrelation -= 0.333333333333;
return autocorrelation;
}
for (long z = 0.0; z<MAXTIME; z++)
{
for (long k=0; k<TIMESTEP; k++)
{
grid.pairswap();
}
if (z == autostart_time)
{
grid.getreference();
signal = 1; // signal is used in the next if statement to verify that the autocorrelation has a reference.
}
if ((z*10)%dataint == 0)
{
if (signal == 1) {
//!!! this is the important segment!!!
cout << z << " before\n";
grid.enterdata(grid.autocorr(),count);
cout << z << " after\n";
cout << grid.autocorr() << " (number returned by function)\n";
count++;
}
}
if (z%(dataint*10) == 0) { dataint *= 10; }
}
From the "important segment" marked in the code, this is my output:
3200 before,
1059760811 after,
0.666667 (number returned by function)
Clearly, something weird is happening to the 'z' variable during the function. I have also become convinced that it is the enterdata function and not the autocorrelation function from tests running each separately.
I have no idea how to fix this, or what is going on. Help?!?!?
Thanks!
Looks like you may have a Stack Overflow issue in your enterdata function.
Writing to before the array starts or past the end of the array result in undefined behavior, including writing over variables already on the stack.
#WhozCraig is right, a stack overwrite by a called function seems the most likely explanation.
You should be able to find out in your debugger how to break on any change to the memory at address of z, this will quickly provide an exact diagnosis.
For Visual Studio (for example), see here.