This is a pretty simple for loop I have come across in a Java tutorial by Schildt. I have been studying it for some time now and am still unsure of how it returns the value 15. In particular I can't figure out the role played by the "sum" variable in the iteration protion of the statement. A good explanation of this would greatly help me in moving forward in my study of java. The author of the book simply throws this out there as an example of how to use a loop without a body with no explanation of the "sum" value and how it is iterated.
Here is the statement:
for(i = 1; i <= 5; sum += i++)
System.out.println("Sum is " + sum);
How do we explain the variable sum as having the final value of 15 in this statement?
Here's what will happen inside the loop.
i=1; sum = 1;
i=2; sum = 1+2 = 3;
i=3; sum = 3+3 = 6;
i=4; sum = 6+4 = 10;
i=5; sum = 10+5 = 15;
i increases 5 times due to the i++ statement, and is added to sum in each loop iteration, so
1 + 2 + 3 + 4 + 5 = 15
This instruction does two things : sum += i++
first:
sum = sum + i;
and later:
i = i + 1;
//Initial values
sum = 0;
i = 1;
//When the loop finish its last instruction in this case the print
sum = sum + 1
sum = 1;
i = i + 1;
i = 2;
============
sum = sum + 2
sum = 3;
i = i + 1;
i = 3;
============
sum = sum + 3
sum = 6;
i = i + 1;
i = 4;
============
sum = sum + 4
sum = 10;
i = i + 1;
i = 5;
============
sum = sum + 5
sum = 15;
i = i + 1;
i = 6;
Related
I have :
#include <stdio.h>
int main(void) {
int s,i,t[] = { 0, 1, 2, 3, 4, 5 };
s = 1;
for(i = 2; i < 6 ; i += i + 1)
s += t[i];
printf("%d",s);
return 0;
}
Why is the result 8?
What I'm thinking:
first loop: 2<6 True
i+=i+1 is 5
s=1+t[5] =>1+5=6
second loop : 5<6 True
i=5+5+2=11
s=6+t[11]???
The loop increment expression (i += i + 1 in your case) happens after the loop body, not before.
So in the first iteration you do
s = 1 + t[2];
More generally, any for loop could be expressed as a while loop:
for (a; b; c)
{
d;
}
is equivalent to
{
a;
while (b)
{
{
d;
}
c;
}
}
For your specific case it's:
{
i = 2;
while (i < 6)
{
{
s += t[i];
}
i += i + 1;
}
}
I will guide you to the for loop reference:
iteration-expression is evaluated after the loop body and its result
is discarded. After evaluating iteration-expression, control is
transferred to cond-expression.
In your example, i += i + 1, which is the iteration expression we're talking about, is evaluated after the loop body.
Taking this into account, the result will be 8
Look attentively at the third expression in the for loop
s = 1;
for(i = 2; i < 6 ; i += i + 1)
s += t[i];
It is i += i + 1. So in iterations of the loop the variable i will be changed the following way
i = 2 (initially)
i = 5 ( i += i + 1 => i += 2 + 1 => i += 3 => i = 2 + 3)
After the second iteration of the loop the variable i will be already greater than 6. (i += i + 1 => i += 5 + 1 => i += 6 => i = 5 + 6)
So this statement
s += t[i];
in fact produces the following sum
1 + t[2] + t[5] = 1 + 2 + 5
that is equal to 8.
I tried to solve it on my own way, but instead of giving me consecutive odd numbers, it gave me the result of a cubic number. How can I make so it'll give me, after the compilation, consecutive odd numbers whose sum equals to n^3(cubic number) like the examples shown above? Thanks in advance and also do not forget to explain me how you did it. Please use C, when giving a much more viable solution.
#include <stdio.h>
#include <math.h>
int main()
{
int n, sum;
printf("Value of n= ");
scanf("%d",&n);
for(int n=1; n<=20; n++)
{
if(n%2!=0);
}
printf("%d", sum=pow(n,3));
return 0;
}
Instead of thinking it like that, I tried a few numbers and found the solution in math. I guess this is not what you wanted, but it does work and consists of only odd numbers.
1^3=1
2^3=3+5
3^3=7+9+11
4^3=13+15+17+19
5^3=21+23+25+27+29
...
x^3=[x*(x-1)+1]+[x*(x-1)+3]+...+[x*(x-1)+2x-1]
for math proof, define it as a series:
An=x^2-x+1+2(n-1)=x^2-x+1+2n-2=x^2-x+2n-1
Sx=(A1+Ax)*x/2=[(x^2-x+1)+(x^2-x+2x-1)]*x/2=(2x^2)*x/2=x^3
Also, because n(n-1) is always even, the numbers must be odd.
to write it as code:
void printOddNumbers(int n)
{
int a1 = n * (n - 1) + 1;
for(int i = 0; i < n; i++)
{
printf("%d+", a1 + 2 * i);
}
printf("\b=%d^3=%d\n", n, n * n * n);
}
So the output will look like: 13+15+17+19=4^3=64.
So, you have an input, n, which is the number of consecutive odd numbers, which should yield a given sum as a result. So, this is how it looks alike:
sum = k + (k + 2) + ... + (k + 2n - 2) =
= n * k + 2 * (1 + 2 + ... + n - 1) =
= n * k + 2 (n * (n - 1) / 2) =
= n * k + n * (n - 1) =
= n * (n + k - 1)
n is known, k is an unkown odd number. So, for sum = 27 and n = 3 this would mean
3 * (3 + k - 1) = 27
3 + k - 1 = 9
k + 2 = 9
k = 7
7 + 9 + 11 = 27
For sum = 125, k = 5:
5 * (5 + k - 1) = 125
5 + k - 1 = 25
k = 21
21 + 23 + 25 + 27 + 29 = 125
So, the implementation would look like this:
int getK(int n, int sum) {
int k = (sum / n) - n + 1;
int currentSum = k;
int result = k;
for (int i = 1; i < n; i++) currentSum += 2 * i + k;
return ((currentSum == sum) && (k % 2)) ? k : 0;
}
Explanation: We return the smallest of the set when the problem is solvable. If it is not an odd, then we return 0 as a sign of error. Also, if the sum does not add up, then the problem is unsolvable and we return 0.
This is a very strange problem. I cannot see any differences between code1 and code2 . However, there should be a difference because they produce different results : (notice f0 and f0A (acts as a buffer))
code1 :
for (k = 0; k < 6; k++) {
r1 = i0 + 6 * k;
f0 = 0.0F;
for (r2 = 0; r2 < 6; r2++) {
f0 += (float)b_a[i0 + 6 * r2] * p_est[r2 + 6 * k];
}
a[r1] = f0;
}
code2:
float f0A[6] = {0};
for (k = 0; k < 6; k++) {
r1 = i0 + 6 * k;
for (r2 = 0; r2 < 6; r2++) {
f0A[r2] += (float)b_a[i0 + 6 * r2] * p_est[r2 + 6 * k];
}
}
for (r2 = 0; r2 < 6; r2++) {
r1 = i0 + 6 * r2;
a[r1] = f0A[r2];
}
In the first loop, you are setting a[r1] to a summation stored in f0. It is being added to each loop.
In the second loop, you aren't doing a summation, your loop is using += but it is storing each one in a different f0A index. Thus a[r1] is not given the correct value
There is the difference
We have an array of "n" numbers. We need to divide it in M subarray such that the cost is minimum.
Cost = (XOR of subarray) X ( length of subarray )
Eg:
array = [11,11,11,24,26,100]
M = 3
OUTPUT => 119
Explanation:
Dividing into subarrays as = > [11] , [11,11,24,26] , [100]
As 11*1 + (11^11^24^26)*4 + 100*1 => 119 is minimum value.
Eg2: array = [12,12]
M = 1
output: 0
As [12,12] one way and (12^12)*2 = 0.
You can solve this problem by using dynamic programming.
Let's define dp[i][j]: the minimum cost for solving this problem when you only have the first i elements of the array and you want to split (partition) them into j subarrays.
dp[i][j] = cost of the last subarray plus cost of the partitioning of the other part of the given array into j-1 subarrays
This is my solution which runs in O(m * n^2):
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 + 10;
const int MAXM = 1000 + 10;
const long long INF = 1e18 + 10;
int n, m, a[MAXN];
long long dp[MAXN][MAXM];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
// start of initialization
for (int i = 0; i <= n; i++)
for (int j = 0; j <= n; j++)
dp[i][j] = INF;
dp[0][0] = 0;
// end of initialization
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int last_subarray_xor = 0, last_subarray_length = 0;
for (int k = i; k >= 1; k--) {
last_subarray_xor ^= a[k];
last_subarray_length = i - k + 1;
dp[i][j] = min(dp[i][j], dp[k - 1][j - 1] + (long long)last_subarray_xor * (long long)last_subarray_length);
}
}
}
cout << dp[n][m] << endl;
return 0;
}
Sample input:
6 3
11 11 11 24 26 100
Sample output:
119
One of the most simple classic dynamic programming problems is called "0-1 Knapsack" that's available on Wikipedia.
Suppose I have following code segment in C.
i = j = k = 1;
j = (i++) + (++k);
result = i + j + k; //POI
//Expected result = 7
Here, I want to find value of result through backward analysis. When I perform backward analysis, I will go through following expressions in order.
j = (i++) + (++k);
++k;
i++;
i = j = k = 1;
j = k = 1;
k = 1;
During backward analysis I will replace each variable by corresponding expression, whenever it is applicable. But I'm confused how to deal with increment/decrement operations.
My current strategy will produce following result
result = i + j + k
//after j = i++ + ++k
result = (i+(i+(k+1)))+k
//after ++k
result = (i+(i+((k+1)+1)))+(k+1)
//after i++
result = ((i+1)+((i+1)+((k+1)+1)))+(k+1)
//after i = j = k = 1
result = ((1+1)+((1+1)+((k+1)+1)))+(k+1)
//after k = 1
result = (((1+1)+((1+1)+((1+1)+1)))+(1+1))
//Simplifying
result = 9
which is ofcourse not true.
Can anyone help me with this?
I think it should be more like this
result = i + j + k
//after j = X + Y // You didn't analyse ++k and i++ yet
result = i+(X+Y)+k
//after Y = ++k
result = (i+(X+(k+1))+(k+1)
//after X = i++
result = ((i+1)+(i+(k+1))+(k+1)
//after i = j = k = 1
result = ((1+1)+(1+(k+1))+(k+1)
//after k = 1
result = ((1+1)+(1+(1+1))+(1+1)
//Simplifying
result = 7
The thing to notice here is i++ increases after evaluating, not before.
i=j=k=1
++k //happens before expression
//k=2,i=j=1
j = k + i
//k=2,i=1,j=3
i++ //happens after expression
//k=2,i=2,j=3
result = i+ j + k
//result = 7
Your mistake was increasing i before ealuation of j, and then getting j=4, instead of j=3
If you want to analyze it backward, something along the lines of
result = i + j + k
i = i+1 = 1 + 1
//result = (1+1) + j + k
j = i + k
k = k+1 = 1+1
//j = 1 + (1+1)
//result = (1+1) + (1+(1+1)) + (1+1)
I suggest that you first decompose the statements into elementary ones as a compiler would do. For instance, using Frama-C to decompose the statements would give something like:
k = 1;
j = k;
i = j;
tmp = i;
i ++;
k ++;
j = tmp + k;
result = (i + j) + k;
It is then a lot easier to do the analysis.
Consider the sequence stating from the bottom :
// 1 + 1 + 1 + 1 + 1 + 1 + 1
k = 1;
// k + 1 + k + k + 1 + k + 1
j = k;
// j + 1 + j + k + 1 + k + 1
i = j;
// i + 1 + i + k + 1 + k + 1
tmp = i;
// i + 1 + tmp + k + 1 + k + 1
i ++;
// i + tmp + k + 1 + k + 1
k ++;
// i + tmp + k + k
j = tmp + k;
// i + j + k
result = (i + j) + k;
// result ?
Which gives you 7 as expected.