Swap two numbers in Java [duplicate] - java

how do I make my swap function in java if there is no method by which we can pass by reference? Could somebody give me a code?
swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
But the changes wont be reflected back since java passes parameters by value.

I think this is the closest you can get to a simple swap, but it does not have a straightforward usage pattern:
int swap(int a, int b) { // usage: y = swap(x, x=y);
return a;
}
y = swap(x, x=y);
It relies on the fact that x will pass into swap before y is assigned to x, then x is returned and assigned to y.
You can make it generic and swap any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
c = swap(a, a=b, b=c)

You can't create a method swap, so that after calling swap(x,y) the values of x and y will be swapped. You could create such a method for mutable classes by swapping their contents¹, but this would not change their object identity and you could not define a general method for this.
You can however write a method that swaps two items in an array or list if that's what you want.
¹ For example you could create a swap method that takes two lists and after executing the method, list x will have the previous contents of list y and list y will have the previous contents of list x.

It depends on what you want to do. This code swaps two elements of an array.
void swap(int i, int j, int[] arr) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Something like this swaps the content of two int[] of equal length.
void swap(int[] arr1, int[] arr2) {
int[] t = arr1.clone();
System.arraycopy(arr2, 0, arr1, 0, t.length);
System.arraycopy(t, 0, arr2, 0, t.length);
}
Something like this swaps the content of two BitSet (using the XOR swap algorithm):
void swap(BitSet s1, BitSet s2) {
s1.xor(s2);
s2.xor(s1);
s1.xor(s2);
}
Something like this swaps the x and y fields of some Point class:
void swapXY(Point p) {
int t = p.x;
p.x = p.y;
p.y = t;
}

Apparently I don't have enough reputation points to comment on Dansalmo's
answer, but it is a good one, though mis-named. His answer is actually a K-combinator.
int K( int a, int b ) {
return a;
}
The JLS is specific about argument evaluation when passing to methods/ctors/etc. (Was this not so in older specs?)
Granted, this is a functional idiom, but it is clear enough to those who recognize it. (If you don't understand code you find, don't mess with it!)
y = K(x, x=y); // swap x and y
The K-combinator is specifically designed for this kind of thing. AFAIK there's no reason it shouldn't pass a code review.
My $0.02.

AFAIS, no one mentions of atomic reference.
Integer
public void swap(AtomicInteger a, AtomicInteger b){
a.set(b.getAndSet(a.get()));
}
String
public void swap(AtomicReference<String> a, AtomicReference<String> b){
a.set(b.getAndSet(a.get()));
}
As per #Stephan's comment: as long as you are not in a multi-threaded app, the following will work as well.
First: wrap your simple types in an array of size 1.
int[] x1 = {x};
int[] y1 = {y};
Then write a swap method
public void swap(int[] a, int[] b) {
assert(a.length == 1);
assert(b.length == 1);
int temp = a[0];
a[0] = b[0];
b[0] = temp;
}
If you want to make this work for all simple types, you'll have to write overloads, because Java Generics don't work for simple types.

I might do something like the following. Of course, with the wealth of Collection classes, i can't imagine ever needing to use this in any practical code.
public class Shift {
public static <T> T[] left (final T... i) {
if (1 >= i.length) {
return i;
}
final T t = i[0];
int x = 0;
for (; x < i.length - 1; x++) {
i[x] = i[x + 1];
}
i[x] = t;
return i;
}
}
Called with two arguments, it's a swap.
It can be used as follows:
int x = 1;
int y = 2;
Integer[] yx = Shift.left(x,y);
Alternatively:
Integer[] yx = {x,y};
Shift.left(yx);
Then
x = yx[0];
y = yx[1];
Note: it auto-boxes primitives.

