Reputation: 27
Suppose I want to calculate net_salary of an employee after taking into account the number of years he's worked and the number of kids he has. I don't want to use nested if statements since that will complicate the number of checks I need to make.
double base_salary, net_salary;
int nmbr_kids, nmbr_years;
if(nmbr_kids >= 1 && nmbr_kids <3){
net_salary = base_salary + 200;
}
else if(nmbr_kids >= 3 && nmbr_kids <4){
net_salary = base_salary + 400;
}
else if (nmbr_kids >= 4){
net_salary = base_salary + 600;
}
else{
net_salary = base_salary;
}
/* now I want to account for the number of years worked by the employee and update accordingly his net_salary */
if(nmbr_years >= 1 && nmbr_years <3){
net_salary = net_salary + 200;
}
else if(nmbr_years >= 3 && nmbr_years <4){
net_salary = net_salary +400;
}
else if(nmbr_years >= 4){
net_salary = net_salary + 600;
}
else{
net_salary = net_salary;
}
Is there a better, more compact way to do the above? Or am I looking at the problem the wrong way?
Upvotes: 2
Views: 139
Reputation: 778
Using the ternary conditional operator you could write it as:
net_salary = base_salary +
nmbr_kids == 0 ? 0 :
nmbr_kids <= 2 ? 200 :
nmbr_kids <= 3 ? 400 : 600;
net_salary +=
nmbr_years == 0 ? 0 :
nmbr_years <= 2 ? 200 :
nmbr_years <= 3 ? 400 : 600;
Or keeping the original logic in the question the first part would be:
net_salary = base_salary +
nmbr_kids >= 1 && nmbr_kids < 3 ? 200 :
nmbr_kids >= 3 && nmbr_kids < 4 ? 400 :
nmbr_kids >= 4 ? 400 : 0;
Upvotes: 1
Reputation: 754860
The first sequence can be altered to:
if (nmbr_kids == 0)
net_salary = base_salary + 0;
else if (nmbr_kids < 3)
net_salary = base_salary + 200;
else if (nmbr_kids < 4)
net_salary = base_salary + 400;
else
net_salary = base_salary + 600;
The key idea here is to eliminate conditions. The original had to check both ends of the range because the case of 0 kids was not dealt with first.
Alternatively, you can define an array:
double kids_bonus[] = { 0, 200, 200, 400, 600, 600, 600, 600 };
enum { NUM_KIDS_BONUS_VALUES = sizeof(kids_bonus) / sizeof(kids_bonus[0]) };
int eff_kids = nmbr_kids;
if (eff_kids >= NUM_KIDS_BONUS_VALUES)
eff_kids = NUM_KIDS_BONUS_VALUES - 1;
net_salary = base_salary + kids_bonus[eff_kids];
Or, with a min
function:
static inline int min(int x, int y) { return (x < y) ? x : y; }
int eff_kids = min(nmbr_kids, NUM_KIDS_BONUS_VALUES - 1);
net_salary = base_salary + kids_bonus[eff_kids];
Of course, if you have an upper limit on the number of kids, you can simply create an array big enough.
Your original condition else if (nmbr_kids >= 3 && nmbr_kids < 4)
would be better written as else if (nmbr_kids == 3)
, of course.
The same tactics can be used in the second case too.
Upvotes: 5
Reputation: 91139
You could do the following:
int find_value(int number, int * array, int length) {
if (number < length) {
return array[number];
} else {
return array[length-1];
}
}
#define LEN(arr) (sizeof(arr)/sizeof(arr[0]))
#define FIND(number, array) find_value(number, array, LEN(array))
int add_kids[] = {0, 200, 200, 400, 600};
int add_years[] = {0, 200, 200, 400, 600};
// ...
net_salary = base_salary + FIND(nmbr_kids, add_kids)
+ FIND(nmbr_years, add_years);
This is called a lookup table.
Upvotes: 1