Why do these two expressions produce the same value? - java

I try to split a string to an array of equal-length substrings and the first thing I do is to calculate how many substrings there would be. While I wrote it myself I used the first expression down below. When I checked an answer given by someone else I saw the second one, which is not very obvious to me. Actually I couldn't figure out why they produce the same result though I could verify with concrete examples. So how do you prove they are equivalent in terms of generating the same result?
int groups = s.length() % subLen == 0 ? s.length() / subLen : s.length() / subLen + 1;
int groups = (s.length() + subLen - 1) / subLen;

Try to substitute s.length() with different values and see how the two calculations arrive at their respective result.
In essence, your version considers two cases that are handled differently and is doing the 'rounding up' explicitly in its second code branch.
The second version adds sublen-1 to the original string length so that the rounding down / truncation of the integer division arrives at the desired result for all given values of s.length().

First let's think about the actual context of the problem, that is , dividing a string, suppose its length is a, into a group of substrings whose lengths are equal, suppose that length is b, and then we know the range of a and b should be a >= b >= 1. If c is the result of the integer division a / b, which always rounds down, and if d is the result of the normal division a / b, and if d is an integer, a + (b - 1) would have no effect on making c bigger because only a + b can increase c by 1. But why does it have to be b - 1 instead of b - 2 or b - 3 etc? Because the minimum of b is 1 and if in b - ? the ? is bigger than 1 there's a chance that b - ? is negative, which means there's a chance that c would be reduced at least by 1 because a could be reduced at least by 1. If d is not an integer, then we know d == c * b + r where r is the remainder and (1) 1 <= r <= b - 1. So (a + b - 1) / b could be written as (c * b + r + b - 1) / b. According to (1) we have b <= r + b - 1 <= 2 * (b - 1), and then have b <= r + b - 1 < 2 * b, and then have (c + 1) * b <= a + b - 1 < (c + 2) * b, and then c + 1 <= (a + b - 1) / b < c + 2, which means c would be increased by 1 exactly when normal division a / b is not an integer.

Related

please translate this python code into java for this question and explain what its internal works [duplicate]

this is so far all i have done
i am trying to optimize the code for less time.but it is not working.
for _ in range(int(input())):
n, m = map(int, input().split())
count = 0
for i in range(1, n+1):
for j in range(1, n+1):
if i < j <= n and ((m%i)%j) == ((m%j)%i):
count += 1
print(count)
another approach I tried:
if i < j <= n and (m-(m%j))%i == 0:
both condition give correct result.but show time limit exceed
what should i do.thanks
Since a < b, we infer that (M mod a) mod b = M mod a, so the condition is equivalent to M mod a = (M mod b) mod a, i.e., M − (M mod b) is a multiple of a. We can iterate over all b and count factors of M − (M mod b) using a sieve, resulting in a Θ(N + M log N)-time algorithm.
N = 2304
M = 23498
def fast():
npairs = 0
nfactors = [1] * (M + 1)
for b in range(2, N + 1):
npairs += nfactors[M - M % b]
for i in range(0, M + 1, b):
nfactors[i] += 1
return npairs
def naive():
return sum((M % a) % b == (M % b) % a for b in range(2, N + 1) for a in range(1, b))
print(fast(), naive())
Think of it like x%mod(a) is same as x%mod(b) only condition a<b and if mod(b) is calculated, don't need to calculate mod(a) again if its already stored .
(n-1) is for all the pairs of 1's
for _ in range(int(input())):
n,m=map(int,input().split())
count=0
dictitems=defaultdict(int)
for i in range(2,n+1):
rem=m%i
count+=dictitems[rem]
for j in range(rem,n+1,i):
dictitems[j]+=1
print(count+(n-1))
Your approach is a good start but takes exactly N * N iterations.
You can start with following improvements.
sort the data
Using 2 pointer approach with optimised search range for second pointer
for i in range(1, n+1):
for j in range(i+1, n+1): # note j start at `i+1`

Recursion with if statements Java

