Lets say I have a boolean bool, and two ints a and b. If bool is true, I want to return a < b, and if bool is false I want to return a > b. Obviously I can write:
if (bool)
return a < b;
else
return a > b;
But this is repetitive. I only want to have to write one return statement, of the form return a (desired operator) b, but I am not sure what that would look like. What would be the simplest way to do this? Obviously this example is fairly trivial, but for larger blocks of code, I'd prefer to not have to rewrite it multiple times with only the operator changed.
In my opinion there's no such operator in C, plus, C doesn't have operator overloading, so that's not possible too.
The best you can do is a function to encapsulate this logic:
function findWhetherLessOrMore(bool findWhetherLess, int operand1, int operand2) {
return findWhetherLess ? operand1 < operand2 : operand1 > operand2;
}
You can change the function name to be concise, so that it does not bloat the code when used a large number of times.
As said in other answers here, I would suggest reconsidering your design if you've to do too much of these condition checks in the program.
There are a handful of options, but none of them are simpler than just writing directly what you want.
Macros:
#define OVERLOADER(cond,a,b,op1,op2) cond ? a op1 b : a op2 b
usage:
return OVERLOADER(cond, a, b, <, >);
Virtual functions (which may optimise well when defined static)
typedef int(*func)(int a, int b);
static int lt(int a, int b) { return a < b; }
static int gt(int a, int b) { return a > b; }
static int dispatcher(int cond, int a, int b, func aa, func bb) {
return cond ? aa(a,b) : bb(a,b);
}
// usage:
int main(int ac, char **av) {
return dispatcher(ac, (int)av[0][0],(int)av[0][1], lt, gt);
}
Also if the operator is particularly difficult to evaluate, one might convert the problem into the form
if (!cond) {
swap(a,b);
}
return a < b;
The ternary operator will always help in writing conditional statements in a single line and/or having a single return statement.
return cond ? a < b : a > b;
// or
return (cond ? a : b) < (cond ? b : a);
I would anyway be a bit suspicious of the need to have a block of hundreds of conditions like this, which my intuition tells that should have a better higher level design.
Related
I am confused when to use 'return' while using recursive function calls.
I am trying to find the "GCD (Greatest common divisor)" of two numbers. What I actually thought would work is:
include <stdio.h>
int gcd (int a, int b);
int main ()
{
int a, b;
printf ("Enter two numbers \n");
scanf ("%d %d", &a, &b);
printf ("GCD for numbers %d and %d is %d\n", a, b, gcd(a,b));
return (0);
}
int gcd (int a, int b)
{
while (a!=b)
{
if (a > b)
gcd(a-b,b);
else if (b > a)
gcd(a,b-a);
}
return (a);
}
But the above code continuously accepts numbers from terminal and fails to run the code.
However, when I replace the function definition as follows the code works as expected returning the right values.
int gcd (int a, int b)
{
while (a!=b)
{
if (a > b)
return gcd(a-b,b);
else if (b > a)
return gcd(a,b-a);
}
return (a);
}
As you see the only change is addition of 'return' before the recursive function call. Why is return required there considering in both the cases I am calling the gcd(arg1, arg2) function?
Why is return required there considering in both the cases I am calling the gcd(arg1, arg2) function?
For the same reason that it is required any other time you call a function and wish to return the value that was returned by that function call; because calling it only calls it, and does nothing else with the resulting value.
I am confused when to use 'return' while using recursive function calls.
Use return for a recursive call, whenever you would use return for any other function call - i.e.: when, and because, that call returns the value you wish to return this time around.
Imagine that we have
#include "magic.h" /* defines gcd2(), which computes GCD in some mysterious way */
And then instead of making recursive calls, we delegate some of the work to that:
/* Of course this solution also works, but is not interesting
int gcd(int a, int b)
{
return gcd2(a, b);
} */
/* So, let's do something that actually shows off the recurrence relation */
int gcd(int a, int b)
{
if (a > b)
return gcd2(a-b, b);
else if (b > a)
return gcd2(a, b-a);
else
return a;
}
(I also removed the while loop, because it is not relevant to the algorithm; of course, a return is reached in every circumstance, and this breaks the loop.)
I assume I don't need to go over the mathematical theory; and also I assume it is clear why return is needed for the gcd2 results.
But it doesn't actually matter how the work is delegated; if gcd is a function that correctly computes GCDs, and gcd2 is also such, then a call to gcd2 may be replaced by a call to gcd. This is the secret - calling a function recursively is not actually different from calling one normally. It's just that considering the possibility, requires a clearer understanding of how calling a function works and what it actually does.
Of course, it is also possible to make good use of the original while loop - by subtracting out as much as possible before doing the recursion. That might look like:
int gcd(int a, int b)
{
if (a > b)
while (a > b)
a -= b; /* prepare a value for the recursion. */
return gcd(a, b); /* and then recurse with that value. */
else if (b > a)
while (b > a)
b -= a; /* similarly. */
return gcd(a, b);
else /* a == b */
return a;
}
But then we might as well go all the way and convert to an iterative approach:
int gcd(int a, int b)
{
while (a != b)
/* whichever is greater, adjust it downward, leaving an (a, b)
pair that has the same GCD. Eventually we reach an equal pair,
for which the result is known. */
if (a > b)
a -= b;
else
b -= a;
return a; /* since the loop exited, they are equal now. */
}
(And we also could do modulo arithmetic to accomplish multiple subtractions at once; this is left as an exercise.)
The first gcd function "tries" to compute the gcd but in the end always returns a unchanged.
The second gcd function computes the gcd recursively and each invocation returns a gcd.
Shake sort of vector:
program works, but:
I was trying to use the same function for bubble up and bubble down for shake sort (bubble up to get the MAX value to the right and bubble down to get the min value to the left). In order to do it I was trying to use the following MACRO which does not compile:
sign is '+' and oper is '>' for bubble
sign is '-' and oper is '<' for bubble down
for bubble up -
start is iterator i (iterated the Vector indices)
end is n-1-i;
for bubble down -
swap start and end values
#define bubble_up_down(var_t, pVector, _Is_swp, start, end, sign, oper)\
{\
var_t current_index;\
var_t current_val;\
var_t next_val;\
for (current_index = *(start) ; current_index (oper) *(end) ; (sign)(sign)current_index){\
{\
VectorGet((pVector), current_index, ¤t_val);\
VectorGet((pVector), current_index(sign)1, &next_val);\
if(current_val (oper) next_val)\
{\
VectorSet((pVector), current_index, next_val);\
VectorSet((pVector), current_index(sign)1, current_val);\
*(_Is_swp) = 1;\
}\
}\
}
Need your advice to fix this macro.
It is not really clear why you want to use a macro here. Do you want to avoid duplicaing code? Or do you want to make your sorting routine type independent?
Anyway, your macro has several errors:
You've probably read that you should guard macro arguments with parentheses. That is usually good advice, because macros are text replacements; for example infamous SQ(x + 1) will resolve to x + 1*x + 1. In your case, the advice is wrong-headed. You will get syntactically wrong "operators" such as (-) and (<) in your code. Just use sign and oper.
Even so, sign sign will resolve to - - or + +, which is not what you want. You could rewrite i++ to the equally valid i = i + 1 or you could use the token-pasting operator, sign##sign, which would produce -- or ++.
Macros aren't functions. You are probably going to invoke your macro inside a function. All local variables that are in scope hen you invoke the macro are also in scope for the macro. That means there is probably no need to define all these pointers.
Why do you pass the array element type, var_t? I reckon that SetVector and GetVector aren't macros, so the type independence falls flat.
If var_t is the type of your array elements, your index isn't necessarily of the same type; it should be an integer type. (Your elements must be comparable with the < operator, so it is one of the arithmetic types, but image what happens if you have an array of char that is longer than 256 elements?)
If your elements are of arithmetic type, there's probably no need for the GetValue and SetValue calls. You can just assign values with the = operator .
All this makes me think that you don't really know what you're doing. That plus the known pitfalls and shortcomings of macros are a good reason not to use any macros here.
Addendum In comments, The PO has said that the macro should achieve two things: It should avoid repeated code and it should make the sorting independent of the types of the array elements. These are two different things.
Writing short local macros to avoid repeating code can be a useful technique, especially, if the code needs to keep variables in sync in several places. Is it useful in your situation?
So you've got your upward-bubbling code:
int done = 0;
while (!done) {
done = 1;
for (int i = 1; i < n; i++) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
}
(This uses a swap function to swap two array elements. It is more straightforward than your version, because it doesn't use get/set accessor functions.) Now you write the downward-bubbling counterpart:
while (!done) {
done = 1;
for (int i = n - 1; i > 0; i--) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
}
These two snippets differ only in the loop control. Both visit all indices from 1 to n - 1. So your macro needs to pass the start and end values. But it also needs to know which way the comparison goes – less than or greater than – and whether to increment or to decrement the index. That's four pieces of data for a simple loop.
You could try to get rid of the comparison and use != for both directions. But then your loops will fail if the array is empty.
The above backwards loop will already fail on empty arrays when you use an unsigned integer as index. Forward and backward lops are asymmetric an C, because the lower and upper bounds are asymmetric, too: Lower bound are always inclusive, upper bound are always exclusive. This forward loop:
for (unsigned int i = 0; i < n; i++) ...
Has the following backward equivalent:
for (unsigned int i = n; i-- > 0; ) ...
Here, the decrement occurs in the condition and the update part is empty. The advantage is that it uses exactly the same bounds, 0 and n, verbatim, but by decrementing before entering the loop body, the same valid range of numbers, 0 to n - 1 are visited. And it works with unsigned ints, which are a natural choice for looping variables.
To cut a long story short: Forward and backward loops are asymmetric in C, so it is not easy to write a macro for them. C's for syntax is more verbose than for i = 1 to n, but that's how it is. Embrace it and alleviate the typing pain by chosing appropriate index names: it's i, not current_index.
Can you make the code less redundant without macros? Of course: You can write two functions for bubbling up and down once:
static int bubble_up(int a[], int n)
{
int done = 1;
for (int i = 1; i < n; i++) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
return done;
}
static int bubble_down(int a[], int n)
{
int done = 1;
for (int i = n; i-- > 1; ) {
if (a[i - 1] > a[i]) {
swap(a, i - 1, i);
done = 0;
}
}
return done;
}
(These functions are static, i.e. private to the current compilation unit.) Now your actual sorting functions look like this:
void sort_bubble_up(int a[], int n)
{
int done = 0;
while (!done) {
done = bubble_down(a, n);
}
}
void sort_bubble_down(int a[], int n)
{
int done = 0;
while (!done) {
done = bubble_down(a, n);
}
}
void sort_shaker(int a[], int n)
{
int done = 0;
while (!done) {
done = bubble_up(a, n) || bubble_down(a, n);
}
}
If you are not afraid of empty loop bodies, you can even get them down to:
void sort_bubble_up(int a[], int n)
{
while (bubble_down(a, n)) { }
}
void sort_bubble_down(int a[], int n)
{
while (bubble_down(a, n)) { }
}
void sort_shaker(int a[], int n)
{
while (bubble_up(a, n) || bubble_down(a, n)) { }
}
All this code works only for int arrays, though. The standard library's way of approaching type independence is to work on the byte level via void * pointers and user-defined comparison functions. The sorting function qsort does this, for example.
C++ and other languages have templates, where you can write an algorithm for several types. When you "instantiate" a template, the compiler creates a function for just this type, which is then called.
You could emulate this with macros. If you just want to call your macro in the function body, you could define:
#define BUBBLE_SORT(ARRAY, N, TYPE) do { \
int done = 0; \
int i; \
\
while (!done) { \
done = 1; \
\
for (i = 1; i < N; i++) { \
if (ARRAY[i - 1] > ARRAY[i]) { \
TYPE sawp = ARRAY[i]; \
\
ARRAY[i] = ARRAY[i - 1]; \
ARRAY[i - 1] = swap; \
done = 0; \
} \
} \
} \
} while (0)
and then use the macro like so:
char c[] = "Mississippi";
BUBBLE_SORT(c, strlen(c), char);
(That do { ... } while (0) thing around thze macro makes the macro behave like a function call, sort of. The new scope of the loop body allows for local variables.)
The problem here is that such multi-line macros are hard to debug. When there is an error in the body, you just get the number of the line where the macro is invoked in an error message. (But you can use -E with most compilers to see how the preprocessor resolves that macro.)
Conclusion:
Macros can be useful, but you have to know what you are doing. In general, try to avoid them, because they are hard to debug and often hard to understand for others. (And this other person might be you half a year later.)
If you must use macros, try to make then look as natural as possible. Passing operators like > or + should make you wary.
Use functions, not macros, for common code.
Embrace C's way to deal with different types. It will be more useful (if less fun) to learn how qsort works than to fiddle with macros for a bubble sort implementation.
If you really need to write a lot of type-independent code, you probably shouldn't use C.
I have a programming assignment that goes like this:
You are given three numbers a, b, and c. (1 ≤ а, b, c ≤ 10^18)
Each time you have two choises, either add b to a (a+=b), or add a to b (b+=a). Write a program that will print out YES or NO depending on whether you can get to c by adding a and b to each other.
I've tried solving this problem using recursion that branches to two branches every time where one branch stores a+b, b and the other branch stores a, b+a. In every recursive call, the function checks the values of a and b, and if they are equal to c the search stops and the function prints YES. The recursion stops when either a or b have a value greater than c.
Here's how the branching works:
And here's the code in C:
#include <stdio.h>
#include <stdlib.h>
void tree(long long int a, long long int b, long long int c){
if(a==c || b==c){
printf("YES");
exit(0);
}
else if(a<c && b<c){
tree(a, b+a, c);
tree(a+b, b, c);
}
}
int main(){
long long int a, b, c;
scanf("%I64d", &a);
scanf("%I64d", &b);
scanf("%I64d", &c);
tree(a, b, c);
printf("NO");
return 0;
}
Now, this program works for small numbers, but since a b and c can be any 64-bit number, the tree can branch itself a few billion times, and the program runs out of memory and crashes.
My question is: Is there any way i can improve my code, or use any other way (other then recursion) to solve this?
OK I'll have to admit that this turned out to be a fascinating question. I really thought that there should be a quick way of finding out the answer but the more I looked at the problem, the more complex it became. For example, if you zigzag down the tree, alternating a+=b with b+=a, you are essentially creating the fibonacci sequence (imagine a=2 and b=3 to start with). Which means that if you could find the answer quickly, you could somehow use a similar program to answer "is c a fibonacci number"?
So I never came up with anything better than searching the binary tree. But I did come up with a way to search the binary tree without running out of memory. The key trick in my algorithm is that at every node you need to search two child nodes. But you don't need to recurse down both paths. You only need to recurse down one path, and if that fails, you can iterate to the other child. When recursing, you should always pick the path where the smaller number changes. This guarantees that you are doubling the minimum element on each recursion level, which guarantees that you will only recurse 64 times max before your minimum element will exceed 2^64.
So I wrote the program and ran it, and it worked just fine. That is until I entered a very large number for c. At that point, it didn't finish. I found from testing that the algorithm appears to have an O(N^2) running time, where N = c. Here are some sample running times (all on a desktop running 64-bit Windows).
Inputs Time in minutes
------ ---------------
a=2 b=3 c=10000000000 (10^10): 0:20
a=2 b=3 c=100000000000 (10^11): 13:42
a=2 b=3 c=100000000001 : 2:21 (randomly found the answer quickly)
a=2 b=3 c=100000000002 : 16:36
a=150 b=207 c=10000000 (10^7) : 0:08 (no solution)
a=150 b=207 c=20000000 : 0:31 (no solution)
a=150 b=207 c=40000000 : 2:05 (no solution)
a=150 b=207 c=100000000 (10^8) : 12:48 (no solution)
Here is my code:
// Given three numbers: a, b, c.
//
// At each step, either do: a += b, or b += a.
// Can you make either a or b equal to c?
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
static int solve(uint64_t a, uint64_t b, uint64_t c);
int main(int argc, char *argv[])
{
uint64_t a = 0, b = 0, c = 0;
if (argc < 4) {
printf("Usage: %s a b c\n", argv[0]);
exit(0);
}
a = strtoull(argv[1], NULL, 0);
b = strtoull(argv[2], NULL, 0);
c = strtoull(argv[3], NULL, 0);
// Note, by checking to see if a or b are solutions here, solve() can
// be made simpler by only checking a + b == c. That speeds up solve().
if (a == c || b == c || solve(a, b, c))
printf("There is a solution\n");
else
printf("There is NO solution\n");
return 0;
}
int solve(uint64_t a, uint64_t b, uint64_t c)
{
do {
uint64_t sum = a + b;
// Check for past solution.
if (sum > c)
return 0;
// Check for solution.
if (sum == c)
return 1;
// The algorithm is to search both branches (a += b and b += a).
// But first we search the branch where add the higher number to the
// lower number, because that branch will be guaranteed to double the
// lower number, meaning we will not recurse more than 64 times. Then
// if that doesn't work out, we iterate to the other branch.
if (a < b) {
// Try a += b recursively.
if (solve(sum, b, c))
return 1;
// Failing that, try b += a.
b = sum;
} else {
// Try b += a recursively.
if (solve(a, sum, c))
return 1;
// Failing that, try a += b.
a = sum;
}
} while(1);
}
Edit: I optimized the above program by removing recursion, reordering the arguments so that a is always less than b at every step, and some more tricks. It runs about 50% faster than before. You can find the optimized program here.
Based on comment from #Oliver Charlesworth, this is an iterative not recursive solution so it won't solve the homework. But it's pretty simple, I step through b because it is larger than a (although that is not entirely clear from the OP) hence fewer iterations required.
#include <stdio.h>
int main(){
unsigned long long int a, b, c, bb;
scanf("%I64u", &a);
scanf("%I64u", &b);
scanf("%I64u", &c);
if (a >= 1 && a < b && b < c) {
for (bb=b; bb<c; bb+=b) {
if ((c - bb) % a == 0) {
printf ("YES\n");
return 0;
}
}
}
printf("NO\n");
return 0;
}
What is the advantage of using bool variable in the code below instead of an int to set the value 1 or 0? What difference does it make?
#include<stdio.h>
int main(void)
{
int p,d;
_Bool isPrime;
for ( p = 2; p <= 50; p++){
isPrime = 1;
for (d = 2; d < p; d++)
if (p %d == 0)
isPrime = 0;
if (isPrime != 0)
printf("%i ",p);
}
printf("\n");
return 0;
}
It's useful for making your intent clear. When you declare a variable as Bool_, it's obvious it's never supposed to have a value other than true and false.
A more conventional way to write your example code would be:
#include
int main(void)
{
for (int p = 2; p <= 50; p++) {
bool isPrime = true;
for (int d = 2; d < p; d++) {
if (p % d == 0) isPrime = false;
}
if (!isPrime) printf("%i ", p);
}
printf("\n");
return 0;
}
I just use plain ints as my boolean type without any typedefs or special defines or enums for true/false values. If you follow my suggestion below on never comparing against boolean constants, then you only need to use 0/1 to initialize the flags anyway. However, such an approach may be deemed too reactionary in these modern times. In that case, one should definitely use since it at least has the benefit of being standardized.
Whatever the boolean constants are called, use them only for initialization. Never ever write something like
if (ready == TRUE) ...
while (empty == FALSE) ...
These can always be replaced by the clearer
if (ready) ...
while (!empty) ...
Note that these can actually reasonably and understandably be read out loud.
Give your boolean variables positive names, ie full instead of notfull. The latter leads to code that is difficult to read easily. Compare
if (full) ...
if (!full) ...
with
if (!notfull) ...
if (notfull) ...
Both of the former pair read naturally, while !notfull is awkward to read even as it is, and becomes much worse in more complex boolean expressions.
Boolean arguments should generally be avoided. Consider a function defined like this
void foo(bool option) { ... }
Within in the body of the function, it is very clear what the argument means since it has a convenient, and hopefully meaningful, name. But, the call sites look like
foo(TRUE);
foo(FALSE):
Here, it's essentially impossible to tell what the parameter mean without always looking at the function definition or declaration, and it gets much worse as soon if you add even more boolean parameters.. I suggest either
typedef enum { OPT_ON, OPT_OFF } foo_option;
void foo(foo_option option);
or
#define OPT_ON true
#define OPT_OFF false
void foo(bool option) { ... }
In either case, the call site now looks like
foo(OPT_ON);
foo(OPT_OFF);
which the reader has at least a chance of understanding without dredging up the definition of foo.
I have this which solves a problem iteratively using a for loop. I want to convert the code to use a recursive algorithm using if-else statement that uses recursion. I've tried several times but I can't get it to work properly.
double A;
int B;
double previous=1;
double answer;
double equation(double A,int B){
for(int i=1; i<=B; i++){
answer= (A*previous)/(i+A*previous);
previous = answer;
};
return answer;
}
EDIT: Here's what I've done so far: http://pastebin.com/raw.php?i=kyeq1v5u
Have a formula. It is a recursive formula. It defines your problem, recursively
equation(A, B) =
IF(B = 1)
A/(1+A)
ELSE
(A*equation(B-1)) / (B+A*equation(B-1))
Edited: There is your complete algorithm in psudo-code. all you have to do is translate to c. Good Luck.
hint: previous is equal to equation(A, B-1)
When thinking about recursive approach, first come up with the condition that ends the recursion bearing in mind that typically recursion progresses in the opposite direction than iterative approach in this kind of functions.
In your case function signature would probably be the same, and each recursive call would have B one smaller than on previous round. Ending condition would be something that you can easily calculate, for example B=1.
Also, you don't need any global variables that you have declared in your code. Use local variables instead so they all can have different values in each recursive function call. It is also bad habit to use global variables when you can avoid them.
pseudo code (There might be some small mistake but it should get you thinking in the right direction
Equation A , B = Equation_internal( A, B , 1, 1)
Equation_internal (A , B , i , prev ) =
case i <= B : return Equation_internal ( A , B , i+1 , (A* prev )/(i+A*prev) )
otherwise return prev.
here my little code
double equation(double A,int B);
double equation2(double A,int B, int curcount, double previous);
double A;
int B;
double previous=1;
double answer;
int main (int argc, const char * argv[])
{
double toto= equation(5,3);
double toto2= equation2(5,3,0,1);
return 0;
}
double equation(double A,int B){
for(int i=1; i<=B; i++){
previous= (A*previous)/(i+A*previous);
};
return previous;
}
double equation2(double A,int B, int curcount, double previous){
if (curcount == B) {
return previous;
}else{
curcount++;
previous= (A*previous)/(curcount+A*previous);
return equation2(A,B,curcount,previous);
}
}