Objective C, difference between n++ and ++n - objective-c

In Objective-C, is there any difference between n++ and ++n (eg. used in a for loop)?

++n; increments the value of n before the expression is evaluated.
n++; increments the value of n after the expression is evaluated.
So compare the results of this
int n = 41;
int o = ++n; //n = 42, o = 42
with the results of this:
int n = 41;
int o = n++; //n = 42, o = 41
In the case of loops:
for (int i = 0; i < j; i++) {/*...*/}
however it doesn't make any difference, unless you had something like this:
for (int i = 0; i < j; x = i++) {/*...*/}
or this:
for (int i = 0; i < j; x = ++i) {/*...*/}
One could say:
It doesn't matter whether to use n++ or ++n as long as no second (related) variable is modified (based on n) within the same expression.
The same rules apply to --n; and n--;, obviously.

++n increments the value before it's used (pre-increment) and n++ increments after (post-increment).
In the context of a for loop, there is no observable difference, as the increment is applied after the code in the loop has been executed.

++n and n++ differ in what the expression evaluates to. An example:
int n = 0;
NSLog(#"%d", n); // 0
NSLog(#"%d", n++); // still 0, increments afterwards
NSLog(#"%d", n); // 1
NSLog(#"%d", ++n); // 2, because it increments first
NSLog(#"%d", n); // 2

In a loop it wont make a difference. Some people say ++n is faster though

In Scott Meyers "More Effective C++" Book he makes a very rational case for preferring prefix increment to postfix increment. In a nutshell, in that language due to operator overloading facilities prefix increment is almost always faster. Objective C doesn't support overloaded operators but if you have or ever will do any C++ or Objective-C++ programming then preferring prefix increment is a good habit to get into.
Remember that most of the time ++n looks like:
n = n + 1
[do something with n]
Whereas n++ looks like (if used as intended):
register A = n; // copy n
[do something with n]
n = A + 1;
As you can see the postfix case has more instructions. In simple for loops most compilers are smart enough to avoid the copy if it's obvious that the pre-increment n isn't going to be used but that case devolves to the prefix case.
I Hope this makes sense. In summary you should use prefix unless you really want the "side-effect" behavior of evaluate then increment that you get from the postfix version.

As stated above,
--n decrements the value of n before the expression is evaluated.
n--; decrements the value of n after the expression is evaluated.
The thing here to note is when using while loops
For example:
n = 5
while(n--) #Runs the loop 5 times
while(--n) #Runs the loop 4 times
As in n-- the loop runs extra time while n = 1
But in --n 1 is first decremented to 0, and then evaluated. This causes the while loop to break.

Related

Prove that the time complexity of a function is O(n^3)

public void function2(long input) {
long s = 0;
for (long i = 1; i < input * input; i++){
for(long j = 1; j < i * i; j++){
s++;
}
}
}
l'm pretty certain that the time complexity of this function is n^3, however if someone could provide a line by line explanation of this, that would be great.
First of all, you need to define what n is if you write something like O(n^3), otherwise it doesn't make any sense. Let's say n is the value (as opposed to e.g. the bit-length) of input, so n = input.
The outer loop has k iterations, where k = n^2. The inner loop has 1^2, 2^2, 3^2, ... up to k^2 iterations, so summing up everything you get O(k^3) iterations (since the sum of the p-th powers of the first m integers is always O(m^(p+1))).
Hence the overall time complexity is O(n^6).

does a for loop have to have a code of execution inside the loop to be considered o(n)?

function doNothing(n) {
for (let i = 0; i < n; i++);
}
Does a for loop that does nothing count as O(n)? Or would this be constant time?
The for loop doesn't "do nothing", it increments the variable i by one on each iteration five times. This is of course ignoring the fact a compiler may choose to remove this code completely.
So the for loop for (let i = 0; i < n; i++); is O(N). In your case however with for (let i = 0; i < 5; i++); since you do only five things, which is a constant amount of work, its O(1) (ie 5 ∈ O(1)) but remember this is because five is a constant not because the loop does nothing.
This is constant time. As i will always run from 0 to 5.
The time complexity of the above piece of code will be O(1).

Looping over an NSmutatable Array starting from a certain index

I have a quick question how can I loop over an NSMutable array starting from a certain index.
For Example I have these double loops I want k to start from the same index as l.
for (Line *l in L)
{
for (Line *k in L)
{
............
}
}
To elaborate further, lets say L has 10 object so l start from 0-10 and k from 0 -10. What I want is if l is equal 1 k should start from 1-10 rather than 0 - 10 and when l is equal 2 k should start from 2- 10 rather than 0. Any help is Appreciated
Objective-C is an extension of C, lookup the C for loop and you'll have your answer. HTH
Addendum
I was going to let you benefit from the learning experience of looking up the C for yourself, however at the time of writing all other answers since added give the code but it is not complete, so here is what you need to produce the l and k values in the order you wish:
for(NSInteger lIndex = 0; lIndex < L.count; lIndex++)
{
Line *l = L[lIndex]; // index into your array to get the element
for(NSInteger kIndex = lIndex; kIndex < L.count; kIndex++)
{
Line *k = L[kIndex];
// process your l and k
}
}
As you can see the for has three sub-parts which are the initialisation, condition, and increment. The initialisation is performed first, then the condition to determine whether to execute the for body, and the increment is executed after the statements in the body and before the condition is tested to determine if another iteration should be performed. A for loop is roughly (there are some differences that are unimportant here) to the while loop:
initialisation;
while(condition)
{
body statements;
increment;
}
You simply need to modify for-statement.
NSInteger indexYouNeed;
NSInteger iterationCount;
for (int i = indexYouNeed; i < iterationCount; i++) {
/* Your code here */
}
You may find this link helpfulll.
You have to use an indexed (ordinary) for loop instead of fast enumeration (for-in):
int l;
for (l=startValue; l<=endValue; l++)
{
int i;
for (int i=l; i<=endValue; i++)
{
…
}
}

Code for factorials in objective C

Using only for or while statements, I'm trying to come up with a program to generate and print a table of the first 10 factorials. Here's my code:
for (count = 1; count<=10; ++count)
{
n = count;
while (n > 0){
count *= (count-1);
n -= 1;
}
NSLog(#" %2g %3g", count, factorial);
}
I don't understand why this is not working. It never gets out of the loop and goes on forever. What's the correction? Thank you!
The reason:
count *= (count-1);
Since count starts at 1, it will always be reset to 0, so the count <= 10 condition of the outer loop will always be true, hence the infinite looping.
And you're overcomplicating it anyway.
for (int i = 1; i <= 10; i++) {
int r = 1, n = i;
while (n)
r *= n--;
printf("%d! = %d\n", i, r);
}
In Math, n! is the same thing as Γ(n+1) (see: http://en.wikipedia.org/wiki/Gamma_function)
So just use:
-(float)factorial:(float)number1 {
return tgammaf(++number1);
}
This will even work for floats and negative numbers,
other solutions posted are long and extraneous and only work with
positive integers.
During the first loop iteration count is 1 and so also n is 1, then you enter the while and you set count to zero (count-1), and decrease n which becomes zero and you exit the while. So during the second loop iteration count will be zero. You keep decreasing count and it never gets increased, so you never exit the loop until a numeric overflow occurs.
You're doing it harder that what it is (and also inefficient) . Is enough that you keep multiplying n for count to get the factorial:
int n=1;
for (count = 1; count<=10; ++count)
{
n*= count;
NSLog(#"%d",n);
}

Which are faster squares or roots?

for (int i = 2; i * i <= n; i++)
for (int i = 2; i <= SQRT(n); i++)
just wondering which is faster I looked at some primitive algorithms for getting roots and it would seem to me that squaring the number would be faster but I don't know for sure. These loops are for determining a numbers "primeness".
Shouldn't the comaprison be between
int sqrt = SQRT(n);
for (int i = 2; i <= sqrt; i++)
and
for (int i = 2; i * i <= n; i++)
The answer will depend on how many loop iterations you do. The sqrt method does less work per iteration, but it has a higher start-up cost. Mind you, this reeks of premature optimisation.
Compiler may 'cache' result of SQRT (n), but i * i it should compute on each step.
Square root will take longer, unless it's implemented in hardware, lookup, or a special machine code version. Newton iteration is the algorithm of choice; it converges quadratically.
Best to benchmark for yourself. I'd recommend moving the call to square root outside the loop so you only do it once rather than every time you check the exit condition.
Why not skip both of them and use some clever maths? The Following code avoid both of them using the Property that Sum of the First n odd numbers is always a perfect square.
A shameless plug for my old blogpost (from my dead blog)
int isPrime(int n)
{
int squares = 1;
int odd = 3;
if( ((n & 1) == 0) || (n < 9)) return (n == 2) || ((n > 1) && (n & 1));
else
{
for( ;squares <= n; odd += 2)
{
if( n % odd == 0)
return 0;
squares+=odd;
}
return 1;
}
}
The square will be faster.
But the square will overflow if n is larger than the square root of the largest int, and then the comparison will go wrong. The square root function could (and you would expect to) be implemented in such a way that is can be calculated on arguments all the way up to the largest representable int. That means it won't go wrong in that way.
In Java, the largest int is 2^31 - 1, which means its square root is just under 46341. If you want to look for primes larger than that, the squaring would stop you.