Got two int a and b, need to find the sum of all the numbers between including them too.
Got Recursion Method:
with two if statements, if use only one if statement code work fine,
otherwise fall with StackOverflowError.
public static int getSum(int a, int b) {
int result = 0;
if (a <= 0 && b <= 0) result = getSum(a + 1, b + 1) + a + b;
if (a >= 0 && b >= 0) result = getSum(a - 1, b - 1) + a + b;
return result;
}
How can I fix it?
Lets assume a is 1, and b is 2.
if (a <= 0 && b <= 0) result = getSum(a + 1, b + 1) + a + b;
if (a >= 0 && b >= 0) result = getSum(a - 1, b - 1) + a + b;
The 2nd kicks in:
result = getSum(1 - 1, 2 - 1) + a + b;
So you call: with a = 0, b = 2. That one picks:
result = getSum(0 + 1, 1 + 1) + a + b;
So you are back to call with 1, 2.
And it starts from scratch. Leading into an endless recursion.
So, there are multiple problems with your current approach:
both if conditions might apply. As you use "<=" and ">=", when a or b are 0, both if conditions kick in
worse: as shown, your setup allows to easily go down-up-down-up-... forever
beyond that: a correct "stop recursion" is missing. For certain input, your code will simply always go and call itself, again.
guessing here: you are also missing corner cases, such as a < 0, but b > 0
So, long story short: your whole algorithm is bogus, and you need to step back and rethink what you are doing here!
This doesn't need recursion, but I assume you are trying to learn recursion.
Please see comments for explanation.
public static int getSum( int a, int b ) {
if ( a == b ) { // if both are equal there are no numbers in between - so sum is number itself.
return a;
}
// if a < b then increment a to reach b otherwise increment b to reach a.
// this works even if a or b or both are negative.
// So when you increment a, add 'a' only to current sum and then move forward
// When you increment b, add 'b' only to current sum and then move forward.
return a < b ? a + getSum( a + 1, b ) : b + getSum( a, b + 1 );
}
You don't need those if statements. Just do it as follows:
public static int getSum(int a, int b){
if (b < a) return 0;
if (b == a) return b;
return a + getSum(a + 1, b);
}

How does Modulus work with negative integers?

I am running a for loop and inside my loop I have the following:
for(int i = 0; i < 12; i = i + 2){
System.out.println("i = " + i);
System.out.print("3 - i % 3 (i is at " + i + ") = " + (3 - i % 3));
System.out.println();
System.out.println("3 - i (" + (i) + ") = " + (3 - i));
}
I do understand how Modulus works normally or with positive numbers, but I do not understand how it works with negative integers?
Can anyone explain it to me please?
Many thanks.
a mod b is very well defined for positive integers a and b. What if a or b are negative? There are three choices that are consistent with that base definition:
a mod b is always positive.
a mod b has the same sign as a.
a mod b has the same sign as b.
Different languages will choose one of these three choices. There is no singular correct answer.
4 % 3 == 1
-4 % 3 == -1
4 % -3 == 1
-4 % -3 == -1
Changing the sign of the first number changes the sign of the result. The sign of the second number doesn't matter.
This is true in many languages (C, C++, Java, Javascript) but not all languages (Python, Ruby).

Java: Prefix - Postfix issue

I have a small issue performing a subtraction on numbers using prefix and postfix operators.
This is my program:
public class postfixprefix
{
public static void main (String args[])
{
int a = 5;
int b;
b = (a++) - (++a);
System.out.println("B = " +b);
}
}
Doing this, theoretically I am supposed to get 0 as the answer, but however, I am getting a -2.
When I try to individually try to increment the values like in this program:
public class postfixprefix
{
public static void main (String args[])
{
int a = 5;
int b, c;
b = a++;
c = ++a;
System.out.println("B = " +b);
System.out.println("C = " +c);
}
}
I get the values as B = 5, C = 7.
So i get the idea that 'c' takes the value of 'a' from 'b' (Please correct me if i am wrong), but what I want to know is
How can I have it not take the value of 'a' from 'b', and
using prefix - postfix, can I have 0 as an answer when they're subtracted.
If you go through this step by step, you can see what happens:
b = (a++) - (++a); //a is now 5
b = 5 - (++a); //read a, then increment it. a is now 6
b = 5 - 7; //increment a, then read it. a is now 7
b = -2
If you do it the other way, you get:
b = (++a) - (a++); //a is now 5
b = 6 - (a++); //increment a, then read it. a is now 6
b = 6 - 6; //read a, then increment it. a is now 7
b = 0
b = a++;
means:
assign to b the value of a
increase a by 1
c = ++a
means:
increase a by 1
assign to c the value of a
b = (a++) - (++a)
means:
get the value of a (5) (a without the ++)
increase the value of a by 1 (thus making it 6) (the result of a++)
increase a by 1 (++a) (thus making it 7)
assign to b thae value 5-7=-2 (5 from step 1, 7 from step 3)
So i get the idea that 'c' takes the value of 'a' from 'b' (Please correct me if i am wrong), but what I want to know is 1) How can I have it not take the value of 'a' from 'b'
Its not like this, in c = ++a; value is taken from a only, in b = a++; statement, a was incremented but after assigning value to b, and then while c = ++a; a is again incremented and assigned to c (as this is pre-increment now)
2) using prefix - postfix, can I have 0 as an answer when they're subtracted.
you can have like: b = (++a) - (a++); as first a increments first and then the second a (which is now 6) is substracted from first a (still 6). And then the final value of a is 7
int a = 5;
int b, c;
b = a++;
c = ++a;
About this code b has a value 5 because posting fix increment/decrement happens after assingment is completed. So the value is 5.
c has a value 7 because prefix increment/decrement happens before assingment is completed. So the value is 7 beause previous statement made the value of a as 6.
About this code
int a = 5;
int b;
b = (a++) - (++a);
System.out.println("B = " +b);
when brackets are applied, your prefix/postfix operations will be completed first in (a++) - (++a); from left to right fashion.
So firstly if we go left to right
(a++) -(++a)
1. (a++) -- Take 5 from a.
2. (++a) -- 5 becomes 6 with ++a take 6.
3. (a++) - (++a) -- Subtract results of (a++) - (++a) operations which makes it -2.
Solutions for you first query -- How can I have it not take the value of 'a' from 'b', and
int a = 5;
int temp = a;
int b, c;
b = a++;
c = ++temp;
System.out.println("B = " +b);
System.out.println("C = " +c);
**Solutions for you first query has been well explained by Sir #Keppil **