Try this magic
public static <T> void swap(T a, T b) {
try {
Field[] fields = a.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object temp = field.get(a);
field.set(a, field.get(b));
field.set(b, temp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
And test it!
System.out.println("a:" + a);
System.out.println("b:" + b);
swap(a,b);
System.out.println("a:" + a);
System.out.println("b:" + b);

For integer types, you can do
a ^= b;
b ^= a;
a ^= b;
using the bit-wise xor operator ^. As all the other suggestions, you probably shouldn't use it in production code.
For a reason I don't know, the single line version a ^= b ^= a ^= b doesn't work (maybe my Java compiler has a bug). The single line worked in C with all compilers I tried. However, two-line versions work:
a ^= b ^= a;
b ^= a;
as well as
b ^= a;
a ^= b ^= a;
A proof that it works: Let a₀ and b₀ be the initial values for a and b. After the first line, a is a₁ = a₀ xor b₀; after the second line, b is b₁ = b₀ xor a₁ = b₀ xor (a₀ xor b₀) = a₀. After the third line, a is a₂ = a₁ xor b₁ = a₁ xor (b₀ xor a₁) = b₀.

Related

Why does my code not work? It passed the base case but after that it got stuck. The Question is "Non Repeating Numbers" on GFG

The Approach I took was I first used bit manipulation to find that first element which was unique in the variable "c", then i used another array to copy the elements of the original array, but without the repeating element, and then used the bit manipulation method again to find the 2nd unique element in "C1".After that since I needed to return an array i added both values to the array "a" and returned it.
class Solution
{
public int[] singleNumber(int[] nums)
{
int a[]=new int[2];
int c=0,c1=0;
for(int i1:nums)
c=c^nums[i1];
a[0]=c;
int b[]=new int[nums.length-1];
for (int i = 0, k = 0; i < nums.length; i++) {
if (nums[i] == c) {
continue;
}
b[k++] = nums[i];
}
for(int i2:b)
c1=c1^b[i2];
a[1]=c1;
return a;
}
}
This is the link for the Question
There are two problems:
expected space complexity is O(1), your is O(N)
as mentioned by #Haoliang: the result of xoring all elements is a ^ b (the xor of the two missing elements) and not one of the answers (a or b), so your logic doesn't work
Here is how you can solve it:
xor all elements => a ^ b
find a bit that is 1 in a ^ b (there has to be a bit that is one if a != b which is the case)
xor all numbers that have that bit set and all number that have that bit not set, this will give you a and b
public int[] solve (int[] arr) {
int xor = 0, a = 0, b = 0;
for (int x : arr)
xor ^= x;
int mask = 1;
while ((mask & xor) == 0)
mask <<= 1;
for (int x : arr) {
if ((mask & x) == 0)
a ^= x;
else
b ^= x;
}
return a < b ? new int[] {a, b} : new int[] {b, a};
}

Collect averages Java Stream in one shot

I'm trying to find how to collect averages of each field in a list of objects in one liner.
Here is what I'm trying to perform:
public class Value {
int a;
int b;
int c;
// rest of the class
}
Now let's assume I have List<Value> values = getMillionValues();
I know that to get average for one field, I can do following:
int averageOfA = values.stream().mapToInt(Value::getA).average()
What do I need to do in order to get averages for all values w/o repeating line above for each variable?
Maybe there are some other libraries, like Guava, that can help to perform these kind of operations?
Seriously, use a for loop.
int count = 0, sumA = 0, sumB = 0, sumC = 0;
for (Value v : values) {
sumA += v.getA();
sumB += v.getB();
sumC += v.getC();
count++;
}
double avgA = ((double) sumA) / count;
double avgB = ((double) sumB) / count;
double avgC = ((double) sumC) / count;
Seriously, use the code above.
Having said that you should use the code above, you can do it with a stream.
You need a few value holders (the average is a double, so your Value class can't store the averages):
class AveragesResult {
public final double a, b, c;
public AveragesResult(double a, double b, double c) {
this.a = a;
this.b = b;
this.c = c;
}
}
class AveragesIntermediate {
public final double a, b;
public AverageIntermediate(double a, double b) {
this.a = a;
this.b = b;
}
}
Now that we have the boilerplate out of the way (for good measure, you should implement hashCode, equals and toString, and add some getters), we can finally write the stream in a short and compact way:
values.stream().collect(teeing(
teeing(averagingInt​(Value::getA), averagingInt​(Value::getB), AveragesIntermediate::new),
averagingInt(Value::getC),
(ir, avgC) -> new AveragesResult(ir.a, ir.b, avgC));
Wasn't that hard, right? Make sure you have statically imported all the Collector functions (it looks a lot uglier with all those Collectors.) and you are using Java 12 (Collectors.teeing is new in Java 12).
Don't use that, use a good old for loop.

If equivalent without using conditional operations and other loop methods java

int function(int a, int b, int c){
if(a==c)
return a;
else
return b;
}
Question is to achieve a same o/p without using if, while, do, for, switch,conditional expression(?:) and other general inbuilt methods like equals
Please tell me the logic and code..
Here's one fairly straightforward option:
int function(int a, int b, int c) {
java.util.HashMap<Boolean, Integer> map = new java.util.HashMap<Boolean, Integer>();
map.put(true, a);
map.put(false, b);
return map.get(a == c);
}
Using maps to emulate switch statements in languages that don't have them is pretty common. Using them to emulate if statements is probably an abuse.
Here's an approach using operators only:
int function(int a, int b, int c) {
//If a == c: result = 0x00000000
//Else: result = 0xFFFFFFFF
int result = (a - c | c - a) >> 31;
//If a == c: result = 0x00000000 & (a ^ b) = 0
//Else: result = 0xFFFFFFFF & (a ^ b) = a ^ b
result &= a ^ b;
//If a == c: result = 0 ^ a = a
//Else: result = (a ^ b) ^ a = b
result ^= a;
return result;
}
I really wish I came up with Cairnarvon's solution. Here's what I got, but in any case you'll end up using conditional statements somewhere hidden in a function call, unless you can figure out how to do this with bitwise operators.
public static int fn(int a, int b, int c) {
Boolean equal = (a == c);
//if equal is false, compareTo will return 0.
//if equal is true, compareTo will return any positive integer, thus we take mod 2 to ensure this is 1
int ret_a = equal.compareTo(Boolean.FALSE) % 2;
//if ret_a is 0, make ret_b = 1
//if ret_a is 1, make ret_b = 0
int ret_b = (ret_a + 1) % 2;
//one of these two terms is guaranteed to be zero, therefore you will only
//return the value of a, or b.
return (ret_a * a) + (ret_b * b);
}
Here is my attempt at a solution with no comparison or bit twiddling. Sadly as #Pshemo pointed out my logic is flawed.
public static int fn(int a, int b, int c) {
//I assumed this will return 1 if not a != c
//See Pshemo's comment about why this is wrong.
int not_equal = ((a - c) * (a - c) ) % 2;
int ret_a = (not_equal + 1) % 2;
int ret_b = not_equal;
//one of these two terms is guaranteed to be zero, therefore you will only
//return the value of a, or b.
return (ret_a * a) + (ret_b * b);
}
There are a number of possible approaches, including:
Do the test in native code. That's cheating.
Find some library class that can used to do the job. There are probably lots of variations on this approach; e.g. see #Cairnarvon's answer.
Do something tricky to generate an exception (or not) depending on the inputs. My initial idea was to use division by zero, but here's another way ...
int insanelyStupidConditional (int a, int b, int c) {
int[] dummy = new int[1];
try {
int foo = dummy[a - c];
} catch (ArrayIndexOutOfBoundsException ex) {
return b;
}
return a;
}
Bit twiddling ... like #Vlad's answer
Anyway, the point of the interview question is not the answer, but whether you are able to think outside of the box to arrive at something. The most practical answer is "change the requirements ... this is insane".
Another way
Base idea return b * f(a,c) + a * (1 - f(a,c)) where
f(a,c) -> 1 for a != c
f(a,c) -> 0 for a == c
so
for a!=c we will return b*(1) + a*(0);
and for a==c we will return b*(0) + a*(1);
code
public static int test(int a, int b, int c) {
// (a - c) | (c - a) will give
// for a != b negative value
// for a == c zero
// to get sign of that value we need to get highest bit
// so >>>31 will do the trick
int signum = ((a - c) | (c - a)) >>> 31;
//for a == c -> signum = 0
//for a != c -> signum = 1 (it indicates that (a - c) | (c - a) was negative)
return b * signum + a * (1 - signum);
}
There you go, no if, while, do, for, switch, inline if (?:), or any other operator (==, !=, >, <, >=, etc.):
int function(int a, int b, int c){
int[] result = {-1, a, b};
return result[new TreeSet<Integer>(Arrays.asList(a, c)).size()];
}
Logic: Adds both a and c to a Set. If they are equal, they'll be added only once, and the set's size will be 1. If they are different, the size will be 2.

Convert bit vector (array of booleans) to an integer, and integer to bit vector, in Java

What's the best way to unstub the following functions?
// Convert a bit-vector to an integer.
int bitvec2int(boolean[] b)
{
[CODE HERE]
}
// Convert an integer x to an n-element bit-vector.
boolean[] int2bitvec(int x, int n)
{
[CODE HERE]
}
Or is there a better way to do that sort of thing than passing boolean arrays around?
This comes up in an Android app where we need an array of 20 booleans to persist and the easiest way to do that is to write an integer or string to the key-value store.
I'll post the way we (Bee and I) wrote the above as an answer. Thanks!
Use java.util.BitSet instead. It'd be much faster than dealing with boolean[].
Also, you should really ask yourself if these 20 boolean really should be enum, in which case you can use EnumSet, which is the Java solution to the bit fields technique from C (see: Effective Java 2nd Edition: Use EnumSet instead of bit fields).
BitSet to/from int conversion
You might as well just use BitSet and drop the int, but just in case you need these:
static BitSet toBitSet(int i) {
BitSet bs = new BitSet(Integer.SIZE);
for (int k = 0; k < Integer.SIZE; k++) {
if ((i & (1 << k)) != 0) {
bs.set(k);
}
}
return bs;
}
static int toInt(BitSet bs) {
int i = 0;
for (int pos = -1; (pos = bs.nextSetBit(pos+1)) != -1; ) {
i |= (1 << pos);
}
return i;
}
Two different techniques were deliberately used for instructional purposes. For robustness, the BitSet to int conversion should ensure that 32 bits is enough.
EnumSet example
This example is based on the one given in the book:
import java.util.*;
public enum Style {
BOLD, ITALIC, UNDERLINE, STRIKETHROUGH;
public static void main(String[] args) {
Set<Style> s1 = EnumSet.of(BOLD, UNDERLINE);
System.out.println(s1); // prints "[BOLD, UNDERLINE]"
s1.addAll(EnumSet.of(ITALIC, UNDERLINE));
System.out.println(s1.contains(ITALIC)); // prints "true"
}
}
From the API:
This representation is extremely compact and efficient. The space and time performance of this class should be good enough to allow its use as a high-quality, typesafe alternative to traditional int-based "bit flags."
// Convert a big-endian bit-vector to an integer.
int bitvec2int(boolean[] b)
{
int x = 0;
for(boolean i : b) x = x << 1 | (i?1:0);
return x;
}
// Convert an integer x to an n-element big-endian bit-vector.
boolean[] int2bitvec(int x, int n)
{
boolean[] b = new boolean[n];
for(int i = 0; i < n; i++) b[i] = (1 << n-i-1 & x) != 0;
return b;
}

Java method to swap primitives

how do I make my swap function in java if there is no method by which we can pass by reference? Could somebody give me a code?
swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
But the changes wont be reflected back since java passes parameters by value.
I think this is the closest you can get to a simple swap, but it does not have a straightforward usage pattern:
int swap(int a, int b) { // usage: y = swap(x, x=y);
return a;
}
y = swap(x, x=y);
It relies on the fact that x will pass into swap before y is assigned to x, then x is returned and assigned to y.
You can make it generic and swap any number of objects of the same type:
<T> T swap(T... args) { // usage: z = swap(a, a=b, b=c, ... y=z);
return args[0];
}
c = swap(a, a=b, b=c)
You can't create a method swap, so that after calling swap(x,y) the values of x and y will be swapped. You could create such a method for mutable classes by swapping their contents¹, but this would not change their object identity and you could not define a general method for this.
You can however write a method that swaps two items in an array or list if that's what you want.
¹ For example you could create a swap method that takes two lists and after executing the method, list x will have the previous contents of list y and list y will have the previous contents of list x.
It depends on what you want to do. This code swaps two elements of an array.
void swap(int i, int j, int[] arr) {
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
Something like this swaps the content of two int[] of equal length.
void swap(int[] arr1, int[] arr2) {
int[] t = arr1.clone();
System.arraycopy(arr2, 0, arr1, 0, t.length);
System.arraycopy(t, 0, arr2, 0, t.length);
}
Something like this swaps the content of two BitSet (using the XOR swap algorithm):
void swap(BitSet s1, BitSet s2) {
s1.xor(s2);
s2.xor(s1);
s1.xor(s2);
}
Something like this swaps the x and y fields of some Point class:
void swapXY(Point p) {
int t = p.x;
p.x = p.y;
p.y = t;
}
Apparently I don't have enough reputation points to comment on Dansalmo's
answer, but it is a good one, though mis-named. His answer is actually a K-combinator.
int K( int a, int b ) {
return a;
}
The JLS is specific about argument evaluation when passing to methods/ctors/etc. (Was this not so in older specs?)
Granted, this is a functional idiom, but it is clear enough to those who recognize it. (If you don't understand code you find, don't mess with it!)
y = K(x, x=y); // swap x and y
The K-combinator is specifically designed for this kind of thing. AFAIK there's no reason it shouldn't pass a code review.
My $0.02.
AFAIS, no one mentions of atomic reference.
Integer
public void swap(AtomicInteger a, AtomicInteger b){
a.set(b.getAndSet(a.get()));
}
String
public void swap(AtomicReference<String> a, AtomicReference<String> b){
a.set(b.getAndSet(a.get()));
}
As per #Stephan's comment: as long as you are not in a multi-threaded app, the following will work as well.
First: wrap your simple types in an array of size 1.
int[] x1 = {x};
int[] y1 = {y};
Then write a swap method
public void swap(int[] a, int[] b) {
assert(a.length == 1);
assert(b.length == 1);
int temp = a[0];
a[0] = b[0];
b[0] = temp;
}
If you want to make this work for all simple types, you'll have to write overloads, because Java Generics don't work for simple types.
I might do something like the following. Of course, with the wealth of Collection classes, i can't imagine ever needing to use this in any practical code.
public class Shift {
public static <T> T[] left (final T... i) {
if (1 >= i.length) {
return i;
}
final T t = i[0];
int x = 0;
for (; x < i.length - 1; x++) {
i[x] = i[x + 1];
}
i[x] = t;
return i;
}
}
Called with two arguments, it's a swap.
It can be used as follows:
int x = 1;
int y = 2;
Integer[] yx = Shift.left(x,y);
Alternatively:
Integer[] yx = {x,y};
Shift.left(yx);
Then
x = yx[0];
y = yx[1];
Note: it auto-boxes primitives.
Try this magic
public static <T> void swap(T a, T b) {
try {
Field[] fields = a.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object temp = field.get(a);
field.set(a, field.get(b));
field.set(b, temp);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
And test it!
System.out.println("a:" + a);
System.out.println("b:" + b);
swap(a,b);
System.out.println("a:" + a);
System.out.println("b:" + b);
For integer types, you can do
a ^= b;
b ^= a;
a ^= b;
using the bit-wise xor operator ^. As all the other suggestions, you probably shouldn't use it in production code.
For a reason I don't know, the single line version a ^= b ^= a ^= b doesn't work (maybe my Java compiler has a bug). The single line worked in C with all compilers I tried. However, two-line versions work:
a ^= b ^= a;
b ^= a;
as well as
b ^= a;
a ^= b ^= a;
A proof that it works: Let a₀ and b₀ be the initial values for a and b. After the first line, a is a₁ = a₀ xor b₀; after the second line, b is b₁ = b₀ xor a₁ = b₀ xor (a₀ xor b₀) = a₀. After the third line, a is a₂ = a₁ xor b₁ = a₁ xor (b₀ xor a₁) = b₀.

Categories

Resources