What is the difference? And does this matter in bigger loops? - java

I was wondering if there is a complexity and time difference when doing these two operations:
1)
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum = sum + i;
}
2)
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
or maybe image the problem to be bigger numbers/data, this is just an example.

These variants are the same from performance point of view (both will be as iadd instruction in java bytecode)
But sum += 1 replaced with sum = (int) (sum + 1)
And it has differrens for types like byte or short for compilation
E.g. this code will be compiled
byte i = 0;
for(int j = 0; j < 10; j++) {
i += j; //i = (byte) (i + j)
}
but you will get compilation error for code
byte i = 0;
for(int j = 0; j < 10; j++) {
i = i + j;
}

There is a difference in priority, compound assignment sum += i is less primary than assignment and addition sum = i + 1.
Incrementation i++ is even more primary.
for more information : operator precedence

Related

Why don't we redistribute inversely in this implementation of Radix sort of strings

I found this implementation of radix sort LSD for strings :
public static void sort(String[] input, int w) {
String[] aux = new String[input.length];
//ascii chars
int R = 256;
int n = input.length;
for(int d = w-1; d >= 0; d--) {
int[] count = new int[R+1];
//update the frequency at i+1 index
for(int i=0; i<n; i++) {
count[input[i].charAt(d) + 1] ++;
}
//transform the frequency into indices
for(int r=0; r< R; r++) {
count[r+1] += count[r];
}
//redistribute
for(int i=0; i<n; i++) {
aux[count[input[i].charAt(d)]++] = input[i];
}
for(int i=0; i<n; i++) {
input[i] = aux[i];
}
}
}
But I don't understand two things :
why here we have count[input[i].charAt(d) + 1] ++; rather than count[input[i].charAt(d)] ++; ?
why we don't redistribute the characters inversely ? I think it's way simpler (my implementation) :
public static void sort(String[] arr, int lenStr) {
int R = 256;
int len = arr.length;
String[] arrSorted = new String[len];
for (int d = lenStr - 1; d >= 0; d--) {
// frequency count of each character
int[] count = new int[R + 1];
for (int i = 0; i < len; i++) {
count[arr[i].charAt(d)]++;
}
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
for (int i = len - 1; i >= 0; i--) {
count[arr[i].charAt(d)]--;
arrSorted[count[arr[i].charAt(d)]] = arr[i];
}
for (int i = 0; i < len; i++) {
arr[i] = arrSorted[i];
}
}
}
I think most of it comes down to personal preference.
why here we have count[input[i].charAt(d) + 1] ++; rather than count[input[i].charAt(d)] ++; ?
Their count[x+1] means, after the second inner loop, how many times character x and any character prior to it appear. For example, we might have the initial counts:
count[0] = 0
count[1] = 2
count[2] = 3
Then after the second for loop we will have:
count[0] = 0
count[1] = 2
count[2] = 5
This means that character 0 takes the positions between count[0] and count[1], character 1 takes the positions between count[1] and count[2] and in general, character x takes the positions between count[x] and count[x+1] This allows them to do this:
for(int i=0; i<n; i++) {
aux[count[input[i].charAt(d)]++] = input[i];
}
Which is a nice one liner that ties everything together neatly IMO, because count[x] changes to mean at what position should we next place character x in our sorted array.
Your implementation works just as well and can also be turned into a one liner:
for (int i = len - 1; i >= 0; i--) {
arrSorted[--count[arr[i].charAt(d)]] = arr[i];
}
If you think it's simpler then you can use it, I don't see any downsides (assuming you've tested it well enough). It's a pretty complex algorithm and once you understand one way of doing it, you tend to stick with it. This is just the implementation that stuck I guess. Simplicity is highly subjective here, personally I think your version is just as complex.

Sum of n terms.. 122333=14

im need to calculate the sum of n terms i wrote this code but it print me all the nums but no the sum
for (i = 1; i <= n; i++){
for ( j = 0; j < i; j++){
System.out.print(i);
}
}
And this is what it print
122333444455555
Thanks for your help
If by 'sum of N terms' you mean,
N=4
Sum= 1+2+2+ 3+3+3+4+4+4+4....N*N
Then it's safe to say that it's Sum(i*i) where 0<i<=N,
this solution will give you answer:
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += i * i;
}
System.out.println(sum);
One good approach here is make use of the modulus:
int input = 122333;
int sum = 0;
while (input > 0) {
sum += input % 10;
input /= 10;
}
System.out.println("Sum of all terms is: " + sum); // 14
The input % 10 term will return the final rightmost digit in the input. We added this to the running total, and then divide the input by 10 to advance the next digit.
I finally did it
for (i = 1; i <= n; i++){
for ( j = 0; j < i; j++){
res=res+i;
System.out.print(i);
}
}
System.out.println(" La sumatoria es "+res);

finding the correct time complexity of these codes

I was trying to find time complexity of these 2 codes but i am not sure about my answers .
code1
int i = 1;
int count = 0;
while (i < n) {
for (int j = 0; j < i; j++) {
count++;
}
i *= 2;
}
I calculated the number of steps in loops and I reached to (log n)^2 but i am not sure about it .
Code2
int k=0;
for (int i = 2; i <= n; i++) {
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
k++;
break;
}
}
}
and for this one I got ( n * log n)
actually I am new to calculating time complexity and I am not sure about them , could you help me find the correct answer .

Minimum Adjustment Cost