Java: How do I perform integer division that rounds towards -Infinity rather than 0?

(note: not the same as this other question since the OP never explicitly specified rounding towards 0 or -Infinity)
JLS 15.17.2 says that integer division rounds towards zero. If I want floor()-like behavior for positive divisors (I don't care about the behavior for negative divisors), what's the simplest way to achieve this that is numerically correct for all inputs?
int ifloor(int n, int d)
{
/* returns q such that n = d*q + r where 0 <= r < d
* for all integer n, d where d > 0
*
* d = 0 should have the same behavior as `n/d`
*
* nice-to-have behaviors for d < 0:
* option (a). same as above:
* returns q such that n = d*q + r where 0 <= r < -d
* option (b). rounds towards +infinity:
* returns q such that n = d*q + r where d < r <= 0
*/
}
long lfloor(long n, long d)
{
/* same behavior as ifloor, except for long integers */
}
(update: I want to have a solution both for int and long arithmetic.)
If you can use third-party libraries, Guava has this: IntMath.divide(int, int, RoundingMode.FLOOR) and LongMath.divide(int, int, RoundingMode.FLOOR). (Disclosure: I contribute to Guava.)
If you don't want to use a third-party library for this, you can still look at the implementation.
(I'm doing everything for longs since the answer for ints is the same, just substitute int for every long and Integer for every Long.)
You could just Math.floor a double division result, otherwise...
Original answer:
return n/d - ( ( n % d != 0 ) && ( (n<0) ^ (d<0) ) ? 1 : 0 );
Optimized answer:
public static long lfloordiv( long n, long d ) {
long q = n/d;
if( q*d == n ) return q;
return q - ((n^d) >>> (Long.SIZE-1));
}
(For completeness, using a BigDecimal with a ROUND_FLOOR rounding mode is also an option.)
New edit: Now I'm just trying to see how far it can be optimized for fun. Using Mark's answer the best I have so far is:
public static long lfloordiv2( long n, long d ){
if( d >= 0 ){
n = -n;
d = -d;
}
long tweak = (n >>> (Long.SIZE-1) ) - 1;
return (n + tweak) / d + tweak;
}
(Uses cheaper operations than the above, but slightly longer bytecode (29 vs. 26)).
There's a rather neat formula for this that works when n < 0 and d > 0: take the bitwise complement of n, do the division, and then take the bitwise complement of the result.
int ifloordiv(int n, int d)
{
if (n >= 0)
return n / d;
else
return ~(~n / d);
}
For the remainder, a similar construction works (compatible with ifloordiv in the sense that the usual invariant ifloordiv(n, d) * d + ifloormod(n, d) == n is satisfied) giving a result that's always in the range [0, d).
int ifloormod(int n, int d)
{
if (n >= 0)
return n % d;
else
return d + ~(~n % d);
}
For negative divisors, the formulas aren't quite so neat. Here are expanded versions of ifloordiv and ifloormod that follow your 'nice-to-have' behavior option (b) for negative divisors.
int ifloordiv(int n, int d)
{
if (d >= 0)
return n >= 0 ? n / d : ~(~n / d);
else
return n <= 0 ? n / d : (n - 1) / d - 1;
}
int ifloormod(int n, int d)
{
if (d >= 0)
return n >= 0 ? n % d : d + ~(~n % d);
else
return n <= 0 ? n % d : d + 1 + (n - 1) % d;
}
For d < 0, there's an unavoidable problem case when d == -1 and n is Integer.MIN_VALUE, since then the mathematical result overflows the type. In that case, the formula above returns the wrapped result, just as the usual Java division does. As far as I'm aware, this is the only corner case where we silently get 'wrong' results.
return BigDecimal.valueOf(n).divide(BigDecimal.valueOf(d), RoundingMode.FLOOR).longValue();

Categories

Resources