Skip to content

Commit 15f1f84

Browse files
authored
Merge branch 'master' into SMJI/stack/min_max_const_time
2 parents 4e13a21 + e291516 commit 15f1f84

File tree

7 files changed

+312
-60
lines changed

7 files changed

+312
-60
lines changed

DIRECTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,9 @@
598598
* [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java)
599599
* [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java)
600600
* [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java)
601+
* [PostfixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixEvaluator.java)
601602
* [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java)
603+
* [PrefixEvaluator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixEvaluator.java)
602604
* [PrefixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PrefixToInfix.java)
603605
* [SortStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/SortStack.java)
604606
* [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java)
@@ -1128,7 +1130,9 @@
11281130
* [LargestRectangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/LargestRectangleTest.java)
11291131
* [NextGreaterElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextGreaterElementTest.java)
11301132
* [NextSmallerElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/NextSmallerElementTest.java)
1133+
* [PostfixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixEvaluatorTest.java)
11311134
* [PostfixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PostfixToInfixTest.java)
1135+
* [PrefixEvaluatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixEvaluatorTest.java)
11321136
* [PrefixToInfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/PrefixToInfixTest.java)
11331137
* [SortStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/SortStackTest.java)
11341138
* [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java)

src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,80 @@
11
package com.thealgorithms.bitmanipulation;
22