I am trying to solve this question:
Given an integer array, adjust each integers so that the difference of
every adjacent integers are not greater than a given number target.
If the array before adjustment is A, the array after adjustment is B,
you should minimize the sum of `| A[i]-B[i] |. You can assume each number in the array is a positive integer and not greater than 100.
`
I see a dp solution but I don't quite understand the recurrence equation.
public static int MinAdjustmentCost(ArrayList<Integer> A, int target) {
// write your code here
if (A == null || A.size() == 0) {
return 0;
}
// D[i][v]: 把index = i的值修改为v,所需要的最小花费
int[][] D = new int[A.size()][101];
int size = A.size();
for (int i = 0; i < size; i++) {
for (int j = 1; j <= 100; j++) {
D[i][j] = Integer.MAX_VALUE;
if (i == 0) {
// The first element.
D[i][j] = Math.abs(j - A.get(i));
} else {
for (int k = 1; k <= 100; k++) {
// 不符合条件
if (Math.abs(j - k) > target) {
continue;
}
int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
D[i][j] = Math.min(D[i][j], dif);
}
}
}
}
int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}
return ret;
}
Could someone explain it to me?
You need to minimize the cost of the adjustment, which is the value you increase/decrease every element such that the difference between every adjacent elements is less than or equal to target. The dp solution is to try every possible value and minimize the cost on the valid ones (when abs(A[i]-A[i-1]) <= target)
First thing is to fill the cost for adjusting first element to 1-100 which is done here:
for (int i = 0; i < size; i++) {
for (int j = 1; j <= 100; j++) {
D[i][j] = Integer.MAX_VALUE; // fill with MAX_VALUE because we want to minimize
if (i == 0) {
// for the first element we just set the cost of adjusting A[i] to j
D[i][j] = Math.abs(j - A.get(i));
}
Now you have D[0][j] as the cost to adjust the first element to be j. Then for every other element, you loop again (from k = 1 to k = 100) for other elements and try to change A[i] to j. And then you check if abs(k-j) is valid (less than or equal to target) then you can adjust A[i] to be j and A[i-1] to be k so you minimize on D[i][j].
Here D[i][j] means the cost of changing A[i] to j and D[i-1][k] is the cost of changing A[i-1] to k. so for every k and j if they are valid (abs(k-j)<=target) then you add them together and minimize the value saved in D[i][j] so you can use it for next element, which is done here:
else {
for (int k = 1; k <= 100; k++) {
// if abs(j-k) > target then changing A[i] to j isn't valid (when A[i-1] is k)
if (Math.abs(j - k) > target) {
continue;
}
// otherwise, calculate the the cost of changing A[i] to j and add to it the cost of changing A[i-1] to k
int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
// minimize D[i][j]
D[i][j] = Math.min(D[i][j], dif);
}
}
At the end, you need to loop from 1 to 100 at the last element and check which is the minimum value over all, which is done here:
int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}
I think if you split the initialization code and the DP calculation code it would be easier to understand, for example:
// fill the initial values
for (int i = 0; i < size; ++i) {
for (int j = 1; j <= 100; ++j) {
// on the first element just save the cost of changing
// A[i] to j
if (i == 0) {
DP[i][j] = abs(j-A.get(i));
} else {
// otherwise intialize with MAX_VALUE
D[i][j] = Integer.MAX_VALUE;
}
}
}
for (int i = 1; i < size; i++) {
for (int j = 1; j <= 100; j++) {
for (int k = 1; k <= 100; k++) {
// if abs(j-k) isn't valid skip it
if (Math.abs(j - k) > target) {
continue;
}
// if it is valid, calculate the cost of changing A[i] to j
// and add it to the cost of changing A[i-1] to k then minimize
// over all values of j and k
int dif = Math.abs(j - A.get(i)) + D[i - 1][k];
D[i][j] = Math.min(D[i][j], dif);
}
}
}
// calculate the minimum cost at the end
int ret = Integer.MAX_VALUE;
for (int i = 1; i <= 100; i++) {
ret = Math.min(ret, D[size - 1][i]);
}

Using nested For Loops to create a table of numbers and stars

I need to print a table that looks like this if the user entered a 5 using nested for loops:
****5
***45
**345
*2345
12345
I've been working on this for hours and the closest I got was:
int size = scan.nextInt();
for (int i = 1; i <= size; i++)
{
for (int star = size-1; star >= i; star--)
System.out.print("*");
for (int k = 1; k <= i; k++)
System.out.print(i);
System.out.println();
}
Which outputs this:
****1
***12
**123
*1234
12345
You have too many loops; I find it easier to reason about zero based looping so I'm going to use that. Iterate i and j from 0 to size. If j + 1 is greater than size - i - 1 then we want to print j + 1. Otherwise, we want a star. Like,
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (j + 1 > size - i - 1) {
System.out.print(j + 1);
} else {
System.out.print('*');
}
}
System.out.println();
}
For size = 5 that outputs (as requested)
****5
***45
**345
*2345
12345
If you simply must have one based indices, that would be
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= size; j++) {
if (j > size - i) {
System.out.print(j);
} else {
System.out.print('*');
}
}
System.out.println();
}
If you want to keep your loops and avoid if statements, you can tweak last loop by changing
for (int k = 1; k <= i; k++)
into
for (int k = 1+size-i; k <= size; k++)
Btw I also find it way easier to start loops from 0, so updated code would look like this:
int size = scan.nextInt();
for (int i = 0; i < size; i++)
{
for (int star = size-1; star > i; star--)
System.out.print("*");
for (int k = size-i; k <= size; k++)
System.out.print(k);
System.out.println();
}
I hope it helps

Categories

Resources