Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 544a2a1

Browse files
authoredOct 26, 2024··
Merge branch 'master' into merge_k_sorted_new_algo
2 parents 43da361 + 5d428d0 commit 544a2a1

25 files changed

+912
-164
lines changed
 

‎DIRECTORY.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@
3939
* [IsEven](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java)
4040
* [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java)
4141
* [LowestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/LowestSetBit.java)
42+
* [ModuloPowerOfTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwo.java)
4243
* [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java)
4344
* [NumberAppearingOddTimes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimes.java)
4445
* [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java)
46+
* [OneBitDifference](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/OneBitDifference.java)
4547
* [OnesComplement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java)
4648
* [ParityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ParityCheck.java)
4749
* [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java)
@@ -100,6 +102,7 @@
100102
* [IntegerToEnglish](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IntegerToEnglish.java)
101103
* [IntegerToRoman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java)
102104
* [IPConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IPConverter.java)
105+
* [IPv6Converter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IPv6Converter.java)
103106
* [MorseCodeConverter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/MorseCodeConverter.java)
104107
* [OctalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToBinary.java)
105108
* [OctalToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java)
@@ -171,9 +174,14 @@
171174
* [GenericHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java)
172175
* [Heap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java)
173176
* [HeapElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java)
177+
* [KthElementFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/KthElementFinder.java)
174178
* [LeftistHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java)
175179
* [MaxHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java)
180+
176181
* [MergeKSortedArrays](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MergeKSortedArrays.java)
182+
183+
* [MedianFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MedianFinder.java)
184+
177185
* [MinHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java)
178186
* [MinPriorityQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java)
179187
* lists
@@ -731,9 +739,11 @@
731739
* [IsEvenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java)
732740
* [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java)
733741
* [LowestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/LowestSetBitTest.java)
742+
* [ModuloPowerOfTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ModuloPowerOfTwoTest.java)
734743
* [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java)
735744
* [NumberAppearingOddTimesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java)
736745
* [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java)
746+
* [OneBitDifferenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/OneBitDifferenceTest.java)
737747
* [OnesComplementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java)
738748
* [ParityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ParityCheckTest.java)
739749
* [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java)
@@ -785,6 +795,7 @@
785795
* [IntegerToEnglishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IntegerToEnglishTest.java)
786796
* [IntegerToRomanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java)
787797
* [IPConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IPConverterTest.java)
798+
* [IPv6ConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IPv6ConverterTest.java)
788799
* [MorseCodeConverterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/MorseCodeConverterTest.java)
789800
* [OctalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java)
790801
* [OctalToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java)
@@ -843,8 +854,13 @@
843854
* heaps
844855
* [FibonacciHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java)
845856
* [GenericHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/GenericHeapTest.java)
857+
* [KthElementFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/KthElementFinderTest.java)
846858
* [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java)
859+
847860
* [MergeKSortedArraysTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MergeKSortedArraysTest.java)
861+
862+
* [MedianFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MedianFinderTest.java)
863+
848864
* [MinPriorityQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/MinPriorityQueueTest.java)
849865
* lists
850866
* [CircleLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/CircleLinkedListTest.java)
@@ -871,6 +887,7 @@
871887
* [TokenBucketTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/TokenBucketTest.java)
872888
* stacks
873889
* [NodeStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/NodeStackTest.java)
890+
* [ReverseStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/ReverseStackTest.java)
874891
* [StackArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayListTest.java)
875892
* [StackArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackArrayTest.java)
876893
* [StackOfLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/stacks/StackOfLinkedListTest.java)

