Skip to content

Commit a34e09e

Browse files
authored
Merge branch 'master' into master
2 parents fb37afe + a537654 commit a34e09e

File tree

9 files changed

+413
-22
lines changed

9 files changed

+413
-22
lines changed

DIRECTORY.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
* [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java)
7474
* [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java)
7575
* [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java)
76+
* [RailFenceCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RailFenceCipher.java)
7677
* [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java)
7778
* [SimpleSubCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java)
7879
* [Vigenere](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Vigenere.java)
@@ -260,6 +261,7 @@
260261
* [StrassenMatrixMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java)
261262
* [TilingProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/TilingProblem.java)
262263
* dynamicprogramming
264+
* [Abbreviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Abbreviation.java)
263265
* [BoardPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java)
264266
* [BoundaryFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java)
265267
* [BruteForceKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java)
@@ -318,6 +320,7 @@
318320
* [JobSequencing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java)
319321
* [MergeIntervals](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MergeIntervals.java)
320322
* [MinimizingLateness](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java)
323+
* [StockProfitCalculator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/StockProfitCalculator.java)
321324
* io
322325
* [BufferedReader](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/io/BufferedReader.java)
323326
* lineclipping
@@ -729,6 +732,7 @@
729732
* [HillCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/HillCipherTest.java)
730733
* [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java)
731734
* [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java)
735+
* [RailFenceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RailFenceTest.java)
732736
* [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java)
733737
* [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java)
734738
* [VigenereTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/VigenereTest.java)
@@ -860,6 +864,7 @@
860864
* [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java)
861865
* [TilingProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/TilingProblemTest.java)
862866
* dynamicprogramming
867+
* [AbbreviationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/AbbreviationTest.java)
863868
* [BoardPathTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoardPathTest.java)
864869
* [BoundaryFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BoundaryFillTest.java)
865870
* [BruteForceKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsackTest.java)
@@ -916,6 +921,7 @@
916921
* [JobSequencingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java)
917922
* [MergeIntervalsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MergeIntervalsTest.java)
918923
* [MinimizingLatenessTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java)
924+
* [StockProfitCalculatorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/StockProfitCalculatorTest.java)
919925
* io
920926
* [BufferedReaderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/io/BufferedReaderTest.java)
921927
* lineclipping
@@ -1033,6 +1039,7 @@
10331039
* [PalindromePrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromePrimeTest.java)
10341040
* [PalindromeSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java)
10351041
* [RangeInSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/RangeInSortedArrayTest.java)
1042+
* [SparsityTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/SparsityTest.java)
10361043
* [ThreeSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/ThreeSumProblemTest.java)
10371044
* [TwoSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java)
10381045
* [WordBoggleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/WordBoggleTest.java)
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* The rail fence cipher (also called a zigzag cipher) is a classical type of transposition cipher.
7+
* It derives its name from the manner in which encryption is performed, in analogy to a fence built with horizontal rails.
8+
* https://en.wikipedia.org/wiki/Rail_fence_cipher
9+
* @author https://github.com/Krounosity
10+
*/
11+
12+
public class RailFenceCipher {
13+
14+
// Encrypts the input string using the rail fence cipher method with the given number of rails.
15+
public String encrypt(String str, int rails) {
16+
17+
// Base case of single rail or rails are more than the number of characters in the string
18+
if (rails == 1 || rails >= str.length()) {
19+
return str;
20+
}
21+
22+
// Boolean flag to determine if the movement is downward or upward in the rail matrix.
23+
boolean down = true;
24+
// Create a 2D array to represent the rails (rows) and the length of the string (columns).
25+
char[][] strRail = new char[rails][str.length()];
26+
27+
// Initialize all positions in the rail matrix with a placeholder character ('\n').
28+
for (int i = 0; i < rails; i++) {
29+
Arrays.fill(strRail[i], '\n');
30+
}
31+
32+
int row = 0; // Start at the first row
33+
int col = 0; // Start at the first column
34+
35+
int i = 0;
36+
37+
// Fill the rail matrix with characters from the string based on the rail pattern.
38+
while (col < str.length()) {
39+
// Change direction to down when at the first row.
40+
if (row == 0) {
41+
down = true;
42+
}
43+
// Change direction to up when at the last row.
44+
else if (row == rails - 1) {
45+
down = false;
46+
}
47+
48+
// Place the character in the current position of the rail matrix.
49+
strRail[row][col] = str.charAt(i);
50+
col++; // Move to the next column.
51+
// Move to the next row based on the direction.
52+
if (down) {
53+
row++;
54+
} else {
55+
row--;
56+
}
57+
58+
i++;
59+
}
60+
61+
// Construct the encrypted string by reading characters row by row.
62+
StringBuilder encryptedString = new StringBuilder();
63+
for (char[] chRow : strRail) {
64+
for (char ch : chRow) {
65+
if (ch != '\n') {
66+
encryptedString.append(ch);
67+
}
68+
}
69+
}
70+
return encryptedString.toString();
71+
}
72+
// Decrypts the input string using the rail fence cipher method with the given number of rails.
73+
public String decrypt(String str, int rails) {
74+
75+
// Base case of single rail or rails are more than the number of characters in the string
76+
if (rails == 1 || rails >= str.length()) {
77+
return str;
78+
}
79+
// Boolean flag to determine if the movement is downward or upward in the rail matrix.
80+
boolean down = true;
81+
82+
// Create a 2D array to represent the rails (rows) and the length of the string (columns).
83+
char[][] strRail = new char[rails][str.length()];
84+
85+
int row = 0; // Start at the first row
86+
int col = 0; // Start at the first column
87+
88+
// Mark the pattern on the rail matrix using '*'.
89+
while (col < str.length()) {
90+
// Change direction to down when at the first row.
91+
if (row == 0) {
92+
down = true;
93+
}
94+
// Change direction to up when at the last row.
95+
else if (row == rails - 1) {
96+
down = false;
97+
}
98+
99+
// Mark the current position in the rail matrix.
100+
strRail[row][col] = '*';
101+
col++; // Move to the next column.
102+
// Move to the next row based on the direction.
103+
if (down) {
104+
row++;
105+
} else {
106+
row--;
107+
}
108+
}
109+
110+
int index = 0; // Index to track characters from the input string.
111+
// Fill the rail matrix with characters from the input string based on the marked pattern.
112+
for (int i = 0; i < rails; i++) {
113+
for (int j = 0; j < str.length(); j++) {
114+
if (strRail[i][j] == '*') {
115+
strRail[i][j] = str.charAt(index++);
116+
}
117+
}
118+
}
119+
120+
// Construct the decrypted string by following the zigzag pattern.
121+
StringBuilder decryptedString = new StringBuilder();
122+
row = 0; // Reset to the first row
123+
col = 0; // Reset to the first column
124+
125+
while (col < str.length()) {
126+
// Change direction to down when at the first row.
127+
if (row == 0) {
128+
down = true;
129+
}
130+
// Change direction to up when at the last row.
131+
else if (row == rails - 1) {
132+
down = false;
133+
}
134+
// Append the character from the rail matrix to the decrypted string.
135+
decryptedString.append(strRail[row][col]);
136+
col++; // Move to the next column.
137+
// Move to the next row based on the direction.
138+
if (down) {
139+
row++;
140+
} else {
141+
row--;
142+
}
143+
}
144+
145+
return decryptedString.toString();
146+
}
147+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package com.thealgorithms.dynamicprogramming;
2+
3+
/**
4+
* A class that provides a solution to the abbreviation problem.
5+
*
6+
* Problem: Given two strings, `a` and `b`, determine if string `a` can be
7+
* transformed into string `b` by performing the following operations:
8+
* 1. Capitalize zero or more of `a`'s lowercase letters (i.e., convert them to uppercase).
9+
* 2. Delete any of the remaining lowercase letters from `a`.
10+
*
11+
* The task is to determine whether it is possible to make string `a` equal to string `b`.
12+
*
13+
* @author Hardvan
14+
*/
15+
public final class Abbreviation {
16+
private Abbreviation() {
17+
}
18+
19+
/**
20+
* Determines if string `a` can be transformed into string `b` by capitalizing
21+
* some of its lowercase letters and deleting the rest.
22+
*
23+
* @param a The input string which may contain both uppercase and lowercase letters.
24+
* @param b The target string containing only uppercase letters.
25+
* @return {@code true} if string `a` can be transformed into string `b`,
26+
* {@code false} otherwise.
27+
*
28+
* Time Complexity: O(n * m) where n = length of string `a` and m = length of string `b`.
29+
* Space Complexity: O(n * m) due to the dynamic programming table.
30+
*/
31+
public static boolean abbr(String a, String b) {
32+
int n = a.length();
33+
int m = b.length();
34+
35+
boolean[][] dp = new boolean[n + 1][m + 1];
36+
37+
dp[0][0] = true;
38+
39+
for (int i = 0; i < n; i++) {
40+
for (int j = 0; j <= m; j++) {
41+
if (dp[i][j]) {
42+
// Case 1: If the current characters match (or can be capitalized to match)
43+
if (j < m && Character.toUpperCase(a.charAt(i)) == b.charAt(j)) {
44+
dp[i + 1][j + 1] = true;
45+
}
46+
// Case 2: If the character in `a` is lowercase, we can skip it
47+
if (Character.isLowerCase(a.charAt(i))) {
48+
dp[i + 1][j] = true;
49+
}
50+
}
51+
}
52+
}
53+
54+
return dp[n][m];
55+
}
56+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.thealgorithms.greedyalgorithms;
2+
3+
/**
4+
* The StockProfitCalculator class provides a method to calculate the maximum profit
5+
* that can be made from a single buy and sell of one share of stock.
6+
* The approach uses a greedy algorithm to efficiently determine the maximum profit.
7+
*
8+
* @author Hardvan
9+
*/
10+
public final class StockProfitCalculator {
11+
private StockProfitCalculator() {
12+
}
13+
14+
/**
15+
* Calculates the maximum profit from a list of stock prices.
16+
*
17+
* @param prices an array of integers representing the stock prices on different days
18+
* @return the maximum profit that can be achieved from a single buy and sell
19+
* transaction, or 0 if no profit can be made
20+
*/
21+
public static int maxProfit(int[] prices) {
22+
if (prices == null || prices.length == 0) {
23+
return 0;
24+
}
25+
26+
int minPrice = prices[0];
27+
int maxProfit = 0;
28+
for (int price : prices) {
29+
minPrice = Math.min(price, minPrice);
30+
maxProfit = Math.max(price - minPrice, maxProfit);
31+
}
32+
return maxProfit;
33+
}
34+
}
Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.thealgorithms.misc;
22

3-
import java.util.Scanner;
4-
53
/*
64
*A matrix is sparse if many of its coefficients are zero (In general if 2/3rd of matrix elements
75
*are 0, it is considered as sparse). The interest in sparsity arises because its exploitation can
@@ -16,12 +14,17 @@ private Sparsity() {
1614
}
1715

1816
/*
17+
* @param mat the input matrix
1918
* @return Sparsity of matrix
2019
*
2120
* where sparsity = number of zeroes/total elements in matrix
2221
*
2322
*/
2423
static double sparsity(double[][] mat) {
24+
if (mat == null || mat.length == 0) {
25+
throw new IllegalArgumentException("Matrix cannot be null or empty");
26+
}
27+
2528
int zero = 0;
2629
// Traversing the matrix to count number of zeroes
2730
for (int i = 0; i < mat.length; i++) {
@@ -32,25 +35,6 @@ static double sparsity(double[][] mat) {
3235
}
3336
}
3437
// return sparsity
35-
return ((double) zero / (mat.length * mat[1].length));
36-
}
37-
38-
// Driver method
39-
public static void main(String[] args) {
40-
Scanner in = new Scanner(System.in);
41-
System.out.println("Enter number of rows in matrix: ");
42-
int n = in.nextInt();
43-
System.out.println("Enter number of Columns in matrix: ");
44-
int m = in.nextInt();
45-
46-
System.out.println("Enter Matrix elements: ");
47-
double[][] mat = new double[n][m];
48-
for (int i = 0; i < n; i++) {
49-
for (int j = 0; j < m; j++) {
50-
mat[i][j] = in.nextDouble();
51-
}
52-
}
53-
System.out.println("Sparsity of matrix is: " + sparsity(mat));
54-
in.close();
38+
return ((double) zero / (mat.length * mat[0].length));
5539
}
5640
}

0 commit comments

Comments
 (0)