33
/**
4-
* This class provides methods to convert between BCD (Binary-Coded Decimal) and binary.
4+
* This class provides methods to convert between BCD (Binary-Coded Decimal) and decimal numbers.
55
*
6-
* Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of binary digits, usually four or eight.
6+
* BCD is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of binary digits, usually four or eight.
77
*
88
* For more information, refer to the
99
* <a href="https://en.wikipedia.org/wiki/Binary-coded_decimal">Binary-Coded Decimal</a> Wikipedia page.
1010
*
1111
* <b>Example usage:</b>
1212
* <pre>
13-
* int binary = BcdConversion.bcdToBinary(0x1234);
14-
* System.out.println("BCD 0x1234 to binary: " + binary); // Output: 1234
13+
* int decimal = BcdConversion.bcdToDecimal(0x1234);
14+
* System.out.println("BCD 0x1234 to decimal: " + decimal); // Output: 1234
1515
*
16-
* int bcd = BcdConversion.binaryToBcd(1234);
17-
* System.out.println("Binary 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
16+
* int bcd = BcdConversion.decimalToBcd(1234);
17+
* System.out.println("Decimal 1234 to BCD: " + Integer.toHexString(bcd)); // Output: 0x1234
1818
* </pre>
1919
*/
2020
public final class BcdConversion {
2121
private BcdConversion() {
2222
}
23+
2324
/**
24-
* Converts a BCD (Binary-Coded Decimal) number to binary.
25+
* Converts a BCD (Binary-Coded Decimal) number to a decimal number.
26+
* <p>Steps:
27+
* <p>1. Validate the BCD number to ensure all digits are between 0 and 9.
28+
* <p>2. Extract the last 4 bits (one BCD digit) from the BCD number.
29+
* <p>3. Multiply the extracted digit by the corresponding power of 10 and add it to the decimal number.
30+
* <p>4. Shift the BCD number right by 4 bits to process the next BCD digit.
31+
* <p>5. Repeat steps 1-4 until the BCD number is zero.
2532
*
2633
* @param bcd The BCD number.
27-
* @return The corresponding binary number.
34+
* @return The corresponding decimal number.
35+
* @throws IllegalArgumentException if the BCD number contains invalid digits.
2836
*/
29-
public static int bcdToBinary(int bcd) {
30-
int binary = 0;
37+
public static int bcdToDecimal(int bcd) {
38+
int decimal = 0;
3139
int multiplier = 1;
40+
41+
// Validate BCD digits
3242
while (bcd > 0) {
33-
int digit = bcd & 0xF; // Extract the last 4 bits (one BCD digit)
34-
binary += digit * multiplier;
43+
int digit = bcd & 0xF;
44+
if (digit > 9) {
45+
throw new IllegalArgumentException("Invalid BCD digit: " + digit);
46+
}
47+
decimal += digit * multiplier;
3548
multiplier *= 10;
36-
bcd >>= 4; // Shift right by 4 bits to process the next BCD digit
49+
bcd >>= 4;
3750
}
38-
return binary;
51+
return decimal;
3952
}
4053

4154
/**
42-
* Converts a binary number to BCD (Binary-Coded Decimal).
55+
* Converts a decimal number to BCD (Binary-Coded Decimal).
56+
* <p>Steps:
57+
* <p>1. Check if the decimal number is within the valid range for BCD (0 to 9999).
58+
* <p>2. Extract the last decimal digit from the decimal number.
59+
* <p>3. Shift the digit to the correct BCD position and add it to the BCD number.
60+
* <p>4. Remove the last decimal digit from the decimal number.
61+
* <p>5. Repeat steps 2-4 until the decimal number is zero.
4362
*
44-
* @param binary The binary number.
63+
* @param decimal The decimal number.
4564
* @return The corresponding BCD number.
65+
* @throws IllegalArgumentException if the decimal number is greater than 9999.
4666
*/
47-
public static int binaryToBcd(int binary) {
67+
public static int decimalToBcd(int decimal) {
68+
if (decimal < 0 || decimal > 9999) {
69+
throw new IllegalArgumentException("Value out of bounds for BCD representation: " + decimal);
70+
}
71+
4872
int bcd = 0;
4973
int shift = 0;
50-
while (binary > 0) {
51-
int digit = binary % 10; // Extract the last decimal digit
52-
bcd |= (digit << (shift * 4)); // Shift the digit to the correct BCD position
53-
binary /= 10; // Remove the last decimal digit
74+
while (decimal > 0) {
75+
int digit = decimal % 10;
76+
bcd |= (digit << (shift * 4));
77+
decimal /= 10;
5478
shift++;
5579
}
5680
return bcd;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.thealgorithms.stacks;
2+
3+
import java.util.Set;
4+
import java.util.Stack;
5+
6+
/**
7+
* Evaluate a postfix (Reverse Polish) expression using a stack.
8+
*
9+
* <p>Example: Expression "5 6 + 2 *" results in 22.
10+
* <p>Applications: Used in calculators and expression evaluation in compilers.
11+
*
12+
* @author Hardvan
13+
*/
14+
public final class PostfixEvaluator {
15+
private PostfixEvaluator() {
16+
}
17+
18+
private static final Set<String> OPERATORS = Set.of("+", "-", "*", "/");
19+
20+
/**
21+
* Evaluates the given postfix expression and returns the result.
22+
*
23+
* @param expression The postfix expression as a string with operands and operators separated by spaces.
24+
* @return The result of evaluating the postfix expression.
25+
* @throws IllegalArgumentException if the expression is invalid.
26+
*/
27+
public static int evaluatePostfix(String expression) {
28+
Stack<Integer> stack = new Stack<>();
29+
30+
for (String token : expression.split("\\s+")) {
31+
if (isOperator(token)) {
32+
int operand2 = stack.pop();
33+
int operand1 = stack.pop();
34+
stack.push(applyOperator(token, operand1, operand2));
35+
} else {
36+
stack.push(Integer.valueOf(token));
37+
}
38+
}
39+
40+
if (stack.size() != 1) {
41+
throw new IllegalArgumentException("Invalid expression");
42+
}
43+
44+
return stack.pop();
45+
}
46+
47+
/**
48+
* Checks if the given token is an operator.
49+
*
50+
* @param token The token to check.
51+
* @return true if the token is an operator, false otherwise.
52+
*/
53+
private static boolean isOperator(String token) {
54+
return OPERATORS.contains(token);
55+
}
56+
57+
/**
58+
* Applies the given operator to the two operands.
59+
*
60+
* @param operator The operator to apply.
61+
* @param a The first operand.
62+
* @param b The second operand.
63+
* @return The result of applying the operator to the operands.
64+
*/
65+
private static int applyOperator(String operator, int a, int b) {
66+
return switch (operator) {
67+
case "+" -> a + b;
68+
case "-" -> a - b;
69+
case "*" -> a * b;
70+
case "/" -> a / b;
71+
default -> throw new IllegalArgumentException("Invalid operator");
72+
};
73+
}
74+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.thealgorithms.stacks;
2+
3+
import java.util.Set;
4+
import java.util.Stack;
5+
6+
/**
7+
* Evaluate a prefix (Polish) expression using a stack.
8+
*
9+
* <p>Example: Expression "+ * 2 3 4" results in 10.
10+
* <p>Applications: Useful for implementing compilers and interpreters.
11+
*
12+
* @author Hardvan
13+
*/
14+
public final class PrefixEvaluator {
15+
private PrefixEvaluator() {
16+
}
17+
18+
private static final Set<String> OPERATORS = Set.of("+", "-", "*", "/");
19+
20+
/**
21+
* Evaluates the given prefix expression and returns the result.
22+
*
23+
* @param expression The prefix expression as a string with operands and operators separated by spaces.
24+
* @return The result of evaluating the prefix expression.
25+
* @throws IllegalArgumentException if the expression is invalid.
26+
*/
27+
public static int evaluatePrefix(String expression) {
28+
Stack<Integer> stack = new Stack<>();
29+
String[] tokens = expression.split("\\s+");
30+
31+
for (int i = tokens.length - 1; i >= 0; i--) {
32+
String token = tokens[i];
33+
if (isOperator(token)) {
34+
int operand1 = stack.pop();
35+
int operand2 = stack.pop();
36+
stack.push(applyOperator(token, operand1, operand2));
37+
} else {
38+
stack.push(Integer.valueOf(token));
39+
}
40+
}
41+
42+
if (stack.size() != 1) {
43+
throw new IllegalArgumentException("Invalid expression");
44+
}
45+
46+
return stack.pop();
47+
}
48+
49+
/**
50+
* Checks if the given token is an operator.
51+
*
52+
* @param token The token to check.
53+
* @return true if the token is an operator, false otherwise.
54+
*/
55+
private static boolean isOperator(String token) {
56+
return OPERATORS.contains(token);
57+
}
58+
59+
/**
60+
* Applies the given operator to the two operands.
61+
*
62+
* @param operator The operator to apply.
63+
* @param a The first operand.
64+
* @param b The second operand.
65+
* @return The result of applying the operator to the operands.
66+
*/
67+
private static int applyOperator(String operator, int a, int b) {
68+
return switch (operator) {
69+
case "+" -> a + b;
70+
case "-" -> a - b;
71+
case "*" -> a * b;
72+
case "/" -> a / b;
73+
default -> throw new IllegalArgumentException("Invalid operator");
74+
};
75+
}
76+
}
Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,85 @@
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

7-
/**
8-
* Unit tests for the BcdConversion class.
9-
*/
108
public class BcdConversionTest {
119

12-
/**
13-
* Test the bcdToBinary method with a BCD number.
14-
*/
1510
@Test
16-
public void testBcdToBinary() {
17-
int binary = BcdConversion.bcdToBinary(0x1234);
18-
assertEquals(1234, binary); // BCD 0x1234 should convert to binary 1234
11+
public void testBcdToDecimal() {
12+
int decimal = BcdConversion.bcdToDecimal(0x1234);
13+
assertEquals(1234, decimal); // BCD 0x1234 should convert to decimal 1234
1914
}
2015

21-
/**
22-
* Test the binaryToBcd method with a binary number.
23-
*/
2416
@Test
25-
public void testBinaryToBcd() {
26-
int bcd = BcdConversion.binaryToBcd(1234);
27-
assertEquals(0x1234, bcd); // Binary 1234 should convert to BCD 0x1234
17+
public void testDecimalToBcd() {
18+
int bcd = BcdConversion.decimalToBcd(1234);
19+
assertEquals(0x1234, bcd); // Decimal 1234 should convert to BCD 0x1234
2820
}
2921

30-
/**
31-
* Test the bcdToBinary method with zero.
32-
*/
3322
@Test
34-
public void testBcdToBinaryZero() {
35-
int binary = BcdConversion.bcdToBinary(0x0);
36-
assertEquals(0, binary); // BCD 0x0 should convert to binary 0
23+
public void testBcdToDecimalZero() {
24+
int decimal = BcdConversion.bcdToDecimal(0x0);
25+
assertEquals(0, decimal); // BCD 0x0 should convert to decimal 0
3726
}
3827

39-
/**
40-
* Test the binaryToBcd method with zero.
41-
*/
4228
@Test
43-
public void testBinaryToBcdZero() {
44-
int bcd = BcdConversion.binaryToBcd(0);
45-
assertEquals(0x0, bcd); // Binary 0 should convert to BCD 0x0
29+
public void testDecimalToBcdZero() {
30+
int bcd = BcdConversion.decimalToBcd(0);
31+
assertEquals(0x0, bcd); // Decimal 0 should convert to BCD 0x0
4632
}
4733

48-
/**
49-
* Test the bcdToBinary method with a single digit BCD number.
50-
*/
5134
@Test
52-
public void testBcdToBinarySingleDigit() {
53-
int binary = BcdConversion.bcdToBinary(0x7);
54-
assertEquals(7, binary); // BCD 0x7 should convert to binary 7
35+
public void testBcdToDecimalSingleDigit() {
36+
int decimal = BcdConversion.bcdToDecimal(0x7);
37+
assertEquals(7, decimal); // BCD 0x7 should convert to decimal 7
5538
}
5639

57-
/**
58-
* Test the binaryToBcd method with a single digit binary number.
59-
*/
6040
@Test
61-
public void testBinaryToBcdSingleDigit() {
62-
int bcd = BcdConversion.binaryToBcd(7);
63-
assertEquals(0x7, bcd); // Binary 7 should convert to BCD 0x7
41+
public void testDecimalToBcdSingleDigit() {
42+
int bcd = BcdConversion.decimalToBcd(7);
43+
assertEquals(0x7, bcd); // Decimal 7 should convert to BCD 0x7
44+
}
45+
46+
@Test
47+
public void testBcdToDecimalMaxValue() {
48+
int decimal = BcdConversion.bcdToDecimal(0x9999);
49+
assertEquals(9999, decimal); // BCD 0x9999 should convert to decimal 9999
50+
}
51+
52+
@Test
53+
public void testDecimalToBcdMaxValue() {
54+
int bcd = BcdConversion.decimalToBcd(9999);
55+
assertEquals(0x9999, bcd); // Decimal 9999 should convert to BCD 0x9999
56+
}
57+
58+
@Test
59+
public void testBcdToDecimalInvalidHighDigit() {
60+
// Testing invalid BCD input where one of the digits is > 9
61+
assertThrows(IllegalArgumentException.class, () -> {
62+
BcdConversion.bcdToDecimal(0x123A); // Invalid BCD, 'A' is not a valid digit
63+
});
64+
}
65+
66+
@Test
67+
public void testDecimalToBcdInvalidValue() {
68+
// Testing conversion for numbers greater than 9999, which cannot be represented in BCD
69+
assertThrows(IllegalArgumentException.class, () -> {
70+
BcdConversion.decimalToBcd(10000); // 10000 is too large for BCD representation
71+
});
72+
}
73+
74+
@Test
75+
public void testBcdToDecimalLeadingZeroes() {
76+
int decimal = BcdConversion.bcdToDecimal(0x0234);
77+
assertEquals(234, decimal); // BCD 0x0234 should convert to decimal 234, ignoring leading zero
78+
}
79+
80+
@Test
81+
public void testDecimalToBcdLeadingZeroes() {
82+
int bcd = BcdConversion.decimalToBcd(234);
83+
assertEquals(0x0234, bcd); // Decimal 234 should convert to BCD 0x0234
6484
}
6585
}

0 commit comments

Comments
 (0)