‎src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* Is number power of 2
4+
* Utility class for checking if a number is a power of two.
5+
* A power of two is a number that can be expressed as 2^n where n is a non-negative integer.
6+
* This class provides a method to determine if a given integer is a power of two using bit manipulation.
7+
*
58
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
69
*/
7-
810
public final class IsPowerTwo {
911
private IsPowerTwo() {
1012
}
13+
14+
/**
15+
* Checks if the given integer is a power of two.
16+
*
17+
* A number is considered a power of two if it is greater than zero and
18+
* has exactly one '1' bit in its binary representation. This method
19+
* uses the property that for any power of two (n), the expression
20+
* (n & (n - 1)) will be zero.
21+
*
22+
* @param number the integer to check
23+
* @return true if the number is a power of two, false otherwise
24+
*/
1125
public static boolean isPowerTwo(int number) {
1226
if (number <= 0) {
1327
return false;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.thealgorithms.bitmanipulation;
2+
3+
/**
4+
* This class provides a method to compute the remainder
5+
* of a number when divided by a power of two (2^n)
6+
* without using division or modulo operations.
7+
*
8+
* @author Hardvan
9+
*/
10+
public final class ModuloPowerOfTwo {
11+
private ModuloPowerOfTwo() {
12+
}
13+
14+
/**
15+
* Computes the remainder of a given integer when divided by 2^n.
16+
*
17+
* @param x the input number
18+
* @param n the exponent (power of two)
19+
* @return the remainder of x divided by 2^n
20+
*/
21+
public static int moduloPowerOfTwo(int x, int n) {
22+
if (n <= 0) {
23+
throw new IllegalArgumentException("The exponent must be positive");
24+
}
25+
26+
return x & ((1 << n) - 1);
27+
}
28+
}

‎src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* Find Non Repeating Number
4+
* A utility class to find the non-repeating number in an array where every other number repeats.
5+
* This class contains a method to identify the single unique number using bit manipulation.
6+
*
7+
* The solution leverages the properties of the XOR operation, which states that:
8+
* - x ^ x = 0 for any integer x (a number XORed with itself is zero)
9+
* - x ^ 0 = x for any integer x (a number XORed with zero is the number itself)
10+
*
11+
* Using these properties, we can find the non-repeating number in linear time with constant space.
12+
*
13+
* Example:
14+
* Given the input array [2, 3, 5, 2, 3], the output will be 5 since it does not repeat.
15+
*
516
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
617
*/
7-
818
public final class NonRepeatingNumberFinder {
919
private NonRepeatingNumberFinder() {
1020
}
1121

22+
/**
23+
* Finds the non-repeating number in the given array.
24+
*
25+
* @param arr an array of integers where every number except one appears twice
26+
* @return the integer that appears only once in the array or 0 if the array is empty
27+
*/
1228
public static int findNonRepeatingNumber(int[] arr) {
1329
int result = 0;
1430
for (int num : arr) {
Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,41 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* Find the Number Appearing Odd Times in an array
4+
* This class provides a method to find the element that appears an
5+
* odd number of times in an array. All other elements in the array
6+
* must appear an even number of times for the logic to work.
7+
*
8+
* The solution uses the XOR operation, which has the following properties:
9+
* - a ^ a = 0 (XOR-ing the same numbers cancels them out)
10+
* - a ^ 0 = a
11+
* - XOR is commutative and associative.
12+
*
13+
* Time Complexity: O(n), where n is the size of the array.
14+
* Space Complexity: O(1), as no extra space is used.
15+
*
16+
* Usage Example:
17+
* int result = NumberAppearingOddTimes.findOddOccurrence(new int[]{1, 2, 1, 2, 3});
18+
* // result will be 3
19+
*
520
* @author Lakshyajeet Singh Goyal (https://github.com/DarkMatter-999)
621
*/
722

823
public final class NumberAppearingOddTimes {
924
private NumberAppearingOddTimes() {
1025
}
26+
27+
/**
28+
* Finds the element in the array that appears an odd number of times.
29+
*
30+
* @param arr the input array containing integers, where all elements
31+
* except one appear an even number of times.
32+
* @return the integer that appears an odd number of times.
33+
*/
1134
public static int findOddOccurrence(int[] arr) {
1235
int result = 0;
13-
14-
// XOR all elements in the array
1536
for (int num : arr) {
1637
result ^= num;
1738
}
18-
1939
return result;
2040
}
2141
}

‎src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* Numbers Different Signs
4+
* This class provides a method to determine whether two integers have
5+
* different signs. It utilizes the XOR operation on the two numbers:
6+
*
7+
* - If two numbers have different signs, their most significant bits
8+
* (sign bits) will differ, resulting in a negative XOR result.
9+
* - If two numbers have the same sign, the XOR result will be non-negative.
10+
*
11+
* Time Complexity: O(1) - Constant time operation.
12+
* Space Complexity: O(1) - No extra space used.
13+
*
514
* @author Bama Charan Chhandogi
615
*/
7-
816
public final class NumbersDifferentSigns {
917
private NumbersDifferentSigns() {
1018
}
1119

20+
/**
21+
* Determines if two integers have different signs using bitwise XOR.
22+
*
23+
* @param num1 the first integer
24+
* @param num2 the second integer
25+
* @return true if the two numbers have different signs, false otherwise
26+
*/
1227
public static boolean differentSigns(int num1, int num2) {
1328
return (num1 ^ num2) < 0;
1429
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.thealgorithms.bitmanipulation;
2+
3+
/**
4+
* This class provides a method to detect if two integers
5+
* differ by exactly one bit flip.
6+
*
7+
* Example:
8+
* 1 (0001) and 2 (0010) differ by exactly one bit flip.
9+
* 7 (0111) and 3 (0011) differ by exactly one bit flip.
10+
*
11+
* @author Hardvan
12+
*/
13+
public final class OneBitDifference {
14+
private OneBitDifference() {
15+
}
16+
17+
/**
18+
* Checks if two integers differ by exactly one bit.
19+
*
20+
* @param x the first integer
21+
* @param y the second integer
22+
* @return true if x and y differ by exactly one bit, false otherwise
23+
*/
24+
public static boolean differByOneBit(int x, int y) {
25+
if (x == y) {
26+
return false;
27+
}
28+
29+
int xor = x ^ y;
30+
return (xor & (xor - 1)) == 0;
31+
}
32+
}
Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,68 @@
11
package com.thealgorithms.bitmanipulation;
22

3-
/*
3+
/**
4+
* A utility class for performing single-bit operations on integers.
5+
* These operations include flipping, setting, clearing, and getting
6+
* individual bits at specified positions.
7+
*
8+
* Bit positions are zero-indexed (i.e., the least significant bit is at position 0).
9+
* These methods leverage bitwise operations for optimal performance.
10+
*
11+
* Examples:
12+
* - `flipBit(3, 1)` flips the bit at index 1 in binary `11` (result: `1`).
13+
* - `setBit(4, 0)` sets the bit at index 0 in `100` (result: `101` or 5).
14+
* - `clearBit(7, 1)` clears the bit at index 1 in `111` (result: `101` or 5).
15+
* - `getBit(6, 0)` checks if the least significant bit is set (result: `0`).
16+
*
17+
* Time Complexity: O(1) for all operations.
18+
*
419
* Author: lukasb1b (https://github.com/lukasb1b)
520
*/
6-
721
public final class SingleBitOperations {
822
private SingleBitOperations() {
923
}
24+
1025
/**
11-
* Flip the bit at position 'bit' in 'num'
26+
* Flips (toggles) the bit at the specified position.
27+
*
28+
* @param num the input number
29+
* @param bit the position of the bit to flip (0-indexed)
30+
* @return the new number after flipping the specified bit
1231
*/
1332
public static int flipBit(final int num, final int bit) {
1433
return num ^ (1 << bit);
1534
}
35+
1636
/**
17-
* Set the bit at position 'bit' to 1 in the 'num' variable
37+
* Sets the bit at the specified position to 1.
38+
*
39+
* @param num the input number
40+
* @param bit the position of the bit to set (0-indexed)
41+
* @return the new number after setting the specified bit to 1
1842
*/
1943
public static int setBit(final int num, final int bit) {
2044
return num | (1 << bit);
2145
}
46+
2247
/**
23-
* Clears the bit located at 'bit' from 'num'
48+
* Clears the bit at the specified position (sets it to 0).
49+
*
50+
* @param num the input number
51+
* @param bit the position of the bit to clear (0-indexed)
52+
* @return the new number after clearing the specified bit
2453
*/
2554
public static int clearBit(final int num, final int bit) {
2655
return num & ~(1 << bit);
2756
}
57+
2858
/**
29-
* Get the bit located at 'bit' from 'num'
59+
* Gets the bit value (0 or 1) at the specified position.
60+
*
61+
* @param num the input number
62+
* @param bit the position of the bit to retrieve (0-indexed)
63+
* @return 1 if the bit is set, 0 otherwise
3064
*/
3165
public static int getBit(final int num, final int bit) {
32-
return ((num >> bit) & 1);
66+
return (num >> bit) & 1;
3367
}
3468
}
Lines changed: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,62 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* @wikipedia - https://en.wikipedia.org/wiki/Two%27s_complement
5-
* This Algorithm was first suggested by Jon Von Neumann
6-
* @author - https://github.com/Monk-AbhinayVerma
7-
* @return the two's complement of any binary number
4+
* This class provides a method to compute the Two's Complement of a given binary number.
5+
*
6+
* <p>In two's complement representation, a binary number's negative value is obtained
7+
* by taking the one's complement (inverting all bits) and then adding 1 to the result.
8+
* This method handles both small and large binary strings and ensures the output is
9+
* correct for all binary inputs, including edge cases like all zeroes and all ones.
10+
*
11+
* <p>For more information on Two's Complement:
12+
* @see <a href="https://en.wikipedia.org/wiki/Two%27s_complement">Wikipedia - Two's Complement</a>
13+
*
14+
* <p>Algorithm originally suggested by Jon von Neumann.
15+
*
16+
* @author Abhinay Verma (https://github.com/Monk-AbhinayVerma)
817
*/
918
public final class TwosComplement {
1019
private TwosComplement() {
1120
}
1221

13-
// Function to get the 2's complement of a binary number
22+
/**
23+
* Computes the Two's Complement of the given binary string.
24+
* Steps:
25+
* 1. Compute the One's Complement (invert all bits).
26+
* 2. Add 1 to the One's Complement to get the Two's Complement.
27+
* 3. Iterate from the rightmost bit to the left, adding 1 and carrying over as needed.
28+
* 4. If a carry is still present after the leftmost bit, prepend '1' to handle overflow.
29+
*
30+
* @param binary The binary number as a string (only '0' and '1' characters allowed).
31+
* @return The two's complement of the input binary string as a new binary string.
32+
* @throws IllegalArgumentException If the input contains non-binary characters.
33+
*/
1434
public static String twosComplement(String binary) {
35+
if (!binary.matches("[01]+")) {
36+
throw new IllegalArgumentException("Input must contain only '0' and '1'.");
37+
}
38+
1539
StringBuilder onesComplement = new StringBuilder();
16-
// Step 1: Find the 1's complement (invert the bits)
17-
for (int i = 0; i < binary.length(); i++) {
18-
if (binary.charAt(i) == '0') {
19-
onesComplement.append('1');
20-
} else {
21-
onesComplement.append('0');
22-
}
40+
for (char bit : binary.toCharArray()) {
41+
onesComplement.append(bit == '0' ? '1' : '0');
2342
}
24-
// Step 2: Add 1 to the 1's complement
43+
2544
StringBuilder twosComplement = new StringBuilder(onesComplement);
2645
boolean carry = true;
27-
for (int i = onesComplement.length() - 1; i >= 0; i--) {
28-
if (onesComplement.charAt(i) == '1' && carry) {
46+
47+
for (int i = onesComplement.length() - 1; i >= 0 && carry; i--) {
48+
if (onesComplement.charAt(i) == '1') {
2949
twosComplement.setCharAt(i, '0');
30-
} else if (onesComplement.charAt(i) == '0' && carry) {
50+
} else {
3151
twosComplement.setCharAt(i, '1');
3252
carry = false;
3353
}
3454
}
35-
// If there is still a carry, append '1' at the beginning
55+
3656
if (carry) {
3757
twosComplement.insert(0, '1');
3858
}
59+
3960
return twosComplement.toString();
4061
}
4162
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package com.thealgorithms.conversions;
2+
3+
import java.net.InetAddress;
4+
import java.net.UnknownHostException;
5+
import java.util.Arrays;
6+
7+
/**
8+
* A utility class for converting between IPv6 and IPv4 addresses.
9+
*
10+
* - Converts IPv4 to IPv6-mapped IPv6 address.
11+
* - Extracts IPv4 address from IPv6-mapped IPv6.
12+
* - Handles exceptions for invalid inputs.
13+
*
14+
* @author Hardvan
15+
*/
16+
public final class IPv6Converter {
17+
private IPv6Converter() {
18+
}
19+
20+
/**
21+
* Converts an IPv4 address (e.g., "192.0.2.128") to an IPv6-mapped IPv6 address.
22+
* Example: IPv4 "192.0.2.128" -> IPv6 "::ffff:192.0.2.128"
23+
*
24+
* @param ipv4Address The IPv4 address in string format.
25+
* @return The corresponding IPv6-mapped IPv6 address.
26+
* @throws UnknownHostException If the IPv4 address is invalid.
27+
* @throws IllegalArgumentException If the IPv6 address is not a mapped IPv4 address.
28+
*/
29+
public static String ipv4ToIpv6(String ipv4Address) throws UnknownHostException {
30+
if (ipv4Address == null || ipv4Address.isEmpty()) {
31+
throw new UnknownHostException("IPv4 address is empty.");
32+
}
33+
34+
InetAddress ipv4 = InetAddress.getByName(ipv4Address);
35+
byte[] ipv4Bytes = ipv4.getAddress();
36+
37+
// Create IPv6-mapped IPv6 address (starts with ::ffff:)
38+
byte[] ipv6Bytes = new byte[16];
39+
ipv6Bytes[10] = (byte) 0xff;
40+
ipv6Bytes[11] = (byte) 0xff;
41+
System.arraycopy(ipv4Bytes, 0, ipv6Bytes, 12, 4);
42+
43+
// Manually format to "::ffff:x.x.x.x" format
44+
StringBuilder ipv6String = new StringBuilder("::ffff:");
45+
for (int i = 12; i < 16; i++) {
46+
ipv6String.append(ipv6Bytes[i] & 0xFF);
47+
if (i < 15) {
48+
ipv6String.append('.');
49+
}
50+
}
51+
return ipv6String.toString();
52+
}
53+
54+
/**
55+
* Extracts the IPv4 address from an IPv6-mapped IPv6 address.
56+
* Example: IPv6 "::ffff:192.0.2.128" -> IPv4 "192.0.2.128"
57+
*
58+
* @param ipv6Address The IPv6 address in string format.
59+
* @return The extracted IPv4 address.
60+
* @throws UnknownHostException If the IPv6 address is invalid or not a mapped IPv4 address.
61+
*/
62+
public static String ipv6ToIpv4(String ipv6Address) throws UnknownHostException {
63+
InetAddress ipv6 = InetAddress.getByName(ipv6Address);
64+
byte[] ipv6Bytes = ipv6.getAddress();
65+
66+
// Check if the address is an IPv6-mapped IPv4 address
67+
if (isValidIpv6MappedIpv4(ipv6Bytes)) {
68+
byte[] ipv4Bytes = Arrays.copyOfRange(ipv6Bytes, 12, 16);
69+
InetAddress ipv4 = InetAddress.getByAddress(ipv4Bytes);
70+
return ipv4.getHostAddress();
71+
} else {
72+
throw new IllegalArgumentException("Not a valid IPv6-mapped IPv4 address.");
73+
}
74+
}
75+
76+
/**
77+
* Helper function to check if the given byte array represents
78+
* an IPv6-mapped IPv4 address (prefix 0:0:0:0:0:ffff).
79+
*
80+
* @param ipv6Bytes Byte array representation of the IPv6 address.
81+
* @return True if the address is IPv6-mapped IPv4, otherwise false.
82+
*/
83+
private static boolean isValidIpv6MappedIpv4(byte[] ipv6Bytes) {
84+
// IPv6-mapped IPv4 addresses are 16 bytes long, with the first 10 bytes set to 0,
85+
// followed by 0xff, 0xff, and the last 4 bytes representing the IPv4 address.
86+
if (ipv6Bytes.length != 16) {
87+
return false;
88+
}
89+
90+
for (int i = 0; i < 10; i++) {
91+
if (ipv6Bytes[i] != 0) {
92+
return false;
93+
}
94+
}
95+
96+
return ipv6Bytes[10] == (byte) 0xff && ipv6Bytes[11] == (byte) 0xff;
97+
}
98+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
2+
package com.thealgorithms.datastructures.heaps;
3+
4+
import java.util.PriorityQueue;
5+
6+
/**
7+
* This class provides methods to find the Kth largest or Kth smallest element
8+
* in an array using heaps. It leverages a min-heap to find the Kth largest element
9+
* and a max-heap to find the Kth smallest element efficiently.
10+
*
11+
* @author Hardvan
12+
*/
13+
public final class KthElementFinder {
14+
private KthElementFinder() {
15+
}
16+
17+
/**
18+
* Finds the Kth largest element in the given array.
19+
* Uses a min-heap of size K to track the largest K elements.
20+
*
21+
* Time Complexity: O(n * log(k)), where n is the size of the input array.
22+
* Space Complexity: O(k), as we maintain a heap of size K.
23+
*
24+
* @param nums the input array of integers
25+
* @param k the desired Kth position (1-indexed, i.e., 1 means the largest element)
26+
* @return the Kth largest element in the array
27+
*/
28+
public static int findKthLargest(int[] nums, int k) {
29+
PriorityQueue<Integer> minHeap = new PriorityQueue<>(k);
30+
for (int num : nums) {
31+
minHeap.offer(num);
32+
if (minHeap.size() > k) {
33+
minHeap.poll();
34+
}
35+
}
36+
return minHeap.peek();
37+
}
38+
39+
/**
40+
* Finds the Kth smallest element in the given array.
41+
* Uses a max-heap of size K to track the smallest K elements.
42+
*
43+
* Time Complexity: O(n * log(k)), where n is the size of the input array.
44+
* Space Complexity: O(k), as we maintain a heap of size K.
45+
*
46+
* @param nums the input array of integers
47+
* @param k the desired Kth position (1-indexed, i.e., 1 means the smallest element)
48+
* @return the Kth smallest element in the array
49+
*/
50+
public static int findKthSmallest(int[] nums, int k) {
51+
PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
52+
for (int num : nums) {
53+
maxHeap.offer(num);
54+
if (maxHeap.size() > k) {
55+
maxHeap.poll();
56+
}
57+
}
58+
return maxHeap.peek();
59+
}
60+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.thealgorithms.datastructures.heaps;
2+
3+
import java.util.PriorityQueue;
4+
5+
/**
6+
* This class maintains the median of a dynamically changing data stream using
7+
* two heaps: a max-heap and a min-heap. The max-heap stores the smaller half
8+
* of the numbers, and the min-heap stores the larger half.
9+
* This data structure ensures that retrieving the median is efficient.
10+
*
11+
* Time Complexity:
12+
* - Adding a number: O(log n) due to heap insertion.
13+
* - Finding the median: O(1).
14+
*
15+
* Space Complexity: O(n), where n is the total number of elements added.
16+
*
17+
* @author Hardvan
18+
*/
19+
public final class MedianFinder {
20+
MedianFinder() {
21+
}
22+
23+
private PriorityQueue<Integer> minHeap = new PriorityQueue<>();
24+
private PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a, b) -> b - a);
25+
26+
/**
27+
* Adds a new number to the data stream. The number is placed in the appropriate
28+
* heap to maintain the balance between the two heaps.
29+
*
30+
* @param num the number to be added to the data stream
31+
*/
32+
public void addNum(int num) {
33+
if (maxHeap.isEmpty() || num <= maxHeap.peek()) {
34+
maxHeap.offer(num);
35+
} else {
36+
minHeap.offer(num);
37+
}
38+
39+
if (maxHeap.size() > minHeap.size() + 1) {
40+
minHeap.offer(maxHeap.poll());
41+
} else if (minHeap.size() > maxHeap.size()) {
42+
maxHeap.offer(minHeap.poll());
43+
}
44+
}
45+
46+
/**
47+
* Finds the median of the numbers added so far. If the total number of elements
48+
* is even, the median is the average of the two middle elements. If odd, the
49+
* median is the middle element from the max-heap.
50+
*
51+
* @return the median of the numbers in the data stream
52+
*/
53+
public double findMedian() {
54+
if (maxHeap.size() == minHeap.size()) {
55+
return (maxHeap.peek() + minHeap.peek()) / 2.0;
56+
}
57+
return maxHeap.peek();
58+
}
59+
}
Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,74 @@
11
package com.thealgorithms.datastructures.stacks;
22

3-
import java.util.Scanner;
43
import java.util.Stack;
54

65
/**
7-
* Reversal of a stack using recursion.
6+
* Provides methods to reverse a stack using recursion.
7+
*
8+
* <p>This class includes methods to reverse the order of elements in a stack
9+
* without using additional data structures. Elements are inserted at the bottom
10+
* of the stack to achieve the reverse order.
11+
*
12+
* <p>Example usage:
13+
* <pre>
14+
* Stack<Integer> stack = new Stack<>();
15+
* stack.push(1);
16+
* stack.push(2);
17+
* stack.push(3);
18+
* ReverseStack.reverseStack(stack);
19+
* </pre>
20+
* After calling {@code reverseStack(stack)}, the stack's order is reversed.
21+
*
22+
* <p>This class is final and has a private constructor to prevent instantiation.
823
*
924
* @author Ishika Agarwal, 2021
1025
*/
1126
public final class ReverseStack {
1227
private ReverseStack() {
1328
}
1429

15-
public static void main(String[] args) {
16-
try (Scanner sc = new Scanner(System.in)) {
17-
System.out.println("Enter the number of elements you wish to insert in the stack");
18-
int n = sc.nextInt();
19-
int i;
20-
Stack<Integer> stack = new Stack<Integer>();
21-
System.out.println("Enter the stack elements");
22-
for (i = 0; i < n; i++) {
23-
stack.push(sc.nextInt());
24-
}
25-
reverseStack(stack);
26-
System.out.println("The reversed stack is:");
27-
while (!stack.isEmpty()) {
28-
System.out.print(stack.peek() + ",");
29-
stack.pop();
30-
}
31-
}
32-
}
33-
34-
private static void reverseStack(Stack<Integer> stack) {
30+
/**
31+
* Reverses the order of elements in the given stack using recursion.
32+
* Steps:
33+
* 1. Check if the stack is empty. If so, return.
34+
* 2. Pop the top element from the stack.
35+
* 3. Recursively reverse the remaining stack.
36+
* 4. Insert the originally popped element at the bottom of the reversed stack.
37+
*
38+
* @param stack the stack to reverse; should not be null
39+
*/
40+
public static void reverseStack(Stack<Integer> stack) {
3541
if (stack.isEmpty()) {
3642
return;
3743
}
3844

39-
// Store the topmost element
40-
int element = stack.peek();
41-
// Remove the topmost element
42-
stack.pop();
43-
44-
// Reverse the stack for the leftover elements
45+
int element = stack.pop();
4546
reverseStack(stack);
46-
47-
// Insert the topmost element to the bottom of the stack
4847
insertAtBottom(stack, element);
4948
}
5049

50+
/**
51+
* Inserts the specified element at the bottom of the stack.
52+
*
53+
* <p>This method is a helper for {@link #reverseStack(Stack)}.
54+
*
55+
* Steps:
56+
* 1. If the stack is empty, push the element and return.
57+
* 2. Remove the top element from the stack.
58+
* 3. Recursively insert the new element at the bottom of the stack.
59+
* 4. Push the removed element back onto the stack.
60+
*
61+
* @param stack the stack in which to insert the element; should not be null
62+
* @param element the element to insert at the bottom of the stack
63+
*/
5164
private static void insertAtBottom(Stack<Integer> stack, int element) {
5265
if (stack.isEmpty()) {
53-
// When stack is empty, insert the element so it will be present at
54-
// the bottom of the stack
5566
stack.push(element);
5667
return;
5768
}
5869

59-
int ele = stack.peek();
60-
// Keep popping elements till stack becomes empty. Push the elements
61-
// once the topmost element has moved to the bottom of the stack.
62-
stack.pop();
70+
int topElement = stack.pop();
6371
insertAtBottom(stack, element);
64-
65-
stack.push(ele);
72+
stack.push(topElement);
6673
}
6774
}

‎src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,49 @@
33
import static org.junit.jupiter.api.Assertions.assertFalse;
44
import static org.junit.jupiter.api.Assertions.assertTrue;
55

6-
import org.junit.jupiter.api.Test;
6+
import java.util.stream.Stream;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
710

811
/**
912
* Test case for IsPowerTwo class
1013
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
1114
*/
1215

1316
public class IsPowerTwoTest {
14-
@Test
15-
public void testIsPowerTwo() {
16-
// test some positive powers of 2
17-
assertTrue(IsPowerTwo.isPowerTwo(1));
18-
assertTrue(IsPowerTwo.isPowerTwo(2));
19-
assertTrue(IsPowerTwo.isPowerTwo(4));
20-
assertTrue(IsPowerTwo.isPowerTwo(16));
21-
assertTrue(IsPowerTwo.isPowerTwo(1024));
2217

23-
// test some negative numbers
24-
assertFalse(IsPowerTwo.isPowerTwo(-1));
25-
assertFalse(IsPowerTwo.isPowerTwo(-2));
26-
assertFalse(IsPowerTwo.isPowerTwo(-4));
18+
@ParameterizedTest
19+
@MethodSource("provideNumbersForPowerTwo")
20+
public void testIsPowerTwo(int number, boolean expected) {
21+
if (expected) {
22+
assertTrue(IsPowerTwo.isPowerTwo(number));
23+
} else {
24+
assertFalse(IsPowerTwo.isPowerTwo(number));
25+
}
26+
}
2727

28-
// test some numbers that are not powers of 2
29-
assertFalse(IsPowerTwo.isPowerTwo(0));
30-
assertFalse(IsPowerTwo.isPowerTwo(3));
31-
assertFalse(IsPowerTwo.isPowerTwo(5));
32-
assertFalse(IsPowerTwo.isPowerTwo(15));
33-
assertFalse(IsPowerTwo.isPowerTwo(1000));
28+
private static Stream<Arguments> provideNumbersForPowerTwo() {
29+
return Stream.of(Arguments.of(1, Boolean.TRUE), // 2^0
30+
Arguments.of(2, Boolean.TRUE), // 2^1
31+
Arguments.of(4, Boolean.TRUE), // 2^2
32+
Arguments.of(8, Boolean.TRUE), // 2^3
33+
Arguments.of(16, Boolean.TRUE), // 2^4
34+
Arguments.of(32, Boolean.TRUE), // 2^5
35+
Arguments.of(64, Boolean.TRUE), // 2^6
36+
Arguments.of(128, Boolean.TRUE), // 2^7
37+
Arguments.of(256, Boolean.TRUE), // 2^8
38+
Arguments.of(1024, Boolean.TRUE), // 2^10
39+
Arguments.of(0, Boolean.FALSE), // 0 is not a power of two
40+
Arguments.of(-1, Boolean.FALSE), // Negative number
41+
Arguments.of(-2, Boolean.FALSE), // Negative number
42+
Arguments.of(-4, Boolean.FALSE), // Negative number
43+
Arguments.of(3, Boolean.FALSE), // 3 is not a power of two
44+
Arguments.of(5, Boolean.FALSE), // 5 is not a power of two
45+
Arguments.of(6, Boolean.FALSE), // 6 is not a power of two
46+
Arguments.of(15, Boolean.FALSE), // 15 is not a power of two
47+
Arguments.of(1000, Boolean.FALSE), // 1000 is not a power of two
48+
Arguments.of(1023, Boolean.FALSE) // 1023 is not a power of two
49+
);
3450
}
3551
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.thealgorithms.bitmanipulation;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.CsvSource;
8+
9+
class ModuloPowerOfTwoTest {
10+
11+
@ParameterizedTest
12+
@CsvSource({
13+
"10, 3, 2",
14+
"15, 2, 3",
15+
"20, 4, 4",
16+
"7, 1, 1",
17+
"5, 1, 1",
18+
"36, 5, 4",
19+
})
20+
void
21+
testModuloPowerOfTwo(int x, int n, int expected) {
22+
assertEquals(expected, ModuloPowerOfTwo.moduloPowerOfTwo(x, n));
23+
}
24+
25+
@ParameterizedTest
26+
@CsvSource({
27+
"10, 0",
28+
"15, -2",
29+
"20, -4",
30+
"7, -1",
31+
"5, -1",
32+
})
33+
void
34+
testNegativeExponent(int x, int n) {
35+
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> ModuloPowerOfTwo.moduloPowerOfTwo(x, n));
36+
assertEquals("The exponent must be positive", exception.getMessage());
37+
}
38+
}

‎src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,35 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5-
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.Arguments;
7+
import org.junit.jupiter.params.provider.MethodSource;
68

79
/**
810
* Test case for Non Repeating Number Finder
11+
* This test class validates the functionality of the
12+
* NonRepeatingNumberFinder by checking various scenarios.
13+
*
914
* @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi)
1015
*/
11-
1216
class NonRepeatingNumberFinderTest {
1317

14-
@Test
15-
void testNonRepeatingNumberFinder() {
16-
int[] arr = {1, 2, 1, 2, 6};
17-
assertEquals(6, NonRepeatingNumberFinder.findNonRepeatingNumber(arr));
18-
int[] arr1 = {1, 2, 1, 2};
19-
assertEquals(0, NonRepeatingNumberFinder.findNonRepeatingNumber(arr1));
20-
int[] arr2 = {12};
21-
assertEquals(12, NonRepeatingNumberFinder.findNonRepeatingNumber(arr2));
18+
@ParameterizedTest
19+
@MethodSource("testCases")
20+
void testNonRepeatingNumberFinder(int[] arr, int expected) {
21+
assertEquals(expected, NonRepeatingNumberFinder.findNonRepeatingNumber(arr));
22+
}
23+
24+
private static Arguments[] testCases() {
25+
return new Arguments[] {
26+
Arguments.of(new int[] {1, 2, 1, 2, 6}, 6), Arguments.of(new int[] {1, 2, 1, 2}, 0), // All numbers repeat
27+
Arguments.of(new int[] {12}, 12), // Single non-repeating number
28+
Arguments.of(new int[] {3, 5, 3, 4, 4}, 5), // More complex case
29+
Arguments.of(new int[] {7, 8, 7, 9, 8, 10, 10}, 9), // Non-repeating in the middle
30+
Arguments.of(new int[] {0, -1, 0, -1, 2}, 2), // Testing with negative numbers
31+
Arguments.of(new int[] {Integer.MAX_VALUE, 1, 1}, Integer.MAX_VALUE), // Edge case with max int
32+
Arguments.of(new int[] {2, 2, 3, 3, 4, 5, 4}, 5), // Mixed duplicates
33+
Arguments.of(new int[] {}, 0) // Edge case: empty array (should be handled as per design)
34+
};
2235
}
2336
}

‎src/test/java/com/thealgorithms/bitmanipulation/NumberAppearingOddTimesTest.java

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,48 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5-
import org.junit.jupiter.api.Test;
5+
import java.util.stream.Stream;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.Arguments;
8+
import org.junit.jupiter.params.provider.MethodSource;
69

710
class NumberAppearingOddTimesTest {
811

9-
@Test
10-
void testFindOddOccurrence() {
11-
int[] arr1 = {5, 6, 7, 8};
12-
assertEquals(12, NumberAppearingOddTimes.findOddOccurrence(arr1));
12+
/**
13+
* Parameterized test for findOddOccurrence method. Tests multiple
14+
* input arrays and their expected results.
15+
*/
16+
@ParameterizedTest
17+
@MethodSource("provideTestCases")
18+
void testFindOddOccurrence(int[] input, int expected) {
19+
assertEquals(expected, NumberAppearingOddTimes.findOddOccurrence(input));
20+
}
21+
22+
/**
23+
* Provides test cases for the parameterized test.
24+
* Each test case consists of an input array and the expected result.
25+
*/
26+
private static Stream<Arguments> provideTestCases() {
27+
return Stream.of(
28+
// Single element appearing odd times (basic case)
29+
Arguments.of(new int[] {5, 6, 7, 8, 6, 7, 5}, 8),
30+
31+
// More complex case with multiple pairs
32+
Arguments.of(new int[] {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2}, 5),
33+
34+
// Case with only one element appearing once
35+
Arguments.of(new int[] {10, 10, 20, 20, 30}, 30),
36+
37+
// Negative numbers with an odd occurrence
38+
Arguments.of(new int[] {-5, -5, -3, -3, -7, -7, -7}, -7),
1339

14-
int[] arr2 = {2, 3, 5, 4, 5, 2, 4, 3, 5, 2, 4, 4, 2};
15-
assertEquals(5, NumberAppearingOddTimes.findOddOccurrence(arr2));
40+
// All elements cancel out to 0 (even occurrences of all elements)
41+
Arguments.of(new int[] {1, 2, 1, 2}, 0),
1642

17-
int[] arr3 = {10, 10, 20, 20, 30};
18-
assertEquals(30, NumberAppearingOddTimes.findOddOccurrence(arr3));
43+
// Array with a single element (trivial case)
44+
Arguments.of(new int[] {42}, 42),
1945

20-
int[] arr4 = {-5, -5, -3, -3, -7, -7, -7};
21-
assertEquals(-7, NumberAppearingOddTimes.findOddOccurrence(arr4));
46+
// Large array with repeated patterns
47+
Arguments.of(new int[] {1, 1, 2, 2, 3, 3, 3, 4, 4}, 3));
2248
}
2349
}

‎src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,44 @@
33
import static org.junit.jupiter.api.Assertions.assertFalse;
44
import static org.junit.jupiter.api.Assertions.assertTrue;
55

6-
import org.junit.jupiter.api.Test;
6+
import java.util.stream.Stream;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
10+
711
/**
8-
* test Cases of Numbers Different Signs
12+
* Parameterized tests for NumbersDifferentSigns class, which checks
13+
* if two integers have different signs using bitwise XOR.
14+
*
915
* @author Bama Charan Chhandogi
1016
*/
1117
class NumbersDifferentSignsTest {
1218

13-
@Test
14-
void testDifferentSignsPositiveNegative() {
15-
assertTrue(NumbersDifferentSigns.differentSigns(2, -1));
19+
@ParameterizedTest
20+
@MethodSource("provideTestCases")
21+
void testDifferentSigns(int num1, int num2, boolean expected) {
22+
if (expected) {
23+
assertTrue(NumbersDifferentSigns.differentSigns(num1, num2));
24+
} else {
25+
assertFalse(NumbersDifferentSigns.differentSigns(num1, num2));
26+
}
1627
}
1728

18-
@Test
19-
void testDifferentSignsNegativePositive() {
20-
assertTrue(NumbersDifferentSigns.differentSigns(-3, 7));
21-
}
29+
private static Stream<Arguments> provideTestCases() {
30+
return Stream.of(
31+
// Different signs (positive and negative)
32+
Arguments.of(2, -1, Boolean.TRUE), Arguments.of(-3, 7, Boolean.TRUE),
2233

23-
@Test
24-
void testSameSignsPositive() {
25-
assertFalse(NumbersDifferentSigns.differentSigns(10, 20));
26-
}
34+
// Same signs (both positive)
35+
Arguments.of(10, 20, Boolean.FALSE), Arguments.of(0, 5, Boolean.FALSE), // 0 is considered non-negative
36+
37+
// Same signs (both negative)
38+
Arguments.of(-5, -8, Boolean.FALSE),
39+
40+
// Edge case: Large positive and negative values
41+
Arguments.of(Integer.MAX_VALUE, Integer.MIN_VALUE, Boolean.TRUE),
2742

28-
@Test
29-
void testSameSignsNegative() {
30-
assertFalse(NumbersDifferentSigns.differentSigns(-5, -8));
43+
// Edge case: Same number (positive and negative)
44+
Arguments.of(-42, -42, Boolean.FALSE), Arguments.of(42, 42, Boolean.FALSE));
3145
}
3246
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.thealgorithms.bitmanipulation;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.CsvSource;
7+
8+
public class OneBitDifferenceTest {
9+
10+
@ParameterizedTest
11+
@CsvSource({"7, 5, true", "3, 2, true", "10, 8, true", "15, 15, false", "4, 1, false"})
12+
void testDifferByOneBit(int x, int y, boolean expected) {
13+
assertEquals(expected, OneBitDifference.differByOneBit(x, y));
14+
}
15+
}

‎src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,60 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5-
import org.junit.jupiter.api.Test;
5+
import java.util.stream.Stream;
6+
import org.junit.jupiter.params.ParameterizedTest;
7+
import org.junit.jupiter.params.provider.Arguments;
8+
import org.junit.jupiter.params.provider.MethodSource;
69

7-
public class SingleBitOperationsTest {
10+
class SingleBitOperationsTest {
811

9-
@Test
10-
public void flipBitTest() {
11-
assertEquals(1, SingleBitOperations.flipBit(3, 1));
12-
assertEquals(11, SingleBitOperations.flipBit(3, 3));
12+
@ParameterizedTest
13+
@MethodSource("provideFlipBitTestCases")
14+
void testFlipBit(int input, int bit, int expected) {
15+
assertEquals(expected, SingleBitOperations.flipBit(input, bit));
1316
}
1417

15-
@Test
16-
public void setBitTest() {
17-
assertEquals(5, SingleBitOperations.setBit(4, 0));
18-
assertEquals(4, SingleBitOperations.setBit(4, 2));
19-
assertEquals(5, SingleBitOperations.setBit(5, 0));
20-
assertEquals(14, SingleBitOperations.setBit(10, 2));
21-
assertEquals(15, SingleBitOperations.setBit(15, 3));
22-
assertEquals(2, SingleBitOperations.setBit(0, 1));
18+
private static Stream<Arguments> provideFlipBitTestCases() {
19+
return Stream.of(Arguments.of(3, 1, 1), // Binary: 11 -> 01
20+
Arguments.of(3, 3, 11) // Binary: 11 -> 1011
21+
);
2322
}
2423

25-
@Test
26-
public void clearBitTest() {
27-
assertEquals(5, SingleBitOperations.clearBit(7, 1));
28-
assertEquals(5, SingleBitOperations.clearBit(5, 1));
24+
@ParameterizedTest
25+
@MethodSource("provideSetBitTestCases")
26+
void testSetBit(int input, int bit, int expected) {
27+
assertEquals(expected, SingleBitOperations.setBit(input, bit));
2928
}
3029

31-
@Test
32-
public void getBitTest() {
33-
assertEquals(0, SingleBitOperations.getBit(6, 0));
34-
assertEquals(1, SingleBitOperations.getBit(7, 1));
30+
private static Stream<Arguments> provideSetBitTestCases() {
31+
return Stream.of(Arguments.of(4, 0, 5), // 100 -> 101
32+
Arguments.of(4, 2, 4), // 100 -> 100 (bit already set)
33+
Arguments.of(0, 1, 2), // 00 -> 10
34+
Arguments.of(10, 2, 14) // 1010 -> 1110
35+
);
36+
}
37+
38+
@ParameterizedTest
39+
@MethodSource("provideClearBitTestCases")
40+
void testClearBit(int input, int bit, int expected) {
41+
assertEquals(expected, SingleBitOperations.clearBit(input, bit));
42+
}
43+
44+
private static Stream<Arguments> provideClearBitTestCases() {
45+
return Stream.of(Arguments.of(7, 1, 5), // 111 -> 101
46+
Arguments.of(5, 1, 5) // 101 -> 101 (bit already cleared)
47+
);
48+
}
49+
50+
@ParameterizedTest
51+
@MethodSource("provideGetBitTestCases")
52+
void testGetBit(int input, int bit, int expected) {
53+
assertEquals(expected, SingleBitOperations.getBit(input, bit));
54+
}
55+
56+
private static Stream<Arguments> provideGetBitTestCases() {
57+
return Stream.of(Arguments.of(6, 0, 0), // 110 -> Bit 0: 0
58+
Arguments.of(7, 1, 1) // 111 -> Bit 1: 1
59+
);
3560
}
3661
}
Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.thealgorithms.bitmanipulation;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
45

56
import org.junit.jupiter.api.Test;
67

@@ -12,7 +13,6 @@ public class TwosComplementTest {
1213

1314
@Test
1415
public void testTwosComplementAllZeroes() {
15-
// Test with a binary number consisting entirely of zeroes
1616
assertEquals("10000", TwosComplement.twosComplement("0000"));
1717
assertEquals("1000", TwosComplement.twosComplement("000"));
1818
assertEquals("100", TwosComplement.twosComplement("00"));
@@ -21,7 +21,6 @@ public void testTwosComplementAllZeroes() {
2121

2222
@Test
2323
public void testTwosComplementAllOnes() {
24-
// Test with a binary number consisting entirely of ones
2524
assertEquals("00001", TwosComplement.twosComplement("11111"));
2625
assertEquals("0001", TwosComplement.twosComplement("1111"));
2726
assertEquals("001", TwosComplement.twosComplement("111"));
@@ -30,25 +29,36 @@ public void testTwosComplementAllOnes() {
3029

3130
@Test
3231
public void testTwosComplementMixedBits() {
33-
// Test with binary numbers with mixed bits
34-
assertEquals("1111", TwosComplement.twosComplement("0001")); // 1's complement: 1110, then add 1: 1111
35-
assertEquals("1001", TwosComplement.twosComplement("0111")); // 1's complement: 1000
36-
assertEquals("11001", TwosComplement.twosComplement("00111")); // 1's complement: 11000, add 1: 11001
37-
assertEquals("011", TwosComplement.twosComplement("101")); // 1's complement: 010, add 1: 011
32+
assertEquals("1111", TwosComplement.twosComplement("0001")); // 1 -> 1111
33+
assertEquals("1001", TwosComplement.twosComplement("0111")); // 0111 -> 1001
34+
assertEquals("11001", TwosComplement.twosComplement("00111")); // 00111 -> 11001
35+
assertEquals("011", TwosComplement.twosComplement("101")); // 101 -> 011
3836
}
3937

4038
@Test
4139
public void testTwosComplementSingleBit() {
42-
// Test with single bit
43-
assertEquals("10", TwosComplement.twosComplement("0"));
44-
assertEquals("1", TwosComplement.twosComplement("1"));
40+
assertEquals("10", TwosComplement.twosComplement("0")); // 0 -> 10
41+
assertEquals("1", TwosComplement.twosComplement("1")); // 1 -> 1
4542
}
4643

4744
@Test
4845
public void testTwosComplementWithLeadingZeroes() {
49-
// Test with leading zeroes in the input
50-
assertEquals("1111", TwosComplement.twosComplement("0001"));
51-
assertEquals("101", TwosComplement.twosComplement("011"));
52-
assertEquals("110", TwosComplement.twosComplement("010"));
46+
assertEquals("1111", TwosComplement.twosComplement("0001")); // 0001 -> 1111
47+
assertEquals("101", TwosComplement.twosComplement("011")); // 011 -> 101
48+
assertEquals("110", TwosComplement.twosComplement("010")); // 010 -> 110
49+
}
50+
51+
@Test
52+
public void testInvalidBinaryInput() {
53+
// Test for invalid input that contains non-binary characters.
54+
assertThrows(IllegalArgumentException.class, () -> TwosComplement.twosComplement("102"));
55+
assertThrows(IllegalArgumentException.class, () -> TwosComplement.twosComplement("abc"));
56+
assertThrows(IllegalArgumentException.class, () -> TwosComplement.twosComplement("10a01"));
57+
}
58+
59+
@Test
60+
public void testEmptyInput() {
61+
// Edge case: Empty input should result in an IllegalArgumentException.
62+
assertThrows(IllegalArgumentException.class, () -> TwosComplement.twosComplement(""));
5363
}
5464
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.thealgorithms.conversions;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import java.net.UnknownHostException;
7+
import org.junit.jupiter.api.Test;
8+
9+
public class IPv6ConverterTest {
10+
11+
private static final String VALID_IPV4 = "192."
12+
+ "0."
13+
+ "2."
14+
+ "128";
15+
private static final String EXPECTED_IPV6_MAPPED = ":"
16+
+ ":ff"
17+
+ "ff"
18+
+ ":19"
19+
+ "2."
20+
+ "0."
21+
+ "2.128";
22+
private static final String INVALID_IPV6_MAPPED = "2001:"
23+
+ "db8"
24+
+ ":"
25+
+ ":1";
26+
private static final String INVALID_IPV4 = "999."
27+
+ "999."
28+
+ "999."
29+
+ "999";
30+
private static final String INVALID_IPV6_FORMAT = "invalid:ipv6"
31+
+ "::address";
32+
private static final String EMPTY_STRING = "";
33+
34+
@Test
35+
public void testIpv4ToIpv6ValidInput() throws UnknownHostException {
36+
String actualIpv6 = IPv6Converter.ipv4ToIpv6(VALID_IPV4);
37+
assertEquals(EXPECTED_IPV6_MAPPED, actualIpv6);
38+
}
39+
40+
@Test
41+
public void testIpv6ToIpv4InvalidIPv6MappedAddress() {
42+
assertThrows(IllegalArgumentException.class, () -> IPv6Converter.ipv6ToIpv4(INVALID_IPV6_MAPPED));
43+
}
44+
45+
@Test
46+
public void testIpv4ToIpv6InvalidIPv4Address() {
47+
assertThrows(UnknownHostException.class, () -> IPv6Converter.ipv4ToIpv6(INVALID_IPV4));
48+
}
49+
50+
@Test
51+
public void testIpv6ToIpv4InvalidFormat() {
52+
assertThrows(UnknownHostException.class, () -> IPv6Converter.ipv6ToIpv4(INVALID_IPV6_FORMAT));
53+
}
54+
55+
@Test
56+
public void testIpv4ToIpv6EmptyString() {
57+
assertThrows(UnknownHostException.class, () -> IPv6Converter.ipv4ToIpv6(EMPTY_STRING));
58+
}
59+
60+
@Test
61+
public void testIpv6ToIpv4EmptyString() {
62+
assertThrows(IllegalArgumentException.class, () -> IPv6Converter.ipv6ToIpv4(EMPTY_STRING));
63+
}
64+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.thealgorithms.datastructures.heaps;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class KthElementFinderTest {
8+
@Test
9+
public void testFindKthLargest() {
10+
int[] nums = {3, 2, 1, 5, 6, 4};
11+
assertEquals(5, KthElementFinder.findKthLargest(nums, 2));
12+
}
13+
14+
@Test
15+
public void testFindKthSmallest() {
16+
int[] nums = {7, 10, 4, 3, 20, 15};
17+
assertEquals(7, KthElementFinder.findKthSmallest(nums, 3));
18+
}
19+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.thealgorithms.datastructures.heaps;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class MedianFinderTest {
8+
@Test
9+
public void testMedianMaintenance() {
10+
MedianFinder mf = new MedianFinder();
11+
mf.addNum(1);
12+
mf.addNum(2);
13+
assertEquals(1.5, mf.findMedian());
14+
mf.addNum(3);
15+
assertEquals(2.0, mf.findMedian());
16+
}
17+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.thealgorithms.datastructures.stacks;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertTrue;
5+
6+
import java.util.Stack;
7+
import org.junit.jupiter.api.Test;
8+
9+
class ReverseStackTest {
10+
11+
@Test
12+
void testReverseEmptyStack() {
13+
Stack<Integer> stack = new Stack<>();
14+
ReverseStack.reverseStack(stack);
15+
assertTrue(stack.isEmpty(), "Reversing an empty stack should result in an empty stack.");
16+
}
17+
18+
@Test
19+
void testReverseSingleElementStack() {
20+
Stack<Integer> stack = new Stack<>();
21+
stack.push(1);
22+
ReverseStack.reverseStack(stack);
23+
assertEquals(1, stack.peek(), "Reversing a single-element stack should have the same element on top.");
24+
}
25+
26+
@Test
27+
void testReverseTwoElementStack() {
28+
Stack<Integer> stack = new Stack<>();
29+
stack.push(1);
30+
stack.push(2);
31+
ReverseStack.reverseStack(stack);
32+
33+
assertEquals(1, stack.pop(), "After reversal, the stack's top element should be the first inserted element.");
34+
assertEquals(2, stack.pop(), "After reversal, the stack's next element should be the second inserted element.");
35+
}
36+
37+
@Test
38+
void testReverseMultipleElementsStack() {
39+
Stack<Integer> stack = new Stack<>();
40+
stack.push(1);
41+
stack.push(2);
42+
stack.push(3);
43+
stack.push(4);
44+
45+
ReverseStack.reverseStack(stack);
46+
47+
assertEquals(1, stack.pop(), "Stack order after reversal should match the initial push order.");
48+
assertEquals(2, stack.pop());
49+
assertEquals(3, stack.pop());
50+
assertEquals(4, stack.pop());
51+
}
52+
53+
@Test
54+
void testReverseStackAndVerifySize() {
55+
Stack<Integer> stack = new Stack<>();
56+
stack.push(10);
57+
stack.push(20);
58+
stack.push(30);
59+
stack.push(40);
60+
int originalSize = stack.size();
61+
62+
ReverseStack.reverseStack(stack);
63+
64+
assertEquals(originalSize, stack.size(), "Stack size should remain unchanged after reversal.");
65+
assertEquals(10, stack.pop(), "Reversal should place the first inserted element on top.");
66+
assertEquals(20, stack.pop());
67+
assertEquals(30, stack.pop());
68+
assertEquals(40, stack.pop());
69+
}
70+
}

0 commit comments

Comments
 (0)
Please sign in to comment.