parent
ad03086f54
commit
00282efd8b
@ -22,9 +22,7 @@ public class IIRFilter {
|
||||
*/
|
||||
public IIRFilter(int order) throws IllegalArgumentException {
|
||||
if (order < 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"order must be greater than zero"
|
||||
);
|
||||
throw new IllegalArgumentException("order must be greater than zero");
|
||||
}
|
||||
|
||||
this.order = order;
|
||||
@ -47,24 +45,19 @@ public class IIRFilter {
|
||||
* @throws IllegalArgumentException if {@code aCoeffs} or {@code bCoeffs} is
|
||||
* not of size {@code order}, or if {@code aCoeffs[0]} is 0.0
|
||||
*/
|
||||
public void setCoeffs(double[] aCoeffs, double[] bCoeffs)
|
||||
throws IllegalArgumentException {
|
||||
public void setCoeffs(double[] aCoeffs, double[] bCoeffs) throws IllegalArgumentException {
|
||||
if (aCoeffs.length != order) {
|
||||
throw new IllegalArgumentException(
|
||||
"aCoeffs must be of size " + order + ", got " + aCoeffs.length
|
||||
);
|
||||
"aCoeffs must be of size " + order + ", got " + aCoeffs.length);
|
||||
}
|
||||
|
||||
if (aCoeffs[0] == 0.0) {
|
||||
throw new IllegalArgumentException(
|
||||
"aCoeffs.get(0) must not be zero"
|
||||
);
|
||||
throw new IllegalArgumentException("aCoeffs.get(0) must not be zero");
|
||||
}
|
||||
|
||||
if (bCoeffs.length != order) {
|
||||
throw new IllegalArgumentException(
|
||||
"bCoeffs must be of size " + order + ", got " + bCoeffs.length
|
||||
);
|
||||
"bCoeffs must be of size " + order + ", got " + bCoeffs.length);
|
||||
}
|
||||
|
||||
for (int i = 0; i <= order; i++) {
|
||||
@ -84,8 +77,7 @@ public class IIRFilter {
|
||||
|
||||
// Process
|
||||
for (int i = 1; i <= order; i++) {
|
||||
result +=
|
||||
(coeffsB[i] * historyX[i - 1] - coeffsA[i] * historyY[i - 1]);
|
||||
result += (coeffsB[i] * historyX[i - 1] - coeffsA[i] * historyY[i - 1]);
|
||||
}
|
||||
result = (result + coeffsB[0] * sample) / coeffsA[0];
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
/** Author : Siddhant Swarup Mallick
|
||||
/**
|
||||
* Author : Siddhant Swarup Mallick
|
||||
* Github : https://github.com/siddhant2002
|
||||
*/
|
||||
|
||||
@ -15,13 +16,12 @@ public class AllPathsFromSourceToTarget {
|
||||
private int v;
|
||||
|
||||
// To store the paths from source to destination
|
||||
static List<List<Integer>> nm=new ArrayList<>();
|
||||
static List<List<Integer>> nm = new ArrayList<>();
|
||||
// adjacency list
|
||||
private ArrayList<Integer>[] adjList;
|
||||
|
||||
// Constructor
|
||||
public AllPathsFromSourceToTarget(int vertices)
|
||||
{
|
||||
public AllPathsFromSourceToTarget(int vertices) {
|
||||
|
||||
// initialise vertex count
|
||||
this.v = vertices;
|
||||
@ -31,8 +31,7 @@ public class AllPathsFromSourceToTarget {
|
||||
}
|
||||
|
||||
// utility method to initialise adjacency list
|
||||
private void initAdjList()
|
||||
{
|
||||
private void initAdjList() {
|
||||
adjList = new ArrayList[v];
|
||||
|
||||
for (int i = 0; i < v; i++) {
|
||||
@ -41,15 +40,12 @@ public class AllPathsFromSourceToTarget {
|
||||
}
|
||||
|
||||
// add edge from u to v
|
||||
public void addEdge(int u, int v)
|
||||
{
|
||||
public void addEdge(int u, int v) {
|
||||
// Add v to u's list.
|
||||
adjList[u].add(v);
|
||||
}
|
||||
|
||||
|
||||
public void storeAllPaths(int s, int d)
|
||||
{
|
||||
public void storeAllPaths(int s, int d) {
|
||||
boolean[] isVisited = new boolean[v];
|
||||
ArrayList<Integer> pathList = new ArrayList<>();
|
||||
|
||||
@ -61,9 +57,9 @@ public class AllPathsFromSourceToTarget {
|
||||
|
||||
// A recursive function to print all paths from 'u' to 'd'.
|
||||
// isVisited[] keeps track of vertices in current path.
|
||||
// localPathList<> stores actual vertices in the current path
|
||||
private void storeAllPathsUtil(Integer u, Integer d, boolean[] isVisited, List<Integer> localPathList)
|
||||
{
|
||||
// localPathList<> stores actual vertices in the current path
|
||||
private void storeAllPathsUtil(
|
||||
Integer u, Integer d, boolean[] isVisited, List<Integer> localPathList) {
|
||||
|
||||
if (u.equals(d)) {
|
||||
nm.add(new ArrayList<>(localPathList));
|
||||
@ -74,7 +70,7 @@ public class AllPathsFromSourceToTarget {
|
||||
isVisited[u] = true;
|
||||
|
||||
// Recursion for all the vertices adjacent to current vertex
|
||||
|
||||
|
||||
for (Integer i : adjList[u]) {
|
||||
if (!isVisited[i]) {
|
||||
// store current node in path[]
|
||||
@ -91,12 +87,11 @@ public class AllPathsFromSourceToTarget {
|
||||
}
|
||||
|
||||
// Driver program
|
||||
public static List<List<Integer>> allPathsFromSourceToTarget(int vertices, int[][] a, int source, int destination)
|
||||
{
|
||||
public static List<List<Integer>> allPathsFromSourceToTarget(
|
||||
int vertices, int[][] a, int source, int destination) {
|
||||
// Create a sample graph
|
||||
AllPathsFromSourceToTarget g = new AllPathsFromSourceToTarget(vertices);
|
||||
for(int i=0 ; i<a.length ; i++)
|
||||
{
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
g.addEdge(a[i][0], a[i][1]);
|
||||
// edges are added
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class ArrayCombination {
|
||||
length = k;
|
||||
Integer[] arr = new Integer[n];
|
||||
for (int i = 1; i <= n; i++) {
|
||||
arr[i-1] = i;
|
||||
arr[i - 1] = i;
|
||||
}
|
||||
return Combination.combination(arr, length);
|
||||
}
|
||||
|
@ -38,11 +38,7 @@ public class Combination {
|
||||
* @param <T> the type of elements in the array.
|
||||
*/
|
||||
private static <T> void backtracking(
|
||||
T[] arr,
|
||||
int index,
|
||||
TreeSet<T> currSet,
|
||||
List<TreeSet<T>> result
|
||||
) {
|
||||
T[] arr, int index, TreeSet<T> currSet, List<TreeSet<T>> result) {
|
||||
if (index + length - currSet.size() > arr.length) return;
|
||||
if (length - 1 == currSet.size()) {
|
||||
for (int i = index; i < arr.length; i++) {
|
||||
|
@ -38,13 +38,7 @@ public class FloodFill {
|
||||
* @param newColor The new color which to be filled in the image
|
||||
* @param oldColor The old color which is to be replaced in the image
|
||||
*/
|
||||
public static void floodFill(
|
||||
int[][] image,
|
||||
int x,
|
||||
int y,
|
||||
int newColor,
|
||||
int oldColor
|
||||
) {
|
||||
public static void floodFill(int[][] image, int x, int y, int newColor, int oldColor) {
|
||||
if (x < 0 || x >= image.length) return;
|
||||
if (y < 0 || y >= image[x].length) return;
|
||||
if (getPixel(image, x, y) != oldColor) return;
|
||||
|
@ -4,9 +4,10 @@ import java.util.*;
|
||||
|
||||
/*
|
||||
* Problem Statement: -
|
||||
|
||||
Given a N*N board with the Knight placed on the first block of an empty board. Moving according to the rules of
|
||||
chess knight must visit each square exactly once. Print the order of each cell in which they are visited.
|
||||
|
||||
Given a N*N board with the Knight placed on the first block of an empty board. Moving according
|
||||
to the rules of chess knight must visit each square exactly once. Print the order of each cell in
|
||||
which they are visited.
|
||||
|
||||
Example: -
|
||||
|
||||
@ -27,14 +28,14 @@ public class KnightsTour {
|
||||
|
||||
private static final int base = 12;
|
||||
private static final int[][] moves = {
|
||||
{ 1, -2 },
|
||||
{ 2, -1 },
|
||||
{ 2, 1 },
|
||||
{ 1, 2 },
|
||||
{ -1, 2 },
|
||||
{ -2, 1 },
|
||||
{ -2, -1 },
|
||||
{ -1, -2 },
|
||||
{1, -2},
|
||||
{2, -1},
|
||||
{2, 1},
|
||||
{1, 2},
|
||||
{-1, 2},
|
||||
{-2, 1},
|
||||
{-2, -1},
|
||||
{-1, -2},
|
||||
}; // Possible moves by knight on chess
|
||||
private static int[][] grid; // chess grid
|
||||
private static int total; // total squares in chess
|
||||
@ -75,23 +76,17 @@ public class KnightsTour {
|
||||
return false;
|
||||
}
|
||||
|
||||
Collections.sort(
|
||||
neighbor,
|
||||
new Comparator<int[]>() {
|
||||
public int compare(int[] a, int[] b) {
|
||||
return a[2] - b[2];
|
||||
}
|
||||
Collections.sort(neighbor, new Comparator<int[]>() {
|
||||
public int compare(int[] a, int[] b) {
|
||||
return a[2] - b[2];
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
for (int[] nb : neighbor) {
|
||||
row = nb[0];
|
||||
column = nb[1];
|
||||
grid[row][column] = count;
|
||||
if (
|
||||
!orphanDetected(count, row, column) &&
|
||||
solve(row, column, count + 1)
|
||||
) {
|
||||
if (!orphanDetected(count, row, column) && solve(row, column, count + 1)) {
|
||||
return true;
|
||||
}
|
||||
grid[row][column] = 0;
|
||||
@ -109,7 +104,7 @@ public class KnightsTour {
|
||||
int y = m[1];
|
||||
if (grid[row + y][column + x] == 0) {
|
||||
int num = countNeighbors(row + y, column + x);
|
||||
neighbour.add(new int[] { row + y, column + x, num });
|
||||
neighbour.add(new int[] {row + y, column + x, num});
|
||||
}
|
||||
}
|
||||
return neighbour;
|
||||
|
@ -51,9 +51,7 @@ public class MazeRecursion {
|
||||
setWay2(map2, 1, 1);
|
||||
|
||||
// Print out the new map1, with the ball footprint
|
||||
System.out.println(
|
||||
"After the ball goes through the map1,show the current map1 condition"
|
||||
);
|
||||
System.out.println("After the ball goes through the map1,show the current map1 condition");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 7; j++) {
|
||||
System.out.print(map[i][j] + " ");
|
||||
@ -62,9 +60,7 @@ public class MazeRecursion {
|
||||
}
|
||||
|
||||
// Print out the new map2, with the ball footprint
|
||||
System.out.println(
|
||||
"After the ball goes through the map2,show the current map2 condition"
|
||||
);
|
||||
System.out.println("After the ball goes through the map2,show the current map2 condition");
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int j = 0; j < 7; j++) {
|
||||
System.out.print(map2[i][j] + " ");
|
||||
@ -85,7 +81,7 @@ public class MazeRecursion {
|
||||
* means the ball has gone through the path but this path is dead end
|
||||
* 5. We will need strategy for the ball to pass through the maze for example:
|
||||
* Down -> Right -> Up -> Left, if the path doesn't work, then backtrack
|
||||
*
|
||||
*
|
||||
* @author OngLipWei
|
||||
* @version Jun 23, 2021 11:36:14 AM
|
||||
* @param map The maze
|
||||
@ -99,7 +95,8 @@ public class MazeRecursion {
|
||||
}
|
||||
if (map[i][j] == 0) { // if the ball haven't gone through this point
|
||||
// then the ball follows the move strategy : down -> right -> up -> left
|
||||
map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2 first。
|
||||
map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2
|
||||
// first。
|
||||
if (setWay(map, i + 1, j)) { // go down
|
||||
return true;
|
||||
} else if (setWay(map, i, j + 1)) { // go right
|
||||
@ -129,7 +126,8 @@ public class MazeRecursion {
|
||||
}
|
||||
if (map[i][j] == 0) { // if the ball haven't gone through this point
|
||||
// then the ball follows the move strategy : up->right->down->left
|
||||
map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2 first。
|
||||
map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2
|
||||
// first。
|
||||
if (setWay2(map, i - 1, j)) { // go up
|
||||
return true;
|
||||
} else if (setWay2(map, i, j + 1)) { // go right
|
||||
|
@ -47,14 +47,8 @@ public class NQueens {
|
||||
List<List<String>> arrangements = new ArrayList<List<String>>();
|
||||
getSolution(queens, arrangements, new int[queens], 0);
|
||||
if (arrangements.isEmpty()) {
|
||||
System.out.println(
|
||||
"There is no way to place " +
|
||||
queens +
|
||||
" queens on board of size " +
|
||||
queens +
|
||||
"x" +
|
||||
queens
|
||||
);
|
||||
System.out.println("There is no way to place " + queens + " queens on board of size "
|
||||
+ queens + "x" + queens);
|
||||
} else {
|
||||
System.out.println("Arrangement for placing " + queens + " queens");
|
||||
}
|
||||
@ -73,11 +67,7 @@ public class NQueens {
|
||||
* @param columnIndex: This is the column in which queen is being placed
|
||||
*/
|
||||
private static void getSolution(
|
||||
int boardSize,
|
||||
List<List<String>> solutions,
|
||||
int[] columns,
|
||||
int columnIndex
|
||||
) {
|
||||
int boardSize, List<List<String>> solutions, int[] columns, int columnIndex) {
|
||||
if (columnIndex == boardSize) {
|
||||
// this means that all queens have been placed
|
||||
List<String> sol = new ArrayList<String>();
|
||||
@ -96,7 +86,8 @@ public class NQueens {
|
||||
for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) {
|
||||
columns[columnIndex] = rowIndex;
|
||||
if (isPlacedCorrectly(columns, rowIndex, columnIndex)) {
|
||||
// If queen is placed successfully at rowIndex in column=columnIndex then try placing queen in next column
|
||||
// If queen is placed successfully at rowIndex in column=columnIndex then try
|
||||
// placing queen in next column
|
||||
getSolution(boardSize, solutions, columns, columnIndex + 1);
|
||||
}
|
||||
}
|
||||
@ -111,11 +102,7 @@ public class NQueens {
|
||||
* @param columnIndex: column in which queen is being placed
|
||||
* @return true: if queen can be placed safely false: otherwise
|
||||
*/
|
||||
private static boolean isPlacedCorrectly(
|
||||
int[] columns,
|
||||
int rowIndex,
|
||||
int columnIndex
|
||||
) {
|
||||
private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) {
|
||||
for (int i = 0; i < columnIndex; i++) {
|
||||
int diff = Math.abs(columns[i] - rowIndex);
|
||||
if (diff == 0 || columnIndex - i == diff) {
|
||||
|
@ -1,11 +1,10 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
|
||||
/*
|
||||
* Problem Statement :
|
||||
* Find the number of ways that a given integer, N , can be expressed as the sum of the Xth powers of unique, natural numbers.
|
||||
* For example, if N=100 and X=3, we have to find all combinations of unique cubes adding up to 100. The only solution is 1^3+2^3+3^3+4^3.
|
||||
* Therefore output will be 1.
|
||||
* Find the number of ways that a given integer, N , can be expressed as the sum of the Xth powers
|
||||
* of unique, natural numbers. For example, if N=100 and X=3, we have to find all combinations of
|
||||
* unique cubes adding up to 100. The only solution is 1^3+2^3+3^3+4^3. Therefore output will be 1.
|
||||
*/
|
||||
public class PowerSum {
|
||||
|
||||
@ -16,26 +15,29 @@ public class PowerSum {
|
||||
return count;
|
||||
}
|
||||
|
||||
//here i is the natural number which will be raised by X and added in sum.
|
||||
// here i is the natural number which will be raised by X and added in sum.
|
||||
public void Sum(int N, int X, int i) {
|
||||
//if sum is equal to N that is one of our answer and count is increased.
|
||||
// if sum is equal to N that is one of our answer and count is increased.
|
||||
if (sum == N) {
|
||||
count++;
|
||||
return;
|
||||
} //we will be adding next natural number raised to X only if on adding it in sum the result is less than N.
|
||||
} // we will be adding next natural number raised to X only if on adding it in sum the
|
||||
// result is less than N.
|
||||
else if (sum + power(i, X) <= N) {
|
||||
sum += power(i, X);
|
||||
Sum(N, X, i + 1);
|
||||
//backtracking and removing the number added last since no possible combination is there with it.
|
||||
// backtracking and removing the number added last since no possible combination is
|
||||
// there with it.
|
||||
sum -= power(i, X);
|
||||
}
|
||||
if (power(i, X) < N) {
|
||||
//calling the sum function with next natural number after backtracking if when it is raised to X is still less than X.
|
||||
// calling the sum function with next natural number after backtracking if when it is
|
||||
// raised to X is still less than X.
|
||||
Sum(N, X, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
//creating a separate power function so that it can be used again and again when required.
|
||||
// creating a separate power function so that it can be used again and again when required.
|
||||
private int power(int a, int b) {
|
||||
return (int) Math.pow(a, b);
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package com.thealgorithms.backtracking;
|
||||
|
||||
|
||||
/*
|
||||
Word Search Problem (https://en.wikipedia.org/wiki/Word_search)
|
||||
|
||||
Given an m x n grid of characters board and a string word, return true if word exists in the grid.
|
||||
|
||||
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or
|
||||
vertically neighboring. The same letter cell may not be used more than once.
|
||||
The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are
|
||||
those horizontally or vertically neighboring. The same letter cell may not be used more than once.
|
||||
|
||||
For example,
|
||||
Given board =
|
||||
@ -27,8 +26,8 @@ word = "ABCB", -> returns false.
|
||||
Depth First Search in matrix (as multiple sources possible) with backtracking
|
||||
like finding cycle in a directed graph. Maintain a record of path
|
||||
|
||||
Tx = O(m * n * 3^L): for each cell, we look at 3 options (not 4 as that one will be visited), we do it L times
|
||||
Sx = O(L) : stack size is max L
|
||||
Tx = O(m * n * 3^L): for each cell, we look at 3 options (not 4 as that one will be visited), we
|
||||
do it L times Sx = O(L) : stack size is max L
|
||||
*/
|
||||
|
||||
public class WordSearch {
|
||||
@ -52,8 +51,7 @@ public class WordSearch {
|
||||
int yi = y + dy[i];
|
||||
if (isValid(xi, yi) && board[xi][yi] == word.charAt(nextIdx) && !visited[xi][yi]) {
|
||||
boolean exists = doDFS(xi, yi, nextIdx + 1);
|
||||
if (exists)
|
||||
return true;
|
||||
if (exists) return true;
|
||||
}
|
||||
}
|
||||
visited[x][y] = false;
|
||||
@ -68,12 +66,10 @@ public class WordSearch {
|
||||
if (board[i][j] == word.charAt(0)) {
|
||||
visited = new boolean[board.length][board[0].length];
|
||||
boolean exists = doDFS(i, j, 1);
|
||||
if (exists)
|
||||
return true;
|
||||
if (exists) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2395,9 +2395,7 @@ public class AES {
|
||||
|
||||
// apply S-Box to all 8-Bit Substrings
|
||||
for (int i = 0; i < 4; i++) {
|
||||
StringBuilder currentByteBits = new StringBuilder(
|
||||
rBytes.substring(i * 2, (i + 1) * 2)
|
||||
);
|
||||
StringBuilder currentByteBits = new StringBuilder(rBytes.substring(i * 2, (i + 1) * 2));
|
||||
|
||||
int currentByte = Integer.parseInt(currentByteBits.toString(), 16);
|
||||
currentByte = SBOX[currentByte];
|
||||
@ -2407,8 +2405,7 @@ public class AES {
|
||||
currentByte = currentByte ^ RCON[rconCounter];
|
||||
}
|
||||
|
||||
currentByteBits =
|
||||
new StringBuilder(Integer.toHexString(currentByte));
|
||||
currentByteBits = new StringBuilder(Integer.toHexString(currentByte));
|
||||
|
||||
// Add zero padding
|
||||
while (currentByteBits.length() < 2) {
|
||||
@ -2416,12 +2413,8 @@ public class AES {
|
||||
}
|
||||
|
||||
// replace bytes in original string
|
||||
rBytes =
|
||||
new StringBuilder(
|
||||
rBytes.substring(0, i * 2) +
|
||||
currentByteBits +
|
||||
rBytes.substring((i + 1) * 2)
|
||||
);
|
||||
rBytes = new StringBuilder(
|
||||
rBytes.substring(0, i * 2) + currentByteBits + rBytes.substring((i + 1) * 2));
|
||||
}
|
||||
|
||||
// t = new BigInteger(rBytes, 16);
|
||||
@ -2438,16 +2431,16 @@ public class AES {
|
||||
public static BigInteger[] keyExpansion(BigInteger initialKey) {
|
||||
BigInteger[] roundKeys = {
|
||||
initialKey,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
BigInteger.ZERO,
|
||||
};
|
||||
|
||||
// initialize rcon iteration
|
||||
@ -2455,23 +2448,18 @@ public class AES {
|
||||
|
||||
for (int i = 1; i < 11; i++) {
|
||||
// get the previous 32 bits the key
|
||||
BigInteger t =
|
||||
roundKeys[i - 1].remainder(new BigInteger("100000000", 16));
|
||||
BigInteger t = roundKeys[i - 1].remainder(new BigInteger("100000000", 16));
|
||||
|
||||
// split previous key into 8-bit segments
|
||||
BigInteger[] prevKey = {
|
||||
roundKeys[i - 1].remainder(new BigInteger("100000000", 16)),
|
||||
roundKeys[i - 1].remainder(
|
||||
new BigInteger("10000000000000000", 16)
|
||||
)
|
||||
roundKeys[i - 1]
|
||||
.remainder(new BigInteger("10000000000000000", 16))
|
||||
.divide(new BigInteger("100000000", 16)),
|
||||
roundKeys[i - 1].remainder(
|
||||
new BigInteger("1000000000000000000000000", 16)
|
||||
)
|
||||
roundKeys[i - 1]
|
||||
.remainder(new BigInteger("1000000000000000000000000", 16))
|
||||
.divide(new BigInteger("10000000000000000", 16)),
|
||||
roundKeys[i - 1].divide(
|
||||
new BigInteger("1000000000000000000000000", 16)
|
||||
),
|
||||
roundKeys[i - 1].divide(new BigInteger("1000000000000000000000000", 16)),
|
||||
};
|
||||
|
||||
// run schedule core
|
||||
@ -2527,9 +2515,7 @@ public class AES {
|
||||
public static BigInteger mergeCellsIntoBlock(int[] cells) {
|
||||
StringBuilder blockBits = new StringBuilder();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
StringBuilder cellBits = new StringBuilder(
|
||||
Integer.toBinaryString(cells[i])
|
||||
);
|
||||
StringBuilder cellBits = new StringBuilder(Integer.toBinaryString(cells[i]));
|
||||
|
||||
// Append leading 0 for full "8-bit" strings
|
||||
while (cellBits.length() < 8) {
|
||||
@ -2545,10 +2531,7 @@ public class AES {
|
||||
/**
|
||||
* @return ciphertext XOR key
|
||||
*/
|
||||
public static BigInteger addRoundKey(
|
||||
BigInteger ciphertext,
|
||||
BigInteger key
|
||||
) {
|
||||
public static BigInteger addRoundKey(BigInteger ciphertext, BigInteger key) {
|
||||
return ciphertext.xor(key);
|
||||
}
|
||||
|
||||
@ -2669,14 +2652,10 @@ public class AES {
|
||||
cells[i * 4 + 3],
|
||||
};
|
||||
|
||||
outputCells[i * 4] =
|
||||
MULT2[row[0]] ^ MULT3[row[1]] ^ row[2] ^ row[3];
|
||||
outputCells[i * 4 + 1] =
|
||||
row[0] ^ MULT2[row[1]] ^ MULT3[row[2]] ^ row[3];
|
||||
outputCells[i * 4 + 2] =
|
||||
row[0] ^ row[1] ^ MULT2[row[2]] ^ MULT3[row[3]];
|
||||
outputCells[i * 4 + 3] =
|
||||
MULT3[row[0]] ^ row[1] ^ row[2] ^ MULT2[row[3]];
|
||||
outputCells[i * 4] = MULT2[row[0]] ^ MULT3[row[1]] ^ row[2] ^ row[3];
|
||||
outputCells[i * 4 + 1] = row[0] ^ MULT2[row[1]] ^ MULT3[row[2]] ^ row[3];
|
||||
outputCells[i * 4 + 2] = row[0] ^ row[1] ^ MULT2[row[2]] ^ MULT3[row[3]];
|
||||
outputCells[i * 4 + 3] = MULT3[row[0]] ^ row[1] ^ row[2] ^ MULT2[row[3]];
|
||||
}
|
||||
return mergeCellsIntoBlock(outputCells);
|
||||
}
|
||||
@ -2697,26 +2676,13 @@ public class AES {
|
||||
cells[i * 4 + 3],
|
||||
};
|
||||
|
||||
outputCells[i * 4] =
|
||||
MULT14[row[0]] ^
|
||||
MULT11[row[1]] ^
|
||||
MULT13[row[2]] ^
|
||||
MULT9[row[3]];
|
||||
outputCells[i * 4 + 1] =
|
||||
MULT9[row[0]] ^
|
||||
MULT14[row[1]] ^
|
||||
MULT11[row[2]] ^
|
||||
MULT13[row[3]];
|
||||
outputCells[i * 4 + 2] =
|
||||
MULT13[row[0]] ^
|
||||
MULT9[row[1]] ^
|
||||
MULT14[row[2]] ^
|
||||
MULT11[row[3]];
|
||||
outputCells[i * 4 + 3] =
|
||||
MULT11[row[0]] ^
|
||||
MULT13[row[1]] ^
|
||||
MULT9[row[2]] ^
|
||||
MULT14[row[3]];
|
||||
outputCells[i * 4] = MULT14[row[0]] ^ MULT11[row[1]] ^ MULT13[row[2]] ^ MULT9[row[3]];
|
||||
outputCells[i * 4 + 1]
|
||||
= MULT9[row[0]] ^ MULT14[row[1]] ^ MULT11[row[2]] ^ MULT13[row[3]];
|
||||
outputCells[i * 4 + 2]
|
||||
= MULT13[row[0]] ^ MULT9[row[1]] ^ MULT14[row[2]] ^ MULT11[row[3]];
|
||||
outputCells[i * 4 + 3]
|
||||
= MULT11[row[0]] ^ MULT13[row[1]] ^ MULT9[row[2]] ^ MULT14[row[3]];
|
||||
}
|
||||
return mergeCellsIntoBlock(outputCells);
|
||||
}
|
||||
@ -2780,9 +2746,7 @@ public class AES {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try (Scanner input = new Scanner(System.in)) {
|
||||
System.out.println(
|
||||
"Enter (e) letter for encrpyt or (d) letter for decrypt :"
|
||||
);
|
||||
System.out.println("Enter (e) letter for encrpyt or (d) letter for decrypt :");
|
||||
char choice = input.nextLine().charAt(0);
|
||||
String in;
|
||||
switch (choice) {
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.thealgorithms.ciphers;
|
||||
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
|
||||
/**
|
||||
* This example program shows how AES encryption and decryption can be done in
|
||||
@ -29,12 +29,8 @@ public class AESEncryption {
|
||||
String decryptedText = decryptText(cipherText, secKey);
|
||||
|
||||
System.out.println("Original Text:" + plainText);
|
||||
System.out.println(
|
||||
"AES Key (Hex Form):" + bytesToHex(secKey.getEncoded())
|
||||
);
|
||||
System.out.println(
|
||||
"Encrypted Text (Hex Form):" + bytesToHex(cipherText)
|
||||
);
|
||||
System.out.println("AES Key (Hex Form):" + bytesToHex(secKey.getEncoded()));
|
||||
System.out.println("Encrypted Text (Hex Form):" + bytesToHex(cipherText));
|
||||
System.out.println("Descrypted Text:" + decryptedText);
|
||||
}
|
||||
|
||||
@ -45,8 +41,7 @@ public class AESEncryption {
|
||||
* @return secKey (Secret key that we encrypt using it)
|
||||
* @throws NoSuchAlgorithmException (from KeyGenrator)
|
||||
*/
|
||||
public static SecretKey getSecretEncryptionKey()
|
||||
throws NoSuchAlgorithmException {
|
||||
public static SecretKey getSecretEncryptionKey() throws NoSuchAlgorithmException {
|
||||
KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES");
|
||||
aesKeyGenerator.init(128); // The AES key size in number of bits
|
||||
return aesKeyGenerator.generateKey();
|
||||
@ -63,7 +58,8 @@ public class AESEncryption {
|
||||
* @throws IllegalBlockSizeException (from Cipher)
|
||||
*/
|
||||
public static byte[] encryptText(String plainText, SecretKey secKey)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException, BadPaddingException {
|
||||
// AES defaults to AES/ECB/PKCS5Padding in Java 7
|
||||
aesCipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
|
||||
@ -76,8 +72,8 @@ public class AESEncryption {
|
||||
* @return plainText
|
||||
*/
|
||||
public static String decryptText(byte[] byteCipherText, SecretKey secKey)
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
|
||||
IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
|
||||
// AES defaults to AES/ECB/PKCS5Padding in Java 7
|
||||
Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
|
||||
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, aesCipher.getIV());
|
||||
|
@ -15,8 +15,7 @@ class AffineCipher {
|
||||
{here x is msg[i] and m is 26} and added 'A' to
|
||||
bring it in range of ascii alphabet[ 65-90 | A-Z ] */
|
||||
if (msg[i] != ' ') {
|
||||
cipher =
|
||||
cipher + (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A');
|
||||
cipher = cipher + (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A');
|
||||
} else { // else simply append space character
|
||||
cipher += msg[i];
|
||||
}
|
||||
@ -29,8 +28,8 @@ class AffineCipher {
|
||||
int a_inv = 0;
|
||||
int flag = 0;
|
||||
|
||||
//Find a^-1 (the multiplicative inverse of a
|
||||
//in the group of integers modulo m.)
|
||||
// Find a^-1 (the multiplicative inverse of a
|
||||
// in the group of integers modulo m.)
|
||||
for (int i = 0; i < 26; i++) {
|
||||
flag = (a * i) % 26;
|
||||
|
||||
@ -45,12 +44,8 @@ class AffineCipher {
|
||||
{here x is cipher[i] and m is 26} and added 'A'
|
||||
to bring it in range of ASCII alphabet[ 65-90 | A-Z ] */
|
||||
if (cipher.charAt(i) != ' ') {
|
||||
msg =
|
||||
msg +
|
||||
(char) (
|
||||
((a_inv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A'
|
||||
);
|
||||
} else { //else simply append space character
|
||||
msg = msg + (char) (((a_inv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A');
|
||||
} else { // else simply append space character
|
||||
msg += cipher.charAt(i);
|
||||
}
|
||||
}
|
||||
@ -67,8 +62,6 @@ class AffineCipher {
|
||||
System.out.println("Encrypted Message is : " + cipherText);
|
||||
|
||||
// Calling Decryption function
|
||||
System.out.println(
|
||||
"Decrypted Message is: " + decryptCipher(cipherText)
|
||||
);
|
||||
System.out.println("Decrypted Message is: " + decryptCipher(cipherText));
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ package com.thealgorithms.ciphers;
|
||||
|
||||
public class Blowfish {
|
||||
|
||||
//Initializing substitution boxes
|
||||
// Initializing substitution boxes
|
||||
String[][] S = {
|
||||
{
|
||||
"d1310ba6",
|
||||
@ -1046,7 +1046,7 @@ public class Blowfish {
|
||||
},
|
||||
};
|
||||
|
||||
//Initializing subkeys with digits of pi
|
||||
// Initializing subkeys with digits of pi
|
||||
String[] P = {
|
||||
"243f6a88",
|
||||
"85a308d3",
|
||||
@ -1068,7 +1068,7 @@ public class Blowfish {
|
||||
"8979fb1b",
|
||||
};
|
||||
|
||||
//Initializing modVal to 2^32
|
||||
// Initializing modVal to 2^32
|
||||
long modVal = 4294967296L;
|
||||
|
||||
/**
|
||||
@ -1098,7 +1098,8 @@ public class Blowfish {
|
||||
* This method returns hexadecimal representation of the binary number passed as parameter
|
||||
*
|
||||
* @param binary Number for which hexadecimal representation is required
|
||||
* @return String object which is a hexadecimal representation of the binary number passed as parameter
|
||||
* @return String object which is a hexadecimal representation of the binary number passed as
|
||||
* parameter
|
||||
*/
|
||||
private String binToHex(String binary) {
|
||||
long num = Long.parseUnsignedLong(binary, 2);
|
||||
@ -1109,7 +1110,8 @@ public class Blowfish {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a string obtained by XOR-ing two strings of same length passed a method parameters
|
||||
* This method returns a string obtained by XOR-ing two strings of same length passed a method
|
||||
* parameters
|
||||
*
|
||||
* @param String a and b are string objects which will be XORed and are to be of same length
|
||||
* @return String object obtained by XOR operation on String a and String b
|
||||
@ -1118,17 +1120,19 @@ public class Blowfish {
|
||||
a = hexToBin(a);
|
||||
b = hexToBin(b);
|
||||
String ans = "";
|
||||
for (int i = 0; i < a.length(); i++) ans +=
|
||||
(char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0');
|
||||
for (int i = 0; i < a.length(); i++)
|
||||
ans += (char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0');
|
||||
ans = binToHex(ans);
|
||||
return ans;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns addition of two hexadecimal numbers passed as parameters and moded with 2^32
|
||||
* This method returns addition of two hexadecimal numbers passed as parameters and moded with
|
||||
* 2^32
|
||||
*
|
||||
* @param String a and b are hexadecimal numbers
|
||||
* @return String object which is a is addition that is then moded with 2^32 of hex numbers passed as parameters
|
||||
* @return String object which is a is addition that is then moded with 2^32 of hex numbers
|
||||
* passed as parameters
|
||||
*/
|
||||
private String addBin(String a, String b) {
|
||||
String ans = "";
|
||||
@ -1140,20 +1144,17 @@ public class Blowfish {
|
||||
return ans.substring(ans.length() - 8);
|
||||
}
|
||||
|
||||
/*F-function splits the 32-bit input into four 8-bit quarters
|
||||
and uses the quarters as input to the S-boxes.
|
||||
The S-boxes accept 8-bit input and produce 32-bit output.
|
||||
The outputs are added modulo 232 and XORed to produce the final 32-bit output
|
||||
*/
|
||||
/*F-function splits the 32-bit input into four 8-bit quarters
|
||||
and uses the quarters as input to the S-boxes.
|
||||
The S-boxes accept 8-bit input and produce 32-bit output.
|
||||
The outputs are added modulo 232 and XORed to produce the final 32-bit output
|
||||
*/
|
||||
private String f(String plainText) {
|
||||
String[] a = new String[4];
|
||||
String ans = "";
|
||||
for (int i = 0; i < 8; i += 2) {
|
||||
//column number for S-box is a 8-bit value
|
||||
long col = Long.parseUnsignedLong(
|
||||
hexToBin(plainText.substring(i, i + 2)),
|
||||
2
|
||||
);
|
||||
// column number for S-box is a 8-bit value
|
||||
long col = Long.parseUnsignedLong(hexToBin(plainText.substring(i, i + 2)), 2);
|
||||
a[i / 2] = S[i / 2][(int) col];
|
||||
}
|
||||
ans = addBin(a[0], a[1]);
|
||||
@ -1162,30 +1163,30 @@ public class Blowfish {
|
||||
return ans;
|
||||
}
|
||||
|
||||
//generate subkeys
|
||||
// generate subkeys
|
||||
private void keyGenerate(String key) {
|
||||
int j = 0;
|
||||
for (int i = 0; i < P.length; i++) {
|
||||
//XOR-ing 32-bit parts of the key with initial subkeys
|
||||
// XOR-ing 32-bit parts of the key with initial subkeys
|
||||
P[i] = xor(P[i], key.substring(j, j + 8));
|
||||
|
||||
j = (j + 8) % key.length();
|
||||
}
|
||||
}
|
||||
|
||||
//round function
|
||||
// round function
|
||||
private String round(int time, String plainText) {
|
||||
String left, right;
|
||||
left = plainText.substring(0, 8);
|
||||
right = plainText.substring(8, 16);
|
||||
left = xor(left, P[time]);
|
||||
|
||||
//output from F function
|
||||
// output from F function
|
||||
String fOut = f(left);
|
||||
|
||||
right = xor(fOut, right);
|
||||
|
||||
//swap left and right
|
||||
// swap left and right
|
||||
return right + left;
|
||||
}
|
||||
|
||||
@ -1198,12 +1199,12 @@ public class Blowfish {
|
||||
* @return String cipherText is the encrypted value
|
||||
*/
|
||||
String encrypt(String plainText, String key) {
|
||||
//generating key
|
||||
// generating key
|
||||
keyGenerate(key);
|
||||
|
||||
for (int i = 0; i < 16; i++) plainText = round(i, plainText);
|
||||
|
||||
//postprocessing
|
||||
// postprocessing
|
||||
String right = plainText.substring(0, 8);
|
||||
String left = plainText.substring(8, 16);
|
||||
right = xor(right, P[16]);
|
||||
@ -1220,12 +1221,12 @@ public class Blowfish {
|
||||
* @return String plainText is the decrypted text
|
||||
*/
|
||||
String decrypt(String cipherText, String key) {
|
||||
//generating key
|
||||
// generating key
|
||||
keyGenerate(key);
|
||||
|
||||
for (int i = 17; i > 1; i--) cipherText = round(i, cipherText);
|
||||
|
||||
//postprocessing
|
||||
// postprocessing
|
||||
String right = cipherText.substring(0, 8);
|
||||
String left = cipherText.substring(8, 16);
|
||||
right = xor(right, P[1]);
|
||||
|
@ -23,16 +23,19 @@ public class Caesar {
|
||||
|
||||
final int length = message.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
// int current = message.charAt(i); //using char to shift characters because ascii
|
||||
// int current = message.charAt(i); //using char to shift characters because
|
||||
// ascii
|
||||
// is in-order latin alphabet
|
||||
char current = message.charAt(i); // Java law : char + int = char
|
||||
|
||||
if (isCapitalLatinLetter(current)) {
|
||||
current += shift;
|
||||
encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
encoded.append((
|
||||
char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
} else if (isSmallLatinLetter(current)) {
|
||||
current += shift;
|
||||
encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
encoded.append((
|
||||
char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters
|
||||
} else {
|
||||
encoded.append(current);
|
||||
}
|
||||
@ -56,10 +59,12 @@ public class Caesar {
|
||||
char current = encryptedMessage.charAt(i);
|
||||
if (isCapitalLatinLetter(current)) {
|
||||
current -= shift;
|
||||
decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
|
||||
decoded.append((
|
||||
char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters
|
||||
} else if (isSmallLatinLetter(current)) {
|
||||
current -= shift;
|
||||
decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
|
||||
decoded.append((
|
||||
char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters
|
||||
} else {
|
||||
decoded.append(current);
|
||||
}
|
||||
|
@ -12,9 +12,8 @@ public class ColumnarTranspositionCipher {
|
||||
private static String keyword;
|
||||
private static Object[][] table;
|
||||
private static String abecedarium;
|
||||
public static final String ABECEDARIUM =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFG" +
|
||||
"HIJKLMNOPQRSTUVWXYZ0123456789,.;:-@";
|
||||
public static final String ABECEDARIUM = "abcdefghijklmnopqrstuvwxyzABCDEFG"
|
||||
+ "HIJKLMNOPQRSTUVWXYZ0123456789,.;:-@";
|
||||
private static final String ENCRYPTION_FIELD = "≈";
|
||||
private static final char ENCRYPTION_FIELD_CHAR = '≈';
|
||||
|
||||
@ -50,14 +49,10 @@ public class ColumnarTranspositionCipher {
|
||||
* @return a String with the word encrypted by the Columnar Transposition
|
||||
* Cipher Rule
|
||||
*/
|
||||
public static String encrpyter(
|
||||
String word,
|
||||
String keyword,
|
||||
String abecedarium
|
||||
) {
|
||||
public static String encrpyter(String word, String keyword, String abecedarium) {
|
||||
ColumnarTranspositionCipher.keyword = keyword;
|
||||
ColumnarTranspositionCipher.abecedarium =
|
||||
Objects.requireNonNullElse(abecedarium, ABECEDARIUM);
|
||||
ColumnarTranspositionCipher.abecedarium
|
||||
= Objects.requireNonNullElse(abecedarium, ABECEDARIUM);
|
||||
table = tableBuilder(word);
|
||||
Object[][] sortedTable = sortTable(table);
|
||||
StringBuilder wordEncrypted = new StringBuilder();
|
||||
@ -120,9 +115,7 @@ public class ColumnarTranspositionCipher {
|
||||
* order to respect the Columnar Transposition Cipher Rule.
|
||||
*/
|
||||
private static int numberOfRows(String word) {
|
||||
if (
|
||||
word.length() / keyword.length() > word.length() / keyword.length()
|
||||
) {
|
||||
if (word.length() / keyword.length() > word.length() / keyword.length()) {
|
||||
return (word.length() / keyword.length()) + 1;
|
||||
} else {
|
||||
return word.length() / keyword.length();
|
||||
@ -147,22 +140,12 @@ public class ColumnarTranspositionCipher {
|
||||
private static Object[][] sortTable(Object[][] table) {
|
||||
Object[][] tableSorted = new Object[table.length][table[0].length];
|
||||
for (int i = 0; i < tableSorted.length; i++) {
|
||||
System.arraycopy(
|
||||
table[i],
|
||||
0,
|
||||
tableSorted[i],
|
||||
0,
|
||||
tableSorted[i].length
|
||||
);
|
||||
System.arraycopy(table[i], 0, tableSorted[i], 0, tableSorted[i].length);
|
||||
}
|
||||
for (int i = 0; i < tableSorted[0].length; i++) {
|
||||
for (int j = i + 1; j < tableSorted[0].length; j++) {
|
||||
if ((int) tableSorted[0][i] > (int) table[0][j]) {
|
||||
Object[] column = getColumn(
|
||||
tableSorted,
|
||||
tableSorted.length,
|
||||
i
|
||||
);
|
||||
Object[] column = getColumn(tableSorted, tableSorted.length, i);
|
||||
switchColumns(tableSorted, j, i, column);
|
||||
}
|
||||
}
|
||||
@ -182,11 +165,7 @@ public class ColumnarTranspositionCipher {
|
||||
}
|
||||
|
||||
private static void switchColumns(
|
||||
Object[][] table,
|
||||
int firstColumnIndex,
|
||||
int secondColumnIndex,
|
||||
Object[] columnToSwitch
|
||||
) {
|
||||
Object[][] table, int firstColumnIndex, int secondColumnIndex, Object[] columnToSwitch) {
|
||||
for (int i = 0; i < table.length; i++) {
|
||||
table[i][secondColumnIndex] = table[i][firstColumnIndex];
|
||||
table[i][firstColumnIndex] = columnToSwitch[i];
|
||||
@ -217,22 +196,12 @@ public class ColumnarTranspositionCipher {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String keywordForExample = "asd215";
|
||||
String wordBeingEncrypted =
|
||||
"This is a test of the Columnar Transposition Cipher";
|
||||
System.out.println(
|
||||
"### Example of Columnar Transposition Cipher ###\n"
|
||||
);
|
||||
String wordBeingEncrypted = "This is a test of the Columnar Transposition Cipher";
|
||||
System.out.println("### Example of Columnar Transposition Cipher ###\n");
|
||||
System.out.println("Word being encryped ->>> " + wordBeingEncrypted);
|
||||
System.out.println(
|
||||
"Word encrypted ->>> " +
|
||||
ColumnarTranspositionCipher.encrpyter(
|
||||
wordBeingEncrypted,
|
||||
keywordForExample
|
||||
)
|
||||
);
|
||||
System.out.println(
|
||||
"Word decryped ->>> " + ColumnarTranspositionCipher.decrypter()
|
||||
);
|
||||
System.out.println("Word encrypted ->>> "
|
||||
+ ColumnarTranspositionCipher.encrpyter(wordBeingEncrypted, keywordForExample));
|
||||
System.out.println("Word decryped ->>> " + ColumnarTranspositionCipher.decrypter());
|
||||
System.out.println("\n### Encrypted Table ###");
|
||||
showTable();
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package com.thealgorithms.ciphers;
|
||||
|
||||
/**
|
||||
* This class is build to demonstrate the application of the DES-algorithm (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a
|
||||
* plain English message. The supplied key must be in form of a 64 bit binary String.
|
||||
* This class is build to demonstrate the application of the DES-algorithm
|
||||
* (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a plain English message. The supplied
|
||||
* key must be in form of a 64 bit binary String.
|
||||
*/
|
||||
public class DES {
|
||||
|
||||
@ -12,7 +13,8 @@ public class DES {
|
||||
private void sanitize(String key) {
|
||||
int length = key.length();
|
||||
if (length != 64) {
|
||||
throw new IllegalArgumentException("DES key must be supplied as a 64 character binary string");
|
||||
throw new IllegalArgumentException(
|
||||
"DES key must be supplied as a 64 character binary string");
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,170 +32,102 @@ public class DES {
|
||||
sanitize(key);
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
//Permutation table to convert initial 64 bit key to 56 bit key
|
||||
private static int[] PC1 =
|
||||
{
|
||||
57, 49, 41, 33, 25, 17, 9,
|
||||
1, 58, 50, 42, 34, 26, 18,
|
||||
10, 2, 59, 51, 43, 35, 27,
|
||||
19, 11, 3, 60, 52, 44, 36,
|
||||
63, 55, 47, 39, 31, 23, 15,
|
||||
7, 62, 54, 46, 38, 30, 22,
|
||||
14, 6, 61, 53, 45, 37, 29,
|
||||
21, 13, 5, 28, 20, 12, 4
|
||||
};
|
||||
|
||||
//Lookup table used to shift the initial key, in order to generate the subkeys
|
||||
private static int[] KEY_SHIFTS =
|
||||
{
|
||||
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
|
||||
};
|
||||
// Permutation table to convert initial 64 bit key to 56 bit key
|
||||
private static int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51,
|
||||
43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30,
|
||||
22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4};
|
||||
|
||||
//Table to convert the 56 bit subkeys to 48 bit subkeys
|
||||
private static int[] PC2 =
|
||||
{
|
||||
14, 17, 11, 24, 1, 5,
|
||||
3, 28, 15, 6, 21, 10,
|
||||
23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2,
|
||||
41, 52, 31, 37, 47, 55,
|
||||
30, 40, 51, 45, 33, 48,
|
||||
44, 49, 39, 56, 34, 53,
|
||||
46, 42, 50, 36, 29, 32
|
||||
};
|
||||
// Lookup table used to shift the initial key, in order to generate the subkeys
|
||||
private static int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
|
||||
|
||||
//Initial permutatation of each 64 but message block
|
||||
private static int[] IP =
|
||||
{
|
||||
58, 50, 42, 34, 26, 18, 10 , 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6,
|
||||
64, 56, 48, 40, 32, 24, 16, 8,
|
||||
57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7
|
||||
};
|
||||
// Table to convert the 56 bit subkeys to 48 bit subkeys
|
||||
private static int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8,
|
||||
16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34,
|
||||
53, 46, 42, 50, 36, 29, 32};
|
||||
|
||||
//Expansion table to convert right half of message blocks from 32 bits to 48 bits
|
||||
private static int[] expansion =
|
||||
{
|
||||
32, 1, 2, 3, 4, 5,
|
||||
4, 5, 6, 7, 8, 9,
|
||||
8, 9, 10, 11, 12, 13,
|
||||
12, 13, 14, 15, 16, 17,
|
||||
16, 17, 18, 19, 20, 21,
|
||||
20, 21, 22, 23, 24, 25,
|
||||
24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1
|
||||
};
|
||||
|
||||
//The eight substitution boxes are defined below
|
||||
private static int[][] s1 = {
|
||||
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
|
||||
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
|
||||
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
|
||||
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
|
||||
};
|
||||
// Initial permutatation of each 64 but message block
|
||||
private static int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54,
|
||||
46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51,
|
||||
43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};
|
||||
|
||||
private static int[][] s2 = {
|
||||
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
|
||||
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
|
||||
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
|
||||
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
|
||||
};
|
||||
|
||||
private static int[][] s3 = {
|
||||
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
|
||||
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
|
||||
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
|
||||
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
|
||||
};
|
||||
|
||||
private static int[][] s4 = {
|
||||
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
|
||||
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
|
||||
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
|
||||
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
|
||||
};
|
||||
|
||||
private static int[][] s5 = {
|
||||
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
|
||||
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
|
||||
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
|
||||
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
|
||||
};
|
||||
|
||||
private static int[][] s6 = {
|
||||
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
|
||||
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
|
||||
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
|
||||
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
|
||||
};
|
||||
|
||||
private static int[][] s7 = {
|
||||
{4, 11, 2, 14, 15, 0, 8, 13 , 3, 12, 9 , 7, 5, 10, 6, 1},
|
||||
{13 , 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
|
||||
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
|
||||
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
|
||||
};
|
||||
|
||||
private static int[][] s8 = {
|
||||
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
|
||||
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6 ,11, 0, 14, 9, 2},
|
||||
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10 ,13, 15, 3, 5, 8},
|
||||
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6 ,11}
|
||||
};
|
||||
|
||||
private static int[][][] s = {s1, s2, s3, s4, s5, s6, s7, s8};
|
||||
// Expansion table to convert right half of message blocks from 32 bits to 48 bits
|
||||
private static int[] expansion = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12,
|
||||
13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29,
|
||||
28, 29, 30, 31, 32, 1};
|
||||
|
||||
//Permutation table, used in the feistel function post s-box usage
|
||||
static int[] permutation =
|
||||
{
|
||||
16, 7, 20, 21,
|
||||
29, 12, 28, 17,
|
||||
1, 15, 23, 26,
|
||||
5, 18, 31, 10,
|
||||
2, 8, 24, 14,
|
||||
32, 27, 3, 9,
|
||||
19, 13, 30, 6,
|
||||
22, 11, 4, 25
|
||||
};
|
||||
// The eight substitution boxes are defined below
|
||||
private static int[][] s1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
|
||||
{0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
|
||||
{4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
|
||||
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}};
|
||||
|
||||
//Table used for final inversion of the message box after 16 rounds of Feistel Function
|
||||
static int[] IPinverse =
|
||||
{
|
||||
40, 8, 48, 16, 56, 24, 64, 32,
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43 ,11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25
|
||||
};
|
||||
private static int[][] s2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
|
||||
{3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
|
||||
{0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
|
||||
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}};
|
||||
|
||||
private static int[][] s3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
|
||||
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
|
||||
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
|
||||
{1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}};
|
||||
|
||||
private static int[][] s4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
|
||||
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
|
||||
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
|
||||
{3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}};
|
||||
|
||||
private static int[][] s5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
|
||||
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
|
||||
{4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
|
||||
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}};
|
||||
|
||||
private static int[][] s6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
|
||||
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
|
||||
{9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
|
||||
{4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}};
|
||||
|
||||
private static int[][] s7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
|
||||
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
|
||||
{1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
|
||||
{6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}};
|
||||
|
||||
private static int[][] s8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
|
||||
{1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
|
||||
{7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
|
||||
{2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};
|
||||
|
||||
private static int[][][] s = {s1, s2, s3, s4, s5, s6, s7, s8};
|
||||
|
||||
// Permutation table, used in the feistel function post s-box usage
|
||||
static int[] permutation = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8,
|
||||
24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25};
|
||||
|
||||
// Table used for final inversion of the message box after 16 rounds of Feistel Function
|
||||
static int[] IPinverse = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6,
|
||||
46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3,
|
||||
43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
|
||||
|
||||
private String[] getSubkeys(String originalKey) {
|
||||
StringBuilder permutedKey = new StringBuilder(); //Initial permutation of keys via PC1
|
||||
StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via PC1
|
||||
int i, j;
|
||||
for (i = 0; i < 56; i++) {
|
||||
permutedKey.append(originalKey.charAt(PC1[i] - 1));
|
||||
permutedKey.append(originalKey.charAt(PC1[i] - 1));
|
||||
}
|
||||
String subKeys[] = new String[16];
|
||||
String initialPermutedKey = permutedKey.toString();
|
||||
String C0 = initialPermutedKey.substring(0, 28), D0 = initialPermutedKey.substring(28);
|
||||
|
||||
//We will now operate on the left and right halves of the permutedKey
|
||||
|
||||
// We will now operate on the left and right halves of the permutedKey
|
||||
for (i = 0; i < 16; i++) {
|
||||
String Cn = C0.substring(KEY_SHIFTS[i]) + C0.substring(0, KEY_SHIFTS[i]);
|
||||
String Dn = D0.substring(KEY_SHIFTS[i]) + D0.substring(0, KEY_SHIFTS[i]);
|
||||
subKeys[i] = Cn + Dn;
|
||||
C0 = Cn; //Re-assign the values to create running permutation
|
||||
C0 = Cn; // Re-assign the values to create running permutation
|
||||
D0 = Dn;
|
||||
}
|
||||
|
||||
//Let us shrink the keys to 48 bits (well, characters here) using PC2
|
||||
// Let us shrink the keys to 48 bits (well, characters here) using PC2
|
||||
for (i = 0; i < 16; i++) {
|
||||
String key = subKeys[i];
|
||||
permutedKey.setLength(0);
|
||||
@ -244,16 +178,17 @@ public class DES {
|
||||
String mixedKey = XOR(expandedKey.toString(), key);
|
||||
StringBuilder substitutedString = new StringBuilder();
|
||||
|
||||
//Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits
|
||||
// Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits
|
||||
for (i = 0; i < 48; i += 6) {
|
||||
String block = mixedKey.substring(i, i + 6);
|
||||
int row = (block.charAt(0) - 48) * 2 + (block.charAt(5) - 48);
|
||||
int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4 + (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48);
|
||||
int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4
|
||||
+ (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48);
|
||||
String substitutedBlock = pad(Integer.toBinaryString(s[i / 6][row][col]), 4);
|
||||
substitutedString.append(substitutedBlock);
|
||||
}
|
||||
|
||||
StringBuilder permutedString = new StringBuilder();
|
||||
StringBuilder permutedString = new StringBuilder();
|
||||
for (i = 0; i < 32; i++) {
|
||||
permutedString.append(substitutedString.charAt(permutation[i] - 1));
|
||||
}
|
||||
@ -269,7 +204,7 @@ public class DES {
|
||||
}
|
||||
String L0 = permutedMessage.substring(0, 32), R0 = permutedMessage.substring(32);
|
||||
|
||||
//Iterate 16 times
|
||||
// Iterate 16 times
|
||||
for (i = 0; i < 16; i++) {
|
||||
String Ln = R0; // Previous Right block
|
||||
String Rn = XOR(L0, feistel(R0, keys[i]));
|
||||
@ -277,7 +212,7 @@ public class DES {
|
||||
R0 = Rn;
|
||||
}
|
||||
|
||||
String combinedBlock = R0 + L0; //Reverse the 16th block
|
||||
String combinedBlock = R0 + L0; // Reverse the 16th block
|
||||
permutedMessage.setLength(0);
|
||||
for (i = 0; i < 64; i++) {
|
||||
permutedMessage.append(combinedBlock.charAt(IPinverse[i] - 1));
|
||||
@ -285,7 +220,7 @@ public class DES {
|
||||
return permutedMessage.toString();
|
||||
}
|
||||
|
||||
//To decode, we follow the same process as encoding, but with reversed keys
|
||||
// To decode, we follow the same process as encoding, but with reversed keys
|
||||
private String decryptBlock(String message, String keys[]) {
|
||||
String reversedKeys[] = new String[keys.length];
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
@ -307,7 +242,7 @@ public class DES {
|
||||
message = padLast(message, desiredLength);
|
||||
}
|
||||
|
||||
for (i = 0; i < l; i+= 8) {
|
||||
for (i = 0; i < l; i += 8) {
|
||||
String block = message.substring(i, i + 8);
|
||||
StringBuilder bitBlock = new StringBuilder();
|
||||
byte[] bytes = block.getBytes();
|
||||
@ -327,18 +262,19 @@ public class DES {
|
||||
StringBuilder decryptedMessage = new StringBuilder();
|
||||
int l = message.length(), i, j;
|
||||
if (l % 64 != 0) {
|
||||
throw new IllegalArgumentException("Encrypted message should be a multiple of 64 characters in length");
|
||||
throw new IllegalArgumentException(
|
||||
"Encrypted message should be a multiple of 64 characters in length");
|
||||
}
|
||||
for (i = 0; i < l; i+= 64) {
|
||||
for (i = 0; i < l; i += 64) {
|
||||
String block = message.substring(i, i + 64);
|
||||
String result = decryptBlock(block.toString(), subKeys);
|
||||
byte res[] = new byte[8];
|
||||
for (j = 0; j < 64; j+=8) {
|
||||
res[j / 8] = (byte)Integer.parseInt(result.substring(j, j + 8), 2);
|
||||
for (j = 0; j < 64; j += 8) {
|
||||
res[j / 8] = (byte) Integer.parseInt(result.substring(j, j + 8), 2);
|
||||
}
|
||||
decryptedMessage.append(new String(res));
|
||||
}
|
||||
return decryptedMessage.toString().replace("\0", ""); // Get rid of the null bytes used for padding
|
||||
return decryptedMessage.toString().replace(
|
||||
"\0", ""); // Get rid of the null bytes used for padding
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,10 +4,11 @@ import java.util.Scanner;
|
||||
|
||||
/*
|
||||
* Java Implementation of Hill Cipher
|
||||
* Hill cipher is a polyalphabetic substitution cipher. Each letter is represented by a number belonging to the set Z26 where A=0 , B=1, ..... Z=25.
|
||||
* To encrypt a message, each block of n letters (since matrix size is n x n) is multiplied by an invertible n × n matrix, against modulus 26.
|
||||
* To decrypt the message, each block is multiplied by the inverse of the matrix used for encryption.
|
||||
* The cipher key and plaintext/ciphertext are user inputs.
|
||||
* Hill cipher is a polyalphabetic substitution cipher. Each letter is represented by a number
|
||||
* belonging to the set Z26 where A=0 , B=1, ..... Z=25. To encrypt a message, each block of n
|
||||
* letters (since matrix size is n x n) is multiplied by an invertible n × n matrix, against
|
||||
* modulus 26. To decrypt the message, each block is multiplied by the inverse of the matrix used
|
||||
* for encryption. The cipher key and plaintext/ciphertext are user inputs.
|
||||
* @author Ojasva Jain
|
||||
*/
|
||||
public class HillCipher {
|
||||
@ -28,7 +29,7 @@ public class HillCipher {
|
||||
keyMatrix[i][j] = userInput.nextInt();
|
||||
}
|
||||
}
|
||||
//check if det = 0
|
||||
// check if det = 0
|
||||
validateDeterminant(keyMatrix, matrixSize);
|
||||
|
||||
int[][] messageVector = new int[matrixSize][1];
|
||||
@ -62,7 +63,7 @@ public class HillCipher {
|
||||
System.out.println("Ciphertext: " + CipherText);
|
||||
}
|
||||
|
||||
//Following function decrypts a message
|
||||
// Following function decrypts a message
|
||||
static void decrypt(String message) {
|
||||
message = message.toUpperCase();
|
||||
// Get key matrix
|
||||
@ -75,10 +76,10 @@ public class HillCipher {
|
||||
keyMatrix[i][j] = userInput.nextInt();
|
||||
}
|
||||
}
|
||||
//check if det = 0
|
||||
// check if det = 0
|
||||
validateDeterminant(keyMatrix, n);
|
||||
|
||||
//solving for the required plaintext message
|
||||
// solving for the required plaintext message
|
||||
int[][] messageVector = new int[n][1];
|
||||
String PlainText = "";
|
||||
int[][] plainMatrix = new int[n][1];
|
||||
@ -157,9 +158,7 @@ public class HillCipher {
|
||||
|
||||
static void validateDeterminant(int[][] keyMatrix, int n) {
|
||||
if (determinant(keyMatrix, n) % 26 == 0) {
|
||||
System.out.println(
|
||||
"Invalid key, as determinant = 0. Program Terminated"
|
||||
);
|
||||
System.out.println("Invalid key, as determinant = 0. Program Terminated");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,8 @@ package com.thealgorithms.ciphers;
|
||||
* Letters in alphabet takes place to two dimension table.
|
||||
* Encrypted text is created according to row and column in two dimension table
|
||||
* Decrypted text is generated by looking at the row and column respectively
|
||||
* Additionally, some letters in english alphabet deliberately throws such as U because U is very similar with V
|
||||
* Additionally, some letters in english alphabet deliberately throws such as U because U is very
|
||||
* similar with V
|
||||
*
|
||||
* @author Hikmet ÇAKIR
|
||||
* @since 08-07-2022+03:00
|
||||
@ -16,11 +17,11 @@ public class Polybius {
|
||||
|
||||
private static final char[][] key = {
|
||||
// 0 1 2 3 4
|
||||
/* 0 */{ 'A', 'B', 'C', 'D', 'E' },
|
||||
/* 1 */{ 'F', 'G', 'H', 'I', 'J' },
|
||||
/* 2 */{ 'K', 'L', 'M', 'N', 'O' },
|
||||
/* 3 */{ 'P', 'Q', 'R', 'S', 'T' },
|
||||
/* 4 */{ 'V', 'W', 'X', 'Y', 'Z' },
|
||||
/* 0 */ {'A', 'B', 'C', 'D', 'E'},
|
||||
/* 1 */ {'F', 'G', 'H', 'I', 'J'},
|
||||
/* 2 */ {'K', 'L', 'M', 'N', 'O'},
|
||||
/* 3 */ {'P', 'Q', 'R', 'S', 'T'},
|
||||
/* 4 */ {'V', 'W', 'X', 'Y', 'Z'},
|
||||
};
|
||||
|
||||
private static String findLocationByCharacter(final char character) {
|
||||
|
@ -20,8 +20,7 @@ public class RSA {
|
||||
* @return encrypted message
|
||||
*/
|
||||
public synchronized String encrypt(String message) {
|
||||
return (new BigInteger(message.getBytes())).modPow(publicKey, modulus)
|
||||
.toString();
|
||||
return (new BigInteger(message.getBytes())).modPow(publicKey, modulus).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,9 +35,7 @@ public class RSA {
|
||||
*/
|
||||
public synchronized String decrypt(String encryptedMessage) {
|
||||
return new String(
|
||||
(new BigInteger(encryptedMessage)).modPow(privateKey, modulus)
|
||||
.toByteArray()
|
||||
);
|
||||
(new BigInteger(encryptedMessage)).modPow(privateKey, modulus).toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,8 +54,7 @@ public class RSA {
|
||||
BigInteger q = new BigInteger(bits / 2, 100, r);
|
||||
modulus = p.multiply(q);
|
||||
|
||||
BigInteger m =
|
||||
(p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
|
||||
BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));
|
||||
|
||||
publicKey = BigInteger.valueOf(3L);
|
||||
|
||||
|
@ -82,5 +82,4 @@ public class SimpleSubCipher {
|
||||
|
||||
return decoded.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,21 +16,9 @@ public class Vigenere {
|
||||
char c = message.charAt(i);
|
||||
if (Character.isLetter(c)) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
result.append(
|
||||
(char) (
|
||||
(c + key.toUpperCase().charAt(j) - 2 * 'A') %
|
||||
26 +
|
||||
'A'
|
||||
)
|
||||
);
|
||||
result.append((char) ((c + key.toUpperCase().charAt(j) - 2 * 'A') % 26 + 'A'));
|
||||
} else {
|
||||
result.append(
|
||||
(char) (
|
||||
(c + key.toLowerCase().charAt(j) - 2 * 'a') %
|
||||
26 +
|
||||
'a'
|
||||
)
|
||||
);
|
||||
result.append((char) ((c + key.toLowerCase().charAt(j) - 2 * 'a') % 26 + 'a'));
|
||||
}
|
||||
} else {
|
||||
result.append(c);
|
||||
@ -48,17 +36,9 @@ public class Vigenere {
|
||||
char c = message.charAt(i);
|
||||
if (Character.isLetter(c)) {
|
||||
if (Character.isUpperCase(c)) {
|
||||
result.append(
|
||||
(char) (
|
||||
'Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26
|
||||
)
|
||||
);
|
||||
result.append((char) ('Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26));
|
||||
} else {
|
||||
result.append(
|
||||
(char) (
|
||||
'z' - (25 - (c - key.toLowerCase().charAt(j))) % 26
|
||||
)
|
||||
);
|
||||
result.append((char) ('z' - (25 - (c - key.toLowerCase().charAt(j))) % 26));
|
||||
}
|
||||
} else {
|
||||
result.append(c);
|
||||
|
@ -6,7 +6,8 @@ import java.util.BitSet;
|
||||
public class A5Cipher {
|
||||
|
||||
private final A5KeyStreamGenerator keyStreamGenerator;
|
||||
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
|
||||
private static final int KEY_STREAM_LENGTH
|
||||
= 228; // 28.5 bytes so we need to pad bytes or something
|
||||
|
||||
public A5Cipher(BitSet sessionKey, BitSet frameCounter) {
|
||||
keyStreamGenerator = new A5KeyStreamGenerator();
|
||||
|
@ -9,7 +9,8 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
private BitSet frameCounter;
|
||||
private BitSet sessionKey;
|
||||
private static final int INITIAL_CLOCKING_CYCLES = 100;
|
||||
private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something
|
||||
private static final int KEY_STREAM_LENGTH
|
||||
= 228; // 28.5 bytes so we need to pad bytes or something
|
||||
|
||||
@Override
|
||||
public void initialize(BitSet sessionKey, BitSet frameCounter) {
|
||||
@ -17,9 +18,9 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
this.frameCounter = (BitSet) frameCounter.clone();
|
||||
this.initialFrameCounter = (BitSet) frameCounter.clone();
|
||||
registers.clear();
|
||||
LFSR lfsr1 = new LFSR(19, 8, new int[] { 13, 16, 17, 18 });
|
||||
LFSR lfsr2 = new LFSR(22, 10, new int[] { 20, 21 });
|
||||
LFSR lfsr3 = new LFSR(23, 10, new int[] { 7, 20, 21, 22 });
|
||||
LFSR lfsr1 = new LFSR(19, 8, new int[] {13, 16, 17, 18});
|
||||
LFSR lfsr2 = new LFSR(22, 10, new int[] {20, 21});
|
||||
LFSR lfsr3 = new LFSR(23, 10, new int[] {7, 20, 21, 22});
|
||||
registers.add(lfsr1);
|
||||
registers.add(lfsr2);
|
||||
registers.add(lfsr3);
|
||||
@ -31,11 +32,7 @@ public class A5KeyStreamGenerator extends CompositeLFSR {
|
||||
}
|
||||
|
||||
public BitSet getNextKeyStream() {
|
||||
for (
|
||||
int cycle = 1;
|
||||
cycle <= INITIAL_CLOCKING_CYCLES;
|
||||
++cycle
|
||||
) this.clock();
|
||||
for (int cycle = 1; cycle <= INITIAL_CLOCKING_CYCLES; ++cycle) this.clock();
|
||||
|
||||
BitSet result = new BitSet(KEY_STREAM_LENGTH);
|
||||
for (int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle) {
|
||||
|
@ -29,12 +29,8 @@ public abstract class CompositeLFSR implements BaseLFSR {
|
||||
bitCount.put(false, 0);
|
||||
bitCount.put(true, 0);
|
||||
|
||||
registers.forEach(lfsr ->
|
||||
bitCount.put(
|
||||
lfsr.getClockBit(),
|
||||
bitCount.get(lfsr.getClockBit()) + 1
|
||||
)
|
||||
);
|
||||
registers.forEach(
|
||||
lfsr -> bitCount.put(lfsr.getClockBit(), bitCount.get(lfsr.getClockBit()) + 1));
|
||||
return bitCount.get(false) <= bitCount.get(true);
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
package com.thealgorithms.ciphers.a5;
|
||||
|
||||
// Source http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html
|
||||
//package com.java2s;
|
||||
//License from project: Open Source License
|
||||
// Source
|
||||
// http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html
|
||||
// package com.java2s;
|
||||
// License from project: Open Source License
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
@ -11,7 +12,7 @@ public class Utils {
|
||||
public static boolean increment(BitSet bits, int size) {
|
||||
int i = size - 1;
|
||||
while (i >= 0 && bits.get(i)) {
|
||||
bits.set(i--, false);/*from w w w . j a v a 2s .c o m*/
|
||||
bits.set(i--, false); /*from w w w . j a v a 2s .c o m*/
|
||||
}
|
||||
if (i < 0) {
|
||||
return false;
|
||||
|
@ -30,13 +30,8 @@ public class AnyBaseToAnyBase {
|
||||
try {
|
||||
System.out.print("Enter number: ");
|
||||
n = in.next();
|
||||
System.out.print(
|
||||
"Enter beginning base (between " +
|
||||
MINIMUM_BASE +
|
||||
" and " +
|
||||
MAXIMUM_BASE +
|
||||
"): "
|
||||
);
|
||||
System.out.print("Enter beginning base (between " + MINIMUM_BASE + " and "
|
||||
+ MAXIMUM_BASE + "): ");
|
||||
b1 = in.nextInt();
|
||||
if (b1 > MAXIMUM_BASE || b1 < MINIMUM_BASE) {
|
||||
System.out.println("Invalid base!");
|
||||
@ -47,12 +42,7 @@ public class AnyBaseToAnyBase {
|
||||
continue;
|
||||
}
|
||||
System.out.print(
|
||||
"Enter end base (between " +
|
||||
MINIMUM_BASE +
|
||||
" and " +
|
||||
MAXIMUM_BASE +
|
||||
"): "
|
||||
);
|
||||
"Enter end base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): ");
|
||||
b2 = in.nextInt();
|
||||
if (b2 > MAXIMUM_BASE || b2 < MINIMUM_BASE) {
|
||||
System.out.println("Invalid base!");
|
||||
|
@ -11,9 +11,7 @@ import java.util.ArrayList;
|
||||
public class DecimalToAnyBase {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
BufferedReader br = new BufferedReader(
|
||||
new InputStreamReader(System.in)
|
||||
);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
|
||||
System.out.println("Enter the decimal input below: ");
|
||||
int decInput = Integer.parseInt(br.readLine());
|
||||
System.out.println();
|
||||
@ -22,15 +20,10 @@ public class DecimalToAnyBase {
|
||||
int base = Integer.parseInt(br.readLine());
|
||||
System.out.println();
|
||||
|
||||
System.out.println("Decimal Input" + " is: " + decInput);
|
||||
System.out.println(
|
||||
"Value of " +
|
||||
decInput +
|
||||
" in base " +
|
||||
base +
|
||||
" is: " +
|
||||
convertToAnyBase(decInput, base)
|
||||
);
|
||||
System.out.println("Decimal Input"
|
||||
+ " is: " + decInput);
|
||||
System.out.println("Value of " + decInput + " in base " + base
|
||||
+ " is: " + convertToAnyBase(decInput, base));
|
||||
|
||||
br.close();
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ class DecimalToBinary {
|
||||
public static void conventionalConversion() {
|
||||
int n, b = 0, c = 0, d;
|
||||
Scanner input = new Scanner(System.in);
|
||||
System.out.printf(
|
||||
"Conventional conversion.%n Enter the decimal number: "
|
||||
);
|
||||
System.out.printf("Conventional conversion.%n Enter the decimal number: ");
|
||||
n = input.nextInt();
|
||||
while (n != 0) {
|
||||
d = n % 2;
|
||||
|
@ -61,7 +61,8 @@ public class HexToOct {
|
||||
hexadecnum = scan.nextLine();
|
||||
|
||||
// first convert hexadecimal to decimal
|
||||
decnum = hex2decimal(hexadecnum); // Pass the string to the hex2decimal function and get the decimal form in
|
||||
decnum = hex2decimal(
|
||||
hexadecnum); // Pass the string to the hex2decimal function and get the decimal form in
|
||||
// variable decnum
|
||||
|
||||
// convert decimal to octal
|
||||
|
@ -19,69 +19,30 @@ public class RgbHsvConversion {
|
||||
// Expected RGB-values taken from https://www.rapidtables.com/convert/color/hsv-to-rgb.html
|
||||
|
||||
// Test hsvToRgb-method
|
||||
assert Arrays.equals(hsvToRgb(0, 0, 0), new int[] { 0, 0, 0 });
|
||||
assert Arrays.equals(hsvToRgb(0, 0, 1), new int[] { 255, 255, 255 });
|
||||
assert Arrays.equals(hsvToRgb(0, 1, 1), new int[] { 255, 0, 0 });
|
||||
assert Arrays.equals(hsvToRgb(60, 1, 1), new int[] { 255, 255, 0 });
|
||||
assert Arrays.equals(hsvToRgb(120, 1, 1), new int[] { 0, 255, 0 });
|
||||
assert Arrays.equals(hsvToRgb(240, 1, 1), new int[] { 0, 0, 255 });
|
||||
assert Arrays.equals(hsvToRgb(300, 1, 1), new int[] { 255, 0, 255 });
|
||||
assert Arrays.equals(
|
||||
hsvToRgb(180, 0.5, 0.5),
|
||||
new int[] { 64, 128, 128 }
|
||||
);
|
||||
assert Arrays.equals(
|
||||
hsvToRgb(234, 0.14, 0.88),
|
||||
new int[] { 193, 196, 224 }
|
||||
);
|
||||
assert Arrays.equals(
|
||||
hsvToRgb(330, 0.75, 0.5),
|
||||
new int[] { 128, 32, 80 }
|
||||
);
|
||||
assert Arrays.equals(hsvToRgb(0, 0, 0), new int[] {0, 0, 0});
|
||||
assert Arrays.equals(hsvToRgb(0, 0, 1), new int[] {255, 255, 255});
|
||||
assert Arrays.equals(hsvToRgb(0, 1, 1), new int[] {255, 0, 0});
|
||||
assert Arrays.equals(hsvToRgb(60, 1, 1), new int[] {255, 255, 0});
|
||||
assert Arrays.equals(hsvToRgb(120, 1, 1), new int[] {0, 255, 0});
|
||||
assert Arrays.equals(hsvToRgb(240, 1, 1), new int[] {0, 0, 255});
|
||||
assert Arrays.equals(hsvToRgb(300, 1, 1), new int[] {255, 0, 255});
|
||||
assert Arrays.equals(hsvToRgb(180, 0.5, 0.5), new int[] {64, 128, 128});
|
||||
assert Arrays.equals(hsvToRgb(234, 0.14, 0.88), new int[] {193, 196, 224});
|
||||
assert Arrays.equals(hsvToRgb(330, 0.75, 0.5), new int[] {128, 32, 80});
|
||||
|
||||
// Test rgbToHsv-method
|
||||
// approximate-assertions needed because of small deviations due to converting between
|
||||
// int-values and double-values.
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(0, 0, 0),
|
||||
new double[] { 0, 0, 0 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(255, 255, 255),
|
||||
new double[] { 0, 0, 1 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(255, 0, 0),
|
||||
new double[] { 0, 1, 1 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(255, 255, 0),
|
||||
new double[] { 60, 1, 1 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(0, 255, 0),
|
||||
new double[] { 120, 1, 1 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(0, 0, 255),
|
||||
new double[] { 240, 1, 1 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(255, 0, 255),
|
||||
new double[] { 300, 1, 1 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(64, 128, 128),
|
||||
new double[] { 180, 0.5, 0.5 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(193, 196, 224),
|
||||
new double[] { 234, 0.14, 0.88 }
|
||||
);
|
||||
assert approximatelyEqualHsv(
|
||||
rgbToHsv(128, 32, 80),
|
||||
new double[] { 330, 0.75, 0.5 }
|
||||
);
|
||||
assert approximatelyEqualHsv(rgbToHsv(0, 0, 0), new double[] {0, 0, 0});
|
||||
assert approximatelyEqualHsv(rgbToHsv(255, 255, 255), new double[] {0, 0, 1});
|
||||
assert approximatelyEqualHsv(rgbToHsv(255, 0, 0), new double[] {0, 1, 1});
|
||||
assert approximatelyEqualHsv(rgbToHsv(255, 255, 0), new double[] {60, 1, 1});
|
||||
assert approximatelyEqualHsv(rgbToHsv(0, 255, 0), new double[] {120, 1, 1});
|
||||
assert approximatelyEqualHsv(rgbToHsv(0, 0, 255), new double[] {240, 1, 1});
|
||||
assert approximatelyEqualHsv(rgbToHsv(255, 0, 255), new double[] {300, 1, 1});
|
||||
assert approximatelyEqualHsv(rgbToHsv(64, 128, 128), new double[] {180, 0.5, 0.5});
|
||||
assert approximatelyEqualHsv(rgbToHsv(193, 196, 224), new double[] {234, 0.14, 0.88});
|
||||
assert approximatelyEqualHsv(rgbToHsv(128, 32, 80), new double[] {330, 0.75, 0.5});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -94,35 +55,23 @@ public class RgbHsvConversion {
|
||||
*/
|
||||
public static int[] hsvToRgb(double hue, double saturation, double value) {
|
||||
if (hue < 0 || hue > 360) {
|
||||
throw new IllegalArgumentException(
|
||||
"hue should be between 0 and 360"
|
||||
);
|
||||
throw new IllegalArgumentException("hue should be between 0 and 360");
|
||||
}
|
||||
|
||||
if (saturation < 0 || saturation > 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"saturation should be between 0 and 1"
|
||||
);
|
||||
throw new IllegalArgumentException("saturation should be between 0 and 1");
|
||||
}
|
||||
|
||||
if (value < 0 || value > 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"value should be between 0 and 1"
|
||||
);
|
||||
throw new IllegalArgumentException("value should be between 0 and 1");
|
||||
}
|
||||
|
||||
double chroma = value * saturation;
|
||||
double hueSection = hue / 60;
|
||||
double secondLargestComponent =
|
||||
chroma * (1 - Math.abs(hueSection % 2 - 1));
|
||||
double secondLargestComponent = chroma * (1 - Math.abs(hueSection % 2 - 1));
|
||||
double matchValue = value - chroma;
|
||||
|
||||
return getRgbBySection(
|
||||
hueSection,
|
||||
chroma,
|
||||
matchValue,
|
||||
secondLargestComponent
|
||||
);
|
||||
return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,21 +84,15 @@ public class RgbHsvConversion {
|
||||
*/
|
||||
public static double[] rgbToHsv(int red, int green, int blue) {
|
||||
if (red < 0 || red > 255) {
|
||||
throw new IllegalArgumentException(
|
||||
"red should be between 0 and 255"
|
||||
);
|
||||
throw new IllegalArgumentException("red should be between 0 and 255");
|
||||
}
|
||||
|
||||
if (green < 0 || green > 255) {
|
||||
throw new IllegalArgumentException(
|
||||
"green should be between 0 and 255"
|
||||
);
|
||||
throw new IllegalArgumentException("green should be between 0 and 255");
|
||||
}
|
||||
|
||||
if (blue < 0 || blue > 255) {
|
||||
throw new IllegalArgumentException(
|
||||
"blue should be between 0 and 255"
|
||||
);
|
||||
throw new IllegalArgumentException("blue should be between 0 and 255");
|
||||
}
|
||||
|
||||
double dRed = (double) red / 255;
|
||||
@ -172,7 +115,7 @@ public class RgbHsvConversion {
|
||||
|
||||
hue = (hue + 360) % 360;
|
||||
|
||||
return new double[] { hue, saturation, value };
|
||||
return new double[] {hue, saturation, value};
|
||||
}
|
||||
|
||||
private static boolean approximatelyEqualHsv(double[] hsv1, double[] hsv2) {
|
||||
@ -184,11 +127,7 @@ public class RgbHsvConversion {
|
||||
}
|
||||
|
||||
private static int[] getRgbBySection(
|
||||
double hueSection,
|
||||
double chroma,
|
||||
double matchValue,
|
||||
double secondLargestComponent
|
||||
) {
|
||||
double hueSection, double chroma, double matchValue, double secondLargestComponent) {
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
@ -219,7 +158,7 @@ public class RgbHsvConversion {
|
||||
blue = convertToInt(secondLargestComponent + matchValue);
|
||||
}
|
||||
|
||||
return new int[] { red, green, blue };
|
||||
return new int[] {red, green, blue};
|
||||
}
|
||||
|
||||
private static int convertToInt(double input) {
|
||||
|
@ -58,11 +58,8 @@ public class TurkishToLatinConversion {
|
||||
'G',
|
||||
};
|
||||
for (int i = 0; i < turkishChars.length; i++) {
|
||||
param =
|
||||
param.replaceAll(
|
||||
new String(new char[] { turkishChars[i] }),
|
||||
new String(new char[] { latinChars[i] })
|
||||
);
|
||||
param = param.replaceAll(
|
||||
new String(new char[] {turkishChars[i]}), new String(new char[] {latinChars[i]}));
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ public class CircularBuffer<Item> {
|
||||
private final AtomicInteger size = new AtomicInteger(0);
|
||||
|
||||
public CircularBuffer(int size) {
|
||||
//noinspection unchecked
|
||||
// noinspection unchecked
|
||||
this.buffer = (Item[]) new Object[size];
|
||||
this.putPointer = new CircularPointer(0, size);
|
||||
this.getPointer = new CircularPointer(0, size);
|
||||
@ -24,8 +24,7 @@ public class CircularBuffer<Item> {
|
||||
}
|
||||
|
||||
public Item get() {
|
||||
if (isEmpty())
|
||||
return null;
|
||||
if (isEmpty()) return null;
|
||||
|
||||
Item item = buffer[getPointer.getAndIncrement()];
|
||||
size.decrementAndGet();
|
||||
@ -33,8 +32,7 @@ public class CircularBuffer<Item> {
|
||||
}
|
||||
|
||||
public boolean put(Item item) {
|
||||
if (isFull())
|
||||
return false;
|
||||
if (isFull()) return false;
|
||||
|
||||
buffer[putPointer.getAndIncrement()] = item;
|
||||
size.incrementAndGet();
|
||||
@ -51,8 +49,7 @@ public class CircularBuffer<Item> {
|
||||
}
|
||||
|
||||
public int getAndIncrement() {
|
||||
if (pointer == max)
|
||||
pointer = 0;
|
||||
if (pointer == max) pointer = 0;
|
||||
int tmp = pointer;
|
||||
pointer++;
|
||||
return tmp;
|
||||
|
@ -43,7 +43,8 @@ public class LFUCache<K, V> {
|
||||
* This method returns value present in the cache corresponding to the key passed as parameter
|
||||
*
|
||||
* @param <K> key for which value is to be retrieved
|
||||
* @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is not present in the cache
|
||||
* @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is
|
||||
* not present in the cache
|
||||
*/
|
||||
public V get(K key) {
|
||||
if (this.map.get(key) == null) {
|
||||
|
@ -126,14 +126,10 @@ public class LRUCache<K, V> {
|
||||
private I key;
|
||||
private J value;
|
||||
|
||||
public Entry() {}
|
||||
public Entry() {
|
||||
}
|
||||
|
||||
public Entry(
|
||||
Entry<I, J> preEntry,
|
||||
Entry<I, J> nextEntry,
|
||||
I key,
|
||||
J value
|
||||
) {
|
||||
public Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) {
|
||||
this.preEntry = preEntry;
|
||||
this.nextEntry = nextEntry;
|
||||
this.key = key;
|
||||
|
@ -124,14 +124,10 @@ public class MRUCache<K, V> {
|
||||
private I key;
|
||||
private J value;
|
||||
|
||||
public Entry() {}
|
||||
public Entry() {
|
||||
}
|
||||
|
||||
public Entry(
|
||||
Entry<I, J> preEntry,
|
||||
Entry<I, J> nextEntry,
|
||||
I key,
|
||||
J value
|
||||
) {
|
||||
public Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) {
|
||||
this.preEntry = preEntry;
|
||||
this.nextEntry = nextEntry;
|
||||
this.key = key;
|
||||
|
@ -44,8 +44,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
*/
|
||||
public void add(final E element) {
|
||||
if (this.size == this.elements.length) {
|
||||
this.elements =
|
||||
Arrays.copyOf(this.elements, newCapacity(2 * this.capacity));
|
||||
this.elements = Arrays.copyOf(this.elements, newCapacity(2 * this.capacity));
|
||||
}
|
||||
|
||||
this.elements[this.size] = element;
|
||||
@ -84,8 +83,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
fastRemove(this.elements, index);
|
||||
|
||||
if (this.capacity > DEFAULT_CAPACITY && size * 4 <= this.capacity) {
|
||||
this.elements =
|
||||
Arrays.copyOf(this.elements, newCapacity(this.capacity / 2));
|
||||
this.elements = Arrays.copyOf(this.elements, newCapacity(this.capacity / 2));
|
||||
}
|
||||
return oldElement;
|
||||
}
|
||||
@ -116,13 +114,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
final int newSize = this.size - 1;
|
||||
|
||||
if (newSize > index) {
|
||||
System.arraycopy(
|
||||
elements,
|
||||
index + 1,
|
||||
elements,
|
||||
index,
|
||||
newSize - index
|
||||
);
|
||||
System.arraycopy(elements, index + 1, elements, index, newSize - index);
|
||||
}
|
||||
|
||||
elements[this.size = newSize] = null;
|
||||
@ -144,9 +136,7 @@ public class DynamicArray<E> implements Iterable<E> {
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return Arrays.toString(
|
||||
Arrays.stream(this.elements).filter(Objects::nonNull).toArray()
|
||||
);
|
||||
return Arrays.toString(Arrays.stream(this.elements).filter(Objects::nonNull).toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Time Complexity = O(E), where E is equal to the number of edges
|
||||
Time Complexity = O(E), where E is equal to the number of edges
|
||||
*/
|
||||
package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
@ -64,13 +64,10 @@ public class A_Star {
|
||||
|
||||
private int distance; // distance advanced so far.
|
||||
private ArrayList<Integer> path; // list of visited nodes in this path.
|
||||
private int estimated; // heuristic value associated to the last node od the path (current node).
|
||||
private int
|
||||
estimated; // heuristic value associated to the last node od the path (current node).
|
||||
|
||||
public PathAndDistance(
|
||||
int distance,
|
||||
ArrayList<Integer> path,
|
||||
int estimated
|
||||
) {
|
||||
public PathAndDistance(int distance, ArrayList<Integer> path, int estimated) {
|
||||
this.distance = distance;
|
||||
this.path = path;
|
||||
this.estimated = estimated;
|
||||
@ -90,25 +87,16 @@ public class A_Star {
|
||||
|
||||
private void printSolution() {
|
||||
if (this.path != null) {
|
||||
System.out.println(
|
||||
"Optimal path: " +
|
||||
this.path +
|
||||
", distance: " +
|
||||
this.distance
|
||||
);
|
||||
System.out.println("Optimal path: " + this.path + ", distance: " + this.distance);
|
||||
} else {
|
||||
System.out.println(
|
||||
"There is no path available to connect the points"
|
||||
);
|
||||
System.out.println("There is no path available to connect the points");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeGraph(Graph graph, ArrayList<Integer> data) {
|
||||
for (int i = 0; i < data.size(); i += 4) {
|
||||
graph.addEdge(
|
||||
new Edge(data.get(i), data.get(i + 1), data.get(i + 2))
|
||||
);
|
||||
graph.addEdge(new Edge(data.get(i), data.get(i + 1), data.get(i + 2)));
|
||||
}
|
||||
/*
|
||||
.x. node
|
||||
@ -165,123 +153,24 @@ public class A_Star {
|
||||
};
|
||||
|
||||
Graph graph = new Graph(20);
|
||||
ArrayList<Integer> graphData = new ArrayList<>(
|
||||
Arrays.asList(
|
||||
0,
|
||||
19,
|
||||
75,
|
||||
null,
|
||||
0,
|
||||
15,
|
||||
140,
|
||||
null,
|
||||
0,
|
||||
16,
|
||||
118,
|
||||
null,
|
||||
19,
|
||||
12,
|
||||
71,
|
||||
null,
|
||||
12,
|
||||
15,
|
||||
151,
|
||||
null,
|
||||
16,
|
||||
9,
|
||||
111,
|
||||
null,
|
||||
9,
|
||||
10,
|
||||
70,
|
||||
null,
|
||||
10,
|
||||
3,
|
||||
75,
|
||||
null,
|
||||
3,
|
||||
2,
|
||||
120,
|
||||
null,
|
||||
2,
|
||||
14,
|
||||
146,
|
||||
null,
|
||||
2,
|
||||
13,
|
||||
138,
|
||||
null,
|
||||
2,
|
||||
6,
|
||||
115,
|
||||
null,
|
||||
15,
|
||||
14,
|
||||
80,
|
||||
null,
|
||||
15,
|
||||
5,
|
||||
99,
|
||||
null,
|
||||
14,
|
||||
13,
|
||||
97,
|
||||
null,
|
||||
5,
|
||||
1,
|
||||
211,
|
||||
null,
|
||||
13,
|
||||
1,
|
||||
101,
|
||||
null,
|
||||
6,
|
||||
1,
|
||||
160,
|
||||
null,
|
||||
1,
|
||||
17,
|
||||
85,
|
||||
null,
|
||||
17,
|
||||
7,
|
||||
98,
|
||||
null,
|
||||
7,
|
||||
4,
|
||||
86,
|
||||
null,
|
||||
17,
|
||||
18,
|
||||
142,
|
||||
null,
|
||||
18,
|
||||
8,
|
||||
92,
|
||||
null,
|
||||
8,
|
||||
11,
|
||||
87
|
||||
)
|
||||
);
|
||||
ArrayList<Integer> graphData = new ArrayList<>(Arrays.asList(0, 19, 75, null, 0, 15, 140,
|
||||
null, 0, 16, 118, null, 19, 12, 71, null, 12, 15, 151, null, 16, 9, 111, null, 9, 10,
|
||||
70, null, 10, 3, 75, null, 3, 2, 120, null, 2, 14, 146, null, 2, 13, 138, null, 2, 6,
|
||||
115, null, 15, 14, 80, null, 15, 5, 99, null, 14, 13, 97, null, 5, 1, 211, null, 13, 1,
|
||||
101, null, 6, 1, 160, null, 1, 17, 85, null, 17, 7, 98, null, 7, 4, 86, null, 17, 18,
|
||||
142, null, 18, 8, 92, null, 8, 11, 87));
|
||||
initializeGraph(graph, graphData);
|
||||
|
||||
PathAndDistance solution = aStar(3, 1, graph, heuristic);
|
||||
solution.printSolution();
|
||||
}
|
||||
|
||||
public static PathAndDistance aStar(
|
||||
int from,
|
||||
int to,
|
||||
Graph graph,
|
||||
int[] heuristic
|
||||
) {
|
||||
public static PathAndDistance aStar(int from, int to, Graph graph, int[] heuristic) {
|
||||
// nodes are prioritised by the less value of the current distance of their paths, and the
|
||||
// estimated value
|
||||
// given by the heuristic function to reach the destination point from the current point.
|
||||
PriorityQueue<PathAndDistance> queue = new PriorityQueue<>(
|
||||
Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated()))
|
||||
);
|
||||
Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated())));
|
||||
|
||||
// dummy data to start the algorithm from the beginning point
|
||||
queue.add(new PathAndDistance(0, new ArrayList<>(List.of(from)), 0));
|
||||
@ -290,34 +179,25 @@ public class A_Star {
|
||||
PathAndDistance currentData = new PathAndDistance(-1, null, -1);
|
||||
while (!queue.isEmpty() && !solutionFound) {
|
||||
currentData = queue.poll(); // first in the queue, best node so keep exploring.
|
||||
int currentPosition = currentData
|
||||
.getPath()
|
||||
.get(currentData.getPath().size() - 1); // current node.
|
||||
int currentPosition
|
||||
= currentData.getPath().get(currentData.getPath().size() - 1); // current node.
|
||||
if (currentPosition == to) {
|
||||
solutionFound = true;
|
||||
} else {
|
||||
for (Edge edge : graph.getNeighbours(currentPosition)) {
|
||||
if (!currentData.getPath().contains(edge.getTo())) { // Avoid Cycles
|
||||
ArrayList<Integer> updatedPath = new ArrayList<>(
|
||||
currentData.getPath()
|
||||
);
|
||||
updatedPath.add(edge.getTo()); // Add the new node to the path, update the distance,
|
||||
ArrayList<Integer> updatedPath = new ArrayList<>(currentData.getPath());
|
||||
updatedPath.add(
|
||||
edge.getTo()); // Add the new node to the path, update the distance,
|
||||
// and the heuristic function value associated to that path.
|
||||
queue.add(
|
||||
new PathAndDistance(
|
||||
currentData.getDistance() + edge.getWeight(),
|
||||
updatedPath,
|
||||
heuristic[edge.getTo()]
|
||||
)
|
||||
);
|
||||
queue.add(new PathAndDistance(currentData.getDistance() + edge.getWeight(),
|
||||
updatedPath, heuristic[edge.getTo()]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (solutionFound)
|
||||
? currentData
|
||||
: new PathAndDistance(-1, null, -1);
|
||||
// Out of while loop, if there is a solution, the current Data stores the optimal path, and its
|
||||
// distance
|
||||
return (solutionFound) ? currentData : new PathAndDistance(-1, null, -1);
|
||||
// Out of while loop, if there is a solution, the current Data stores the optimal path, and
|
||||
// its distance
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,10 @@ package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs in form of edges which have
|
||||
start vertex, end vertex and weights. Vertices should be labelled with a number between 0 and total number of vertices-1,both inclusive*/{
|
||||
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs
|
||||
in form of edges which have start vertex, end vertex and weights. Vertices should be labelled with a
|
||||
number between 0 and total number of vertices-1,both inclusive*/
|
||||
{
|
||||
|
||||
int vertex, edge;
|
||||
private Edge[] edges;
|
||||
@ -49,7 +51,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
obj.go();
|
||||
}
|
||||
|
||||
public void go() { // shows distance to all vertices // Interactive run for understanding the class first time. Assumes source vertex is 0 and
|
||||
public void go() { // shows distance to all vertices // Interactive run for understanding the
|
||||
// class first time. Assumes source vertex is 0 and
|
||||
Scanner sc = new Scanner(System.in); // Grab scanner object for user input
|
||||
int i, v, e, u, ve, w, j, neg = 0;
|
||||
System.out.println("Enter no. of vertices and edges please");
|
||||
@ -63,7 +66,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
w = sc.nextInt();
|
||||
arr[i] = new Edge(u, ve, w);
|
||||
}
|
||||
int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance between source
|
||||
int[] dist = new int[v]; // Distance array for holding the finalized shortest path distance
|
||||
// between source
|
||||
// and all vertices
|
||||
int[] p = new int[v]; // Parent array for holding the paths
|
||||
for (i = 0; i < v; i++) {
|
||||
@ -73,10 +77,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
p[0] = -1;
|
||||
for (i = 0; i < v - 1; i++) {
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if (dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
|
||||
p[arr[j].v] = arr[j].u;
|
||||
}
|
||||
@ -84,10 +86,7 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
}
|
||||
// Final cycle for negative checking
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if (dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
neg = 1;
|
||||
System.out.println("Negative cycle");
|
||||
break;
|
||||
@ -113,9 +112,13 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
* @param end Ending vertex
|
||||
* @param Edge Array of edges
|
||||
*/
|
||||
public void show(int source, int end, Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray() method // Just shows results of computation, if graph is passed to it. The graph should
|
||||
public void show(int source, int end,
|
||||
Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray()
|
||||
// method // Just shows results of computation, if graph is passed to it. The
|
||||
// graph should
|
||||
int i, j, v = vertex, e = edge, neg = 0;
|
||||
double[] dist = new double[v]; // Distance array for holding the finalized shortest path distance between source
|
||||
double[] dist = new double[v]; // Distance array for holding the finalized shortest path
|
||||
// distance between source
|
||||
// and all vertices
|
||||
int[] p = new int[v]; // Parent array for holding the paths
|
||||
for (i = 0; i < v; i++) {
|
||||
@ -125,10 +128,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
p[source] = -1;
|
||||
for (i = 0; i < v - 1; i++) {
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
(int) dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
|
||||
p[arr[j].v] = arr[j].u;
|
||||
}
|
||||
@ -136,10 +137,8 @@ start vertex, end vertex and weights. Vertices should be labelled with a number
|
||||
}
|
||||
// Final cycle for negative checking
|
||||
for (j = 0; j < e; j++) {
|
||||
if (
|
||||
(int) dist[arr[j].u] != Integer.MAX_VALUE &&
|
||||
dist[arr[j].v] > dist[arr[j].u] + arr[j].w
|
||||
) {
|
||||
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
|
||||
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
|
||||
neg = 1;
|
||||
System.out.println("Negative cycle");
|
||||
break;
|
||||
|
@ -17,11 +17,7 @@ import java.util.Arrays;
|
||||
public class BipartiteGrapfDFS {
|
||||
|
||||
private static boolean bipartite(
|
||||
int V,
|
||||
ArrayList<ArrayList<Integer>> adj,
|
||||
int[] color,
|
||||
int node
|
||||
) {
|
||||
int V, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
|
||||
if (color[node] == -1) {
|
||||
color[node] = 1;
|
||||
}
|
||||
@ -38,10 +34,7 @@ public class BipartiteGrapfDFS {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean isBipartite(
|
||||
int V,
|
||||
ArrayList<ArrayList<Integer>> adj
|
||||
) {
|
||||
public static boolean isBipartite(int V, ArrayList<ArrayList<Integer>> adj) {
|
||||
// Code here
|
||||
int[] color = new int[V + 1];
|
||||
Arrays.fill(color, -1);
|
||||
@ -57,9 +50,7 @@ public class BipartiteGrapfDFS {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
BufferedReader read = new BufferedReader(
|
||||
new InputStreamReader(System.in)
|
||||
);
|
||||
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
|
||||
int t = Integer.parseInt(read.readLine().trim());
|
||||
while (t-- > 0) {
|
||||
String[] S = read.readLine().trim().split(" ");
|
||||
|
@ -137,11 +137,7 @@ public class ConnectedComponent {
|
||||
graphInts.addEdge(8, 10);
|
||||
graphInts.addEdge(10, 8);
|
||||
|
||||
System.out.println(
|
||||
"Amount of different char-graphs: " + graphChars.countGraphs()
|
||||
);
|
||||
System.out.println(
|
||||
"Amount of different int-graphs: " + graphInts.countGraphs()
|
||||
);
|
||||
System.out.println("Amount of different char-graphs: " + graphChars.countGraphs());
|
||||
System.out.println("Amount of different int-graphs: " + graphInts.countGraphs());
|
||||
}
|
||||
}
|
||||
|
@ -24,9 +24,7 @@ class Cycle {
|
||||
visited[i] = false;
|
||||
}
|
||||
|
||||
System.out.println(
|
||||
"Enter the details of each edges <Start Node> <End Node>"
|
||||
);
|
||||
System.out.println("Enter the details of each edges <Start Node> <End Node>");
|
||||
|
||||
for (int i = 0; i < edges; i++) {
|
||||
int start, end;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Refer https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/
|
||||
for better understanding
|
||||
for better understanding
|
||||
*/
|
||||
package com.thealgorithms.datastructures.graphs;
|
||||
|
||||
@ -45,12 +45,8 @@ class dijkstras {
|
||||
Set[u] = true;
|
||||
|
||||
for (int v = 0; v < k; v++) {
|
||||
if (
|
||||
!Set[v] &&
|
||||
graph[u][v] != 0 &&
|
||||
dist[u] != Integer.MAX_VALUE &&
|
||||
dist[u] + graph[u][v] < dist[v]
|
||||
) {
|
||||
if (!Set[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE
|
||||
&& dist[u] + graph[u][v] < dist[v]) {
|
||||
dist[v] = dist[u] + graph[u][v];
|
||||
}
|
||||
}
|
||||
@ -61,23 +57,23 @@ class dijkstras {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[][] graph = new int[][] {
|
||||
{ 0, 4, 0, 0, 0, 0, 0, 8, 0 },
|
||||
{ 4, 0, 8, 0, 0, 0, 0, 11, 0 },
|
||||
{ 0, 8, 0, 7, 0, 4, 0, 0, 2 },
|
||||
{ 0, 0, 7, 0, 9, 14, 0, 0, 0 },
|
||||
{ 0, 0, 0, 9, 0, 10, 0, 0, 0 },
|
||||
{ 0, 0, 4, 14, 10, 0, 2, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 2, 0, 1, 6 },
|
||||
{ 8, 11, 0, 0, 0, 0, 1, 0, 7 },
|
||||
{ 0, 0, 2, 0, 0, 0, 6, 7, 0 },
|
||||
{0, 4, 0, 0, 0, 0, 0, 8, 0},
|
||||
{4, 0, 8, 0, 0, 0, 0, 11, 0},
|
||||
{0, 8, 0, 7, 0, 4, 0, 0, 2},
|
||||
{0, 0, 7, 0, 9, 14, 0, 0, 0},
|
||||
{0, 0, 0, 9, 0, 10, 0, 0, 0},
|
||||
{0, 0, 4, 14, 10, 0, 2, 0, 0},
|
||||
{0, 0, 0, 0, 0, 2, 0, 1, 6},
|
||||
{8, 11, 0, 0, 0, 0, 1, 0, 7},
|
||||
{0, 0, 2, 0, 0, 0, 6, 7, 0},
|
||||
};
|
||||
dijkstras t = new dijkstras();
|
||||
t.dijkstra(graph, 0);
|
||||
} //main
|
||||
} //djikstras
|
||||
} // main
|
||||
} // djikstras
|
||||
/*
|
||||
OUTPUT :
|
||||
Vertex Distance
|
||||
Vertex Distance
|
||||
0 0
|
||||
1 4
|
||||
2 12
|
||||
|
@ -9,42 +9,32 @@ public class FloydWarshall {
|
||||
public static final int INFINITY = 999;
|
||||
|
||||
public FloydWarshall(int numberofvertices) {
|
||||
DistanceMatrix = new int[numberofvertices + 1][numberofvertices + 1]; // stores the value of distance from all the possible path form the source
|
||||
DistanceMatrix = new int[numberofvertices + 1][numberofvertices
|
||||
+ 1]; // stores the value of distance from all the possible path form the source
|
||||
// vertex to destination vertex
|
||||
// The matrix is initialized with 0's by default
|
||||
this.numberofvertices = numberofvertices;
|
||||
}
|
||||
|
||||
public void floydwarshall(int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex
|
||||
public void floydwarshall(
|
||||
int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
DistanceMatrix[source][destination] =
|
||||
AdjacencyMatrix[source][destination];
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination];
|
||||
}
|
||||
}
|
||||
for (
|
||||
int intermediate = 1;
|
||||
intermediate <= numberofvertices;
|
||||
intermediate++
|
||||
) {
|
||||
for (int intermediate = 1; intermediate <= numberofvertices; intermediate++) {
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
if (
|
||||
DistanceMatrix[source][intermediate] +
|
||||
DistanceMatrix[intermediate][destination] <
|
||||
DistanceMatrix[source][destination]
|
||||
) { // calculated distance it get replaced as new shortest distance // if the new distance calculated is less then the earlier shortest
|
||||
DistanceMatrix[source][destination] =
|
||||
DistanceMatrix[source][intermediate] +
|
||||
DistanceMatrix[intermediate][destination];
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
if (DistanceMatrix[source][intermediate]
|
||||
+ DistanceMatrix[intermediate][destination]
|
||||
< DistanceMatrix[source]
|
||||
[destination]) { // calculated distance it get replaced as
|
||||
// new shortest distance // if the new
|
||||
// distance calculated is less then the
|
||||
// earlier shortest
|
||||
DistanceMatrix[source][destination] = DistanceMatrix[source][intermediate]
|
||||
+ DistanceMatrix[intermediate][destination];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -55,11 +45,7 @@ public class FloydWarshall {
|
||||
System.out.println();
|
||||
for (int source = 1; source <= numberofvertices; source++) {
|
||||
System.out.print(source + "\t");
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberofvertices;
|
||||
destination++
|
||||
) {
|
||||
for (int destination = 1; destination <= numberofvertices; destination++) {
|
||||
System.out.print(DistanceMatrix[source][destination] + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
@ -70,15 +56,10 @@ public class FloydWarshall {
|
||||
Scanner scan = new Scanner(System.in);
|
||||
System.out.println("Enter the number of vertices");
|
||||
int numberOfVertices = scan.nextInt();
|
||||
int[][] adjacencyMatrix = new int[numberOfVertices +
|
||||
1][numberOfVertices + 1];
|
||||
int[][] adjacencyMatrix = new int[numberOfVertices + 1][numberOfVertices + 1];
|
||||
System.out.println("Enter the Weighted Matrix for the graph");
|
||||
for (int source = 1; source <= numberOfVertices; source++) {
|
||||
for (
|
||||
int destination = 1;
|
||||
destination <= numberOfVertices;
|
||||
destination++
|
||||
) {
|
||||
for (int destination = 1; destination <= numberOfVertices; destination++) {
|
||||
adjacencyMatrix[source][destination] = scan.nextInt();
|
||||
if (source == destination) {
|
||||
adjacencyMatrix[source][destination] = 0;
|
||||
|
@ -21,7 +21,7 @@ public class HamiltonianCycle {
|
||||
this.V = graph.length;
|
||||
this.cycle = new int[this.V + 1];
|
||||
|
||||
//Initialize path array with -1 value
|
||||
// Initialize path array with -1 value
|
||||
for (int i = 0; i < this.cycle.length; i++) {
|
||||
this.cycle[i] = -1;
|
||||
}
|
||||
@ -41,13 +41,15 @@ public class HamiltonianCycle {
|
||||
return cycle;
|
||||
}
|
||||
|
||||
/** function to find paths recursively
|
||||
/**
|
||||
* function to find paths recursively
|
||||
* Find paths recursively from given vertex
|
||||
* @param vertex Vertex from which path is to be found
|
||||
* @returns true if path is found false otherwise
|
||||
*/
|
||||
public boolean isPathFound(int vertex) {
|
||||
boolean isLastVertexConnectedToStart = this.graph[vertex][0] == 1 && this.pathCount == this.V;
|
||||
boolean isLastVertexConnectedToStart
|
||||
= this.graph[vertex][0] == 1 && this.pathCount == this.V;
|
||||
if (isLastVertexConnectedToStart) {
|
||||
return true;
|
||||
}
|
||||
@ -83,7 +85,8 @@ public class HamiltonianCycle {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** function to check if path is already selected
|
||||
/**
|
||||
* function to check if path is already selected
|
||||
* Check if path is already selected
|
||||
* @param vertex Starting vertex
|
||||
*/
|
||||
|
@ -133,7 +133,7 @@ class TopologicalSort<E extends Comparable<E>> {
|
||||
public class KahnsAlgorithm {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//Graph definition and initialization
|
||||
// Graph definition and initialization
|
||||
AdjacencyList<String> graph = new AdjacencyList<>();
|
||||
graph.addEdge("a", "b");
|
||||
graph.addEdge("c", "a");
|
||||
@ -144,7 +144,7 @@ public class KahnsAlgorithm {
|
||||
|
||||
TopologicalSort<String> topSort = new TopologicalSort<>(graph);
|
||||
|
||||
//Printing the order
|
||||
// Printing the order
|
||||
for (String s : topSort.topSortOrder()) {
|
||||
System.out.print(s + " ");
|
||||
}
|
||||
|
@ -7,17 +7,18 @@ import java.util.Stack;
|
||||
/**
|
||||
* Java program that implements Kosaraju Algorithm.
|
||||
* @author Shivanagouda S A (https://github.com/shivu2002a)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the transpose
|
||||
graph (same graph with all the edges reversed) has exactly the same SCCs as the original graph.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly connected.
|
||||
Single node is always a SCC.
|
||||
* Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the
|
||||
transpose graph (same graph with all the edges reversed) has exactly the same SCCs as the original
|
||||
graph.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly
|
||||
connected. Single node is always a SCC.
|
||||
|
||||
* Example:
|
||||
|
||||
@ -26,19 +27,20 @@ import java.util.Stack;
|
||||
| / | \ /
|
||||
| / | \ /
|
||||
v / v \ /
|
||||
1 5 --> 6
|
||||
1 5 --> 6
|
||||
|
||||
For the above graph, the SCC list goes as follows:
|
||||
0, 1, 2
|
||||
0, 1, 2
|
||||
3
|
||||
4, 5, 6
|
||||
7
|
||||
|
||||
|
||||
We can also see that order of the nodes in an SCC doesn't matter since they are in cycle.
|
||||
|
||||
{@summary}
|
||||
* Kosaraju Algorithm:
|
||||
1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges sorted by lowest finish time.
|
||||
* Kosaraju Algorithm:
|
||||
1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges
|
||||
sorted by lowest finish time.
|
||||
2. Find the transpose graph by reversing the edges.
|
||||
3. Pop nodes one by one from the stack and again to DFS on the modified graph.
|
||||
|
||||
@ -48,7 +50,7 @@ import java.util.Stack;
|
||||
| / | \ /
|
||||
| / | \ /
|
||||
| v | v v
|
||||
1 5 <--- 6
|
||||
1 5 <--- 6
|
||||
|
||||
We can observe that this graph has the same SCC as that of original graph.
|
||||
|
||||
@ -59,33 +61,33 @@ public class Kosaraju {
|
||||
// Sort edges according to lowest finish time
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
|
||||
//Store each component
|
||||
// Store each component
|
||||
private List<Integer> scc = new ArrayList<>();
|
||||
|
||||
//All the strongly connected components
|
||||
// All the strongly connected components
|
||||
private List<List<Integer>> sccsList = new ArrayList<>();
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param v Node count
|
||||
* @param list Adjacency list of graph
|
||||
* @return List of SCCs
|
||||
*/
|
||||
public List<List<Integer>> kosaraju(int v, List<List<Integer>> list){
|
||||
|
||||
public List<List<Integer>> kosaraju(int v, List<List<Integer>> list) {
|
||||
|
||||
sortEdgesByLowestFinishTime(v, list);
|
||||
|
||||
|
||||
List<List<Integer>> transposeGraph = createTransposeMatrix(v, list);
|
||||
|
||||
findStronglyConnectedComponents(v, transposeGraph);
|
||||
|
||||
|
||||
return sccsList;
|
||||
}
|
||||
|
||||
private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list){
|
||||
private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list) {
|
||||
int[] vis = new int[v];
|
||||
for (int i = 0; i < v; i++) {
|
||||
if(vis[i] == 0){
|
||||
if (vis[i] == 0) {
|
||||
dfs(i, vis, list);
|
||||
}
|
||||
}
|
||||
@ -105,15 +107,15 @@ public class Kosaraju {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param v Node count
|
||||
* @param transposeGraph Transpose of the given adjacency list
|
||||
*/
|
||||
public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph){
|
||||
public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph) {
|
||||
int[] vis = new int[v];
|
||||
while (!stack.isEmpty()) {
|
||||
var node = stack.pop();
|
||||
if(vis[node] == 0){
|
||||
if (vis[node] == 0) {
|
||||
dfs2(node, vis, transposeGraph);
|
||||
sccsList.add(scc);
|
||||
scc = new ArrayList<>();
|
||||
@ -121,24 +123,21 @@ public class Kosaraju {
|
||||
}
|
||||
}
|
||||
|
||||
//Dfs to store the nodes in order of lowest finish time
|
||||
private void dfs(int node, int[] vis, List<List<Integer>> list){
|
||||
// Dfs to store the nodes in order of lowest finish time
|
||||
private void dfs(int node, int[] vis, List<List<Integer>> list) {
|
||||
vis[node] = 1;
|
||||
for(Integer neighbour : list.get(node)){
|
||||
if(vis[neighbour] == 0)
|
||||
dfs(neighbour, vis, list);
|
||||
for (Integer neighbour : list.get(node)) {
|
||||
if (vis[neighbour] == 0) dfs(neighbour, vis, list);
|
||||
}
|
||||
stack.push(node);
|
||||
}
|
||||
|
||||
//Dfs to find all the nodes of each strongly connected component
|
||||
private void dfs2(int node, int[] vis, List<List<Integer>> list){
|
||||
// Dfs to find all the nodes of each strongly connected component
|
||||
private void dfs2(int node, int[] vis, List<List<Integer>> list) {
|
||||
vis[node] = 1;
|
||||
for(Integer neighbour : list.get(node)){
|
||||
if(vis[neighbour] == 0)
|
||||
dfs2(neighbour, vis, list);
|
||||
for (Integer neighbour : list.get(node)) {
|
||||
if (vis[neighbour] == 0) dfs2(neighbour, vis, list);
|
||||
}
|
||||
scc.add(node);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ import java.util.PriorityQueue;
|
||||
|
||||
public class Kruskal {
|
||||
|
||||
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number of
|
||||
// vertices
|
||||
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number
|
||||
// of vertices
|
||||
private static class Edge {
|
||||
|
||||
private int from;
|
||||
@ -30,12 +30,7 @@ public class Kruskal {
|
||||
}
|
||||
}
|
||||
|
||||
private static void addEdge(
|
||||
HashSet<Edge>[] graph,
|
||||
int from,
|
||||
int to,
|
||||
int weight
|
||||
) {
|
||||
private static void addEdge(HashSet<Edge>[] graph, int from, int to, int weight) {
|
||||
graph[from].add(new Edge(from, to, weight));
|
||||
}
|
||||
|
||||
@ -58,9 +53,7 @@ public class Kruskal {
|
||||
System.out.println("Initial Graph: ");
|
||||
for (int i = 0; i < graph.length; i++) {
|
||||
for (Edge edge : graph[i]) {
|
||||
System.out.println(
|
||||
i + " <-- weight " + edge.weight + " --> " + edge.to
|
||||
);
|
||||
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,9 +63,7 @@ public class Kruskal {
|
||||
System.out.println("\nMinimal Graph: ");
|
||||
for (int i = 0; i < solGraph.length; i++) {
|
||||
for (Edge edge : solGraph[i]) {
|
||||
System.out.println(
|
||||
i + " <-- weight " + edge.weight + " --> " + edge.to
|
||||
);
|
||||
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -83,9 +74,8 @@ public class Kruskal {
|
||||
// captain of i, stores the set with all the connected nodes to i
|
||||
HashSet<Integer>[] connectedGroups = new HashSet[nodes];
|
||||
HashSet<Edge>[] minGraph = new HashSet[nodes];
|
||||
PriorityQueue<Edge> edges = new PriorityQueue<>(
|
||||
(Comparator.comparingInt(edge -> edge.weight))
|
||||
);
|
||||
PriorityQueue<Edge> edges
|
||||
= new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight)));
|
||||
for (int i = 0; i < nodes; i++) {
|
||||
minGraph[i] = new HashSet<>();
|
||||
connectedGroups[i] = new HashSet<>();
|
||||
@ -98,18 +88,12 @@ public class Kruskal {
|
||||
while (connectedElements != nodes && !edges.isEmpty()) {
|
||||
Edge edge = edges.poll();
|
||||
// This if avoids cycles
|
||||
if (
|
||||
!connectedGroups[captain[edge.from]].contains(edge.to) &&
|
||||
!connectedGroups[captain[edge.to]].contains(edge.from)
|
||||
) {
|
||||
if (!connectedGroups[captain[edge.from]].contains(edge.to)
|
||||
&& !connectedGroups[captain[edge.to]].contains(edge.from)) {
|
||||
// merge sets of the captains of each point connected by the edge
|
||||
connectedGroups[captain[edge.from]].addAll(
|
||||
connectedGroups[captain[edge.to]]
|
||||
);
|
||||
connectedGroups[captain[edge.from]].addAll(connectedGroups[captain[edge.to]]);
|
||||
// update captains of the elements merged
|
||||
connectedGroups[captain[edge.from]].forEach(i ->
|
||||
captain[i] = captain[edge.from]
|
||||
);
|
||||
connectedGroups[captain[edge.from]].forEach(i -> captain[i] = captain[edge.from]);
|
||||
// add Edge to minimal graph
|
||||
addEdge(minGraph, edge.from, edge.to, edge.weight);
|
||||
// count how many elements have been merged
|
||||
|
@ -71,9 +71,7 @@ class AdjacencyMatrixGraph {
|
||||
public AdjacencyMatrixGraph(int givenNumberOfVertices) {
|
||||
this.setNumberOfVertices(givenNumberOfVertices);
|
||||
this.setNumberOfEdges(0);
|
||||
this.setAdjacency(
|
||||
new int[givenNumberOfVertices][givenNumberOfVertices]
|
||||
);
|
||||
this.setAdjacency(new int[givenNumberOfVertices][givenNumberOfVertices]);
|
||||
for (int i = 0; i < givenNumberOfVertices; i++) {
|
||||
for (int j = 0; j < givenNumberOfVertices; j++) {
|
||||
this.adjacency()[i][j] = AdjacencyMatrixGraph.EDGE_NONE;
|
||||
@ -247,11 +245,7 @@ class AdjacencyMatrixGraph {
|
||||
* has been visited
|
||||
* @param orderList the list to add vertices to as they are visited
|
||||
*/
|
||||
private void depthFirstOrder(
|
||||
int currentVertex,
|
||||
boolean[] visited,
|
||||
List<Integer> orderList
|
||||
) {
|
||||
private void depthFirstOrder(int currentVertex, boolean[] visited, List<Integer> orderList) {
|
||||
// If this vertex has already been visited, do nothing and return
|
||||
if (visited[currentVertex]) {
|
||||
return;
|
||||
@ -264,11 +258,9 @@ class AdjacencyMatrixGraph {
|
||||
|
||||
// Get the adjacency array for this vertex
|
||||
int[] adjacent = _adjacency[currentVertex];
|
||||
for (
|
||||
int i = 0;
|
||||
i < adjacent.length;
|
||||
i++
|
||||
) { // we are considering exploring, recurse on it // If an edge exists between the currentVertex and the vertex
|
||||
for (int i = 0; i < adjacent.length;
|
||||
i++) { // we are considering exploring, recurse on it // If an edge exists between the
|
||||
// currentVertex and the vertex
|
||||
if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) {
|
||||
depthFirstOrder(i, visited, orderList);
|
||||
}
|
||||
@ -317,11 +309,9 @@ class AdjacencyMatrixGraph {
|
||||
// Get the adjacency array for the currentVertex and
|
||||
// check each node
|
||||
int[] adjacent = _adjacency[currentVertex];
|
||||
for (
|
||||
int vertex = 0;
|
||||
vertex < adjacent.length;
|
||||
vertex++
|
||||
) { // vertex we are considering exploring, we add it to the queue // If an edge exists between the current vertex and the
|
||||
for (int vertex = 0; vertex < adjacent.length;
|
||||
vertex++) { // vertex we are considering exploring, we add it to the queue // If an
|
||||
// edge exists between the current vertex and the
|
||||
if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) {
|
||||
queue.add(vertex);
|
||||
}
|
||||
|
@ -31,9 +31,7 @@ class PrimMST {
|
||||
void printMST(int[] parent, int n, int[][] graph) {
|
||||
System.out.println("Edge Weight");
|
||||
for (int i = 1; i < V; i++) {
|
||||
System.out.println(
|
||||
parent[i] + " - " + i + " " + graph[i][parent[i]]
|
||||
);
|
||||
System.out.println(parent[i] + " - " + i + " " + graph[i][parent[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,17 +70,12 @@ class PrimMST {
|
||||
// Update key value and parent index of the adjacent
|
||||
// vertices of the picked vertex. Consider only those
|
||||
// vertices which are not yet included in MST
|
||||
for (
|
||||
int v = 0;
|
||||
v < V;
|
||||
v++
|
||||
) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is false for vertices not yet included in MST // graph[u][v] is non zero only for adjacent vertices of m
|
||||
for (int v = 0; v < V;
|
||||
v++) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is
|
||||
// false for vertices not yet included in MST // graph[u][v] is non zero only
|
||||
// for adjacent vertices of m
|
||||
{
|
||||
if (
|
||||
graph[u][v] != 0 &&
|
||||
!mstSet[v] &&
|
||||
graph[u][v] < key[v]
|
||||
) {
|
||||
if (graph[u][v] != 0 && !mstSet[v] && graph[u][v] < key[v]) {
|
||||
parent[v] = u;
|
||||
key[v] = graph[u][v];
|
||||
}
|
||||
@ -104,11 +97,11 @@ class PrimMST {
|
||||
9 */
|
||||
PrimMST t = new PrimMST();
|
||||
int[][] graph = new int[][] {
|
||||
{ 0, 2, 0, 6, 0 },
|
||||
{ 2, 0, 3, 8, 5 },
|
||||
{ 0, 3, 0, 0, 7 },
|
||||
{ 6, 8, 0, 0, 9 },
|
||||
{ 0, 5, 7, 9, 0 },
|
||||
{0, 2, 0, 6, 0},
|
||||
{2, 0, 3, 8, 5},
|
||||
{0, 3, 0, 0, 7},
|
||||
{6, 8, 0, 0, 9},
|
||||
{0, 5, 7, 9, 0},
|
||||
};
|
||||
|
||||
// Print the solution
|
||||
|
@ -8,16 +8,16 @@ import java.util.Stack;
|
||||
/**
|
||||
* Java program that implements Tarjan's Algorithm.
|
||||
* @author Shivanagouda S A (https://github.com/shivu2002a)
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred as SCC.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly connected.
|
||||
Single node is always a SCC.
|
||||
* Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a
|
||||
directed graph, which, from here onwards will be referred as SCC.
|
||||
|
||||
* A graph is said to be strongly connected if every vertex is reachable from every other vertex.
|
||||
The SCCs of a directed graph form a partition into subgraphs that are themselves strongly
|
||||
connected. Single node is always a SCC.
|
||||
|
||||
* Example:
|
||||
0 --------> 1 -------> 3 --------> 4
|
||||
@ -38,24 +38,25 @@ import java.util.Stack;
|
||||
1, 2, 0
|
||||
3
|
||||
4
|
||||
|
||||
|
||||
We can also see that order of the nodes in an SCC doesn't matter since they are in cycle.
|
||||
|
||||
{@summary}
|
||||
Tarjan's Algorithm:
|
||||
* DFS search produces a DFS tree
|
||||
* Strongly Connected Components form subtrees of the DFS tree.
|
||||
* If we can find the head of these subtrees, we can get all the nodes in that subtree (including the head)
|
||||
and that will be one SCC.
|
||||
* There is no back edge from one SCC to another (here can be cross edges, but they will not be used).
|
||||
Tarjan's Algorithm:
|
||||
* DFS search produces a DFS tree
|
||||
* Strongly Connected Components form subtrees of the DFS tree.
|
||||
* If we can find the head of these subtrees, we can get all the nodes in that subtree (including
|
||||
the head) and that will be one SCC.
|
||||
* There is no back edge from one SCC to another (here can be cross edges, but they will not be
|
||||
used).
|
||||
|
||||
* Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s algorithm does
|
||||
the same in a single DFS, which leads to much lower constant factors in the latter.
|
||||
* Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s
|
||||
algorithm does the same in a single DFS, which leads to much lower constant factors in the latter.
|
||||
|
||||
*/
|
||||
public class TarjansAlgorithm {
|
||||
|
||||
//Timer for tracking lowtime and insertion time
|
||||
// Timer for tracking lowtime and insertion time
|
||||
private int Time;
|
||||
|
||||
private List<List<Integer>> SCClist = new ArrayList<List<Integer>>();
|
||||
@ -66,15 +67,15 @@ public class TarjansAlgorithm {
|
||||
|
||||
// insertionTime:Time when a node is visited 1st time while DFS traversal
|
||||
|
||||
// lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time) that can
|
||||
// be reached from a subtree rooted with a particular node.
|
||||
// lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time)
|
||||
// that can be reached from a subtree rooted with a particular node.
|
||||
int[] lowTime = new int[V];
|
||||
int[] insertionTime = new int[V];
|
||||
for (int i = 0; i < V; i++) {
|
||||
insertionTime[i] = -1;
|
||||
lowTime[i] = -1;
|
||||
}
|
||||
|
||||
|
||||
// To check if element is present in stack
|
||||
boolean[] isInStack = new boolean[V];
|
||||
|
||||
@ -90,36 +91,36 @@ public class TarjansAlgorithm {
|
||||
}
|
||||
|
||||
private void stronglyConnCompsUtil(int u, int[] lowTime, int[] insertionTime,
|
||||
boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) {
|
||||
boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) {
|
||||
|
||||
// Initialize insertion time and lowTime value of current node
|
||||
insertionTime[u] = Time;
|
||||
lowTime[u] = Time;
|
||||
Time += 1;
|
||||
|
||||
//Push current node into stack
|
||||
// Push current node into stack
|
||||
isInStack[u] = true;
|
||||
st.push(u);
|
||||
|
||||
// Go through all vertices adjacent to this
|
||||
for (Integer vertex : graph.get(u)) {
|
||||
//If the adjacent node is unvisited, do DFS
|
||||
// If the adjacent node is unvisited, do DFS
|
||||
if (insertionTime[vertex] == -1) {
|
||||
stronglyConnCompsUtil(vertex, lowTime, insertionTime, isInStack, st, graph);
|
||||
//update lowTime for the current node comparing lowtime of adj node
|
||||
// update lowTime for the current node comparing lowtime of adj node
|
||||
lowTime[u] = Math.min(lowTime[u], lowTime[vertex]);
|
||||
} else if (isInStack[vertex]) {
|
||||
//If adj node is in stack, update low
|
||||
// If adj node is in stack, update low
|
||||
lowTime[u] = Math.min(lowTime[u], insertionTime[vertex]);
|
||||
}
|
||||
}
|
||||
//If lowtime and insertion time are same, current node is the head of an SCC
|
||||
// head node found, get all the nodes in this SCC
|
||||
// If lowtime and insertion time are same, current node is the head of an SCC
|
||||
// head node found, get all the nodes in this SCC
|
||||
if (lowTime[u] == insertionTime[u]) {
|
||||
int w = -1;
|
||||
var scc = new ArrayList<Integer>();
|
||||
|
||||
//Stack has all the nodes of the current SCC
|
||||
// Stack has all the nodes of the current SCC
|
||||
while (w != u) {
|
||||
w = st.pop();
|
||||
scc.add(w);
|
||||
@ -128,5 +129,4 @@ public class TarjansAlgorithm {
|
||||
SCClist.add(scc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,8 @@ public class HashMapCuckooHashing {
|
||||
}
|
||||
|
||||
/**
|
||||
* The 2 Hash Functions takes a given key and finds an index based on its data, 2 distinctive ways to minimize collisions
|
||||
* The 2 Hash Functions takes a given key and finds an index based on its data, 2 distinctive
|
||||
* ways to minimize collisions
|
||||
*
|
||||
* @param key the desired key to be converted
|
||||
* @return int an index corresponding to the key
|
||||
@ -57,10 +58,10 @@ public class HashMapCuckooHashing {
|
||||
}
|
||||
|
||||
/**
|
||||
* inserts the key into the hash map by wrapping it as an Integer object, then uses while loop to insert new key
|
||||
* if desired place is empty, return.
|
||||
* if already occupied, continue while loop over the new key that has just been pushed out.
|
||||
* if while loop continues more than Thresh, rehash table to new size, then push again.
|
||||
* inserts the key into the hash map by wrapping it as an Integer object, then uses while loop
|
||||
* to insert new key if desired place is empty, return. if already occupied, continue while loop
|
||||
* over the new key that has just been pushed out. if while loop continues more than Thresh,
|
||||
* rehash table to new size, then push again.
|
||||
*
|
||||
* @param key the desired key to be inserted in the hash map
|
||||
*/
|
||||
@ -70,26 +71,19 @@ public class HashMapCuckooHashing {
|
||||
int hash, loopCounter = 0;
|
||||
|
||||
if (isFull()) {
|
||||
System.out.println(
|
||||
"Hash table is full, lengthening & rehashing table"
|
||||
);
|
||||
System.out.println("Hash table is full, lengthening & rehashing table");
|
||||
reHashTableIncreasesTableSize();
|
||||
}
|
||||
|
||||
if (checkTableContainsKey(key)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Key already inside, no duplicates allowed"
|
||||
);
|
||||
throw new IllegalArgumentException("Key already inside, no duplicates allowed");
|
||||
}
|
||||
|
||||
while (loopCounter <= thresh) {
|
||||
loopCounter++;
|
||||
hash = hashFunction1(key);
|
||||
|
||||
if (
|
||||
(buckets[hash] == null) ||
|
||||
Objects.equals(buckets[hash], AVAILABLE)
|
||||
) {
|
||||
if ((buckets[hash] == null) || Objects.equals(buckets[hash], AVAILABLE)) {
|
||||
buckets[hash] = wrappedInt;
|
||||
size++;
|
||||
checkLoadFactor();
|
||||
@ -116,16 +110,14 @@ public class HashMapCuckooHashing {
|
||||
buckets[hash] = wrappedInt;
|
||||
wrappedInt = temp;
|
||||
}
|
||||
System.out.println(
|
||||
"Infinite loop occurred, lengthening & rehashing table"
|
||||
);
|
||||
System.out.println("Infinite loop occurred, lengthening & rehashing table");
|
||||
reHashTableIncreasesTableSize();
|
||||
insertKey2HashTable(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates new HashMapCuckooHashing object, then inserts each of the elements in the previous table to it with its new hash functions.
|
||||
* then refers current array to new table.
|
||||
* creates new HashMapCuckooHashing object, then inserts each of the elements in the previous
|
||||
* table to it with its new hash functions. then refers current array to new table.
|
||||
*
|
||||
*/
|
||||
public void reHashTableIncreasesTableSize() {
|
||||
@ -164,9 +156,7 @@ public class HashMapCuckooHashing {
|
||||
size--;
|
||||
return;
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"Key " + key + " already inside, no duplicates allowed"
|
||||
);
|
||||
throw new IllegalArgumentException("Key " + key + " already inside, no duplicates allowed");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -177,9 +167,7 @@ public class HashMapCuckooHashing {
|
||||
if ((buckets[i] == null) || Objects.equals(buckets[i], AVAILABLE)) {
|
||||
System.out.println("Bucket " + i + ": Empty");
|
||||
} else {
|
||||
System.out.println(
|
||||
"Bucket " + i + ": " + buckets[i].toString()
|
||||
);
|
||||
System.out.println("Bucket " + i + ": " + buckets[i].toString());
|
||||
}
|
||||
}
|
||||
System.out.println();
|
||||
@ -202,11 +190,9 @@ public class HashMapCuckooHashing {
|
||||
if (Objects.equals(buckets[hash], wrappedInt)) return hash;
|
||||
|
||||
hash = hashFunction2(key);
|
||||
if (
|
||||
!Objects.equals(buckets[hash], wrappedInt)
|
||||
) throw new IllegalArgumentException(
|
||||
"Key " + key + " not found in table"
|
||||
); else {
|
||||
if (!Objects.equals(buckets[hash], wrappedInt))
|
||||
throw new IllegalArgumentException("Key " + key + " not found in table");
|
||||
else {
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@ -218,16 +204,8 @@ public class HashMapCuckooHashing {
|
||||
* @return int the index where the key is located
|
||||
*/
|
||||
public boolean checkTableContainsKey(int key) {
|
||||
return (
|
||||
(
|
||||
buckets[hashFunction1(key)] != null &&
|
||||
buckets[hashFunction1(key)].equals(key)
|
||||
) ||
|
||||
(
|
||||
buckets[hashFunction2(key)] != null &&
|
||||
buckets[hashFunction2(key)] == key
|
||||
)
|
||||
);
|
||||
return ((buckets[hashFunction1(key)] != null && buckets[hashFunction1(key)].equals(key))
|
||||
|| (buckets[hashFunction2(key)] != null && buckets[hashFunction2(key)] == key));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -237,10 +215,7 @@ public class HashMapCuckooHashing {
|
||||
public double checkLoadFactor() {
|
||||
double factor = (double) size / tableSize;
|
||||
if (factor > .7) {
|
||||
System.out.printf(
|
||||
"Load factor is %.2f , rehashing table\n",
|
||||
factor
|
||||
);
|
||||
System.out.printf("Load factor is %.2f , rehashing table\n", factor);
|
||||
reHashTableIncreasesTableSize();
|
||||
}
|
||||
return factor;
|
||||
|
@ -15,9 +15,7 @@ import java.util.Map;
|
||||
public class Intersection {
|
||||
|
||||
public static List<Integer> intersection(int[] arr1, int[] arr2) {
|
||||
if (
|
||||
arr1 == null || arr2 == null || arr1.length == 0 || arr2.length == 0
|
||||
) {
|
||||
if (arr1 == null || arr2 == null || arr1.length == 0 || arr2.length == 0) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Integer, Integer> cnt = new HashMap<>(16);
|
||||
@ -34,5 +32,6 @@ public class Intersection {
|
||||
return res;
|
||||
}
|
||||
|
||||
private Intersection() {}
|
||||
private Intersection() {
|
||||
}
|
||||
}
|
||||
|
@ -20,31 +20,27 @@ public class Main {
|
||||
choice = In.nextInt();
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
{
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertHash(key);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteHash(key);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
System.out.println("Print table");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
case 1: {
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertHash(key);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteHash(key);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
System.out.println("Print table");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,59 +24,41 @@ public class MainCuckooHashing {
|
||||
choice = In.nextInt();
|
||||
|
||||
switch (choice) {
|
||||
case 1:
|
||||
{
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertKey2HashTable(key);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteKeyFromHashTable(key);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
System.out.println("Print table:\n");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
System.out.println(
|
||||
"Enter the Key to find and print: "
|
||||
);
|
||||
key = In.nextInt();
|
||||
System.out.println(
|
||||
"Key: " +
|
||||
key +
|
||||
" is at index: " +
|
||||
h.findKeyInTable(key) +
|
||||
"\n"
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
System.out.printf(
|
||||
"Load factor is: %.2f\n",
|
||||
h.checkLoadFactor()
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
h.reHashTableIncreasesTableSize();
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
System.out.println("Enter the Key: ");
|
||||
key = In.nextInt();
|
||||
h.insertKey2HashTable(key);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
System.out.println("Enter the Key delete: ");
|
||||
key = In.nextInt();
|
||||
h.deleteKeyFromHashTable(key);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
System.out.println("Print table:\n");
|
||||
h.displayHashtable();
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
In.close();
|
||||
return;
|
||||
}
|
||||
case 5: {
|
||||
System.out.println("Enter the Key to find and print: ");
|
||||
key = In.nextInt();
|
||||
System.out.println("Key: " + key + " is at index: " + h.findKeyInTable(key) + "\n");
|
||||
break;
|
||||
}
|
||||
case 6: {
|
||||
System.out.printf("Load factor is: %.2f\n", h.checkLoadFactor());
|
||||
break;
|
||||
}
|
||||
case 7: {
|
||||
h.reHashTableIncreasesTableSize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,32 @@
|
||||
package com.thealgorithms.datastructures.hashmap.hashing;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
/*
|
||||
This class finds the majority element(s) in an array of integers.
|
||||
A majority element is an element that appears more than or equal to n/2 times, where n is the length of the array.
|
||||
A majority element is an element that appears more than or equal to n/2 times, where n is the length
|
||||
of the array.
|
||||
*/
|
||||
public class MajorityElement {
|
||||
/*
|
||||
This method returns the majority element(s) in the given array of integers.
|
||||
@param nums: an array of integers
|
||||
@return a list of majority elements
|
||||
*/
|
||||
public static List<Integer> majority(int[] nums){
|
||||
HashMap<Integer,Integer> numToCount = new HashMap<>();
|
||||
/*
|
||||
This method returns the majority element(s) in the given array of integers.
|
||||
@param nums: an array of integers
|
||||
@return a list of majority elements
|
||||
*/
|
||||
public static List<Integer> majority(int[] nums) {
|
||||
HashMap<Integer, Integer> numToCount = new HashMap<>();
|
||||
int n = nums.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (numToCount.containsKey(nums[i])){
|
||||
numToCount.put(nums[i],numToCount.get(nums[i])+1);
|
||||
if (numToCount.containsKey(nums[i])) {
|
||||
numToCount.put(nums[i], numToCount.get(nums[i]) + 1);
|
||||
} else {
|
||||
numToCount.put(nums[i],1);
|
||||
numToCount.put(nums[i], 1);
|
||||
}
|
||||
}
|
||||
List<Integer> majorityElements = new ArrayList<>();
|
||||
for (int key: numToCount.keySet()) {
|
||||
if (numToCount.get(key) >= n/2){
|
||||
for (int key : numToCount.keySet()) {
|
||||
if (numToCount.get(key) >= n / 2) {
|
||||
majorityElements.add(key);
|
||||
}
|
||||
}
|
||||
|
@ -19,5 +19,4 @@ public abstract class Map<Key, Value> {
|
||||
protected int hash(Key key, int size) {
|
||||
return (key.hashCode() & Integer.MAX_VALUE) % size;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -47,10 +47,10 @@ public class FibonacciHeap {
|
||||
* $ret = the HeapNode we inserted
|
||||
*/
|
||||
public HeapNode insert(int key) {
|
||||
HeapNode toInsert = new HeapNode(key); //creates the node
|
||||
HeapNode toInsert = new HeapNode(key); // creates the node
|
||||
if (this.empty()) {
|
||||
this.min = toInsert;
|
||||
} else { //tree is not empty
|
||||
} else { // tree is not empty
|
||||
min.setNext(toInsert);
|
||||
this.updateMin(toInsert);
|
||||
}
|
||||
@ -69,14 +69,14 @@ public class FibonacciHeap {
|
||||
if (this.empty()) {
|
||||
return;
|
||||
}
|
||||
if (this.numOfHeapNodes == 1) { //if there is only one tree
|
||||
if (this.numOfHeapNodes == 1) { // if there is only one tree
|
||||
this.min = null;
|
||||
this.numOfTrees--;
|
||||
this.numOfHeapNodes--;
|
||||
return;
|
||||
}
|
||||
//change all children's parent to null//
|
||||
if (this.min.child != null) { //min has a child
|
||||
// change all children's parent to null//
|
||||
if (this.min.child != null) { // min has a child
|
||||
HeapNode child = this.min.child;
|
||||
HeapNode tmpChild = child;
|
||||
child.parent = null;
|
||||
@ -85,14 +85,14 @@ public class FibonacciHeap {
|
||||
child.parent = null;
|
||||
}
|
||||
}
|
||||
//delete the node//
|
||||
// delete the node//
|
||||
if (this.numOfTrees > 1) {
|
||||
(this.min.prev).next = this.min.next;
|
||||
(this.min.next).prev = this.min.prev;
|
||||
if (this.min.child != null) {
|
||||
(this.min.prev).setNext(this.min.child);
|
||||
}
|
||||
} else { //this.numOfTrees = 1
|
||||
} else { // this.numOfTrees = 1
|
||||
this.min = this.min.child;
|
||||
}
|
||||
this.numOfHeapNodes--;
|
||||
@ -136,17 +136,15 @@ public class FibonacciHeap {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a counters array, where the value of the i-th index is the number of trees with rank i in the heap.
|
||||
* returns an empty array for an empty heap
|
||||
* Return a counters array, where the value of the i-th index is the number of trees with rank i
|
||||
* in the heap. returns an empty array for an empty heap
|
||||
*/
|
||||
public int[] countersRep() {
|
||||
if (this.empty()) {
|
||||
return new int[0]; ///return an empty array
|
||||
return new int[0]; /// return an empty array
|
||||
}
|
||||
int[] rankArray = new int[(int) Math.floor(
|
||||
Math.log(this.size()) / Math.log(GOLDEN_RATIO)
|
||||
) +
|
||||
1]; //creates the array
|
||||
int[] rankArray = new int[(int) Math.floor(Math.log(this.size()) / Math.log(GOLDEN_RATIO))
|
||||
+ 1]; // creates the array
|
||||
rankArray[this.min.rank]++;
|
||||
HeapNode curr = this.min.next;
|
||||
while (curr != this.min) {
|
||||
@ -163,8 +161,8 @@ public class FibonacciHeap {
|
||||
* @post (numOfnodes = = $prev numOfnodes - 1)
|
||||
*/
|
||||
public void delete(HeapNode x) {
|
||||
this.decreaseKey(x, x.getKey() + 1); //change key to be the minimal (-1)
|
||||
this.deleteMin(); //delete it
|
||||
this.decreaseKey(x, x.getKey() + 1); // change key to be the minimal (-1)
|
||||
this.deleteMin(); // delete it
|
||||
}
|
||||
|
||||
/**
|
||||
@ -176,13 +174,13 @@ public class FibonacciHeap {
|
||||
private void decreaseKey(HeapNode x, int delta) {
|
||||
int newKey = x.getKey() - delta;
|
||||
x.key = newKey;
|
||||
if (x.isRoot()) { //no parent to x
|
||||
if (x.isRoot()) { // no parent to x
|
||||
this.updateMin(x);
|
||||
return;
|
||||
}
|
||||
if (x.getKey() >= x.parent.getKey()) {
|
||||
return;
|
||||
} //we don't need to cut
|
||||
} // we don't need to cut
|
||||
HeapNode prevParent = x.parent;
|
||||
this.cut(x);
|
||||
this.cascadingCuts(prevParent);
|
||||
@ -197,17 +195,18 @@ public class FibonacciHeap {
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function returns the total number of link operations made during the run-time of the program.
|
||||
* A link operation is the operation which gets as input two trees of the same rank, and generates a tree of
|
||||
* rank bigger by one.
|
||||
* This static function returns the total number of link operations made during the run-time of
|
||||
* the program. A link operation is the operation which gets as input two trees of the same
|
||||
* rank, and generates a tree of rank bigger by one.
|
||||
*/
|
||||
public static int totalLinks() {
|
||||
return totalLinks;
|
||||
}
|
||||
|
||||
/**
|
||||
* This static function returns the total number of cut operations made during the run-time of the program.
|
||||
* A cut operation is the operation which disconnects a subtree from its parent (during decreaseKey/delete methods).
|
||||
* This static function returns the total number of cut operations made during the run-time of
|
||||
* the program. A cut operation is the operation which disconnects a subtree from its parent
|
||||
* (during decreaseKey/delete methods).
|
||||
*/
|
||||
public static int totalCuts() {
|
||||
return totalCuts;
|
||||
@ -231,7 +230,7 @@ public class FibonacciHeap {
|
||||
* @post (numOfnodes == $prev numOfnodes)
|
||||
*/
|
||||
private void cascadingCuts(HeapNode curr) {
|
||||
if (!curr.isMarked()) { //stop the recursion
|
||||
if (!curr.isMarked()) { // stop the recursion
|
||||
curr.mark();
|
||||
if (!curr.isRoot()) this.markedHeapNoodesCounter++;
|
||||
} else {
|
||||
@ -255,10 +254,10 @@ public class FibonacciHeap {
|
||||
this.markedHeapNoodesCounter--;
|
||||
curr.marked = false;
|
||||
}
|
||||
if (curr.parent.child == curr) { //we should change the parent's child
|
||||
if (curr.next == curr) { //curr do not have brothers
|
||||
if (curr.parent.child == curr) { // we should change the parent's child
|
||||
if (curr.next == curr) { // curr do not have brothers
|
||||
curr.parent.child = null;
|
||||
} else { //curr have brothers
|
||||
} else { // curr have brothers
|
||||
curr.parent.child = curr.next;
|
||||
}
|
||||
}
|
||||
@ -285,10 +284,8 @@ public class FibonacciHeap {
|
||||
*
|
||||
*/
|
||||
private HeapNode[] toBuckets(HeapNode curr) {
|
||||
HeapNode[] buckets = new HeapNode[(int) Math.floor(
|
||||
Math.log(this.size()) / Math.log(GOLDEN_RATIO)
|
||||
) +
|
||||
1];
|
||||
HeapNode[] buckets
|
||||
= new HeapNode[(int) Math.floor(Math.log(this.size()) / Math.log(GOLDEN_RATIO)) + 1];
|
||||
curr.prev.next = null;
|
||||
HeapNode tmpCurr;
|
||||
while (curr != null) {
|
||||
@ -398,7 +395,7 @@ public class FibonacciHeap {
|
||||
private void mark() {
|
||||
if (this.isRoot()) {
|
||||
return;
|
||||
} //check if the node is a root
|
||||
} // check if the node is a root
|
||||
this.marked = true;
|
||||
}
|
||||
|
||||
|
@ -45,16 +45,10 @@ public class GenericHeap<T extends Comparable<T>> {
|
||||
int lci = 2 * pi + 1;
|
||||
int rci = 2 * pi + 2;
|
||||
int mini = pi;
|
||||
if (
|
||||
lci < this.size() &&
|
||||
isLarger(this.data.get(lci), this.data.get(mini)) > 0
|
||||
) {
|
||||
if (lci < this.size() && isLarger(this.data.get(lci), this.data.get(mini)) > 0) {
|
||||
mini = lci;
|
||||
}
|
||||
if (
|
||||
rci < this.size() &&
|
||||
isLarger(this.data.get(rci), this.data.get(mini)) > 0
|
||||
) {
|
||||
if (rci < this.size() && isLarger(this.data.get(rci), this.data.get(mini)) > 0) {
|
||||
mini = rci;
|
||||
}
|
||||
if (mini != pi) {
|
||||
@ -67,7 +61,7 @@ public class GenericHeap<T extends Comparable<T>> {
|
||||
return this.data.get(0);
|
||||
}
|
||||
|
||||
//t has higher property then return +ve
|
||||
// t has higher property then return +ve
|
||||
private int isLarger(T t, T o) {
|
||||
return t.compareTo(o);
|
||||
}
|
||||
@ -83,7 +77,7 @@ public class GenericHeap<T extends Comparable<T>> {
|
||||
|
||||
public void updatePriority(T item) {
|
||||
int index = map.get(item);
|
||||
//because we enter lesser value then old vale
|
||||
// because we enter lesser value then old vale
|
||||
upHeapify(index);
|
||||
}
|
||||
}
|
||||
|
@ -122,10 +122,8 @@ public class HeapElement {
|
||||
return false;
|
||||
}
|
||||
HeapElement otherHeapElement = (HeapElement) o;
|
||||
return (
|
||||
(this.key == otherHeapElement.key) &&
|
||||
(this.additionalInfo.equals(otherHeapElement.additionalInfo))
|
||||
);
|
||||
return ((this.key == otherHeapElement.key)
|
||||
&& (this.additionalInfo.equals(otherHeapElement.additionalInfo)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -134,10 +132,7 @@ public class HeapElement {
|
||||
public int hashCode() {
|
||||
int result = 0;
|
||||
result = 31 * result + (int) key;
|
||||
result =
|
||||
31 *
|
||||
result +
|
||||
(additionalInfo != null ? additionalInfo.hashCode() : 0);
|
||||
result = 31 * result + (additionalInfo != null ? additionalInfo.hashCode() : 0);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -2,117 +2,113 @@ package com.thealgorithms.datastructures.heaps;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/*
|
||||
/*
|
||||
* This is a leftist heap that follows the same operations as a
|
||||
* binary min heap, but may be unbalanced at times and follows a
|
||||
* leftist property, in which the left side is more heavy on the
|
||||
* right based on the null-path length (npl) values.
|
||||
*
|
||||
*
|
||||
* Source: https://iq.opengenus.org/leftist-heap/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
public class LeftistHeap {
|
||||
private class Node {
|
||||
private int element, npl;
|
||||
private Node left, right;
|
||||
private class Node {
|
||||
private int element, npl;
|
||||
private Node left, right;
|
||||
|
||||
// Node constructor setting the data element and left/right pointers to null
|
||||
private Node(int element) {
|
||||
this.element = element;
|
||||
left = right = null;
|
||||
npl = 0;
|
||||
}
|
||||
}
|
||||
// Node constructor setting the data element and left/right pointers to null
|
||||
private Node(int element) {
|
||||
this.element = element;
|
||||
left = right = null;
|
||||
npl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private Node root;
|
||||
private Node root;
|
||||
|
||||
// Constructor
|
||||
public LeftistHeap() {
|
||||
root = null;
|
||||
}
|
||||
// Constructor
|
||||
public LeftistHeap() {
|
||||
root = null;
|
||||
}
|
||||
|
||||
// Checks if heap is empty
|
||||
public boolean isEmpty() {
|
||||
return root == null;
|
||||
}
|
||||
// Checks if heap is empty
|
||||
public boolean isEmpty() {
|
||||
return root == null;
|
||||
}
|
||||
|
||||
// Resets structure to initial state
|
||||
public void clear() {
|
||||
// We will put head is null
|
||||
root = null;
|
||||
}
|
||||
// Resets structure to initial state
|
||||
public void clear() {
|
||||
// We will put head is null
|
||||
root = null;
|
||||
}
|
||||
|
||||
// Merge function that merges the contents of another leftist heap with the
|
||||
// current one
|
||||
public void merge(LeftistHeap h1) {
|
||||
// If the present function is rhs then we ignore the merge
|
||||
root = merge(root, h1.root);
|
||||
h1.root = null;
|
||||
}
|
||||
// Merge function that merges the contents of another leftist heap with the
|
||||
// current one
|
||||
public void merge(LeftistHeap h1) {
|
||||
// If the present function is rhs then we ignore the merge
|
||||
root = merge(root, h1.root);
|
||||
h1.root = null;
|
||||
}
|
||||
|
||||
// Function merge with two Nodes a and b
|
||||
public Node merge(Node a, Node b) {
|
||||
if (a == null)
|
||||
return b;
|
||||
// Function merge with two Nodes a and b
|
||||
public Node merge(Node a, Node b) {
|
||||
if (a == null) return b;
|
||||
|
||||
if (b == null)
|
||||
return a;
|
||||
if (b == null) return a;
|
||||
|
||||
// Violates leftist property, so must do a swap
|
||||
if (a.element > b.element) {
|
||||
Node temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
// Violates leftist property, so must do a swap
|
||||
if (a.element > b.element) {
|
||||
Node temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
// Now we call the function merge to merge a and b
|
||||
a.right = merge(a.right, b);
|
||||
// Now we call the function merge to merge a and b
|
||||
a.right = merge(a.right, b);
|
||||
|
||||
// Violates leftist property so must swap here
|
||||
if (a.left == null) {
|
||||
a.left = a.right;
|
||||
a.right = null;
|
||||
} else {
|
||||
if (a.left.npl < a.right.npl) {
|
||||
Node temp = a.left;
|
||||
a.left = a.right;
|
||||
a.right = temp;
|
||||
}
|
||||
a.npl = a.right.npl + 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
// Violates leftist property so must swap here
|
||||
if (a.left == null) {
|
||||
a.left = a.right;
|
||||
a.right = null;
|
||||
} else {
|
||||
if (a.left.npl < a.right.npl) {
|
||||
Node temp = a.left;
|
||||
a.left = a.right;
|
||||
a.right = temp;
|
||||
}
|
||||
a.npl = a.right.npl + 1;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
// Function insert. Uses the merge function to add the data
|
||||
public void insert(int a) {
|
||||
root = merge(new Node(a), root);
|
||||
}
|
||||
// Function insert. Uses the merge function to add the data
|
||||
public void insert(int a) {
|
||||
root = merge(new Node(a), root);
|
||||
}
|
||||
|
||||
// Returns and removes the minimum element in the heap
|
||||
public int extract_min() {
|
||||
// If is empty return -1
|
||||
if (isEmpty())
|
||||
return -1;
|
||||
// Returns and removes the minimum element in the heap
|
||||
public int extract_min() {
|
||||
// If is empty return -1
|
||||
if (isEmpty()) return -1;
|
||||
|
||||
int min = root.element;
|
||||
root = merge(root.left, root.right);
|
||||
return min;
|
||||
}
|
||||
int min = root.element;
|
||||
root = merge(root.left, root.right);
|
||||
return min;
|
||||
}
|
||||
|
||||
// Function returning a list of an in order traversal of the data structure
|
||||
public ArrayList<Integer> in_order() {
|
||||
ArrayList<Integer> lst = new ArrayList<>();
|
||||
in_order_aux(root, lst);
|
||||
return new ArrayList<>(lst);
|
||||
}
|
||||
// Function returning a list of an in order traversal of the data structure
|
||||
public ArrayList<Integer> in_order() {
|
||||
ArrayList<Integer> lst = new ArrayList<>();
|
||||
in_order_aux(root, lst);
|
||||
return new ArrayList<>(lst);
|
||||
}
|
||||
|
||||
// Auxiliary function for in_order
|
||||
private void in_order_aux(Node n, ArrayList<Integer> lst) {
|
||||
if (n == null)
|
||||
return;
|
||||
in_order_aux(n.left, lst);
|
||||
lst.add(n.element);
|
||||
in_order_aux(n.right, lst);
|
||||
}
|
||||
// Auxiliary function for in_order
|
||||
private void in_order_aux(Node n, ArrayList<Integer> lst) {
|
||||
if (n == null) return;
|
||||
in_order_aux(n.left, lst);
|
||||
lst.add(n.element);
|
||||
in_order_aux(n.right, lst);
|
||||
}
|
||||
}
|
@ -70,30 +70,20 @@ public class MaxHeap implements Heap {
|
||||
// than any of its children's
|
||||
private void toggleDown(int elementIndex) {
|
||||
double key = maxHeap.get(elementIndex - 1).getKey();
|
||||
boolean wrongOrder =
|
||||
(key < getElementKey(elementIndex * 2)) ||
|
||||
(key < getElementKey(Math.min(elementIndex * 2, maxHeap.size())));
|
||||
boolean wrongOrder = (key < getElementKey(elementIndex * 2))
|
||||
|| (key < getElementKey(Math.min(elementIndex * 2, maxHeap.size())));
|
||||
while ((2 * elementIndex <= maxHeap.size()) && wrongOrder) {
|
||||
// Check whether it shall swap the element with its left child or its right one if any.
|
||||
if (
|
||||
(2 * elementIndex < maxHeap.size()) &&
|
||||
(
|
||||
getElementKey(elementIndex * 2 + 1) >
|
||||
getElementKey(elementIndex * 2)
|
||||
)
|
||||
) {
|
||||
if ((2 * elementIndex < maxHeap.size())
|
||||
&& (getElementKey(elementIndex * 2 + 1) > getElementKey(elementIndex * 2))) {
|
||||
swap(elementIndex, 2 * elementIndex + 1);
|
||||
elementIndex = 2 * elementIndex + 1;
|
||||
} else {
|
||||
swap(elementIndex, 2 * elementIndex);
|
||||
elementIndex = 2 * elementIndex;
|
||||
}
|
||||
wrongOrder =
|
||||
(key < getElementKey(elementIndex * 2)) ||
|
||||
(
|
||||
key <
|
||||
getElementKey(Math.min(elementIndex * 2, maxHeap.size()))
|
||||
);
|
||||
wrongOrder = (key < getElementKey(elementIndex * 2))
|
||||
|| (key < getElementKey(Math.min(elementIndex * 2, maxHeap.size())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,12 +102,10 @@ public class MaxHeap implements Heap {
|
||||
@Override
|
||||
public void deleteElement(int elementIndex) {
|
||||
if (maxHeap.isEmpty()) try {
|
||||
throw new EmptyHeapException(
|
||||
"Attempt to delete an element from an empty heap"
|
||||
);
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new EmptyHeapException("Attempt to delete an element from an empty heap");
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if ((elementIndex > maxHeap.size()) || (elementIndex <= 0)) {
|
||||
throw new IndexOutOfBoundsException("Index out of heap range");
|
||||
}
|
||||
@ -125,22 +113,13 @@ public class MaxHeap implements Heap {
|
||||
maxHeap.set(elementIndex - 1, getElement(maxHeap.size()));
|
||||
maxHeap.remove(maxHeap.size());
|
||||
// Shall the new element be moved up...
|
||||
if (
|
||||
getElementKey(elementIndex) >
|
||||
getElementKey((int) Math.floor(elementIndex / 2.0))
|
||||
) {
|
||||
if (getElementKey(elementIndex) > getElementKey((int) Math.floor(elementIndex / 2.0))) {
|
||||
toggleUp(elementIndex);
|
||||
} // ... or down ?
|
||||
else if (
|
||||
(
|
||||
(2 * elementIndex <= maxHeap.size()) &&
|
||||
(getElementKey(elementIndex) < getElementKey(elementIndex * 2))
|
||||
) ||
|
||||
(
|
||||
(2 * elementIndex < maxHeap.size()) &&
|
||||
(getElementKey(elementIndex) < getElementKey(elementIndex * 2))
|
||||
)
|
||||
) {
|
||||
else if (((2 * elementIndex <= maxHeap.size())
|
||||
&& (getElementKey(elementIndex) < getElementKey(elementIndex * 2)))
|
||||
|| ((2 * elementIndex < maxHeap.size())
|
||||
&& (getElementKey(elementIndex) < getElementKey(elementIndex * 2)))) {
|
||||
toggleDown(elementIndex);
|
||||
}
|
||||
}
|
||||
@ -150,9 +129,7 @@ public class MaxHeap implements Heap {
|
||||
try {
|
||||
return extractMax();
|
||||
} catch (Exception e) {
|
||||
throw new EmptyHeapException(
|
||||
"Heap is empty. Error retrieving element"
|
||||
);
|
||||
throw new EmptyHeapException("Heap is empty. Error retrieving element");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,30 +64,20 @@ public class MinHeap implements Heap {
|
||||
// than any of its children's
|
||||
private void toggleDown(int elementIndex) {
|
||||
double key = minHeap.get(elementIndex - 1).getKey();
|
||||
boolean wrongOrder =
|
||||
(key > getElementKey(elementIndex * 2)) ||
|
||||
(key > getElementKey(Math.min(elementIndex * 2, minHeap.size())));
|
||||
boolean wrongOrder = (key > getElementKey(elementIndex * 2))
|
||||
|| (key > getElementKey(Math.min(elementIndex * 2, minHeap.size())));
|
||||
while ((2 * elementIndex <= minHeap.size()) && wrongOrder) {
|
||||
// Check whether it shall swap the element with its left child or its right one if any.
|
||||
if (
|
||||
(2 * elementIndex < minHeap.size()) &&
|
||||
(
|
||||
getElementKey(elementIndex * 2 + 1) <
|
||||
getElementKey(elementIndex * 2)
|
||||
)
|
||||
) {
|
||||
if ((2 * elementIndex < minHeap.size())
|
||||
&& (getElementKey(elementIndex * 2 + 1) < getElementKey(elementIndex * 2))) {
|
||||
swap(elementIndex, 2 * elementIndex + 1);
|
||||
elementIndex = 2 * elementIndex + 1;
|
||||
} else {
|
||||
swap(elementIndex, 2 * elementIndex);
|
||||
elementIndex = 2 * elementIndex;
|
||||
}
|
||||
wrongOrder =
|
||||
(key > getElementKey(elementIndex * 2)) ||
|
||||
(
|
||||
key >
|
||||
getElementKey(Math.min(elementIndex * 2, minHeap.size()))
|
||||
);
|
||||
wrongOrder = (key > getElementKey(elementIndex * 2))
|
||||
|| (key > getElementKey(Math.min(elementIndex * 2, minHeap.size())));
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,12 +96,10 @@ public class MinHeap implements Heap {
|
||||
@Override
|
||||
public void deleteElement(int elementIndex) {
|
||||
if (minHeap.isEmpty()) try {
|
||||
throw new EmptyHeapException(
|
||||
"Attempt to delete an element from an empty heap"
|
||||
);
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new EmptyHeapException("Attempt to delete an element from an empty heap");
|
||||
} catch (EmptyHeapException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if ((elementIndex > minHeap.size()) || (elementIndex <= 0)) {
|
||||
throw new IndexOutOfBoundsException("Index out of heap range");
|
||||
}
|
||||
@ -119,22 +107,13 @@ public class MinHeap implements Heap {
|
||||
minHeap.set(elementIndex - 1, getElement(minHeap.size()));
|
||||
minHeap.remove(minHeap.size());
|
||||
// Shall the new element be moved up...
|
||||
if (
|
||||
getElementKey(elementIndex) <
|
||||
getElementKey((int) Math.floor(elementIndex / 2.0))
|
||||
) {
|
||||
if (getElementKey(elementIndex) < getElementKey((int) Math.floor(elementIndex / 2.0))) {
|
||||
toggleUp(elementIndex);
|
||||
} // ... or down ?
|
||||
else if (
|
||||
(
|
||||
(2 * elementIndex <= minHeap.size()) &&
|
||||
(getElementKey(elementIndex) > getElementKey(elementIndex * 2))
|
||||
) ||
|
||||
(
|
||||
(2 * elementIndex < minHeap.size()) &&
|
||||
(getElementKey(elementIndex) > getElementKey(elementIndex * 2))
|
||||
)
|
||||
) {
|
||||
else if (((2 * elementIndex <= minHeap.size())
|
||||
&& (getElementKey(elementIndex) > getElementKey(elementIndex * 2)))
|
||||
|| ((2 * elementIndex < minHeap.size())
|
||||
&& (getElementKey(elementIndex) > getElementKey(elementIndex * 2)))) {
|
||||
toggleDown(elementIndex);
|
||||
}
|
||||
}
|
||||
@ -144,9 +123,7 @@ public class MinHeap implements Heap {
|
||||
try {
|
||||
return extractMin();
|
||||
} catch (Exception e) {
|
||||
throw new EmptyHeapException(
|
||||
"Heap is empty. Error retrieving element"
|
||||
);
|
||||
throw new EmptyHeapException("Heap is empty. Error retrieving element");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -82,10 +82,7 @@ public class MinPriorityQueue {
|
||||
while (2 * k <= this.size || 2 * k + 1 <= this.size) {
|
||||
int minIndex;
|
||||
if (this.heap[2 * k] >= this.heap[k]) {
|
||||
if (
|
||||
2 * k + 1 <= this.size &&
|
||||
this.heap[2 * k + 1] >= this.heap[k]
|
||||
) {
|
||||
if (2 * k + 1 <= this.size && this.heap[2 * k + 1] >= this.heap[k]) {
|
||||
break;
|
||||
} else if (2 * k + 1 > this.size) {
|
||||
break;
|
||||
@ -94,14 +91,8 @@ public class MinPriorityQueue {
|
||||
if (2 * k + 1 > this.size) {
|
||||
minIndex = this.heap[2 * k] < this.heap[k] ? 2 * k : k;
|
||||
} else {
|
||||
if (
|
||||
this.heap[k] > this.heap[2 * k] ||
|
||||
this.heap[k] > this.heap[2 * k + 1]
|
||||
) {
|
||||
minIndex =
|
||||
this.heap[2 * k] < this.heap[2 * k + 1]
|
||||
? 2 * k
|
||||
: 2 * k + 1;
|
||||
if (this.heap[k] > this.heap[2 * k] || this.heap[k] > this.heap[2 * k + 1]) {
|
||||
minIndex = this.heap[2 * k] < this.heap[2 * k + 1] ? 2 * k : 2 * k + 1;
|
||||
} else {
|
||||
minIndex = k;
|
||||
}
|
||||
|
@ -38,9 +38,7 @@ public class CircleLinkedList<E> {
|
||||
public void append(E value) {
|
||||
if (value == null) {
|
||||
// we do not want to add null elements to the list.
|
||||
throw new NullPointerException(
|
||||
"Cannot add null element to the list"
|
||||
);
|
||||
throw new NullPointerException("Cannot add null element to the list");
|
||||
}
|
||||
// head.next points to the last element;
|
||||
if (tail == null) {
|
||||
@ -70,9 +68,7 @@ public class CircleLinkedList<E> {
|
||||
public E remove(int pos) {
|
||||
if (pos > size || pos < 0) {
|
||||
// catching errors
|
||||
throw new IndexOutOfBoundsException(
|
||||
"position cannot be greater than size or negative"
|
||||
);
|
||||
throw new IndexOutOfBoundsException("position cannot be greater than size or negative");
|
||||
}
|
||||
// we need to keep track of the element before the element we want to remove we can see why
|
||||
// bellow.
|
||||
|
@ -120,8 +120,7 @@ public class CursorLinkedList<T> {
|
||||
while (current_index != -1) {
|
||||
T current_element = cursorSpace[current_index].element;
|
||||
if (current_element.equals(element)) {
|
||||
cursorSpace[prev_index].next =
|
||||
cursorSpace[current_index].next;
|
||||
cursorSpace[prev_index].next = cursorSpace[current_index].next;
|
||||
free(current_index);
|
||||
break;
|
||||
}
|
||||
|
@ -217,7 +217,8 @@ class LinkOperations {
|
||||
public void insertTail(int x, DoublyLinkedList doublyLinkedList) {
|
||||
Link newLink = new Link(x);
|
||||
newLink.next = null; // currentTail(tail) newlink -->
|
||||
if (doublyLinkedList.isEmpty()) { // Check if there are no elements in list then it adds first element
|
||||
if (doublyLinkedList
|
||||
.isEmpty()) { // Check if there are no elements in list then it adds first element
|
||||
tail = newLink;
|
||||
head = tail;
|
||||
} else {
|
||||
@ -234,15 +235,9 @@ class LinkOperations {
|
||||
* @param x Element to be inserted
|
||||
* @param index Index(from start) at which the element x to be inserted
|
||||
*/
|
||||
public void insertElementByIndex(
|
||||
int x,
|
||||
int index,
|
||||
DoublyLinkedList doublyLinkedList
|
||||
) {
|
||||
public void insertElementByIndex(int x, int index, DoublyLinkedList doublyLinkedList) {
|
||||
if (index > size) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Index: " + index + ", Size: " + size
|
||||
);
|
||||
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||
}
|
||||
if (index == 0) {
|
||||
insertHead(x, doublyLinkedList);
|
||||
@ -277,7 +272,8 @@ class LinkOperations {
|
||||
if (head == null) {
|
||||
tail = null;
|
||||
} else {
|
||||
head.previous = null; // oldHead --> 2ndElement(head) nothing pointing at old head so will be removed
|
||||
head.previous = null; // oldHead --> 2ndElement(head) nothing pointing at old head so
|
||||
// will be removed
|
||||
}
|
||||
--size;
|
||||
return temp;
|
||||
@ -314,9 +310,7 @@ class LinkOperations {
|
||||
if (current != tail) {
|
||||
current = current.next;
|
||||
} else { // If we reach the tail and the element is still not found
|
||||
throw new RuntimeException(
|
||||
"The element to be deleted does not exist!"
|
||||
);
|
||||
throw new RuntimeException("The element to be deleted does not exist!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,11 +36,7 @@ public class MergeSortedArrayList {
|
||||
* @param listB the second list to merge
|
||||
* @param listC the result list after merging
|
||||
*/
|
||||
public static void merge(
|
||||
List<Integer> listA,
|
||||
List<Integer> listB,
|
||||
List<Integer> listC
|
||||
) {
|
||||
public static void merge(List<Integer> listA, List<Integer> listB, List<Integer> listC) {
|
||||
int pa = 0;
|
||||
/* the index of listA */
|
||||
int pb = 0;
|
||||
|
@ -12,9 +12,7 @@ public class MergeSortedSinglyLinkedList extends SinglyLinkedList {
|
||||
}
|
||||
assert listA.toString().equals("2->4->6->8->10");
|
||||
assert listB.toString().equals("1->3->5->7->9");
|
||||
assert merge(listA, listB)
|
||||
.toString()
|
||||
.equals("1->2->3->4->5->6->7->8->9->10");
|
||||
assert merge(listA, listB).toString().equals("1->2->3->4->5->6->7->8->9->10");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -24,10 +22,7 @@ public class MergeSortedSinglyLinkedList extends SinglyLinkedList {
|
||||
* @param listB the second sored list
|
||||
* @return merged sorted list
|
||||
*/
|
||||
public static SinglyLinkedList merge(
|
||||
SinglyLinkedList listA,
|
||||
SinglyLinkedList listB
|
||||
) {
|
||||
public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList listB) {
|
||||
Node headA = listA.getHead();
|
||||
Node headB = listB.getHead();
|
||||
|
||||
|
@ -18,9 +18,7 @@ public class Merge_K_SortedLinkedlist {
|
||||
*/
|
||||
Node mergeKList(Node[] a, int N) {
|
||||
// Min Heap
|
||||
PriorityQueue<Node> min = new PriorityQueue<>(
|
||||
Comparator.comparingInt(x -> x.data)
|
||||
);
|
||||
PriorityQueue<Node> min = new PriorityQueue<>(Comparator.comparingInt(x -> x.data));
|
||||
|
||||
// adding head of all linkedList in min heap
|
||||
min.addAll(Arrays.asList(a).subList(0, N));
|
||||
|
@ -1,25 +1,30 @@
|
||||
/** Author : Suraj Kumar
|
||||
/**
|
||||
* Author : Suraj Kumar
|
||||
* Github : https://github.com/skmodi649
|
||||
*/
|
||||
|
||||
/** PROBLEM DESCRIPTION :
|
||||
/**
|
||||
* PROBLEM DESCRIPTION :
|
||||
* There is a single linked list and we are supposed to find a random node in the given linked list
|
||||
*/
|
||||
|
||||
/** ALGORITHM :
|
||||
/**
|
||||
* ALGORITHM :
|
||||
* Step 1 : START
|
||||
* Step 2 : Create an arraylist of type integer
|
||||
* Step 3 : Declare an integer type variable for size and linked list type for head
|
||||
* Step 4 : We will use two methods, one for traversing through the linked list using while loop and also increase the size by 1
|
||||
* Step 4 : We will use two methods, one for traversing through the linked list using while loop and
|
||||
* also increase the size by 1
|
||||
*
|
||||
* (a) RandomNode(head)
|
||||
* (b) run a while loop till null;
|
||||
* (c) add the value to arraylist;
|
||||
* (d) increase the size;
|
||||
*
|
||||
* Step 5 : Now use another method for getting random values using Math.random() and return the value present in arraylist for the calculated index
|
||||
* Step 6 : Now in main() method we will simply insert nodes in the linked list and then call the appropriate method and then print the random node generated
|
||||
* Step 7 : STOP
|
||||
* Step 5 : Now use another method for getting random values using Math.random() and return the
|
||||
* value present in arraylist for the calculated index Step 6 : Now in main() method we will simply
|
||||
* insert nodes in the linked list and then call the appropriate method and then print the random
|
||||
* node generated Step 7 : STOP
|
||||
*/
|
||||
|
||||
package com.thealgorithms.datastructures.lists;
|
||||
@ -86,6 +91,7 @@ public class RandomNode {
|
||||
* Time Complexity : O(n)
|
||||
* Auxiliary Space Complexity : O(1)
|
||||
*/
|
||||
/** Time Complexity : O(n)
|
||||
/**
|
||||
* Time Complexity : O(n)
|
||||
* Auxiliary Space Complexity : O(1)
|
||||
*/
|
||||
|
@ -23,10 +23,7 @@ public class SearchSinglyLinkedListRecursion extends SinglyLinkedList {
|
||||
* {@code false}.
|
||||
*/
|
||||
private boolean searchRecursion(Node node, int key) {
|
||||
return (
|
||||
node != null &&
|
||||
(node.value == key || searchRecursion(node.next, key))
|
||||
);
|
||||
return (node != null && (node.value == key || searchRecursion(node.next, key)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -125,19 +125,20 @@ public class SinglyLinkedList extends Node {
|
||||
public Node reverseList(Node node) {
|
||||
Node prev = null;
|
||||
Node curr = node;
|
||||
|
||||
|
||||
while (curr != null && curr.next != null) {
|
||||
Node next=curr.next;
|
||||
Node next = curr.next;
|
||||
curr.next = prev;
|
||||
prev = curr;
|
||||
curr = next;
|
||||
}
|
||||
//when curr.next==null, the current element is left without pointing it to its prev,so
|
||||
if(curr != null){
|
||||
// when curr.next==null, the current element is left without pointing it to its prev,so
|
||||
if (curr != null) {
|
||||
curr.next = prev;
|
||||
prev=curr;
|
||||
prev = curr;
|
||||
}
|
||||
//prev will be pointing to the last element in the Linkedlist, it will be the new head of the reversed linkedlist
|
||||
// prev will be pointing to the last element in the Linkedlist, it will be the new head of
|
||||
// the reversed linkedlist
|
||||
return prev;
|
||||
}
|
||||
|
||||
@ -244,9 +245,7 @@ public class SinglyLinkedList extends Node {
|
||||
// skip all duplicates
|
||||
if (newHead.next != null && newHead.value == newHead.next.value) {
|
||||
// move till the end of duplicates sublist
|
||||
while (
|
||||
newHead.next != null && newHead.value == newHead.next.value
|
||||
) {
|
||||
while (newHead.next != null && newHead.value == newHead.next.value) {
|
||||
newHead = newHead.next;
|
||||
}
|
||||
// skip all duplicates
|
||||
@ -412,15 +411,10 @@ public class SinglyLinkedList extends Node {
|
||||
assert list.toString().equals("10->7->5->3->1");
|
||||
System.out.println(list);
|
||||
/* Test search function */
|
||||
assert list.search(10) &&
|
||||
list.search(5) &&
|
||||
list.search(1) &&
|
||||
!list.search(100);
|
||||
assert list.search(10) && list.search(5) && list.search(1) && !list.search(100);
|
||||
|
||||
/* Test get function */
|
||||
assert list.getNth(0) == 10 &&
|
||||
list.getNth(2) == 5 &&
|
||||
list.getNth(4) == 1;
|
||||
assert list.getNth(0) == 10 && list.getNth(2) == 5 && list.getNth(4) == 1;
|
||||
|
||||
/* Test delete function */
|
||||
list.deleteHead();
|
||||
@ -443,10 +437,7 @@ public class SinglyLinkedList extends Node {
|
||||
}
|
||||
|
||||
SinglyLinkedList instance = new SinglyLinkedList();
|
||||
Node head = new Node(
|
||||
0,
|
||||
new Node(2, new Node(3, new Node(3, new Node(4))))
|
||||
);
|
||||
Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4)))));
|
||||
instance.setHead(head);
|
||||
instance.deleteDuplicates();
|
||||
instance.print();
|
||||
@ -469,7 +460,8 @@ class Node {
|
||||
*/
|
||||
Node next;
|
||||
|
||||
Node() {}
|
||||
Node() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -189,25 +189,23 @@ public class SkipList<E extends Comparable<E>> {
|
||||
}
|
||||
|
||||
Collections.reverse(layers);
|
||||
String result = layers
|
||||
.stream()
|
||||
.map(layer -> {
|
||||
StringBuilder acc = new StringBuilder();
|
||||
for (boolean b : layer) {
|
||||
if (b) {
|
||||
acc.append("[ ]");
|
||||
} else {
|
||||
acc.append("---");
|
||||
}
|
||||
acc.append(" ");
|
||||
}
|
||||
return acc.toString();
|
||||
})
|
||||
.collect(Collectors.joining("\n"));
|
||||
String positions = IntStream
|
||||
.range(0, sizeWithHeader - 1)
|
||||
.mapToObj(i -> String.format("%3d", i))
|
||||
.collect(Collectors.joining(" "));
|
||||
String result = layers.stream()
|
||||
.map(layer -> {
|
||||
StringBuilder acc = new StringBuilder();
|
||||
for (boolean b : layer) {
|
||||
if (b) {
|
||||
acc.append("[ ]");
|
||||
} else {
|
||||
acc.append("---");
|
||||
}
|
||||
acc.append(" ");
|
||||
}
|
||||
return acc.toString();
|
||||
})
|
||||
.collect(Collectors.joining("\n"));
|
||||
String positions = IntStream.range(0, sizeWithHeader - 1)
|
||||
.mapToObj(i -> String.format("%3d", i))
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
return result + String.format("%n H %s%n", positions);
|
||||
}
|
||||
@ -299,17 +297,14 @@ public class SkipList<E extends Comparable<E>> {
|
||||
public BernoulliHeightStrategy(double probability) {
|
||||
if (probability <= 0 || probability >= 1) {
|
||||
throw new IllegalArgumentException(
|
||||
"Probability should be from 0 to 1. But was: " + probability
|
||||
);
|
||||
"Probability should be from 0 to 1. But was: " + probability);
|
||||
}
|
||||
this.probability = probability;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int height(int expectedSize) {
|
||||
long height = Math.round(
|
||||
Math.log10(expectedSize) / Math.log10(1 / probability)
|
||||
);
|
||||
long height = Math.round(Math.log10(expectedSize) / Math.log10(1 / probability));
|
||||
if (height > Integer.MAX_VALUE) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.thealgorithms.datastructures.queues;
|
||||
|
||||
//This program implements the concept of CircularQueue in Java
|
||||
//Link to the concept: (https://en.wikipedia.org/wiki/Circular_buffer)
|
||||
// This program implements the concept of CircularQueue in Java
|
||||
// Link to the concept: (https://en.wikipedia.org/wiki/Circular_buffer)
|
||||
public class CircularQueue {
|
||||
|
||||
int[] arr;
|
||||
@ -23,7 +23,8 @@ public class CircularQueue {
|
||||
public boolean isFull() {
|
||||
if (topOfQueue + 1 == beginningOfQueue) {
|
||||
return true;
|
||||
} else return topOfQueue == size - 1 && beginningOfQueue == 0;
|
||||
} else
|
||||
return topOfQueue == size - 1 && beginningOfQueue == 0;
|
||||
}
|
||||
|
||||
public void enQueue(int value) {
|
||||
|
@ -124,11 +124,9 @@ public class LinkedQueue<T> implements Iterable<T> {
|
||||
|
||||
public T peek(int pos) {
|
||||
if (pos > size)
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Position %s out of range!".formatted(pos));
|
||||
throw new IndexOutOfBoundsException("Position %s out of range!".formatted(pos));
|
||||
Node<T> node = front;
|
||||
while (pos-- > 0)
|
||||
node = node.next;
|
||||
while (pos-- > 0) node = node.next;
|
||||
return node.data;
|
||||
}
|
||||
|
||||
@ -140,7 +138,6 @@ public class LinkedQueue<T> implements Iterable<T> {
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<>() {
|
||||
|
||||
Node<T> node = front;
|
||||
|
||||
@Override
|
||||
@ -168,16 +165,14 @@ public class LinkedQueue<T> implements Iterable<T> {
|
||||
* Clear all nodes in queue
|
||||
*/
|
||||
public void clear() {
|
||||
while (size > 0)
|
||||
dequeue();
|
||||
while (size > 0) dequeue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringJoiner join = new StringJoiner(", "); // separator of ', '
|
||||
Node<T> travel = front;
|
||||
while ((travel = travel.next) != null)
|
||||
join.add(String.valueOf(travel.data));
|
||||
while ((travel = travel.next) != null) join.add(String.valueOf(travel.data));
|
||||
return '[' + join.toString() + ']';
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
package com.thealgorithms.datastructures.queues;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This class implements a PriorityQueue.
|
||||
*
|
||||
@ -126,7 +123,8 @@ class PriorityQueue {
|
||||
if (isEmpty()) {
|
||||
throw new RuntimeException("Queue is Empty");
|
||||
} else {
|
||||
int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is the greatest
|
||||
int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is
|
||||
// the greatest
|
||||
|
||||
// Swap max and last element
|
||||
int temp = queueArray[1];
|
||||
@ -175,4 +173,3 @@ class PriorityQueue {
|
||||
return nItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,16 +28,13 @@ class BalancedBrackets {
|
||||
*/
|
||||
public static boolean isPaired(char leftBracket, char rightBracket) {
|
||||
char[][] pairedBrackets = {
|
||||
{ '(', ')' },
|
||||
{ '[', ']' },
|
||||
{ '{', '}' },
|
||||
{ '<', '>' },
|
||||
{'(', ')'},
|
||||
{'[', ']'},
|
||||
{'{', '}'},
|
||||
{'<', '>'},
|
||||
};
|
||||
for (char[] pairedBracket : pairedBrackets) {
|
||||
if (
|
||||
pairedBracket[0] == leftBracket &&
|
||||
pairedBracket[1] == rightBracket
|
||||
) {
|
||||
if (pairedBracket[0] == leftBracket && pairedBracket[1] == rightBracket) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -58,24 +55,21 @@ class BalancedBrackets {
|
||||
Stack<Character> bracketsStack = new Stack<>();
|
||||
for (char bracket : brackets.toCharArray()) {
|
||||
switch (bracket) {
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
bracketsStack.push(bracket);
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if (
|
||||
bracketsStack.isEmpty() ||
|
||||
!isPaired(bracketsStack.pop(), bracket)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other character is invalid */
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
bracketsStack.push(bracket);
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
if (bracketsStack.isEmpty() || !isPaired(bracketsStack.pop(), bracket)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* other character is invalid */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return bracketsStack.isEmpty();
|
||||
|
@ -1,8 +1,12 @@
|
||||
/** Author : Siddhant Swarup Mallick
|
||||
/**
|
||||
* Author : Siddhant Swarup Mallick
|
||||
* Github : https://github.com/siddhant2002
|
||||
*/
|
||||
|
||||
/** Program description - Given an integer array. The task is to find the maximum of the minimum of the array */
|
||||
/**
|
||||
* Program description - Given an integer array. The task is to find the maximum of the minimum of
|
||||
* the array
|
||||
*/
|
||||
package com.thealgorithms.datastructures.stacks;
|
||||
|
||||
import java.util.*;
|
||||
|
@ -24,12 +24,7 @@ public class DecimalToAnyUsingStack {
|
||||
private static String convert(int number, int radix) {
|
||||
if (radix < 2 || radix > 16) {
|
||||
throw new ArithmeticException(
|
||||
String.format(
|
||||
"Invalid input -> number:%d,radius:%d",
|
||||
number,
|
||||
radix
|
||||
)
|
||||
);
|
||||
String.format("Invalid input -> number:%d,radius:%d", number, radix));
|
||||
}
|
||||
char[] tables = {
|
||||
'0',
|
||||
|
@ -1,7 +1,8 @@
|
||||
package com.thealgorithms.datastructures.stacks;
|
||||
|
||||
// 1. You are given a string exp representing an expression.
|
||||
// 2. Assume that the expression is balanced i.e. the opening and closing brackets match with each other.
|
||||
// 2. Assume that the expression is balanced i.e. the opening and closing brackets match with each
|
||||
// other.
|
||||
// 3. But, some of the pair of brackets maybe extra/needless.
|
||||
// 4. You are required to print true if you detect extra brackets and false otherwise.
|
||||
// e.g.'
|
||||
|
@ -10,8 +10,7 @@ public class InfixToPostfix {
|
||||
assert "34+5*6-".equals(infix2PostFix("(3+4)*5-6"));
|
||||
}
|
||||
|
||||
public static String infix2PostFix(String infixExpression)
|
||||
throws Exception {
|
||||
public static String infix2PostFix(String infixExpression) throws Exception {
|
||||
if (!BalancedBrackets.isBalanced(infixExpression)) {
|
||||
throw new Exception("invalid expression");
|
||||
}
|
||||
@ -28,10 +27,7 @@ public class InfixToPostfix {
|
||||
}
|
||||
stack.pop();
|
||||
} else {
|
||||
while (
|
||||
!stack.isEmpty() &&
|
||||
precedence(element) <= precedence(stack.peek())
|
||||
) {
|
||||
while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) {
|
||||
output.append(stack.pop());
|
||||
}
|
||||
stack.push(element);
|
||||
@ -45,16 +41,16 @@ public class InfixToPostfix {
|
||||
|
||||
private static int precedence(char operator) {
|
||||
switch (operator) {
|
||||
case '+':
|
||||
case '-':
|
||||
return 0;
|
||||
case '*':
|
||||
case '/':
|
||||
return 1;
|
||||
case '^':
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
case '+':
|
||||
case '-':
|
||||
return 0;
|
||||
case '*':
|
||||
case '/':
|
||||
return 1;
|
||||
case '^':
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class LargestRectangle {
|
||||
maxArea = Math.max(maxArea, tmp[1] * (i - tmp[0]));
|
||||
start = tmp[0];
|
||||
}
|
||||
st.push(new int[] { start, heights[i] });
|
||||
st.push(new int[] {start, heights[i]});
|
||||
}
|
||||
while (!st.isEmpty()) {
|
||||
int[] tmp = st.pop();
|
||||
@ -29,8 +29,7 @@ public class LargestRectangle {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
assert largestRectanglehistogram(new int[] { 2, 1, 5, 6, 2, 3 })
|
||||
.equals("10");
|
||||
assert largestRectanglehistogram(new int[] { 2, 4 }).equals("4");
|
||||
assert largestRectanglehistogram(new int[] {2, 1, 5, 6, 2, 3}).equals("10");
|
||||
assert largestRectanglehistogram(new int[] {2, 4}).equals("4");
|
||||
}
|
||||
}
|
||||
|
@ -97,8 +97,8 @@ public class MaximumMinimumWindow {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] arr = new int[] { 10, 20, 30, 50, 10, 70, 30 };
|
||||
int[] target = new int[] { 70, 30, 20, 10, 10, 10, 10 };
|
||||
int[] arr = new int[] {10, 20, 30, 50, 10, 70, 30};
|
||||
int[] target = new int[] {70, 30, 20, 10, 10, 10, 10};
|
||||
int[] res = calculateMaxOfMin(arr, arr.length);
|
||||
assert Arrays.equals(target, res);
|
||||
}
|
||||
|
@ -37,7 +37,8 @@ import java.util.Stack;
|
||||
popped elements.
|
||||
d. Finally, push the next in the stack.
|
||||
|
||||
3. If elements are left in stack after completing while loop then their Next Grater element is -1.
|
||||
3. If elements are left in stack after completing while loop then their Next Grater element is
|
||||
-1.
|
||||
*/
|
||||
|
||||
public class NextGraterElement {
|
||||
@ -61,7 +62,7 @@ public class NextGraterElement {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
int[] input = {2, 7, 3, 5, 4, 6, 8};
|
||||
int[] result = findNextGreaterElements(input);
|
||||
System.out.println(Arrays.toString(result));
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import java.util.Arrays;
|
||||
import java.util.Stack;
|
||||
|
||||
/*
|
||||
Given an array "input" you need to print the first smaller element for each element to the left side of an array.
|
||||
For a given element x of an array, the Next Smaller element of that element is the
|
||||
first smaller element to the left side of it. If no such element is present print -1.
|
||||
|
||||
Given an array "input" you need to print the first smaller element for each element to the left
|
||||
side of an array. For a given element x of an array, the Next Smaller element of that element is
|
||||
the first smaller element to the left side of it. If no such element is present print -1.
|
||||
|
||||
Example
|
||||
input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
At i = 0
|
||||
@ -24,17 +24,17 @@ import java.util.Stack;
|
||||
Next smaller element between (0 , 4) is 4
|
||||
At i = 6
|
||||
Next smaller element between (0 , 5) is 6
|
||||
|
||||
|
||||
result : [-1, 2, 2, 3, 3, 4, 6]
|
||||
|
||||
|
||||
1) Create a new empty stack st
|
||||
|
||||
|
||||
2) Iterate over array "input" , where "i" goes from 0 to input.length -1.
|
||||
a) We are looking for value just smaller than `input[i]`. So keep popping from "stack"
|
||||
a) We are looking for value just smaller than `input[i]`. So keep popping from "stack"
|
||||
till elements in "stack.peek() >= input[i]" or stack becomes empty.
|
||||
b) If the stack is non-empty, then the top element is our previous element. Else the previous element does not exist.
|
||||
c) push input[i] in stack.
|
||||
3) If elements are left then their answer is -1
|
||||
b) If the stack is non-empty, then the top element is our previous element. Else the
|
||||
previous element does not exist. c) push input[i] in stack. 3) If elements are left then their
|
||||
answer is -1
|
||||
*/
|
||||
|
||||
public class NextSmallerElement {
|
||||
@ -61,7 +61,7 @@ public class NextSmallerElement {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] input = { 2, 7, 3, 5, 4, 6, 8 };
|
||||
int[] input = {2, 7, 3, 5, 4, 6, 8};
|
||||
int[] result = findNextSmallerElements(input);
|
||||
System.out.println(Arrays.toString(result));
|
||||
}
|
||||
|
@ -50,7 +50,8 @@ public class NodeStack<Item> {
|
||||
/**
|
||||
* Constructors for the NodeStack.
|
||||
*/
|
||||
public NodeStack() {}
|
||||
public NodeStack() {
|
||||
}
|
||||
|
||||
private NodeStack(Item item) {
|
||||
this.data = item;
|
||||
|
@ -20,12 +20,12 @@ public class PostfixToInfix {
|
||||
|
||||
public static boolean isOperator(char token) {
|
||||
switch (token) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '/':
|
||||
case '*':
|
||||
case '^':
|
||||
return true;
|
||||
case '+':
|
||||
case '-':
|
||||
case '/':
|
||||
case '*':
|
||||
case '^':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -42,7 +42,8 @@ public class PostfixToInfix {
|
||||
int operandCount = 0;
|
||||
int operatorCount = 0;
|
||||
|
||||
/* Traverse the postfix string to check if --> Number of operands = Number of operators + 1 */
|
||||
/* Traverse the postfix string to check if --> Number of operands = Number of operators + 1
|
||||
*/
|
||||
for (int i = 0; i < postfix.length(); i++) {
|
||||
char token = postfix.charAt(i);
|
||||
|
||||
@ -59,8 +60,8 @@ public class PostfixToInfix {
|
||||
|
||||
/* Operand count is set to 2 because:-
|
||||
*
|
||||
* 1) the previous set of operands & operators combined have become a single valid expression,
|
||||
* which could be considered/assigned as a single operand.
|
||||
* 1) the previous set of operands & operators combined have become a single valid
|
||||
* expression, which could be considered/assigned as a single operand.
|
||||
*
|
||||
* 2) the operand in the current iteration.
|
||||
*/
|
||||
@ -123,7 +124,6 @@ public class PostfixToInfix {
|
||||
assert getPostfixToInfix("AB+CD+*").equals("((A+B)*(C+D))");
|
||||
assert getPostfixToInfix("AB+C+D+").equals("(((A+B)+C)+D)");
|
||||
assert getPostfixToInfix("ABCDE^*/-").equals("(A-(B/(C*(D^E))))");
|
||||
assert getPostfixToInfix("AB+CD^/E*FGH+-^")
|
||||
.equals("((((A+B)/(C^D))*E)^(F-(G+H)))");
|
||||
assert getPostfixToInfix("AB+CD^/E*FGH+-^").equals("((((A+B)/(C^D))*E)^(F-(G+H)))");
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,7 @@ public class ReverseStack {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Scanner sc = new Scanner(System.in);
|
||||
System.out.println(
|
||||
"Enter the number of elements you wish to insert in the stack"
|
||||
);
|
||||
System.out.println("Enter the number of elements you wish to insert in the stack");
|
||||
int n = sc.nextInt();
|
||||
int i;
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
@ -36,28 +34,29 @@ public class ReverseStack {
|
||||
return;
|
||||
}
|
||||
|
||||
//Store the topmost element
|
||||
// Store the topmost element
|
||||
int element = stack.peek();
|
||||
//Remove the topmost element
|
||||
// Remove the topmost element
|
||||
stack.pop();
|
||||
|
||||
//Reverse the stack for the leftover elements
|
||||
// Reverse the stack for the leftover elements
|
||||
reverseStack(stack);
|
||||
|
||||
//Insert the topmost element to the bottom of the stack
|
||||
// Insert the topmost element to the bottom of the stack
|
||||
insertAtBottom(stack, element);
|
||||
}
|
||||
|
||||
private static void insertAtBottom(Stack<Integer> stack, int element) {
|
||||
if (stack.isEmpty()) {
|
||||
//When stack is empty, insert the element so it will be present at the bottom of the stack
|
||||
// When stack is empty, insert the element so it will be present at the bottom of the
|
||||
// stack
|
||||
stack.push(element);
|
||||
return;
|
||||
}
|
||||
|
||||
int ele = stack.peek();
|
||||
/*Keep popping elements till stack becomes empty. Push the elements once the topmost element has
|
||||
moved to the bottom of the stack.
|
||||
/*Keep popping elements till stack becomes empty. Push the elements once the topmost element
|
||||
has moved to the bottom of the stack.
|
||||
*/
|
||||
stack.pop();
|
||||
insertAtBottom(stack, element);
|
||||
|
@ -23,9 +23,7 @@ class StackOfLinkedList {
|
||||
assert stack.pop() == 5;
|
||||
assert stack.pop() == 4;
|
||||
|
||||
System.out.println(
|
||||
"Top element of stack currently is: " + stack.peek()
|
||||
);
|
||||
System.out.println("Top element of stack currently is: " + stack.peek());
|
||||
}
|
||||
}
|
||||
|
||||
@ -120,9 +118,7 @@ class LinkedListStack {
|
||||
builder.append(cur.data).append("->");
|
||||
cur = cur.next;
|
||||
}
|
||||
return builder
|
||||
.replace(builder.length() - 2, builder.length(), "")
|
||||
.toString();
|
||||
return builder.replace(builder.length() - 2, builder.length(), "").toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,23 +3,23 @@ package com.thealgorithms.datastructures.trees;
|
||||
/*
|
||||
* Avl is algo that balance itself while adding new alues to tree
|
||||
* by rotating branches of binary tree and make itself Binary seaarch tree
|
||||
* there are four cases which has to tackle
|
||||
* rotating - left right ,left left,right right,right left
|
||||
* there are four cases which has to tackle
|
||||
* rotating - left right ,left left,right right,right left
|
||||
|
||||
Test Case:
|
||||
|
||||
AVLTree tree=new AVLTree();
|
||||
tree.insert(20);
|
||||
tree.insert(25);
|
||||
tree.insert(30);
|
||||
tree.insert(10);
|
||||
tree.insert(5);
|
||||
tree.insert(15);
|
||||
tree.insert(27);
|
||||
tree.insert(19);
|
||||
tree.insert(16);
|
||||
|
||||
tree.display();
|
||||
tree.insert(20);
|
||||
tree.insert(25);
|
||||
tree.insert(30);
|
||||
tree.insert(10);
|
||||
tree.insert(5);
|
||||
tree.insert(15);
|
||||
tree.insert(27);
|
||||
tree.insert(19);
|
||||
tree.insert(16);
|
||||
|
||||
tree.display();
|
||||
|
||||
|
||||
|
||||
@ -59,16 +59,16 @@ public class AVLSimple {
|
||||
}
|
||||
node.height = Math.max(height(node.left), height(node.right)) + 1;
|
||||
int bf = bf(node);
|
||||
//LL case
|
||||
// LL case
|
||||
if (bf > 1 && item < node.left.data) return rightRotate(node);
|
||||
//RR case
|
||||
// RR case
|
||||
if (bf < -1 && item > node.right.data) return leftRotate(node);
|
||||
//RL case
|
||||
// RL case
|
||||
if (bf < -1 && item < node.right.data) {
|
||||
node.right = rightRotate(node.right);
|
||||
return leftRotate(node);
|
||||
}
|
||||
//LR case
|
||||
// LR case
|
||||
if (bf > 1 && item > node.left.data) {
|
||||
node.left = leftRotate(node.left);
|
||||
return rightRotate(node);
|
||||
@ -84,11 +84,15 @@ public class AVLSimple {
|
||||
|
||||
private void display(Node node) {
|
||||
String str = "";
|
||||
if (node.left != null) str += node.left.data + "=>"; else str +=
|
||||
"END=>";
|
||||
if (node.left != null)
|
||||
str += node.left.data + "=>";
|
||||
else
|
||||
str += "END=>";
|
||||
str += node.data + "";
|
||||
if (node.right != null) str += "<=" + node.right.data; else str +=
|
||||
"<=END";
|
||||
if (node.right != null)
|
||||
str += "<=" + node.right.data;
|
||||
else
|
||||
str += "<=END";
|
||||
System.out.println(str);
|
||||
if (node.left != null) display(node.left);
|
||||
if (node.right != null) display(node.right);
|
||||
|
@ -39,17 +39,20 @@ public class BSTRecursiveGeneric<T extends Comparable<T>> {
|
||||
integerTree.add(5);
|
||||
integerTree.add(10);
|
||||
integerTree.add(9);
|
||||
assert !integerTree.find(4) : "4 is not yet present in BST";
|
||||
assert integerTree.find(10) : "10 should be present in BST";
|
||||
assert !integerTree.find(4)
|
||||
: "4 is not yet present in BST";
|
||||
assert integerTree.find(10)
|
||||
: "10 should be present in BST";
|
||||
integerTree.remove(9);
|
||||
assert !integerTree.find(9) : "9 was just deleted from BST";
|
||||
assert !integerTree.find(9)
|
||||
: "9 was just deleted from BST";
|
||||
integerTree.remove(1);
|
||||
assert !integerTree.find(
|
||||
1
|
||||
) : "Since 1 was not present so find deleting would do no change";
|
||||
assert !integerTree.find(1)
|
||||
: "Since 1 was not present so find deleting would do no change";
|
||||
integerTree.add(20);
|
||||
integerTree.add(70);
|
||||
assert integerTree.find(70) : "70 was inserted but not found";
|
||||
assert integerTree.find(70)
|
||||
: "70 was inserted but not found";
|
||||
/*
|
||||
Will print in following order
|
||||
5 10 20 70
|
||||
@ -63,17 +66,20 @@ public class BSTRecursiveGeneric<T extends Comparable<T>> {
|
||||
stringTree.add("banana");
|
||||
stringTree.add("pineapple");
|
||||
stringTree.add("date");
|
||||
assert !stringTree.find("girl") : "girl is not yet present in BST";
|
||||
assert stringTree.find("pineapple") : "10 should be present in BST";
|
||||
assert !stringTree.find("girl")
|
||||
: "girl is not yet present in BST";
|
||||
assert stringTree.find("pineapple")
|
||||
: "10 should be present in BST";
|
||||
stringTree.remove("date");
|
||||
assert !stringTree.find("date") : "date was just deleted from BST";
|
||||
assert !stringTree.find("date")
|
||||
: "date was just deleted from BST";
|
||||
stringTree.remove("boy");
|
||||
assert !stringTree.find(
|
||||
"boy"
|
||||
) : "Since boy was not present so deleting would do no change";
|
||||
assert !stringTree.find("boy")
|
||||
: "Since boy was not present so deleting would do no change";
|
||||
stringTree.add("india");
|
||||
stringTree.add("hills");
|
||||
assert stringTree.find("hills") : "hills was inserted but not found";
|
||||
assert stringTree.find("hills")
|
||||
: "hills was inserted but not found";
|
||||
/*
|
||||
Will print in following order
|
||||
banana hills india pineapple
|
||||
|
@ -143,7 +143,8 @@ public class BinaryTree {
|
||||
if (temp.right == null && temp.left == null) {
|
||||
if (temp == root) {
|
||||
root = null;
|
||||
} // This if/else assigns the new node to be either the left or right child of the parent
|
||||
} // This if/else assigns the new node to be either the left or right child of the
|
||||
// parent
|
||||
else if (temp.parent.data < temp.data) {
|
||||
temp.parent.right = null;
|
||||
} else {
|
||||
@ -179,7 +180,8 @@ public class BinaryTree {
|
||||
else {
|
||||
successor.parent = temp.parent;
|
||||
|
||||
// This if/else assigns the new node to be either the left or right child of the parent
|
||||
// This if/else assigns the new node to be either the left or right child of the
|
||||
// parent
|
||||
if (temp.parent.data < temp.data) {
|
||||
temp.parent.right = successor;
|
||||
} else {
|
||||
|
@ -24,8 +24,6 @@ public class CheckBinaryTreeIsValidBST {
|
||||
}
|
||||
|
||||
return (
|
||||
isBSTUtil(node.left, min, node.data - 1) &&
|
||||
isBSTUtil(node.right, node.data + 1, max)
|
||||
);
|
||||
isBSTUtil(node.left, min, node.data - 1) && isBSTUtil(node.right, node.data + 1, max));
|
||||
}
|
||||
}
|
||||
|
@ -80,11 +80,7 @@ public class CheckIfBinaryTreeBalanced {
|
||||
* @param depth The current depth of the node
|
||||
* @param isBalanced The array of length 1 keeping track of our balance
|
||||
*/
|
||||
private int isBalancedRecursive(
|
||||
BTNode node,
|
||||
int depth,
|
||||
boolean[] isBalanced
|
||||
) {
|
||||
private int isBalancedRecursive(BTNode node, int depth, boolean[] isBalanced) {
|
||||
// If the node is null, we should not explore it and the height is 0
|
||||
// If the tree is already not balanced, might as well stop because we
|
||||
// can't make it balanced now!
|
||||
@ -94,11 +90,7 @@ public class CheckIfBinaryTreeBalanced {
|
||||
|
||||
// Visit the left and right children, incrementing their depths by 1
|
||||
int leftHeight = isBalancedRecursive(node.left, depth + 1, isBalanced);
|
||||
int rightHeight = isBalancedRecursive(
|
||||
node.right,
|
||||
depth + 1,
|
||||
isBalanced
|
||||
);
|
||||
int rightHeight = isBalancedRecursive(node.right, depth + 1, isBalanced);
|
||||
|
||||
// If the height of either of the left or right subtrees differ by more
|
||||
// than 1, we cannot be balanced
|
||||
@ -174,10 +166,7 @@ public class CheckIfBinaryTreeBalanced {
|
||||
|
||||
// The height of the subtree containing this node is the
|
||||
// max of the left and right subtree heighs plus 1
|
||||
subtreeHeights.put(
|
||||
node,
|
||||
Math.max(rightHeight, leftHeight) + 1
|
||||
);
|
||||
subtreeHeights.put(node, Math.max(rightHeight, leftHeight) + 1);
|
||||
|
||||
// We've now visited this node, so we pop it from the stack
|
||||
nodeStack.pop();
|
||||
|
@ -48,10 +48,12 @@ public class CheckTreeIsSymmetric {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isSymmetric(leftSubtreeRoot.right, rightSubtreRoot.left) && isSymmetric(leftSubtreeRoot.left, rightSubtreRoot.right);
|
||||
return isSymmetric(leftSubtreeRoot.right, rightSubtreRoot.left)
|
||||
&& isSymmetric(leftSubtreeRoot.left, rightSubtreRoot.right);
|
||||
}
|
||||
|
||||
private static boolean isInvalidSubtree(Node leftSubtreeRoot, Node rightSubtreeRoot) {
|
||||
return leftSubtreeRoot == null || rightSubtreeRoot == null || leftSubtreeRoot.data != rightSubtreeRoot.data;
|
||||
return leftSubtreeRoot == null || rightSubtreeRoot == null
|
||||
|| leftSubtreeRoot.data != rightSubtreeRoot.data;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.thealgorithms.datastructures.trees;
|
||||
|
||||
import com.thealgorithms.datastructures.trees.BinaryTree.Node;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -37,13 +36,8 @@ public class CreateBinaryTreeFromInorderPreorder {
|
||||
return createTreeOptimized(preorder, inorderMap, 0, 0, inorder.length);
|
||||
}
|
||||
|
||||
private static Node createTree(
|
||||
final Integer[] preorder,
|
||||
final Integer[] inorder,
|
||||
final int preStart,
|
||||
final int inStart,
|
||||
final int size
|
||||
) {
|
||||
private static Node createTree(final Integer[] preorder, final Integer[] inorder,
|
||||
final int preStart, final int inStart, final int size) {
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -55,32 +49,15 @@ public class CreateBinaryTreeFromInorderPreorder {
|
||||
}
|
||||
int leftNodesCount = i - inStart;
|
||||
int rightNodesCount = size - leftNodesCount - 1;
|
||||
root.left =
|
||||
createTree(
|
||||
preorder,
|
||||
inorder,
|
||||
preStart + 1,
|
||||
inStart,
|
||||
leftNodesCount
|
||||
);
|
||||
root.right =
|
||||
createTree(
|
||||
preorder,
|
||||
inorder,
|
||||
preStart + leftNodesCount + 1,
|
||||
i + 1,
|
||||
rightNodesCount
|
||||
);
|
||||
root.left = createTree(preorder, inorder, preStart + 1, inStart, leftNodesCount);
|
||||
root.right
|
||||
= createTree(preorder, inorder, preStart + leftNodesCount + 1, i + 1, rightNodesCount);
|
||||
return root;
|
||||
}
|
||||
|
||||
private static Node createTreeOptimized(
|
||||
final Integer[] preorder,
|
||||
final Map<Integer, Integer> inorderMap,
|
||||
final int preStart,
|
||||
final int inStart,
|
||||
final int size
|
||||
) {
|
||||
private static Node createTreeOptimized(final Integer[] preorder,
|
||||
final Map<Integer, Integer> inorderMap, final int preStart, final int inStart,
|
||||
final int size) {
|
||||
if (size == 0) {
|
||||
return null;
|
||||
}
|
||||
@ -89,22 +66,10 @@ public class CreateBinaryTreeFromInorderPreorder {
|
||||
int i = inorderMap.get(preorder[preStart]);
|
||||
int leftNodesCount = i - inStart;
|
||||
int rightNodesCount = size - leftNodesCount - 1;
|
||||
root.left =
|
||||
createTreeOptimized(
|
||||
preorder,
|
||||
inorderMap,
|
||||
preStart + 1,
|
||||
inStart,
|
||||
leftNodesCount
|
||||
);
|
||||
root.right =
|
||||
createTreeOptimized(
|
||||
preorder,
|
||||
inorderMap,
|
||||
preStart + leftNodesCount + 1,
|
||||
i + 1,
|
||||
rightNodesCount
|
||||
);
|
||||
root.left
|
||||
= createTreeOptimized(preorder, inorderMap, preStart + 1, inStart, leftNodesCount);
|
||||
root.right = createTreeOptimized(
|
||||
preorder, inorderMap, preStart + leftNodesCount + 1, i + 1, rightNodesCount);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,7 @@ public class GenericTree {
|
||||
if (node == null) {
|
||||
System.out.println("Enter root's data");
|
||||
} else {
|
||||
System.out.println(
|
||||
"Enter data of parent of index " + node.data + " " + childindx
|
||||
);
|
||||
System.out.println("Enter data of parent of index " + node.data + " " + childindx);
|
||||
}
|
||||
// input
|
||||
node = new Node();
|
||||
|
@ -34,15 +34,11 @@ public class KDTree {
|
||||
* @param points Array of initial points
|
||||
*/
|
||||
KDTree(Point[] points) {
|
||||
if (points.length == 0) throw new IllegalArgumentException(
|
||||
"Points array cannot be empty"
|
||||
);
|
||||
if (points.length == 0) throw new IllegalArgumentException("Points array cannot be empty");
|
||||
this.k = points[0].getDimension();
|
||||
for (Point point : points) if (
|
||||
point.getDimension() != k
|
||||
) throw new IllegalArgumentException(
|
||||
"Points must have the same dimension"
|
||||
);
|
||||
for (Point point : points)
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Points must have the same dimension");
|
||||
this.root = build(points, 0);
|
||||
}
|
||||
|
||||
@ -53,19 +49,13 @@ public class KDTree {
|
||||
*
|
||||
*/
|
||||
KDTree(int[][] pointsCoordinates) {
|
||||
if (pointsCoordinates.length == 0) throw new IllegalArgumentException(
|
||||
"Points array cannot be empty"
|
||||
);
|
||||
if (pointsCoordinates.length == 0)
|
||||
throw new IllegalArgumentException("Points array cannot be empty");
|
||||
this.k = pointsCoordinates[0].length;
|
||||
Point[] points = Arrays
|
||||
.stream(pointsCoordinates)
|
||||
.map(Point::new)
|
||||
.toArray(Point[]::new);
|
||||
for (Point point : points) if (
|
||||
point.getDimension() != k
|
||||
) throw new IllegalArgumentException(
|
||||
"Points must have the same dimension"
|
||||
);
|
||||
Point[] points = Arrays.stream(pointsCoordinates).map(Point::new).toArray(Point[] ::new);
|
||||
for (Point point : points)
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Points must have the same dimension");
|
||||
this.root = build(points, 0);
|
||||
}
|
||||
|
||||
@ -125,11 +115,7 @@ public class KDTree {
|
||||
*
|
||||
* @return The distance between the two points
|
||||
*/
|
||||
public static int comparableDistanceExceptAxis(
|
||||
Point p1,
|
||||
Point p2,
|
||||
int axis
|
||||
) {
|
||||
public static int comparableDistanceExceptAxis(Point p1, Point p2, int axis) {
|
||||
int distance = 0;
|
||||
for (int i = 0; i < p1.getDimension(); i++) {
|
||||
if (i == axis) continue;
|
||||
@ -177,9 +163,10 @@ public class KDTree {
|
||||
* @return The nearest child Node
|
||||
*/
|
||||
public Node getNearChild(Point point) {
|
||||
if (
|
||||
point.getCoordinate(axis) < this.point.getCoordinate(axis)
|
||||
) return left; else return right;
|
||||
if (point.getCoordinate(axis) < this.point.getCoordinate(axis))
|
||||
return left;
|
||||
else
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -190,9 +177,10 @@ public class KDTree {
|
||||
* @return The farthest child Node
|
||||
*/
|
||||
public Node getFarChild(Point point) {
|
||||
if (
|
||||
point.getCoordinate(axis) < this.point.getCoordinate(axis)
|
||||
) return right; else return left;
|
||||
if (point.getCoordinate(axis) < this.point.getCoordinate(axis))
|
||||
return right;
|
||||
else
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,18 +209,11 @@ public class KDTree {
|
||||
if (points.length == 0) return null;
|
||||
int axis = depth % k;
|
||||
if (points.length == 1) return new Node(points[0], axis);
|
||||
Arrays.sort(
|
||||
points,
|
||||
Comparator.comparingInt(o -> o.getCoordinate(axis))
|
||||
);
|
||||
Arrays.sort(points, Comparator.comparingInt(o -> o.getCoordinate(axis)));
|
||||
int median = points.length >> 1;
|
||||
Node node = new Node(points[median], axis);
|
||||
node.left = build(Arrays.copyOfRange(points, 0, median), depth + 1);
|
||||
node.right =
|
||||
build(
|
||||
Arrays.copyOfRange(points, median + 1, points.length),
|
||||
depth + 1
|
||||
);
|
||||
node.right = build(Arrays.copyOfRange(points, median + 1, points.length), depth + 1);
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -243,9 +224,8 @@ public class KDTree {
|
||||
*
|
||||
*/
|
||||
public void insert(Point point) {
|
||||
if (point.getDimension() != k) throw new IllegalArgumentException(
|
||||
"Point has wrong dimension"
|
||||
);
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Point has wrong dimension");
|
||||
root = insert(root, point, 0);
|
||||
}
|
||||
|
||||
@ -261,9 +241,10 @@ public class KDTree {
|
||||
private Node insert(Node root, Point point, int depth) {
|
||||
int axis = depth % k;
|
||||
if (root == null) return new Node(point, axis);
|
||||
if (point.getCoordinate(axis) < root.getAxisCoordinate()) root.left =
|
||||
insert(root.left, point, depth + 1); else root.right =
|
||||
insert(root.right, point, depth + 1);
|
||||
if (point.getCoordinate(axis) < root.getAxisCoordinate())
|
||||
root.left = insert(root.left, point, depth + 1);
|
||||
else
|
||||
root.right = insert(root.right, point, depth + 1);
|
||||
|
||||
return root;
|
||||
}
|
||||
@ -276,9 +257,8 @@ public class KDTree {
|
||||
* @return The Node corresponding to the specified point
|
||||
*/
|
||||
public Optional<Node> search(Point point) {
|
||||
if (point.getDimension() != k) throw new IllegalArgumentException(
|
||||
"Point has wrong dimension"
|
||||
);
|
||||
if (point.getDimension() != k)
|
||||
throw new IllegalArgumentException("Point has wrong dimension");
|
||||
return search(root, point);
|
||||
}
|
||||
|
||||
@ -323,9 +303,8 @@ public class KDTree {
|
||||
} else {
|
||||
Node left = findMin(root.left, axis);
|
||||
Node right = findMin(root.right, axis);
|
||||
Node[] candidates = { left, root, right };
|
||||
return Arrays
|
||||
.stream(candidates)
|
||||
Node[] candidates = {left, root, right};
|
||||
return Arrays.stream(candidates)
|
||||
.filter(Objects::nonNull)
|
||||
.min(Comparator.comparingInt(a -> a.point.getCoordinate(axis)))
|
||||
.orElse(null);
|
||||
@ -359,9 +338,8 @@ public class KDTree {
|
||||
} else {
|
||||
Node left = findMax(root.left, axis);
|
||||
Node right = findMax(root.right, axis);
|
||||
Node[] candidates = { left, root, right };
|
||||
return Arrays
|
||||
.stream(candidates)
|
||||
Node[] candidates = {left, root, right};
|
||||
return Arrays.stream(candidates)
|
||||
.filter(Objects::nonNull)
|
||||
.max(Comparator.comparingInt(a -> a.point.getCoordinate(axis)))
|
||||
.orElse(null);
|
||||
@ -374,8 +352,8 @@ public class KDTree {
|
||||
* @param point the point to delete
|
||||
* */
|
||||
public void delete(Point point) {
|
||||
Node node = search(point)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Point not found"));
|
||||
Node node
|
||||
= search(point).orElseThrow(() -> new IllegalArgumentException("Point not found"));
|
||||
root = delete(root, node);
|
||||
}
|
||||
|
||||
@ -398,12 +376,13 @@ public class KDTree {
|
||||
Node min = findMin(root.left, root.getAxis());
|
||||
root.point = min.point;
|
||||
root.left = delete(root.left, min);
|
||||
} else return null;
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
root.getAxisCoordinate() < node.point.getCoordinate(root.getAxis())
|
||||
) root.left = delete(root.left, node); else root.right =
|
||||
delete(root.right, node);
|
||||
if (root.getAxisCoordinate() < node.point.getCoordinate(root.getAxis()))
|
||||
root.left = delete(root.left, node);
|
||||
else
|
||||
root.right = delete(root.right, node);
|
||||
return root;
|
||||
}
|
||||
|
||||
@ -427,17 +406,12 @@ public class KDTree {
|
||||
if (root == null) return nearest;
|
||||
if (root.point.equals(point)) return root;
|
||||
int distance = Point.comparableDistance(root.point, point);
|
||||
int distanceExceptAxis = Point.comparableDistanceExceptAxis(
|
||||
root.point,
|
||||
point,
|
||||
root.getAxis()
|
||||
);
|
||||
if (distance < Point.comparableDistance(nearest.point, point)) nearest =
|
||||
root;
|
||||
int distanceExceptAxis
|
||||
= Point.comparableDistanceExceptAxis(root.point, point, root.getAxis());
|
||||
if (distance < Point.comparableDistance(nearest.point, point)) nearest = root;
|
||||
nearest = findNearest(root.getNearChild(point), point, nearest);
|
||||
if (
|
||||
distanceExceptAxis < Point.comparableDistance(nearest.point, point)
|
||||
) nearest = findNearest(root.getFarChild(point), point, nearest);
|
||||
if (distanceExceptAxis < Point.comparableDistance(nearest.point, point))
|
||||
nearest = findNearest(root.getFarChild(point), point, nearest);
|
||||
return nearest;
|
||||
}
|
||||
}
|
||||
|
@ -8,17 +8,17 @@ public class LCA {
|
||||
private static Scanner scanner = new Scanner(System.in);
|
||||
|
||||
public static void main(String[] args) {
|
||||
//The adjacency list representation of a tree:
|
||||
// The adjacency list representation of a tree:
|
||||
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
|
||||
|
||||
//v is the number of vertices and e is the number of edges
|
||||
// v is the number of vertices and e is the number of edges
|
||||
int v = scanner.nextInt(), e = v - 1;
|
||||
|
||||
for (int i = 0; i < v; i++) {
|
||||
adj.add(new ArrayList<Integer>());
|
||||
}
|
||||
|
||||
//Storing the given tree as an adjacency list
|
||||
// Storing the given tree as an adjacency list
|
||||
int to, from;
|
||||
for (int i = 0; i < e; i++) {
|
||||
to = scanner.nextInt();
|
||||
@ -28,19 +28,19 @@ public class LCA {
|
||||
adj.get(from).add(to);
|
||||
}
|
||||
|
||||
//parent[v1] gives parent of a vertex v1
|
||||
// parent[v1] gives parent of a vertex v1
|
||||
int[] parent = new int[v];
|
||||
|
||||
//depth[v1] gives depth of vertex v1 with respect to the root
|
||||
// depth[v1] gives depth of vertex v1 with respect to the root
|
||||
int[] depth = new int[v];
|
||||
|
||||
//Assuming the tree to be rooted at 0, hence calculating parent and depth of every vertex
|
||||
// Assuming the tree to be rooted at 0, hence calculating parent and depth of every vertex
|
||||
dfs(adj, 0, -1, parent, depth);
|
||||
|
||||
//Inputting the two vertices whose LCA is to be calculated
|
||||
// Inputting the two vertices whose LCA is to be calculated
|
||||
int v1 = scanner.nextInt(), v2 = scanner.nextInt();
|
||||
|
||||
//Outputting the LCA
|
||||
// Outputting the LCA
|
||||
System.out.println(getLCA(v1, v2, depth, parent));
|
||||
}
|
||||
|
||||
@ -54,12 +54,7 @@ public class LCA {
|
||||
* @param depth An array to store depth of all vertices
|
||||
*/
|
||||
private static void dfs(
|
||||
ArrayList<ArrayList<Integer>> adj,
|
||||
int s,
|
||||
int p,
|
||||
int[] parent,
|
||||
int[] depth
|
||||
) {
|
||||
ArrayList<ArrayList<Integer>> adj, int s, int p, int[] parent, int[] depth) {
|
||||
for (int adjacent : adj.get(s)) {
|
||||
if (adjacent != p) {
|
||||
parent[adjacent] = s;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user