diff --git a/.gitignore b/.gitignore index 129bc5fbd7b7..e74117ebc9b3 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,12 @@ gradle-app.setting !gradle-wrapper.jar build/ +# maven +*.classpath +*.project +*.settings +/target/ + local.properties ##----------idea---------- @@ -35,4 +41,4 @@ gradle.properties .vscode -*.log \ No newline at end of file +*.log diff --git a/Backtracking/PowerSum.java b/Backtracking/PowerSum.java deleted file mode 100644 index c06fa4439197..000000000000 --- a/Backtracking/PowerSum.java +++ /dev/null @@ -1,52 +0,0 @@ -package Backtracking; - -import java.util.Scanner; -/* - * 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. -*/ -public class PowerSum { - - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - System.out.println("Enter the number and the power"); - int N = sc.nextInt(); - int X = sc.nextInt(); - PowerSum ps = new PowerSum(); - int count = ps.powSum(N,X); - //printing the answer. - System.out.println("Number of combinations of different natural number's raised to "+X+" having sum "+N+" are : "); - System.out.println(count); - sc.close(); - } - private int count = 0,sum=0; - public int powSum(int N, int X) { - Sum(N,X,1); - return count; - } - //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 == 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. - 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. - sum-=power(i,X); - } - if(power(i,X) 0; i--) { - cipherText = addRoundKey(cipherText, roundKeys[i]); - cipherText = mixColumnsDec(cipherText); - cipherText = shiftRowsDec(cipherText); - cipherText = subBytesDec(cipherText); - } - - // Invert initial round - cipherText = addRoundKey(cipherText, roundKeys[0]); - - return cipherText; - } - - 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 :"); - char choice = input.nextLine().charAt(0); - String in; - switch (choice) { - case 'E', 'e' -> { - System.out.println("Choose a plaintext block (128-Bit Integer in base 16):"); - in = input.nextLine(); - BigInteger plaintext = new BigInteger(in, 16); - System.out.println("Choose a Key (128-Bit Integer in base 16):"); - in = input.nextLine(); - BigInteger encryptionKey = new BigInteger(in, 16); - System.out.println( - "The encrypted message is: \n" + encrypt(plaintext, encryptionKey).toString(16)); - } - case 'D', 'd' -> { - System.out.println("Enter your ciphertext block (128-Bit Integer in base 16):"); - in = input.nextLine(); - BigInteger ciphertext = new BigInteger(in, 16); - System.out.println("Choose a Key (128-Bit Integer in base 16):"); - in = input.nextLine(); - BigInteger decryptionKey = new BigInteger(in, 16); - System.out.println( - "The deciphered message is:\n" + decrypt(ciphertext, decryptionKey).toString(16)); - } - default -> System.out.println("** End **"); - } - } - } -} diff --git a/Conversions/AnyBaseToAnyBase.java b/Conversions/AnyBaseToAnyBase.java deleted file mode 100644 index 2fc4499a0526..000000000000 --- a/Conversions/AnyBaseToAnyBase.java +++ /dev/null @@ -1,127 +0,0 @@ -package Conversions; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.InputMismatchException; -import java.util.Scanner; - -/** - * Class for converting from "any" base to "any" other base, when "any" means from 2-36. Works by - * going from base 1 to decimal to base 2. Includes auxiliary method for determining whether a - * number is valid for a given base. - * - * @author Michael Rolland - * @version 2017.10.10 - */ -public class AnyBaseToAnyBase { - - /** Smallest and largest base you want to accept as valid input */ - static final int MINIMUM_BASE = 2; - - static final int MAXIMUM_BASE = 36; - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - String n; - int b1, b2; - while (true) { - try { - System.out.print("Enter number: "); - n = in.next(); - 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!"); - continue; - } - if (!validForBase(n, b1)) { - System.out.println("The number is invalid for this base!"); - continue; - } - System.out.print( - "Enter end base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): "); - b2 = in.nextInt(); - if (b2 > MAXIMUM_BASE || b2 < MINIMUM_BASE) { - System.out.println("Invalid base!"); - continue; - } - break; - } catch (InputMismatchException e) { - System.out.println("Invalid input."); - in.next(); - } - } - System.out.println(base2base(n, b1, b2)); - in.close(); - } - - /** Checks if a number (as a String) is valid for a given base. */ - public static boolean validForBase(String n, int base) { - char[] validDigits = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' - }; - // digitsForBase contains all the valid digits for the base given - char[] digitsForBase = Arrays.copyOfRange(validDigits, 0, base); - - // Convert character array into set for convenience of contains() method - HashSet digitsList = new HashSet<>(); - for (int i = 0; i < digitsForBase.length; i++) digitsList.add(digitsForBase[i]); - - // Check that every digit in n is within the list of valid digits for that base. - for (char c : n.toCharArray()) if (!digitsList.contains(c)) return false; - - return true; - } - - /** - * Method to convert any integer from base b1 to base b2. Works by converting from b1 to decimal, - * then decimal to b2. - * - * @param n The integer to be converted. - * @param b1 Beginning base. - * @param b2 End base. - * @return n in base b2. - */ - public static String base2base(String n, int b1, int b2) { - // Declare variables: decimal value of n, - // character of base b1, character of base b2, - // and the string that will be returned. - int decimalValue = 0, charB2; - char charB1; - String output = ""; - // Go through every character of n - for (int i = 0; i < n.length(); i++) { - // store the character in charB1 - charB1 = n.charAt(i); - // if it is a non-number, convert it to a decimal value >9 and store it in charB2 - if (charB1 >= 'A' && charB1 <= 'Z') charB2 = 10 + (charB1 - 'A'); - // Else, store the integer value in charB2 - else charB2 = charB1 - '0'; - // Convert the digit to decimal and add it to the - // decimalValue of n - decimalValue = decimalValue * b1 + charB2; - } - - // Converting the decimal value to base b2: - // A number is converted from decimal to another base - // by continuously dividing by the base and recording - // the remainder until the quotient is zero. The number in the - // new base is the remainders, with the last remainder - // being the left-most digit. - if (0 == decimalValue) return "0"; - // While the quotient is NOT zero: - while (decimalValue != 0) { - // If the remainder is a digit < 10, simply add it to - // the left side of the new number. - if (decimalValue % b2 < 10) output = Integer.toString(decimalValue % b2) + output; - // If the remainder is >= 10, add a character with the - // corresponding value to the new number. (A = 10, B = 11, C = 12, ...) - else output = (char) ((decimalValue % b2) + 55) + output; - // Divide by the new base again - decimalValue /= b2; - } - return output; - } -} diff --git a/Conversions/AnyBaseToDecimal.java b/Conversions/AnyBaseToDecimal.java deleted file mode 100644 index 61b1a82f0ea3..000000000000 --- a/Conversions/AnyBaseToDecimal.java +++ /dev/null @@ -1,51 +0,0 @@ -package Conversions; - -/** @author Varun Upadhyay (https://github.com/varunu28) */ - -// Driver program -public class AnyBaseToDecimal { - public static void main(String[] args) { - assert convertToDecimal("1010", 2) == Integer.valueOf("1010", 2); - assert convertToDecimal("777", 8) == Integer.valueOf("777", 8); - assert convertToDecimal("999", 10) == Integer.valueOf("999", 10); - assert convertToDecimal("ABCDEF", 16) == Integer.valueOf("ABCDEF", 16); - assert convertToDecimal("XYZ", 36) == Integer.valueOf("XYZ", 36); - } - - /** - * Convert any radix to decimal number - * - * @param s the string to be convert - * @param radix the radix - * @return decimal of bits - * @throws NumberFormatException if {@code bits} or {@code radix} is invalid - */ - public static int convertToDecimal(String s, int radix) { - int num = 0; - int pow = 1; - - for (int i = s.length() - 1; i >= 0; i--) { - int digit = valOfChar(s.charAt(i)); - if (digit >= radix) { - throw new NumberFormatException("For input string " + s); - } - num += valOfChar(s.charAt(i)) * pow; - pow *= radix; - } - return num; - } - - /** - * Convert character to integer - * - * @param c the character - * @return represented digit of given character - * @throws NumberFormatException if {@code ch} is not UpperCase or Digit character. - */ - public static int valOfChar(char c) { - if (!(Character.isUpperCase(c) || Character.isDigit(c))) { - throw new NumberFormatException("invalid character :" + c); - } - return Character.isDigit(c) ? c - '0' : c - 'A' + 10; - } -} diff --git a/Conversions/AnytoAny.java b/Conversions/AnytoAny.java deleted file mode 100644 index c213513171ef..000000000000 --- a/Conversions/AnytoAny.java +++ /dev/null @@ -1,30 +0,0 @@ -package Conversions; - -import java.util.Scanner; -// given a source number , source base, destination base, this code can give you the destination -// number. -// sn ,sb,db ---> ()dn . this is what we have to do . - -public class AnytoAny { - - public static void main(String[] args) { - Scanner scn = new Scanner(System.in); - int sn = scn.nextInt(); - int sb = scn.nextInt(); - int db = scn.nextInt(); - int m = 1, dec = 0, dn = 0; - while (sn != 0) { - dec = dec + (sn % 10) * m; - m *= sb; - sn /= 10; - } - m = 1; - while (dec != 0) { - dn = dn + (dec % db) * m; - m *= 10; - dec /= db; - } - System.out.println(dn); - scn.close(); - } -} diff --git a/Conversions/BinaryToDecimal.java b/Conversions/BinaryToDecimal.java deleted file mode 100644 index beb71af5107d..000000000000 --- a/Conversions/BinaryToDecimal.java +++ /dev/null @@ -1,27 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** This class converts a Binary number to a Decimal number */ -class BinaryToDecimal { - - /** - * Main Method - * - * @param args Command line arguments - */ - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - int binNum, binCopy, d, s = 0, power = 0; - System.out.print("Binary number: "); - binNum = sc.nextInt(); - binCopy = binNum; - while (binCopy != 0) { - d = binCopy % 10; - s += d * (int) Math.pow(2, power++); - binCopy /= 10; - } - System.out.println("Decimal equivalent:" + s); - sc.close(); - } -} diff --git a/Conversions/BinaryToHexadecimal.java b/Conversions/BinaryToHexadecimal.java deleted file mode 100644 index c5ff3298fd03..000000000000 --- a/Conversions/BinaryToHexadecimal.java +++ /dev/null @@ -1,55 +0,0 @@ -package Conversions; - -import java.util.*; - -/** - * Converts any Binary Number to a Hexadecimal Number - * - * @author Nishita Aggarwal - */ -public class BinaryToHexadecimal { - - /** - * This method converts a binary number to a hexadecimal number. - * - * @param binary The binary number - * @return The hexadecimal number - */ - static String binToHex(int binary) { - // hm to store hexadecimal codes for binary numbers within the range: 0000 to 1111 i.e. for - // decimal numbers 0 to 15 - HashMap hm = new HashMap<>(); - // String to store hexadecimal code - String hex = ""; - int i; - for (i = 0; i < 10; i++) { - hm.put(i, String.valueOf(i)); - } - for (i = 10; i < 16; i++) hm.put(i, String.valueOf((char) ('A' + i - 10))); - int currbit; - while (binary != 0) { - int code4 = 0; // to store decimal equivalent of number formed by 4 decimal digits - for (i = 0; i < 4; i++) { - currbit = binary % 10; - binary = binary / 10; - code4 += currbit * Math.pow(2, i); - } - hex = hm.get(code4) + hex; - } - return hex; - } - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - System.out.println("Enter binary number:"); - int binary = sc.nextInt(); - String hex = binToHex(binary); - System.out.println("Hexadecimal Code:" + hex); - sc.close(); - } -} diff --git a/Conversions/BinaryToOctal.java b/Conversions/BinaryToOctal.java deleted file mode 100644 index 1ea555e42916..000000000000 --- a/Conversions/BinaryToOctal.java +++ /dev/null @@ -1,47 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** - * Converts any Binary number to an Octal Number - * - * @author Zachary Jones - */ -public class BinaryToOctal { - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - System.out.println("Input the binary number: "); - int b = sc.nextInt(); - System.out.println("Octal equivalent: " + convertBinaryToOctal(b)); - sc.close(); - } - - /** - * This method converts a binary number to an octal number. - * - * @param binary The binary number - * @return The octal number - */ - public static String convertBinaryToOctal(int binary) { - String octal = ""; - int currBit = 0, j = 1; - while (binary != 0) { - int code3 = 0; - for (int i = 0; i < 3; i++) { - currBit = binary % 10; - binary = binary / 10; - code3 += currBit * j; - j *= 2; - } - octal = code3 + octal; - j = 1; - } - return octal; - } -} diff --git a/Conversions/DecimalToAnyBase.java b/Conversions/DecimalToAnyBase.java deleted file mode 100644 index 127cc22c0ce7..000000000000 --- a/Conversions/DecimalToAnyBase.java +++ /dev/null @@ -1,61 +0,0 @@ -package Conversions; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.util.ArrayList; - -/** @author Varun Upadhyay (https://github.com/varunu28) */ - -// Driver Program -public class DecimalToAnyBase { - public static void main(String[] args) throws Exception { - 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(); - - System.out.println("Enter the base below: "); - 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)); - - br.close(); - } - - /** - * This method produces a String value of any given input decimal in any base - * - * @param inp Decimal of which we need the value in base in String format - * @return string format of the converted value in the given base - */ - public static String convertToAnyBase(int inp, int base) { - ArrayList charArr = new ArrayList<>(); - - while (inp > 0) { - charArr.add(reVal(inp % base)); - inp /= base; - } - - StringBuilder str = new StringBuilder(charArr.size()); - - for (Character ch : charArr) { - str.append(ch); - } - - return str.reverse().toString(); - } - - /** - * This method produces character value of the input integer and returns it - * - * @param num integer of which we need the character value of - * @return character value of input integer - */ - public static char reVal(int num) { - if (num >= 0 && num <= 9) return (char) (num + '0'); - else return (char) (num - 10 + 'A'); - } -} diff --git a/Conversions/DecimalToBinary.java b/Conversions/DecimalToBinary.java deleted file mode 100644 index 0f79394c79db..000000000000 --- a/Conversions/DecimalToBinary.java +++ /dev/null @@ -1,47 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** This class converts a Decimal number to a Binary number */ -class DecimalToBinary { - - /** - * Main Method - * - * @param args Command Line Arguments - */ - public static void main(String args[]) { - conventionalConversion(); - bitwiseConversion(); - } - - /** This method converts a decimal number to a binary number using a conventional algorithm. */ - 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: "); - n = input.nextInt(); - while (n != 0) { - d = n % 2; - b = b + d * (int) Math.pow(10, c++); - n /= 2; - } // converting decimal to binary - System.out.println("\tBinary number: " + b); - input.close(); - } - - /** This method converts a decimal number to a binary number using a bitwise algorithm */ - public static void bitwiseConversion() { - int n, b = 0, c = 0, d; - Scanner input = new Scanner(System.in); - System.out.printf("Bitwise conversion.%n Enter the decimal number: "); - n = input.nextInt(); - while (n != 0) { - d = (n & 1); - b += d * (int) Math.pow(10, c++); - n >>= 1; - } - System.out.println("\tBinary number: " + b); - input.close(); - } -} diff --git a/Conversions/DecimalToHexaDecimal.java b/Conversions/DecimalToHexaDecimal.java deleted file mode 100644 index 21abb681a547..000000000000 --- a/Conversions/DecimalToHexaDecimal.java +++ /dev/null @@ -1,33 +0,0 @@ -package Conversions; - -// hex = [0 - 9] -> [A - F] -class DecimalToHexaDecimal { - private static final int sizeOfIntInHalfBytes = 8; - private static final int numberOfBitsInAHalfByte = 4; - private static final int halfByte = 0x0F; - private static final char[] hexDigits = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - - // Returns the hex value of the dec entered in the parameter. - public static String decToHex(int dec) { - StringBuilder hexBuilder = new StringBuilder(sizeOfIntInHalfBytes); - hexBuilder.setLength(sizeOfIntInHalfBytes); - for (int i = sizeOfIntInHalfBytes - 1; i >= 0; --i) { - int j = dec & halfByte; - hexBuilder.setCharAt(i, hexDigits[j]); - dec >>= numberOfBitsInAHalfByte; - } - return hexBuilder.toString().toLowerCase(); - } - - // Test above function. - public static void main(String[] args) { - System.out.println("Test..."); - int dec = 305445566; - String libraryDecToHex = Integer.toHexString(dec); - String decToHex = decToHex(dec); - System.out.println("Result from the library : " + libraryDecToHex); - System.out.println("Result decToHex method : " + decToHex); - } -} diff --git a/Conversions/DecimalToOctal.java b/Conversions/DecimalToOctal.java deleted file mode 100644 index 1a4fa9f75b1c..000000000000 --- a/Conversions/DecimalToOctal.java +++ /dev/null @@ -1,29 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** This class converts Decimal numbers to Octal Numbers */ -public class DecimalToOctal { - /** - * Main Method - * - * @param args Command line Arguments - */ - - // enter in a decimal value to get Octal output - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - int n, k, d, s = 0, c = 0; - System.out.print("Decimal number: "); - n = sc.nextInt(); - k = n; - while (k != 0) { - d = k % 8; - s += d * (int) Math.pow(10, c++); - k /= 8; - } - - System.out.println("Octal equivalent:" + s); - sc.close(); - } -} diff --git a/Conversions/HexToOct.java b/Conversions/HexToOct.java deleted file mode 100644 index 636548fb0042..000000000000 --- a/Conversions/HexToOct.java +++ /dev/null @@ -1,73 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** - * Converts any Hexadecimal Number to Octal - * - * @author Tanmay Joshi - */ -public class HexToOct { - /** - * This method converts a Hexadecimal number to a decimal number - * - * @param s The Hexadecimal Number - * @return The Decimal number - */ - public static int hex2decimal(String s) { - String str = "0123456789ABCDEF"; - s = s.toUpperCase(); - int val = 0; - for (int i = 0; i < s.length(); i++) { - char a = s.charAt(i); - int n = str.indexOf(a); - val = 16 * val + n; - } - return val; - } - - /** - * This method converts a Decimal number to a octal number - * - * @param q The Decimal Number - * @return The Octal number - */ - public static int decimal2octal(int q) { - int now; - int i = 1; - int octnum = 0; - while (q > 0) { - now = q % 8; - octnum = (now * (int) (Math.pow(10, i))) + octnum; - q /= 8; - i++; - } - octnum /= 10; - return octnum; - } - - /** - * Main method that gets the hex input from user and converts it into octal. - * - * @param args arguments - */ - public static void main(String args[]) { - String hexadecnum; - int decnum, octalnum; - Scanner scan = new Scanner(System.in); - - System.out.print("Enter Hexadecimal Number : "); - hexadecnum = scan.nextLine(); - - // first convert hexadecimal to decimal - decnum = - hex2decimal( - hexadecnum); // Pass the string to the hex2decimal function and get the decimal form in - // variable decnum - - // convert decimal to octal - octalnum = decimal2octal(decnum); - System.out.println("Number in octal: " + octalnum); - scan.close(); - } -} diff --git a/Conversions/HexaDecimalToBinary.java b/Conversions/HexaDecimalToBinary.java deleted file mode 100644 index 06fbc7efd24a..000000000000 --- a/Conversions/HexaDecimalToBinary.java +++ /dev/null @@ -1,35 +0,0 @@ -package Conversions; - -// Hex [0-9],[A-F] -> Binary [0,1] - -public class HexaDecimalToBinary { - - private final int LONG_BITS = 8; - - public void convert(String numHex) { - // String a HexaDecimal: - int conHex = Integer.parseInt(numHex, 16); - // Hex a Binary: - String binary = Integer.toBinaryString(conHex); - // Output: - System.out.println(numHex + " = " + completeDigits(binary)); - } - - public String completeDigits(String binNum) { - for (int i = binNum.length(); i < LONG_BITS; i++) { - binNum = "0" + binNum; - } - return binNum; - } - - public static void main(String[] args) { - - // Testing Numbers: - String[] hexNums = {"1", "A1", "ef", "BA", "AA", "BB", "19", "01", "02", "03", "04"}; - HexaDecimalToBinary objConvert = new HexaDecimalToBinary(); - - for (String num : hexNums) { - objConvert.convert(num); - } - } -} diff --git a/Conversions/HexaDecimalToDecimal.java b/Conversions/HexaDecimalToDecimal.java deleted file mode 100644 index d85177b791bb..000000000000 --- a/Conversions/HexaDecimalToDecimal.java +++ /dev/null @@ -1,39 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -public class HexaDecimalToDecimal { - - // convert hexadecimal to decimal - public static int getHexaToDec(String hex) { - String digits = "0123456789ABCDEF"; - hex = hex.toUpperCase(); - int val = 0; - for (int i = 0; i < hex.length(); i++) { - int d = digits.indexOf(hex.charAt(i)); - val = 16 * val + d; - } - return val; - } - - // Main method gets the hexadecimal input from user and converts it into Decimal output. - - public static void main(String args[]) { - String hexa_Input; - int dec_output; - Scanner scan = new Scanner(System.in); - - System.out.print("Enter Hexadecimal Number : "); - hexa_Input = scan.nextLine(); - - // convert hexadecimal to decimal - - dec_output = getHexaToDec(hexa_Input); - /* - Pass the string to the getHexaToDec function - and it returns the decimal form in the variable dec_output. - */ - System.out.println("Number in Decimal: " + dec_output); - scan.close(); - } -} diff --git a/Conversions/IntegerToRoman.java b/Conversions/IntegerToRoman.java deleted file mode 100644 index fd8a0bb409a1..000000000000 --- a/Conversions/IntegerToRoman.java +++ /dev/null @@ -1,39 +0,0 @@ -package Conversions; - -/** - * Converting Integers into Roman Numerals - * - *

('I', 1); ('IV',4); ('V', 5); ('IX',9); ('X', 10); ('XL',40); ('L', 50); ('XC',90); ('C', 100); - * ('D', 500); ('M', 1000); - */ -public class IntegerToRoman { - private static int[] allArabianRomanNumbers = - new int[] {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; - private static String[] allRomanNumbers = - new String[] {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; - - // Value must be > 0 - - public static String integerToRoman(int num) { - if (num <= 0) { - return ""; - } - - StringBuilder builder = new StringBuilder(); - - for (int a = 0; a < allArabianRomanNumbers.length; a++) { - int times = num / allArabianRomanNumbers[a]; - for (int b = 0; b < times; b++) { - builder.append(allRomanNumbers[a]); - } - - num -= times * allArabianRomanNumbers[a]; - } - - return builder.toString(); - } - - public static void main(String[] args) { - System.out.println(IntegerToRoman.integerToRoman(2131)); - } -} diff --git a/Conversions/OctalToDecimal.java b/Conversions/OctalToDecimal.java deleted file mode 100644 index 1f3ad662a3bc..000000000000 --- a/Conversions/OctalToDecimal.java +++ /dev/null @@ -1,45 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** - * Converts any Octal Number to a Decimal Number - * - * @author Zachary Jones - */ -public class OctalToDecimal { - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - System.out.print("Octal Input: "); - String inputOctal = sc.nextLine(); - int result = convertOctalToDecimal(inputOctal); - if (result != -1) System.out.println("Result convertOctalToDecimal : " + result); - sc.close(); - } - - /** - * This method converts an octal number to a decimal number. - * - * @param inputOctal The octal number - * @return The decimal number - */ - public static int convertOctalToDecimal(String inputOctal) { - - try { - // Actual conversion of Octal to Decimal: - Integer outputDecimal = Integer.parseInt(inputOctal, 8); - return outputDecimal; - } catch (NumberFormatException ne) { - // Printing a warning message if the input is not a valid octal - // number: - System.out.println("Invalid Input, Expecting octal number 0-7"); - return -1; - } - } -} diff --git a/Conversions/OctalToHexadecimal.java b/Conversions/OctalToHexadecimal.java deleted file mode 100644 index 589fefbb5e9a..000000000000 --- a/Conversions/OctalToHexadecimal.java +++ /dev/null @@ -1,62 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** - * Converts any Octal Number to HexaDecimal - * - * @author Tanmay Joshi - */ -public class OctalToHexadecimal { - - /** - * This method converts a Octal number to a decimal number - * - * @param s The Octal Number - * @return The Decimal number - */ - public static int octToDec(String s) { - int i = 0; - for (int j = 0; j < s.length(); j++) { - char num = s.charAt(j); - num -= '0'; - i *= 8; - i += num; - } - return i; - } - - /** - * This method converts a Decimal number to a Hexadecimal number - * - * @param d The Decimal Number - * @return The Hexadecimal number - */ - public static String decimalToHex(int d) { - String digits = "0123456789ABCDEF"; - if (d <= 0) return "0"; - String hex = ""; - while (d > 0) { - int digit = d % 16; - hex = digits.charAt(digit) + hex; - d = d / 16; - } - return hex; - } - - public static void main(String args[]) { - - Scanner input = new Scanner(System.in); - System.out.print("Enter the Octal number: "); - // Take octal number as input from user in a string - String oct = input.next(); - - // Pass the octal number to function and get converted decimal form - int decimal = octToDec(oct); - - // Pass the decimal number to function and get converted Hex form of the number - String hex = decimalToHex(decimal); - System.out.println("The Hexadecimal equivalant is: " + hex); - input.close(); - } -} diff --git a/Conversions/RgbHsvConversion.java b/Conversions/RgbHsvConversion.java deleted file mode 100644 index 60fffe7a5f72..000000000000 --- a/Conversions/RgbHsvConversion.java +++ /dev/null @@ -1,165 +0,0 @@ -package Conversions; - -import java.util.Arrays; - -/** - * The RGB color model is an additive color model in which red, green, and blue light are added - * together in various ways to reproduce a broad array of colors. The name of the model comes from - * the initials of the three additive primary colors, red, green, and blue. Meanwhile, the HSV - * representation models how colors appear under light. In it, colors are represented using three - * components: hue, saturation and (brightness-)value. This class provides methods for converting - * colors from one representation to the other. (description adapted from - * https://en.wikipedia.org/wiki/RGB_color_model and https://en.wikipedia.org/wiki/HSL_and_HSV). - */ -public class RgbHsvConversion { - - public static void main(String[] args) { - // 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}); - - // 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}); - } - - /** - * Conversion from the HSV-representation to the RGB-representation. - * - * @param hue Hue of the color. - * @param saturation Saturation of the color. - * @param value Brightness-value of the color. - * @return The tuple of RGB-components. - */ - 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"); - } - - if (saturation < 0 || saturation > 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"); - } - - double chroma = value * saturation; - double hueSection = hue / 60; - double secondLargestComponent = chroma * (1 - Math.abs(hueSection % 2 - 1)); - double matchValue = value - chroma; - - return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent); - } - - /** - * Conversion from the RGB-representation to the HSV-representation. - * - * @param red Red-component of the color. - * @param green Green-component of the color. - * @param blue Blue-component of the color. - * @return The tuple of HSV-components. - */ - 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"); - } - - if (green < 0 || green > 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"); - } - - double dRed = (double) red / 255; - double dGreen = (double) green / 255; - double dBlue = (double) blue / 255; - double value = Math.max(Math.max(dRed, dGreen), dBlue); - double chroma = value - Math.min(Math.min(dRed, dGreen), dBlue); - double saturation = value == 0 ? 0 : chroma / value; - double hue; - - if (chroma == 0) { - hue = 0; - } else if (value == dRed) { - hue = 60 * (0 + (dGreen - dBlue) / chroma); - } else if (value == dGreen) { - hue = 60 * (2 + (dBlue - dRed) / chroma); - } else { - hue = 60 * (4 + (dRed - dGreen) / chroma); - } - - hue = (hue + 360) % 360; - - return new double[] {hue, saturation, value}; - } - - private static boolean approximatelyEqualHsv(double[] hsv1, double[] hsv2) { - boolean bHue = Math.abs(hsv1[0] - hsv2[0]) < 0.2; - boolean bSaturation = Math.abs(hsv1[1] - hsv2[1]) < 0.002; - boolean bValue = Math.abs(hsv1[2] - hsv2[2]) < 0.002; - - return bHue && bSaturation && bValue; - } - - private static int[] getRgbBySection( - double hueSection, double chroma, double matchValue, double secondLargestComponent) { - int red; - int green; - int blue; - - if (hueSection >= 0 && hueSection <= 1) { - red = convertToInt(chroma + matchValue); - green = convertToInt(secondLargestComponent + matchValue); - blue = convertToInt(matchValue); - } else if (hueSection > 1 && hueSection <= 2) { - red = convertToInt(secondLargestComponent + matchValue); - green = convertToInt(chroma + matchValue); - blue = convertToInt(matchValue); - } else if (hueSection > 2 && hueSection <= 3) { - red = convertToInt(matchValue); - green = convertToInt(chroma + matchValue); - blue = convertToInt(secondLargestComponent + matchValue); - } else if (hueSection > 3 && hueSection <= 4) { - red = convertToInt(matchValue); - green = convertToInt(secondLargestComponent + matchValue); - blue = convertToInt(chroma + matchValue); - } else if (hueSection > 4 && hueSection <= 5) { - red = convertToInt(secondLargestComponent + matchValue); - green = convertToInt(matchValue); - blue = convertToInt(chroma + matchValue); - } else { - red = convertToInt(chroma + matchValue); - green = convertToInt(matchValue); - blue = convertToInt(secondLargestComponent + matchValue); - } - - return new int[] {red, green, blue}; - } - - private static int convertToInt(double input) { - return (int) Math.round(255 * input); - } -} diff --git a/Conversions/RomanToInteger.java b/Conversions/RomanToInteger.java deleted file mode 100644 index 36a61e740a2a..000000000000 --- a/Conversions/RomanToInteger.java +++ /dev/null @@ -1,66 +0,0 @@ -package Conversions; - -import java.util.*; - -public class RomanToInteger { - - private static Map map = - new HashMap() { - /** */ - private static final long serialVersionUID = 87605733047260530L; - - { - put('I', 1); - put('V', 5); - put('X', 10); - put('L', 50); - put('C', 100); - put('D', 500); - put('M', 1000); - } - }; - // Roman Number = Roman Numerals - - /** - * This function convert Roman number into Integer - * - * @param A Roman number string - * @return integer - */ - public static int romanToInt(String A) { - - A = A.toUpperCase(); - char prev = ' '; - - int sum = 0; - - int newPrev = 0; - for (int i = A.length() - 1; i >= 0; i--) { - char c = A.charAt(i); - - if (prev != ' ') { - // checking current Number greater then previous or not - newPrev = map.get(prev) > newPrev ? map.get(prev) : newPrev; - } - - int currentNum = map.get(c); - - // if current number greater then prev max previous then add - if (currentNum >= newPrev) { - sum += currentNum; - } else { - // subtract upcoming number until upcoming number not greater then prev max - sum -= currentNum; - } - - prev = c; - } - - return sum; - } - - public static void main(String[] args) { - int sum = romanToInt("MDCCCIV"); - System.out.println(sum); - } -} diff --git a/Conversions/TurkishToLatinConversion.java b/Conversions/TurkishToLatinConversion.java deleted file mode 100644 index 346b7e77efde..000000000000 --- a/Conversions/TurkishToLatinConversion.java +++ /dev/null @@ -1,42 +0,0 @@ -package Conversions; - -import java.util.Scanner; - -/** - * Converts turkish character to latin character - * - * @author Özgün Gökşenli - */ -public class TurkishToLatinConversion { - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - System.out.println("Input the string: "); - String b = sc.next(); - System.out.println("Converted: " + convertTurkishToLatin(b)); - sc.close(); - } - - /** - * This method converts a turkish character to latin character. - * - * @param param String paramter - * @return String - */ - public static String convertTurkishToLatin(String param) { - char[] turkishChars = - new char[] {0x131, 0x130, 0xFC, 0xDC, 0xF6, 0xD6, 0x15F, 0x15E, 0xE7, 0xC7, 0x11F, 0x11E}; - char[] latinChars = new char[] {'i', 'I', 'u', 'U', 'o', 'O', 's', 'S', 'c', 'C', 'g', 'G'}; - for (int i = 0; i < turkishChars.length; i++) { - param = - param.replaceAll( - new String(new char[] {turkishChars[i]}), new String(new char[] {latinChars[i]})); - } - return param; - } -} diff --git a/DataStructures/Bags/Bag.java b/DataStructures/Bags/Bag.java deleted file mode 100644 index dc89a8a33027..000000000000 --- a/DataStructures/Bags/Bag.java +++ /dev/null @@ -1,110 +0,0 @@ -package DataStructures.Bags; - -import java.util.Iterator; -import java.util.NoSuchElementException; - -/** - * Collection which does not allow removing elements (only collect and iterate) - * - * @param - the generic type of an element in this bag - */ -public class Bag implements Iterable { - - private Node firstElement; // first element of the bag - private int size; // size of bag - - private static class Node { - private Element content; - private Node nextElement; - } - - /** Create an empty bag */ - public Bag() { - firstElement = null; - size = 0; - } - - /** @return true if this bag is empty, false otherwise */ - public boolean isEmpty() { - return firstElement == null; - } - - /** @return the number of elements */ - public int size() { - return size; - } - - /** @param element - the element to add */ - public void add(Element element) { - Node oldfirst = firstElement; - firstElement = new Node<>(); - firstElement.content = element; - firstElement.nextElement = oldfirst; - size++; - } - - /** - * Checks if the bag contains a specific element - * - * @param element which you want to look for - * @return true if bag contains element, otherwise false - */ - public boolean contains(Element element) { - Iterator iterator = this.iterator(); - while (iterator.hasNext()) { - if (iterator.next().equals(element)) { - return true; - } - } - return false; - } - - /** @return an iterator that iterates over the elements in this bag in arbitrary order */ - public Iterator iterator() { - return new ListIterator<>(firstElement); - } - - @SuppressWarnings("hiding") - private class ListIterator implements Iterator { - private Node currentElement; - - public ListIterator(Node firstElement) { - currentElement = firstElement; - } - - public boolean hasNext() { - return currentElement != null; - } - - /** remove is not allowed in a bag */ - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - public Element next() { - if (!hasNext()) throw new NoSuchElementException(); - Element element = currentElement.content; - currentElement = currentElement.nextElement; - return element; - } - } - - /** main-method for testing */ - public static void main(String[] args) { - Bag bag = new Bag<>(); - - bag.add("1"); - bag.add("1"); - bag.add("2"); - - System.out.println("size of bag = " + bag.size()); - for (String s : bag) { - System.out.println(s); - } - - System.out.println(bag.contains(null)); - System.out.println(bag.contains("1")); - System.out.println(bag.contains("3")); - } -} diff --git a/DataStructures/Buffers/CircularBuffer.java b/DataStructures/Buffers/CircularBuffer.java deleted file mode 100644 index 5c0304dbd366..000000000000 --- a/DataStructures/Buffers/CircularBuffer.java +++ /dev/null @@ -1,130 +0,0 @@ -package DataStructures.Buffers; - -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -public class CircularBuffer { - private char[] _buffer; - public final int _buffer_size; - private int _write_index = 0; - private int _read_index = 0; - private AtomicInteger _readable_data = new AtomicInteger(0); - - public CircularBuffer(int buffer_size) { - if (!IsPowerOfTwo(buffer_size)) { - throw new IllegalArgumentException(); - } - this._buffer_size = buffer_size; - _buffer = new char[buffer_size]; - } - - private boolean IsPowerOfTwo(int i) { - return (i & (i - 1)) == 0; - } - - private int getTrueIndex(int i) { - return i % _buffer_size; - } - - public Character readOutChar() { - Character result = null; - - // if we have data to read - if (_readable_data.get() > 0) { - - result = Character.valueOf(_buffer[getTrueIndex(_read_index)]); - _readable_data.decrementAndGet(); - _read_index++; - } - - return result; - } - - public boolean writeToCharBuffer(char c) { - boolean result = false; - - // if we can write to the buffer - if (_readable_data.get() < _buffer_size) { - // write to buffer - _buffer[getTrueIndex(_write_index)] = c; - _readable_data.incrementAndGet(); - _write_index++; - result = true; - } - - return result; - } - - private static class TestWriteWorker implements Runnable { - String _alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"; - Random _random = new Random(); - CircularBuffer _buffer; - - public TestWriteWorker(CircularBuffer cb) { - this._buffer = cb; - } - - private char getRandomChar() { - return _alphabet.charAt(_random.nextInt(_alphabet.length())); - } - - public void run() { - while (!Thread.interrupted()) { - if (!_buffer.writeToCharBuffer(getRandomChar())) { - Thread.yield(); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - return; - } - } - } - } - } - - private static class TestReadWorker implements Runnable { - CircularBuffer _buffer; - - public TestReadWorker(CircularBuffer cb) { - this._buffer = cb; - } - - @Override - public void run() { - System.out.println("Printing Buffer:"); - while (!Thread.interrupted()) { - Character c = _buffer.readOutChar(); - if (c != null) { - System.out.print(c.charValue()); - } else { - Thread.yield(); - try { - Thread.sleep(10); - } catch (InterruptedException e) { - System.out.println(); - return; - } - } - } - } - } - - public static void main(String[] args) throws InterruptedException { - int buffer_size = 1024; - // create circular buffer - CircularBuffer cb = new CircularBuffer(buffer_size); - - // create threads that read and write the buffer. - Thread write_thread = new Thread(new TestWriteWorker(cb)); - Thread read_thread = new Thread(new TestReadWorker(cb)); - read_thread.start(); - write_thread.start(); - - // wait some amount of time - Thread.sleep(10000); - - // interrupt threads and exit - write_thread.interrupt(); - read_thread.interrupt(); - } -} diff --git a/DataStructures/DynamicArray/DynamicArray.java b/DataStructures/DynamicArray/DynamicArray.java deleted file mode 100644 index 031d1c950c90..000000000000 --- a/DataStructures/DynamicArray/DynamicArray.java +++ /dev/null @@ -1,211 +0,0 @@ -package DataStructures.DynamicArray; - -import java.util.*; -import java.util.function.Consumer; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; - -/** - * This class implements a dynamic array - * - * @param the type that each index of the array will hold - */ -public class DynamicArray implements Iterable { - private static final int DEFAULT_CAPACITY = 16; - - private int capacity; - private int size; - private Object[] elements; - - /** - * constructor - * - * @param capacity the starting length of the desired array - */ - public DynamicArray(final int capacity) { - this.size = 0; - this.capacity = capacity; - this.elements = new Object[this.capacity]; - } - - /** No-args constructor */ - public DynamicArray() { - this(DEFAULT_CAPACITY); - } - - /** - * Adds an element to the array If full, creates a copy array twice the size of the current one - * - * @param element the element of type to be added to the array - */ - public void add(final E element) { - if (this.size == this.elements.length) { - this.elements = Arrays.copyOf(this.elements, newCapacity(2 * this.capacity)); - } - - this.elements[this.size] = element; - size++; - } - - /** - * Places element of type at the desired index - * - * @param index the index for the element to be placed - * @param element the element to be inserted - */ - public void put(final int index, E element) { - this.elements[index] = element; - } - - /** - * get method for element at a given index returns null if the index is empty - * - * @param index the desired index of the element - * @return the element at the specified index - */ - public E get(final int index) { - return getElement(index); - } - - /** - * Removes an element from the array - * - * @param index the index of the element to be removed - * @return the element removed - */ - public E remove(final int index) { - final E oldElement = getElement(index); - fastRemove(this.elements, index); - - if (this.capacity > DEFAULT_CAPACITY && size * 4 <= this.capacity) - this.elements = Arrays.copyOf(this.elements, newCapacity(this.capacity / 2)); - return oldElement; - } - - /** - * get method for size field - * - * @return int size - */ - public int getSize() { - return this.size; - } - - /** - * isEmpty helper method - * - * @return boolean true if the array contains no elements, false otherwise - */ - public boolean isEmpty() { - return this.size == 0; - } - - public Stream stream() { - return StreamSupport.stream(spliterator(), false); - } - - private void fastRemove(final Object[] elements, final int index) { - final int newSize = this.size - 1; - - if (newSize > index) { - System.arraycopy(elements, index + 1, elements, index, newSize - index); - } - - elements[this.size = newSize] = null; - } - - private E getElement(final int index) { - return (E) this.elements[index]; - } - - private int newCapacity(int capacity) { - this.capacity = capacity; - return this.capacity; - } - - /** - * returns a String representation of this object - * - * @return String a String representing the array - */ - @Override - public String toString() { - return Arrays.toString(Arrays.stream(this.elements).filter(Objects::nonNull).toArray()); - } - - /** - * Creates and returns a new Dynamic Array Iterator - * - * @return Iterator a Dynamic Array Iterator - */ - @Override - public Iterator iterator() { - return new DynamicArrayIterator(); - } - - private class DynamicArrayIterator implements Iterator { - - private int cursor; - - @Override - public boolean hasNext() { - return this.cursor != size; - } - - @Override - public E next() { - if (this.cursor > DynamicArray.this.size) throw new NoSuchElementException(); - - if (this.cursor > DynamicArray.this.elements.length) - throw new ConcurrentModificationException(); - - final E element = DynamicArray.this.getElement(this.cursor); - this.cursor++; - - return element; - } - - @Override - public void remove() { - if (this.cursor < 0) throw new IllegalStateException(); - - DynamicArray.this.remove(this.cursor); - this.cursor--; - } - - @Override - public void forEachRemaining(Consumer action) { - Objects.requireNonNull(action); - - for (int i = 0; i < DynamicArray.this.size; i++) { - action.accept(DynamicArray.this.getElement(i)); - } - } - } - - /** - * This class is the driver for the DynamicArray class it tests a variety of methods and prints - * the output - */ - public static void main(String[] args) { - DynamicArray names = new DynamicArray<>(); - names.add("Peubes"); - names.add("Marley"); - - for (String name : names) { - System.out.println(name); - } - - names.stream().forEach(System.out::println); - - System.out.println(names); - - System.out.println(names.getSize()); - - names.remove(0); - - for (String name : names) { - System.out.println(name); - } - } -} diff --git a/DataStructures/Graphs/A_Star.java b/DataStructures/Graphs/A_Star.java deleted file mode 100644 index 4116fce89a0c..000000000000 --- a/DataStructures/Graphs/A_Star.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - Time Complexity = O(E), where E is equal to the number of edges -*/ - -package DataStructures.Graphs; - -import java.util.*; - -public class A_Star { - - private static class Graph { - // Graph's structure can be changed only applying changes to this class. - private ArrayList> graph; - - // Initialise ArrayLists in Constructor - public Graph(int size) { - this.graph = new ArrayList<>(); - for (int i = 0; i < size; i++) { - this.graph.set(i, new ArrayList<>()); - } - } - - private ArrayList getNeighbours(int from) { - return this.graph.get(from); - } - - // Graph is bidirectional, for just one direction remove second instruction of this method. - private void addEdge(Edge edge) { - this.graph.get(edge.getFrom()).add(new Edge(edge.getFrom(), edge.getTo(), edge.getWeight())); - this.graph.get(edge.getTo()).add(new Edge(edge.getTo(), edge.getFrom(), edge.getWeight())); - } - } - - private static class Edge { - private int from; - private int to; - private int weight; - - public Edge(int from, int to, int weight) { - this.from = from; - this.to = to; - this.weight = weight; - } - - public int getFrom() { - return from; - } - - public int getTo() { - return to; - } - - public int getWeight() { - return weight; - } - } - - // class to iterate during the algorithm execution, and also used to return the solution. - private static class PathAndDistance { - private int distance; // distance advanced so far. - private ArrayList path; // list of visited nodes in this path. - private int - estimated; // heuristic value associated to the last node od the path (current node). - - public PathAndDistance(int distance, ArrayList path, int estimated) { - this.distance = distance; - this.path = path; - this.estimated = estimated; - } - - public int getDistance() { - return distance; - } - - public ArrayList getPath() { - return path; - } - - public int getEstimated() { - return estimated; - } - - private void printSolution() { - if (this.path != null) - System.out.println( - "Optimal path: " + this.path + ", distance: " + this.distance); - else System.out.println("There is no path available to connect the points"); - } - } - - private static void initializeGraph(Graph graph, ArrayList 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))); - } - /* - .x. node - (y) cost - - or | or / bidirectional connection - - ( 98)- .7. -(86)- .4. - | - ( 85)- .17. -(142)- .18. -(92)- .8. -(87)- .11. - | - . 1. -------------------- (160) - | \ | - (211) \ .6. - | \ | - . 5. (101)-.13. -(138) (115) - | | | / - ( 99) ( 97) | / - | | | / - .12. -(151)- .15. -(80)- .14. | / - | | | | / - ( 71) (140) (146)- .2. -(120) - | | | - .19. -( 75)- . 0. .10. -(75)- .3. - | | - (118) ( 70) - | | - .16. -(111)- .9. - */ - } - - public static void main(String[] args) { - // heuristic function optimistic values - int[] heuristic = { - 366, 0, 160, 242, 161, 178, 77, 151, 226, 244, 241, 234, 380, 98, 193, 253, 329, 80, 199, 374 - }; - - Graph graph = new Graph(20); - ArrayList 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) { - // 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 queue = - new PriorityQueue<>(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)); - - boolean solutionFound = false; - 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. - if (currentPosition == to) solutionFound = true; - else - for (Edge edge : graph.getNeighbours(currentPosition)) - if (!currentData.getPath().contains(edge.getTo())) { // Avoid Cycles - ArrayList 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()])); - } - } - 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 - } -} diff --git a/DataStructures/Graphs/BellmanFord.java b/DataStructures/Graphs/BellmanFord.java deleted file mode 100644 index 273f5f772957..000000000000 --- a/DataStructures/Graphs/BellmanFord.java +++ /dev/null @@ -1,161 +0,0 @@ -package 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*/ -{ - int vertex, edge; - private Edge edges[]; - private int index = 0; - - BellmanFord(int v, int e) { - vertex = v; - edge = e; - edges = new Edge[e]; - } - - class Edge { - int u, v; - int w; - /** - * @param u Source Vertex - * @param v End vertex - * @param c Weight - */ - public Edge(int a, int b, int c) { - u = a; - v = b; - w = c; - } - } - /** - * @param p[] Parent array which shows updates in edges - * @param i Current vertex under consideration - */ - void printPath(int p[], int i) { - if (p[i] == -1) // Found the path back to parent - return; - printPath(p, p[i]); - System.out.print(i + " "); - } - - public static void main(String args[]) { - BellmanFord obj = new BellmanFord(0, 0); // Dummy object to call nonstatic variables - obj.go(); - } - - public void - go() // Interactive run for understanding the class first time. Assumes source vertex is 0 and - // shows distance to all vertices - { - 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"); - v = sc.nextInt(); - e = sc.nextInt(); - Edge arr[] = new Edge[e]; // Array of edges - System.out.println("Input edges"); - for (i = 0; i < e; i++) { - u = sc.nextInt(); - ve = sc.nextInt(); - 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 - // and all vertices - int p[] = new int[v]; // Parent array for holding the paths - for (i = 0; i < v; i++) dist[i] = Integer.MAX_VALUE; // Initializing distance values - dist[0] = 0; - p[0] = -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) { - dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update - p[arr[j].v] = arr[j].u; - } - } - } - // 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) { - neg = 1; - System.out.println("Negative cycle"); - break; - } - if (neg == 0) // Go ahead and show results of computation - { - System.out.println("Distances are: "); - for (i = 0; i < v; i++) System.out.println(i + " " + dist[i]); - System.out.println("Path followed:"); - for (i = 0; i < v; i++) { - System.out.print("0 "); - printPath(p, i); - System.out.println(); - } - } - sc.close(); - } - /** - * @param source Starting vertex - * @param end Ending vertex - * @param Edge Array of edges - */ - public void show( - int source, - int end, - Edge arr[]) // Just shows results of computation, if graph is passed to it. The graph should - // be created by using addEdge() method and passed by calling getEdgeArray() method - { - 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 - // and all vertices - int p[] = new int[v]; // Parent array for holding the paths - for (i = 0; i < v; i++) dist[i] = Integer.MAX_VALUE; // Initializing distance values - dist[source] = 0; - 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) { - dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update - p[arr[j].v] = arr[j].u; - } - } - } - // 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) { - neg = 1; - System.out.println("Negative cycle"); - break; - } - if (neg == 0) // Go ahead and show results of computaion - { - System.out.println("Distance is: " + dist[end]); - System.out.println("Path followed:"); - System.out.print(source + " "); - printPath(p, end); - System.out.println(); - } - } - /** - * @param x Source Vertex - * @param y End vertex - * @param z Weight - */ - public void addEdge(int x, int y, int z) // Adds unidirectional edge - { - edges[index++] = new Edge(x, y, z); - } - - public Edge[] getEdgeArray() { - return edges; - } -} diff --git a/DataStructures/Graphs/ConnectedComponent.java b/DataStructures/Graphs/ConnectedComponent.java deleted file mode 100644 index 7f9403cadaec..000000000000 --- a/DataStructures/Graphs/ConnectedComponent.java +++ /dev/null @@ -1,139 +0,0 @@ -package DataStructures.Graphs; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -/** - * A class that counts the number of different connected components in a graph - * - * @author Lukas Keul, Florian Mercks - */ -class Graph> { - - class Node { - E name; - - public Node(E name) { - this.name = name; - } - } - - class Edge { - Node startNode, endNode; - - public Edge(Node startNode, Node endNode) { - this.startNode = startNode; - this.endNode = endNode; - } - } - - ArrayList edgeList; - ArrayList nodeList; - - public Graph() { - edgeList = new ArrayList(); - nodeList = new ArrayList(); - } - - /** - * Adds a new Edge to the graph. If the nodes aren't yet in nodeList, they will be added to it. - * - * @param startNode the starting Node from the edge - * @param endNode the ending Node from the edge - */ - public void addEdge(E startNode, E endNode) { - Node start = null, end = null; - for (Node node : nodeList) { - if (startNode.compareTo(node.name) == 0) { - start = node; - } else if (endNode.compareTo(node.name) == 0) { - end = node; - } - } - if (start == null) { - start = new Node(startNode); - nodeList.add(start); - } - if (end == null) { - end = new Node(endNode); - nodeList.add(end); - } - - edgeList.add(new Edge(start, end)); - } - - /** - * Main method used for counting the connected components. Iterates through the array of nodes to - * do a depth first search to get all nodes of the graph from the actual node. These nodes are - * added to the array markedNodes and will be ignored if they are chosen in the nodeList. - * - * @return returns the amount of unconnected graphs - */ - public int countGraphs() { - int count = 0; - Set markedNodes = new HashSet(); - - for (Node n : nodeList) { - if (!markedNodes.contains(n)) { - markedNodes.add(n); - markedNodes.addAll(depthFirstSearch(n, new ArrayList())); - count++; - } - } - - return count; - } - - /** - * Implementation of depth first search. - * - * @param n the actual visiting node - * @param visited A list of already visited nodes in the depth first search - * @return returns a set of visited nodes - */ - public ArrayList depthFirstSearch(Node n, ArrayList visited) { - visited.add(n); - for (Edge e : edgeList) { - if (e.startNode.equals(n) && !visited.contains(e.endNode)) { - depthFirstSearch(e.endNode, visited); - } - } - return visited; - } -} - -public class ConnectedComponent { - - public static void main(String[] args) { - Graph graphChars = new Graph<>(); - - // Graph 1 - graphChars.addEdge('a', 'b'); - graphChars.addEdge('a', 'e'); - graphChars.addEdge('b', 'e'); - graphChars.addEdge('b', 'c'); - graphChars.addEdge('c', 'd'); - graphChars.addEdge('d', 'a'); - - graphChars.addEdge('x', 'y'); - graphChars.addEdge('x', 'z'); - - graphChars.addEdge('w', 'w'); - - Graph graphInts = new Graph<>(); - - // Graph 2 - graphInts.addEdge(1, 2); - graphInts.addEdge(2, 3); - graphInts.addEdge(2, 4); - graphInts.addEdge(3, 5); - - graphInts.addEdge(7, 8); - 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()); - } -} diff --git a/DataStructures/Graphs/Cycles.java b/DataStructures/Graphs/Cycles.java deleted file mode 100644 index 27b0c2bf3c42..000000000000 --- a/DataStructures/Graphs/Cycles.java +++ /dev/null @@ -1,87 +0,0 @@ -package DataStructures.Graphs; - -import java.util.ArrayList; -import java.util.Scanner; - -class Cycle { - - private int nodes, edges; - private int[][] adjacencyMatrix; - private boolean[] visited; - ArrayList> cycles = new ArrayList>(); - - public Cycle() { - Scanner in = new Scanner(System.in); - System.out.print("Enter the no. of nodes: "); - nodes = in.nextInt(); - System.out.print("Enter the no. of Edges: "); - edges = in.nextInt(); - - adjacencyMatrix = new int[nodes][nodes]; - visited = new boolean[nodes]; - - for (int i = 0; i < nodes; i++) { - visited[i] = false; - } - - System.out.println("Enter the details of each edges "); - - for (int i = 0; i < edges; i++) { - int start, end; - start = in.nextInt(); - end = in.nextInt(); - adjacencyMatrix[start][end] = 1; - } - in.close(); - } - - public void start() { - for (int i = 0; i < nodes; i++) { - ArrayList temp = new ArrayList<>(); - dfs(i, i, temp); - for (int j = 0; j < nodes; j++) { - adjacencyMatrix[i][j] = 0; - adjacencyMatrix[j][i] = 0; - } - } - } - - private void dfs(Integer start, Integer curr, ArrayList temp) { - temp.add(curr); - visited[curr] = true; - for (int i = 0; i < nodes; i++) { - if (adjacencyMatrix[curr][i] == 1) { - if (i == start) { - cycles.add(new ArrayList(temp)); - } else { - if (!visited[i]) { - dfs(start, i, temp); - } - } - } - } - - if (temp.size() > 0) { - temp.remove(temp.size() - 1); - } - visited[curr] = false; - } - - public void printAll() { - for (int i = 0; i < cycles.size(); i++) { - for (int j = 0; j < cycles.get(i).size(); j++) { - System.out.print(cycles.get(i).get(j) + " -> "); - } - System.out.println(cycles.get(i).get(0)); - System.out.println(); - } - } -} - -public class Cycles { - public static void main(String[] args) { - Cycle c = new Cycle(); - c.start(); - c.printAll(); - } -} diff --git a/DataStructures/Graphs/FloydWarshall.java b/DataStructures/Graphs/FloydWarshall.java deleted file mode 100644 index 8833e8005aaa..000000000000 --- a/DataStructures/Graphs/FloydWarshall.java +++ /dev/null @@ -1,76 +0,0 @@ -package DataStructures.Graphs; - -import java.util.Scanner; - -public class FloydWarshall { - private int DistanceMatrix[][]; - private int numberofvertices; // number of vertices in the graph - 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 - // 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 - { - for (int source = 1; source <= numberofvertices; source++) { - for (int destination = 1; destination <= numberofvertices; destination++) { - DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination]; - } - } - 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]) - // if the new distance calculated is less then the earlier shortest - // calculated distance it get replaced as new shortest distance - { - DistanceMatrix[source][destination] = - DistanceMatrix[source][intermediate] + DistanceMatrix[intermediate][destination]; - } - } - } - } - for (int source = 1; source <= numberofvertices; source++) System.out.print("\t" + source); - System.out.println(); - for (int source = 1; source <= numberofvertices; source++) { - System.out.print(source + "\t"); - for (int destination = 1; destination <= numberofvertices; destination++) { - System.out.print(DistanceMatrix[source][destination] + "\t"); - } - System.out.println(); - } - } - - public static void main(String... arg) { - 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]; - System.out.println("Enter the Weighted Matrix for the graph"); - for (int source = 1; source <= numberOfVertices; source++) { - for (int destination = 1; destination <= numberOfVertices; destination++) { - adjacencyMatrix[source][destination] = scan.nextInt(); - if (source == destination) { - adjacencyMatrix[source][destination] = 0; - continue; - } - if (adjacencyMatrix[source][destination] == 0) { - adjacencyMatrix[source][destination] = INFINITY; - } - } - } - System.out.println("The Transitive Closure of the Graph"); - FloydWarshall floydwarshall = new FloydWarshall(numberOfVertices); - floydwarshall.floydwarshall(adjacencyMatrix); - scan.close(); - } -} diff --git a/DataStructures/Graphs/Graphs.java b/DataStructures/Graphs/Graphs.java deleted file mode 100644 index 9a1f713836b2..000000000000 --- a/DataStructures/Graphs/Graphs.java +++ /dev/null @@ -1,129 +0,0 @@ -package DataStructures.Graphs; - -import java.util.ArrayList; - -class AdjacencyListGraph> { - - ArrayList verticies; - - public AdjacencyListGraph() { - verticies = new ArrayList<>(); - } - - private class Vertex { - E data; - ArrayList adjacentVerticies; - - public Vertex(E data) { - adjacentVerticies = new ArrayList<>(); - this.data = data; - } - - public boolean addAdjacentVertex(Vertex to) { - for (Vertex v : adjacentVerticies) { - if (v.data.compareTo(to.data) == 0) { - return false; // the edge already exists - } - } - return adjacentVerticies.add(to); // this will return true; - } - - public boolean removeAdjacentVertex(E to) { - // use indexes here so it is possible to - // remove easily without implementing - // equals method that ArrayList.remove(Object o) uses - for (int i = 0; i < adjacentVerticies.size(); i++) { - if (adjacentVerticies.get(i).data.compareTo(to) == 0) { - adjacentVerticies.remove(i); - return true; - } - } - return false; - } - } - - /** - * this method removes an edge from the graph between two specified verticies - * - * @param from the data of the vertex the edge is from - * @param to the data of the vertex the edge is going to - * @return returns false if the edge doesn't exist, returns true if the edge exists and is removed - */ - public boolean removeEdge(E from, E to) { - Vertex fromV = null; - for (Vertex v : verticies) { - if (from.compareTo(v.data) == 0) { - fromV = v; - break; - } - } - if (fromV == null) return false; - return fromV.removeAdjacentVertex(to); - } - - /** - * this method adds an edge to the graph between two specified verticies - * - * @param from the data of the vertex the edge is from - * @param to the data of the vertex the edge is going to - * @return returns true if the edge did not exist, return false if it already did - */ - public boolean addEdge(E from, E to) { - Vertex fromV = null, toV = null; - for (Vertex v : verticies) { - if (from.compareTo(v.data) == 0) { // see if from vertex already exists - fromV = v; - } else if (to.compareTo(v.data) == 0) { // see if to vertex already exists - toV = v; - } - if (fromV != null && toV != null) break; // both nodes exist so stop searching - } - if (fromV == null) { - fromV = new Vertex(from); - verticies.add(fromV); - } - if (toV == null) { - toV = new Vertex(to); - verticies.add(toV); - } - return fromV.addAdjacentVertex(toV); - } - - /** - * this gives a list of verticies in the graph and their adjacencies - * - * @return returns a string describing this graph - */ - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (Vertex v : verticies) { - sb.append("Vertex: "); - sb.append(v.data); - sb.append("\n"); - sb.append("Adjacent verticies: "); - for (Vertex v2 : v.adjacentVerticies) { - sb.append(v2.data); - sb.append(" "); - } - sb.append("\n"); - } - return sb.toString(); - } -} - -public class Graphs { - - public static void main(String args[]) { - AdjacencyListGraph graph = new AdjacencyListGraph<>(); - assert graph.addEdge(1, 2); - assert graph.addEdge(1, 5); - assert graph.addEdge(2, 5); - assert !graph.addEdge(1, 2); - assert graph.addEdge(2, 3); - assert graph.addEdge(3, 4); - assert graph.addEdge(4, 1); - assert !graph.addEdge(2, 3); - System.out.println(graph); - } -} diff --git a/DataStructures/Graphs/KahnsAlgorithm.java b/DataStructures/Graphs/KahnsAlgorithm.java deleted file mode 100644 index eac840340a58..000000000000 --- a/DataStructures/Graphs/KahnsAlgorithm.java +++ /dev/null @@ -1,155 +0,0 @@ -package DataStructures.Graphs; - -import java.util.ArrayList; -import java.util.Map; -import java.util.LinkedHashMap; -import java.util.HashMap; -import java.util.Set; -import java.util.Queue; -import java.util.LinkedList; - -/** - * An algorithm that sorts a graph in toplogical order. - */ - -/** - * A class that represents the adjaceny list of a graph - */ -class AdjacencyList>{ - - Map> adj; - - AdjacencyList(){ - adj = new LinkedHashMap>(); - } - - /** - * This function adds an Edge to the adjaceny list - * @param from , the vertex the edge is from - * @param to, the vertex the edge is going to - */ - void addEdge(E from, E to){ - try{ - adj.get(from).add(to); - } - catch(Exception E){ - adj.put(from,new ArrayList()); - adj.get(from).add(to); - } - if(!adj.containsKey(to)){ - adj.put(to, new ArrayList()); - } - } - - /** - * @param v, A vertex in a graph - * @return returns an ArrayList of all the adjacents of vertex v - */ - ArrayList getAdjacents(E v){ - return adj.get(v); - } - - /** - * @return returns a set of all vertices in the graph - */ - Set getVertices(){ - return adj.keySet(); - } - - /** - * Prints the adjacency list - */ - void printGraph(){ - for(E vertex: adj.keySet()){ - System.out.print(vertex+" : "); - for(E adjacent: adj.get(vertex)){ - System.out.print(adjacent+" "); - } - System.out.println(); - } - } -} - -class TopologicalSort>{ - AdjacencyList graph; - Map inDegree; - - TopologicalSort(AdjacencyList graph){ - this.graph = graph; - } - - - /** - * Calculates the in degree of all vertices - */ - void calculateInDegree(){ - inDegree = new HashMap<>(); - for(E vertex: graph.getVertices()){ - if(!inDegree.containsKey(vertex)){ - inDegree.put(vertex,0); - } - for(E adjacent: graph.getAdjacents(vertex)){ - try{ - inDegree.put(adjacent,inDegree.get(adjacent) + 1); - } - catch(Exception e){ - inDegree.put(adjacent,1); - } - } - } - } - - /** - * Returns an ArrayList with vertices arranged in topological order - */ - ArrayList topSortOrder(){ - calculateInDegree(); - Queue q = new LinkedList(); - - for(E vertex: inDegree.keySet()){ - if(inDegree.get(vertex) == 0){ - q.add(vertex); - } - } - - ArrayList answer = new ArrayList<>(); - - while(!q.isEmpty()){ - E current = q.poll(); - answer.add(current); - for(E adjacent: graph.getAdjacents(current)){ - inDegree.put(adjacent,inDegree.get(adjacent)-1); - if(inDegree.get(adjacent) == 0){ - q.add(adjacent); - } - } - } - - return answer; - - } -} - -/** - * A driver class that sorts a given graph in topological order. - */ -public class KahnsAlgorithm{ - public static void main(String[] args){ - - //Graph definition and initialization - AdjacencyList graph = new AdjacencyList<>(); - graph.addEdge("a","b"); - graph.addEdge("c","a"); - graph.addEdge("a","d"); - graph.addEdge("b","d"); - graph.addEdge("c","u"); - graph.addEdge("u","b"); - - TopologicalSort topSort = new TopologicalSort<>(graph); - - //Printing the order - for(String s: topSort.topSortOrder()){ - System.out.print(s+" "); - } - } -} \ No newline at end of file diff --git a/DataStructures/Graphs/Kruskal.java b/DataStructures/Graphs/Kruskal.java deleted file mode 100644 index 3c8f6e44c01e..000000000000 --- a/DataStructures/Graphs/Kruskal.java +++ /dev/null @@ -1,105 +0,0 @@ -package DataStructures.Graphs; - -// Problem -> Connect all the edges with the minimum cost. -// Possible Solution -> Kruskal Algorithm (KA), KA finds the minimum-spanning-tree, which means, the -// group of edges with the minimum sum of their weights that connect the whole graph. -// The graph needs to be connected, because if there are nodes impossible to reach, there are no -// edges that could connect every node in the graph. -// KA is a Greedy Algorithm, because edges are analysed based on their weights, that is why a -// Priority Queue is used, to take first those less weighted. -// This implementations below has some changes compared to conventional ones, but they are explained -// all along the code. - -import java.util.Comparator; -import java.util.HashSet; -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 - - private static class Edge { - private int from; - private int to; - private int weight; - - public Edge(int from, int to, int weight) { - this.from = from; - this.to = to; - this.weight = weight; - } - } - - private static void addEdge(HashSet[] graph, int from, int to, int weight) { - graph[from].add(new Edge(from, to, weight)); - } - - public static void main(String[] args) { - HashSet[] graph = new HashSet[7]; - for (int i = 0; i < graph.length; i++) { - graph[i] = new HashSet<>(); - } - addEdge(graph, 0, 1, 2); - addEdge(graph, 0, 2, 3); - addEdge(graph, 0, 3, 3); - addEdge(graph, 1, 2, 4); - addEdge(graph, 2, 3, 5); - addEdge(graph, 1, 4, 3); - addEdge(graph, 2, 4, 1); - addEdge(graph, 3, 5, 7); - addEdge(graph, 4, 5, 8); - addEdge(graph, 5, 6, 9); - - 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); - } - } - - Kruskal k = new Kruskal(); - HashSet[] solGraph = k.kruskal(graph); - - 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); - } - } - } - - public HashSet[] kruskal(HashSet[] graph) { - int nodes = graph.length; - int[] captain = new int[nodes]; - // captain of i, stores the set with all the connected nodes to i - HashSet[] connectedGroups = new HashSet[nodes]; - HashSet[] minGraph = new HashSet[nodes]; - PriorityQueue edges = new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight))); - for (int i = 0; i < nodes; i++) { - minGraph[i] = new HashSet<>(); - connectedGroups[i] = new HashSet<>(); - connectedGroups[i].add(i); - captain[i] = i; - edges.addAll(graph[i]); - } - int connectedElements = 0; - // as soon as two sets merge all the elements, the algorithm must stop - 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)) { - // merge sets of the captains of each point connected by the edge - 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]); - // add Edge to minimal graph - addEdge(minGraph, edge.from, edge.to, edge.weight); - // count how many elements have been merged - connectedElements = connectedGroups[captain[edge.from]].size(); - } - } - return minGraph; - } -} diff --git a/DataStructures/Graphs/MatrixGraphs.java b/DataStructures/Graphs/MatrixGraphs.java deleted file mode 100644 index 3b27477d0021..000000000000 --- a/DataStructures/Graphs/MatrixGraphs.java +++ /dev/null @@ -1,336 +0,0 @@ -package DataStructures.Graphs; - -import java.util.List; -import java.util.Queue; -import java.util.ArrayList; -import java.util.LinkedList; - -/** - * Implementation of a graph in a matrix form - * Also known as an adjacency matrix representation - * [Adjacency matrix - Wikipedia](https://en.wikipedia.org/wiki/Adjacency_matrix) - * - * @author Unknown - */ -public class MatrixGraphs { - - public static void main(String args[]) { - AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10); - graph.addEdge(1, 2); - graph.addEdge(1, 5); - graph.addEdge(2, 5); - graph.addEdge(1, 2); - graph.addEdge(2, 3); - graph.addEdge(3, 4); - graph.addEdge(4, 1); - graph.addEdge(2, 3); - graph.addEdge(3, 9); - graph.addEdge(9, 1); - graph.addEdge(9, 8); - graph.addEdge(1, 8); - graph.addEdge(5, 6); - System.out.println("The graph matrix:"); - System.out.println(graph); - System.out.println("Depth first order beginning at node '1':"); - System.out.println(graph.depthFirstOrder(1)); - System.out.println("Breadth first order beginning at node '1':"); - System.out.println(graph.breadthFirstOrder(1)); - } -} - -/** - * AdjacencyMatrixGraph Implementation - */ -class AdjacencyMatrixGraph { - /** - * The number of vertices in the graph - */ - private int _numberOfVertices; - - /** - * The number of edges in the graph - */ - private int _numberOfEdges; - - /** - * The adjacency matrix for the graph - */ - private int[][] _adjacency; - - /** - * Static variables to define whether or not an edge exists in the - * adjacency matrix - */ - static final int EDGE_EXIST = 1; - static final int EDGE_NONE = 0; - - /** - * Constructor - */ - public AdjacencyMatrixGraph(int givenNumberOfVertices) { - this.setNumberOfVertices(givenNumberOfVertices); - this.setNumberOfEdges(0); - 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; - } - } - } - - /** - * Updates the number of vertices in the graph - * - * @param newNumberOfVertices the new number of vertices - */ - private void setNumberOfVertices(int newNumberOfVertices) { - this._numberOfVertices = newNumberOfVertices; - } - - /** - * Getter for `this._numberOfVertices` - * - * @return the number of vertices in the graph - */ - public int numberOfVertices() { - return this._numberOfVertices; - } - - /** - * Updates the number of edges in the graph - * - * @param newNumberOfEdges - * */ - private void setNumberOfEdges(int newNumberOfEdges) { - this._numberOfEdges = newNumberOfEdges; - } - - /** - * Getter for `this._numberOfEdges` - * - * @return the number of edges - */ - public int numberOfEdges() { - return this._numberOfEdges; - } - - /** - * Sets a new matrix as the adjacency matrix - * - * @param newAdjacency the new adjaceny matrix - */ - private void setAdjacency(int[][] newAdjacency) { - this._adjacency = newAdjacency; - } - - /** - * Getter for the adjacency matrix - * - * @return the adjacency matrix - */ - private int[][] adjacency() { - return this._adjacency; - } - - /** - * Checks if two vertices are connected by an edge - * - * @param from the parent vertex to check for adjacency - * @param to the child vertex to check for adjacency - * @return whether or not the vertices are adjancent - */ - private boolean adjacencyOfEdgeDoesExist(int from, int to) { - return (this.adjacency()[from][to] != AdjacencyMatrixGraph.EDGE_NONE); - } - - /** - * Checks if a particular vertex exists in a graph - * - * @param aVertex the vertex to check for existence - * @return whether or not the vertex exists - */ - public boolean vertexDoesExist(int aVertex) { - if (aVertex >= 0 && aVertex < this.numberOfVertices()) { - return true; - } else { - return false; - } - } - - /** - * Checks if two vertices are connected by an edge - * - * @param from the parent vertex to check for adjacency - * @param to the child vertex to check for adjacency - * @return whether or not the vertices are adjancent - */ - public boolean edgeDoesExist(int from, int to) { - if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) { - return (this.adjacencyOfEdgeDoesExist(from, to)); - } - - return false; - } - - /** - * This method adds an edge to the graph between two specified vertices - * - * @param from the data of the vertex the edge is from - * @param to the data of the vertex the edge is going to - * @return returns true if the edge did not exist, return false if it already did - */ - public boolean addEdge(int from, int to) { - if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) { - if (!this.adjacencyOfEdgeDoesExist(from, to)) { - this.adjacency()[from][to] = AdjacencyMatrixGraph.EDGE_EXIST; - this.adjacency()[to][from] = AdjacencyMatrixGraph.EDGE_EXIST; - this.setNumberOfEdges(this.numberOfEdges() + 1); - return true; - } - } - - return false; - } - - /** - * this method removes an edge from the graph between two specified vertices - * - * @param from the data of the vertex the edge is from - * @param to the data of the vertex the edge is going to - * @return returns false if the edge doesn't exist, returns true if the edge exists and is removed - */ - public boolean removeEdge(int from, int to) { - if (!this.vertexDoesExist(from) || !this.vertexDoesExist(to)) { - if (this.adjacencyOfEdgeDoesExist(from, to)) { - this.adjacency()[from][to] = AdjacencyMatrixGraph.EDGE_NONE; - this.adjacency()[to][from] = AdjacencyMatrixGraph.EDGE_NONE; - this.setNumberOfEdges(this.numberOfEdges() - 1); - return true; - } - } - return false; - } - - /** - * This method returns a list of the vertices in a depth first order - * beginning with the specified vertex - * - * @param startVertex the vertex to begin the traversal - * @return the list of the ordered vertices - */ - public List depthFirstOrder(int startVertex) { - // If the startVertex is invalid, return an empty list - if (startVertex >= _numberOfVertices || startVertex < 0) - return new ArrayList(); - - // Create an array to track the visited vertices - boolean[] visited = new boolean[_numberOfVertices]; - - // Create a list to keep track of the order of our traversal - ArrayList orderList = new ArrayList(); - - // Perform our DFS algorithm - depthFirstOrder(startVertex, visited, orderList); - - return orderList; - } - - /** - * Helper method for public depthFirstOrder(int) that will perform - * a depth first traversal recursively on the graph - * - * @param currentVertex the currently exploring vertex - * @param visited the array of values denoting whether or not that vertex has been visited - * @param orderList the list to add vertices to as they are visited - */ - private void depthFirstOrder(int currentVertex, boolean[] visited, List orderList) { - // If this vertex has already been visited, do nothing and return - if (visited[currentVertex]) - return; - - // Visit the currentVertex by marking it as visited and adding it - // to the orderList - visited[currentVertex] = true; - orderList.add(currentVertex); - - // Get the adjacency array for this vertex - int[] adjacent = _adjacency[currentVertex]; - for (int i = 0; i < adjacent.length; i++) - // If an edge exists between the currentVertex and the vertex - // we are considering exploring, recurse on it - if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) - depthFirstOrder(i, visited, orderList); - } - - /** - * This method returns a list of the vertices in a breadth first order - * beginning with the specified vertex - * - * @param startVertex the vertext to begin the traversal - * @return the list of the ordered vertices - */ - public List breadthFirstOrder(int startVertex) { - // If the specified startVertex is invalid, return an empty list - if (startVertex >= _numberOfVertices || startVertex < 0) - return new ArrayList(); - - // Create an array to keep track of the visited vertices - boolean[] visited = new boolean[_numberOfVertices]; - - // Create a list to keep track of the ordered vertices - ArrayList orderList = new ArrayList(); - - // Create a queue for our BFS algorithm and add the startVertex - // to the queue - Queue queue = new LinkedList(); - queue.add(startVertex); - - // Continue until the queue is empty - while (! queue.isEmpty()) { - // Remove the first vertex in the queue - int currentVertex = queue.poll(); - - // If we've visited this vertex, skip it - if (visited[currentVertex]) - continue; - - // We now visit this vertex by adding it to the orderList and - // marking it as visited - orderList.add(currentVertex); - visited[currentVertex] = true; - - // Get the adjacency array for the currentVertex and - // check each node - int[] adjacent = _adjacency[currentVertex]; - for (int vertex = 0; vertex < adjacent.length; vertex++) - // If an edge exists between the current vertex and the - // vertex we are considering exploring, we add it to the queue - if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) - queue.add(vertex); - } - - return orderList; - } - - /** - * this gives a list of vertices in the graph and their adjacencies - * - * @return returns a string describing this graph - */ - public String toString() { - String s = " "; - for (int i = 0; i < this.numberOfVertices(); i++) { - s = s + String.valueOf(i) + " "; - } - s = s + " \n"; - - for (int i = 0; i < this.numberOfVertices(); i++) { - s = s + String.valueOf(i) + " : "; - for (int j = 0; j < this.numberOfVertices(); j++) { - s = s + String.valueOf(this._adjacency[i][j]) + " "; - } - s = s + "\n"; - } - return s; - } -} diff --git a/DataStructures/Graphs/PrimMST.java b/DataStructures/Graphs/PrimMST.java deleted file mode 100644 index 9c3b973ffd63..000000000000 --- a/DataStructures/Graphs/PrimMST.java +++ /dev/null @@ -1,102 +0,0 @@ -package DataStructures.Graphs; - -/** - * A Java program for Prim's Minimum Spanning Tree (MST) algorithm. adjacency matrix representation - * of the graph - */ -class PrimMST { - // Number of vertices in the graph - private static final int V = 5; - - // A utility function to find the vertex with minimum key - // value, from the set of vertices not yet included in MST - int minKey(int key[], Boolean mstSet[]) { - // Initialize min value - int min = Integer.MAX_VALUE, min_index = -1; - - for (int v = 0; v < V; v++) - if (mstSet[v] == false && key[v] < min) { - min = key[v]; - min_index = v; - } - - return min_index; - } - - // A utility function to print the constructed MST stored in - // parent[] - 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]]); - } - - // Function to construct and print MST for a graph represented - // using adjacency matrix representation - void primMST(int graph[][]) { - // Array to store constructed MST - int parent[] = new int[V]; - - // Key values used to pick minimum weight edge in cut - int key[] = new int[V]; - - // To represent set of vertices not yet included in MST - Boolean mstSet[] = new Boolean[V]; - - // Initialize all keys as INFINITE - for (int i = 0; i < V; i++) { - key[i] = Integer.MAX_VALUE; - mstSet[i] = false; - } - - // Always include first 1st vertex in MST. - key[0] = 0; // Make key 0 so that this vertex is - // picked as first vertex - parent[0] = -1; // First node is always root of MST - - // The MST will have V vertices - for (int count = 0; count < V - 1; count++) { - // Pick thd minimum key vertex from the set of vertices - // not yet included in MST - int u = minKey(key, mstSet); - - // Add the picked vertex to the MST Set - mstSet[u] = true; - - // 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++) - - // graph[u][v] is non zero only for adjacent vertices of m - // mstSet[v] is false for vertices not yet included in MST - // Update the key only if graph[u][v] is smaller than key[v] - if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) { - parent[v] = u; - key[v] = graph[u][v]; - } - } - - // print the constructed MST - printMST(parent, V, graph); - } - - public static void main(String[] args) { - /* Let us create the following graph - 2 3 - (0)--(1)--(2) - | / \ | - 6| 8/ \5 |7 - | / \ | - (3)-------(4) - 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}, - }; - - // Print the solution - t.primMST(graph); - } -} diff --git a/DataStructures/HashMap/Hashing/HashMap.java b/DataStructures/HashMap/Hashing/HashMap.java deleted file mode 100644 index 38ea337fa1ec..000000000000 --- a/DataStructures/HashMap/Hashing/HashMap.java +++ /dev/null @@ -1,145 +0,0 @@ -package DataStructures.HashMap.Hashing; - -public class HashMap { - private int hsize; - private LinkedList[] buckets; - - public HashMap(int hsize) { - buckets = new LinkedList[hsize]; - for (int i = 0; i < hsize; i++) { - buckets[i] = new LinkedList(); - // Java requires explicit initialisaton of each object - } - this.hsize = hsize; - } - - public int hashing(int key) { - int hash = key % hsize; - if (hash < 0) hash += hsize; - return hash; - } - - public void insertHash(int key) { - int hash = hashing(key); - buckets[hash].insert(key); - } - - public void deleteHash(int key) { - int hash = hashing(key); - - buckets[hash].delete(key); - } - - public void displayHashtable() { - for (int i = 0; i < hsize; i++) { - System.out.printf("Bucket %d :", i); - System.out.println(buckets[i].display()); - } - } - - public static class LinkedList { - private Node first; - - public LinkedList() { - first = null; - } - - public void insert(int key) { - if (isEmpty()) { - first = new Node(key); - return; - } - - Node temp = findEnd(first); - temp.setNext(new Node(key)); - } - - private Node findEnd(Node n) { - if (n.getNext() == null) { - return n; - } else { - return findEnd(n.getNext()); - } - } - - public Node findKey(int key) { - if (!isEmpty()) { - return findKey(first, key); - } else { - System.out.println("List is empty"); - return null; - } - } - - private Node findKey(Node n, int key) { - if (n.getKey() == key) { - return n; - } else if (n.getNext() == null) { - System.out.println("Key not found"); - return null; - } else { - return findKey(n.getNext(), key); - } - } - - public void delete(int key) { - if (!isEmpty()) { - if (first.getKey() == key) { - first = null; - } else { - delete(first, key); - } - } else { - System.out.println("List is empty"); - } - } - - private void delete(Node n, int key) { - if (n.getNext().getKey() == key) { - if (n.getNext().getNext() == null) { - n.setNext(null); - } else { - n.setNext(n.getNext().getNext()); - } - } - } - - public String display() { - return display(first); - } - - private String display(Node n) { - if (n == null) { - return "null"; - } else { - return n.getKey() + "->" + display(n.getNext()); - } - } - - public boolean isEmpty() { - return first == null; - } - } - - public static class Node { - private Node next; - private int key; - - public Node(int key) { - next = null; - this.key = key; - } - - public Node getNext() { - return next; - } - - public int getKey() { - return key; - } - - public void setNext(Node next) { - this.next = next; - } - } -} diff --git a/DataStructures/HashMap/Hashing/HashMapLinearProbing.java b/DataStructures/HashMap/Hashing/HashMapLinearProbing.java deleted file mode 100644 index f381eab74431..000000000000 --- a/DataStructures/HashMap/Hashing/HashMapLinearProbing.java +++ /dev/null @@ -1,196 +0,0 @@ -package DataStructures.HashMap.Hashing; - -import java.util.*; - -/** - * This class is an implementation of a hash table using linear probing It uses a dynamic array to - * lengthen the size of the hash table when load factor > .7 - */ -public class HashMapLinearProbing { - private int hsize; // size of the hash table - private Integer[] buckets; // array representing the table - private Integer AVAILABLE; - private int size; // amount of elements in the hash table - - /** - * Constructor initializes buckets array, hsize, and creates dummy object for AVAILABLE - * - * @param hsize the desired size of the hash map - */ - public HashMapLinearProbing(int hsize) { - this.buckets = new Integer[hsize]; - this.hsize = hsize; - this.AVAILABLE = Integer.MIN_VALUE; - this.size = 0; - } - - /** - * The Hash Function takes a given key and finds an index based on its data - * - * @param key the desired key to be converted - * @return int an index corresponding to the key - */ - public int hashing(int key) { - int hash = key % hsize; - if (hash < 0) { - hash += hsize; - } - return hash; - } - - /** - * inserts the key into the hash map by wrapping it as an Integer object - * - * @param key the desired key to be inserted in the hash map - */ - public void insertHash(int key) { - Integer wrappedInt = key; - int hash = hashing(key); - - if (isFull()) { - System.out.println("Hash table is full"); - return; - } - - for (int i = 0; i < hsize; i++) { - if (buckets[hash] == null || buckets[hash] == AVAILABLE) { - buckets[hash] = wrappedInt; - size++; - return; - } - - if (hash + 1 < hsize) { - hash++; - } else { - hash = 0; - } - } - } - - /** - * deletes a key from the hash map and adds an available placeholder - * - * @param key the desired key to be deleted - */ - public void deleteHash(int key) { - Integer wrappedInt = key; - int hash = hashing(key); - - if (isEmpty()) { - System.out.println("Table is empty"); - return; - } - - for (int i = 0; i < hsize; i++) { - if (buckets[hash] != null && buckets[hash].equals(wrappedInt)) { - buckets[hash] = AVAILABLE; - size--; - return; - } - - if (hash + 1 < hsize) { - hash++; - } else { - hash = 0; - } - } - System.out.println("Key " + key + " not found"); - } - - /** Displays the hash table line by line */ - public void displayHashtable() { - for (int i = 0; i < hsize; i++) { - if (buckets[i] == null || buckets[i] == AVAILABLE) { - System.out.println("Bucket " + i + ": Empty"); - } else { - System.out.println("Bucket " + i + ": " + buckets[i].toString()); - } - } - } - - /** - * Finds the index of location based on an inputed key - * - * @param key the desired key to be found - * @return int the index where the key is located - */ - public int findHash(int key) { - Integer wrappedInt = key; - int hash = hashing(key); - - if (isEmpty()) { - System.out.println("Table is empty"); - return -1; - } - - for (int i = 0; i < hsize; i++) { - try { - if (buckets[hash].equals(wrappedInt)) { - buckets[hash] = AVAILABLE; - return hash; - } - } catch (Exception E) { - } - - if (hash + 1 < hsize) { - hash++; - } else { - hash = 0; - } - } - System.out.println("Key " + key + " not found"); - return -1; - } - - private void lengthenTable() { - buckets = Arrays.copyOf(buckets, hsize * 2); - hsize *= 2; - System.out.println("Table size is now: " + hsize); - } - - /** - * Checks the load factor of the hash table if greater than .7, automatically lengthens table to - * prevent further collisions - */ - public void checkLoadFactor() { - double factor = (double) size / hsize; - if (factor > .7) { - System.out.println("Load factor is " + factor + ", lengthening table"); - lengthenTable(); - } else { - System.out.println("Load factor is " + factor); - } - } - - /** - * isFull returns true if the hash map is full and false if not full - * - * @return boolean is Empty - */ - public boolean isFull() { - boolean response = true; - for (int i = 0; i < hsize; i++) { - if (buckets[i] == null || buckets[i] == AVAILABLE) { - response = false; - break; - } - } - return response; - } - - /** - * isEmpty returns true if the hash map is empty and false if not empty - * - * @return boolean is Empty - */ - public boolean isEmpty() { - boolean response = true; - for (int i = 0; i < hsize; i++) { - if (buckets[i] != null) { - response = false; - break; - } - } - return response; - } -} diff --git a/DataStructures/HashMap/Hashing/Main.java b/DataStructures/HashMap/Hashing/Main.java deleted file mode 100644 index 3cbe7f57a42d..000000000000 --- a/DataStructures/HashMap/Hashing/Main.java +++ /dev/null @@ -1,51 +0,0 @@ -package DataStructures.HashMap.Hashing; - -import java.util.Scanner; - -public class Main { - public static void main(String[] args) { - - int choice, key; - - HashMap h = new HashMap(7); - Scanner In = new Scanner(System.in); - - while (true) { - System.out.println("Enter your Choice :"); - System.out.println("1. Add Key"); - System.out.println("2. Delete Key"); - System.out.println("3. Print Table"); - System.out.println("4. Exit"); - - 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; - } - } - } - } -} diff --git a/DataStructures/HashMap/Hashing/MainLinearProbing.java b/DataStructures/HashMap/Hashing/MainLinearProbing.java deleted file mode 100644 index 90d1a7906704..000000000000 --- a/DataStructures/HashMap/Hashing/MainLinearProbing.java +++ /dev/null @@ -1,65 +0,0 @@ -package DataStructures.HashMap.Hashing; - -import java.util.Scanner; - -public class MainLinearProbing { - public static void main(String[] args) { - - int choice, key; - - HashMapLinearProbing h = new HashMapLinearProbing(7); - Scanner In = new Scanner(System.in); - - while (true) { - System.out.println("Enter your Choice :"); - System.out.println("1. Add Key"); - System.out.println("2. Delete Key"); - System.out.println("3. Print Table"); - System.out.println("4. Exit"); - System.out.println("5. Search and print key index"); - System.out.println("6. Check load factor"); - - 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 5: - { - System.out.println("Enter the Key to find and print: "); - key = In.nextInt(); - System.out.println("Key: " + key + " is at index: " + h.findHash(key)); - break; - } - case 6: - { - h.checkLoadFactor(); - break; - } - } - } - } -} diff --git a/DataStructures/Heaps/EmptyHeapException.java b/DataStructures/Heaps/EmptyHeapException.java deleted file mode 100644 index c47442951a6a..000000000000 --- a/DataStructures/Heaps/EmptyHeapException.java +++ /dev/null @@ -1,12 +0,0 @@ -package DataStructures.Heaps; - -/** - * @author Nicolas Renard Exception to be thrown if the getElement method is used on an empty heap. - */ -@SuppressWarnings("serial") -public class EmptyHeapException extends Exception { - - public EmptyHeapException(String message) { - super(message); - } -} diff --git a/DataStructures/Heaps/Heap.java b/DataStructures/Heaps/Heap.java deleted file mode 100644 index 75e113f8334f..000000000000 --- a/DataStructures/Heaps/Heap.java +++ /dev/null @@ -1,40 +0,0 @@ -package DataStructures.Heaps; - -/** - * Interface common to heap data structures.
- * - *

Heaps are tree-like data structures that allow storing elements in a specific way. Each node - * corresponds to an element and has one parent node (except for the root) and at most two children - * nodes. Every element contains a key, and those keys indicate how the tree shall be built. For - * instance, for a min-heap, the key of a node shall be greater than or equal to its parent's and - * lower than or equal to its children's (the opposite rule applies to a max-heap). - * - *

All heap-related operations (inserting or deleting an element, extracting the min or max) are - * performed in O(log n) time. - * - * @author Nicolas Renard - */ -public interface Heap { - - /** - * @return the top element in the heap, the one with lowest key for min-heap or with the highest - * key for max-heap - * @throws EmptyHeapException if heap is empty - */ - HeapElement getElement() throws EmptyHeapException; - - /** - * Inserts an element in the heap. Adds it to then end and toggle it until it finds its right - * position. - * - * @param element an instance of the HeapElement class. - */ - void insertElement(HeapElement element); - - /** - * Delete an element in the heap. - * - * @param elementIndex int containing the position in the heap of the element to be deleted. - */ - void deleteElement(int elementIndex); -} diff --git a/DataStructures/Heaps/HeapElement.java b/DataStructures/Heaps/HeapElement.java deleted file mode 100644 index e15763bff820..000000000000 --- a/DataStructures/Heaps/HeapElement.java +++ /dev/null @@ -1,124 +0,0 @@ -package DataStructures.Heaps; - -/** - * Class for heap elements.
- * - *

A heap element contains two attributes: a key which will be used to build the tree (int or - * double, either primitive type or object) and any kind of IMMUTABLE object the user sees fit to - * carry any information he/she likes. Be aware that the use of a mutable object might jeopardize - * the integrity of this information. - * - * @author Nicolas Renard - */ -public class HeapElement { - private final double key; - private final Object additionalInfo; - - // Constructors - - /** - * @param key : a number of primitive type 'double' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(double key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * @param key : a number of primitive type 'int' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(int key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * @param key : a number of object type 'Integer' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(Integer key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** - * @param key : a number of object type 'Double' - * @param info : any kind of IMMUTABLE object. May be null, since the purpose is only to carry - * additional information of use for the user - */ - public HeapElement(Double key, Object info) { - this.key = key; - this.additionalInfo = info; - } - - /** @param key : a number of primitive type 'double' */ - public HeapElement(double key) { - this.key = key; - this.additionalInfo = null; - } - - /** @param key : a number of primitive type 'int' */ - public HeapElement(int key) { - this.key = key; - this.additionalInfo = null; - } - - /** @param key : a number of object type 'Integer' */ - public HeapElement(Integer key) { - this.key = key; - this.additionalInfo = null; - } - - /** @param key : a number of object type 'Double' */ - public HeapElement(Double key) { - this.key = key; - this.additionalInfo = null; - } - - // Getters - - /** @return the object containing the additional info provided by the user. */ - public Object getInfo() { - return additionalInfo; - } - - /** @return the key value of the element */ - public double getKey() { - return key; - } - - // Overridden object methods - - public String toString() { - return "Key: " + key + " - " + additionalInfo.toString(); - } - - /** - * @param otherHeapElement - * @return true if the keys on both elements are identical and the additional info objects are - * identical. - */ - @Override - public boolean equals(Object o) { - if (o != null) { - if (!(o instanceof HeapElement)) return false; - HeapElement otherHeapElement = (HeapElement) o; - return (this.key == otherHeapElement.key) - && (this.additionalInfo.equals(otherHeapElement.additionalInfo)); - } - return false; - } - - @Override - public int hashCode() { - int result = 0; - result = 31 * result + (int) key; - result = 31 * result + (additionalInfo != null ? additionalInfo.hashCode() : 0); - return result; - } -} diff --git a/DataStructures/Heaps/MaxHeap.java b/DataStructures/Heaps/MaxHeap.java deleted file mode 100644 index 1c9e0a08348f..000000000000 --- a/DataStructures/Heaps/MaxHeap.java +++ /dev/null @@ -1,125 +0,0 @@ -package DataStructures.Heaps; - -import java.util.ArrayList; -import java.util.List; - -/** - * Heap tree where a node's key is higher than or equal to its parent's and lower than or equal to - * its children's. - * - * @author Nicolas Renard - */ -public class MaxHeap implements Heap { - - private final List maxHeap; - - public MaxHeap(List listElements) { - maxHeap = new ArrayList<>(); - for (HeapElement heapElement : listElements) { - if (heapElement != null) insertElement(heapElement); - else System.out.println("Null element. Not added to heap"); - } - if (maxHeap.size() == 0) System.out.println("No element has been added, empty heap."); - } - - /** - * Get the element at a given index. The key for the list is equal to index value - 1 - * - * @param elementIndex index - * @return heapElement - */ - public HeapElement getElement(int elementIndex) { - if ((elementIndex <= 0) || (elementIndex > maxHeap.size())) - throw new IndexOutOfBoundsException("Index out of heap range"); - return maxHeap.get(elementIndex - 1); - } - - // Get the key of the element at a given index - private double getElementKey(int elementIndex) { - return maxHeap.get(elementIndex - 1).getKey(); - } - - // Swaps two elements in the heap - private void swap(int index1, int index2) { - HeapElement temporaryElement = maxHeap.get(index1 - 1); - maxHeap.set(index1 - 1, maxHeap.get(index2 - 1)); - maxHeap.set(index2 - 1, temporaryElement); - } - - // Toggle an element up to its right place as long as its key is lower than its parent's - private void toggleUp(int elementIndex) { - double key = maxHeap.get(elementIndex - 1).getKey(); - while (getElementKey((int) Math.floor(elementIndex / 2.0)) < key) { - swap(elementIndex, (int) Math.floor(elementIndex / 2.0)); - elementIndex = (int) Math.floor(elementIndex / 2.0); - } - } - - // Toggle an element down to its right place as long as its key is higher - // 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()))); - 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))) { - 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()))); - } - } - - private HeapElement extractMax() { - HeapElement result = maxHeap.get(0); - deleteElement(0); - return result; - } - - @Override - public void insertElement(HeapElement element) { - maxHeap.add(element); - toggleUp(maxHeap.size()); - } - - @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(); - } - if ((elementIndex > maxHeap.size()) || (elementIndex <= 0)) - throw new IndexOutOfBoundsException("Index out of heap range"); - // The last element in heap replaces the one to be deleted - 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))) - toggleUp(elementIndex); - // ... or down ? - else if (((2 * elementIndex <= maxHeap.size()) - && (getElementKey(elementIndex) < getElementKey(elementIndex * 2))) - || ((2 * elementIndex < maxHeap.size()) - && (getElementKey(elementIndex) < getElementKey(elementIndex * 2)))) - toggleDown(elementIndex); - } - - @Override - public HeapElement getElement() throws EmptyHeapException { - try { - return extractMax(); - } catch (Exception e) { - throw new EmptyHeapException("Heap is empty. Error retrieving element"); - } - } -} diff --git a/DataStructures/Heaps/MinHeap.java b/DataStructures/Heaps/MinHeap.java deleted file mode 100644 index 1c384063c932..000000000000 --- a/DataStructures/Heaps/MinHeap.java +++ /dev/null @@ -1,120 +0,0 @@ -package DataStructures.Heaps; - -import java.util.ArrayList; -import java.util.List; - -/** - * Heap tree where a node's key is higher than or equal to its parent's and lower than or equal to - * its children's. - * - * @author Nicolas Renard - */ -public class MinHeap implements Heap { - - private final List minHeap; - - public MinHeap(List listElements) { - minHeap = new ArrayList<>(); - for (HeapElement heapElement : listElements) { - if (heapElement != null) insertElement(heapElement); - else System.out.println("Null element. Not added to heap"); - } - if (minHeap.size() == 0) System.out.println("No element has been added, empty heap."); - } - - // Get the element at a given index. The key for the list is equal to index value - 1 - public HeapElement getElement(int elementIndex) { - if ((elementIndex <= 0) || (elementIndex > minHeap.size())) - throw new IndexOutOfBoundsException("Index out of heap range"); - return minHeap.get(elementIndex - 1); - } - - // Get the key of the element at a given index - private double getElementKey(int elementIndex) { - return minHeap.get(elementIndex - 1).getKey(); - } - - // Swaps two elements in the heap - private void swap(int index1, int index2) { - HeapElement temporaryElement = minHeap.get(index1 - 1); - minHeap.set(index1 - 1, minHeap.get(index2 - 1)); - minHeap.set(index2 - 1, temporaryElement); - } - - // Toggle an element up to its right place as long as its key is lower than its parent's - private void toggleUp(int elementIndex) { - double key = minHeap.get(elementIndex - 1).getKey(); - while (getElementKey((int) Math.floor(elementIndex / 2.0)) > key) { - swap(elementIndex, (int) Math.floor(elementIndex / 2.0)); - elementIndex = (int) Math.floor(elementIndex / 2.0); - } - } - - // Toggle an element down to its right place as long as its key is higher - // 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()))); - 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))) { - 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()))); - } - } - - private HeapElement extractMin() { - HeapElement result = minHeap.get(0); - deleteElement(0); - return result; - } - - @Override - public void insertElement(HeapElement element) { - minHeap.add(element); - toggleUp(minHeap.size()); - } - - @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(); - } - if ((elementIndex > minHeap.size()) || (elementIndex <= 0)) - throw new IndexOutOfBoundsException("Index out of heap range"); - // The last element in heap replaces the one to be deleted - 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))) - toggleUp(elementIndex); - // ... or down ? - else if (((2 * elementIndex <= minHeap.size()) - && (getElementKey(elementIndex) > getElementKey(elementIndex * 2))) - || ((2 * elementIndex < minHeap.size()) - && (getElementKey(elementIndex) > getElementKey(elementIndex * 2)))) - toggleDown(elementIndex); - } - - @Override - public HeapElement getElement() throws EmptyHeapException { - try { - return extractMin(); - } catch (Exception e) { - throw new EmptyHeapException("Heap is empty. Error retrieving element"); - } - } -} diff --git a/DataStructures/Heaps/MinPriorityQueue.java b/DataStructures/Heaps/MinPriorityQueue.java deleted file mode 100644 index 82950d22e700..000000000000 --- a/DataStructures/Heaps/MinPriorityQueue.java +++ /dev/null @@ -1,125 +0,0 @@ -package DataStructures.Heaps; - -/** - * Minimum Priority Queue It is a part of heap data structure A heap is a specific tree based data - * structure in which all the nodes of tree are in a specific order. that is the children are - * arranged in some respect of their parents, can either be greater or less than the parent. This - * makes it a min priority queue or max priority queue. - * - *

- * - *

Functions: insert, delete, peek, isEmpty, print, heapSort, sink - */ -public class MinPriorityQueue { - private int[] heap; - private int capacity; - private int size; - - // calss the constructor and initializes the capacity - MinPriorityQueue(int c) { - this.capacity = c; - this.size = 0; - this.heap = new int[c + 1]; - } - - // inserts the key at the end and rearranges it - // so that the binary heap is in appropriate order - public void insert(int key) { - if (this.isFull()) return; - this.heap[this.size + 1] = key; - int k = this.size + 1; - while (k > 1) { - if (this.heap[k] < this.heap[k / 2]) { - int temp = this.heap[k]; - this.heap[k] = this.heap[k / 2]; - this.heap[k / 2] = temp; - } - k = k / 2; - } - this.size++; - } - - // returns the highest priority value - public int peek() { - return this.heap[1]; - } - - // returns boolean value whether the heap is empty or not - public boolean isEmpty() { - if (0 == this.size) return true; - return false; - } - - // returns boolean value whether the heap is full or not - public boolean isFull() { - if (this.size == this.capacity) return true; - return false; - } - - // prints the heap - public void print() { - for (int i = 1; i <= this.capacity; i++) System.out.print(this.heap[i] + " "); - System.out.println(); - } - - // heap sorting can be done by performing - // delete function to the number of times of the size of the heap - // it returns reverse sort because it is a min priority queue - public void heapSort() { - for (int i = 1; i < this.capacity; i++) this.delete(); - } - - // this function reorders the heap after every delete function - private void sink() { - int k = 1; - 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]) { - break; - } else if (2 * k + 1 > this.size) { - break; - } - } - 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; - } else { - minIndex = k; - } - } - int temp = this.heap[k]; - this.heap[k] = this.heap[minIndex]; - this.heap[minIndex] = temp; - k = minIndex; - } - } - - // deletes the highest priority value from the heap - public int delete() { - int min = this.heap[1]; - this.heap[1] = this.heap[this.size]; - this.heap[this.size] = min; - this.size--; - this.sink(); - return min; - } - - public static void main(String[] args) { - // testing - MinPriorityQueue q = new MinPriorityQueue(8); - q.insert(5); - q.insert(2); - q.insert(4); - q.insert(1); - q.insert(7); - q.insert(6); - q.insert(3); - q.insert(8); - q.print(); // [ 1, 2, 3, 5, 7, 6, 4, 8 ] - q.heapSort(); - q.print(); // [ 8, 7, 6, 5, 4, 3, 2, 1 ] - } -} diff --git a/DataStructures/Lists/CircleLinkedList.java b/DataStructures/Lists/CircleLinkedList.java deleted file mode 100644 index de264ddc845f..000000000000 --- a/DataStructures/Lists/CircleLinkedList.java +++ /dev/null @@ -1,103 +0,0 @@ -package DataStructures.Lists; - -public class CircleLinkedList { - private static class Node { - Node next; - E value; - - private Node(E value, Node next) { - this.value = value; - this.next = next; - } - } - - // For better O.O design this should be private allows for better black box design - private int size; - // this will point to dummy node; - private Node head = null; - private Node tail = null; // keeping a tail pointer to keep track of the end of list - - // constructer for class.. here we will make a dummy node for circly linked list implementation - // with reduced error catching as our list will never be empty; - public CircleLinkedList() { - // creation of the dummy node - head = new Node(null, head); - tail = head; - size = 0; - } - - // getter for the size... needed because size is private. - public int getSize() { - return size; - } - - // for the sake of simplistiy this class will only contain the append function or addLast other - // add functions can be implemented however this is the basses of them all really. - 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"); - } - // head.next points to the last element; - if (tail == null){ - tail = new Node(value, head); - head.next = tail; - } - else{ - tail.next = new Node(value, head); - tail = tail.next; - } - size++; - } - - // utility function for teraversing the list - public String toString(){ - Node p = head.next; - String s = "[ "; - while(p!=head){ - s += p.value; - s += " , "; - p = p.next; - } - return s + " ]"; - } - - public static void main(String args[]){ - CircleLinkedList cl = new CircleLinkedList(); - cl.append(12); - System.out.println(cl); - cl.append(23); - System.out.println(cl); - cl.append(34); - System.out.println(cl); - cl.append(56); - System.out.println(cl); - cl.remove(3); - System.out.println(cl); - } - - public E remove(int pos) { - if (pos > size || pos < 0) { - // catching errors - 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. - Node before = head; - for (int i = 1; i <= pos; i++) { - before = before.next; - } - Node destroy = before.next; - E saved = destroy.value; - // assigning the next reference to the the element following the element we want to remove... - // the last element will be assigned to the head. - before.next = before.next.next; - // scrubbing - if(destroy == tail){ - tail = before; - } - destroy = null; - size--; - return saved; - } -} diff --git a/DataStructures/Lists/CountSinglyLinkedListRecursion.java b/DataStructures/Lists/CountSinglyLinkedListRecursion.java deleted file mode 100644 index 78e854e2c670..000000000000 --- a/DataStructures/Lists/CountSinglyLinkedListRecursion.java +++ /dev/null @@ -1,26 +0,0 @@ -package DataStructures.Lists; - -public class CountSinglyLinkedListRecursion extends SinglyLinkedList { - public static void main(String[] args) { - CountSinglyLinkedListRecursion list = new CountSinglyLinkedListRecursion(); - for (int i = 1; i <= 5; ++i) { - list.insert(i); - } - assert list.count() == 5; - } - - /** - * Calculate the count of the list manually using recursion. - * - * @param head head of the list. - * @return count of the list. - */ - private int countRecursion(Node head) { - return head == null ? 0 : 1 + countRecursion(head.next); - } - /** Returns the count of the list. */ - @Override - public int count() { - return countRecursion(getHead()); - } -} diff --git a/DataStructures/Lists/CreateAndDetectLoop.java b/DataStructures/Lists/CreateAndDetectLoop.java deleted file mode 100644 index 149bf51df700..000000000000 --- a/DataStructures/Lists/CreateAndDetectLoop.java +++ /dev/null @@ -1,95 +0,0 @@ -package DataStructures.Lists; - -import java.util.Scanner; - -public class CreateAndDetectLoop { - - /** - * Prints the linked list. - * - * @param head head node of the linked list - */ - static void printList(Node head) { - Node cur = head; - - while (cur != null) { - System.out.print(cur.value + " "); - cur = cur.next; - } - } - - /** - * Creates a loop in the linked list. - * @see - * GeeksForGeeks: Make a loop at K-th position - * @param head head node of the linked list - * @param k position of node where loop is to be created - */ - static void createLoop(Node head, int k) { - if (head == null) - return; - Node temp = head; - int count = 1; - while (count < k) { // Traverse the list till the kth node - temp = temp.next; - count++; - } - - Node connectedPoint = temp; - - while (temp.next != null) // Traverse remaining nodes - temp = temp.next; - - temp.next = connectedPoint; // Connect last node to k-th element - } - - /** - * Detects the presence of a loop in the linked list. - * @see - * Floyd's Cycle Detection Algorithm - * - * @param head the head node of the linked list - * - * @return true if loop exists else false - */ - static boolean detectLoop(Node head) { - Node sptr = head; - Node fptr = head; - - while (fptr != null && fptr.next != null) { - sptr = sptr.next; - fptr = fptr.next.next; - if (fptr == sptr) - return true; - } - - return false; - } - - public static void main(String[] args) { - SinglyLinkedList singlyLinkedList = new SinglyLinkedList(); - Scanner sc = new Scanner(System.in); - - System.out.println("Enter the number of elements to be inserted: "); - int n = sc.nextInt(); - System.out.printf("Enter the %d elements: \n", n); - while (n-- > 0) - singlyLinkedList.insert(sc.nextInt()); - - System.out.print("Given list: "); - printList(singlyLinkedList.getHead()); - System.out.println(); - - System.out.println("Enter the location to generate loop: "); - int k = sc.nextInt(); - - createLoop(singlyLinkedList.getHead(), k); - - if (detectLoop(singlyLinkedList.getHead())) - System.out.println("Loop found"); - else - System.out.println("No loop found"); - - sc.close(); - } -} diff --git a/DataStructures/Lists/CursorLinkedList.java b/DataStructures/Lists/CursorLinkedList.java deleted file mode 100644 index 5eedb91cb0fa..000000000000 --- a/DataStructures/Lists/CursorLinkedList.java +++ /dev/null @@ -1,195 +0,0 @@ -package DataStructures.Lists; - -import java.util.Objects; - -/** - * This class implements a Cursor Linked List. - * - * A CursorLinkedList is an array version of a Linked List. Essentially you have an array of list nodes but instead of - * each node containing a pointer to the next item in the linked list, each node element in the array contains the index for the next node element. - * - */ -public class CursorLinkedList { - - private static class Node { - - T element; - int next; - - Node(T element, int next) { - this.element = element; - this.next = next; - } - } - - private final int os; - private int head; - private final Node[] cursorSpace; - private int count; - private static final int CURSOR_SPACE_SIZE = 100; - - { - // init at loading time - cursorSpace = new Node[CURSOR_SPACE_SIZE]; - for (int i = 0; i < CURSOR_SPACE_SIZE; i++) { - cursorSpace[i] = new Node<>(null, i + 1); - } - cursorSpace[CURSOR_SPACE_SIZE - 1].next = 0; - } - - public CursorLinkedList() { - os = 0; - count = 0; - head = -1; - } - - public void printList() { - - if (head != -1) { - - int start = head; - while (start != -1) { - - T element = cursorSpace[start].element; - System.out.println(element.toString()); - start = cursorSpace[start].next; - } - } - } - - /** - * @return the logical index of the element within the list , not the actual index of the - * [cursorSpace] array - */ - public int indexOf(T element) { - - Objects.requireNonNull(element); - Node iterator = cursorSpace[head]; - for (int i = 0; i < count; i++) { - if (iterator.element.equals(element)) { - return i; - } - iterator = cursorSpace[iterator.next]; - } - - return -1; - } - - /** - * @param position , the logical index of the element , not the actual one within the - * [cursorSpace] array . this method should be used to get the index give by indexOf() method. - * @return - */ - public T get(int position) { - - if (position >= 0 && position < count) { - - int start = head; - int counter = 0; - while (start != -1) { - - T element = cursorSpace[start].element; - if (counter == position) { - return element; - } - - start = cursorSpace[start].next; - counter++; - } - } - - return null; - } - - public void removeByIndex(int index) { - - if (index >= 0 && index < count) { - - T element = get(index); - remove(element); - } - } - - public void remove(T element) { - - Objects.requireNonNull(element); - - // case element is in the head - T temp_element = cursorSpace[head].element; - int temp_next = cursorSpace[head].next; - if (temp_element.equals(element)) { - free(head); - head = temp_next; - } else { // otherwise cases - - int prev_index = head; - int current_index = cursorSpace[prev_index].next; - - while (current_index != -1) { - - T current_element = cursorSpace[current_index].element; - if (current_element.equals(element)) { - cursorSpace[prev_index].next = cursorSpace[current_index].next; - free(current_index); - break; - } - - prev_index = current_index; - current_index = cursorSpace[prev_index].next; - } - } - - count--; - } - - private void free(int index) { - - Node os_node = cursorSpace[os]; - int os_next = os_node.next; - cursorSpace[os].next = index; - cursorSpace[index].element = null; - cursorSpace[index].next = os_next; - } - - public void append(T element) { - - Objects.requireNonNull(element); - int availableIndex = alloc(); - cursorSpace[availableIndex].element = element; - - if (head == -1) { - head = availableIndex; - } - - int iterator = head; - while (cursorSpace[iterator].next != -1) { - iterator = cursorSpace[iterator].next; - } - - cursorSpace[iterator].next = availableIndex; - cursorSpace[availableIndex].next = -1; - - count++; - } - - /** @return the index of the next available node */ - private int alloc() { - - // 1- get the index at which the os is pointing - int availableNodeIndex = cursorSpace[os].next; - - if (availableNodeIndex == 0) { - throw new OutOfMemoryError(); - } - - // 2- make the os point to the next of the @var{availableNodeIndex} - int availableNext = cursorSpace[availableNodeIndex].next; - cursorSpace[os].next = availableNext; - - // this to indicate an end of the list , helpful at testing since any err - // would throw an outOfBoundException - cursorSpace[availableNodeIndex].next = -1; - - return availableNodeIndex; - } -} diff --git a/DataStructures/Lists/DoublyLinkedList.java b/DataStructures/Lists/DoublyLinkedList.java deleted file mode 100644 index a3a0bcba92af..000000000000 --- a/DataStructures/Lists/DoublyLinkedList.java +++ /dev/null @@ -1,357 +0,0 @@ -package DataStructures.Lists; - -/** - * This class implements a DoublyLinkedList. This is done using the classes LinkedList and Link. - * - *

A linked list is similar to an array, it holds values. However, links in a linked list do not - * have indexes. With a linked list you do not need to predetermine it's size as it grows and - * shrinks as it is edited. This is an example of a double ended, doubly linked list. Each link - * references the next link and the previous one. - * - * @author Unknown - */ -public class DoublyLinkedList { - /** Head refers to the front of the list */ - private Link head; - /** Tail refers to the back of the list */ - private Link tail; - - /** Size refers to the number of elements present in the list */ - private int size; - - /** Default Constructor */ - public DoublyLinkedList() { - head = null; - tail = null; - size = 0; - } - - /** - * Constructs a list containing the elements of the array - * - * @param array the array whose elements are to be placed into this list - * @throws NullPointerException if the specified collection is null - */ - public DoublyLinkedList(int[] array) { - if (array == null) throw new NullPointerException(); - for (int i : array) { - insertTail(i); - } - size = array.length; - } - - /** - * Insert an element at the head - * - * @param x Element to be inserted - */ - public void insertHead(int x) { - Link newLink = new Link(x); // Create a new link with a value attached to it - if (isEmpty()) // Set the first element added to be the tail - tail = newLink; - else head.previous = newLink; // newLink <-- currenthead(head) - newLink.next = head; // newLink <--> currenthead(head) - head = newLink; // newLink(head) <--> oldhead - ++size; - } - - /** - * Insert an element at the tail - * - * @param x Element to be inserted - */ - public void insertTail(int x) { - Link newLink = new Link(x); - newLink.next = null; // currentTail(tail) newlink --> - if (isEmpty()) { // Check if there are no elements in list then it adds first element - tail = newLink; - head = tail; - } else { - tail.next = newLink; // currentTail(tail) --> newLink --> - newLink.previous = tail; // currentTail(tail) <--> newLink --> - tail = newLink; // oldTail <--> newLink(tail) --> - } - ++size; - } - - /** - * Insert an element at the index - * - * @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) { - if (index > size) throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); - if (index == 0) { - insertHead(x); - } else { - if (index == size) { - insertTail(x); - } else { - Link newLink = new Link(x); - Link previousLink = head; // - for (int i = 1; i < index; i++) { // Loop to reach the index - previousLink = previousLink.next; - } - // previousLink is the Link at index - 1 from start - previousLink.next.previous = newLink; - newLink.next = previousLink.next; - newLink.previous = previousLink; - previousLink.next = newLink; - } - } - ++size; - } - - /** - * Delete the element at the head - * - * @return The new head - */ - public Link deleteHead() { - Link temp = head; - head = head.next; // oldHead <--> 2ndElement(head) - - if (head == null) { - tail = null; - } else { - head.previous = - null; // oldHead --> 2ndElement(head) nothing pointing at old head so will be removed - } - --size; - return temp; - } - - /** - * Delete the element at the tail - * - * @return The new tail - */ - public Link deleteTail() { - Link temp = tail; - tail = tail.previous; // 2ndLast(tail) <--> oldTail --> null - - if (tail == null) { - head = null; - } else { - tail.next = null; // 2ndLast(tail) --> null - } - --size; - return temp; - } - - /** - * Delete the element from somewhere in the list - * - * @param x element to be deleted - * @return Link deleted - */ - public void delete(int x) { - Link current = head; - - while (current.value != x) { // Find the position to delete - 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!"); - } - } - - if (current == head) deleteHead(); - else if (current == tail) deleteTail(); - else { // Before: 1 <--> 2(current) <--> 3 - current.previous.next = current.next; // 1 --> 3 - current.next.previous = current.previous; // 1 <--> 3 - } - --size; - } - - /** - * Inserts element and reorders - * - * @param x Element to be added - */ - public void insertOrdered(int x) { - Link newLink = new Link(x); - Link current = head; - while (current != null && x > current.value) // Find the position to insert - current = current.next; - - if (current == head) insertHead(x); - else if (current == null) insertTail(x); - else { // Before: 1 <--> 2(current) <--> 3 - newLink.previous = current.previous; // 1 <-- newLink - current.previous.next = newLink; // 1 <--> newLink - newLink.next = current; // 1 <--> newLink --> 2(current) <--> 3 - current.previous = newLink; // 1 <--> newLink <--> 2(current) <--> 3 - } - ++size; - } - - /** - * Deletes the passed node from the current list - * - * @param z Element to be deleted - */ - public void deleteNode(Link z) { - if (z.next == null) { - deleteTail(); - } else if (z == head) { - deleteHead(); - } else { // before <-- 1 <--> 2(z) <--> 3 --> - z.previous.next = z.next; // 1 --> 3 - z.next.previous = z.previous; // 1 <--> 3 - } - --size; - } - - public static void removeDuplicates(DoublyLinkedList l) { - Link linkOne = l.head; - while (linkOne.next != null) { // list is present - Link linkTwo = linkOne.next; // second link for comparison - while (linkTwo.next != null) { - if (linkOne.value == linkTwo.value) // if there are duplicates values then - l.delete(linkTwo.value); // delete the link - linkTwo = linkTwo.next; // go to next link - } - linkOne = linkOne.next; // go to link link to iterate the whole list again - } - } - - /** - * Reverses the list in place - * - * @param l the DoublyLinkedList to reverse - */ - public void reverse() { - // Keep references to the head and tail - Link thisHead = this.head; - Link thisTail = this.tail; - - // Flip the head and tail references - this.head = thisTail; - this.tail = thisHead; - - // While the link we're visiting is not null, flip the - // next and previous links - Link nextLink = thisHead; - while (nextLink != null) { - Link nextLinkNext = nextLink.next; - Link nextLinkPrevious = nextLink.previous; - nextLink.next = nextLinkPrevious; - nextLink.previous = nextLinkNext; - - // Now, we want to go to the next link - nextLink = nextLinkNext; - } - } - - /** Clears List */ - public void clearList() { - head = null; - tail = null; - size = 0; - } - - /** - * Returns true if list is empty - * - * @return true if list is empty - */ - public boolean isEmpty() { - return (head == null); - } - - /** Prints contents of the list */ - public void display() { // Prints contents of the list - Link current = head; - while (current != null) { - current.displayLink(); - current = current.next; - } - System.out.println(); - } - - /** - * Prints the contents of the list in reverse order - */ - public void displayBackwards() { - Link current = tail; - while (current != null) { - current.displayLink(); - current = current.previous; - } - System.out.println(); - } -} - -/** - * This class is used to implement the nodes of the linked list. - * - * @author Unknown - */ -class Link { - /** Value of node */ - public int value; - /** This points to the link in front of the new link */ - public Link next; - /** This points to the link behind the new link */ - public Link previous; - - /** - * Constructor - * - * @param value Value of node - */ - public Link(int value) { - this.value = value; - } - - /** Displays the node */ - public void displayLink() { - System.out.print(value + " "); - } - - /** - * Main Method - * - * @param args Command line arguments - */ - public static void main(String args[]) { - DoublyLinkedList myList = new DoublyLinkedList(); - myList.insertHead(13); - myList.insertHead(7); - myList.insertHead(10); - myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) --> - myList.displayBackwards(); - - myList.insertTail(11); - myList.display(); // <-- 10(head) <--> 7 <--> 13 <--> 11(tail) --> - myList.displayBackwards(); - - myList.deleteTail(); - myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) --> - myList.displayBackwards(); - - myList.delete(7); - myList.display(); // <-- 10(head) <--> 13(tail) --> - myList.displayBackwards(); - - myList.insertOrdered(23); - myList.insertOrdered(67); - myList.insertOrdered(3); - myList.display(); // <-- 3(head) <--> 10 <--> 13 <--> 23 <--> 67(tail) --> - myList.insertElementByIndex(5, 1); - myList.display(); // <-- 3(head) <--> 5 <--> 10 <--> 13 <--> 23 <--> 67(tail) --> - myList.displayBackwards(); - myList.reverse(); // <-- 67(head) <--> 23 <--> 13 <--> 10 <--> 5 <--> 3(tail) --> - myList.display(); - - myList.clearList(); - myList.display(); - myList.displayBackwards(); - myList.insertHead(20); - myList.display(); - myList.displayBackwards(); - } -} diff --git a/DataStructures/Lists/MergeSortedArrayList.java b/DataStructures/Lists/MergeSortedArrayList.java deleted file mode 100644 index 45f30f66c4fd..000000000000 --- a/DataStructures/Lists/MergeSortedArrayList.java +++ /dev/null @@ -1,56 +0,0 @@ -package DataStructures.Lists; - -import java.util.ArrayList; -import java.util.List; - -/** @author https://github.com/shellhub */ -public class MergeSortedArrayList { - public static void main(String[] args) { - List listA = new ArrayList<>(); - List listB = new ArrayList<>(); - List listC = new ArrayList<>(); - - /* init ListA and List B */ - for (int i = 1; i <= 10; i += 2) { - listA.add(i); /* listA: [1, 3, 5, 7, 9] */ - listB.add(i + 1); /* listB: [2, 4, 6, 8, 10] */ - } - - /* merge listA and listB to listC */ - merge(listA, listB, listC); - - System.out.println("listA: " + listA); - System.out.println("listB: " + listB); - System.out.println("listC: " + listC); - } - - /** - * merge two sorted ArrayList - * - * @param listA the first list to merge - * @param listB the second list to merge - * @param listC the result list after merging - */ - public static void merge(List listA, List listB, List listC) { - int pa = 0; /* the index of listA */ - int pb = 0; /* the index of listB */ - - while (pa < listA.size() && pb < listB.size()) { - if (listA.get(pa) <= listB.get(pb)) { - listC.add(listA.get(pa++)); - } else { - listC.add(listB.get(pb++)); - } - } - - /* copy left element of listA to listC */ - while (pa < listA.size()) { - listC.add(listA.get(pa++)); - } - - /* copy left element of listB to listC */ - while (pb < listB.size()) { - listC.add(listB.get(pb++)); - } - } -} diff --git a/DataStructures/Lists/MergeSortedSinglyLinkedList.java b/DataStructures/Lists/MergeSortedSinglyLinkedList.java deleted file mode 100644 index 526a539ce41e..000000000000 --- a/DataStructures/Lists/MergeSortedSinglyLinkedList.java +++ /dev/null @@ -1,51 +0,0 @@ -package DataStructures.Lists; - -public class MergeSortedSinglyLinkedList extends SinglyLinkedList { - - public static void main(String[] args) { - SinglyLinkedList listA = new SinglyLinkedList(); - SinglyLinkedList listB = new SinglyLinkedList(); - - for (int i = 2; i <= 10; i += 2) { - listA.insert(i); - listB.insert(i - 1); - } - 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"); - } - - /** - * Merge two sorted SingleLinkedList - * - * @param listA the first sorted list - * @param listB the second sored list - * @return merged sorted list - */ - public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList listB) { - Node headA = listA.getHead(); - Node headB = listB.getHead(); - - int size = listA.size() + listB.size(); - - Node head = new Node(); - Node tail = head; - while (headA != null && headB != null) { - if (headA.value <= headB.value) { - tail.next = headA; - headA = headA.next; - } else { - tail.next = headB; - headB = headB.next; - } - tail = tail.next; - } - if (headA == null) { - tail.next = headB; - } - if (headB == null) { - tail.next = headA; - } - return new SinglyLinkedList(head.next, size); - } -} diff --git a/DataStructures/Lists/Merge_K_SortedLinkedlist.java b/DataStructures/Lists/Merge_K_SortedLinkedlist.java deleted file mode 100644 index 61d3a90525ea..000000000000 --- a/DataStructures/Lists/Merge_K_SortedLinkedlist.java +++ /dev/null @@ -1,54 +0,0 @@ -package DataStructures.Lists; - -import java.util.Arrays; -import java.util.Comparator; -import java.util.PriorityQueue; - -/** @author Arun Pandey (https://github.com/pandeyarun709) */ -public class Merge_K_SortedLinkedlist { - - /** - * This function merge K sorted LinkedList - * - * @param a array of LinkedList - * @param N size of array - * @return node - */ - Node mergeKList(Node[] a, int N) { - // Min Heap - PriorityQueue min = new PriorityQueue<>(Comparator.comparingInt(x -> x.data)); - - // adding head of all linkedList in min heap - min.addAll(Arrays.asList(a).subList(0, N)); - - // Make new head among smallest heads in K linkedList - Node head = min.poll(); - min.add(head.next); - Node curr = head; - - // merging LinkedList - while (!min.isEmpty()) { - - Node temp = min.poll(); - curr.next = temp; - curr = temp; - - // Add Node in min Heap only if temp.next is not null - if (temp.next != null) { - min.add(temp.next); - } - } - - return head; - } - - private class Node { - private int data; - private Node next; - - public Node(int d) { - this.data = d; - next = null; - } - } -} diff --git a/DataStructures/Lists/SearchSinglyLinkedListRecursion.java b/DataStructures/Lists/SearchSinglyLinkedListRecursion.java deleted file mode 100644 index 2f5cd4b18ca6..000000000000 --- a/DataStructures/Lists/SearchSinglyLinkedListRecursion.java +++ /dev/null @@ -1,31 +0,0 @@ -package DataStructures.Lists; - -public class SearchSinglyLinkedListRecursion extends SinglyLinkedList { - public static void main(String[] args) { - SearchSinglyLinkedListRecursion list = new SearchSinglyLinkedListRecursion(); - for (int i = 1; i <= 10; ++i) { - list.insert(i); - } - - for (int i = 1; i <= 10; ++i) { - assert list.search(i); - } - assert !list.search(-1) && !list.search(100); - } - - /** - * Test if the value key is present in the list using recursion. - * - * @param node the head node. - * @param key the value to be searched. - * @return {@code true} if key is present in the list, otherwise {@code false}. - */ - private boolean searchRecursion(Node node, int key) { - return node != null && (node.value == key || searchRecursion(node.next, key)); - } - - @Override - public boolean search(int key) { - return searchRecursion(getHead(), key); - } -} diff --git a/DataStructures/Lists/SinglyLinkedList.java b/DataStructures/Lists/SinglyLinkedList.java deleted file mode 100644 index 2457bb3a6376..000000000000 --- a/DataStructures/Lists/SinglyLinkedList.java +++ /dev/null @@ -1,349 +0,0 @@ -package DataStructures.Lists; - -import java.util.StringJoiner; - -/** https://en.wikipedia.org/wiki/Linked_list */ -public class SinglyLinkedList { - /** Head refer to the front of the list */ - private Node head; - - /** Size of SinglyLinkedList */ - private int size; - - /** Init SinglyLinkedList */ - public SinglyLinkedList() { - head = null; - size = 0; - } - - /** - * Init SinglyLinkedList with specified head node and size - * - * @param head the head node of list - * @param size the size of list - */ - public SinglyLinkedList(Node head, int size) { - this.head = head; - this.size = size; - } - - /** - * Inserts an element at the head of the list - * - * @param x element to be added - */ - public void insertHead(int x) { - insertNth(x, 0); - } - - /** - * Insert an element at the tail of the list - * - * @param data element to be added - */ - public void insert(int data) { - insertNth(data, size); - } - - /** - * Inserts a new node at a specified position of the list - * - * @param data data to be stored in a new node - * @param position position at which a new node is to be inserted - */ - public void insertNth(int data, int position) { - checkBounds(position, 0, size); - Node newNode = new Node(data); - if (head == null) { - /* the list is empty */ - head = newNode; - size++; - return; - } else if (position == 0) { - /* insert at the head of the list */ - newNode.next = head; - head = newNode; - size++; - return; - } - Node cur = head; - for (int i = 0; i < position - 1; ++i) { - cur = cur.next; - } - newNode.next = cur.next; - cur.next = newNode; - size++; - } - - /** - Detects if there is a loop in the singly linked list - using floy'd turtle and hare algorithm. - **/ - public boolean detectLoop(){ - Node currentNodeFast = head; - Node currentNodeSlow = head; - boolean flag = false; - while(currentNodeFast!=null && currentNodeFast.next != null && currentNodeSlow!=null && currentNodeSlow.next != null){ - currentNodeFast = currentNodeFast.next.next; - currentNodeSlow = currentNodeSlow.next; - if (currentNodeFast==currentNodeSlow){ - flag = true; - break; - } - } - return flag; - } - - /** - Swaps nodes of two given values a and b. - **/ - - public void swapNodes(int a, int b){ - Node currentNode = head; - Node temp = null; - while(currentNode!=null){ - if (currentNode.next.value == a){ - temp = currentNode.next; - } - if(currentNode.next.value == b){ - currentNode.next=temp; - } - currentNode=currentNode.next; - } - } - - - /** - Reverse a singly linked list from a given node till the end - **/ - - - Node reverseList(Node node) { - Node prev = null, curr = node, next; - while (curr != null) { - next = curr.next; - curr.next = prev; - prev = curr; - curr = next; - } - node = prev; - return node; - } - - - - /** Deletes a node at the head */ - public void deleteHead() { - deleteNth(0); - } - - /** Deletes an element at the tail */ - public void delete() { - deleteNth(size - 1); - } - - /** Deletes an element at Nth position */ - public void deleteNth(int position) { - checkBounds(position, 0, size - 1); - if (position == 0) { - Node destroy = head; - head = head.next; - destroy = null; /* clear to let GC do its work */ - size--; - return; - } - Node cur = head; - for (int i = 0; i < position - 1; ++i) { - cur = cur.next; - } - - Node destroy = cur.next; - cur.next = cur.next.next; - destroy = null; // clear to let GC do its work - - size--; - } - - /** - * @param position to check position - * @param low low index - * @param high high index - * @throws IndexOutOfBoundsException if {@code position} not in range {@code low} to {@code high} - */ - public void checkBounds(int position, int low, int high) { - if (position > high || position < low) { - throw new IndexOutOfBoundsException(position + ""); - } - } - - /** Clear all nodes in the list */ - public void clear() { - Node cur = head; - while (cur != null) { - Node prev = cur; - cur = cur.next; - prev = null; // clear to let GC do its work - } - head = null; - size = 0; - } - - /** - * Checks if the list is empty - * - * @return {@code true} if list is empty, otherwise {@code false}. - */ - public boolean isEmpty() { - return size == 0; - } - - /** - * Returns the size of the linked list. - * - * @return the size of the list. - */ - public int size() { - return size; - } - - /** - * Get head of the list. - * - * @return head of the list. - */ - public Node getHead() { - return head; - } - - /** - * Calculate the count of the list manually - * - * @return count of the list - */ - public int count() { - int count = 0; - Node cur = head; - while (cur != null) { - cur = cur.next; - count++; - } - return count; - } - - /** - * Test if the value key is present in the list. - * - * @param key the value to be searched. - * @return {@code true} if key is present in the list, otherwise {@code false}. - */ - public boolean search(int key) { - Node cur = head; - while (cur != null) { - if (cur.value == key) { - return true; - } - cur = cur.next; - } - return false; - } - - /** - * Return element at special index. - * - * @param index given index of element - * @return element at special index. - */ - public int getNth(int index) { - checkBounds(index, 0, size - 1); - Node cur = head; - for (int i = 0; i < index; ++i) { - cur = cur.next; - } - return cur.value; - } - - @Override - public String toString() { - StringJoiner joiner = new StringJoiner("->"); - Node cur = head; - while (cur != null) { - joiner.add(cur.value + ""); - cur = cur.next; - } - return joiner.toString(); - } - - /** Driver Code */ - public static void main(String[] arg) { - SinglyLinkedList list = new SinglyLinkedList(); - assert list.isEmpty(); - assert list.size() == 0 && list.count() == 0; - assert list.toString().equals(""); - - /* Test insert function */ - list.insertHead(5); - list.insertHead(7); - list.insertHead(10); - list.insert(3); - list.insertNth(1, 4); - assert list.toString().equals("10->7->5->3->1"); - - /* Test search function */ - 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; - - /* Test delete function */ - list.deleteHead(); - list.deleteNth(1); - list.delete(); - assert list.toString().equals("7->3"); - - assert list.size == 2 && list.size() == list.count(); - - list.clear(); - assert list.isEmpty(); - - try { - list.delete(); - assert false; /* this should not happen */ - } catch (Exception e) { - assert true; /* this should happen */ - } - } -} - -/** - * This class is the nodes of the SinglyLinked List. They consist of a value and a pointer to the - * node after them. - */ -class Node { - /** The value of the node */ - int value; - - /** Point to the next node */ - Node next; - - Node() {} - - /** - * Constructor - * - * @param value Value to be put in the node - */ - Node(int value) { - this(value, null); - } - - /** - * Constructor - * - * @param value Value to be put in the node - * @param next Reference to the next node - */ - Node(int value, Node next) { - this.value = value; - this.next = next; - } -} diff --git a/DataStructures/Queues/Deques.java b/DataStructures/Queues/Deques.java deleted file mode 100644 index 499db9cfa417..000000000000 --- a/DataStructures/Queues/Deques.java +++ /dev/null @@ -1,247 +0,0 @@ -package DataStructures.Queues; - -/** - * A [deque](https://en.wikipedia.org/wiki/Double-ended_queue) is short for a double ended queue - * pronounced "deck" and sometimes referred to as a head-tail linked list. A deque is a data - * structure based on a doubly linked list, but only supports adding and removal of nodes from the - * beginning and the end of the list. - * - * @author [Ian Cowan](https://github.com/iccowan) - */ -public class Deques { - /** Node for the deque */ - class DequeNode { - /** Value of the node */ - S val; - - /** Next node in the deque from this node */ - DequeNode next = null; - - /** Previous node in the deque from this node */ - DequeNode prev = null; - - /** Constructor */ - DequeNode(S val) { - this.val = val; - } - } - - /** Head of the deque */ - DequeNode head = null; - - /** Tail of the deque */ - DequeNode tail = null; - - /** Size of the deque */ - int size = 0; - - /** - * Adds the specified value to the head of the deque - * - * @param val Value to add to the deque - */ - public void addFirst(T val) { - // Create a new node with the given value - DequeNode newNode = new DequeNode(val); - - // Add the node - if (head == null) { - // If the deque is empty, add the node as the head and tail - head = newNode; - tail = newNode; - } else { - // If the deque is not empty, insert the node as the new head - newNode.next = head; - head.prev = newNode; - head = newNode; - } - - size++; - } - - /** - * Adds the specified value to the tail of the deque - * - * @param val Value to add to the deque - */ - public void addLast(T val) { - // Create a new node with the given value - DequeNode newNode = new DequeNode(val); - - // Add the node - if (tail == null) { - // If the deque is empty, add the node as the head and tail - head = newNode; - tail = newNode; - } else { - // If the deque is not empty, insert the node as the new tail - newNode.prev = tail; - tail.next = newNode; - tail = newNode; - } - - size++; - } - - /** - * Removes and returns the first (head) value in the deque - * - * @return the value of the head of the deque - */ - public T pollFirst() { - // If the head is null, return null - if (head == null) return null; - - // First, let's get the value of the old head - T oldHeadVal = head.val; - - // Now, let's remove the head - if (head == tail) { - // If there is only one node, remove it - head = null; - tail = null; - } else { - // If there is more than one node, fix the references - head.next.prev = null; - DequeNode oldHead = head; - head = head.next; - - // Can be considered unnecessary... - // Unlinking the old head to make sure there are no random - // references possibly affecting garbage collection - oldHead.next = null; - } - - size--; - return oldHeadVal; - } - - /** - * Removes and returns the last (tail) value in the deque - * - * @return the value of the tail of the deque - */ - public T pollLast() { - // If the tail is null, return null - if (tail == null) return null; - - // Let's get the value of the old tail - T oldTailVal = tail.val; - - // Now, remove the tail - if (head == tail) { - // If there is only one node, remove it - head = null; - tail = null; - } else { - // If there is more than one node, fix the references - tail.prev.next = null; - DequeNode oldTail = tail; - tail = tail.prev; - - // Similarly to above, can be considered unnecessary - // See `pollFirst()` for explanation - oldTail.prev = null; - } - - size--; - return oldTailVal; - } - - /** - * Returns the first (head) value of the deque WITHOUT removing - * - * @return the value of the head of the deque - */ - public T peekFirst() { - return head.val; - } - - /** - * Returns the last (tail) value of the deque WITHOUT removing - * - * @return the value of the tail of the deque - */ - public T peekLast() { - return tail.val; - } - - /** - * Returns the size of the deque - * - * @return the size of the deque - */ - public int size() { - return size; - } - - /** - * Returns whether or not the deque is empty - * - * @return whether or not the deque is empty - */ - public boolean isEmpty() { - return head == null; - } - - /** - * Returns a stringified deque in a pretty form: - * - *

Head -> 1 <-> 2 <-> 3 <- Tail - * - * @return the stringified deque - */ - @Override - public String toString() { - String dequeString = "Head -> "; - DequeNode currNode = head; - while (currNode != null) { - dequeString += currNode.val; - - if (currNode.next != null) dequeString += " <-> "; - - currNode = currNode.next; - } - - dequeString += " <- Tail"; - - return dequeString; - } - - public static void main(String[] args) { - Deques myDeque = new Deques(); - for (int i = 0; i < 42; i++) { - if (i / 42.0 < 0.5) { - myDeque.addFirst(i); - } else { - myDeque.addLast(i); - } - } - - System.out.println(myDeque); - System.out.println("Size: " + myDeque.size()); - System.out.println(); - - myDeque.pollFirst(); - myDeque.pollFirst(); - myDeque.pollLast(); - System.out.println(myDeque); - System.out.println("Size: " + myDeque.size()); - System.out.println(); - - int dequeSize = myDeque.size(); - for (int i = 0; i < dequeSize; i++) { - int removing = -1; - if (i / 39.0 < 0.5) { - removing = myDeque.pollFirst(); - } else { - removing = myDeque.pollLast(); - } - - System.out.println("Removing: " + removing); - } - - System.out.println(myDeque); - System.out.println(myDeque.size()); - } -} diff --git a/DataStructures/Queues/GenericArrayListQueue.java b/DataStructures/Queues/GenericArrayListQueue.java deleted file mode 100644 index 9bd7e5602414..000000000000 --- a/DataStructures/Queues/GenericArrayListQueue.java +++ /dev/null @@ -1,83 +0,0 @@ -package DataStructures.Queues; - -import java.util.ArrayList; - -/** - * This class implements a GenericArrayListQueue. - * - * A GenericArrayListQueue data structure functions the same as any specific-typed queue. The - * GenericArrayListQueue holds elements of types to-be-specified at runtime. The elements that are - * added first are the first to be removed (FIFO). New elements are added to the back/rear of the - * queue. - */ -public class GenericArrayListQueue { - /** The generic ArrayList for the queue T is the generic element */ - ArrayList _queue = new ArrayList<>(); - - /** - * Checks if the queue has elements (not empty). - * - * @return True if the queue has elements. False otherwise. - */ - private boolean hasElements() { - return !_queue.isEmpty(); - } - - /** - * Checks what's at the front of the queue. - * - * @return If queue is not empty, element at the front of the queue. Otherwise, null - */ - public T peek() { - T result = null; - if (this.hasElements()) { - result = _queue.get(0); - } - return result; - } - - /** - * Inserts an element of type T to the queue. - * - * @param element of type T to be added - * @return True if the element was added successfully - */ - public boolean add(T element) { - return _queue.add(element); - } - - /** - * Retrieve what's at the front of the queue - * - * @return If queue is not empty, element retrieved. Otherwise, null - */ - public T pull() { - T result = null; - if (this.hasElements()) { - result = _queue.remove(0); - } - return result; - } - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String[] args) { - GenericArrayListQueue queue = new GenericArrayListQueue<>(); - System.out.println("Running..."); - assert queue.peek() == null; - assert queue.pull() == null; - assert queue.add(1); - assert queue.peek() == 1; - assert queue.add(2); - assert queue.peek() == 1; - assert queue.pull() == 1; - assert queue.peek() == 2; - assert queue.pull() == 2; - assert queue.peek() == null; - assert queue.pull() == null; - System.out.println("Finished."); - } -} diff --git a/DataStructures/Queues/LinkedQueue.java b/DataStructures/Queues/LinkedQueue.java deleted file mode 100644 index e3d693f50f3b..000000000000 --- a/DataStructures/Queues/LinkedQueue.java +++ /dev/null @@ -1,159 +0,0 @@ -package DataStructures.Queues; - -import java.util.NoSuchElementException; - -public class LinkedQueue { - class Node { - int data; - Node next; - - public Node() { - this(0); - } - - public Node(int data) { - this(data, null); - } - - public Node(int data, Node next) { - this.data = data; - this.next = next; - } - } - - /** Front of Queue */ - private Node front; - - /** Rear of Queue */ - private Node rear; - - /** Size of Queue */ - private int size; - - /** Init LinkedQueue */ - public LinkedQueue() { - front = rear = new Node(); - } - - /** - * Check if queue is empty - * - * @return true if queue is empty, otherwise false - */ - public boolean isEmpty() { - return size == 0; - } - - /** - * Add element to rear of queue - * - * @param data insert value - * @return true if add successfully - */ - public boolean enqueue(int data) { - Node newNode = new Node(data); - rear.next = newNode; - rear = newNode; /* make rear point at last node */ - size++; - return true; - } - - /** - * Remove element at the front of queue - * - * @return element at the front of queue - */ - public int dequeue() { - if (isEmpty()) { - throw new NoSuchElementException("queue is empty"); - } - Node destroy = front.next; - int retValue = destroy.data; - front.next = front.next.next; - destroy = null; /* clear let GC do it's work */ - size--; - - if (isEmpty()) { - front = rear; - } - - return retValue; - } - - /** - * Peek element at the front of queue without removing - * - * @return element at the front - */ - public int peekFront() { - if (isEmpty()) { - throw new NoSuchElementException("queue is empty"); - } - return front.next.data; - } - - /** - * Peek element at the rear of queue without removing - * - * @return element at the front - */ - public int peekRear() { - if (isEmpty()) { - throw new NoSuchElementException("queue is empty"); - } - return rear.data; - } - - /** - * Return size of queue - * - * @return size of queue - */ - public int size() { - return size; - } - - /** Clear all nodes in queue */ - public void clear() { - while (!isEmpty()) { - dequeue(); - } - } - - @Override - public String toString() { - if (isEmpty()) { - return "[]"; - } - StringBuilder builder = new StringBuilder(); - Node cur = front.next; - builder.append("["); - while (cur != null) { - builder.append(cur.data).append(", "); - cur = cur.next; - } - builder.replace(builder.length() - 2, builder.length(), "]"); - return builder.toString(); - } - - /* Driver Code */ - public static void main(String[] args) { - LinkedQueue queue = new LinkedQueue(); - assert queue.isEmpty(); - - queue.enqueue(1); /* 1 */ - queue.enqueue(2); /* 1 2 */ - queue.enqueue(3); /* 1 2 3 */ - System.out.println(queue); /* [1, 2, 3] */ - - assert queue.size() == 3; - assert queue.dequeue() == 1; - assert queue.peekFront() == 2; - assert queue.peekRear() == 3; - - queue.clear(); - assert queue.isEmpty(); - - System.out.println(queue); /* [] */ - } -} diff --git a/DataStructures/Queues/PriorityQueues.java b/DataStructures/Queues/PriorityQueues.java deleted file mode 100644 index bcdfb2ec7426..000000000000 --- a/DataStructures/Queues/PriorityQueues.java +++ /dev/null @@ -1,120 +0,0 @@ -package DataStructures.Queues; - -/** - * This class implements a PriorityQueue. - * - *

A priority queue adds elements into positions based on their priority. So the most important - * elements are placed at the front/on the top. In this example I give numbers that are bigger, a - * higher priority. Queues in theory have no fixed size but when using an array implementation it - * does. - */ -class PriorityQueue { - /** The max size of the queue */ - private int maxSize; - /** The array for the queue */ - private int[] queueArray; - /** How many items are in the queue */ - private int nItems; - - /** - * Constructor - * - * @param size Size of the queue - */ - public PriorityQueue(int size) { - maxSize = size; - queueArray = new int[size]; - nItems = 0; - } - - /** - * Inserts an element in it's appropriate place - * - * @param value Value to be inserted - */ - public void insert(int value) { - if (isFull()) { - throw new RuntimeException("Queue is full"); - } else { - int j = nItems - 1; // index of last element - while (j >= 0 && queueArray[j] > value) { - queueArray[j + 1] = queueArray[j]; // Shifts every element up to make room for insertion - j--; - } - queueArray[j + 1] = value; // Once the correct position is found the value is inserted - nItems++; - } - } - - /** - * Remove the element from the front of the queue - * - * @return The element removed - */ - public int remove() { - return queueArray[--nItems]; - } - - /** - * Checks what's at the front of the queue - * - * @return element at the front of the queue - */ - public int peek() { - return queueArray[nItems - 1]; - } - - /** - * Returns true if the queue is empty - * - * @return true if the queue is empty - */ - public boolean isEmpty() { - return (nItems == 0); - } - - /** - * Returns true if the queue is full - * - * @return true if the queue is full - */ - public boolean isFull() { - return (nItems == maxSize); - } - - /** - * Returns the number of elements in the queue - * - * @return number of elements in the queue - */ - public int getSize() { - return nItems; - } -} - -/** - * This class implements the PriorityQueue class above. - * - * @author Unknown - */ -public class PriorityQueues { - /** - * Main method - * - * @param args Command Line Arguments - */ - public static void main(String[] args) { - PriorityQueue myQueue = new PriorityQueue(4); - myQueue.insert(10); - myQueue.insert(2); - myQueue.insert(5); - myQueue.insert(3); - // [2, 3, 5, 10] Here higher numbers have higher priority, so they are on the top - - for (int i = 3; i >= 0; i--) - System.out.print( - myQueue.remove() + " "); // will print the queue in reverse order [10, 5, 3, 2] - - // As you can see, a Priority Queue can be used as a sorting algotithm - } -} diff --git a/DataStructures/Queues/Queues.java b/DataStructures/Queues/Queues.java deleted file mode 100644 index 52d8510ae328..000000000000 --- a/DataStructures/Queues/Queues.java +++ /dev/null @@ -1,163 +0,0 @@ -package DataStructures.Queues; - -/** - * This implements Queues by using the class Queue. - * - * A queue data structure functions the same as a real world queue. The elements that are added - * first are the first to be removed. New elements are added to the back/rear of the queue. - */ -class Queue { - /** Default initial capacity. */ - private static final int DEFAULT_CAPACITY = 10; - - /** Max size of the queue */ - private int maxSize; - /** The array representing the queue */ - private int[] queueArray; - /** Front of the queue */ - private int front; - /** Rear of the queue */ - private int rear; - /** How many items are in the queue */ - private int nItems; - - /** init with DEFAULT_CAPACITY */ - public Queue() { - this(DEFAULT_CAPACITY); - } - - /** - * Constructor - * - * @param size Size of the new queue - */ - public Queue(int size) { - maxSize = size; - queueArray = new int[size]; - front = 0; - rear = -1; - nItems = 0; - } - - /** - * Inserts an element at the rear of the queue - * - * @param x element to be added - * @return True if the element was added successfully - */ - public boolean insert(int x) { - if (isFull()) return false; - // If the back of the queue is the end of the array wrap around to the front - rear = (rear + 1) % maxSize; - queueArray[rear] = x; - nItems++; - return true; - } - - /** - * Remove an element from the front of the queue - * - * @return the new front of the queue - */ - public int remove() { - if (isEmpty()) { - return -1; - } - int temp = queueArray[front]; - front = (front + 1) % maxSize; - nItems--; - return temp; - } - - /** - * Checks what's at the front of the queue - * - * @return element at the front of the queue - */ - public int peekFront() { - return queueArray[front]; - } - - /** - * Checks what's at the rear of the queue - * - * @return element at the rear of the queue - */ - public int peekRear() { - return queueArray[rear]; - } - - /** - * Returns true if the queue is empty - * - * @return true if the queue is empty - */ - public boolean isEmpty() { - return nItems == 0; - } - - /** - * Returns true if the queue is full - * - * @return true if the queue is full - */ - public boolean isFull() { - return nItems == maxSize; - } - - /** - * Returns the number of elements in the queue - * - * @return number of elements in the queue - */ - public int getSize() { - return nItems; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("["); - for (int i = front; ; i = ++i % maxSize) { - sb.append(queueArray[i]).append(", "); - if (i == rear) { - break; - } - } - sb.replace(sb.length() - 2, sb.length(), "]"); - return sb.toString(); - } -} - -/** - * This class is the example for the Queue class - * - * @author Unknown - */ -public class Queues { - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String[] args) { - Queue myQueue = new Queue(4); - myQueue.insert(10); - myQueue.insert(2); - myQueue.insert(5); - myQueue.insert(3); - // [10(front), 2, 5, 3(rear)] - - System.out.println(myQueue.isFull()); // Will print true - - myQueue.remove(); // Will make 2 the new front, making 10 no longer part of the queue - // [10, 2(front), 5, 3(rear)] - - myQueue.insert(7); // Insert 7 at the rear which will get 0 index because of wrap around - // [7(rear), 2(front), 5, 3] - - System.out.println(myQueue.peekFront()); // Will print 2 - System.out.println(myQueue.peekRear()); // Will print 7 - System.out.println(myQueue.toString()); // Will print [2, 5, 3, 7] - } -} diff --git a/DataStructures/Stacks/BalancedBrackets.java b/DataStructures/Stacks/BalancedBrackets.java deleted file mode 100644 index 6b8efce6d7a2..000000000000 --- a/DataStructures/Stacks/BalancedBrackets.java +++ /dev/null @@ -1,78 +0,0 @@ -package DataStructures.Stacks; - -import java.util.Stack; - -/** - * The nested brackets problem is a problem that determines if a sequence of brackets are properly - * nested. A sequence of brackets s is considered properly nested if any of the following conditions - * are true: - s is empty - s has the form (U) or [U] or {U} where U is a properly nested string - s - * has the form VW where V and W are properly nested strings For example, the string "()()[()]" is - * properly nested but "[(()]" is not. The function called is_balanced takes as input a string S - * which is a sequence of brackets and returns true if S is nested and false otherwise. - * - * @author akshay sharma - * @author khalil2535 - * @author shellhub - */ -class BalancedBrackets { - - /** - * Check if {@code leftBracket} and {@code rightBracket} is paired or not - * - * @param leftBracket left bracket - * @param rightBracket right bracket - * @return {@code true} if {@code leftBracket} and {@code rightBracket} is paired, otherwise - * {@code false} - */ - public static boolean isPaired(char leftBracket, char rightBracket) { - char[][] pairedBrackets = { - {'(', ')'}, - {'[', ']'}, - {'{', '}'}, - {'<', '>'} - }; - for (char[] pairedBracket : pairedBrackets) { - if (pairedBracket[0] == leftBracket && pairedBracket[1] == rightBracket) { - return true; - } - } - return false; - } - - /** - * Check if {@code brackets} is balanced - * - * @param brackets the brackets - * @return {@code true} if {@code brackets} is balanced, otherwise {@code false} - */ - public static boolean isBalanced(String brackets) { - if (brackets == null) { - throw new IllegalArgumentException("brackets is null"); - } - Stack 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 */ - return false; - } - } - return bracketsStack.isEmpty(); - } - - public static void main(String[] args) { - assert isBalanced("[()]{}{[()()]()}"); - assert !isBalanced("[(])"); - } -} diff --git a/DataStructures/Stacks/DecimalToAnyUsingStack.java b/DataStructures/Stacks/DecimalToAnyUsingStack.java deleted file mode 100644 index d0fa7d5ba93b..000000000000 --- a/DataStructures/Stacks/DecimalToAnyUsingStack.java +++ /dev/null @@ -1,42 +0,0 @@ -package DataStructures.Stacks; - -import java.util.Stack; - -public class DecimalToAnyUsingStack { - public static void main(String[] args) { - assert convert(0, 2).equals("0"); - assert convert(30, 2).equals("11110"); - assert convert(30, 8).equals("36"); - assert convert(30, 10).equals("30"); - assert convert(30, 16).equals("1E"); - } - - /** - * Convert decimal number to another radix - * - * @param number the number to be converted - * @param radix the radix - * @return another radix - * @throws ArithmeticException if number or radius is invalid - */ - 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)); - } - char[] tables = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' - }; - Stack bits = new Stack<>(); - do { - bits.push(tables[number % radix]); - number = number / radix; - } while (number != 0); - - StringBuilder result = new StringBuilder(); - while (!bits.isEmpty()) { - result.append(bits.pop()); - } - return result.toString(); - } -} diff --git a/DataStructures/Stacks/InfixToPostfix.java b/DataStructures/Stacks/InfixToPostfix.java deleted file mode 100644 index 862c0150d136..000000000000 --- a/DataStructures/Stacks/InfixToPostfix.java +++ /dev/null @@ -1,55 +0,0 @@ -package DataStructures.Stacks; - -import java.util.Stack; - -public class InfixToPostfix { - public static void main(String[] args) throws Exception { - assert "32+".equals(infix2PostFix("3+2")); - assert "123++".equals(infix2PostFix("1+(2+3)")); - assert "34+5*6-".equals(infix2PostFix("(3+4)*5-6")); - } - - public static String infix2PostFix(String infixExpression) throws Exception { - if (!BalancedBrackets.isBalanced(infixExpression)) { - throw new Exception("invalid expression"); - } - StringBuilder output = new StringBuilder(); - Stack stack = new Stack<>(); - for (char element : infixExpression.toCharArray()) { - if (Character.isLetterOrDigit(element)) { - output.append(element); - } else if (element == '(') { - stack.push(element); - } else if (element == ')') { - while (!stack.isEmpty() && stack.peek() != '(') { - output.append(stack.pop()); - } - stack.pop(); - } else { - while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) { - output.append(stack.pop()); - } - stack.push(element); - } - } - while (!stack.isEmpty()) { - output.append(stack.pop()); - } - return output.toString(); - } - - private static int precedence(char operator) { - switch (operator) { - case '+': - case '-': - return 0; - case '*': - case '/': - return 1; - case '^': - return 2; - default: - return -1; - } - } -} diff --git a/DataStructures/Stacks/NodeStack.java b/DataStructures/Stacks/NodeStack.java deleted file mode 100644 index 623068dcb1e3..000000000000 --- a/DataStructures/Stacks/NodeStack.java +++ /dev/null @@ -1,171 +0,0 @@ -package DataStructures.Stacks; -/** - * Implementation of a stack using nodes. Unlimited size, no arraylist. - * - * @author Kyler Smith, 2017 - */ -public class NodeStack { - - /** Entry point for the program. */ - public static void main(String[] args) { - NodeStack Stack = new NodeStack(); - - Stack.push(3); - Stack.push(4); - Stack.push(5); - System.out.println("Testing :"); - Stack.print(); // prints : 5 4 3 - - Integer x = Stack.pop(); // x = 5 - Stack.push(1); - Stack.push(8); - Integer y = Stack.peek(); // y = 8 - System.out.println("Testing :"); - Stack.print(); // prints : 8 1 4 3 - - System.out.println("Testing :"); - System.out.println("x : " + x); - System.out.println("y : " + y); - } - - /** - * Information each node should contain. - * - * @value data : information of the value in the node - * @value head : the head of the stack - * @value next : the next value from this node - * @value previous : the last value from this node - * @value size : size of the stack - */ - private Item data; - - private static NodeStack head; - private NodeStack next; - private NodeStack previous; - private static int size = 0; - - /** Constructors for the NodeStack. */ - public NodeStack() {} - - private NodeStack(Item item) { - this.data = item; - } - - /** - * Put a value onto the stack. - * - * @param item : value to be put on the stack. - */ - public void push(Item item) { - - NodeStack newNs = new NodeStack(item); - - if (this.isEmpty()) { - NodeStack.setHead(new NodeStack<>(item)); - newNs.setNext(null); - newNs.setPrevious(null); - } else { - newNs.setPrevious(NodeStack.head); - NodeStack.head.setNext(newNs); - NodeStack.head.setHead(newNs); - } - - NodeStack.setSize(NodeStack.getSize() + 1); - } - - /** - * Value to be taken off the stack. - * - * @return item : value that is returned. - */ - public Item pop() { - - Item item = (Item) NodeStack.head.getData(); - - NodeStack.head.setHead(NodeStack.head.getPrevious()); - NodeStack.head.setNext(null); - - NodeStack.setSize(NodeStack.getSize() - 1); - - return item; - } - - /** - * Value that is next to be taken off the stack. - * - * @return item : the next value that would be popped off the stack. - */ - public Item peek() { - return (Item) NodeStack.head.getData(); - } - - /** - * If the stack is empty or there is a value in. - * - * @return boolean : whether or not the stack has anything in it. - */ - public boolean isEmpty() { - return NodeStack.getSize() == 0; - } - - /** - * Returns the size of the stack. - * - * @return int : number of values in the stack. - */ - public int size() { - return NodeStack.getSize(); - } - - /** - * Print the contents of the stack in the following format. - * - *

x <- head (next out) y z <- tail (first in) . . . - */ - public void print() { - for (NodeStack n = NodeStack.head; n != null; n = n.previous) { - System.out.println(n.getData().toString()); - } - } - - /** Getters and setters (private) */ - private NodeStack getHead() { - return NodeStack.head; - } - - private static void setHead(NodeStack ns) { - NodeStack.head = ns; - } - - private NodeStack getNext() { - return next; - } - - private void setNext(NodeStack next) { - this.next = next; - } - - private NodeStack getPrevious() { - return previous; - } - - private void setPrevious(NodeStack previous) { - this.previous = previous; - } - - private static int getSize() { - return size; - } - - private static void setSize(int size) { - NodeStack.size = size; - } - - private Item getData() { - return this.data; - } - - private void setData(Item item) { - this.data = item; - } -} diff --git a/DataStructures/Stacks/StackArray.java b/DataStructures/Stacks/StackArray.java deleted file mode 100644 index 77f65e493c6e..000000000000 --- a/DataStructures/Stacks/StackArray.java +++ /dev/null @@ -1,158 +0,0 @@ -package DataStructures.Stacks; - -/** - * This class implements a Stack using a regular array. - * - *

A stack is exactly what it sounds like. An element gets added to the top of the stack and only - * the element on the top may be removed. This is an example of an array implementation of a Stack. - * So an element can only be added/removed from the end of the array. In theory stack have no fixed - * size, but with an array implementation it does. - */ -public class StackArray { - - /** Driver Code */ - public static void main(String[] args) { - // Declare a stack of maximum size 4 - StackArray myStackArray = new StackArray(4); - - assert myStackArray.isEmpty(); - assert !myStackArray.isFull(); - - // Populate the stack - myStackArray.push(5); - myStackArray.push(8); - myStackArray.push(2); - myStackArray.push(9); - - assert !myStackArray.isEmpty(); - assert myStackArray.isFull(); - assert myStackArray.peek() == 9; - assert myStackArray.pop() == 9; - assert myStackArray.peek() == 2; - assert myStackArray.size() == 3; - } - - /** Default initial capacity. */ - private static final int DEFAULT_CAPACITY = 10; - - /** The max size of the Stack */ - private int maxSize; - - /** The array representation of the Stack */ - private int[] stackArray; - - /** The top of the stack */ - private int top; - - /** init Stack with DEFAULT_CAPACITY */ - public StackArray() { - this(DEFAULT_CAPACITY); - } - - /** - * Constructor - * - * @param size Size of the Stack - */ - public StackArray(int size) { - maxSize = size; - stackArray = new int[maxSize]; - top = -1; - } - - /** - * Adds an element to the top of the stack - * - * @param value The element added - */ - public void push(int value) { - if (!isFull()) { // Checks for a full stack - top++; - stackArray[top] = value; - } else { - resize(maxSize * 2); - push(value); // don't forget push after resizing - } - } - - /** - * Removes the top element of the stack and returns the value you've removed - * - * @return value popped off the Stack - */ - public int pop() { - if (!isEmpty()) { // Checks for an empty stack - return stackArray[top--]; - } - - if (top < maxSize / 4) { - resize(maxSize / 2); - return pop(); // don't forget pop after resizing - } else { - System.out.println("The stack is already empty"); - return -1; - } - } - - /** - * Returns the element at the top of the stack - * - * @return element at the top of the stack - */ - public int peek() { - if (!isEmpty()) { // Checks for an empty stack - return stackArray[top]; - } else { - System.out.println("The stack is empty, cant peek"); - return -1; - } - } - - private void resize(int newSize) { - int[] transferArray = new int[newSize]; - - for (int i = 0; i < stackArray.length; i++) { - transferArray[i] = stackArray[i]; - } - // This reference change might be nice in here - stackArray = transferArray; - maxSize = newSize; - } - - /** - * Returns true if the stack is empty - * - * @return true if the stack is empty - */ - public boolean isEmpty() { - return (top == -1); - } - - /** - * Returns true if the stack is full - * - * @return true if the stack is full - */ - public boolean isFull() { - return (top + 1 == maxSize); - } - - /** - * Deletes everything in the Stack - * - *

Doesn't delete elements in the array but if you call push method after calling makeEmpty it - * will overwrite previous values - */ - public void makeEmpty() { // Doesn't delete elements in the array but if you call - top = -1; // push method after calling makeEmpty it will overwrite previous values - } - - /** - * Return size of stack - * - * @return size of stack - */ - public int size() { - return top + 1; - } -} diff --git a/DataStructures/Stacks/StackArrayList.java b/DataStructures/Stacks/StackArrayList.java deleted file mode 100644 index c9b31d625dd9..000000000000 --- a/DataStructures/Stacks/StackArrayList.java +++ /dev/null @@ -1,105 +0,0 @@ -package DataStructures.Stacks; - -import java.util.ArrayList; -import java.util.EmptyStackException; - -/** - * This class implements a Stack using an ArrayList. - * - *

A stack is exactly what it sounds like. An element gets added to the top of the stack and only - * the element on the top may be removed. - * - *

This is an ArrayList Implementation of a stack, where size is not a problem we can extend the - * stack as much as we want. - */ -public class StackArrayList { - - /** Driver Code */ - public static void main(String[] args) { - StackArrayList stack = new StackArrayList(); - assert stack.isEmpty(); - - for (int i = 1; i <= 5; ++i) { - stack.push(i); - assert stack.size() == i; - } - - assert stack.size() == 5; - assert stack.peek() == 5 && stack.pop() == 5 && stack.peek() == 4; - - /* pop elements at the top of this stack one by one */ - while (!stack.isEmpty()) { - stack.pop(); - } - assert stack.isEmpty(); - - try { - stack.pop(); - assert false; /* this should not happen */ - } catch (EmptyStackException e) { - assert true; /* this should happen */ - } - } - - /** ArrayList representation of the stack */ - private ArrayList stack; - - /** Constructor */ - public StackArrayList() { - stack = new ArrayList<>(); - } - - /** - * Adds value to the end of list which is the top for stack - * - * @param value value to be added - */ - public void push(int value) { - stack.add(value); - } - - /** - * Removes the element at the top of this stack and returns - * - * @return Element popped - * @throws EmptyStackException if the stack is empty. - */ - public int pop() { - if (isEmpty()) { - throw new EmptyStackException(); - } - - /* remove the element on the top of the stack */ - return stack.remove(stack.size() - 1); - } - - /** - * Test if the stack is empty. - * - * @return {@code true} if this stack is empty, {@code false} otherwise. - */ - public boolean isEmpty() { - return stack.isEmpty(); - } - - /** - * Return the element at the top of this stack without removing it from the stack. - * - * @return the element at the top of this stack. - */ - public int peek() { - if (isEmpty()) { - throw new EmptyStackException(); - } - return stack.get(stack.size() - 1); - } - - /** - * Return size of this stack. - * - * @return size of this stack. - */ - public int size() { - return stack.size(); - } -} diff --git a/DataStructures/Stacks/StackOfLinkedList.java b/DataStructures/Stacks/StackOfLinkedList.java deleted file mode 100644 index 39e1f5275161..000000000000 --- a/DataStructures/Stacks/StackOfLinkedList.java +++ /dev/null @@ -1,135 +0,0 @@ -package DataStructures.Stacks; - -import java.util.NoSuchElementException; - -/** @author Varun Upadhyay (https://github.com/varunu28) */ - -// An implementation of a Stack using a Linked List - -class StackOfLinkedList { - - public static void main(String[] args) { - - LinkedListStack stack = new LinkedListStack(); - stack.push(1); - stack.push(2); - stack.push(3); - stack.push(4); - stack.push(5); - - System.out.println(stack); - - System.out.println("Size of stack currently is: " + stack.getSize()); - - assert stack.pop() == 5; - assert stack.pop() == 4; - - System.out.println("Top element of stack currently is: " + stack.peek()); - } -} - -// A node class - -class Node { - public int data; - public Node next; - - public Node(int data) { - this.data = data; - this.next = null; - } -} - -/** - * A class which implements a stack using a linked list - * - *

Contains all the stack methods : push, pop, printStack, isEmpty - */ -class LinkedListStack { - - /** Top of stack */ - Node head; - - /** Size of stack */ - private int size; - - /** Init properties */ - public LinkedListStack() { - head = null; - size = 0; - } - - /** - * Add element at top - * - * @param x to be added - * @return true if add successfully - */ - public boolean push(int x) { - Node newNode = new Node(x); - newNode.next = head; - head = newNode; - size++; - return true; - } - - /** - * Pop element at top of stack - * - * @return element at top of stack - * @throws NoSuchElementException if stack is empty - */ - public int pop() { - if (size == 0) { - throw new NoSuchElementException("Empty stack. Nothing to pop"); - } - Node destroy = head; - head = head.next; - int retValue = destroy.data; - destroy = null; // clear to let GC do it's work - size--; - return retValue; - } - - /** - * Peek element at top of stack - * - * @return element at top of stack - * @throws NoSuchElementException if stack is empty - */ - public int peek() { - if (size == 0) { - throw new NoSuchElementException("Empty stack. Nothing to pop"); - } - return head.data; - } - - @Override - public String toString() { - Node cur = head; - StringBuilder builder = new StringBuilder(); - while (cur != null) { - builder.append(cur.data).append("->"); - cur = cur.next; - } - return builder.replace(builder.length() - 2, builder.length(), "").toString(); - } - - /** - * Check if stack is empty - * - * @return true if stack is empty, otherwise false - */ - public boolean isEmpty() { - return size == 0; - } - - /** - * Return size of stack - * - * @return size of stack - */ - public int getSize() { - return size; - } -} diff --git a/DataStructures/Trees/AVLTree.java b/DataStructures/Trees/AVLTree.java deleted file mode 100644 index 52121a56a5ca..000000000000 --- a/DataStructures/Trees/AVLTree.java +++ /dev/null @@ -1,224 +0,0 @@ -package DataStructures.Trees; - -public class AVLTree { - - private Node root; - - private class Node { - private int key; - private int balance; - private int height; - private Node left, right, parent; - - Node(int k, Node p) { - key = k; - parent = p; - } - } - - public boolean insert(int key) { - if (root == null) root = new Node(key, null); - else { - Node n = root; - Node parent; - while (true) { - if (n.key == key) return false; - - parent = n; - - boolean goLeft = n.key > key; - n = goLeft ? n.left : n.right; - - if (n == null) { - if (goLeft) { - parent.left = new Node(key, parent); - } else { - parent.right = new Node(key, parent); - } - rebalance(parent); - break; - } - } - } - return true; - } - - private void delete(Node node) { - if (node.left == null && node.right == null) { - if (node.parent == null) root = null; - else { - Node parent = node.parent; - if (parent.left == node) { - parent.left = null; - } else parent.right = null; - rebalance(parent); - } - return; - } - if (node.left != null) { - Node child = node.left; - while (child.right != null) child = child.right; - node.key = child.key; - delete(child); - } else { - Node child = node.right; - while (child.left != null) child = child.left; - node.key = child.key; - delete(child); - } - } - - public void delete(int delKey) { - if (root == null) return; - Node node = root; - Node child = root; - - while (child != null) { - node = child; - child = delKey >= node.key ? node.right : node.left; - if (delKey == node.key) { - delete(node); - return; - } - } - } - - private void rebalance(Node n) { - setBalance(n); - - if (n.balance == -2) { - if (height(n.left.left) >= height(n.left.right)) n = rotateRight(n); - else n = rotateLeftThenRight(n); - - } else if (n.balance == 2) { - if (height(n.right.right) >= height(n.right.left)) n = rotateLeft(n); - else n = rotateRightThenLeft(n); - } - - if (n.parent != null) { - rebalance(n.parent); - } else { - root = n; - } - } - - private Node rotateLeft(Node a) { - - Node b = a.right; - b.parent = a.parent; - - a.right = b.left; - - if (a.right != null) a.right.parent = a; - - b.left = a; - a.parent = b; - - if (b.parent != null) { - if (b.parent.right == a) { - b.parent.right = b; - } else { - b.parent.left = b; - } - } - - setBalance(a, b); - - return b; - } - - private Node rotateRight(Node a) { - - Node b = a.left; - b.parent = a.parent; - - a.left = b.right; - - if (a.left != null) a.left.parent = a; - - b.right = a; - a.parent = b; - - if (b.parent != null) { - if (b.parent.right == a) { - b.parent.right = b; - } else { - b.parent.left = b; - } - } - - setBalance(a, b); - - return b; - } - - private Node rotateLeftThenRight(Node n) { - n.left = rotateLeft(n.left); - return rotateRight(n); - } - - private Node rotateRightThenLeft(Node n) { - n.right = rotateRight(n.right); - return rotateLeft(n); - } - - private int height(Node n) { - if (n == null) return -1; - return n.height; - } - - private void setBalance(Node... nodes) { - for (Node n : nodes) { - reheight(n); - n.balance = height(n.right) - height(n.left); - } - } - - public void printBalance() { - printBalance(root); - } - - private void printBalance(Node n) { - if (n != null) { - printBalance(n.left); - System.out.printf("%s ", n.balance); - printBalance(n.right); - } - } - - private void reheight(Node node) { - if (node != null) { - node.height = 1 + Math.max(height(node.left), height(node.right)); - } - } - - public boolean search(int key) { - Node result = searchHelper(this.root, key); - if (result != null) return true; - - return false; - } - - private Node searchHelper(Node root, int key) { - // root is null or key is present at root - if (root == null || root.key == key) return root; - - // key is greater than root's key - if (root.key > key) - return searchHelper(root.left, key); // call the function on the node's left child - - // key is less than root's key then - // call the function on the node's right child as it is greater - return searchHelper(root.right, key); - } - - public static void main(String[] args) { - AVLTree tree = new AVLTree(); - - System.out.println("Inserting values 1 to 10"); - for (int i = 1; i < 10; i++) tree.insert(i); - - System.out.print("Printing balance: "); - tree.printBalance(); - } -} diff --git a/DataStructures/Trees/BSTIterative.java b/DataStructures/Trees/BSTIterative.java deleted file mode 100644 index 7cf283db95bb..000000000000 --- a/DataStructures/Trees/BSTIterative.java +++ /dev/null @@ -1,289 +0,0 @@ -package DataStructures.Trees; - -/** - * - * - *

Binary Search Tree (Iterative)

- * - *

An implementation of BST iteratively. Binary Search Tree is a binary tree which satisfies - * three properties: left child is less than root node, right child is grater than root node, both - * left and right childs must themselves be a BST. - * - * @author [Lakhan Nad](https://github.com/Lakhan-Nad) - */ -import java.util.Stack; - -public class BSTIterative { - /** Reference for the node of BST. */ - private Node root; - - /** Default Constructor Initializes the root of BST with null. */ - BSTIterative() { - root = null; - } - - /** main function for tests */ - public static void main(String[] args) { - BSTIterative tree = new BSTIterative(); - tree.add(3); - tree.add(2); - tree.add(9); - assert !tree.find(4) : "4 is not yet present in BST"; - assert tree.find(2) : "2 should be present in BST"; - tree.remove(2); - assert !tree.find(2) : "2 was just deleted from BST"; - tree.remove(1); - assert !tree.find(1) : "Since 1 was not present so find deleting would do no change"; - tree.add(30); - tree.add(40); - assert tree.find(40) : "40 was inserted but not found"; - /* - Will print following order - 3 9 30 40 - */ - tree.inorder(); - } - - /** - * A method to insert a new value in BST. If the given value is already present in BST the - * insertion is ignored. - * - * @param data the value to be inserted - */ - public void add(int data) { - Node parent = null; - Node temp = this.root; - int rightOrLeft = -1; - /* Finds the proper place this node can - * be placed in according to rules of BST. - */ - while (temp != null) { - if (temp.data > data) { - parent = temp; - temp = parent.left; - rightOrLeft = 0; - } else if (temp.data < data) { - parent = temp; - temp = parent.right; - rightOrLeft = 1; - } else { - System.out.println(data + " is already present in BST."); - return; // if data already present we ignore insertion - } - } - /* Creates a newNode with the value passed - * Since this data doesn't already exists - */ - Node newNode = new Node(data); - /* If the parent node is null - * then the insertion is to be done in - * root itself. - */ - if (parent == null) { - this.root = newNode; - } else { - /* Check if insertion is to be made in - * left or right subtree. - */ - if (rightOrLeft == 0) { - parent.left = newNode; - } else { - parent.right = newNode; - } - } - } - - /** - * A method to delete the node in BST. If node is present it will be deleted - * - * @param data the value that needs to be deleted - */ - public void remove(int data) { - Node parent = null; - Node temp = this.root; - int rightOrLeft = -1; - /* Find the parent of the node and node itself - * That is to be deleted. - * parent variable store parent - * temp stores node itself. - * rightOrLeft use to keep track weather child - * is left or right subtree - */ - while (temp != null) { - if (temp.data == data) { - break; - } else if (temp.data > data) { - parent = temp; - temp = parent.left; - rightOrLeft = 0; - } else { - parent = temp; - temp = parent.right; - rightOrLeft = 1; - } - } - /* If temp is null than node with given value is not - * present in our tree. - */ - if (temp != null) { - Node replacement; // used to store the new values for replacing nodes - if (temp.right == null && temp.left == null) { // Leaf node Case - replacement = null; - } else if (temp.right == null) { // Node with only right child - replacement = temp.left; - temp.left = null; - } else if (temp.left == null) { // Node with only left child - replacement = temp.right; - temp.right = null; - } else { - /* If both left and right child are present - * we replace this nodes data with - * leftmost node's data in its right subtree - * to maintain the balance of BST. - * And then delete that node - */ - if (temp.right.left == null) { - temp.data = temp.right.data; - replacement = temp; - temp.right = temp.right.right; - } else { - Node parent2 = temp.right; - Node child = temp.right.left; - while (child.left != null) { - parent2 = child; - child = parent2.left; - } - temp.data = child.data; - parent2.left = child.right; - replacement = temp; - } - } - /* Change references of parent after - * deleting the child. - */ - if (parent == null) { - this.root = replacement; - } else { - if (rightOrLeft == 0) { - parent.left = replacement; - } else { - parent.right = replacement; - } - } - } - } - - /** A method for inorder traversal of BST. */ - public void inorder() { - if (this.root == null) { - System.out.println("This BST is empty."); - return; - } - System.out.println("Inorder traversal of this tree is:"); - Stack st = new Stack(); - Node cur = this.root; - while (cur != null || !st.empty()) { - while (cur != null) { - st.push(cur); - cur = cur.left; - } - cur = st.pop(); - System.out.print(cur.data + " "); - cur = cur.right; - } - System.out.println(); // for next line - } - - /** A method used to print postorder traversal of BST. */ - public void postorder() { - if (this.root == null) { - System.out.println("This BST is empty."); - return; - } - System.out.println("Postorder traversal of this tree is:"); - Stack st = new Stack(); - Node cur = this.root, temp2; - while (cur != null || !st.empty()) { - if (cur != null) { - st.push(cur); - cur = cur.left; - } else { - temp2 = st.peek(); - if (temp2.right != null) { - cur = temp2.right; - } else { - st.pop(); - while (!st.empty() && st.peek().right == temp2) { - System.out.print(temp2.data + " "); - temp2 = st.pop(); - } - System.out.print(temp2.data + " "); - } - } - } - System.out.println(); // for next line - } - - /** Method used to display preorder traversal of BST. */ - public void preorder() { - if (this.root == null) { - System.out.println("This BST is empty."); - return; - } - System.out.println("Preorder traversal of this tree is:"); - Stack st = new Stack(); - st.push(this.root); - Node temp; - while (!st.empty()) { - temp = st.pop(); - System.out.print(temp.data + " "); - if (temp.right != null) { - st.push(temp.right); - } - if (temp.left != null) { - st.push(temp.left); - } - } - System.out.println(); // for next line - } - - /** - * A method to check if given data exists in out Binary Search Tree. - * - * @param data the value that needs to be searched for - * @return boolean representing if the value was find - */ - public boolean find(int data) { - Node temp = this.root; - /* Check if node exists - */ - while (temp != null) { - if (temp.data > data) { - temp = temp.left; - } else if (temp.data < data) { - temp = temp.right; - } else { - /* If found return true - */ - System.out.println(data + " is present in the BST."); - return true; - } - } - System.out.println(data + " not found."); - return false; - } - - /** The Node class used for building binary search tree */ - private static class Node { - int data; - Node left; - Node right; - - /** Constructor with data as parameter */ - Node(int d) { - data = d; - left = null; - right = null; - } - } -} diff --git a/DataStructures/Trees/BSTRecursive.java b/DataStructures/Trees/BSTRecursive.java deleted file mode 100644 index 3802ceb4285e..000000000000 --- a/DataStructures/Trees/BSTRecursive.java +++ /dev/null @@ -1,244 +0,0 @@ -package DataStructures.Trees; - -/** - * - * - *

Binary Search Tree (Recursive)

- * - * An implementation of BST recursively. In recursive implementation the checks are down the tree - * First root is checked if not found then its childs are checked Binary Search Tree is a binary - * tree which satisfies three properties: left child is less than root node, right child is grater - * than root node, both left and right childs must themselves be a BST. - * - *

I have made public functions as methods and to actually implement recursive approach I have - * used private methods - * - * @author [Lakhan Nad](https://github.com/Lakhan-Nad) - */ -public class BSTRecursive { - /** only data member is root of BST */ - private Node root; - - /** Constructor use to initialize node as null */ - BSTRecursive() { - root = null; - } - - /** main function for tests */ - public static void main(String[] args) { - BSTRecursive tree = new BSTRecursive(); - tree.add(5); - tree.add(10); - tree.add(9); - assert !tree.find(4) : "4 is not yet present in BST"; - assert tree.find(10) : "10 should be present in BST"; - tree.remove(9); - assert !tree.find(9) : "9 was just deleted from BST"; - tree.remove(1); - assert !tree.find(1) : "Since 1 was not present so find deleting would do no change"; - tree.add(20); - tree.add(70); - assert tree.find(70) : "70 was inserted but not found"; - /* - Will print in following order - 5 10 20 70 - */ - tree.inorder(); - } - - /** - * Recursive method to delete a data if present in BST. - * - * @param node the current node to search for data - * @param data the value to be deleted - * @return Node the updated value of root parameter after delete operation - */ - private Node delete(Node node, int data) { - if (node == null) { - System.out.println("No such data present in BST."); - } else if (node.data > data) { - node.left = delete(node.left, data); - } else if (node.data < data) { - node.right = delete(node.right, data); - } else { - if (node.right == null && node.left == null) { // If it is leaf node - node = null; - } else if (node.left == null) { // If only right node is present - Node temp = node.right; - node.right = null; - node = temp; - } else if (node.right == null) { // Only left node is present - Node temp = node.left; - node.left = null; - node = temp; - } else { // both child are present - Node temp = node.right; - // Find leftmost child of right subtree - while (temp.left != null) { - temp = temp.left; - } - node.data = temp.data; - node.right = delete(node.right, temp.data); - } - } - return node; - } - - /** - * Recursive insertion of value in BST. - * - * @param node to check if the data can be inserted in current node or its subtree - * @param data the value to be inserted - * @return the modified value of the root parameter after insertion - */ - private Node insert(Node node, int data) { - if (node == null) { - node = new Node(data); - } else if (node.data > data) { - node.left = insert(node.left, data); - } else if (node.data < data) { - node.right = insert(node.right, data); - } - return node; - } - - /** - * Recursively print Preorder traversal of the BST - * - * @param node the root node - */ - private void preOrder(Node node) { - if (node == null) { - return; - } - System.out.print(node.data + " "); - if (node.left != null) { - preOrder(node.left); - } - if (node.right != null) { - preOrder(node.right); - } - } - - /** - * Recursively print Postorder travesal of BST. - * - * @param node the root node - */ - private void postOrder(Node node) { - if (node == null) { - return; - } - if (node.left != null) { - postOrder(node.left); - } - if (node.right != null) { - postOrder(node.right); - } - System.out.print(node.data + " "); - } - - /** - * Recursively print Inorder traversal of BST. - * - * @param node the root node - */ - private void inOrder(Node node) { - if (node == null) { - return; - } - if (node.left != null) { - inOrder(node.left); - } - System.out.print(node.data + " "); - if (node.right != null) { - inOrder(node.right); - } - } - - /** - * Serach recursively if the given value is present in BST or not. - * - * @param node the current node to check - * @param data the value to be checked - * @return boolean if data is present or not - */ - private boolean search(Node node, int data) { - if (node == null) { - return false; - } else if (node.data == data) { - return true; - } else if (node.data > data) { - return search(node.left, data); - } else { - return search(node.right, data); - } - } - - /** - * add in BST. if the value is not already present it is inserted or else no change takes place. - * - * @param data the value to be inserted - */ - public void add(int data) { - this.root = insert(this.root, data); - } - - /** - * If data is present in BST delete it else do nothing. - * - * @param data the value to be removed - */ - public void remove(int data) { - this.root = delete(this.root, data); - } - - /** To call inorder traversal on tree */ - public void inorder() { - System.out.println("Inorder traversal of this tree is:"); - inOrder(this.root); - System.out.println(); // for next line - } - - /** To call postorder traversal on tree */ - public void postorder() { - System.out.println("Postorder traversal of this tree is:"); - postOrder(this.root); - System.out.println(); // for next li - } - - /** To call preorder traversal on tree. */ - public void preorder() { - System.out.println("Preorder traversal of this tree is:"); - preOrder(this.root); - System.out.println(); // for next li - } - - /** - * To check if given value is present in tree or not. - * - * @param data the data to be found for - */ - public boolean find(int data) { - if (search(this.root, data)) { - System.out.println(data + " is present in given BST."); - return true; - } - System.out.println(data + " not found."); - return false; - } - - /** The Node class used for building binary search tree */ - private static class Node { - int data; - Node left; - Node right; - - /** Constructor with data as parameter */ - Node(int d) { - data = d; - left = null; - right = null; - } - } -} diff --git a/DataStructures/Trees/BSTRecursiveGeneric.java b/DataStructures/Trees/BSTRecursiveGeneric.java deleted file mode 100644 index a3b117a6fc46..000000000000 --- a/DataStructures/Trees/BSTRecursiveGeneric.java +++ /dev/null @@ -1,296 +0,0 @@ -package DataStructures.Trees; - -import java.util.ArrayList; -import java.util.List; - -/** - *

Binary Search Tree (Recursive) Generic Type Implementation

- * - *

- * A recursive implementation of generic type BST. - * - * Reference: https://en.wikipedia.org/wiki/Binary_search_tree - *

- * - * @author [Madhur Panwar](https://github.com/mdrpanwar) - */ -public class BSTRecursiveGeneric> { - /** only data member is root of BST */ - private Node root; - - /** Constructor use to initialize node as null */ - public BSTRecursiveGeneric() { - root = null; - } - - /** main function for testing */ - public static void main(String[] args) { - System.out.println("Testing for integer data..."); - // Integer - DataStructures.Trees.BSTRecursiveGeneric integerTree = new DataStructures.Trees.BSTRecursiveGeneric(); - - 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"; - integerTree.remove(9); - 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"; - integerTree.add(20); - integerTree.add(70); - assert integerTree.find(70) : "70 was inserted but not found"; - /* - Will print in following order - 5 10 20 70 - */ - integerTree.inorder(); - System.out.println(); - System.out.println("Testing for string data..."); - // String - DataStructures.Trees.BSTRecursiveGeneric stringTree = new DataStructures.Trees.BSTRecursiveGeneric(); - - 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"; - stringTree.remove("date"); - 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"; - stringTree.add("india"); - stringTree.add("hills"); - assert stringTree.find("hills") : "hills was inserted but not found"; - /* - Will print in following order - banana hills india pineapple - */ - stringTree.inorder(); - - } - - /** - * Recursive method to delete a data if present in BST. - * - * @param node the node under which to (recursively) search for data - * @param data the value to be deleted - * @return Node the updated value of root parameter after delete operation - */ - private Node delete(Node node, T data) { - if (node == null) { - System.out.println("No such data present in BST."); - } else if (node.data.compareTo(data) > 0) { - node.left = delete(node.left, data); - } else if (node.data.compareTo(data) < 0) { - node.right = delete(node.right, data); - } else { - if (node.right == null && node.left == null) { // If it is leaf node - node = null; - } else if (node.left == null) { // If only right node is present - Node temp = node.right; - node.right = null; - node = temp; - } else if (node.right == null) { // Only left node is present - Node temp = node.left; - node.left = null; - node = temp; - } else { // both child are present - Node temp = node.right; - // Find leftmost child of right subtree - while (temp.left != null) { - temp = temp.left; - } - node.data = temp.data; - node.right = delete(node.right, temp.data); - } - } - return node; - } - - /** - * Recursive insertion of value in BST. - * - * @param node to check if the data can be inserted in current node or its subtree - * @param data the value to be inserted - * @return the modified value of the root parameter after insertion - */ - private Node insert(Node node, T data) { - if (node == null) { - node = new Node<>(data); - } else if (node.data.compareTo(data) > 0) { - node.left = insert(node.left, data); - } else if (node.data.compareTo(data) < 0) { - node.right = insert(node.right, data); - } - return node; - } - - /** - * Recursively print Preorder traversal of the BST - * - * @param node the root node - */ - private void preOrder(Node node) { - if (node == null) { - return; - } - System.out.print(node.data + " "); - if (node.left != null) { - preOrder(node.left); - } - if (node.right != null) { - preOrder(node.right); - } - } - - /** - * Recursively print Postorder traversal of BST. - * - * @param node the root node - */ - private void postOrder(Node node) { - if (node == null) { - return; - } - if (node.left != null) { - postOrder(node.left); - } - if (node.right != null) { - postOrder(node.right); - } - System.out.print(node.data + " "); - } - - /** - * Recursively print Inorder traversal of BST. - * - * @param node the root node - */ - private void inOrder(Node node) { - if (node == null) { - return; - } - if (node.left != null) { - inOrder(node.left); - } - System.out.print(node.data + " "); - if (node.right != null) { - inOrder(node.right); - } - } - - /** - * Recursively traverse the tree using inorder traversal - * and keep adding elements to argument list. - * - * @param node the root node - * @param sortedList the list to add the srted elements into - */ - private void inOrderSort(Node node, List sortedList) { - if (node == null) { - return; - } - if (node.left != null) { - inOrderSort(node.left, sortedList); - } - sortedList.add(node.data); - if (node.right != null) { - inOrderSort(node.right, sortedList); - } - } - - /** - * Serach recursively if the given value is present in BST or not. - * - * @param node the node under which to check - * @param data the value to be checked - * @return boolean if data is present or not - */ - private boolean search(Node node, T data) { - if (node == null) { - return false; - } else if (node.data.compareTo(data) == 0) { - return true; - } else if (node.data.compareTo(data) > 0) { - return search(node.left, data); - } else { - return search(node.right, data); - } - } - - /** - * add in BST. if the value is not already present it is inserted or else no change takes place. - * - * @param data the value to be inserted - */ - public void add(T data) { - this.root = insert(this.root, data); - } - - /** - * If data is present in BST delete it else do nothing. - * - * @param data the value to be removed - */ - public void remove(T data) { - this.root = delete(this.root, data); - } - - /** To call inorder traversal on tree */ - public void inorder() { - System.out.println("Inorder traversal of this tree is:"); - inOrder(this.root); - System.out.println(); // for next line - } - - /** return a sorted list by traversing the tree elements using inorder traversal */ - public List inorderSort() { - List sortedList = new ArrayList<>(); - inOrderSort(this.root, sortedList); - return sortedList; - } - - /** To call postorder traversal on tree */ - public void postorder() { - System.out.println("Postorder traversal of this tree is:"); - postOrder(this.root); - System.out.println(); // for next line - } - - /** To call preorder traversal on tree. */ - public void preorder() { - System.out.println("Preorder traversal of this tree is:"); - preOrder(this.root); - System.out.println(); // for next line - } - - /** - * To check if given value is present in tree or not. - * - * @param data the data to be found for - */ - public boolean find(T data) { - if (search(this.root, data)) { - System.out.println(data + " is present in given BST."); - return true; - } - System.out.println(data + " not found."); - return false; - } - - /** The generic Node class used for building binary search tree */ - private static class Node { - T data; - Node left; - Node right; - - /** Constructor with data as parameter */ - Node(T d) { - data = d; - left = null; - right = null; - } - } -} diff --git a/DataStructures/Trees/BinaryTree.java b/DataStructures/Trees/BinaryTree.java deleted file mode 100644 index 0669f80fd8c3..000000000000 --- a/DataStructures/Trees/BinaryTree.java +++ /dev/null @@ -1,301 +0,0 @@ -package DataStructures.Trees; - -import java.util.Queue; -import java.util.LinkedList; - -/** - * This entire class is used to build a Binary Tree data structure. There is the Node Class and the - * Tree Class, both explained below. - */ - -/** - * A binary tree is a data structure in which an element has two successors(children). The left - * child is usually smaller than the parent, and the right child is usually bigger. - * - * @author Unknown - */ -public class BinaryTree { - - /** - * This class implements the nodes that will go on the Binary Tree. They consist of the data in - * them, the node to the left, the node to the right, and the parent from which they came from. - * - * @author Unknown - */ - static class Node { - /** Data for the node */ - public int data; - /** The Node to the left of this one */ - public Node left; - /** The Node to the right of this one */ - public Node right; - /** The parent of this node */ - public Node parent; - - /** - * Constructor of Node - * - * @param value Value to put in the node - */ - public Node(int value) { - data = value; - left = null; - right = null; - parent = null; - } - } - - /** The root of the Binary Tree */ - private Node root; - - /** Constructor */ - public BinaryTree() { - root = null; - } - - /** Parameterized Constructor */ - public BinaryTree(Node root) { - this.root = root; - } - - /** - * Method to find a Node with a certain value - * - * @param key Value being looked for - * @return The node if it finds it, otherwise returns the parent - */ - public Node find(int key) { - Node current = root; - while (current != null) { - if (key < current.data) { - if (current.left == null) return current; // The key isn't exist, returns the parent - current = current.left; - } else if (key > current.data) { - if (current.right == null) return current; - current = current.right; - } else { // If you find the value return it - return current; - } - } - return null; - } - - /** - * Inserts certain value into the Binary Tree - * - * @param value Value to be inserted - */ - public void put(int value) { - Node newNode = new Node(value); - if (root == null) root = newNode; - else { - // This will return the soon to be parent of the value you're inserting - Node parent = find(value); - - // This if/else assigns the new node to be either the left or right child of the parent - if (value < parent.data) { - parent.left = newNode; - parent.left.parent = parent; - return; - } else { - parent.right = newNode; - parent.right.parent = parent; - return; - } - } - } - - /** - * Deletes a given value from the Binary Tree - * - * @param value Value to be deleted - * @return If the value was deleted - */ - public boolean remove(int value) { - // temp is the node to be deleted - Node temp = find(value); - - // If the value doesn't exist - if (temp.data != value) return false; - - // No children - 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 - else if (temp.parent.data < temp.data) temp.parent.right = null; - else temp.parent.left = null; - return true; - } - - // Two children - else if (temp.left != null && temp.right != null) { - Node successor = findSuccessor(temp); - - // The left tree of temp is made the left tree of the successor - successor.left = temp.left; - successor.left.parent = successor; - - // If the successor has a right child, the child's grandparent is it's new parent - if (successor.parent != temp) { - if (successor.right != null) { - successor.right.parent = successor.parent; - successor.parent.left = successor.right; - successor.right = temp.right; - successor.right.parent = successor; - } else { - successor.parent.left = null; - successor.right = temp.right; - successor.right.parent = successor; - } - } - - if (temp == root) { - successor.parent = null; - root = successor; - return true; - } - - // If you're not deleting the root - else { - successor.parent = temp.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 temp.parent.left = successor; - return true; - } - } - // One child - else { - // If it has a right child - if (temp.right != null) { - if (temp == root) { - root = temp.right; - return true; - } - - temp.right.parent = temp.parent; - - // Assigns temp to left or right child - if (temp.data < temp.parent.data) temp.parent.left = temp.right; - else temp.parent.right = temp.right; - return true; - } - // If it has a left child - else { - if (temp == root) { - root = temp.left; - return true; - } - - temp.left.parent = temp.parent; - - // Assigns temp to left or right side - if (temp.data < temp.parent.data) temp.parent.left = temp.left; - else temp.parent.right = temp.left; - return true; - } - } - } - - /** - * This method finds the Successor to the Node given. Move right once and go left down the tree as - * far as you can - * - * @param n Node that you want to find the Successor of - * @return The Successor of the node - */ - public Node findSuccessor(Node n) { - if (n.right == null) return n; - Node current = n.right; - Node parent = n.right; - while (current != null) { - parent = current; - current = current.left; - } - return parent; - } - - /** - * Returns the root of the Binary Tree - * - * @return the root of the Binary Tree - */ - public Node getRoot() { - return root; - } - - /** - * Prints leftChild - root - rightChild - * This is the equivalent of a depth first search - * - * @param localRoot The local root of the binary tree - */ - public void inOrder(Node localRoot) { - if (localRoot != null) { - inOrder(localRoot.left); - System.out.print(localRoot.data + " "); - inOrder(localRoot.right); - } - } - - /** - * Prints root - leftChild - rightChild - * - * @param localRoot The local root of the binary tree - */ - public void preOrder(Node localRoot) { - if (localRoot != null) { - System.out.print(localRoot.data + " "); - preOrder(localRoot.left); - preOrder(localRoot.right); - } - } - - /** - * Prints rightChild - leftChild - root - * - * @param localRoot The local root of the binary tree - */ - public void postOrder(Node localRoot) { - if (localRoot != null) { - postOrder(localRoot.left); - postOrder(localRoot.right); - System.out.print(localRoot.data + " "); - } - } - - /** - * Prints the tree in a breadth first search order - * This is similar to pre-order traversal, but instead of being - * implemented with a stack (or recursion), it is implemented - * with a queue - * - * @param localRoot The local root of the binary tree - */ - public void bfs(Node localRoot) { - // Create a queue for the order of the nodes - Queue queue = new LinkedList(); - - // If the give root is null, then we don't add to the queue - // and won't do anything - if (localRoot != null) - queue.add(localRoot); - - // Continue until the queue is empty - while (! queue.isEmpty()) { - // Get the next node on the queue to visit - localRoot = queue.remove(); - - // Print the data from the node we are visiting - System.out.print(localRoot.data + " "); - - // Add the children to the queue if not null - if (localRoot.right != null) - queue.add(localRoot.right); - if (localRoot.left != null) - queue.add(localRoot.left); - } - } -} diff --git a/DataStructures/Trees/CeilInBinarySearchTree.java b/DataStructures/Trees/CeilInBinarySearchTree.java deleted file mode 100644 index c81c0f685d92..000000000000 --- a/DataStructures/Trees/CeilInBinarySearchTree.java +++ /dev/null @@ -1,75 +0,0 @@ -package DataStructures.Trees; - -import DataStructures.Trees.BinaryTree.Node; - -/** - * Problem Statement - * Ceil value for any number x in a collection is a number y which is either equal to x or the least greater number than x. - * - * Problem: Given a binary search tree containing positive integer values. - * Find ceil value for a given key in O(lg(n)) time. In case if it is not present return -1. - * - * Ex.1. [30,20,40,10,25,35,50] represents level order traversal of a binary search tree. Find ceil for 10. - * Answer: 20 - * - * Ex.2. [30,20,40,10,25,35,50] represents level order traversal of a binary search tree. Find ceil for 22 - * Answer: 25 - * - * Ex.2. [30,20,40,10,25,35,50] represents level order traversal of a binary search tree. Find ceil for 52 - * Answer: -1 - */ - -/** - * - * Solution 1: - * Brute Force Solution: - * Do an inorder traversal and save result into an array. Iterate over the array to get an element equal to or greater - * than current key. - * Time Complexity: O(n) - * Space Complexity: O(n) for auxillary array to save inorder representation of tree. - *

- *

- * Solution 2: - * Brute Force Solution: - * Do an inorder traversal and save result into an array.Since array is sorted do a binary search over the array to get an - * element equal to or greater than current key. - * Time Complexity: O(n) for traversal of tree and O(lg(n)) for binary search in array. Total = O(n) - * Space Complexity: O(n) for auxillary array to save inorder representation of tree. - *

- *

- * Solution 3: Optimal - * We can do a DFS search on given tree in following fashion. - * i) if root is null then return null because then ceil doesn't exist - * ii) If key is lesser than root value than ceil will be in right subtree so call recursively on right subtree - * iii) if key is greater than current root, then either - * a) the root is ceil - * b) ceil is in left subtree: call for left subtree. If left subtree returns a non null value then that will be ceil - * otherwise the root is ceil - */ -public class CeilInBinarySearchTree { - - public static Node getCeil(Node root, int key) { - if (root == null) { - return null; - } - - // if root value is same as key than root is the ceiling - if (root.data == key) { - return root; - } - - // if root value is lesser than key then ceil must be in right subtree - if (root.data < key) { - return getCeil(root.right, key); - } - - // if root value is greater than key then ceil can be in left subtree or if - // it is not in left subtree then current node will be ceil - Node result = getCeil(root.left, key); - - // if result is null it means that there is no ceil in children subtrees - // and the root is the ceil otherwise the returned node is the ceil. - return result == null ? root : result; - } -} - diff --git a/DataStructures/Trees/CreateBSTFromSortedArray.java b/DataStructures/Trees/CreateBSTFromSortedArray.java deleted file mode 100644 index f31e7928c6b1..000000000000 --- a/DataStructures/Trees/CreateBSTFromSortedArray.java +++ /dev/null @@ -1,45 +0,0 @@ -package DataStructures.Trees; - -import DataStructures.Trees.BinaryTree.Node; - -/** - * Given a sorted array. Create a balanced binary search tree from it. - * - * Steps: - * 1. Find the middle element of array. This will act as root - * 2. Use the left half recursively to create left subtree - * 3. Use the right half recursively to create right subtree - */ -public class CreateBSTFromSortedArray { - - public static void main(String[] args) { - test(new int[]{}); - test(new int[]{1, 2, 3}); - test(new int[]{1, 2, 3, 4, 5}); - test(new int[]{1, 2, 3, 4, 5, 6, 7}); - } - - private static void test(int[] array) { - BinaryTree root = new BinaryTree(createBst(array, 0, array.length - 1)); - System.out.println("\n\nPreorder Traversal: "); - root.preOrder(root.getRoot()); - System.out.println("\nInorder Traversal: "); - root.inOrder(root.getRoot()); - System.out.println("\nPostOrder Traversal: "); - root.postOrder(root.getRoot()); - } - - private static Node createBst(int[] array, int start, int end) { - // No element left. - if (start > end) { - return null; - } - int mid = start + (end - start) / 2; - - // middle element will be the root - Node root = new Node(array[mid]); - root.left = createBst(array, start, mid - 1); - root.right = createBst(array, mid + 1, end); - return root; - } -} diff --git a/DataStructures/Trees/CreateBinaryTreeFromInorderPreorder.java b/DataStructures/Trees/CreateBinaryTreeFromInorderPreorder.java deleted file mode 100644 index ea9583bb3f94..000000000000 --- a/DataStructures/Trees/CreateBinaryTreeFromInorderPreorder.java +++ /dev/null @@ -1,95 +0,0 @@ -package DataStructures.Trees; - -import java.util.HashMap; -import java.util.Map; -import DataStructures.Trees.BinaryTree.Node; - -/** - * Approach: Naive Solution: Create root node from first value present in - * preorder traversal. Look for the index of root node's value in inorder - * traversal. That will tell total nodes present in left subtree and right - * subtree. Based on that index create left and right subtree. - * Complexity: - * Time: O(n^2) for each node there is iteration to find index in inorder array - * Space: Stack size = O(height) = O(lg(n)) - * - * Optimized Solution: Instead of iterating over inorder array to find index of - * root value, create a hashmap and find out the index of root value. - * Complexity: - * Time: O(n) hashmap reduced iteration to find index in inorder array - * Space: O(n) space taken by hashmap - * - */ -public class CreateBinaryTreeFromInorderPreorder { - public static void main(String[] args) { - test(new Integer[] {}, new Integer[] {}); // empty tree - test(new Integer[] { 1 }, new Integer[] { 1 }); // single node tree - test(new Integer[] { 1, 2, 3, 4 }, new Integer[] { 1, 2, 3, 4 }); // right skewed tree - test(new Integer[] { 1, 2, 3, 4 }, new Integer[] { 4, 3, 2, 1 }); // left skewed tree - test(new Integer[] { 3, 9, 20, 15, 7 }, new Integer[] { 9, 3, 15, 20, 7 }); // normal tree - } - - private static void test(final Integer[] preorder, final Integer[] inorder) { - System.out.println("\n===================================================="); - System.out.println("Naive Solution..."); - BinaryTree root = new BinaryTree(createTree(preorder, inorder, 0, 0, inorder.length)); - System.out.println("Preorder Traversal: "); - root.preOrder(root.getRoot()); - System.out.println("\nInorder Traversal: "); - root.inOrder(root.getRoot()); - System.out.println("\nPostOrder Traversal: "); - root.postOrder(root.getRoot()); - - Map map = new HashMap<>(); - for (int i = 0; i < inorder.length; i++) { - map.put(inorder[i], i); - } - BinaryTree optimizedRoot = new BinaryTree(createTreeOptimized(preorder, inorder, 0, 0, inorder.length, map)); - System.out.println("\n\nOptimized solution..."); - System.out.println("Preorder Traversal: "); - optimizedRoot.preOrder(root.getRoot()); - System.out.println("\nInorder Traversal: "); - optimizedRoot.inOrder(root.getRoot()); - System.out.println("\nPostOrder Traversal: "); - optimizedRoot.postOrder(root.getRoot()); - } - - private static Node createTree(final Integer[] preorder, final Integer[] inorder, - final int preStart, final int inStart, final int size) { - if (size == 0) { - return null; - } - - Node root = new Node(preorder[preStart]); - int i = inStart; - while (preorder[preStart] != inorder[i]) { - i++; - } - 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); - return root; - - } - - private static Node createTreeOptimized(final Integer[] preorder, final Integer[] inorder, - final int preStart, final int inStart, final int size, - final Map inorderMap) { - if (size == 0) { - return null; - } - - Node root = new Node(preorder[preStart]); - int i = inorderMap.get(preorder[preStart]); - int leftNodesCount = i - inStart; - int rightNodesCount = size - leftNodesCount - 1; - root.left = createTreeOptimized(preorder, inorder, preStart + 1, inStart, - leftNodesCount, inorderMap); - root.right = createTreeOptimized(preorder, inorder, preStart + leftNodesCount + 1, - i + 1, rightNodesCount, inorderMap); - return root; - } - -} diff --git a/DataStructures/Trees/GenericTree.java b/DataStructures/Trees/GenericTree.java deleted file mode 100644 index cb30c4f452a2..000000000000 --- a/DataStructures/Trees/GenericTree.java +++ /dev/null @@ -1,212 +0,0 @@ -package DataStructures.Trees; - -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Scanner; - -/** - * A generic tree is a tree which can have as many children as it can be It might be possible that - * every node present is directly connected to root node. - * - *

In this code Every function has two copies: one function is helper function which can be - * called from main and from that function a private function is called which will do the actual - * work. I have done this, while calling from main one have to give minimum parameters. - */ -public class GenericTree { - private class Node { - int data; - ArrayList child = new ArrayList<>(); - } - - private Node root; - private int size; - - public GenericTree() { // Constructor - Scanner scn = new Scanner(System.in); - root = create_treeG(null, 0, scn); - } - - private Node create_treeG(Node node, int childindx, Scanner scn) { - // display - if (node == null) { - System.out.println("Enter root's data"); - } else { - System.out.println("Enter data of parent of index " + node.data + " " + childindx); - } - // input - node = new Node(); - node.data = scn.nextInt(); - System.out.println("number of children"); - int number = scn.nextInt(); - for (int i = 0; i < number; i++) { - Node child = create_treeG(node, i, scn); - size++; - node.child.add(child); - } - return node; - } - - /** Function to display the generic tree */ - public void display() { // Helper function - display_1(root); - } - - private void display_1(Node parent) { - System.out.print(parent.data + "=>"); - for (int i = 0; i < parent.child.size(); i++) { - System.out.print(parent.child.get(i).data + " "); - } - System.out.println("."); - for (int i = 0; i < parent.child.size(); i++) { - display_1(parent.child.get(i)); - } - } - - /** - * One call store the size directly but if you are asked compute size this function to calculate - * size goes as follows - * - * @return size - */ - public int size2call() { - return size2(root); - } - - public int size2(Node roott) { - int sz = 0; - for (int i = 0; i < roott.child.size(); i++) { - sz += size2(roott.child.get(i)); - } - return sz + 1; - } - - /** - * Function to compute maximum value in the generic tree - * - * @return maximum value - */ - public int maxcall() { - int maxi = root.data; - return max(root, maxi); - } - - private int max(Node roott, int maxi) { - if (maxi < roott.data) maxi = roott.data; - for (int i = 0; i < roott.child.size(); i++) { - maxi = max(roott.child.get(i), maxi); - } - - return maxi; - } - - /** - * Function to compute HEIGHT of the generic tree - * - * @return height - */ - public int heightcall() { - return height(root) - 1; - } - - private int height(Node node) { - int h = 0; - for (int i = 0; i < node.child.size(); i++) { - int k = height(node.child.get(i)); - if (k > h) h = k; - } - return h + 1; - } - - /** - * Function to find whether a number is present in the generic tree or not - * - * @param info number - * @return present or not - */ - public boolean findcall(int info) { - return find(root, info); - } - - private boolean find(Node node, int info) { - if (node.data == info) return true; - for (int i = 0; i < node.child.size(); i++) { - if (find(node.child.get(i), info)) return true; - } - return false; - } - - /** - * Function to calculate depth of generic tree - * - * @param dep depth - */ - public void depthcaller(int dep) { - depth(root, dep); - } - - public void depth(Node node, int dep) { - if (dep == 0) { - System.out.println(node.data); - return; - } - for (int i = 0; i < node.child.size(); i++) depth(node.child.get(i), dep - 1); - return; - } - - /** Function to print generic tree in pre-order */ - public void preordercall() { - preorder(root); - System.out.println("."); - } - - private void preorder(Node node) { - System.out.print(node.data + " "); - for (int i = 0; i < node.child.size(); i++) preorder(node.child.get(i)); - } - - /** Function to print generic tree in post-order */ - public void postordercall() { - postorder(root); - System.out.println("."); - } - - private void postorder(Node node) { - for (int i = 0; i < node.child.size(); i++) postorder(node.child.get(i)); - System.out.print(node.data + " "); - } - - /** Function to print generic tree in level-order */ - public void levelorder() { - LinkedList q = new LinkedList<>(); - q.addLast(root); - while (!q.isEmpty()) { - int k = q.getFirst().data; - System.out.print(k + " "); - - for (int i = 0; i < q.getFirst().child.size(); i++) { - q.addLast(q.getFirst().child.get(i)); - } - q.removeFirst(); - } - System.out.println("."); - } - - /** Function to remove all leaves of generic tree */ - public void removeleavescall() { - removeleaves(root); - } - - private void removeleaves(Node node) { - ArrayList arr = new ArrayList<>(); - for (int i = 0; i < node.child.size(); i++) { - if (node.child.get(i).child.size() == 0) { - arr.add(i); - // node.child.remove(i); - // i--; - } else removeleaves(node.child.get(i)); - } - for (int i = arr.size() - 1; i >= 0; i--) { - node.child.remove(arr.get(i) + 0); - } - } -} diff --git a/DataStructures/Trees/LevelOrderTraversal.java b/DataStructures/Trees/LevelOrderTraversal.java deleted file mode 100644 index 07ae57041419..000000000000 --- a/DataStructures/Trees/LevelOrderTraversal.java +++ /dev/null @@ -1,49 +0,0 @@ -package DataStructures.Trees; - -public class LevelOrderTraversal { - - class Node { - int data; - Node left, right; - - public Node(int item) { - data = item; - left = right = null; - } - } - - // Root of the Binary Tree - Node root; - - public LevelOrderTraversal(Node root) { - this.root = root; - } - - /* function to print level order traversal of tree*/ - void printLevelOrder() { - int h = height(root); - int i; - for (i = 1; i <= h; i++) printGivenLevel(root, i); - } - - /* Compute the "height" of a tree -- the number of - nodes along the longest path from the root node - down to the farthest leaf node.*/ - int height(Node root) { - if (root == null) return 0; - else { - /** Return the height of larger subtree */ - return Math.max(height(root.left), height(root.right)) + 1; - } - } - - /* Print nodes at the given level */ - void printGivenLevel(Node root, int level) { - if (root == null) return; - if (level == 1) System.out.print(root.data + " "); - else if (level > 1) { - printGivenLevel(root.left, level - 1); - printGivenLevel(root.right, level - 1); - } - } -} diff --git a/DataStructures/Trees/LevelOrderTraversalQueue.java b/DataStructures/Trees/LevelOrderTraversalQueue.java deleted file mode 100644 index 58f48eba6bc5..000000000000 --- a/DataStructures/Trees/LevelOrderTraversalQueue.java +++ /dev/null @@ -1,45 +0,0 @@ -package DataStructures.Trees; - -import java.util.LinkedList; -import java.util.Queue; - -/* Class to print Level Order Traversal */ -public class LevelOrderTraversalQueue { - - /* Class to represent Tree node */ - class Node { - int data; - Node left, right; - - public Node(int item) { - data = item; - left = null; - right = null; - } - } - - /* Given a binary tree. Print its nodes in level order - using array for implementing queue */ - void printLevelOrder(Node root) { - Queue queue = new LinkedList(); - queue.add(root); - while (!queue.isEmpty()) { - - /* poll() removes the present head. - For more information on poll() visit - http://www.tutorialspoint.com/java/util/linkedlist_poll.htm */ - Node tempNode = queue.poll(); - System.out.print(tempNode.data + " "); - - /*Enqueue left child */ - if (tempNode.left != null) { - queue.add(tempNode.left); - } - - /*Enqueue right child */ - if (tempNode.right != null) { - queue.add(tempNode.right); - } - } - } -} diff --git a/DataStructures/Trees/PrintTopViewofTree.java b/DataStructures/Trees/PrintTopViewofTree.java deleted file mode 100644 index 78626f46ba7d..000000000000 --- a/DataStructures/Trees/PrintTopViewofTree.java +++ /dev/null @@ -1,104 +0,0 @@ -package DataStructures.Trees; // Java program to print top view of Binary tree - -import java.util.HashSet; -import java.util.LinkedList; -import java.util.Queue; - -// Class for a tree node -class TreeNode { - // Members - int key; - TreeNode left, right; - - // Constructor - public TreeNode(int key) { - this.key = key; - left = right = null; - } -} - -// A class to represent a queue item. The queue is used to do Level -// order traversal. Every Queue item contains node and horizontal -// distance of node from root -class QItem { - TreeNode node; - int hd; - - public QItem(TreeNode n, int h) { - node = n; - hd = h; - } -} - -// Class for a Binary Tree -class Tree { - TreeNode root; - - // Constructors - public Tree() { - root = null; - } - - public Tree(TreeNode n) { - root = n; - } - - // This method prints nodes in top view of binary tree - public void printTopView() { - // base case - if (root == null) { - return; - } - - // Creates an empty hashset - HashSet set = new HashSet<>(); - - // Create a queue and add root to it - Queue Q = new LinkedList(); - Q.add(new QItem(root, 0)); // Horizontal distance of root is 0 - - // Standard BFS or level order traversal loop - while (!Q.isEmpty()) { - // Remove the front item and get its details - QItem qi = Q.remove(); - int hd = qi.hd; - TreeNode n = qi.node; - - // If this is the first node at its horizontal distance, - // then this node is in top view - if (!set.contains(hd)) { - set.add(hd); - System.out.print(n.key + " "); - } - - // Enqueue left and right children of current node - if (n.left != null) Q.add(new QItem(n.left, hd - 1)); - if (n.right != null) Q.add(new QItem(n.right, hd + 1)); - } - } -} - -// Driver class to test above methods -public class PrintTopViewofTree { - public static void main(String[] args) { - /* Create following Binary Tree - 1 - / \ - 2 3 - \ - 4 - \ - 5 - \ - 6*/ - TreeNode root = new TreeNode(1); - root.left = new TreeNode(2); - root.right = new TreeNode(3); - root.left.right = new TreeNode(4); - root.left.right.right = new TreeNode(5); - root.left.right.right.right = new TreeNode(6); - Tree t = new Tree(root); - System.out.println("Following are nodes in top view of Binary Tree"); - t.printTopView(); - } -} diff --git a/DataStructures/Trees/RedBlackBST.java b/DataStructures/Trees/RedBlackBST.java deleted file mode 100644 index f8c7b640d6c1..000000000000 --- a/DataStructures/Trees/RedBlackBST.java +++ /dev/null @@ -1,331 +0,0 @@ -package DataStructures.Trees; - -import java.util.Scanner; - -/** @author jack870131 */ -public class RedBlackBST { - - private final int R = 0; - private final int B = 1; - - private class Node { - - int key = -1, color = B; - Node left = nil, right = nil, p = nil; - - Node(int key) { - this.key = key; - } - } - - private final Node nil = new Node(-1); - private Node root = nil; - - public void printTree(Node node) { - if (node == nil) { - return; - } - printTree(node.left); - System.out.print( - ((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); - printTree(node.right); - } - - public void printTreepre(Node node) { - if (node == nil) { - return; - } - System.out.print( - ((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); - printTree(node.left); - printTree(node.right); - } - - private Node findNode(Node findNode, Node node) { - if (root == nil) { - return null; - } - if (findNode.key < node.key) { - if (node.left != nil) { - return findNode(findNode, node.left); - } - } else if (findNode.key > node.key) { - if (node.right != nil) { - return findNode(findNode, node.right); - } - } else if (findNode.key == node.key) { - return node; - } - return null; - } - - private void insert(Node node) { - Node temp = root; - if (root == nil) { - root = node; - node.color = B; - node.p = nil; - } else { - node.color = R; - while (true) { - if (node.key < temp.key) { - if (temp.left == nil) { - temp.left = node; - node.p = temp; - break; - } else { - temp = temp.left; - } - } else if (node.key >= temp.key) { - if (temp.right == nil) { - temp.right = node; - node.p = temp; - break; - } else { - temp = temp.right; - } - } - } - fixTree(node); - } - } - - private void fixTree(Node node) { - while (node.p.color == R) { - Node y = nil; - if (node.p == node.p.p.left) { - y = node.p.p.right; - - if (y != nil && y.color == R) { - node.p.color = B; - y.color = B; - node.p.p.color = R; - node = node.p.p; - continue; - } - if (node == node.p.right) { - node = node.p; - rotateLeft(node); - } - node.p.color = B; - node.p.p.color = R; - rotateRight(node.p.p); - } else { - y = node.p.p.left; - if (y != nil && y.color == R) { - node.p.color = B; - y.color = B; - node.p.p.color = R; - node = node.p.p; - continue; - } - if (node == node.p.left) { - node = node.p; - rotateRight(node); - } - node.p.color = B; - node.p.p.color = R; - rotateLeft(node.p.p); - } - } - root.color = B; - } - - void rotateLeft(Node node) { - if (node.p != nil) { - if (node == node.p.left) { - node.p.left = node.right; - } else { - node.p.right = node.right; - } - node.right.p = node.p; - node.p = node.right; - if (node.right.left != nil) { - node.right.left.p = node; - } - node.right = node.right.left; - node.p.left = node; - } else { - Node right = root.right; - root.right = right.left; - right.left.p = root; - root.p = right; - right.left = root; - right.p = nil; - root = right; - } - } - - void rotateRight(Node node) { - if (node.p != nil) { - if (node == node.p.left) { - node.p.left = node.left; - } else { - node.p.right = node.left; - } - - node.left.p = node.p; - node.p = node.left; - if (node.left.right != nil) { - node.left.right.p = node; - } - node.left = node.left.right; - node.p.right = node; - } else { - Node left = root.left; - root.left = root.left.right; - left.right.p = root; - root.p = left; - left.right = root; - left.p = nil; - root = left; - } - } - - void transplant(Node target, Node with) { - if (target.p == nil) { - root = with; - } else if (target == target.p.left) { - target.p.left = with; - } else target.p.right = with; - with.p = target.p; - } - - Node treeMinimum(Node subTreeRoot) { - while (subTreeRoot.left != nil) { - subTreeRoot = subTreeRoot.left; - } - return subTreeRoot; - } - - boolean delete(Node z) { - if ((z = findNode(z, root)) == null) return false; - Node x; - Node y = z; - int yorigcolor = y.color; - - if (z.left == nil) { - x = z.right; - transplant(z, z.right); - } else if (z.right == nil) { - x = z.left; - transplant(z, z.left); - } else { - y = treeMinimum(z.right); - yorigcolor = y.color; - x = y.right; - if (y.p == z) x.p = y; - else { - transplant(y, y.right); - y.right = z.right; - y.right.p = y; - } - transplant(z, y); - y.left = z.left; - y.left.p = y; - y.color = z.color; - } - if (yorigcolor == B) deleteFixup(x); - return true; - } - - void deleteFixup(Node x) { - while (x != root && x.color == B) { - if (x == x.p.left) { - Node w = x.p.right; - if (w.color == R) { - w.color = B; - x.p.color = R; - rotateLeft(x.p); - w = x.p.right; - } - if (w.left.color == B && w.right.color == B) { - w.color = R; - x = x.p; - continue; - } else if (w.right.color == B) { - w.left.color = B; - w.color = R; - rotateRight(w); - w = x.p.right; - } - if (w.right.color == R) { - w.color = x.p.color; - x.p.color = B; - w.right.color = B; - rotateLeft(x.p); - x = root; - } - } else { - Node w = x.p.left; - if (w.color == R) { - w.color = B; - x.p.color = R; - rotateRight(x.p); - w = x.p.left; - } - if (w.right.color == B && w.left.color == B) { - w.color = R; - x = x.p; - continue; - } else if (w.left.color == B) { - w.right.color = B; - w.color = R; - rotateLeft(w); - w = x.p.left; - } - if (w.left.color == R) { - w.color = x.p.color; - x.p.color = B; - w.left.color = B; - rotateRight(x.p); - x = root; - } - } - } - x.color = B; - } - - public void insertDemo() { - Scanner scan = new Scanner(System.in); - while (true) { - System.out.println("Add items"); - - int item; - Node node; - - item = scan.nextInt(); - while (item != -999) { - node = new Node(item); - insert(node); - item = scan.nextInt(); - } - printTree(root); - System.out.println("Pre order"); - printTreepre(root); - break; - } - scan.close(); - } - - public void deleteDemo() { - Scanner scan = new Scanner(System.in); - System.out.println("Delete items"); - int item; - Node node; - item = scan.nextInt(); - node = new Node(item); - System.out.print("Deleting item " + item); - if (delete(node)) { - System.out.print(": deleted!"); - } else { - System.out.print(": does not exist!"); - } - - System.out.println(); - printTree(root); - System.out.println("Pre order"); - printTreepre(root); - scan.close(); - } -} diff --git a/DataStructures/Trees/TreeTraversal.java b/DataStructures/Trees/TreeTraversal.java deleted file mode 100644 index e9cca1ccdd6b..000000000000 --- a/DataStructures/Trees/TreeTraversal.java +++ /dev/null @@ -1,113 +0,0 @@ -package DataStructures.Trees; - -import java.util.LinkedList; - -/** @author Varun Upadhyay (https://github.com/varunu28) */ - -// Driver Program -public class TreeTraversal { - public static void main(String[] args) { - Node tree = new Node(5); - tree.insert(3); - tree.insert(2); - tree.insert(7); - tree.insert(4); - tree.insert(6); - tree.insert(8); - - // Prints 5 3 2 4 7 6 8 - System.out.println("Pre order traversal:"); - tree.printPreOrder(); - System.out.println(); - // Prints 2 3 4 5 6 7 8 - System.out.println("In order traversal:"); - tree.printInOrder(); - System.out.println(); - // Prints 2 4 3 6 8 7 5 - System.out.println("Post order traversal:"); - tree.printPostOrder(); - System.out.println(); - // Prints 5 3 7 2 4 6 8 - System.out.println("Level order traversal:"); - tree.printLevelOrder(); - System.out.println(); - } -} - -/** - * The Node class which initializes a Node of a tree Consists of all 4 traversal methods: - * printInOrder, printPostOrder, printPreOrder & printLevelOrder printInOrder: LEFT -> ROOT -> RIGHT - * printPreOrder: ROOT -> LEFT -> RIGHT printPostOrder: LEFT -> RIGHT -> ROOT printLevelOrder: - * Prints by level (starting at root), from left to right. - */ -class Node { - Node left, right; - int data; - - public Node(int data) { - this.data = data; - } - - public void insert(int value) { - if (value < data) { - if (left == null) { - left = new Node(value); - } else { - left.insert(value); - } - } else { - if (right == null) { - right = new Node(value); - } else { - right.insert(value); - } - } - } - - public void printInOrder() { - if (left != null) { - left.printInOrder(); - } - System.out.print(data + " "); - if (right != null) { - right.printInOrder(); - } - } - - public void printPreOrder() { - System.out.print(data + " "); - if (left != null) { - left.printPreOrder(); - } - if (right != null) { - right.printPreOrder(); - } - } - - public void printPostOrder() { - if (left != null) { - left.printPostOrder(); - } - if (right != null) { - right.printPostOrder(); - } - System.out.print(data + " "); - } - - /** O(n) time algorithm. Uses O(n) space to store nodes in a queue to aid in traversal. */ - public void printLevelOrder() { - LinkedList queue = new LinkedList<>(); - queue.add(this); - while (queue.size() > 0) { - Node head = queue.remove(); - System.out.print(head.data + " "); - // Add children of recently-printed node to queue, if they exist. - if (head.left != null) { - queue.add(head.left); - } - if (head.right != null) { - queue.add(head.right); - } - } - } -} diff --git a/DataStructures/Trees/TrieImp.java b/DataStructures/Trees/TrieImp.java deleted file mode 100644 index 3c3ddc5d35ee..000000000000 --- a/DataStructures/Trees/TrieImp.java +++ /dev/null @@ -1,129 +0,0 @@ -package DataStructures.Trees; - -/** - * Trie Data structure implementation without any libraries - * - * @author Dheeraj Kumar Barnwal (https://github.com/dheeraj92) - */ -import java.util.Scanner; - -public class TrieImp { - - public class TrieNode { - TrieNode[] child; - boolean end; - - public TrieNode() { - child = new TrieNode[26]; - end = false; - } - } - - private final TrieNode root; - - public TrieImp() { - root = new TrieNode(); - } - - public void insert(String word) { - TrieNode currentNode = root; - for (int i = 0; i < word.length(); i++) { - TrieNode node = currentNode.child[word.charAt(i) - 'a']; - if (node == null) { - node = new TrieNode(); - currentNode.child[word.charAt(i) - 'a'] = node; - } - currentNode = node; - } - currentNode.end = true; - } - - public boolean search(String word) { - TrieNode currentNode = root; - for (int i = 0; i < word.length(); i++) { - char ch = word.charAt(i); - TrieNode node = currentNode.child[ch - 'a']; - if (node == null) { - return false; - } - currentNode = node; - } - return currentNode.end; - } - - public boolean delete(String word) { - TrieNode currentNode = root; - for (int i = 0; i < word.length(); i++) { - char ch = word.charAt(i); - TrieNode node = currentNode.child[ch - 'a']; - if (node == null) { - return false; - } - currentNode = node; - } - if (currentNode.end == true) { - currentNode.end = false; - return true; - } - return false; - } - - public static void sop(String print) { - System.out.println(print); - } - - /** Regex to check if word contains only a-z character */ - public static boolean isValid(String word) { - return word.matches("^[a-z]+$"); - } - - public static void main(String[] args) { - TrieImp obj = new TrieImp(); - String word; - @SuppressWarnings("resource") - Scanner scan = new Scanner(System.in); - sop("string should contain only a-z character for all operation"); - while (true) { - sop("1. Insert\n2. Search\n3. Delete\n4. Quit"); - try { - int t = scan.nextInt(); - switch (t) { - case 1: - word = scan.next(); - if (isValid(word)) obj.insert(word); - else sop("Invalid string: allowed only a-z"); - break; - case 2: - word = scan.next(); - boolean resS = false; - if (isValid(word)) resS = obj.search(word); - else sop("Invalid string: allowed only a-z"); - if (resS) sop("word found"); - else sop("word not found"); - break; - case 3: - word = scan.next(); - boolean resD = false; - if (isValid(word)) resD = obj.delete(word); - else sop("Invalid string: allowed only a-z"); - if (resD) { - sop("word got deleted successfully"); - } else { - sop("word not found"); - } - break; - case 4: - sop("Quit successfully"); - System.exit(1); - break; - default: - sop("Input int from 1-4"); - break; - } - } catch (Exception e) { - String badInput = scan.next(); - sop("This is bad input: " + badInput); - } - } - } -} diff --git a/DataStructures/Trees/ValidBSTOrNot.java b/DataStructures/Trees/ValidBSTOrNot.java deleted file mode 100644 index 3b3d626286c9..000000000000 --- a/DataStructures/Trees/ValidBSTOrNot.java +++ /dev/null @@ -1,40 +0,0 @@ -package DataStructures.Trees; - -public class ValidBSTOrNot { - - class Node { - int data; - Node left, right; - - public Node(int item) { - data = item; - left = right = null; - } - } - - // Root of the Binary Tree - - /* can give min and max value according to your code or - can write a function to find min and max value of tree. */ - - /* returns true if given search tree is binary - search tree (efficient version) */ - boolean isBST(Node root) { - return isBSTUtil(root, Integer.MIN_VALUE, Integer.MAX_VALUE); - } - - /* Returns true if the given tree is a BST and its - values are >= min and <= max. */ - boolean isBSTUtil(Node node, int min, int max) { - /* an empty tree is BST */ - if (node == null) return true; - - /* false if this node violates the min/max constraints */ - if (node.data < min || node.data > max) return false; - - /* otherwise check the subtrees recursively - tightening the min/max constraints */ - // Allow only distinct values - return (isBSTUtil(node.left, min, node.data - 1) && isBSTUtil(node.right, node.data + 1, max)); - } -} diff --git a/DataStructures/Trees/VerticalOrderTraversal.java b/DataStructures/Trees/VerticalOrderTraversal.java deleted file mode 100644 index bfbd36caabdb..000000000000 --- a/DataStructures/Trees/VerticalOrderTraversal.java +++ /dev/null @@ -1,106 +0,0 @@ -package DataStructures.Trees; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.Map; -import java.util.Queue; - -/* The following class implements a vertical order traversal -in a tree from top to bottom and left to right, so for a tree : - 1 - / \ - 2 3 - / \ \ - 4 5 6 - \ / \ - 7 8 10 - \ - 9 - the sequence will be : - 4 2 7 1 5 9 3 8 6 10 - */ -public class VerticalOrderTraversal{ - - - public static void main(String[] args) { - BinaryTree tree = new BinaryTree(); - tree.put(5); - tree.put(6); - tree.put(3); - tree.put(1); - tree.put(4); - BinaryTree.Node root = tree.getRoot(); - ArrayList ans = verticalTraversal(root); - for(int i : ans) { - System.out.print(i+" "); - } - } - - /*Function that receives a root Node and prints the tree - in Vertical Order.*/ - private static ArrayList verticalTraversal(BinaryTree.Node root) { - /*Queue to store the Nodes.*/ - Queue queue= new LinkedList<>(); - - /*Queue to store the index of particular vertical - column of a tree , with root at 0, Nodes on left - with negative index and Nodes on right with positive - index. */ - Queue index = new LinkedList<>(); - - /*Map of Integer and ArrayList to store all the - elements in a particular index in a single arrayList - that will have a key equal to the index itself. */ - Map> map = new HashMap<>(); - - /* min and max stores leftmost and right most index to - later print the tree in vertical fashion.*/ - int max =0, min =0; - queue.offer(root); - index.offer(0); - - while(!queue.isEmpty()) { - - if(queue.peek().left!=null) { - /*Adding the left Node if it is not null - and its index by subtracting 1 from it's - parent's index*/ - queue.offer(queue.peek().left); - index.offer(index.peek()-1); - } - if(queue.peek().right!=null) { - /*Adding the right Node if it is not null - and its index by adding 1 from it's - parent's index*/ - queue.offer(queue.peek().right); - index.offer(index.peek()+1); - } - /*If the map does not contains the index a new - ArrayList is created with the index as key.*/ - if(!map.containsKey(index.peek())) { - ArrayList a = new ArrayList<>(); - map.put(index.peek(), a); - } - /*For a index, corresponding Node data is added - to the respective ArrayList present at that - index. */ - map.get(index.peek()).add(queue.peek().data); - max = (int)Math.max(max,index.peek()); - min = (int)Math.min(min,index.peek()); - /*The Node and its index are removed - from their respective queues.*/ - index.poll();queue.poll(); - } - /*Finally map data is printed here which has keys - from min to max. Each ArrayList represents a - vertical column that is added in ans ArrayList.*/ - ArrayList ans= new ArrayList<>(); - for(int i =min ; i<= max ; i++) { - for(int j = 0 ; j Comparable type - * @return first found index of the element - */ - > int find(T array[], T key); -} diff --git a/DivideAndConquer/ClosestPair.java b/DivideAndConquer/ClosestPair.java deleted file mode 100644 index 48a2950e8a46..000000000000 --- a/DivideAndConquer/ClosestPair.java +++ /dev/null @@ -1,334 +0,0 @@ -package DivideAndConquer; - -/** - * For a set of points in a coordinates system (10000 maximum), ClosestPair class calculates the two - * closest points. - */ -public final class ClosestPair { - - /** Number of points */ - int numberPoints; - /** Input data, maximum 10000. */ - private Location[] array; - /** Minimum point coordinate. */ - Location point1 = null; - /** Minimum point coordinate. */ - Location point2 = null; - /** Minimum point length. */ - private static double minNum = Double.MAX_VALUE; - - public static void setMinNum(double minNum) { - ClosestPair.minNum = minNum; - } - - public static void setSecondCount(int secondCount) { - ClosestPair.secondCount = secondCount; - } - - /** secondCount */ - private static int secondCount = 0; - - /** Constructor. */ - ClosestPair(int points) { - numberPoints = points; - array = new Location[numberPoints]; - } - - /** Location class is an auxiliary type to keep points coordinates. */ - public static class Location { - - double x; - double y; - - /** - * @param xpar (IN Parameter) x coordinate
- * @param ypar (IN Parameter) y coordinate
- */ - Location(final double xpar, final double ypar) { // Save x, y coordinates - this.x = xpar; - this.y = ypar; - } - } - - public Location[] createLocation(int numberValues) { - return new Location[numberValues]; - } - - public Location buildLocation(double x, double y) { - return new Location(x, y); - } - - /** - * xPartition function: arrange x-axis. - * - * @param a (IN Parameter) array of points
- * @param first (IN Parameter) first point
- * @param last (IN Parameter) last point
- * @return pivot index - */ - public int xPartition(final Location[] a, final int first, final int last) { - - Location pivot = a[last]; // pivot - int i = first - 1; - Location temp; // Temporarily store value for position transformation - for (int j = first; j <= last - 1; j++) { - if (a[j].x <= pivot.x) { // Less than or less than pivot - i++; - temp = a[i]; // array[i] <-> array[j] - a[i] = a[j]; - a[j] = temp; - } - } - i++; - temp = a[i]; // array[pivot] <-> array[i] - a[i] = a[last]; - a[last] = temp; - return i; // pivot index - } - - /** - * yPartition function: arrange y-axis. - * - * @param a (IN Parameter) array of points
- * @param first (IN Parameter) first point
- * @param last (IN Parameter) last point
- * @return pivot index - */ - public int yPartition(final Location[] a, final int first, final int last) { - - Location pivot = a[last]; // pivot - int i = first - 1; - Location temp; // Temporarily store value for position transformation - for (int j = first; j <= last - 1; j++) { - if (a[j].y <= pivot.y) { // Less than or less than pivot - i++; - temp = a[i]; // array[i] <-> array[j] - a[i] = a[j]; - a[j] = temp; - } - } - i++; - temp = a[i]; // array[pivot] <-> array[i] - a[i] = a[last]; - a[last] = temp; - return i; // pivot index - } - - /** - * xQuickSort function: //x-axis Quick Sorting. - * - * @param a (IN Parameter) array of points
- * @param first (IN Parameter) first point
- * @param last (IN Parameter) last point
- */ - public void xQuickSort(final Location[] a, final int first, final int last) { - - if (first < last) { - int q = xPartition(a, first, last); // pivot - xQuickSort(a, first, q - 1); // Left - xQuickSort(a, q + 1, last); // Right - } - } - - /** - * yQuickSort function: //y-axis Quick Sorting. - * - * @param a (IN Parameter) array of points
- * @param first (IN Parameter) first point
- * @param last (IN Parameter) last point
- */ - public void yQuickSort(final Location[] a, final int first, final int last) { - - if (first < last) { - int q = yPartition(a, first, last); // pivot - yQuickSort(a, first, q - 1); // Left - yQuickSort(a, q + 1, last); // Right - } - } - - /** - * closestPair function: find closest pair. - * - * @param a (IN Parameter) array stored before divide
- * @param indexNum (IN Parameter) number coordinates divideArray
- * @return minimum distance
- */ - public double closestPair(final Location[] a, final int indexNum) { - - Location[] divideArray = new Location[indexNum]; - System.arraycopy(a, 0, divideArray, 0, indexNum); // Copy previous array - int divideX = indexNum / 2; // Intermediate value for divide - Location[] leftArray = new Location[divideX]; // divide - left array - // divide-right array - Location[] rightArray = new Location[indexNum - divideX]; - if (indexNum <= 3) { // If the number of coordinates is 3 or less - return bruteForce(divideArray); - } - // divide-left array - System.arraycopy(divideArray, 0, leftArray, 0, divideX); - // divide-right array - System.arraycopy(divideArray, divideX, rightArray, 0, indexNum - divideX); - - double minLeftArea; // Minimum length of left array - double minRightArea; // Minimum length of right array - double minValue; // Minimum lengt - - minLeftArea = closestPair(leftArray, divideX); // recursive closestPair - minRightArea = closestPair(rightArray, indexNum - divideX); - // window size (= minimum length) - minValue = Math.min(minLeftArea, minRightArea); - - // Create window. Set the size for creating a window - // and creating a new array for the coordinates in the window - for (int i = 0; i < indexNum; i++) { - double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x); - if (xGap < minValue) { - ClosestPair.setSecondCount(secondCount + 1); // size of the array - } else { - if (divideArray[i].x > divideArray[divideX].x) { - break; - } - } - } - // new array for coordinates in window - Location[] firstWindow = new Location[secondCount]; - int k = 0; - for (int i = 0; i < indexNum; i++) { - double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x); - if (xGap < minValue) { // if it's inside a window - firstWindow[k] = divideArray[i]; // put in an array - k++; - } else { - if (divideArray[i].x > divideArray[divideX].x) { - break; - } - } - } - yQuickSort(firstWindow, 0, secondCount - 1); // Sort by y coordinates - /* Coordinates in Window */ - double length; - // size comparison within window - for (int i = 0; i < secondCount - 1; i++) { - for (int j = (i + 1); j < secondCount; j++) { - double xGap = Math.abs(firstWindow[i].x - firstWindow[j].x); - double yGap = Math.abs(firstWindow[i].y - firstWindow[j].y); - if (yGap < minValue) { - length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2)); - // If measured distance is less than current min distance - if (length < minValue) { - // Change minimum distance to current distance - minValue = length; - // Conditional for registering final coordinate - if (length < minNum) { - ClosestPair.setMinNum(length); - point1 = firstWindow[i]; - point2 = firstWindow[j]; - } - } - } else { - break; - } - } - } - ClosestPair.setSecondCount(0); - return minValue; - } - - /** - * bruteForce function: When the number of coordinates is less than 3. - * - * @param arrayParam (IN Parameter) array stored before divide
- * @return
- */ - public double bruteForce(final Location[] arrayParam) { - - double minValue = Double.MAX_VALUE; // minimum distance - double length; - double xGap; // Difference between x coordinates - double yGap; // Difference between y coordinates - double result = 0; - - if (arrayParam.length == 2) { - // Difference between x coordinates - xGap = (arrayParam[0].x - arrayParam[1].x); - // Difference between y coordinates - yGap = (arrayParam[0].y - arrayParam[1].y); - // distance between coordinates - length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2)); - // Conditional statement for registering final coordinate - if (length < minNum) { - ClosestPair.setMinNum(length); - } - point1 = arrayParam[0]; - point2 = arrayParam[1]; - result = length; - } - if (arrayParam.length == 3) { - for (int i = 0; i < arrayParam.length - 1; i++) { - for (int j = (i + 1); j < arrayParam.length; j++) { - // Difference between x coordinates - xGap = (arrayParam[i].x - arrayParam[j].x); - // Difference between y coordinates - yGap = (arrayParam[i].y - arrayParam[j].y); - // distance between coordinates - length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2)); - // If measured distance is less than current min distance - if (length < minValue) { - // Change minimum distance to current distance - minValue = length; - if (length < minNum) { - // Registering final coordinate - ClosestPair.setMinNum(length); - point1 = arrayParam[i]; - point2 = arrayParam[j]; - } - } - } - } - result = minValue; - } - return result; // If only one point returns 0. - } - - /** - * main function: execute class. - * - * @param args (IN Parameter)
- */ - public static void main(final String[] args) { - - // Input data consists of one x-coordinate and one y-coordinate - - ClosestPair cp = new ClosestPair(12); - cp.array[0] = cp.buildLocation(2, 3); - cp.array[1] = cp.buildLocation(2, 16); - cp.array[2] = cp.buildLocation(3, 9); - cp.array[3] = cp.buildLocation(6, 3); - cp.array[4] = cp.buildLocation(7, 7); - cp.array[5] = cp.buildLocation(19, 4); - cp.array[6] = cp.buildLocation(10, 11); - cp.array[7] = cp.buildLocation(15, 2); - cp.array[8] = cp.buildLocation(15, 19); - cp.array[9] = cp.buildLocation(16, 11); - cp.array[10] = cp.buildLocation(17, 13); - cp.array[11] = cp.buildLocation(9, 12); - - System.out.println("Input data"); - System.out.println("Number of points: " + cp.array.length); - for (int i = 0; i < cp.array.length; i++) { - System.out.println("x: " + cp.array[i].x + ", y: " + cp.array[i].y); - } - - cp.xQuickSort(cp.array, 0, cp.array.length - 1); // Sorting by x value - - double result; // minimum distance - - result = cp.closestPair(cp.array, cp.array.length); - // ClosestPair start - // minimum distance coordinates and distance output - System.out.println("Output Data"); - System.out.println("(" + cp.point1.x + ", " + cp.point1.y + ")"); - System.out.println("(" + cp.point2.x + ", " + cp.point2.y + ")"); - System.out.println("Minimum Distance : " + result); - } -} diff --git a/DivideAndConquer/SkylineAlgorithm.java b/DivideAndConquer/SkylineAlgorithm.java deleted file mode 100644 index 3e027fd748b6..000000000000 --- a/DivideAndConquer/SkylineAlgorithm.java +++ /dev/null @@ -1,169 +0,0 @@ -package DivideAndConquer; - -import java.util.ArrayList; -import java.util.Comparator; - -/** - * @author dimgrichr - *

Space complexity: O(n) Time complexity: O(nlogn), because it is a divide and conquer - * algorithm - */ -public class SkylineAlgorithm { - private ArrayList points; - - /** - * Main constructor of the application. ArrayList points gets created, which represents the sum of - * all edges. - */ - public SkylineAlgorithm() { - points = new ArrayList<>(); - } - - /** @return points, the ArrayList that includes all points. */ - public ArrayList getPoints() { - return points; - } - - /** - * The main divide and conquer, and also recursive algorithm. It gets an ArrayList full of points - * as an argument. If the size of that ArrayList is 1 or 2, the ArrayList is returned as it is, or - * with one less point (if the initial size is 2 and one of it's points, is dominated by the other - * one). On the other hand, if the ArrayList's size is bigger than 2, the function is called - * again, twice, with arguments the corresponding half of the initial ArrayList each time. Once - * the flashback has ended, the function produceFinalSkyLine gets called, in order to produce the - * final skyline, and return it. - * - * @param list, the initial list of points - * @return leftSkyLine, the combination of first half's and second half's skyline - * @see Point - */ - public ArrayList produceSubSkyLines(ArrayList list) { - - // part where function exits flashback - int size = list.size(); - if (size == 1) { - return list; - } else if (size == 2) { - if (list.get(0).dominates(list.get(1))) { - list.remove(1); - } else { - if (list.get(1).dominates(list.get(0))) { - list.remove(0); - } - } - return list; - } - - // recursive part of the function - ArrayList leftHalf = new ArrayList<>(); - ArrayList rightHalf = new ArrayList<>(); - for (int i = 0; i < list.size(); i++) { - if (i < list.size() / 2) { - leftHalf.add(list.get(i)); - } else { - rightHalf.add(list.get(i)); - } - } - ArrayList leftSubSkyLine = produceSubSkyLines(leftHalf); - ArrayList rightSubSkyLine = produceSubSkyLines(rightHalf); - - // skyline is produced - return produceFinalSkyLine(leftSubSkyLine, rightSubSkyLine); - } - - /** - * The first half's skyline gets cleared from some points that are not part of the final skyline - * (Points with same x-value and different y=values. The point with the smallest y-value is kept). - * Then, the minimum y-value of the points of first half's skyline is found. That helps us to - * clear the second half's skyline, because, the points of second half's skyline that have greater - * y-value of the minimum y-value that we found before, are dominated, so they are not part of the - * final skyline. Finally, the "cleaned" first half's and second half's skylines, are combined, - * producing the final skyline, which is returned. - * - * @param left the skyline of the left part of points - * @param right the skyline of the right part of points - * @return left the final skyline - */ - public ArrayList produceFinalSkyLine(ArrayList left, ArrayList right) { - - // dominated points of ArrayList left are removed - for (int i = 0; i < left.size() - 1; i++) { - if (left.get(i).x == left.get(i + 1).x && left.get(i).y > left.get(i + 1).y) { - left.remove(i); - i--; - } - } - - // minimum y-value is found - int min = left.get(0).y; - for (int i = 1; i < left.size(); i++) { - if (min > left.get(i).y) { - min = left.get(i).y; - if (min == 1) { - i = left.size(); - } - } - } - - // dominated points of ArrayList right are removed - for (int i = 0; i < right.size(); i++) { - if (right.get(i).y >= min) { - right.remove(i); - i--; - } - } - - // final skyline found and returned - left.addAll(right); - return left; - } - - public static class Point { - private int x; - private int y; - - /** - * The main constructor of Point Class, used to represent the 2 Dimension points. - * - * @param x the point's x-value. - * @param y the point's y-value. - */ - public Point(int x, int y) { - this.x = x; - this.y = y; - } - - /** @return x, the x-value */ - public int getX() { - return x; - } - - /** @return y, the y-value */ - public int getY() { - return y; - } - - /** - * Based on the skyline theory, it checks if the point that calls the function dominates the - * argument point. - * - * @param p1 the point that is compared - * @return true if the point wich calls the function dominates p1 false otherwise. - */ - public boolean dominates(Point p1) { - // checks if p1 is dominated - return (this.x < p1.x && this.y <= p1.y) || (this.x <= p1.x && this.y < p1.y); - } - } - - /** - * It is used to compare the 2 Dimension points, based on their x-values, in order get sorted - * later. - */ - class XComparator implements Comparator { - @Override - public int compare(Point a, Point b) { - return Integer.compare(a.x, b.x); - } - } -} diff --git a/DynamicProgramming/BoardPath.java b/DynamicProgramming/BoardPath.java deleted file mode 100644 index 89f5c805b577..000000000000 --- a/DynamicProgramming/BoardPath.java +++ /dev/null @@ -1,75 +0,0 @@ -package DynamicProgramming; -/* -* this is an important Algo in which -* we have starting and ending of board and we have to reach -* we have to count no. of ways -* that help to reach end point i.e number by rolling dice -* which have 1 to 6 digits - -Test Case: -here target is 10 - -int n=10; - startAlgo(); - System.out.println(bpR(0,n)); - System.out.println(endAlgo()+"ms"); - int[] strg=new int [n+1]; - startAlgo(); - System.out.println(bpRS(0,n,strg)); - System.out.println(endAlgo()+"ms"); - startAlgo(); - System.out.println(bpIS(0,n,strg)); - System.out.println(endAlgo()+"ms"); - - - -*/ -public class BoardPath { - public static long startTime; - public static long endTime; - - public static void startAlgo() { - startTime = System.currentTimeMillis(); - } - - public static long endAlgo() { - endTime = System.currentTimeMillis(); - return endTime - startTime; - } - - public static int bpR(int start, int end) { - if (start == end) { - return 1; - } else if (start > end) return 0; - int count = 0; - for (int dice = 1; dice <= 6; dice++) { - count += bpR(start + dice, end); - } - return count; - } - - public static int bpRS(int curr, int end, int strg[]) { - if (curr == end) { - return 1; - } else if (curr > end) return 0; - if (strg[curr] != 0) return strg[curr]; - int count = 0; - for (int dice = 1; dice <= 6; dice++) { - count += bpRS(curr + dice, end, strg); - } - strg[curr] = count; - return count; - } - - public static int bpIS(int curr, int end, int[] strg) { - strg[end] = 1; - for (int i = end - 1; i >= 0; i--) { - int count = 0; - for (int dice = 1; dice <= 6 && dice + i < strg.length; dice++) { - count += strg[i + dice]; - } - strg[i] = count; - } - return strg[0]; - } -} diff --git a/DynamicProgramming/BruteForceKnapsack.java b/DynamicProgramming/BruteForceKnapsack.java deleted file mode 100644 index a695dd01d058..000000000000 --- a/DynamicProgramming/BruteForceKnapsack.java +++ /dev/null @@ -1,41 +0,0 @@ -package DynamicProgramming; - -/* A Naive recursive implementation -of 0-1 Knapsack problem */ -public class BruteForceKnapsack { - - // A utility function that returns - // maximum of two integers - static int max(int a, int b) { - return (a > b) ? a : b; - } - - // Returns the maximum value that - // can be put in a knapsack of - // capacity W - static int knapSack(int W, int wt[], int val[], int n) { - // Base Case - if (n == 0 || W == 0) return 0; - - // If weight of the nth item is - // more than Knapsack capacity W, - // then this item cannot be included - // in the optimal solution - if (wt[n - 1] > W) return knapSack(W, wt, val, n - 1); - - // Return the maximum of two cases: - // (1) nth item included - // (2) not included - else - return max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1), knapSack(W, wt, val, n - 1)); - } - - // Driver code - public static void main(String args[]) { - int val[] = new int[] {60, 100, 120}; - int wt[] = new int[] {10, 20, 30}; - int W = 50; - int n = val.length; - System.out.println(knapSack(W, wt, val, n)); - } -} diff --git a/DynamicProgramming/CoinChange.java b/DynamicProgramming/CoinChange.java deleted file mode 100644 index f6d4f8f574c2..000000000000 --- a/DynamicProgramming/CoinChange.java +++ /dev/null @@ -1,82 +0,0 @@ -package DynamicProgramming; - -/** @author Varun Upadhyay (https://github.com/varunu28) */ -public class CoinChange { - - // Driver Program - public static void main(String[] args) { - - int amount = 12; - int[] coins = {2, 4, 5}; - - System.out.println( - "Number of combinations of getting change for " + amount + " is: " + change(coins, amount)); - System.out.println( - "Minimum number of coins required for amount :" - + amount - + " is: " - + minimumCoins(coins, amount)); - } - - /** - * This method finds the number of combinations of getting change for a given amount and change - * coins - * - * @param coins The list of coins - * @param amount The amount for which we need to find the change Finds the number of combinations - * of change - */ - public static int change(int[] coins, int amount) { - - int[] combinations = new int[amount + 1]; - combinations[0] = 1; - - for (int coin : coins) { - for (int i = coin; i < amount + 1; i++) { - combinations[i] += combinations[i - coin]; - } - // Uncomment the below line to see the state of combinations for each coin - // printAmount(combinations); - } - - return combinations[amount]; - } - - /** - * This method finds the minimum number of coins needed for a given amount. - * - * @param coins The list of coins - * @param amount The amount for which we need to find the minimum number of coins. Finds the the - * minimum number of coins that make a given value. - */ - public static int minimumCoins(int[] coins, int amount) { - // minimumCoins[i] will store the minimum coins needed for amount i - int[] minimumCoins = new int[amount + 1]; - - minimumCoins[0] = 0; - - for (int i = 1; i <= amount; i++) { - minimumCoins[i] = Integer.MAX_VALUE; - } - for (int i = 1; i <= amount; i++) { - for (int coin : coins) { - if (coin <= i) { - int sub_res = minimumCoins[i - coin]; - if (sub_res != Integer.MAX_VALUE && sub_res + 1 < minimumCoins[i]) - minimumCoins[i] = sub_res + 1; - } - } - } - // Uncomment the below line to see the state of combinations for each coin - // printAmount(minimumCoins); - return minimumCoins[amount]; - } - - // A basic print method which prints all the contents of the array - public static void printAmount(int[] arr) { - for (int i = 0; i < arr.length; i++) { - System.out.print(arr[i] + " "); - } - System.out.println(); - } -} diff --git a/DynamicProgramming/DyanamicProgrammingKnapsack.java b/DynamicProgramming/DyanamicProgrammingKnapsack.java deleted file mode 100644 index 54950cf3a153..000000000000 --- a/DynamicProgramming/DyanamicProgrammingKnapsack.java +++ /dev/null @@ -1,36 +0,0 @@ -package DynamicProgramming; - -// A Dynamic Programming based solution -// for 0-1 Knapsack problem -public class DyanamicProgrammingKnapsack { - static int max(int a, int b) { - return (a > b) ? a : b; - } - - // Returns the maximum value that can - // be put in a knapsack of capacity W - static int knapSack(int W, int wt[], int val[], int n) { - int i, w; - int K[][] = new int[n + 1][W + 1]; - - // Build table K[][] in bottom up manner - for (i = 0; i <= n; i++) { - for (w = 0; w <= W; w++) { - if (i == 0 || w == 0) K[i][w] = 0; - else if (wt[i - 1] <= w) K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]); - else K[i][w] = K[i - 1][w]; - } - } - - return K[n][W]; - } - - // Driver code - public static void main(String args[]) { - int val[] = new int[] {60, 100, 120}; - int wt[] = new int[] {10, 20, 30}; - int W = 50; - int n = val.length; - System.out.println(knapSack(W, wt, val, n)); - } -} diff --git a/DynamicProgramming/EditDistance.java b/DynamicProgramming/EditDistance.java deleted file mode 100644 index 55a101cb8eee..000000000000 --- a/DynamicProgramming/EditDistance.java +++ /dev/null @@ -1,118 +0,0 @@ -package DynamicProgramming; - -/** - * A DynamicProgramming based solution for Edit Distance problem In Java Description of Edit - * Distance with an Example: - * - *

Edit distance is a way of quantifying how dissimilar two strings (e.g., words) are to one - * another, by counting the minimum number of operations required to transform one string into the - * other. The distance operations are the removal, insertion, or substitution of a character in the - * string. - * - *

- * - *

The Distance between "kitten" and "sitting" is 3. A minimal edit script that transforms the - * former into the latter is: - * - *

kitten → sitten (substitution of "s" for "k") sitten → sittin (substitution of "i" for "e") - * sittin → sitting (insertion of "g" at the end). - * - * @author SUBHAM SANGHAI - */ -import java.util.Scanner; - -public class EditDistance { - - public static int minDistance(String word1, String word2) { - int len1 = word1.length(); - int len2 = word2.length(); - // len1+1, len2+1, because finally return dp[len1][len2] - int[][] dp = new int[len1 + 1][len2 + 1]; - /* If second string is empty, the only option is to - insert all characters of first string into second*/ - for (int i = 0; i <= len1; i++) { - dp[i][0] = i; - } - /* If first string is empty, the only option is to - insert all characters of second string into first*/ - for (int j = 0; j <= len2; j++) { - dp[0][j] = j; - } - // iterate though, and check last char - for (int i = 0; i < len1; i++) { - char c1 = word1.charAt(i); - for (int j = 0; j < len2; j++) { - char c2 = word2.charAt(j); - // if last two chars equal - if (c1 == c2) { - // update dp value for +1 length - dp[i + 1][j + 1] = dp[i][j]; - } else { - /* if two characters are different , - then take the minimum of the various operations(i.e insertion,removal,substitution)*/ - int replace = dp[i][j] + 1; - int insert = dp[i][j + 1] + 1; - int delete = dp[i + 1][j] + 1; - - int min = replace > insert ? insert : replace; - min = delete > min ? min : delete; - dp[i + 1][j + 1] = min; - } - } - } - /* return the final answer , after traversing through both the strings*/ - return dp[len1][len2]; - } - - public static void main(String[] args) { - Scanner input = new Scanner(System.in); - String s1, s2; - System.out.println("Enter the First String"); - s1 = input.nextLine(); - System.out.println("Enter the Second String"); - s2 = input.nextLine(); - // ans stores the final Edit Distance between the two strings - int ans = minDistance(s1, s2); - System.out.println( - "The minimum Edit Distance between \"" + s1 + "\" and \"" + s2 + "\" is " + ans); - input.close(); - } - - // edit distance problem - - public static int editDistance(String s1, String s2){ - int[][] storage = new int[s1.length() + 1][s2.length() + 1]; - return editDistance(s1, s2,storage); - - } - - public static int editDistance(String s1, String s2, int[][] storage) { - int m = s1.length(); - int n = s2.length(); - if (storage[m][n] > 0) { - return storage[m][n]; - -} -if (m== 0) { - storage[m][n] = n; - return storage[m][n]; - - } - if (n== 0) { - storage[m][n] = m; - return storage[m][n]; - - } - if (s1.charAt(0) == s2.charAt(0)) { - storage[m][n] = editDistance(s1.substring(1), s2.substring(1), storage); - return storage[m][n]; - - } else { - int op1 = editDistance(s1, s2.substring(1),storage); - int op2 = editDistance(s1.substring(1), s2,storage); - int op3 = editDistance(s1.substring(1),s2.substring(1),storage); - storage[m][n] = 1 + Math.min(op1, Math.min(op2, op3)); - return storage[m][n]; - } - } -} diff --git a/DynamicProgramming/EggDropping.java b/DynamicProgramming/EggDropping.java deleted file mode 100644 index cd2bf82a49cf..000000000000 --- a/DynamicProgramming/EggDropping.java +++ /dev/null @@ -1,45 +0,0 @@ -package DynamicProgramming; - -/** DynamicProgramming solution for the Egg Dropping Puzzle */ -public class EggDropping { - - // min trials with n eggs and m floors - - private static int minTrials(int n, int m) { - - int[][] eggFloor = new int[n + 1][m + 1]; - int result, x; - - for (int i = 1; i <= n; i++) { - eggFloor[i][0] = 0; // Zero trial for zero floor. - eggFloor[i][1] = 1; // One trial for one floor - } - - // j trials for only 1 egg - - for (int j = 1; j <= m; j++) eggFloor[1][j] = j; - - // Using bottom-up approach in DP - - for (int i = 2; i <= n; i++) { - for (int j = 2; j <= m; j++) { - eggFloor[i][j] = Integer.MAX_VALUE; - for (x = 1; x <= j; x++) { - result = 1 + Math.max(eggFloor[i - 1][x - 1], eggFloor[i][j - x]); - - // choose min of all values for particular x - if (result < eggFloor[i][j]) eggFloor[i][j] = result; - } - } - } - - return eggFloor[n][m]; - } - - public static void main(String args[]) { - int n = 2, m = 4; - // result outputs min no. of trials in worst case for n eggs and m floors - int result = minTrials(n, m); - System.out.println(result); - } -} diff --git a/DynamicProgramming/Fibonacci.java b/DynamicProgramming/Fibonacci.java deleted file mode 100644 index 568cd4dd80a2..000000000000 --- a/DynamicProgramming/Fibonacci.java +++ /dev/null @@ -1,91 +0,0 @@ -package DynamicProgramming; - -import java.util.HashMap; -import java.util.Map; -import java.util.Scanner; - -/** @author Varun Upadhyay (https://github.com/varunu28) */ -public class Fibonacci { - - private static Map map = new HashMap<>(); - - public static void main(String[] args) { - - // Methods all returning [0, 1, 1, 2, 3, 5, ...] for n = [0, 1, 2, 3, 4, 5, ...] - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - - System.out.println(fibMemo(n)); - System.out.println(fibBotUp(n)); - System.out.println(fibOptimized(n)); - sc.close(); - } - - /** - * This method finds the nth fibonacci number using memoization technique - * - * @param n The input n for which we have to determine the fibonacci number Outputs the nth - * fibonacci number - */ - public static int fibMemo(int n) { - if (map.containsKey(n)) { - return map.get(n); - } - - int f; - - if (n <= 1) { - f = n; - } else { - f = fibMemo(n - 1) + fibMemo(n - 2); - map.put(n, f); - } - return f; - } - - /** - * This method finds the nth fibonacci number using bottom up - * - * @param n The input n for which we have to determine the fibonacci number Outputs the nth - * fibonacci number - */ - public static int fibBotUp(int n) { - - Map fib = new HashMap<>(); - - for (int i = 0; i <= n; i++) { - int f; - if (i <= 1) { - f = i; - } else { - f = fib.get(i - 1) + fib.get(i - 2); - } - fib.put(i, f); - } - - return fib.get(n); - } - - /** - * This method finds the nth fibonacci number using bottom up - * - * @param n The input n for which we have to determine the fibonacci number Outputs the nth - * fibonacci number - *

This is optimized version of Fibonacci Program. Without using Hashmap and recursion. It - * saves both memory and time. Space Complexity will be O(1) Time Complexity will be O(n) - *

Whereas , the above functions will take O(n) Space. - * @author Shoaib Rayeen (https://github.com/shoaibrayeen) - */ - public static int fibOptimized(int n) { - if (n == 0) { - return 0; - } - int prev = 0, res = 1, next; - for (int i = 2; i <= n; i++) { - next = prev + res; - prev = res; - res = next; - } - return res; - } -} diff --git a/DynamicProgramming/FordFulkerson.java b/DynamicProgramming/FordFulkerson.java deleted file mode 100644 index 419316d71ea5..000000000000 --- a/DynamicProgramming/FordFulkerson.java +++ /dev/null @@ -1,70 +0,0 @@ -package DynamicProgramming; - -import java.util.LinkedList; -import java.util.Queue; -import java.util.Vector; - -public class FordFulkerson { - static final int INF = 987654321; - // edges - static int V; - static int[][] capacity, flow; - - public static void main(String[] args) { - System.out.println("V : 6"); - V = 6; - capacity = new int[V][V]; - - capacity[0][1] = 12; - capacity[0][3] = 13; - capacity[1][2] = 10; - capacity[2][3] = 13; - capacity[2][4] = 3; - capacity[2][5] = 15; - capacity[3][2] = 7; - capacity[3][4] = 15; - capacity[4][5] = 17; - - System.out.println("Max capacity in networkFlow : " + networkFlow(0, 5)); - } - - private static int networkFlow(int source, int sink) { - flow = new int[V][V]; - int totalFlow = 0; - while (true) { - Vector parent = new Vector<>(V); - for (int i = 0; i < V; i++) parent.add(-1); - Queue q = new LinkedList<>(); - parent.set(source, source); - q.add(source); - while (!q.isEmpty() && parent.get(sink) == -1) { - int here = q.peek(); - q.poll(); - for (int there = 0; there < V; ++there) - if (capacity[here][there] - flow[here][there] > 0 && parent.get(there) == -1) { - q.add(there); - parent.set(there, here); - } - } - if (parent.get(sink) == -1) break; - - int amount = INF; - String printer = "path : "; - StringBuilder sb = new StringBuilder(); - for (int p = sink; p != source; p = parent.get(p)) { - amount = Math.min(capacity[parent.get(p)][p] - flow[parent.get(p)][p], amount); - sb.append(p + "-"); - } - sb.append(source); - for (int p = sink; p != source; p = parent.get(p)) { - flow[parent.get(p)][p] += amount; - flow[p][parent.get(p)] -= amount; - } - totalFlow += amount; - printer += sb.reverse() + " / max flow : " + totalFlow; - System.out.println(printer); - } - - return totalFlow; - } -} diff --git a/DynamicProgramming/KadaneAlgorithm.java b/DynamicProgramming/KadaneAlgorithm.java deleted file mode 100644 index f33d941e8da1..000000000000 --- a/DynamicProgramming/KadaneAlgorithm.java +++ /dev/null @@ -1,52 +0,0 @@ -package DynamicProgramming; - -import java.util.Scanner; - -/** - * Program to implement Kadane’s Algorithm to calculate maximum contiguous subarray sum of an array - * Time Complexity: O(n) - * - * @author Nishita Aggarwal - */ -public class KadaneAlgorithm { - - /** - * This method implements Kadane's Algorithm - * - * @param arr The input array - * @return The maximum contiguous subarray sum of the array - */ - static int largestContiguousSum(int arr[]) { - int i, len = arr.length, cursum = 0, maxsum = Integer.MIN_VALUE; - if (len == 0) // empty array - return 0; - for (i = 0; i < len; i++) { - cursum += arr[i]; - if (cursum > maxsum) { - maxsum = cursum; - } - if (cursum <= 0) { - cursum = 0; - } - } - return maxsum; - } - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - int n, arr[], i; - n = sc.nextInt(); - arr = new int[n]; - for (i = 0; i < n; i++) { - arr[i] = sc.nextInt(); - } - int maxContSum = largestContiguousSum(arr); - System.out.println(maxContSum); - sc.close(); - } -} diff --git a/DynamicProgramming/Knapsack.java b/DynamicProgramming/Knapsack.java deleted file mode 100644 index 116af1965acb..000000000000 --- a/DynamicProgramming/Knapsack.java +++ /dev/null @@ -1,31 +0,0 @@ -package DynamicProgramming; - -/** A DynamicProgramming based solution for 0-1 Knapsack problem */ -public class Knapsack { - - private static int knapSack(int W, int wt[], int val[], int n) throws IllegalArgumentException { - if (wt == null || val == null) throw new IllegalArgumentException(); - int i, w; - int rv[][] = new int[n + 1][W + 1]; // rv means return value - - // Build table rv[][] in bottom up manner - for (i = 0; i <= n; i++) { - for (w = 0; w <= W; w++) { - if (i == 0 || w == 0) rv[i][w] = 0; - else if (wt[i - 1] <= w) - rv[i][w] = Math.max(val[i - 1] + rv[i - 1][w - wt[i - 1]], rv[i - 1][w]); - else rv[i][w] = rv[i - 1][w]; - } - } - - return rv[n][W]; - } - - // Driver program to test above function - public static void main(String args[]) { - int val[] = new int[] {50, 100, 130}; - int wt[] = new int[] {10, 20, 40}; - int W = 50; - System.out.println(knapSack(W, wt, val, val.length)); - } -} diff --git a/DynamicProgramming/KnapsackMemoization.java b/DynamicProgramming/KnapsackMemoization.java deleted file mode 100644 index fb4c49d58fd5..000000000000 --- a/DynamicProgramming/KnapsackMemoization.java +++ /dev/null @@ -1,53 +0,0 @@ -package DynamicProgramming; - - -import java.util.Arrays; - -/** - * Recursive Solution for 0-1 knapsack with memoization - */ -public class KnapsackMemoization { - - private static int[][] t; - - - // Returns the maximum value that can - // be put in a knapsack of capacity W - public static int knapsack(int[] wt, int[] value, int W, int n) { - if(t[n][W] != -1) { - return t[n][W]; - } - if (n == 0 || W == 0) { - return 0; - } - if (wt[n - 1] <= W) { - t[n-1][W-wt[n-1]] = knapsack(wt, value, W - wt[n - 1], n - 1); - // Include item in the bag. In that case add the value of the item and call for the remaining items - int tmp1 = value[n - 1] + t[n-1][W-wt[n-1]]; - // Don't include the nth item in the bag anl call for remaining item without reducing the weight - int tmp2 = knapsack(wt, value, W, n - 1); - t[n-1][W] = tmp2; - // include the larger one - int tmp = tmp1 > tmp2 ? tmp1 : tmp2; - t[n][W] = tmp; - return tmp; - // If Weight for the item is more than the desired weight then don't include it - // Call for rest of the n-1 items - } else if (wt[n - 1] > W) { - t[n][W] = knapsack(wt, value, W, n - 1); - return t[n][W]; - } - return -1; - } - - // Driver code - public static void main(String args[]) { - int[] wt = {1, 3, 4, 5}; - int[] value = {1, 4, 5, 7}; - int W = 10; - t = new int[wt.length+1][W+1]; - Arrays.stream(t).forEach(a -> Arrays.fill(a, -1)); - int res = knapsack(wt, value, W, wt.length); - System.out.println("Maximum knapsack value " + res); - } -} diff --git a/DynamicProgramming/LevenshteinDistance.java b/DynamicProgramming/LevenshteinDistance.java deleted file mode 100644 index c18d24f3f7a0..000000000000 --- a/DynamicProgramming/LevenshteinDistance.java +++ /dev/null @@ -1,52 +0,0 @@ -package DynamicProgramming; - -/** - * @author Kshitij VERMA (github.com/kv19971) LEVENSHTEIN DISTANCE dyamic programming implementation - * to show the difference between two strings - * (https://en.wikipedia.org/wiki/Levenshtein_distance) - */ -public class LevenshteinDistance { - private static int minimum(int a, int b, int c) { - if (a < b && a < c) { - return a; - } else if (b < a && b < c) { - return b; - } else { - return c; - } - } - - private static int calculate_distance(String a, String b) { - int len_a = a.length() + 1; - int len_b = b.length() + 1; - int[][] distance_mat = new int[len_a][len_b]; - for (int i = 0; i < len_a; i++) { - distance_mat[i][0] = i; - } - for (int j = 0; j < len_b; j++) { - distance_mat[0][j] = j; - } - for (int i = 0; i < len_a; i++) { - for (int j = 0; j < len_b; j++) { - int cost; - if (a.charAt(i) == b.charAt(j)) { - cost = 0; - } else { - cost = 1; - } - distance_mat[i][j] = - minimum(distance_mat[i - 1][j], distance_mat[i - 1][j - 1], distance_mat[i][j - 1]) - + cost; - } - } - return distance_mat[len_a - 1][len_b - 1]; - } - - public static void main(String[] args) { - String a = ""; // enter your string here - String b = ""; // enter your string here - - System.out.print("Levenshtein distance between " + a + " and " + b + " is: "); - System.out.println(calculate_distance(a, b)); - } -} diff --git a/DynamicProgramming/LongestAlternatingSubsequence.java b/DynamicProgramming/LongestAlternatingSubsequence.java deleted file mode 100644 index 3551edf0262e..000000000000 --- a/DynamicProgramming/LongestAlternatingSubsequence.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - - * Problem Statement: - - * Find Longest Alternating Subsequence - - * A sequence {x1, x2, .. xn} is alternating sequence if its elements satisfy one of the following relations : - - x1 < x2 > x3 < x4 > x5 < …. xn or - x1 > x2 < x3 > x4 < x5 > …. xn -*/ - -import java.io.*; - -public class LongestAlternatingSubsequence { - - /* Function to return longest alternating subsequence length*/ - static int AlternatingLength(int arr[], int n){ - /* - - las[i][0] = Length of the longest - alternating subsequence ending at - index i and last element is - greater than its previous element - - las[i][1] = Length of the longest - alternating subsequence ending at - index i and last element is - smaller than its previous - element - - */ - int las[][] = new int[n][2]; // las = LongestAlternatingSubsequence - - for (int i = 0; i < n; i++) - las[i][0] = las[i][1] = 1; - - int result = 1; // Initialize result - - /* Compute values in bottom up manner */ - for (int i = 1; i < n; i++){ - - /* Consider all elements as previous of arr[i]*/ - for (int j = 0; j < i; j++){ - - /* If arr[i] is greater, then check with las[j][1] */ - if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) - las[i][0] = las[j][1] + 1; - - /* If arr[i] is smaller, then check with las[j][0]*/ - if( arr[j] > arr[i] && las[i][1] < las[j][0] + 1) - las[i][1] = las[j][0] + 1; - } - - /* Pick maximum of both values at index i */ - if (result < Math.max(las[i][0], las[i][1])) - result = Math.max(las[i][0], las[i][1]); - } - - return result; - } - - public static void main(String[] args) - { - int arr[] = { 10, 22, 9, 33, 49,50, 31, 60 }; - int n = arr.length; - System.out.println("Length of Longest "+"alternating subsequence is " +AlternatingLength(arr, n)); - } -} diff --git a/DynamicProgramming/LongestCommonSubsequence.java b/DynamicProgramming/LongestCommonSubsequence.java deleted file mode 100644 index f39587010f14..000000000000 --- a/DynamicProgramming/LongestCommonSubsequence.java +++ /dev/null @@ -1,64 +0,0 @@ -package DynamicProgramming; - -class LongestCommonSubsequence { - - public static String getLCS(String str1, String str2) { - - // At least one string is null - if (str1 == null || str2 == null) return null; - - // At least one string is empty - if (str1.length() == 0 || str2.length() == 0) return ""; - - String[] arr1 = str1.split(""); - String[] arr2 = str2.split(""); - - // lcsMatrix[i][j] = LCS of first i elements of arr1 and first j characters of arr2 - int[][] lcsMatrix = new int[arr1.length + 1][arr2.length + 1]; - - for (int i = 0; i < arr1.length + 1; i++) lcsMatrix[i][0] = 0; - for (int j = 1; j < arr2.length + 1; j++) lcsMatrix[0][j] = 0; - for (int i = 1; i < arr1.length + 1; i++) { - for (int j = 1; j < arr2.length + 1; j++) { - if (arr1[i - 1].equals(arr2[j - 1])) { - lcsMatrix[i][j] = lcsMatrix[i - 1][j - 1] + 1; - } else { - lcsMatrix[i][j] = - lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1] ? lcsMatrix[i - 1][j] : lcsMatrix[i][j - 1]; - } - } - } - return lcsString(str1, str2, lcsMatrix); - } - - public static String lcsString(String str1, String str2, int[][] lcsMatrix) { - StringBuilder lcs = new StringBuilder(); - int i = str1.length(), j = str2.length(); - while (i > 0 && j > 0) { - if (str1.charAt(i - 1) == str2.charAt(j - 1)) { - lcs.append(str1.charAt(i - 1)); - i--; - j--; - } else if (lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1]) { - i--; - } else { - j--; - } - } - return lcs.reverse().toString(); - } - - public static void main(String[] args) { - String str1 = "DSGSHSRGSRHTRD"; - String str2 = "DATRGAGTSHS"; - String lcs = getLCS(str1, str2); - - // Print LCS - if (lcs != null) { - System.out.println("String 1: " + str1); - System.out.println("String 2: " + str2); - System.out.println("LCS: " + lcs); - System.out.println("LCS length: " + lcs.length()); - } - } -} diff --git a/DynamicProgramming/LongestIncreasingSubsequence.java b/DynamicProgramming/LongestIncreasingSubsequence.java deleted file mode 100644 index 90fa08347b72..000000000000 --- a/DynamicProgramming/LongestIncreasingSubsequence.java +++ /dev/null @@ -1,89 +0,0 @@ -package DynamicProgramming; - -import java.util.Scanner; - -/** @author Afrizal Fikri (https://github.com/icalF) */ -public class LongestIncreasingSubsequence { - public static void main(String[] args) { - - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - - int arr[] = new int[n]; - for (int i = 0; i < n; i++) { - arr[i] = sc.nextInt(); - } - - System.out.println(LIS(arr)); - System.out.println(findLISLen(arr)); - sc.close(); - } - - private static int upperBound(int[] ar, int l, int r, int key) { - while (l < r - 1) { - int m = (l + r) >>> 1; - if (ar[m] >= key) r = m; - else l = m; - } - - return r; - } - - private static int LIS(int[] array) { - int N = array.length; - if (N == 0) return 0; - - int[] tail = new int[N]; - - // always points empty slot in tail - int length = 1; - - tail[0] = array[0]; - for (int i = 1; i < N; i++) { - - // new smallest value - if (array[i] < tail[0]) tail[0] = array[i]; - - // array[i] extends largest subsequence - else if (array[i] > tail[length - 1]) tail[length++] = array[i]; - - // array[i] will become end candidate of an existing subsequence or - // Throw away larger elements in all LIS, to make room for upcoming grater elements than - // array[i] - // (and also, array[i] would have already appeared in one of LIS, identify the location and - // replace it) - else tail[upperBound(tail, -1, length - 1, array[i])] = array[i]; - } - - return length; - } - - /** @author Alon Firestein (https://github.com/alonfirestein) */ - - // A function for finding the length of the LIS algorithm in O(nlogn) complexity. - public static int findLISLen(int a[]) { - int size = a.length; - int arr[] = new int[size]; - arr[0] = a[0]; - int lis = 1; - for (int i = 1; i < size; i++) { - int index = binarySearchBetween(arr, lis, a[i]); - arr[index] = a[i]; - if (index > lis) lis++; - } - return lis; - } - // O(logn) - private static int binarySearchBetween(int[] t, int end, int key) { - int left = 0; - int right = end; - if (key < t[0]) return 0; - if (key > t[end]) return end + 1; - while (left < right - 1) { - int middle = (left + right) / 2; - if (t[middle] < key) left = middle; - else right = middle; - } - return right; - } -} diff --git a/DynamicProgramming/LongestPalindromicSubsequence.java b/DynamicProgramming/LongestPalindromicSubsequence.java deleted file mode 100644 index 0626c208bdd7..000000000000 --- a/DynamicProgramming/LongestPalindromicSubsequence.java +++ /dev/null @@ -1,59 +0,0 @@ -package DynamicProgramming; - -/** - * Algorithm explanation https://www.educative.io/edpresso/longest-palindromic-subsequence-algorithm - */ -public class LongestPalindromicSubsequence { - public static void main(String[] args) { - String a = "BBABCBCAB"; - String b = "BABCBAB"; - - String aLPS = LPS(a); - String bLPS = LPS(b); - - System.out.println(a + " => " + aLPS); - System.out.println(b + " => " + bLPS); - } - - public static String LPS(String original) throws IllegalArgumentException { - StringBuilder reverse = new StringBuilder(original); - reverse = reverse.reverse(); - return recursiveLPS(original, reverse.toString()); - } - - private static String recursiveLPS(String original, String reverse) { - String bestResult = ""; - - // no more chars, then return empty - if (original.length() == 0 || reverse.length() == 0) { - bestResult = ""; - } else { - - // if the last chars match, then remove it from both strings and recur - if (original.charAt(original.length() - 1) == reverse.charAt(reverse.length() - 1)) { - String bestSubResult = - recursiveLPS( - original.substring(0, original.length() - 1), - reverse.substring(0, reverse.length() - 1)); - - bestResult = reverse.charAt(reverse.length() - 1) + bestSubResult; - } else { - // otherwise (1) ignore the last character of reverse, and recur on original and updated - // reverse again - // (2) ignore the last character of original and recur on the updated original and reverse - // again - // then select the best result from these two subproblems. - - String bestSubResult1 = recursiveLPS(original, reverse.substring(0, reverse.length() - 1)); - String bestSubResult2 = recursiveLPS(original.substring(0, original.length() - 1), reverse); - if (bestSubResult1.length() > bestSubResult2.length()) { - bestResult = bestSubResult1; - } else { - bestResult = bestSubResult2; - } - } - } - - return bestResult; - } -} diff --git a/DynamicProgramming/LongestPalindromicSubstring.java b/DynamicProgramming/LongestPalindromicSubstring.java deleted file mode 100644 index 1652567676fb..000000000000 --- a/DynamicProgramming/LongestPalindromicSubstring.java +++ /dev/null @@ -1,53 +0,0 @@ -package DynamicProgramming; - -/* - * Algorithm explanation https://leetcode.com/problems/longest-palindromic-substring/ - */ -public class LongestPalindromicSubstring { - public static void main(String[] args) { - String a = "babad"; - String b = "cbbd"; - - String aLPS = LPS(a); - String bLPS = LPS(b); - - System.out.println(a + " => " + aLPS); - System.out.println(b + " => " + bLPS); - } - - private static String LPS(String input) { - if(input == null || input.length() == 0){ - return input; - } - boolean arr[][] = new boolean[input.length()][input.length()]; - int start = 0, end = 0; - for (int g = 0; g < input.length(); g++) { - for (int i = 0, j = g; j < input.length(); i++, j++) { - - if (g == 0) { - arr[i][j] = true; - } else if (g == 1) { - if (input.charAt(i) == input.charAt(j)) { - arr[i][j] = true; - } else { - arr[i][j] = false; - } - } else { - - if (input.charAt(i) == input.charAt(j) && arr[i + 1][j - 1]) { - arr[i][j] = true; - } else { - arr[i][j] = false; - } - } - - if (arr[i][j]) { - start = i; - end = j; - } - } - } - return input.substring(start, end + 1); - } - -} diff --git a/DynamicProgramming/LongestValidParentheses.java b/DynamicProgramming/LongestValidParentheses.java deleted file mode 100644 index 24c8ea4a1daf..000000000000 --- a/DynamicProgramming/LongestValidParentheses.java +++ /dev/null @@ -1,58 +0,0 @@ -package DynamicProgramming; - -import java.util.Scanner; - -/** - * Given a string containing just the characters '(' and ')', find the length of the longest valid - * (well-formed) parentheses substring. - * - * @author Libin Yang (https://github.com/yanglbme) - * @since 2018/10/5 - */ -public class LongestValidParentheses { - - public static int getLongestValidParentheses(String s) { - if (s == null || s.length() < 2) { - return 0; - } - char[] chars = s.toCharArray(); - int n = chars.length; - int[] res = new int[n]; - res[0] = 0; - res[1] = chars[1] == ')' && chars[0] == '(' ? 2 : 0; - - int max = res[1]; - - for (int i = 2; i < n; ++i) { - if (chars[i] == ')') { - if (chars[i - 1] == '(') { - res[i] = res[i - 2] + 2; - } else { - int index = i - res[i - 1] - 1; - if (index >= 0 && chars[index] == '(') { - // ()(()) - res[i] = res[i - 1] + 2 + (index - 1 >= 0 ? res[index - 1] : 0); - } - } - } - max = Math.max(max, res[i]); - } - - return max; - } - - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - - while (true) { - String str = sc.nextLine(); - if ("quit".equals(str)) { - break; - } - - System.out.println("Len is: " + getLongestValidParentheses(str)); - } - - sc.close(); - } -} diff --git a/DynamicProgramming/MatrixChainMultiplication.java b/DynamicProgramming/MatrixChainMultiplication.java deleted file mode 100644 index 9a17fe815fa1..000000000000 --- a/DynamicProgramming/MatrixChainMultiplication.java +++ /dev/null @@ -1,135 +0,0 @@ -package DynamicProgramming; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Scanner; - -public class MatrixChainMultiplication { - private static Scanner scan = new Scanner(System.in); - private static ArrayList mArray = new ArrayList<>(); - private static int size; - private static int[][] m; - private static int[][] s; - private static int[] p; - - public static void main(String[] args) { - int count = 1; - while (true) { - String[] mSize = input("input size of matrix A(" + count + ") ( ex. 10 20 ) : "); - int col = Integer.parseInt(mSize[0]); - if (col == 0) break; - int row = Integer.parseInt(mSize[1]); - - Matrix matrix = new Matrix(count, col, row); - mArray.add(matrix); - count++; - } - for (Matrix m : mArray) { - System.out.format("A(%d) = %2d x %2d%n", m.count(), m.col(), m.row()); - } - - size = mArray.size(); - m = new int[size + 1][size + 1]; - s = new int[size + 1][size + 1]; - p = new int[size + 1]; - - for (int i = 0; i < size + 1; i++) { - Arrays.fill(m[i], -1); - Arrays.fill(s[i], -1); - } - - for (int i = 0; i < p.length; i++) { - p[i] = i == 0 ? mArray.get(i).col() : mArray.get(i - 1).row(); - } - - matrixChainOrder(); - for (int i = 0; i < size; i++) { - System.out.print("-------"); - } - System.out.println(); - printArray(m); - for (int i = 0; i < size; i++) { - System.out.print("-------"); - } - System.out.println(); - printArray(s); - for (int i = 0; i < size; i++) { - System.out.print("-------"); - } - System.out.println(); - - System.out.println("Optimal solution : " + m[1][size]); - System.out.print("Optimal parens : "); - printOptimalParens(1, size); - } - - private static void printOptimalParens(int i, int j) { - if (i == j) { - System.out.print("A" + i); - } else { - System.out.print("("); - printOptimalParens(i, s[i][j]); - printOptimalParens(s[i][j] + 1, j); - System.out.print(")"); - } - } - - private static void printArray(int[][] array) { - for (int i = 1; i < size + 1; i++) { - for (int j = 1; j < size + 1; j++) { - System.out.print(String.format("%7d", array[i][j])); - } - System.out.println(); - } - } - - private static void matrixChainOrder() { - for (int i = 1; i < size + 1; i++) { - m[i][i] = 0; - } - - for (int l = 2; l < size + 1; l++) { - for (int i = 1; i < size - l + 2; i++) { - int j = i + l - 1; - m[i][j] = Integer.MAX_VALUE; - - for (int k = i; k < j; k++) { - int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; - if (q < m[i][j]) { - m[i][j] = q; - s[i][j] = k; - } - } - } - } - } - - private static String[] input(String string) { - System.out.print(string); - return (scan.nextLine().split(" ")); - } -} - -class Matrix { - private int count; - private int col; - private int row; - - Matrix(int count, int col, int row) { - this.count = count; - this.col = col; - this.row = row; - } - - int count() { - return count; - } - - int col() { - return col; - } - - int row() { - return row; - } -} diff --git a/DynamicProgramming/MemoizationTechniqueKnapsack.java b/DynamicProgramming/MemoizationTechniqueKnapsack.java deleted file mode 100644 index 3c469c11a375..000000000000 --- a/DynamicProgramming/MemoizationTechniqueKnapsack.java +++ /dev/null @@ -1,56 +0,0 @@ -package DynamicProgramming; -// Here is the top-down approach of -// dynamic programming -public class MemoizationTechniqueKnapsack { - - // A utility function that returns - // maximum of two integers - static int max(int a, int b) { - return (a > b) ? a : b; - } - - // Returns the value of maximum profit - static int knapSackRec(int W, int wt[], int val[], int n, int[][] dp) { - - // Base condition - if (n == 0 || W == 0) return 0; - - if (dp[n][W] != -1) return dp[n][W]; - - if (wt[n - 1] > W) - - // Store the value of function call - // stack in table before return - return dp[n][W] = knapSackRec(W, wt, val, n - 1, dp); - else - - // Return value of table after storing - return dp[n][W] = - max( - (val[n - 1] + knapSackRec(W - wt[n - 1], wt, val, n - 1, dp)), - knapSackRec(W, wt, val, n - 1, dp)); - } - - static int knapSack(int W, int wt[], int val[], int N) { - - // Declare the table dynamically - int dp[][] = new int[N + 1][W + 1]; - - // Loop to initially filled the - // table with -1 - for (int i = 0; i < N + 1; i++) for (int j = 0; j < W + 1; j++) dp[i][j] = -1; - - return knapSackRec(W, wt, val, N, dp); - } - - // Driver Code - public static void main(String[] args) { - int val[] = {60, 100, 120}; - int wt[] = {10, 20, 30}; - - int W = 50; - int N = val.length; - - System.out.println(knapSack(W, wt, val, N)); - } -} diff --git a/DynamicProgramming/MinimumPathSum.java b/DynamicProgramming/MinimumPathSum.java deleted file mode 100644 index cc0fcaa4ed98..000000000000 --- a/DynamicProgramming/MinimumPathSum.java +++ /dev/null @@ -1,81 +0,0 @@ -package DynamicProgramming; - -/* -Given the following grid with length m and width n: -\---\---\---\ (n) -\ 1 \ 3 \ 1 \ -\---\---\---\ -\ 1 \ 5 \ 1 \ -\---\---\---\ -\ 4 \ 2 \ 1 \ -\---\---\---\ -(m) -Find the path where its sum is the smallest. - -All numbers given are positive. -The Time Complexity of your algorithm should be smaller than or equal to O(mn). -The Space Complexity of your algorithm should be smaller than or equal to O(mn). -You can only move from the top left corner to the down right corner. -You can only move one step down or right. - -EXAMPLE: -INPUT: grid = [[1,3,1],[1,5,1],[4,2,1]] -OUTPUT: 7 -EXPLANATIONS: 1 + 3 + 1 + 1 + 1 = 7 - -For more information see https://www.geeksforgeeks.org/maximum-path-sum-matrix/ -*/ -public class MinimumPathSum { - - public void testRegular() { - int[][] grid = { - {1, 3, 1}, - {1, 5, 1}, - {4, 2, 1} - }; - System.out.println(minimumPathSum(grid)); - } - - public void testLessColumns() { - int[][] grid = { - {1, 2}, - {5, 6}, - {1, 1} - }; - System.out.println(minimumPathSum(grid)); - } - - public void testLessRows() { - int[][] grid = { - {2, 3, 3}, - {7, 2, 1} - }; - System.out.println(minimumPathSum(grid)); - } - - public void testOneRowOneColumn() { - int[][] grid = {{2}}; - System.out.println(minimumPathSum(grid)); - } - - public static int minimumPathSum(int[][] grid) { - int m = grid.length, n = grid[0].length; - if (n == 0) { - return 0; - } - int[][] dp = new int[m][n]; - dp[0][0] = grid[0][0]; - for (int i = 0; i < n - 1; i++) { - dp[0][i + 1] = dp[0][i] + grid[0][i + 1]; - } - for (int i = 0; i < m - 1; i++) { - dp[i + 1][0] = dp[i][0] + grid[i + 1][0]; - } - for (int i = 1; i < m; i++) { - for (int j = 1; j < n; j++) { - dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; - } - } - return dp[m - 1][n - 1]; - } -} diff --git a/DynamicProgramming/MinimumSumPartition.java b/DynamicProgramming/MinimumSumPartition.java deleted file mode 100644 index c47984dbc941..000000000000 --- a/DynamicProgramming/MinimumSumPartition.java +++ /dev/null @@ -1,86 +0,0 @@ -package DynamicProgramming; -// Partition a set into two subsets such that the difference of subset sums is minimum - -/* -Input: arr[] = {1, 6, 11, 5} -Output: 1 -Explanation: -Subset1 = {1, 5, 6}, sum of Subset1 = 12 -Subset2 = {11}, sum of Subset2 = 11 - -Input: arr[] = {36, 7, 46, 40} -Output: 23 -Explanation: -Subset1 = {7, 46} ; sum of Subset1 = 53 -Subset2 = {36, 40} ; sum of Subset2 = 76 - */ - -public class MinimumSumPartition { - public static int subSet(int[] arr) { - int n = arr.length; - int sum = getSum(arr); - boolean[][] dp = new boolean[n + 1][sum + 1]; - for (int i = 0; i <= n; i++) { - dp[i][0] = true; - } - for (int j = 0; j <= sum; j++) { - dp[0][j] = false; - } - - // fill dp array - for (int i = 1; i <= n; i++) { - for (int j = 1; j <= sum; j++) { - if (arr[i - 1] < j) { - dp[i][j] = dp[i - 1][j - arr[i - 1]] || dp[i - 1][j]; - } else if (arr[i - 1] == j) { - dp[i][j] = true; - } else { - dp[i][j] = dp[i - 1][j]; - } - } - } - - // fill the index array - int[] index = new int[sum]; - int p = 0; - for (int i = 0; i <= sum / 2; i++) { - if (dp[n][i]) { - index[p++] = i; - } - } - - return getMin(index, sum); - } - - /** - * Calculate sum of array elements - * - * @param arr the array - * @return sum of given array - */ - public static int getSum(int[] arr) { - int sum = 0; - for (int temp : arr) { - sum += temp; - } - return sum; - } - - public static int getMin(int[] arr, int sum) { - if (arr.length == 0) { - return 0; - } - int min = Integer.MAX_VALUE; - for (int temp : arr) { - min = Math.min(min, sum - 2 * temp); - } - return min; - } - - /** Driver Code */ - public static void main(String[] args) { - assert subSet(new int[] {1, 6, 11, 5}) == 1; - assert subSet(new int[] {36, 7, 46, 40}) == 23; - assert subSet(new int[] {1, 2, 3, 9}) == 3; - } -} diff --git a/DynamicProgramming/PalindromicPartitioning.java b/DynamicProgramming/PalindromicPartitioning.java deleted file mode 100644 index e11837622597..000000000000 --- a/DynamicProgramming/PalindromicPartitioning.java +++ /dev/null @@ -1,94 +0,0 @@ -package DynamicProgramming; - -import java.util.Scanner; - -/** - * @file - * @brief Implements [Palindrome - * Partitioning](https://leetcode.com/problems/palindrome-partitioning-ii/) - * algorithm, giving you the minimum number of partitions you need to make - * - * @details - * palindrome partitioning uses dynamic programming and goes to all the possible - * partitions to find the minimum you are given a string and you need to give - * minimum number of partitions needed to divide it into a number of palindromes - * [Palindrome Partitioning] - * (https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/) overall time - * complexity O(n^2) For example: example 1:- String : "nitik" Output : 2 => "n - * | iti | k" For example: example 2:- String : "ababbbabbababa" Output : 3 => - * "aba | b | bbabb | ababa" - * @author [Syed] (https://github.com/roeticvampire) - */ -public class PalindromicPartitioning { - - public static int minimalpartitions(String word){ - int len=word.length(); - /* We Make two arrays to create a bottom-up solution. - minCuts[i] = Minimum number of cuts needed for palindrome partitioning of substring word[0..i] - isPalindrome[i][j] = true if substring str[i..j] is palindrome - Base Condition: C[i] is 0 if P[0][i]= true - */ - int[] minCuts = new int[len]; - boolean[][] isPalindrome = new boolean[len][len]; - - int i, j, L; // different looping variables - - // Every substring of length 1 is a palindrome - for (i = 0; i < len; i++) { - isPalindrome[i][i] = true; - } - - /* L is substring length. Build the solution in bottom up manner by considering all substrings of length starting from 2 to n. */ - for (L = 2; L <= len; L++) { - // For substring of length L, set different possible starting indexes - for (i = 0; i < len - L + 1; i++) { - j = i + L - 1; // Ending index - // If L is 2, then we just need to - // compare two characters. Else need to - // check two corner characters and value - // of P[i+1][j-1] - if (L == 2) - isPalindrome[i][j] = (word.charAt(i) == word.charAt(j)); - else - { - if((word.charAt(i) == word.charAt(j)) && isPalindrome[i + 1][j - 1]) - isPalindrome[i][j] =true; - else - isPalindrome[i][j]=false; - - } - } - } - - //We find the minimum for each index - for (i = 0; i < len; i++) { - if (isPalindrome[0][i] == true) - minCuts[i] = 0; - else { - minCuts[i] = Integer.MAX_VALUE; - for (j = 0; j < i; j++) { - if (isPalindrome[j + 1][i] == true && 1 + minCuts[j] < minCuts[i]) - minCuts[i] = 1 + minCuts[j]; - } - } - } - - // Return the min cut value for complete - // string. i.e., str[0..n-1] - return minCuts[len - 1]; - } - - - - public static void main(String[] args) { - Scanner input = new Scanner(System.in); - String word; - System.out.println("Enter the First String"); - word = input.nextLine(); - // ans stores the final minimal cut count needed for partitioning - int ans = minimalpartitions(word); - System.out.println( - "The minimum cuts needed to partition \"" + word + "\" into palindromes is " + ans); - input.close(); - } -} diff --git a/DynamicProgramming/RegexMatching.java b/DynamicProgramming/RegexMatching.java deleted file mode 100644 index 724e53886f4c..000000000000 --- a/DynamicProgramming/RegexMatching.java +++ /dev/null @@ -1,171 +0,0 @@ -package DynamicProgramming; - -/** - * Given a text and wildcard pattern implement a wildcard pattern matching - * algorithm that finds if wildcard is matched with text. The matching should - * cover the entire text - * ?-> matches single characters - * *-> match the sequence of characters - **/ - -/** - * For calculation of Time and Space Complexity. Let N be length of src and M be length of pat - **/ - -public class RegexMatching { - - // Method 1: Using Recursion - // Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space - static boolean regexRecursion(String src, String pat) { - if (src.length() == 0 && pat.length() == 0) { - return true; - } - if (src.length() != 0 && pat.length() == 0) { - return false; - } - if (src.length() == 0 && pat.length() != 0) { - for (int i = 0; i < pat.length(); i++) { - if (pat.charAt(i) != '*') { - return false; - } - } - return true; - } - char chs = src.charAt(0); - char chp = pat.charAt(0); - - String ros = src.substring(1); - String rop = pat.substring(1); - - boolean ans; - if (chs == chp || chp == '?') { - ans = regexRecursion(ros, rop); - } else if (chp == '*') { - boolean blank = regexRecursion(src, rop); - boolean multiple = regexRecursion(ros, pat); - ans = blank || multiple; - } else { - ans = false; - } - return ans; - } - - // Method 2: Using Recursion and breaking string using virtual index - // Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space - static boolean regexRecursion(String src, String pat, int svidx, int pvidx) { - if (src.length() == svidx && pat.length() == pvidx) { - return true; - } - if (src.length() != svidx && pat.length() == pvidx) { - return false; - } - if (src.length() == svidx && pat.length() != pvidx) { - for (int i = pvidx; i < pat.length(); i++) { - if (pat.charAt(i) != '*') { - return false; - } - } - return true; - } - char chs = src.charAt(svidx); - char chp = pat.charAt(pvidx); - - boolean ans; - if (chs == chp || chp == '?') { - ans = regexRecursion(src, pat, svidx + 1, pvidx + 1); - } else if (chp == '*') { - boolean blank = regexRecursion(src, pat, svidx, pvidx + 1); - boolean multiple = regexRecursion(src, pat, svidx + 1, pvidx); - ans = blank || multiple; - } else { - ans = false; - } - return ans; - } - - // Method 3: Top-Down DP(Memoization) - // Time Complexity=0(N*M) Space Complexity=0(N*M)+Recursion Extra Space - static boolean regexRecursion(String src, String pat, int svidx, int pvidx, int[][] strg) { - if (src.length() == svidx && pat.length() == pvidx) { - return true; - } - if (src.length() != svidx && pat.length() == pvidx) { - return false; - } - if (src.length() == svidx && pat.length() != pvidx) { - for (int i = pvidx; i < pat.length(); i++) { - if (pat.charAt(i) != '*') { - return false; - } - } - return true; - } - if (strg[svidx][pvidx] != 0) { - return strg[svidx][pvidx] == 1 ? false : true; - } - char chs = src.charAt(svidx); - char chp = pat.charAt(pvidx); - - boolean ans; - if (chs == chp || chp == '?') { - ans = regexRecursion(src, pat, svidx + 1, pvidx + 1, strg); - } else if (chp == '*') { - boolean blank = regexRecursion(src, pat, svidx, pvidx + 1, strg); - boolean multiple = regexRecursion(src, pat, svidx + 1, pvidx, strg); - ans = blank || multiple; - } else { - ans = false; - } - strg[svidx][pvidx] = ans == false ? 1 : 2; - return ans; - } - - // Method 4: Bottom-Up DP(Tabulation) - // Time Complexity=0(N*M) Space Complexity=0(N*M) - static boolean regexBU(String src, String pat) { - - boolean strg[][] = new boolean[src.length() + 1][pat.length() + 1]; - strg[src.length()][pat.length()] = true; - for (int row = src.length(); row >= 0; row--) { - for (int col = pat.length() - 1; col >= 0; col--) { - if (row == src.length()) { - if (pat.charAt(col) == '*') { - strg[row][col] = strg[row][col + 1]; - } else { - strg[row][col] = false; - } - } else { - char chs = src.charAt(row); - char chp = pat.charAt(col); - - boolean ans; - if (chs == chp || chp == '?') { - ans = strg[row + 1][col + 1]; - } else if (chp == '*') { - boolean blank = strg[row][col + 1]; - boolean multiple = strg[row + 1][col]; - ans = blank || multiple; - } else { - ans = false; - } - strg[row][col] = ans; - } - } - } - return strg[0][0]; - } - - public static void main(String[] args) { - - String src = "aa"; - String pat = "*"; - System.out.println("Method 1: "+regexRecursion(src, pat)); - System.out.println("Method 2: "+regexRecursion(src, pat, 0, 0)); - System.out.println("Method 3: "+regexRecursion(src, pat, 0, 0, new int[src.length()][pat.length()])); - System.out.println("Method 4: "+regexBU(src, pat)); - - } - -} -// Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/ -// Question Link : https://practice.geeksforgeeks.org/problems/wildcard-pattern-matching/1 diff --git a/DynamicProgramming/RodCutting.java b/DynamicProgramming/RodCutting.java deleted file mode 100644 index f3afb4a5cc31..000000000000 --- a/DynamicProgramming/RodCutting.java +++ /dev/null @@ -1,29 +0,0 @@ -package DynamicProgramming; - -/** - * A DynamicProgramming solution for Rod cutting problem Returns the best obtainable price for a rod - * of length n and price[] as prices of different pieces - */ -public class RodCutting { - - private static int cutRod(int[] price, int n) { - int val[] = new int[n + 1]; - val[0] = 0; - - for (int i = 1; i <= n; i++) { - int max_val = Integer.MIN_VALUE; - for (int j = 0; j < i; j++) max_val = Math.max(max_val, price[j] + val[i - j - 1]); - - val[i] = max_val; - } - - return val[n]; - } - - // main function to test - public static void main(String args[]) { - int[] arr = new int[] {2, 5, 13, 19, 20}; - int result = cutRod(arr, arr.length); - System.out.println("Maximum Obtainable Value is " + result); - } -} diff --git a/DynamicProgramming/SubsetSum.java b/DynamicProgramming/SubsetSum.java deleted file mode 100644 index 2e97ffb18042..000000000000 --- a/DynamicProgramming/SubsetSum.java +++ /dev/null @@ -1,44 +0,0 @@ -package DynamicProgramming; - -public class SubsetSum { - - /** Driver Code */ - public static void main(String[] args) { - int[] arr = new int[] {50, 4, 10, 15, 34}; - assert subsetSum(arr, 64); /* 4 + 10 + 15 + 34 = 64 */ - assert subsetSum(arr, 99); /* 50 + 15 + 34 = 99 */ - assert !subsetSum(arr, 5); - assert !subsetSum(arr, 66); - } - - /** - * Test if a set of integers contains a subset that sum to a given integer. - * - * @param arr the array contains integers. - * @param sum target sum of subset. - * @return {@code true} if subset exists, otherwise {@code false}. - */ - private static boolean subsetSum(int[] arr, int sum) { - int n = arr.length; - boolean[][] isSum = new boolean[n + 2][sum + 1]; - - isSum[n + 1][0] = true; - for (int i = 1; i <= sum; i++) { - isSum[n + 1][i] = false; - } - - for (int i = n; i > 0; i--) { - isSum[i][0] = true; - for (int j = 1; j <= arr[i - 1] - 1; j++) { - if (j <= sum) { - isSum[i][j] = isSum[i + 1][j]; - } - } - for (int j = arr[i - 1]; j <= sum; j++) { - isSum[i][j] = (isSum[i + 1][j] || isSum[i + 1][j - arr[i - 1]]); - } - } - - return isSum[1][sum]; - } -} diff --git a/DynamicProgramming/WineProblem.java b/DynamicProgramming/WineProblem.java deleted file mode 100644 index 6462793002f9..000000000000 --- a/DynamicProgramming/WineProblem.java +++ /dev/null @@ -1,88 +0,0 @@ -package DynamicProgramming; - -/** - * Imagine you have a collection of N wines placed next to each other on the - * shelf. The price of ith wine is pi(Prices of different wines are different). - * Because wine gets better every year supposing today is year 1, on year y the - * price would be y*pi i.e y times the value of the initial year. You want to - * sell all wines but you have to sell one wine per year. One more constraint on - * each year you are allowed to sell either leftmost or rightmost wine on the - * shelf. You are not allowed to reorder. You have to find the maximum profit - **/ - -public class WineProblem { - - // Method 1: Using Recursion - // Time Complexity=0(2^N) Space Complexity=Recursion extra space - public static int WPRecursion(int[] arr, int si, int ei) { - int n = arr.length; - int year = (n - (ei - si + 1)) + 1; - if (si == ei) { - return arr[si] * year; - } - - int start = WPRecursion(arr, si + 1, ei) + arr[si] * year; - int end = WPRecursion(arr, si, ei - 1) + arr[ei] * year; - - int ans = Math.max(start, end); - - return ans; - } - - // Method 2: Top-Down DP(Memoization) - // Time Complexity=0(N*N) Space Complexity=0(N*N)+Recursion extra space - public static int WPTD(int[] arr, int si, int ei, int[][] strg) { - int n = arr.length; - int year = (n - (ei - si + 1)) + 1; - if (si == ei) { - return arr[si] * year; - } - - if (strg[si][ei] != 0) { - return strg[si][ei]; - } - int start = WPTD(arr, si + 1, ei, strg) + arr[si] * year; - int end = WPTD(arr, si, ei - 1, strg) + arr[ei] * year; - - int ans = Math.max(start, end); - - strg[si][ei] = ans; - - return ans; - } - - // Method 3: Bottom-Up DP(Tabulation) - // Time Complexity=0(N*N/2)->0(N*N) Space Complexity=0(N*N) - public static int WPBU(int[] arr) { - int n = arr.length; - int[][] strg = new int[n][n]; - - for (int slide = 0; slide <= n - 1; slide++) { - for (int si = 0; si <= n - slide - 1; si++) { - int ei = si + slide; - int year = (n - (ei - si + 1)) + 1; - if (si == ei) { - strg[si][ei] = arr[si] * year; - } else { - int start = strg[si + 1][ei] + arr[si] * year; - int end = strg[si][ei - 1] + arr[ei] * year; - - strg[si][ei] = Math.max(start, end); - - } - } - } - return strg[0][n - 1]; - } - - public static void main(String[] args) { - int[] arr = { 2, 3, 5, 1, 4 }; - System.out.println("Method 1: " + WPRecursion(arr, 0, arr.length - 1)); - System.out.println("Method 2: " + WPTD(arr, 0, arr.length - 1, new int[arr.length][arr.length])); - System.out.println("Method 3: " + WPBU(arr)); - - } - -} -// Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/ -// Question Link : https://www.geeksforgeeks.org/maximum-profit-sale-wines/ \ No newline at end of file diff --git a/Maths/AbsoluteMax.java b/Maths/AbsoluteMax.java deleted file mode 100644 index fe1376232322..000000000000 --- a/Maths/AbsoluteMax.java +++ /dev/null @@ -1,34 +0,0 @@ -package Maths; - -import java.util.Arrays; - -/** - * description: - * - *

absMax([0, 5, 1, 11]) = 11, absMax([3 , -10, -2]) = -10 - */ -public class AbsoluteMax { - public static void main(String[] args) { - int[] testnums = {-2, 0, 16}; - assert absMax(testnums) == 16; - - int[] numbers = {3, -10, -2}; - System.out.println("absMax(" + Arrays.toString(numbers) + ") = " + absMax(numbers)); - } - - /** - * get the value, return the absolute max value - * - * @param numbers contains elements - * @return the absolute max value - */ - public static int absMax(int[] numbers) { - int absMaxValue = numbers[0]; - for (int i = 1, length = numbers.length; i < length; ++i) { - if (Math.abs(numbers[i]) > Math.abs(absMaxValue)) { - absMaxValue = numbers[i]; - } - } - return absMaxValue; - } -} diff --git a/Maths/AbsoluteMin.java b/Maths/AbsoluteMin.java deleted file mode 100644 index 8e8c71fdbb29..000000000000 --- a/Maths/AbsoluteMin.java +++ /dev/null @@ -1,34 +0,0 @@ -package Maths; - -import java.util.Arrays; - -/** - * description: - * - *

absMin([0, 5, 1, 11]) = 0, absMin([3 , -10, -2]) = -2 - */ -public class AbsoluteMin { - public static void main(String[] args) { - int[] testnums = {4, 0, 16}; - assert absMin(testnums) == 0; - - int[] numbers = {3, -10, -2}; - System.out.println("absMin(" + Arrays.toString(numbers) + ") = " + absMin(numbers)); - } - - /** - * get the value, returns the absolute min value min - * - * @param numbers contains elements - * @return the absolute min value - */ - public static int absMin(int[] numbers) { - int absMinValue = numbers[0]; - for (int i = 1, length = numbers.length; i < length; ++i) { - if (Math.abs(numbers[i]) < Math.abs(absMinValue)) { - absMinValue = numbers[i]; - } - } - return absMinValue; - } -} diff --git a/Maths/AbsoluteValue.java b/Maths/AbsoluteValue.java deleted file mode 100644 index d465de67d4ff..000000000000 --- a/Maths/AbsoluteValue.java +++ /dev/null @@ -1,26 +0,0 @@ -package Maths; - -import java.util.Random; - -public class AbsoluteValue { - - public static void main(String[] args) { - Random random = new Random(); - - /* test 1000 random numbers */ - for (int i = 1; i <= 1000; ++i) { - int randomNumber = random.nextInt(); - assert absVal(randomNumber) == Math.abs(randomNumber); - } - } - - /** - * If value is less than zero, make value positive. - * - * @param value a number - * @return the absolute value of a number - */ - public static int absVal(int value) { - return value < 0 ? -value : value; - } -} diff --git a/Maths/AliquotSum.java b/Maths/AliquotSum.java deleted file mode 100644 index 09b7c730b159..000000000000 --- a/Maths/AliquotSum.java +++ /dev/null @@ -1,32 +0,0 @@ -package Maths; - -/** - * In number theory, the aliquot sum s(n) of a positive integer n is the sum of all proper divisors - * of n, that is, all divisors of n other than n itself. For example, the proper divisors of 15 - * (that is, the positive divisors of 15 that are not equal to 15) are 1, 3 and 5, so the aliquot - * sum of 15 is 9 i.e. (1 + 3 + 5). Wikipedia: https://en.wikipedia.org/wiki/Aliquot_sum - */ -public class AliquotSum { - public static void main(String[] args) { - assert aliquotSum(1) == 0; - assert aliquotSum(6) == 6; - assert aliquotSum(15) == 9; - assert aliquotSum(19) == 1; - } - - /** - * Finds the aliquot sum of an integer number - * - * @param number a positive integer - * @return aliquot sum of given {@code number} - */ - public static int aliquotSum(int number) { - int sum = 0; - for (int i = 1, limit = number / 2; i <= limit; ++i) { - if (number % i == 0) { - sum += i; - } - } - return sum; - } -} diff --git a/Maths/AmicableNumber.java b/Maths/AmicableNumber.java deleted file mode 100644 index 4080ce6263a0..000000000000 --- a/Maths/AmicableNumber.java +++ /dev/null @@ -1,87 +0,0 @@ -package Maths; - -/** - * Amicable numbers are two different numbers so related that the sum of the proper divisors of each - * is equal to the other number. (A proper divisor of a number is a positive factor of that number - * other than the number itself. For example, the proper divisors of 6 are 1, 2, and 3.) A pair of - * amicable numbers constitutes an aliquot sequence of period 2. It is unknown if there are - * infinitely many pairs of amicable numbers. * - * - *

* link: https://en.wikipedia.org/wiki/Amicable_numbers * - * - *

Simple Example : (220,284) 220 is divisible by {1,2,4,5,10,11,20,22,44,55,110 } <- Sum = 284 - * 284 is divisible by -> 1,2,4,71,142 and the Sum of that is. Yes right you probably expected it - * 220 - */ -public class AmicableNumber { - - public static void main(String[] args) { - - AmicableNumber.findAllInRange(1, 3000); - /* Res -> Int Range of 1 till 3000there are 3Amicable_numbers These are 1: = ( 220,284) 2: = ( 1184,1210) - 3: = ( 2620,2924) So it worked */ - - } - - /** - * @param startValue - * @param stopValue - * @return - */ - static void findAllInRange(int startValue, int stopValue) { - - /* the 2 for loops are to avoid to double check tuple. For example (200,100) and (100,200) is the same calculation - * also to avoid is to check the number with it self. a number with itself is always a AmicableNumber - * */ - StringBuilder res = new StringBuilder(); - int countofRes = 0; - - for (int i = startValue; i < stopValue; i++) { - for (int j = i + 1; j <= stopValue; j++) { - if (isAmicableNumber(i, j)) { - countofRes++; - res.append("" + countofRes + ": = ( " + i + "," + j + ")" + "\t"); - } - } - } - res.insert( - 0, - "Int Range of " - + startValue - + " till " - + stopValue - + " there are " - + countofRes - + " Amicable_numbers.These are \n "); - System.out.println(res.toString()); - } - - /** - * Check if {@code numberOne and numberTwo } are AmicableNumbers or not - * - * @param numberOne numberTwo - * @return {@code true} if {@code numberOne numberTwo} isAmicableNumbers otherwise false - */ - static boolean isAmicableNumber(int numberOne, int numberTwo) { - - return ((recursiveCalcOfDividerSum(numberOne, numberOne) == numberTwo - && numberOne == recursiveCalcOfDividerSum(numberTwo, numberTwo))); - } - - /** - * calculated in recursive calls the Sum of all the Dividers beside it self - * - * @param number div = the next to test dividely by using the modulo operator - * @return sum of all the dividers - */ - static int recursiveCalcOfDividerSum(int number, int div) { - - if (div == 1) { - return 0; - } else if (number % --div == 0) { - return recursiveCalcOfDividerSum(number, div) + div; - } else { - return recursiveCalcOfDividerSum(number, div); - } - } -} diff --git a/Maths/Area.java b/Maths/Area.java deleted file mode 100644 index 4a8acca575b7..000000000000 --- a/Maths/Area.java +++ /dev/null @@ -1,161 +0,0 @@ -package Maths; - -/** Find the area of various geometric shapes */ -public class Area { - public static void main(String[] args) { - - /* test cube */ - assert Double.compare(surfaceAreaCube(1), 6.0) == 0; - - /* test sphere */ - assert Double.compare(surfaceAreaSphere(5), 314.1592653589793) == 0; - assert Double.compare(surfaceAreaSphere(1), 12.566370614359172) == 0; - - /* test rectangle */ - assert Double.compare(surfaceAreaRectangle(10, 20), 200.0) == 0; - - /* test square */ - assert Double.compare(surfaceAreaSquare(10), 100.0) == 0; - - /* test triangle */ - assert Double.compare(surfaceAreaTriangle(10, 10), 50.0) == 0; - - /* test parallelogram */ - assert Double.compare(surfaceAreaParallelogram(10, 20), 200.0) == 0; - - /* test trapezium */ - assert Double.compare(surfaceAreaTrapezium(10, 20, 30), 450.0) == 0; - - /* test circle */ - assert Double.compare(surfaceAreaCircle(20), 1256.6370614359173) == 0; - - /* test cylinder */ - assert Double.compare(surfaceAreaCylinder(1,2), 18.84955592153876) == 0; - - /* test hemisphere */ - assert Double.compare(surfaceAreaHemisphere(5), 235.61944901923448) == 0; - assert Double.compare(surfaceAreaHemisphere(1), 9.42477796076938) == 0; - - /* test cone */ - assert Double.compare(surfaceAreaCone(6, 8), 301.59289474462014) == 0; - assert Double.compare(surfaceAreaCone(10, 24), 1130.9733552923256) == 0; - - } - - /** - * Calculate the surface area of a cube. - * - * @param sideLength side length of cube - * @return surface area of given cube - */ - private static double surfaceAreaCube(double sideLength) { - return 6 * sideLength * sideLength; - } - - /** - * Calculate the surface area of a sphere. - * - * @param radius radius of sphere - * @return surface area of given sphere - */ - private static double surfaceAreaSphere(double radius) { - return 4 * Math.PI * radius * radius; - } - - /** - * Calculate the area of a rectangle - * - * @param length length of rectangle - * @param width width of rectangle - * @return area of given rectangle - */ - private static double surfaceAreaRectangle(double length, double width) { - return length * width; - } - - /** - * Calculate surface area of a cylinder - * - * @param radius radius of the floor - * @param height height of the cylinder. - * @return volume of given cylinder - */ - private static double surfaceAreaCylinder(double radius, double height) { - return 2 * (Math.PI * radius * radius + Math.PI * radius * height); - } - - /** - * Calculate the area of a square - * - * @param sideLength side length of square - * @return area of given square - */ - private static double surfaceAreaSquare(double sideLength) { - return sideLength * sideLength; - } - - /** - * Calculate the area of a triangle - * - * @param base base of triangle - * @param height height of triangle - * @return area of given triangle - */ - private static double surfaceAreaTriangle(double base, double height) { - return base * height / 2; - } - - /** - * Calculate the area of a parallelogram - * - * @param base base of parallelogram - * @param height height of parallelogram - * @return area of given parallelogram - */ - private static double surfaceAreaParallelogram(double base, double height) { - return base * height; - } - - /** - * Calculate the area of a trapezium - * - * @param base1 upper base of trapezium - * @param base2 bottom base of trapezium - * @param height height of trapezium - * @return area of given trapezium - */ - private static double surfaceAreaTrapezium(double base1, double base2, double height) { - return (base1 + base2) * height / 2; - } - - /** - * Calculate the area of a circle - * - * @param radius radius of circle - * @return area of given circle - */ - private static double surfaceAreaCircle(double radius) { - return Math.PI * radius * radius; - } - - /** - * Calculate the surface area of a hemisphere. - * - * @param radius radius of hemisphere - * @return surface area of given hemisphere - */ - private static double surfaceAreaHemisphere(double radius) { - return 3 * Math.PI * radius * radius; - } - - /** - * Calculate the surface area of a cone. - * - * @param radius radius of cone. - * @param height of cone. - * @return surface area of given cone. - */ - private static double surfaceAreaCone(double radius, double height) { - return Math.PI * radius * (radius + Math.pow((height * height + radius * radius), 0.5)); - } -} diff --git a/Maths/Armstrong.java b/Maths/Armstrong.java deleted file mode 100644 index e41e85d062fd..000000000000 --- a/Maths/Armstrong.java +++ /dev/null @@ -1,44 +0,0 @@ -package Maths; - -/** - * An Armstrong number is equal to the sum of the cubes of its digits. For example, 370 is an - * Armstrong number because 3*3*3 + 7*7*7 + 0*0*0 = 370. An Armstrong number is often called - * Narcissistic number. - */ -public class Armstrong { - - public static void main(String[] args) { - assert (isArmStrong(0)); - assert (isArmStrong(1)); - assert (isArmStrong(153)); - assert (isArmStrong(1634)); - assert (isArmStrong(371)); - assert (!isArmStrong(200)); - } - - /** - * Checks whether a given number is an armstrong number or not. - * - * @param number number to check - * @return {@code true} if given number is armstrong number, {@code false} otherwise - */ - private static boolean isArmStrong(int number) { - int sum = 0; - int temp = number; - int numberOfDigits = 0; - while (temp != 0) { - numberOfDigits++; - temp /= 10; - } - temp = number; /* copy number again */ - while (number > 0) { - int remainder = number % 10; - int power = 1; - for (int i = 1; i <= numberOfDigits; power *= remainder, ++i) - ; - sum = sum + power; - number /= 10; - } - return sum == temp; - } -} diff --git a/Maths/AutomorphicNumber.java b/Maths/AutomorphicNumber.java deleted file mode 100644 index c0fac2a53b2d..000000000000 --- a/Maths/AutomorphicNumber.java +++ /dev/null @@ -1,65 +0,0 @@ -package Maths; - -/** - * A number is said to be an Automorphic, if it is present in the last digit(s) of its square. - * Example- Let the number be 25, its square is 625. - * Since, 25(The input number) is present in the last two digits of its square(625), - * it is an Automorphic Number. - */ -import java.io.*; - -public class AutomorphicNumber -{ - //returns True if the number is a Automorphic number and False if it is not an Automorphic number - public static boolean isAutomorphic(int n) - { - int m, c, r, p, k; c = 0; - /** m = Temporary variable to store a copy of the number entered by the user. - * n = The number entered by the user - * c = Count the digits of the number entered by user. - * p = To calculate the square of the number. - * k = Support variable to count the digits of the number - */ - double s; - m = n; - p = m * m; //Calculating square of the number - do - { - k = n / 10; - c = c + 1; //Counting the digits of the number entered by user. - n = k; - } - while(n != 0); - s = Math.pow(10, c); - r = p %(int)s; - if(m == r) //Checking if the original number entered is present at the end of the square - { - return true; - } - else - { - return false; - } - } - - /** Method to check if number is Automorphic Number or Not - * 1) Input - Enter a Number: 25 - * Output - It is an Automorphic Number. - * 2) Input - Enter a Number: 7 - * Output - It is not an Automorphic Number. - */ - public static void main(String args[]) throws IOException - { - BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); - System.out.println("Enter a Number: "); - int n=Integer.parseInt(br.readLine()); - if(isAutomorphic(n)) - { - System.out.println("It is an Automorphic Number."); - } - else - { - System.out.println("It is not an Automorphic Number."); - } - } -} diff --git a/Maths/Average.java b/Maths/Average.java deleted file mode 100644 index 5c66569a642e..000000000000 --- a/Maths/Average.java +++ /dev/null @@ -1,42 +0,0 @@ -package Maths; - -/** Calculate average of a list of numbers */ -public class Average { - private static final double SMALL_VALUE = 0.00001f; - - public static void main(String[] args) { - assert Math.abs(average(new double[] {3, 6, 9, 12, 15, 18, 21}) - 12) < SMALL_VALUE; - assert Math.abs(average(new double[] {5, 10, 15, 20, 25, 30, 35}) - 20) < SMALL_VALUE; - assert Math.abs(average(new double[] {1, 2, 3, 4, 5, 6, 7, 8}) - 4.5) < SMALL_VALUE; - int[] array = {2, 4, 10}; - assert average(array) == 5; - } - - /** - * Calculate average of a list of numbers - * - * @param numbers array to store numbers - * @return mean of given numbers - */ - public static double average(double[] numbers) { - double sum = 0; - for (double number : numbers) { - sum += number; - } - return sum / numbers.length; - } - - /** - * find average value of int array - * - * @param array the array contains element and the sum does not excess long value limit - * @return average value - */ - public static int average(int[] array) { - long sum = 0; - for (int i = 0; i < array.length; ++i) { - sum += array[i]; - } - return (int) (sum / array.length); - } -} diff --git a/Maths/BinaryPow.java b/Maths/BinaryPow.java deleted file mode 100644 index b9d5b68fa7d4..000000000000 --- a/Maths/BinaryPow.java +++ /dev/null @@ -1,48 +0,0 @@ -package Maths; - -public class BinaryPow { - /** - * Calculate a^p using binary exponentiation - * [Binary-Exponentiation](https://cp-algorithms.com/algebra/binary-exp.html) - * - * @param a the base for exponentiation - * @param p the exponent - must be greater than 0 - * @return a^p - */ - public static int binPow(int a, int p) { - int res = 1; - while (p > 0) { - if ((p & 1) == 1) { - res = res * a; - } - a = a * a; - p >>>= 1; - } - return res; - } - - /** - * Function for testing binary exponentiation - * - * @param a the base - * @param p the exponent - */ - public static void test(int a, int p) { - int res = binPow(a, p); - assert res == (int) Math.pow(a, p) : "Incorrect Implementation"; - System.out.println(a + "^" + p + ": " + res); - } - - /** - * Main Function to call tests - * - * @param args System Line Arguments - */ - public static void main(String[] args) { - // prints 2^15: 32768 - test(2, 15); - - // prints 3^9: 19683 - test(3, 9); - } -} diff --git a/Maths/Ceil.java b/Maths/Ceil.java deleted file mode 100644 index fd6d8300a4c9..000000000000 --- a/Maths/Ceil.java +++ /dev/null @@ -1,29 +0,0 @@ -package Maths; - -import java.util.Random; - -public class Ceil { - public static void main(String[] args) { - Random random = new Random(); - for (int i = 1; i <= 1000; ++i) { - double randomNumber = random.nextDouble(); - assert ceil(randomNumber) == Math.ceil(randomNumber); - } - } - - /** - * Returns the smallest (closest to negative infinity) - * - * @param number the number - * @return the smallest (closest to negative infinity) of given {@code number} - */ - public static double ceil(double number) { - if (number - (int) number == 0) { - return number; - } else if (number - (int) number > 0) { - return (int) (number + 1); - } else { - return (int) number; - } - } -} diff --git a/Maths/CircularConvolutionFFT.java b/Maths/CircularConvolutionFFT.java deleted file mode 100644 index dc207489e4a8..000000000000 --- a/Maths/CircularConvolutionFFT.java +++ /dev/null @@ -1,55 +0,0 @@ -package Maths; - -import java.util.ArrayList; - -/** - * Class for circular convolution of two discrete signals using the convolution theorem. - * - * @author Ioannis Karavitsis - * @version 1.0 - */ -public class CircularConvolutionFFT { - /** - * This method pads the signal with zeros until it reaches the new size. - * - * @param x The signal to be padded. - * @param newSize The new size of the signal. - */ - private static void padding(ArrayList x, int newSize) { - if (x.size() < newSize) { - int diff = newSize - x.size(); - for (int i = 0; i < diff; i++) x.add(new FFT.Complex()); - } - } - - /** - * Discrete circular convolution function. It uses the convolution theorem for discrete signals: - * convolved = IDFT(DFT(a)*DFT(b)). Then we use the FFT algorithm for faster calculations of the - * two DFTs and the final IDFT. - * - *

More info: https://en.wikipedia.org/wiki/Convolution_theorem - * - * @param a The first signal. - * @param b The other signal. - * @return The convolved signal. - */ - public static ArrayList fftCircularConvolution( - ArrayList a, ArrayList b) { - int convolvedSize = - Math.max( - a.size(), b.size()); // The two signals must have the same size equal to the bigger one - padding(a, convolvedSize); // Zero padding the smaller signal - padding(b, convolvedSize); - - /* Find the FFTs of both signal. Here we use the Bluestein algorithm because we want the FFT to have the same length with the signal and not bigger */ - FFTBluestein.fftBluestein(a, false); - FFTBluestein.fftBluestein(b, false); - ArrayList convolved = new ArrayList<>(); - - for (int i = 0; i < a.size(); i++) convolved.add(a.get(i).multiply(b.get(i))); // FFT(a)*FFT(b) - - FFTBluestein.fftBluestein(convolved, true); // IFFT - - return convolved; - } -} diff --git a/Maths/Combinations.java b/Maths/Combinations.java deleted file mode 100644 index cc19ee9088be..000000000000 --- a/Maths/Combinations.java +++ /dev/null @@ -1,74 +0,0 @@ -package Maths; - -/** @see Combination */ -public class Combinations { - public static void main(String[] args) { - assert combinations(1, 1) == 1; - assert combinations(10, 5) == 252; - assert combinations(6, 3) == 20; - assert combinations(20, 5) == 15504; - - // Since, 200 is a big number its factorial will go beyond limits of long even when 200C5 can be saved in a long - // variable. So below will fail - // assert combinations(200, 5) == 2535650040l; - - assert combinationsOptimized(100, 0) == 1; - assert combinationsOptimized(1, 1) == 1; - assert combinationsOptimized(10, 5) == 252; - assert combinationsOptimized(6, 3) == 20; - assert combinationsOptimized(20, 5) == 15504; - assert combinationsOptimized(200, 5) == 2535650040l; - } - - /** - * Calculate of factorial - * - * @param n the number - * @return factorial of given number - */ - public static long factorial(int n) { - if (n < 0) { - throw new IllegalArgumentException("number is negative"); - } - return n == 0 || n == 1 ? 1 : n * factorial(n - 1); - } - - /** - * Calculate combinations - * - * @param n first number - * @param k second number - * @return combinations of given {@code n} and {@code k} - */ - public static long combinations(int n, int k) { - return factorial(n) / (factorial(k) * factorial(n - k)); - } - - /** - * The above method can exceed limit of long (overflow) when factorial(n) is larger than limits of long variable. - * Thus even if nCk is within range of long variable above reason can lead to incorrect result. - * This is an optimized version of computing combinations. - * Observations: - * nC(k + 1) = (n - k) * nCk / (k + 1) - * We know the value of nCk when k = 1 which is nCk = n - * Using this base value and above formula we can compute the next term nC(k+1) - * @param n - * @param k - * @return nCk - */ - public static long combinationsOptimized(int n, int k) { - if (n < 0 || k < 0) { - throw new IllegalArgumentException("n or k can't be negative"); - } - if (n < k) { - throw new IllegalArgumentException("n can't be smaller than k"); - } - // nC0 is always 1 - long solution = 1; - for(int i = 0; i < k; i++) { - long next = (n - i) * solution / (i + 1); - solution = next; - } - return solution; - } -} diff --git a/Maths/Convolution.java b/Maths/Convolution.java deleted file mode 100644 index f96811735a2a..000000000000 --- a/Maths/Convolution.java +++ /dev/null @@ -1,43 +0,0 @@ -package Maths; - -/** - * Class for linear convolution of two discrete signals - * - * @author Ioannis Karavitsis - * @version 1.0 - */ -public class Convolution { - /** - * Discrete linear convolution function. Both input signals and the output signal must start from - * 0. If you have a signal that has values before 0 then shift it to start from 0. - * - * @param A The first discrete signal - * @param B The second discrete signal - * @return The convolved signal - */ - public static double[] convolution(double[] A, double[] B) { - double[] convolved = new double[A.length + B.length - 1]; - - /* - The discrete convolution of two signals A and B is defined as: - - A.length - C[i] = Σ (A[k]*B[i-k]) - k=0 - - It's obvious that: 0 <= k <= A.length , 0 <= i <= A.length + B.length - 2 and 0 <= i-k <= B.length - 1 - From the last inequality we get that: i - B.length + 1 <= k <= i and thus we get the conditions below. - */ - for (int i = 0; i < convolved.length; i++) { - convolved[i] = 0; - int k = Math.max(i - B.length + 1, 0); - - while (k < i + 1 && k < A.length) { - convolved[i] += A[k] * B[i - k]; - k++; - } - } - - return convolved; - } -} diff --git a/Maths/ConvolutionFFT.java b/Maths/ConvolutionFFT.java deleted file mode 100644 index e43db72affc8..000000000000 --- a/Maths/ConvolutionFFT.java +++ /dev/null @@ -1,60 +0,0 @@ -package Maths; - -import java.util.ArrayList; - -/** - * Class for linear convolution of two discrete signals using the convolution theorem. - * - * @author Ioannis Karavitsis - * @version 1.0 - */ -public class ConvolutionFFT { - /** - * This method pads the signal with zeros until it reaches the new size. - * - * @param x The signal to be padded. - * @param newSize The new size of the signal. - */ - private static void padding(ArrayList x, int newSize) { - if (x.size() < newSize) { - int diff = newSize - x.size(); - for (int i = 0; i < diff; i++) x.add(new FFT.Complex()); - } - } - - /** - * Discrete linear convolution function. It uses the convolution theorem for discrete signals - * convolved: = IDFT(DFT(a)*DFT(b)). This is true for circular convolution. In order to get the - * linear convolution of the two signals we first pad the two signals to have the same size equal - * to the convolved signal (a.size() + b.size() - 1). Then we use the FFT algorithm for faster - * calculations of the two DFTs and the final IDFT. - * - *

More info: https://en.wikipedia.org/wiki/Convolution_theorem - * https://ccrma.stanford.edu/~jos/ReviewFourier/FFT_Convolution.html - * - * @param a The first signal. - * @param b The other signal. - * @return The convolved signal. - */ - public static ArrayList convolutionFFT( - ArrayList a, ArrayList b) { - int convolvedSize = a.size() + b.size() - 1; // The size of the convolved signal - padding(a, convolvedSize); // Zero padding both signals - padding(b, convolvedSize); - - /* Find the FFTs of both signals (Note that the size of the FFTs will be bigger than the convolvedSize because of the extra zero padding in FFT algorithm) */ - FFT.fft(a, false); - FFT.fft(b, false); - ArrayList convolved = new ArrayList<>(); - - for (int i = 0; i < a.size(); i++) convolved.add(a.get(i).multiply(b.get(i))); // FFT(a)*FFT(b) - - FFT.fft(convolved, true); // IFFT - convolved - .subList(convolvedSize, convolved.size()) - .clear(); // Remove the remaining zeros after the convolvedSize. These extra zeros came from - // paddingPowerOfTwo() method inside the fft() method. - - return convolved; - } -} diff --git a/Maths/EulerMethod.java b/Maths/EulerMethod.java deleted file mode 100644 index c10a603c3cd7..000000000000 --- a/Maths/EulerMethod.java +++ /dev/null @@ -1,105 +0,0 @@ -package Maths; - -import java.util.ArrayList; -import java.util.function.BiFunction; - -/** - * In mathematics and computational science, the Euler method (also called forward Euler method) is - * a first-order numerical procedure for solving ordinary differential equations (ODEs) with a given - * initial value. It is the most basic explicit method for numerical integration of ordinary - * differential equations. The method proceeds in a series of steps. At each step the y-value is - * calculated by evaluating the differential equation at the previous step, multiplying the result - * with the step-size and adding it to the last y-value: y_n+1 = y_n + stepSize * f(x_n, y_n). - * (description adapted from https://en.wikipedia.org/wiki/Euler_method ) (see also: - * https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ ) - */ -public class EulerMethod { - - /** Illustrates how the algorithm is used in 3 examples and prints the results to the console. */ - public static void main(String[] args) { - System.out.println("example 1:"); - BiFunction exampleEquation1 = (x, y) -> x; - ArrayList points1 = eulerFull(0, 4, 0.1, 0, exampleEquation1); - assert points1.get(points1.size() - 1)[1] == 7.800000000000003; - points1.forEach( - point -> System.out.println(String.format("x: %1$f; y: %2$f", point[0], point[1]))); - - // example from https://en.wikipedia.org/wiki/Euler_method - System.out.println("\n\nexample 2:"); - BiFunction exampleEquation2 = (x, y) -> y; - ArrayList points2 = eulerFull(0, 4, 0.1, 1, exampleEquation2); - assert points2.get(points2.size() - 1)[1] == 45.25925556817596; - points2.forEach( - point -> System.out.println(String.format("x: %1$f; y: %2$f", point[0], point[1]))); - - // example from https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ - System.out.println("\n\nexample 3:"); - BiFunction exampleEquation3 = (x, y) -> x + y + x * y; - ArrayList points3 = eulerFull(0, 0.1, 0.025, 1, exampleEquation3); - assert points3.get(points3.size() - 1)[1] == 1.1116729841674804; - points3.forEach( - point -> System.out.println(String.format("x: %1$f; y: %2$f", point[0], point[1]))); - } - - /** - * calculates the next y-value based on the current value of x, y and the stepSize the console. - * - * @param xCurrent Current x-value. - * @param stepSize Step-size on the x-axis. - * @param yCurrent Current y-value. - * @param differentialEquation The differential equation to be solved. - * @return The next y-value. - */ - public static double eulerStep( - double xCurrent, - double stepSize, - double yCurrent, - BiFunction differentialEquation) { - if (stepSize <= 0) { - throw new IllegalArgumentException("stepSize should be greater than zero"); - } - double yNext = yCurrent + stepSize * differentialEquation.apply(xCurrent, yCurrent); - return yNext; - } - - /** - * Loops through all the steps until xEnd is reached, adds a point for each step and then returns - * all the points - * - * @param xStart First x-value. - * @param xEnd Last x-value. - * @param stepSize Step-size on the x-axis. - * @param yStart First y-value. - * @param differentialEquation The differential equation to be solved. - * @return The points constituting the solution of the differential equation. - */ - public static ArrayList eulerFull( - double xStart, - double xEnd, - double stepSize, - double yStart, - BiFunction differentialEquation) { - if (xStart >= xEnd) { - throw new IllegalArgumentException("xEnd should be greater than xStart"); - } - if (stepSize <= 0) { - throw new IllegalArgumentException("stepSize should be greater than zero"); - } - - ArrayList points = new ArrayList(); - double[] firstPoint = {xStart, yStart}; - points.add(firstPoint); - double yCurrent = yStart; - double xCurrent = xStart; - - while (xCurrent < xEnd) { - // Euler method for next step - yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation); - xCurrent += stepSize; - double[] point = {xCurrent, yCurrent}; - points.add(point); - } - - return points; - } -} diff --git a/Maths/FFT.java b/Maths/FFT.java deleted file mode 100644 index 30c8cfbdf7bf..000000000000 --- a/Maths/FFT.java +++ /dev/null @@ -1,245 +0,0 @@ -package Maths; - -import java.util.ArrayList; -import java.util.Collections; - -/** - * Class for calculating the Fast Fourier Transform (FFT) of a discrete signal using the - * Cooley-Tukey algorithm. - * - * @author Ioannis Karavitsis - * @version 1.0 - */ -public class FFT { - /** - * This class represents a complex number and has methods for basic operations. - * - *

More info: https://introcs.cs.princeton.edu/java/32class/Complex.java.html - */ - static class Complex { - private double real, img; - - /** Default Constructor. Creates the complex number 0. */ - public Complex() { - real = 0; - img = 0; - } - - /** - * Constructor. Creates a complex number. - * - * @param r The real part of the number. - * @param i The imaginary part of the number. - */ - public Complex(double r, double i) { - real = r; - img = i; - } - - /** - * Returns the real part of the complex number. - * - * @return The real part of the complex number. - */ - public double getReal() { - return real; - } - - /** - * Returns the imaginary part of the complex number. - * - * @return The imaginary part of the complex number. - */ - public double getImaginary() { - return img; - } - - /** - * Adds this complex number to another. - * - * @param z The number to be added. - * @return The sum. - */ - public Complex add(Complex z) { - Complex temp = new Complex(); - temp.real = this.real + z.real; - temp.img = this.img + z.img; - return temp; - } - - /** - * Subtracts a number from this complex number. - * - * @param z The number to be subtracted. - * @return The difference. - */ - public Complex subtract(Complex z) { - Complex temp = new Complex(); - temp.real = this.real - z.real; - temp.img = this.img - z.img; - return temp; - } - - /** - * Multiplies this complex number by another. - * - * @param z The number to be multiplied. - * @return The product. - */ - public Complex multiply(Complex z) { - Complex temp = new Complex(); - temp.real = this.real * z.real - this.img * z.img; - temp.img = this.real * z.img + this.img * z.real; - return temp; - } - - /** - * Multiplies this complex number by a scalar. - * - * @param n The real number to be multiplied. - * @return The product. - */ - public Complex multiply(double n) { - Complex temp = new Complex(); - temp.real = this.real * n; - temp.img = this.img * n; - return temp; - } - - /** - * Finds the conjugate of this complex number. - * - * @return The conjugate. - */ - public Complex conjugate() { - Complex temp = new Complex(); - temp.real = this.real; - temp.img = -this.img; - return temp; - } - - /** - * Finds the magnitude of the complex number. - * - * @return The magnitude. - */ - public double abs() { - return Math.hypot(this.real, this.img); - } - - /** - * Divides this complex number by another. - * - * @param z The divisor. - * @return The quotient. - */ - public Complex divide(Complex z) { - Complex temp = new Complex(); - temp.real = (this.real * z.real + this.img * z.img) / (z.abs() * z.abs()); - temp.img = (this.img * z.real - this.real * z.img) / (z.abs() * z.abs()); - return temp; - } - - /** - * Divides this complex number by a scalar. - * - * @param n The divisor which is a real number. - * @return The quotient. - */ - public Complex divide(double n) { - Complex temp = new Complex(); - temp.real = this.real / n; - temp.img = this.img / n; - return temp; - } - } - - /** - * Iterative In-Place Radix-2 Cooley-Tukey Fast Fourier Transform Algorithm with Bit-Reversal. The - * size of the input signal must be a power of 2. If it isn't then it is padded with zeros and the - * output FFT will be bigger than the input signal. - * - *

More info: https://www.algorithm-archive.org/contents/cooley_tukey/cooley_tukey.html - * https://www.geeksforgeeks.org/iterative-fast-fourier-transformation-polynomial-multiplication/ - * https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm - * https://cp-algorithms.com/algebra/fft.html - * - * @param x The discrete signal which is then converted to the FFT or the IFFT of signal x. - * @param inverse True if you want to find the inverse FFT. - */ - public static void fft(ArrayList x, boolean inverse) { - /* Pad the signal with zeros if necessary */ - paddingPowerOfTwo(x); - int N = x.size(); - - /* Find the log2(N) */ - int log2N = 0; - while ((1 << log2N) < N) log2N++; - - /* Swap the values of the signal with bit-reversal method */ - int reverse; - for (int i = 0; i < N; i++) { - reverse = reverseBits(i, log2N); - if (i < reverse) Collections.swap(x, i, reverse); - } - - int direction = inverse ? -1 : 1; - - /* Main loop of the algorithm */ - for (int len = 2; len <= N; len *= 2) { - double angle = -2 * Math.PI / len * direction; - Complex wlen = new Complex(Math.cos(angle), Math.sin(angle)); - for (int i = 0; i < N; i += len) { - Complex w = new Complex(1, 0); - for (int j = 0; j < len / 2; j++) { - Complex u = x.get(i + j); - Complex v = w.multiply(x.get(i + j + len / 2)); - x.set(i + j, u.add(v)); - x.set(i + j + len / 2, u.subtract(v)); - w = w.multiply(wlen); - } - } - } - - /* Divide by N if we want the inverse FFT */ - if (inverse) { - for (int i = 0; i < x.size(); i++) { - Complex z = x.get(i); - x.set(i, z.divide(N)); - } - } - } - - /** - * This function reverses the bits of a number. It is used in Cooley-Tukey FFT algorithm. - * - *

E.g. num = 13 = 00001101 in binary log2N = 8 Then reversed = 176 = 10110000 in binary - * - *

More info: https://cp-algorithms.com/algebra/fft.html - * https://www.geeksforgeeks.org/write-an-efficient-c-program-to-reverse-bits-of-a-number/ - * - * @param num The integer you want to reverse its bits. - * @param log2N The number of bits you want to reverse. - * @return The reversed number - */ - private static int reverseBits(int num, int log2N) { - int reversed = 0; - for (int i = 0; i < log2N; i++) { - if ((num & (1 << i)) != 0) reversed |= 1 << (log2N - 1 - i); - } - return reversed; - } - - /** - * This method pads an ArrayList with zeros in order to have a size equal to the next power of two - * of the previous size. - * - * @param x The ArrayList to be padded. - */ - private static void paddingPowerOfTwo(ArrayList x) { - int n = 1; - int oldSize = x.size(); - while (n < oldSize) n *= 2; - for (int i = 0; i < n - oldSize; i++) x.add(new Complex()); - } -} diff --git a/Maths/FFTBluestein.java b/Maths/FFTBluestein.java deleted file mode 100644 index 06e87b15bce6..000000000000 --- a/Maths/FFTBluestein.java +++ /dev/null @@ -1,61 +0,0 @@ -package Maths; - -import java.util.ArrayList; - -/** - * Class for calculating the Fast Fourier Transform (FFT) of a discrete signal using the Bluestein's - * algorithm. - * - * @author Ioannis Karavitsis - * @version 1.0 - */ -public class FFTBluestein { - /** - * Bluestein's FFT Algorithm. - * - *

More info: https://en.wikipedia.org/wiki/Chirp_Z-transform#Bluestein.27s_algorithm - * http://tka4.org/materials/lib/Articles-Books/Numerical%20Algorithms/Hartley_Trasform/Bluestein%27s%20FFT%20algorithm%20-%20Wikipedia,%20the%20free%20encyclopedia.htm - * - * @param x The discrete signal which is then converted to the FFT or the IFFT of signal x. - * @param inverse True if you want to find the inverse FFT. - */ - public static void fftBluestein(ArrayList x, boolean inverse) { - int N = x.size(); - int bnSize = 2 * N - 1; - int direction = inverse ? -1 : 1; - ArrayList an = new ArrayList<>(); - ArrayList bn = new ArrayList<>(); - - /* Initialization of the b(n) sequence (see Wikipedia's article above for the symbols used)*/ - for (int i = 0; i < bnSize; i++) bn.add(new FFT.Complex()); - - for (int i = 0; i < N; i++) { - double angle = (i - N + 1) * (i - N + 1) * Math.PI / N * direction; - bn.set(i, new FFT.Complex(Math.cos(angle), Math.sin(angle))); - bn.set(bnSize - i - 1, new FFT.Complex(Math.cos(angle), Math.sin(angle))); - } - - /* Initialization of the a(n) sequence */ - for (int i = 0; i < N; i++) { - double angle = -i * i * Math.PI / N * direction; - an.add(x.get(i).multiply(new FFT.Complex(Math.cos(angle), Math.sin(angle)))); - } - - ArrayList convolution = ConvolutionFFT.convolutionFFT(an, bn); - - /* The final multiplication of the convolution with the b*(k) factor */ - for (int i = 0; i < N; i++) { - double angle = -1 * i * i * Math.PI / N * direction; - FFT.Complex bk = new FFT.Complex(Math.cos(angle), Math.sin(angle)); - x.set(i, bk.multiply(convolution.get(i + N - 1))); - } - - /* Divide by N if we want the inverse FFT */ - if (inverse) { - for (int i = 0; i < N; i++) { - FFT.Complex z = x.get(i); - x.set(i, z.divide(N)); - } - } - } -} diff --git a/Maths/Factorial.java b/Maths/Factorial.java deleted file mode 100644 index 3bd2e74a4864..000000000000 --- a/Maths/Factorial.java +++ /dev/null @@ -1,28 +0,0 @@ -package Maths; - -public class Factorial { - - /* Driver Code */ - public static void main(String[] args) { - assert factorial(0) == 1; - assert factorial(1) == 1; - assert factorial(5) == 120; - assert factorial(10) == 3628800; - } - - /** - * Calculate factorial N using iteration - * - * @param n the number - * @return the factorial of {@code n} - */ - public static long factorial(int n) { - if (n < 0) { - throw new IllegalArgumentException("number is negative"); - } - long factorial = 1; - for (int i = 1; i <= n; factorial *= i, ++i) - ; - return factorial; - } -} diff --git a/Maths/FactorialRecursion.java b/Maths/FactorialRecursion.java deleted file mode 100644 index e580fe9b1ba6..000000000000 --- a/Maths/FactorialRecursion.java +++ /dev/null @@ -1,26 +0,0 @@ -package Maths; - -public class FactorialRecursion { - - /* Driver Code */ - public static void main(String[] args) { - assert factorial(0) == 1; - assert factorial(1) == 1; - assert factorial(2) == 2; - assert factorial(3) == 6; - assert factorial(5) == 120; - } - - /** - * Recursive FactorialRecursion Method - * - * @param n The number to factorial - * @return The factorial of the number - */ - public static long factorial(int n) { - if (n < 0) { - throw new IllegalArgumentException("number is negative"); - } - return n == 0 || n == 1 ? 1 : n * factorial(n - 1); - } -} diff --git a/Maths/FibonacciNumber.java b/Maths/FibonacciNumber.java deleted file mode 100644 index 1cec0963d30c..000000000000 --- a/Maths/FibonacciNumber.java +++ /dev/null @@ -1,35 +0,0 @@ -package Maths; - -/** Fibonacci: 0 1 1 2 3 5 8 13 21 ... */ -public class FibonacciNumber { - public static void main(String[] args) { - assert isFibonacciNumber(1); - assert isFibonacciNumber(2); - assert isFibonacciNumber(21); - assert !isFibonacciNumber(9); - assert !isFibonacciNumber(10); - } - - /** - * Check if a number is perfect square number - * - * @param number the number to be checked - * @return true if {@code number} is perfect square, otherwise false - */ - public static boolean isPerfectSquare(int number) { - int sqrt = (int) Math.sqrt(number); - return sqrt * sqrt == number; - } - - /** - * Check if a number is fibonacci number This is true if and only if at least one of 5x^2+4 or - * 5x^2-4 is a perfect square - * - * @param number the number - * @return true if {@code number} is fibonacci number, otherwise false - * @link https://en.wikipedia.org/wiki/Fibonacci_number#Identification - */ - public static boolean isFibonacciNumber(int number) { - return isPerfectSquare(5 * number * number + 4) || isPerfectSquare(5 * number * number - 4); - } -} diff --git a/Maths/FindMax.java b/Maths/FindMax.java deleted file mode 100644 index 961b23380a3a..000000000000 --- a/Maths/FindMax.java +++ /dev/null @@ -1,39 +0,0 @@ -package Maths; - -import java.util.Arrays; -import java.util.Random; - -public class FindMax { - - /** Driver Code */ - public static void main(String[] args) { - Random random = new Random(); - - /* random size */ - int size = random.nextInt(100) + 1; - int[] array = new int[size]; - - /* init array with random numbers */ - for (int i = 0; i < size; i++) { - array[i] = random.nextInt() % 100; - } - - assert Arrays.stream(array).max().getAsInt() == findMax(array); - } - - /** - * find max of array - * - * @param array the array contains element - * @return max value of given array - */ - public static int findMax(int[] array) { - int max = array[0]; - for (int i = 1; i < array.length; ++i) { - if (array[i] > max) { - max = array[i]; - } - } - return max; - } -} diff --git a/Maths/FindMaxRecursion.java b/Maths/FindMaxRecursion.java deleted file mode 100644 index 38fe2dae8ac5..000000000000 --- a/Maths/FindMaxRecursion.java +++ /dev/null @@ -1,54 +0,0 @@ -package Maths; - -import java.util.Arrays; -import java.util.Random; - -public class FindMaxRecursion { - public static void main(String[] args) { - Random rand = new Random(); - - /* rand size */ - int size = rand.nextInt(100) + 1; - int[] array = new int[size]; - - /* init array with rand numbers */ - for (int i = 0; i < size; i++) { - array[i] = rand.nextInt() % 100; - } - - assert max(array, array.length) == Arrays.stream(array).max().getAsInt(); - assert max(array, 0, array.length - 1) == Arrays.stream(array).max().getAsInt(); - } - - /** - * Get max of array using divide and conquer algorithm - * - * @param array contains elements - * @param low the index of the first element - * @param high the index of the last element - * @return max of {@code array} - */ - public static int max(int[] array, int low, int high) { - if (low == high) { - return array[low]; // or array[high] - } - - int mid = (low + high) >>> 1; - - int leftMax = max(array, low, mid); // get max in [low, mid] - int rightMax = max(array, mid + 1, high); // get max in [mid+1, high] - - return Math.max(leftMax, rightMax); - } - - /** - * Get max of array using recursion algorithm - * - * @param array contains elements - * @param len length of given array - * @return max value of {@code array} - */ - public static int max(int[] array, int len) { - return len == 1 ? array[0] : Math.max(max(array, len - 1), array[len - 1]); - } -} diff --git a/Maths/FindMin.java b/Maths/FindMin.java deleted file mode 100644 index 198bd1e93a7b..000000000000 --- a/Maths/FindMin.java +++ /dev/null @@ -1,39 +0,0 @@ -package Maths; - -import java.util.Arrays; -import java.util.Random; - -public class FindMin { - - /** Driver Code */ - public static void main(String[] args) { - Random random = new Random(); - - /* random size */ - int size = random.nextInt(100) + 1; - int[] array = new int[size]; - - /* init array with random numbers */ - for (int i = 0; i < size; i++) { - array[i] = random.nextInt() % 100; - } - - assert Arrays.stream(array).min().getAsInt() == findMin(array); - } - - /** - * Find the minimum number of an array of numbers. - * - * @param array the array contains element - * @return min value - */ - public static int findMin(int[] array) { - int min = array[0]; - for (int i = 1; i < array.length; ++i) { - if (array[i] < min) { - min = array[i]; - } - } - return min; - } -} diff --git a/Maths/FindMinRecursion.java b/Maths/FindMinRecursion.java deleted file mode 100644 index 4922e0d109e6..000000000000 --- a/Maths/FindMinRecursion.java +++ /dev/null @@ -1,56 +0,0 @@ -package Maths; - -import java.util.Arrays; -import java.util.Random; - -public class FindMinRecursion { - - /** Driver Code */ - public static void main(String[] args) { - Random rand = new Random(); - - /* rand size */ - int size = rand.nextInt(100) + 1; - int[] array = new int[size]; - - /* init array with rand numbers */ - for (int i = 0; i < size; i++) { - array[i] = rand.nextInt() % 100; - } - - assert min(array, 0, array.length - 1) == Arrays.stream(array).min().getAsInt(); - assert min(array, array.length) == Arrays.stream(array).min().getAsInt(); - } - - /** - * Get min of array using divide and conquer algorithm - * - * @param array contains elements - * @param low the index of the first element - * @param high the index of the last element - * @return min of {@code array} - */ - public static int min(int[] array, int low, int high) { - if (low == high) { - return array[low]; // or array[high] - } - - int mid = (low + high) >>> 1; - - int leftMin = min(array, low, mid); // get min in [low, mid] - int rightMin = min(array, mid + 1, high); // get min in [mid+1, high] - - return Math.min(leftMin, rightMin); - } - - /** - * Get min of array using recursion algorithm - * - * @param array contains elements - * @param len length of given array - * @return min value of {@code array} - */ - public static int min(int[] array, int len) { - return len == 1 ? array[0] : Math.min(min(array, len - 1), array[len - 1]); - } -} diff --git a/Maths/Floor.java b/Maths/Floor.java deleted file mode 100644 index dbd41ac87344..000000000000 --- a/Maths/Floor.java +++ /dev/null @@ -1,29 +0,0 @@ -package Maths; - -import java.util.Random; - -public class Floor { - public static void main(String[] args) { - Random random = new Random(); - for (int i = 1; i <= 1000; ++i) { - double randomNumber = random.nextDouble(); - assert floor(randomNumber) == Math.floor(randomNumber); - } - } - - /** - * Returns the largest (closest to positive infinity) - * - * @param number the number - * @return the largest (closest to positive infinity) of given {@code number} - */ - public static double floor(double number) { - if (number - (int) number == 0) { - return number; - } else if (number - (int) number > 0) { - return (int) number; - } else { - return (int) number - 1; - } - } -} diff --git a/Maths/GCD.java b/Maths/GCD.java deleted file mode 100644 index 0f17f6ea5f11..000000000000 --- a/Maths/GCD.java +++ /dev/null @@ -1,57 +0,0 @@ -package Maths; - -/** - * This is Euclid's algorithm which is used to find the greatest common denominator Overide function - * name gcd - * - * @author Oskar Enmalm 3/10/17 - */ -public class GCD { - - /** - * get greatest common divisor - * - * @param num1 the first number - * @param num2 the second number - * @return gcd - */ - public static int gcd(int num1, int num2) { - if (num1 < 0 || num2 < 0) { - throw new ArithmeticException(); - } - - if (num1 == 0 || num2 == 0) { - return Math.abs(num1 - num2); - } - - while (num1 % num2 != 0) { - int remainder = num1 % num2; - num1 = num2; - num2 = remainder; - } - return num2; - } - - /** - * get greatest common divisor in array - * - * @param number contains number - * @return gcd - */ - public static int gcd(int[] number) { - int result = number[0]; - for (int i = 1; i < number.length; i++) - // call gcd function (input two value) - result = gcd(result, number[i]); - - return result; - } - - public static void main(String[] args) { - int[] myIntArray = {4, 16, 32}; - - // call gcd function (input array) - System.out.println(gcd(myIntArray)); // => 4 - System.out.printf("gcd(40,24)=%d gcd(24,40)=%d%n", gcd(40, 24), gcd(24, 40)); // => 8 - } -} diff --git a/Maths/GCDRecursion.java b/Maths/GCDRecursion.java deleted file mode 100644 index d0104d3db9e9..000000000000 --- a/Maths/GCDRecursion.java +++ /dev/null @@ -1,34 +0,0 @@ -package Maths; - -/** @author https://github.com/shellhub/ */ -public class GCDRecursion { - public static void main(String[] args) { - System.out.println(gcd(20, 15)); /* output: 5 */ - System.out.println(gcd(10, 8)); /* output: 2 */ - System.out.println(gcd(gcd(10, 5), gcd(5, 10))); /* output: 5 */ - } - - /** - * get greatest common divisor - * - * @param a the first number - * @param b the second number - * @return gcd - */ - public static int gcd(int a, int b) { - - if (a < 0 || b < 0) { - throw new ArithmeticException(); - } - - if (a == 0 || b == 0) { - return Math.abs(a - b); - } - - if (a % b == 0) { - return b; - } else { - return gcd(b, a % b); - } - } -} diff --git a/Maths/Gaussian.java b/Maths/Gaussian.java deleted file mode 100644 index a48d26ee8ee9..000000000000 --- a/Maths/Gaussian.java +++ /dev/null @@ -1,68 +0,0 @@ -/** - * \file - * \brief [Gaussian elimination - * method](https://en.wikipedia.org/wiki/Gaussian_elimination) - */ -package Maths; -import java.util.*; - -/** Main function */ -public class Gaussian { - - public static void main(String[] args) { - int mat_size, i, j, step; - Scanner sc = new Scanner(System.in); - - System.out.println("Matrix Size : "); - mat_size = sc.nextInt(); - - double [][] mat = new double[mat_size+1][mat_size+1]; - double [][] x = new double[mat_size][mat_size+1]; - - System.out.println("Enter value of the matrix"); - System.out.println(' '); - for (i = 0; i < mat_size; i++) { - for (j = 0; j <= mat_size; j++) { - mat[i][j] = sc.nextInt(); - } - } - - // perform Gaussian elimination - for (step = 0; step < mat_size - 1; step++) { - for (i = step; i < mat_size - 1; i++) { - double a = (mat[i + 1][step] / mat[step][step]); - - for (j = step; j <= mat_size; j++) - mat[i + 1][j] = mat[i + 1][j] - (a * mat[step][j]); - } - } - - System.out.println("Matrix using Gaussian Elimination method: "); - System.out.println(" "); - for (i = 0; i < mat_size; i++) { - for (j = 0; j <= mat_size; j++) { - x[i][j] = mat[i][j]; - System.out.print(mat[i][j] + " "); - } - System.out.println(); - } - System.out.println( "Value of the Gaussian Elimination method: "); - System.out.println(" "); - - for (i = mat_size - 1; i >= 0; i--) { - double sum = 0; - for (j = mat_size - 1; j > i; j--) { - x[i][j] = x[j][j] * x[i][j]; - sum = x[i][j] + sum; - } - if (x[i][i] == 0){ - x[i][i] = 0; - } - else{ - x[i][i] = (x[i][mat_size] - sum) / (x[i][i]); - } - System.out.print("x" + i + "=" + x[i][i]); - System.out.println(" "); - } - } -} diff --git a/Maths/GenericRoot.java b/Maths/GenericRoot.java deleted file mode 100644 index 67074177be4b..000000000000 --- a/Maths/GenericRoot.java +++ /dev/null @@ -1,28 +0,0 @@ -package Maths; - -/* - * Algorithm explanation: https://technotip.com/6774/c-program-to-find-generic-root-of-a-number/#:~:text=Generic%20Root%3A%20of%20a%20number,get%20a%20single%2Ddigit%20output.&text=For%20Example%3A%20If%20user%20input,%2B%204%20%2B%205%20%3D%2015. - */ -public class GenericRoot { - public static void main(String[] args) { - int number1 = 1234; - int number2 = 12345; - int result1 = genericRoot(number1); - int result2 = genericRoot(number2); - System.out.println("Generic root of " + number1 + " is: " + result1); - System.out.println("Generic root of " + number2 + " is: " + result2); - } - - private static int genericRoot(int n) { - int root = 0; - while (n > 0 || root > 9) { - if (n == 0) { - n = root; - root = 0; - } - root += n % 10; - n /= 10; - } - return root; - } -} diff --git a/Maths/KrishnamurthyNumber.java b/Maths/KrishnamurthyNumber.java deleted file mode 100644 index 130914226ee2..000000000000 --- a/Maths/KrishnamurthyNumber.java +++ /dev/null @@ -1,70 +0,0 @@ -package Maths; - -/* This is a program to check if a number is a Krishnamurthy number or not. -A number is a Krishnamurthy number if the sum of the factorials of the digits of the number is equal to the number itself. -For example, 1, 2 and 145 are Krishnamurthy numbers. -Krishnamurthy number is also referred to as a Strong number. -*/ - -import java.io.*; - -public class KrishnamurthyNumber -{ - //returns True if the number is a Krishnamurthy number and False if it is not. - public static boolean isKMurthy(int n) - { - //initialising the variable s that will store the sum of the factorials of the digits to 0 - int s=0; - //storing the number n in a temporary variable tmp - int tmp=n; - - //Krishnamurthy numbers are positive - if(n<=0) - { - return false; - } - - //checking if the number is a Krishnamurthy number - else - { - while(n!=0) - { - //initialising the variable fact that will store the factorials of the digits - int fact=1; - //computing factorial of each digit - for (int i=1;i<=n%10;i++) - { - fact=fact*i; - } - //computing the sum of the factorials - s=s+fact; - //discarding the digit for which factorial has been calculated - n=n/10; - } - - //evaluating if sum of the factorials of the digits equals the number itself - if(tmp==s) - { - return true; - } - else - { - return false; - } - } - } - public static void main(String args[]) throws IOException - { - BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); - System.out.println("Enter a number to check if it is a Krishnamurthy number: "); - int n=Integer.parseInt(br.readLine()); - if(isKMurthy(n)) - { - System.out.println(n+" is a Krishnamurthy number."); - } - else - { - System.out.println(n+" is NOT a Krishnamurthy number."); - } - } -} diff --git a/Maths/LucasSeries.java b/Maths/LucasSeries.java deleted file mode 100644 index ade5ab2c52fe..000000000000 --- a/Maths/LucasSeries.java +++ /dev/null @@ -1,43 +0,0 @@ -package Maths; - -/** https://en.wikipedia.org/wiki/Lucas_number */ -public class LucasSeries { - public static void main(String[] args) { - assert lucasSeries(1) == 2 && lucasSeriesIteration(1) == 2; - assert lucasSeries(2) == 1 && lucasSeriesIteration(2) == 1; - assert lucasSeries(3) == 3 && lucasSeriesIteration(3) == 3; - assert lucasSeries(4) == 4 && lucasSeriesIteration(4) == 4; - assert lucasSeries(5) == 7 && lucasSeriesIteration(5) == 7; - assert lucasSeries(6) == 11 && lucasSeriesIteration(6) == 11; - assert lucasSeries(11) == 123 && lucasSeriesIteration(11) == 123; - } - - /** - * Calculate nth number of lucas series(2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, ....) using - * recursion - * - * @param n nth - * @return nth number of lucas series - */ - public static int lucasSeries(int n) { - return n == 1 ? 2 : n == 2 ? 1 : lucasSeries(n - 1) + lucasSeries(n - 2); - } - - /** - * Calculate nth number of lucas series(2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, ....) using - * iteration - * - * @param n nth - * @return nth number of lucas series - */ - public static int lucasSeriesIteration(int n) { - int previous = 2; - int current = 1; - for (int i = 1; i < n; i++) { - int next = previous + current; - previous = current; - current = next; - } - return previous; - } -} diff --git a/Maths/MaxValue.java b/Maths/MaxValue.java deleted file mode 100644 index 504f87bc20a8..000000000000 --- a/Maths/MaxValue.java +++ /dev/null @@ -1,32 +0,0 @@ -package Maths; - -import java.util.Random; - -public class MaxValue { - - /** Driver Code */ - public static void main(String[] args) { - Random rand = new Random(); - - /* test 100 times using rand numbers */ - for (int i = 1; i <= 100; ++i) { - /* generate number from -50 to 49 */ - int a = rand.nextInt(100) - 50; - int b = rand.nextInt(100) - 50; - assert max(a, b) == Math.max(a, b); - } - } - - /** - * Returns the greater of two {@code int} values. That is, the result is the argument closer to - * the value of {@link Integer#MAX_VALUE}. If the arguments have the same value, the result is - * that same value. - * - * @param a an argument. - * @param b another argument. - * @return the larger of {@code a} and {@code b}. - */ - public static int max(int a, int b) { - return a >= b ? a : b; - } -} diff --git a/Maths/Median.java b/Maths/Median.java deleted file mode 100644 index b0b011232a3c..000000000000 --- a/Maths/Median.java +++ /dev/null @@ -1,28 +0,0 @@ -package Maths; - -import java.util.Arrays; - -/** Wikipedia: https://en.wikipedia.org/wiki/Median */ -public class Median { - public static void main(String[] args) { - assert median(new int[] {0}) == 0; - assert median(new int[] {1, 2}) == 1.5; - assert median(new int[] {4, 1, 3, 2}) == 2.5; - assert median(new int[] {1, 3, 3, 6, 7, 8, 9}) == 6; - assert median(new int[] {1, 2, 3, 4, 5, 6, 8, 9}) == 4.5; - } - - /** - * Calculate average median - * - * @param values number series - * @return median of given {@code values} - */ - public static double median(int[] values) { - Arrays.sort(values); - int length = values.length; - return length % 2 == 0 - ? (values[length / 2] + values[length / 2 - 1]) / 2.0 - : values[length / 2]; - } -} diff --git a/Maths/MinValue.java b/Maths/MinValue.java deleted file mode 100644 index 3bb4b5434113..000000000000 --- a/Maths/MinValue.java +++ /dev/null @@ -1,32 +0,0 @@ -package Maths; - -import java.util.Random; - -public class MinValue { - - /** Driver Code */ - public static void main(String[] args) { - Random rand = new Random(); - - /* test 100 times using rand numbers */ - for (int i = 1; i <= 100; ++i) { - /* generate number from -50 to 49 */ - int a = rand.nextInt(100) - 50; - int b = rand.nextInt(100) - 50; - assert min(a, b) == Math.min(a, b); - } - } - - /** - * Returns the smaller of two {@code int} values. That is, the result the argument closer to the - * value of {@link Integer#MIN_VALUE}. If the arguments have the same value, the result is that - * same value. - * - * @param a an argument. - * @param b another argument. - * @return the smaller of {@code a} and {@code b}. - */ - public static int min(int a, int b) { - return a <= b ? a : b; - } -} diff --git a/Maths/Mode.java b/Maths/Mode.java deleted file mode 100644 index 5d28c8c8c4bf..000000000000 --- a/Maths/Mode.java +++ /dev/null @@ -1,59 +0,0 @@ -package Maths; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; - -/* - * Find the mode of an array of numbers - * - * The mode of an array of numbers is the most frequently occurring number in the array, - * or the most frequently occurring numbers if there are multiple numbers with the same frequency - */ -public class Mode { - - public static void main(String[] args) { - - /* Test array of integers */ - assert (mode(new int[] {})) == null; - assert Arrays.equals(mode(new int[] {5}), new int[] {5}); - assert Arrays.equals(mode(new int[] {1, 2, 3, 4, 5}), new int[] {1, 2, 3, 4, 5}); - assert Arrays.equals(mode(new int[] {7, 9, 9, 4, 5, 6, 7, 7, 8}), new int[] {7}); - assert Arrays.equals(mode(new int[] {7, 9, 9, 4, 5, 6, 7, 7, 9}), new int[] {7, 9}); - } - - /* - * Find the mode of an array of integers - * - * @param numbers array of integers - * @return mode of the array - */ - public static int[] mode(int[] numbers) { - - if (numbers.length == 0) return null; - - HashMap count = new HashMap<>(); - - for (int num : numbers) { - if (count.containsKey(num)) { - - count.put(num, count.get(num) + 1); - - } else { - - count.put(num, 1); - } - } - - int max = Collections.max(count.values()); - ArrayList modes = new ArrayList<>(); - - for (int num : count.keySet()) { - if (count.get(num) == max) { - modes.add(num); - } - } - return modes.stream().mapToInt(n -> n).toArray(); - } -} diff --git a/Maths/NonRepeatingElement.java b/Maths/NonRepeatingElement.java deleted file mode 100644 index e332d8e803fa..000000000000 --- a/Maths/NonRepeatingElement.java +++ /dev/null @@ -1,71 +0,0 @@ -package Maths; -import java.util.Scanner; - -/* - * Find the 2 elements which are non repeating in an array - * Reason to use bitwise operator: It makes our program faster as we are operating on bits and not on - * actual numbers. - */ -public class NonRepeatingElement { - - public static void main(String[] args) { - - Scanner sc = new Scanner(System.in); - int i, res = 0; - System.out.println("Enter the number of elements in the array"); - int n = sc.nextInt(); - if((n & 1) == 1) - { - //Not allowing odd number of elements as we are expecting 2 non repeating numbers - System.out.println("Array should contain even number of elements"); - return; - } - int arr[] = new int[n]; - - System.out.println("Enter "+n+" elements in the array. NOTE: Only 2 elements should not repeat"); - for(i = 0; i 0)//Case 1 explained below - num1^=arr[i]; - else - num2^=arr[i];//Case 2 explained below - - } - - System.out.println("The two non repeating elements are "+num1+" and "+num2); - - } - - /* - Explanation of the code: - let us assume we have an array [1,2,1,2,3,4] - Property of XOR: num ^ num = 0. - If we XOR all the elemnets of the array we will be left with 3 ^ 4 as 1 ^ 1 and 2 ^ 2 would give 0. - Our task is to find num1 and num2 from the result of 3 ^ 4 = 7. - We need to find two's complement of 7 and find the rightmost set bit. i.e. (num & (-num)) - Two's complement of 7 is 001 and hence res = 1. - There can be 2 options when we Bitise AND this res with all the elements in our array - 1. Result will come non zero number - 2. Result will be 0. - In the first case we will XOR our element with the first number (which is initially 0) - In the second case we will XOR our element with the second number(which is initially 0) - This is how we will get non repeating elements with the help of bitwise operators. - */ -} diff --git a/Maths/NumberOfDigits.java b/Maths/NumberOfDigits.java deleted file mode 100644 index acc9f8c91cb0..000000000000 --- a/Maths/NumberOfDigits.java +++ /dev/null @@ -1,59 +0,0 @@ -package Maths; - -/** Find the number of digits in a number. */ -public class NumberOfDigits { - public static void main(String[] args) { - int[] numbers = {0, 12, 123, 1234, -12345, 123456, 1234567, 12345678, 123456789}; - for (int i = 0; i < numbers.length; ++i) { - assert numberOfDigits(numbers[i]) == i + 1; - assert numberOfDigitsFast(numbers[i]) == i + 1; - assert numberOfDigitsFaster(numbers[i]) == i + 1; - assert numberOfDigitsRecursion(numbers[i]) == i + 1; - } - } - - /** - * Find the number of digits in a number. - * - * @param number number to find - * @return number of digits of given number - */ - private static int numberOfDigits(int number) { - int digits = 0; - do { - digits++; - number /= 10; - } while (number != 0); - return digits; - } - - /** - * Find the number of digits in a number fast version. - * - * @param number number to find - * @return number of digits of given number - */ - private static int numberOfDigitsFast(int number) { - return number == 0 ? 1 : (int) Math.floor(Math.log10(Math.abs(number)) + 1); - } - - /** - * Find the number of digits in a number faster version. - * - * @param number number to find - * @return number of digits of given number - */ - private static int numberOfDigitsFaster(int number) { - return number < 0 ? (-number + "").length() : (number + "").length(); - } - - /** - * Find the number of digits in a number using recursion. - * - * @param number number to find - * @return number of digits of given number - */ - private static int numberOfDigitsRecursion(int number) { - return number / 10 == 0 ? 1 : 1 + numberOfDigitsRecursion(number / 10); - } -} diff --git a/Maths/PalindromeNumber.java b/Maths/PalindromeNumber.java deleted file mode 100644 index 08c4ba01bea7..000000000000 --- a/Maths/PalindromeNumber.java +++ /dev/null @@ -1,30 +0,0 @@ -package Maths; - -public class PalindromeNumber { - public static void main(String[] args) { - - assert isPalindrome(12321); - assert !isPalindrome(1234); - assert isPalindrome(1); - } - - /** - * Check if {@code n} is palindrome number or not - * - * @param number the number - * @return {@code true} if {@code n} is palindrome number, otherwise {@code false} - */ - public static boolean isPalindrome(int number) { - if (number < 0) { - throw new IllegalArgumentException(number + ""); - } - int numberCopy = number; - int reverseNumber = 0; - while (numberCopy != 0) { - int remainder = numberCopy % 10; - reverseNumber = reverseNumber * 10 + remainder; - numberCopy /= 10; - } - return number == reverseNumber; - } -} diff --git a/Maths/ParseInteger.java b/Maths/ParseInteger.java deleted file mode 100644 index cf9c9efc88fd..000000000000 --- a/Maths/ParseInteger.java +++ /dev/null @@ -1,33 +0,0 @@ -package Maths; - -public class ParseInteger { - public static void main(String[] args) { - assert parseInt("123") == Integer.parseInt("123"); - assert parseInt("-123") == Integer.parseInt("-123"); - assert parseInt("0123") == Integer.parseInt("0123"); - assert parseInt("+123") == Integer.parseInt("+123"); - } - - /** - * Parse a string to integer - * - * @param s the string - * @return the integer value represented by the argument in decimal. - * @throws NumberFormatException if the {@code string} does not contain a parsable integer. - */ - public static int parseInt(String s) { - if (s == null || s.length() == 0) { - throw new NumberFormatException("null"); - } - boolean isNegative = s.charAt(0) == '-'; - boolean isPositive = s.charAt(0) == '+'; - int number = 0; - for (int i = isNegative ? 1 : isPositive ? 1 : 0, length = s.length(); i < length; ++i) { - if (!Character.isDigit(s.charAt(i))) { - throw new NumberFormatException("s=" + s); - } - number = number * 10 + s.charAt(i) - '0'; - } - return isNegative ? -number : number; - } -} diff --git a/Maths/PerfectCube.java b/Maths/PerfectCube.java deleted file mode 100644 index 2ecb8e805a42..000000000000 --- a/Maths/PerfectCube.java +++ /dev/null @@ -1,24 +0,0 @@ -package Maths; - -/** https://en.wikipedia.org/wiki/Cube_(algebra) */ -public class PerfectCube { - public static void main(String[] args) { - assert !isPerfectCube(-1); - assert isPerfectCube(0); - assert isPerfectCube(1); - assert !isPerfectCube(4); - assert isPerfectCube(8); - assert isPerfectCube(27); - } - - /** - * Check if a number is perfect cube or not - * - * @param number number to check - * @return {@code true} if {@code number} is perfect cube, otherwise {@code false} - */ - public static boolean isPerfectCube(int number) { - int a = (int) Math.pow(number, 1.0 / 3); - return a * a * a == number; - } -} diff --git a/Maths/PerfectNumber.java b/Maths/PerfectNumber.java deleted file mode 100644 index de56c4175c02..000000000000 --- a/Maths/PerfectNumber.java +++ /dev/null @@ -1,32 +0,0 @@ -package Maths; - -/** - * In number theory, a perfect number is a positive integer that is equal to the sum of its positive - * divisors, excluding the number itself. For instance, 6 has divisors 1, 2 and 3 (excluding - * itself), and 1 + 2 + 3 = 6, so 6 is a perfect number. - * - *

link:https://en.wikipedia.org/wiki/Perfect_number - */ -public class PerfectNumber { - public static void main(String[] args) { - assert isPerfectNumber(6); /* 1 + 2 + 3 == 6 */ - assert !isPerfectNumber(8); /* 1 + 2 + 4 != 8 */ - assert isPerfectNumber(28); /* 1 + 2 + 4 + 7 + 14 == 28 */ - } - - /** - * Check if {@code number} is perfect number or not - * - * @param number the number - * @return {@code true} if {@code number} is perfect number, otherwise false - */ - public static boolean isPerfectNumber(int number) { - int sum = 0; /* sum of its positive divisors */ - for (int i = 1; i < number; ++i) { - if (number % i == 0) { - sum += i; - } - } - return sum == number; - } -} diff --git a/Maths/PerfectSquare.java b/Maths/PerfectSquare.java deleted file mode 100644 index aef645e2ed2b..000000000000 --- a/Maths/PerfectSquare.java +++ /dev/null @@ -1,23 +0,0 @@ -package Maths; - -/** https://en.wikipedia.org/wiki/Perfect_square */ -public class PerfectSquare { - public static void main(String[] args) { - assert !isPerfectSquare(-1); - assert !isPerfectSquare(3); - assert !isPerfectSquare(5); - assert isPerfectSquare(9); - assert isPerfectSquare(100); - } - - /** - * Check if a number is perfect square number - * - * @param number the number to be checked - * @return true if {@code number} is perfect square, otherwise false - */ - public static boolean isPerfectSquare(int number) { - int sqrt = (int) Math.sqrt(number); - return sqrt * sqrt == number; - } -} diff --git a/Maths/PiNilakantha.java b/Maths/PiNilakantha.java deleted file mode 100644 index 1bdcceef86b7..000000000000 --- a/Maths/PiNilakantha.java +++ /dev/null @@ -1,40 +0,0 @@ -package Maths; - -public class PiNilakantha { - - // Calculates Pi using Nilakantha's infinite series - // Method 2 in the following link explains the algorithm - // https://en.scratch-wiki.info/wiki/Calculating_Pi - - public static void main(String[] args) { - assert calculatePi(0) == 3.0; - assert calculatePi(10) > 3.0; - assert calculatePi(100) < 4.0; - - System.out.println(calculatePi(500)); - } - - /** - * @param iterations number of times the infinite series gets repeated Pi get more accurate the - * higher the value of iterations is Values from 0 up to 500 are allowed since double - * precision is not sufficient for more than about 500 repetitions of this algorithm - * @return the pi value of the calculation with a precision of x iteration - */ - public static double calculatePi(int iterations) { - if (iterations < 0 || iterations > 500) { - throw new IllegalArgumentException("Please input Integer Number between 0 and 500"); - } - - double pi = 3; - int divCounter = 2; - - for (int i = 0; i < iterations; i++) { - - if (i % 2 == 0) pi = pi + 4.0 / (divCounter * (divCounter + 1) * (divCounter + 2)); - else pi = pi - 4.0 / (divCounter * (divCounter + 1) * (divCounter + 2)); - - divCounter += 2; - } - return pi; - } -} diff --git a/Maths/Pow.java b/Maths/Pow.java deleted file mode 100644 index 6af5446510af..000000000000 --- a/Maths/Pow.java +++ /dev/null @@ -1,26 +0,0 @@ -package Maths; - -// POWER (exponentials) Examples (a^b) -public class Pow { - public static void main(String[] args) { - assert pow(2, 0) == Math.pow(2, 0); // == 1 - assert pow(0, 2) == Math.pow(0, 2); // == 0 - assert pow(2, 10) == Math.pow(2, 10); // == 1024 - assert pow(10, 2) == Math.pow(10, 2); // == 100 - } - - /** - * Returns the value of the first argument raised to the power of the second argument - * - * @param a the base. - * @param b the exponent. - * @return the value {@code a}{@code b}. - */ - public static long pow(int a, int b) { - long result = 1; - for (int i = 1; i <= b; i++) { - result *= a; - } - return result; - } -} diff --git a/Maths/PowRecursion.java b/Maths/PowRecursion.java deleted file mode 100644 index 598fc724e54a..000000000000 --- a/Maths/PowRecursion.java +++ /dev/null @@ -1,21 +0,0 @@ -package Maths; - -public class PowRecursion { - public static void main(String[] args) { - assert Double.compare(pow(2, 0), Math.pow(2, 0)) == 0; - assert Double.compare(pow(0, 2), Math.pow(0, 2)) == 0; - assert Double.compare(pow(2, 10), Math.pow(2, 10)) == 0; - assert Double.compare(pow(10, 2), Math.pow(10, 2)) == 0; - } - - /** - * Returns the value of the first argument raised to the power of the second argument - * - * @param a the base. - * @param b the exponent. - * @return the value {@code a}{@code b}. - */ - public static long pow(int a, int b) { - return b == 0 ? 1 : a * pow(a, b - 1); - } -} diff --git a/Maths/PowerOfTwoOrNot.java b/Maths/PowerOfTwoOrNot.java deleted file mode 100644 index 329f64d139f2..000000000000 --- a/Maths/PowerOfTwoOrNot.java +++ /dev/null @@ -1,23 +0,0 @@ -package Maths; - -/** A utility to check if a given number is power of two or not. For example 8,16 etc. */ -public class PowerOfTwoOrNot { - - public static void main(String[] args) { - assert !checkIfPowerOfTwoOrNot(0); - assert checkIfPowerOfTwoOrNot(1); - assert checkIfPowerOfTwoOrNot(8); - assert checkIfPowerOfTwoOrNot(16); - assert checkIfPowerOfTwoOrNot(1024); - } - - /** - * Checks whether given number is power of two or not. - * - * @param number the number to check - * @return {@code true} if given number is power of two, otherwise {@code false} - */ - public static boolean checkIfPowerOfTwoOrNot(int number) { - return number != 0 && ((number & (number - 1)) == 0); - } -} diff --git a/Maths/PrimeCheck.java b/Maths/PrimeCheck.java deleted file mode 100644 index 6ea901a8a73e..000000000000 --- a/Maths/PrimeCheck.java +++ /dev/null @@ -1,38 +0,0 @@ -package Maths; - -import java.util.Scanner; - -public class PrimeCheck { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - - System.out.print("Enter a number: "); - int n = scanner.nextInt(); - if (isPrime(n)) { - System.out.println(n + " is a prime number"); - } else { - System.out.println(n + " is not a prime number"); - } - scanner.close(); - } - - /*** - * Checks if a number is prime or not - * @param n the number - * @return {@code true} if {@code n} is prime - */ - public static boolean isPrime(int n) { - if (n == 2) { - return true; - } - if (n < 2 || n % 2 == 0) { - return false; - } - for (int i = 3, limit = (int) Math.sqrt(n); i <= limit; i += 2) { - if (n % i == 0) { - return false; - } - } - return true; - } -} diff --git a/Maths/PrimeFactorization.java b/Maths/PrimeFactorization.java deleted file mode 100644 index 79e12a7dc49b..000000000000 --- a/Maths/PrimeFactorization.java +++ /dev/null @@ -1,32 +0,0 @@ -package Maths; - -import java.util.Scanner; - -public class PrimeFactorization { - public static void main(String[] args) { - System.out.println("## all prime factors ##"); - Scanner scanner = new Scanner(System.in); - System.out.print("Enter a number: "); - int n = scanner.nextInt(); - System.out.print(("printing factors of " + n + " : ")); - pfactors(n); - scanner.close(); - } - - public static void pfactors(int n) { - - while (n % 2 == 0) { - System.out.print(2 + " "); - n /= 2; - } - - for (int i = 3; i <= Math.sqrt(n); i += 2) { - while (n % i == 0) { - System.out.print(i + " "); - n /= i; - } - } - - if (n > 2) System.out.print(n); - } -} diff --git a/Maths/PythagoreanTriple.java b/Maths/PythagoreanTriple.java deleted file mode 100644 index 5aaf95c7550e..000000000000 --- a/Maths/PythagoreanTriple.java +++ /dev/null @@ -1,30 +0,0 @@ -package Maths; - -/** https://en.wikipedia.org/wiki/Pythagorean_triple */ -public class PythagoreanTriple { - public static void main(String[] args) { - assert isPythagTriple(3, 4, 5); - assert isPythagTriple(5, 12, 13); - assert isPythagTriple(6, 8, 10); - assert !isPythagTriple(10, 20, 30); - assert !isPythagTriple(6, 8, 100); - assert !isPythagTriple(-1, -1, 1); - } - - /** - * Check if a,b,c are a Pythagorean Triple - * - * @param a x/y component length of a right triangle - * @param b y/x component length of a right triangle - * @param c hypotenuse length of a right triangle - * @return boolean true if a, b, c satisfy the Pythagorean theorem, otherwise - * false - */ - public static boolean isPythagTriple(int a, int b, int c) { - if (a <= 0 || b <= 0 || c <= 0) { - return false; - } else { - return (a * a) + (b * b) == (c * c); - } - } -} diff --git a/Maths/SumOfArithmeticSeries.java b/Maths/SumOfArithmeticSeries.java deleted file mode 100644 index 01e7c3a0357c..000000000000 --- a/Maths/SumOfArithmeticSeries.java +++ /dev/null @@ -1,40 +0,0 @@ -package Maths; - -/** - * In mathematics, an arithmetic progression (AP) or arithmetic sequence is a sequence of numbers - * such that the difference between the consecutive terms is constant. Difference here means the - * second minus the first. For instance, the sequence 5, 7, 9, 11, 13, 15, . . . is an arithmetic - * progression with common difference of 2. - * - *

Wikipedia: https://en.wikipedia.org/wiki/Arithmetic_progression - */ -public class SumOfArithmeticSeries { - public static void main(String[] args) { - - /* 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 */ - assert Double.compare(55.0, sumOfSeries(1, 1, 10)) == 0; - - /* 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 */ - assert Double.compare(100.0, sumOfSeries(1, 2, 10)) == 0; - - /* 1 + 11 + 21 + 31 + 41 + 51 + 61 + 71 + 81 + 91 */ - assert Double.compare(460.0, sumOfSeries(1, 10, 10)) == 0; - - /* 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 0.6 + 0.7 + 0.8 + 0.9 + 1.0 */ - assert Double.compare(5.5, sumOfSeries(0.1, 0.1, 10)) == 0; - - assert Double.compare(49600.0, sumOfSeries(1, 10, 100)) == 0; - } - - /** - * Calculate sum of arithmetic series - * - * @param firstTerm the initial term of an arithmetic series - * @param commonDiff the common difference of an arithmetic series - * @param numOfTerms the total terms of an arithmetic series - * @return sum of given arithmetic series - */ - private static double sumOfSeries(double firstTerm, double commonDiff, int numOfTerms) { - return numOfTerms / 2.0 * (2 * firstTerm + (numOfTerms - 1) * commonDiff); - } -} diff --git a/Maths/SumOfDigits.java b/Maths/SumOfDigits.java deleted file mode 100644 index 11b3726a9ddf..000000000000 --- a/Maths/SumOfDigits.java +++ /dev/null @@ -1,56 +0,0 @@ -package Maths; - -public class SumOfDigits { - public static void main(String[] args) { - assert sumOfDigits(-123) == 6 && sumOfDigitsRecursion(-123) == 6 && sumOfDigitsFast(-123) == 6; - - assert sumOfDigits(0) == 0 && sumOfDigitsRecursion(0) == 0 && sumOfDigitsFast(0) == 0; - - assert sumOfDigits(12345) == 15 - && sumOfDigitsRecursion(12345) == 15 - && sumOfDigitsFast(12345) == 15; - } - - /** - * Calculate the sum of digits of a number - * - * @param number the number contains digits - * @return sum of digits of given {@code number} - */ - public static int sumOfDigits(int number) { - number = number < 0 ? -number : number; /* calculate abs value */ - int sum = 0; - while (number != 0) { - sum += number % 10; - number /= 10; - } - return sum; - } - - /** - * Calculate the sum of digits of a number using recursion - * - * @param number the number contains digits - * @return sum of digits of given {@code number} - */ - public static int sumOfDigitsRecursion(int number) { - number = number < 0 ? -number : number; /* calculate abs value */ - return number < 10 ? number : number % 10 + sumOfDigitsRecursion(number / 10); - } - - /** - * Calculate the sum of digits of a number using char array - * - * @param number the number contains digits - * @return sum of digits of given {@code number} - */ - public static int sumOfDigitsFast(int number) { - number = number < 0 ? -number : number; /* calculate abs value */ - char[] digits = (number + "").toCharArray(); - int sum = 0; - for (int i = 0; i < digits.length; ++i) { - sum += digits[i] - '0'; - } - return sum; - } -} diff --git a/Maths/VampireNumber.java b/Maths/VampireNumber.java deleted file mode 100644 index e09dd0bb0cf8..000000000000 --- a/Maths/VampireNumber.java +++ /dev/null @@ -1,78 +0,0 @@ -package Maths; - -import java.util.ArrayList; -import java.util.Collections; - -/** - * n number theory, a vampire number (or true vampire number) is a composite natural number with an - * even number of digits, that can be factored into two natural numbers each with half as many - * digits as the original number and not both with trailing zeroes, where the two factors contain - * precisely all the digits of the original number, in any order, counting multiplicity. The first - * vampire number is 1260 = 21 × 60. * - * - *

* link: https://en.wikipedia.org/wiki/Vampire_number * - * - *

- */ -public class VampireNumber { - - public static void main(String[] args) { - - test(10, 1000); - } - - static void test(int startValue, int stopValue) { - int countofRes = 1; - StringBuilder res = new StringBuilder(); - - for (int i = startValue; i <= stopValue; i++) { - for (int j = i; j <= stopValue; j++) { - // System.out.println(i+ " "+ j); - if (isVampireNumber(i, j, true)) { - countofRes++; - res.append("" + countofRes + ": = ( " + i + "," + j + " = " + i * j + ")" + "\n"); - } - } - } - System.out.println(res); - } - - static boolean isVampireNumber(int a, int b, boolean noPseudoVamireNumbers) { - - // this is for pseudoVampireNumbers pseudovampire number need not be of length n/2 digits for - // example - // 126 = 6 x 21 - if (noPseudoVamireNumbers) { - if (a * 10 <= b || b * 10 <= a) { - return false; - } - } - - String mulDigits = splitIntoDigits(a * b, 0); - String faktorDigits = splitIntoDigits(a, b); - - return mulDigits.equals(faktorDigits); - } - - // methode to Split the numbers to Digits - static String splitIntoDigits(int num, int num2) { - - StringBuilder res = new StringBuilder(); - - ArrayList digits = new ArrayList<>(); - while (num > 0) { - digits.add(num % 10); - num /= 10; - } - while (num2 > 0) { - digits.add(num2 % 10); - num2 /= 10; - } - Collections.sort(digits); - for (int i : digits) { - res.append(i); - } - - return res.toString(); - } -} diff --git a/Maths/VectorCrossProduct.java b/Maths/VectorCrossProduct.java deleted file mode 100644 index 572ba6ad0ab3..000000000000 --- a/Maths/VectorCrossProduct.java +++ /dev/null @@ -1,124 +0,0 @@ -package Maths; - -/** - * @file - * - * @brief Calculates the [Cross Product](https://en.wikipedia.org/wiki/Cross_product) and the magnitude of two mathematical 3D vectors. - * - * - * @details Cross Product of two vectors gives a vector. - * Direction Ratios of a vector are the numeric parts of the given vector. They are the tree parts of the - * vector which determine the magnitude (value) of the vector. - * The method of finding a cross product is the same as finding the determinant of an order 3 matrix consisting - * of the first row with unit vectors of magnitude 1, the second row with the direction ratios of the - * first vector and the third row with the direction ratios of the second vector. - * The magnitude of a vector is it's value expressed as a number. - * Let the direction ratios of the first vector, P be: a, b, c - * Let the direction ratios of the second vector, Q be: x, y, z - * Therefore the calculation for the cross product can be arranged as: - * - * ``` - * P x Q: - * 1 1 1 - * a b c - * x y z - * ``` - * - * The direction ratios (DR) are calculated as follows: - * 1st DR, J: (b * z) - (c * y) - * 2nd DR, A: -((a * z) - (c * x)) - * 3rd DR, N: (a * y) - (b * x) - * - * Therefore, the direction ratios of the cross product are: J, A, N - * The following Java Program calculates the direction ratios of the cross products of two vector. - * The program uses a function, cross() for doing so. - * The direction ratios for the first and the second vector has to be passed one by one seperated by a space character. - * - * Magnitude of a vector is the square root of the sum of the squares of the direction ratios. - * - * - * For maintaining filename consistency, Vector class has been termed as VectorCrossProduct - * - * @author [Syed](https://github.com/roeticvampire) - */ - - -public class VectorCrossProduct { - int x; - int y; - int z; - //Default constructor, initialises all three Direction Ratios to 0 - VectorCrossProduct(){ - x=0; - y=0; - z=0; - } - - /** - * constructor, initialises Vector with given Direction Ratios - * @param _x set to x - * @param _y set to y - * @param _z set to z - */ - VectorCrossProduct(int _x,int _y, int _z){ - x=_x; - y=_y; - z=_z; - } - - /** - * Returns the magnitude of the vector - * @return double - */ - double magnitude(){ - return Math.sqrt(x*x +y*y +z*z); - } - - /** - * Returns the dot product of the current vector with a given vector - * @param b: the second vector - * @return int: the dot product - */ - int dotProduct(VectorCrossProduct b){ - return x*b.x + y*b.y +z*b.z; - } - - /** - * Returns the cross product of the current vector with a given vector - * @param b: the second vector - * @return vectorCrossProduct: the cross product - */ - VectorCrossProduct crossProduct(VectorCrossProduct b){ - VectorCrossProduct product=new VectorCrossProduct(); - product.x = (y * b.z) - (z * b.y); - product.y = -((x * b.z) - (z * b.x)); - product.z = (x * b.y) - (y * b.x); - return product; - } - - /** - * Display the Vector - */ - void displayVector(){ - System.out.println("x : "+x+"\ty : "+y+"\tz : "+z); - } - - public static void main(String[] args) { - test(); - } - static void test(){ - //Create two vectors - VectorCrossProduct A=new VectorCrossProduct(1,-2,3); - VectorCrossProduct B=new VectorCrossProduct(2,0,3); - - //Determine cross product - VectorCrossProduct crossProd=A.crossProduct(B); - crossProd.displayVector(); - - //Determine dot product - int dotProd=A.dotProduct(B); - System.out.println("Dot Product of A and B: "+dotProd); - - } - -} diff --git a/Maths/Volume.java b/Maths/Volume.java deleted file mode 100644 index b92bb17ec657..000000000000 --- a/Maths/Volume.java +++ /dev/null @@ -1,92 +0,0 @@ -package Maths; - - -/* Find volume of various shapes.*/ -public class Volume { - public static void main(String[] args) { - - /* test cube */ - assert Double.compare(volumeCube(7), 343.0) == 0; - - /* test cuboid */ - assert Double.compare(volumeCuboid(2, 5, 7), 70.0) == 0; - - /* test sphere */ - assert Double.compare(volumeSphere(5), 523.5987755982989) == 0; - - /* test cylinder */ - assert Double.compare(volumeCylinder(1,2), 12.566370614359172) == 0; - - /* test hemisphere */ - assert Double.compare(volumeHemisphere(5), 261.79938779914943) == 0; - - /* test cone */ - assert Double.compare(volumeCone(5, 7), 916.297857297023) == 0; - - } - - - /** - * Calculate the volume of a cube. - * - * @param sideLength side length of cube - * @return volume of given cube - */ - private static double volumeCube(double sidelength) { - return sidelength * sidelength * sidelength; - } - - /** - * Calculate the volume of a cuboid. - * - * @param width of cuboid - * @param height of cuboid - * @param length of cuboid - * @return volume of given cuboid - */ - private static double volumeCuboid(double width, double height, double length) { - return width * height * length; - } - - /** - * Calculate the volume of a sphere. - * - * @param radius radius of sphere - * @return volume of given sphere - */ - private static double volumeSphere(double radius) { - return 4 / 3 * Math.PI * radius * radius * radius; - } - - /** - * Calculate volume of a cylinder - * - * @param radius radius of the floor - * @param height height of the cylinder. - * @return volume of given cylinder - */ - private static double volumeCylinder(double radius, double height) { - return Math.PI * radius * radius * height; - } - - /** - * Calculate the volume of a hemisphere. - * - * @param radius radius of hemisphere - * @return volume of given hemisphere - */ - private static double volumeHemisphere(double radius) { - return 2 / 3 * Math.PI * radius * radius * radius; - } - - /** - * Calculate the volume of a cone. - * - * @param radius radius of cone. - * @param height of cone. - * @return volume of given cone. - */ - private static double volumeCone(double radius, double height) { - return Math.PI * radius * radius * height / 3; - } -} diff --git a/MatrixExponentiation/Fibonacci.java b/MatrixExponentiation/Fibonacci.java deleted file mode 100644 index bdcc06816db8..000000000000 --- a/MatrixExponentiation/Fibonacci.java +++ /dev/null @@ -1,74 +0,0 @@ -package MatrixExponentiation; - -import java.util.Scanner; - -/** @author Anirudh Buvanesh (https://github.com/anirudhb11) - * For more information see https://www.geeksforgeeks.org/matrix-exponentiation/ - * */ -public class Fibonacci { - // Exponentiation matrix for Fibonacci sequence - private static final int [][] fibMatrix = {{1,1}, {1,0}}; - private static final int [][] identityMatrix = {{1,0}, {0,1}}; - //First 2 fibonacci numbers - private static final int [][] baseFibNumbers = {{1}, {0}}; - - /** - * Performs multiplication of 2 matrices - * @param matrix1 - * @param matrix2 - * @return The product of matrix1 and matrix2 - */ - - private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2){ - //Check if matrices passed can be multiplied - int rowsInMatrix1 = matrix1.length; - int columnsInMatrix1 = matrix1[0].length; - - int rowsInMatrix2 = matrix2.length; - int columnsInMatrix2 = matrix2[0].length; - - assert columnsInMatrix1 == rowsInMatrix2; - int [][] product = new int[rowsInMatrix1][columnsInMatrix2]; - for (int rowIndex = 0; rowIndex < rowsInMatrix1; rowIndex ++){ - for(int colIndex = 0; colIndex < columnsInMatrix2; colIndex++){ - int matrixEntry = 0; - for(int intermediateIndex = 0; intermediateIndex < columnsInMatrix1; intermediateIndex++){ - matrixEntry += matrix1[rowIndex][intermediateIndex] * matrix2[intermediateIndex][colIndex]; - } - product[rowIndex][colIndex] = matrixEntry; - } - } - return product; - } - - /** - * Calculates the fibonacci number using matrix exponentiaition technique - * @param n The input n for which we have to determine the fibonacci number Outputs the nth - * * fibonacci number - * @return a 2 X 1 array as { {F_n+1}, {F_n} } - */ - public static int[][] fib(int n){ - if(n == 0){ - return Fibonacci.identityMatrix; - } - else{ - int [][] cachedResult = fib(n/2); - int [][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult); - if(n%2 == 0){ - return matrixExpResult; - } - else{ - return matrixMultiplication(Fibonacci.fibMatrix, matrixExpResult); - } - } - } - - public static void main(String[] args) { - // Returns [0, 1, 1, 2, 3, 5 ..] for n = [0, 1, 2, 3, 4, 5.. ] - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - int [][] result = matrixMultiplication(fib(n), baseFibNumbers); - System.out.println("Fib(" + n + ") = "+ result[1][0] ); - sc.close(); - } -} diff --git a/MinimizingLateness/MinimizingLateness.java b/MinimizingLateness/MinimizingLateness.java deleted file mode 100644 index cf06a0d44a70..000000000000 --- a/MinimizingLateness/MinimizingLateness.java +++ /dev/null @@ -1,60 +0,0 @@ -package MinimizingLateness; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.StringTokenizer; - -public class MinimizingLateness { - - private static class Schedule { // Schedule class - int t = 0; // Time required for the operation to be performed - int d = 0; // Time the job should be completed - int s = 0; // Start time of the task - int f = 0; // End time of the operation - - public Schedule(int t, int d) { - this.t = t; - this.d = d; - } - } - - public static void main(String[] args) throws IOException { - StringTokenizer token; - - BufferedReader in = new BufferedReader(new FileReader("MinimizingLateness/lateness_data.txt")); - String ch = in.readLine(); - if (ch == null || ch.isEmpty()) { - in.close(); - return; - } - int indexCount = Integer.parseInt(ch); - System.out.println("Input Data : "); - System.out.println(indexCount); // number of operations - Schedule[] array = new Schedule[indexCount]; // Create an array to hold the operation - int i = 0; - while ((ch = in.readLine()) != null) { - token = new StringTokenizer(ch, " "); - // Include the time required for the operation to be performed in the array and the time it - // should be completed. - array[i] = - new Schedule(Integer.parseInt(token.nextToken()), Integer.parseInt(token.nextToken())); - i++; - System.out.println(array[i - 1].t + " " + array[i - 1].d); - } - - int tryTime = 0; // Total time worked - int lateness = 0; // Lateness - for (int j = 0; j < indexCount - 1; j++) { - array[j].s = tryTime; // Start time of the task - array[j].f = tryTime + array[j].t; // Time finished - tryTime = tryTime + array[j].t; // Add total work time - // Lateness - lateness = lateness + Math.max(0, tryTime - array[j].d); - } - System.out.println(); - System.out.println("Output Data : "); - System.out.println(lateness); - in.close(); - } -} diff --git a/Misc/ColorContrastRatio.java b/Misc/ColorContrastRatio.java deleted file mode 100644 index b3dcf12267cb..000000000000 --- a/Misc/ColorContrastRatio.java +++ /dev/null @@ -1,104 +0,0 @@ -package Misc; - -import java.awt.Color; - -/** - * @brief A Java implementation of the offcial W3 documented procedure to calculate contrast ratio - * between colors on the web. This is used to calculate the readability of a foreground color on - * top of a background color. - * @since 2020-10-15 - * @see [Color Contrast Ratio](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-procedure) - * @author [Seth Falco](https://github.com/SethFalco) - */ -public class ColorContrastRatio { - - /** - * @brief Calculates the contrast ratio between two given colors. - * @param a Any color, used to get the red, green, and blue values. - * @param b Another color, which will be compared against the first color. - * @return The contrast ratio between the two colors. - */ - public double getContrastRatio(Color a, Color b) { - final double aColorLuminance = getRelativeLuminance(a); - final double bColorLuminance = getRelativeLuminance(b); - - if (aColorLuminance > bColorLuminance) - return (aColorLuminance + 0.05) / (bColorLuminance + 0.05); - - return (bColorLuminance + 0.05) / (aColorLuminance + 0.05); - } - - /** - * @brief Calculates the relative luminance of a given color. - * @param color Any color, used to get the red, green, and blue values. - * @return The relative luminance of the color. - * @see [More info on relative - * luminance.](https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef) - */ - public double getRelativeLuminance(Color color) { - final double red = getColor(color.getRed()); - final double green = getColor(color.getGreen()); - final double blue = getColor(color.getBlue()); - - return 0.2126 * red + 0.7152 * green + 0.0722 * blue; - } - - /** - * @brief Calculates the final value for a color to be used in the relative luminance formula as - * described in step 1. - * @param color8Bit 8-bit representation of a color component value. - * @return Value for the provided color component to be used in the relative luminance formula. - */ - public double getColor(int color8Bit) { - final double sRgb = getColorSRgb(color8Bit); - return (sRgb <= 0.03928) ? sRgb / 12.92 : Math.pow((sRgb + 0.055) / 1.055, 2.4); - } - - /** - * @brief Calculates the Color sRGB value as denoted in step 1 of the procedure document. - * @param color8Bit 8-bit representation of a color component value. - * @return A percentile value of the color component. - */ - private double getColorSRgb(double color8Bit) { - return color8Bit / 255.0; - } - - /** - * You can check this example against another open-source implementation available on GitHub. - * - * @see [Online Contrast - * Ratio](https://contrast-ratio.com/#rgb%28226%2C%20229%2C%20248-on-rgb%2823%2C%20103%2C%20154%29) - * @see [GitHub Repository for Online Contrast Ratio](https://github.com/LeaVerou/contrast-ratio) - */ - private static void test() { - final ColorContrastRatio algImpl = new ColorContrastRatio(); - - final Color black = Color.BLACK; - final double blackLuminance = algImpl.getRelativeLuminance(black); - assert blackLuminance == 0 : "Test 1 Failed - Incorrect relative luminance."; - - final Color white = Color.WHITE; - final double whiteLuminance = algImpl.getRelativeLuminance(white); - assert whiteLuminance == 1 : "Test 2 Failed - Incorrect relative luminance."; - - final double highestColorRatio = algImpl.getContrastRatio(black, white); - assert highestColorRatio == 21 : "Test 3 Failed - Incorrect contrast ratio."; - - final Color foreground = new Color(23, 103, 154); - final double foregroundLuminance = algImpl.getRelativeLuminance(foreground); - assert foregroundLuminance == 0.12215748057375966 - : "Test 4 Failed - Incorrect relative luminance."; - - final Color background = new Color(226, 229, 248); - final double backgroundLuminance = algImpl.getRelativeLuminance(background); - assert backgroundLuminance == 0.7898468477881603 - : "Test 5 Failed - Incorrect relative luminance."; - - final double contrastRatio = algImpl.getContrastRatio(foreground, background); - assert contrastRatio == 4.878363954846178 : "Test 6 Failed - Incorrect contrast ratio."; - } - - public static void main(String args[]) { - test(); - } -} diff --git a/Misc/InverseOfMatrix.java b/Misc/InverseOfMatrix.java deleted file mode 100644 index ed11d77ed205..000000000000 --- a/Misc/InverseOfMatrix.java +++ /dev/null @@ -1,131 +0,0 @@ -package Misc; -import java.util.Scanner; - -/* -* Wikipedia link : https://en.wikipedia.org/wiki/Invertible_matrix -* -* Here we use gauss elimination method to find the inverse of a given matrix. -* To understand gauss elimination method to find inverse of a matrix: https://www.sangakoo.com/en/unit/inverse-matrix-method-of-gaussian-elimination -* -* We can also find the inverse of a matrix -*/ -public class InverseOfMatrix -{ - public static void main(String argv[]) - { - Scanner input = new Scanner(System.in); - System.out.println("Enter the matrix size (Square matrix only): "); - int n = input.nextInt(); - double a[][]= new double[n][n]; - System.out.println("Enter the elements of matrix: "); - for(int i=0; i=0; --j) - { - x[j][i] = b[index[j]][i]; - for (int k=j+1; k c1) c1 = c0; - } - c[i] = c1; - } - - // Search the pivoting element from each column - int k = 0; - for (int j=0; j pi1) - { - pi1 = pi0; - k = i; - } - } - // Interchange rows according to the pivoting order - int itmp = index[j]; - index[j] = index[k]; - index[k] = itmp; - for (int i=j+1; i p1; - private PriorityQueue p2; - - // Constructor - public MedianOfRunningArray() { - this.p1 = new PriorityQueue<>(Collections.reverseOrder()); // Max Heap - this.p2 = new PriorityQueue<>(); // Min Heap - } - - /* - Inserting lower half of array to max Heap - and upper half to min heap - */ - public void insert(Integer e) { - p2.add(e); - if (p2.size() - p1.size() > 1) p1.add(p2.remove()); - } - - /* - Returns median at any given point - */ - public Integer median() { - if (p1.size() == p2.size()) return (p1.peek() + p2.peek()) / 2; - return p1.size() > p2.size() ? p1.peek() : p2.peek(); - } - - public static void main(String[] args) { - /* - Testing the median function - */ - - MedianOfRunningArray p = new MedianOfRunningArray(); - int arr[] = {10, 7, 4, 9, 2, 3, 11, 17, 14}; - for (int i = 0; i < 9; i++) { - p.insert(arr[i]); - System.out.print(p.median() + " "); - } - } -} diff --git a/Misc/PalindromePrime.java b/Misc/PalindromePrime.java deleted file mode 100644 index ea27a602b833..000000000000 --- a/Misc/PalindromePrime.java +++ /dev/null @@ -1,47 +0,0 @@ -package Misc; - -import java.util.Scanner; - -public class PalindromePrime { - - public static void main(String[] args) { // Main funtion - Scanner in = new Scanner(System.in); - System.out.println("Enter the quantity of First Palindromic Primes you want"); - int n = in.nextInt(); // Input of how many first palindromic prime we want - functioning(n); // calling function - functioning - in.close(); - } - - public static boolean prime(int num) { // checking if number is prime or not - for (int divisor = 3; divisor <= Math.sqrt(num); divisor += 2) { - if (num % divisor == 0) { - return false; // false if not prime - } - } - return true; // True if prime - } - - public static int reverse(int n) { // Returns the reverse of the number - int reverse = 0; - while (n != 0) { - reverse *= 10; - reverse += n % 10; - n /= 10; - } - return reverse; - } - - public static void functioning(int y) { - if (y == 0) return; - System.out.print(2 + "\n"); // print the first Palindromic Prime - int count = 1; - int num = 3; - while (count < y) { - if (num == reverse(num) && prime(num)) { // number is prime and it's reverse is same - count++; // counts check when to terminate while loop - System.out.print(num + "\n"); // print the Palindromic Prime - } - num += 2; // inrease iterator value by two - } - } -} diff --git a/Misc/RangeInSortedArray.java b/Misc/RangeInSortedArray.java deleted file mode 100644 index 5e0563bc21e4..000000000000 --- a/Misc/RangeInSortedArray.java +++ /dev/null @@ -1,82 +0,0 @@ -package Misc; - -import java.util.*; - -public class RangeInSortedArray { - - public static void main(String[] args) { - // Testcases - assert Arrays.equals(sortedRange(new int[] {1, 2, 3, 3, 3, 4, 5}, 3), new int[] {2, 4}); - assert Arrays.equals(sortedRange(new int[] {1, 2, 3, 3, 3, 4, 5}, 4), new int[] {5, 5}); - assert Arrays.equals(sortedRange(new int[] {0, 1, 2}, 3), new int[] {-1, -1}); - } - - // Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums' - // Gives [-1, -1] in case element doesn't exist in array - public static int[] sortedRange(int[] nums, int key) { - int[] range = new int[] {-1, -1}; - alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); - alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); - return range; - } - - // Recursive altered binary search which searches for leftmost as well as rightmost occurrence of - // 'key' - public static void alteredBinSearch( - int[] nums, int key, int left, int right, int[] range, boolean goLeft) { - if (left > right) return; - int mid = (left + right) / 2; - if (nums[mid] > key) alteredBinSearch(nums, key, left, mid - 1, range, goLeft); - else if (nums[mid] < key) alteredBinSearch(nums, key, mid + 1, right, range, goLeft); - else { - if (goLeft) { - if (mid == 0 || nums[mid - 1] != key) range[0] = mid; - else alteredBinSearch(nums, key, left, mid - 1, range, goLeft); - } else { - if (mid == nums.length - 1 || nums[mid + 1] != key) range[1] = mid; - else alteredBinSearch(nums, key, mid + 1, right, range, goLeft); - } - } - } - - // Iterative altered binary search which searches for leftmost as well as rightmost occurrence of - // 'key' - public static void alteredBinSearchIter( - int[] nums, int key, int left, int right, int[] range, boolean goLeft) { - while (left <= right) { - int mid = (left + right) / 2; - if (nums[mid] > key) right = mid - 1; - else if (nums[mid] < key) left = mid + 1; - else { - if (goLeft) { - if (mid == 0 || nums[mid - 1] != key) { - range[0] = mid; - return; - } else right = mid - 1; - } else { - if (mid == nums.length - 1 || nums[mid + 1] != key) { - range[1] = mid; - return; - } else left = mid + 1; - } - } - } - } - - public static int getCountLessThan(int[] nums, int key) { - return getLessThan(nums, key, 0, nums.length - 1); - } - - public static int getLessThan(int[] nums, int key, int left, int right) { - int count = 0; - while (left <= right) { - int mid = (left + right) / 2; - if (nums[mid] > key) right = mid - 1; - else if (nums[mid] <= key) { - count = mid + 1; // Atleast mid+1 elements exist which are <= key - left = mid + 1; - } - } - return count; - } -} diff --git a/Misc/Sort012D.java b/Misc/Sort012D.java deleted file mode 100644 index 3d9785bad673..000000000000 --- a/Misc/Sort012D.java +++ /dev/null @@ -1,53 +0,0 @@ -package Misc; -import java.util.*; -/** -The array is divided into four sections: -a[1..Lo-1] zeroes -a[Lo..Mid-1] ones -a[Mid..Hi] unknown -a[Hi+1..N] twos -If array [mid] =0, then swap array [mid] with array [low] and increment both pointers once. -If array [mid] = 1, then no swapping is required. Increment mid pointer once. -If array [mid] = 2, then we swap array [mid] with array [high] and decrement the high pointer once. -For more information on the Dutch national flag algorithm refer https://en.wikipedia.org/wiki/Dutch_national_flag_problem -*/ -public class Sort012D { - public static void main(String args[]) { - Scanner np = new Scanner(System.in); - int n = np.nextInt(); - int a[] = new int[n]; - for (int i = 0; i < n; i++) { - a[i] = np.nextInt(); - } - sort012(a);} - - public static void sort012(int[]a){ - int l = 0; - int h = a.length - 1; - int mid = 0; - int temp ; - while (mid <= h) { - switch (a[mid]) { - case 0: { - temp = a[l]; - a[l] = a[mid]; - a[mid] = temp; - l++; - mid++; - break;} - case 1: - mid++; - break; - case 2: { - temp = a[mid]; - a[mid] = a[h]; - a[h] = temp; - h--; - break; - } - } - } - System.out.println("the Sorted array is "); - for (int i = 0; i < a.length; i++) - System.out.print(+a[i] + " "); } -} diff --git a/Misc/ThreeSumProblem.java b/Misc/ThreeSumProblem.java deleted file mode 100644 index a5ccae862ddc..000000000000 --- a/Misc/ThreeSumProblem.java +++ /dev/null @@ -1,109 +0,0 @@ -import java.util.*; -public class ThreeSumProblem { - public static void main(String args[]) - { - Scanner scan = new Scanner(System.in); - System.out.print("Enter the target sum "); - int ts= scan.nextInt(); - System.out.print("Enter the number of elements in the array "); - int n = scan.nextInt(); - System.out.println("Enter all your array elements:"); - int arr[]= new int[n]; - for(int i=0;i> BruteForce(int[] nums,int target) { - List> arr = new ArrayList>(); - - for(int i=0;i temp = new ArrayList<>(); - temp.add(nums[i]); - temp.add(nums[j]); - temp.add(nums[k]); - Collections.sort(temp); - arr.add(temp); - } - - - } - } - } - arr = new ArrayList>(new LinkedHashSet>(arr)); - return arr; - } - public List> TwoPointer(int[] nums, int target) { - Arrays.sort(nums); - List> arr = new ArrayList>(); - int start=0; - int end=0; - int i = 0; - while(i temp = new ArrayList<>(); - temp.add(nums[i]); - temp.add(nums[start]); - temp.add(nums[end]); - arr.add(temp); - start++; - end--; - } - else if (nums[start]+nums[end]+nums[i]> set = new LinkedHashSet>(arr); - return new ArrayList>(set); - } - public List> Hashmap(int[] nums, int target) { - Arrays.sort(nums); - Set> ts = new HashSet(); - HashMap hm = new HashMap<>(); - - for(int i=0;ij) - { - List temp = new ArrayList<>(); - temp.add(nums[i]); - temp.add(nums[j]); - temp.add(t); - ts.add(temp); - } - } - } - return new ArrayList(ts); - } - -} - diff --git a/Misc/TwoSumProblem.java b/Misc/TwoSumProblem.java deleted file mode 100644 index 620f5d883c07..000000000000 --- a/Misc/TwoSumProblem.java +++ /dev/null @@ -1,115 +0,0 @@ -package Misc; -import java.util.*; -import java.util.stream.Collectors; - -public class TwoSumProblem { - public static void main(String args[]) - { - Scanner scan = new Scanner(System.in); - System.out.print("Enter the target sum "); - int ts= scan.nextInt(); - System.out.print("Enter the number of elements in the array "); - int n = scan.nextInt(); - System.out.println("Enter all your array elements:"); - int arr[]= new int[n]; - for(int i=0;i hm=new HashMap(); - for(int i =0;i temp - = hm.entrySet() - .stream() - .sorted((i1, i2) - -> i1.getValue().compareTo( - i2.getValue())) - .collect(Collectors.toMap( - Map.Entry::getKey, - Map.Entry::getValue, - (e1, e2) -> e1, LinkedHashMap::new)); - - int start = 0; - int end = nums.length - 1; - while (starttarget) - end-=1; - else if(currSum hm=new HashMap(); - for(int i=0;i boggleBoard(char[][] board, String[] words) { - Trie trie = new Trie(); - for (String word : words) trie.add(word); - Set finalWords = new HashSet<>(); - boolean[][] visited = new boolean[board.length][board.length]; - for (int i = 0; i < board.length; i++) - for (int j = 0; j < board[i].length; j++) - explore(i, j, board, trie.root, visited, finalWords); - return new ArrayList<>(finalWords); - } - - public static void main(String[] args) { - // Testcase - List ans = - new ArrayList<>( - Arrays.asList("a", "boggle", "this", "NOTRE_PEATED", "is", "simple", "board")); - assert (boggleBoard( - new char[][] { - {'t', 'h', 'i', 's', 'i', 's', 'a'}, - {'s', 'i', 'm', 'p', 'l', 'e', 'x'}, - {'b', 'x', 'x', 'x', 'x', 'e', 'b'}, - {'x', 'o', 'g', 'g', 'l', 'x', 'o'}, - {'x', 'x', 'x', 'D', 'T', 'r', 'a'}, - {'R', 'E', 'P', 'E', 'A', 'd', 'x'}, - {'x', 'x', 'x', 'x', 'x', 'x', 'x'}, - {'N', 'O', 'T', 'R', 'E', '_', 'P'}, - {'x', 'x', 'D', 'E', 'T', 'A', 'E'}, - }, - new String[] { - "this", - "is", - "not", - "a", - "simple", - "test", - "boggle", - "board", - "REPEATED", - "NOTRE_PEATED", - }) - .equals(ans)); - } - - public static void explore( - int i, - int j, - char[][] board, - TrieNode trieNode, - boolean[][] visited, - Set finalWords) { - if (visited[i][j]) return; - - char letter = board[i][j]; - if (!trieNode.children.containsKey(letter)) { - return; - } - visited[i][j] = true; - trieNode = trieNode.children.get(letter); - if (trieNode.children.containsKey('*')) finalWords.add(trieNode.word); - - List neighbors = getNeighbors(i, j, board); - for (Integer[] neighbor : neighbors) - explore(neighbor[0], neighbor[1], board, trieNode, visited, finalWords); - - visited[i][j] = false; - } - - public static List getNeighbors(int i, int j, char[][] board) { - List neighbors = new ArrayList<>(); - if (i > 0 && j > 0) neighbors.add(new Integer[] {i - 1, j - 1}); - - if (i > 0 && j < board[0].length - 1) neighbors.add(new Integer[] {i - 1, j + 1}); - - if (i < board.length - 1 && j < board[0].length - 1) - neighbors.add(new Integer[] {i + 1, j + 1}); - - if (i < board.length - 1 && j > 0) neighbors.add(new Integer[] {i + 1, j - 1}); - - if (i > 0) neighbors.add(new Integer[] {i - 1, j}); - - if (i < board.length - 1) neighbors.add(new Integer[] {i + 1, j}); - - if (j > 0) neighbors.add(new Integer[] {i, j - 1}); - - if (j < board[0].length - 1) neighbors.add(new Integer[] {i, j + 1}); - - return neighbors; - } -} - -// Trie used to optimize string search -class TrieNode { - - Map children = new HashMap<>(); - String word = ""; -} - -class Trie { - - TrieNode root; - char endSymbol; - - public Trie() { - this.root = new TrieNode(); - this.endSymbol = '*'; - } - - public void add(String str) { - TrieNode node = this.root; - for (int i = 0; i < str.length(); i++) { - char letter = str.charAt(i); - if (!node.children.containsKey(letter)) { - TrieNode newNode = new TrieNode(); - node.children.put(letter, newNode); - } - node = node.children.get(letter); - } - node.children.put(this.endSymbol, null); - node.word = str; - } -} diff --git a/Misc/matrixTranspose.java b/Misc/matrixTranspose.java deleted file mode 100644 index 0de36524ec53..000000000000 --- a/Misc/matrixTranspose.java +++ /dev/null @@ -1,78 +0,0 @@ -package Misc; - -import java.util.Scanner; - -/** - * - * - *

Find the Transpose of Matrix!

- * - * Simply take input from the user and print the matrix before the transpose and after the - * transpose. - * - *

Note: Giving proper comments in your program makes it more user friendly and it is - * assumed as a high quality code. - * - * @author Rajat-Jain29 - * @version 11.0.9 - * @since 2014-03-31 - */ -public class matrixTranspose { - public static void main(String[] args) { - /* - * This is the main method - * - * @param args Unused. - * - * @return Nothing. - */ - Scanner sc = new Scanner(System.in); - int i, j, row, column; - System.out.println("Enter the number of rows in the 2D matrix:"); - - /* - * Take input from user for how many rows to be print - */ - row = sc.nextInt(); - - System.out.println("Enter the number of columns in the 2D matrix:"); - - /* - * Take input from user for how many coloumn to be print - */ - column = sc.nextInt(); - int[][] arr = new int[row][column]; - System.out.println("Enter the elements"); - for (i = 0; i < row; i++) { - for (j = 0; j < column; j++) { - arr[i][j] = sc.nextInt(); - } - } - - /* - * Print matrix before the Transpose in proper way - */ - - System.out.println("The matrix is:"); - for (i = 0; i < row; i++) { - for (j = 0; j < column; j++) { - System.out.print(arr[i][j] + "\t"); - } - System.out.print("\n"); - } - - /* - * Print matrix after the tranpose in proper way Transpose means Interchanging - * of rows wth column so we interchange the rows in next loop Thus at last - * matrix of transpose is obtained through user input... - */ - - System.out.println("The Transpose of the given matrix is:"); - for (i = 0; i < column; i++) { - for (j = 0; j < row; j++) { - System.out.print(arr[j][i] + "\t"); - } - System.out.print("\n"); - } - } -} diff --git a/Others/BankersAlgorithm.java b/Others/BankersAlgorithm.java deleted file mode 100644 index 40d7267baacf..000000000000 --- a/Others/BankersAlgorithm.java +++ /dev/null @@ -1,186 +0,0 @@ -package Others; - -/** - * This file contains an implementation of BANKER'S ALGORITM - * Wikipedia: https://en.wikipedia.org/wiki/Banker%27s_algorithm - * - * The algorithm for finding out whether or not a system is in a safe state can be described as follows: - * 1. Let Work and Finish be vectors of length ‘m’ and ‘n’ respectively. - * Initialize: Work= Available - * Finish [i]=false; for i=1,2,……,n - * 2. Find an i such that both - * a) Finish [i]=false - * b) Need_i<=work - * - * if no such i exists goto step (4) - * 3. Work=Work + Allocation_i - * Finish[i]= true - * goto step(2) - * 4. If Finish[i]=true for all i, - * then the system is in safe state. - * - * Time Complexity: O(n*n*m) - * Space Complexity: O(n*m) - * where n = number of processes and m = number of resources. - * - * @author AMRITESH ANAND (https://github.com/amritesh19) - */ - -import java.util.Scanner; - -public class BankersAlgorithm { - - /** - * This method finds the need of each process - */ - static void calculateNeed(int needArray[][], int maxArray[][], int allocationArray[][], int totalProcess, int totalResources) - { - for (int i = 0 ; i < totalProcess ; i++){ - for (int j = 0 ; j < totalResources ; j++){ - needArray[i][j] = maxArray[i][j] - allocationArray[i][j]; - } - } - } - - /** - * This method find the system is in safe state or not - * @param processes[] int array of processes (0...n-1), size = n - * @param availableArray[] int array of number of instances of each resource, size = m - * @param maxArray[][] int matrix(2-D array) of maximum demand of each process in a system, size = n*m - * @param allocationArray[][] int matrix(2-D array) of the number of resources of each type currently allocated to each process, size = n*m - * @param totalProcess number of total processes, n - * @param totalResources number of total resources, m - * - * @return boolean if the system is in safe state or not - */ - static boolean checkSafeSystem(int processes[], int availableArray[], int maxArray[][], int allocationArray[][], int totalProcess, int totalResources) - { - int [][]needArray = new int[totalProcess][totalResources]; - - calculateNeed(needArray, maxArray, allocationArray, totalProcess, totalResources); - - boolean []finishProcesses = new boolean[totalProcess]; - - int []safeSequenceArray = new int[totalProcess]; - - int []workArray = new int[totalResources]; - - for (int i = 0; i < totalResources ; i++) - workArray[i] = availableArray[i]; - - int count = 0; - - // While all processes are not finished or system is not in safe state. - while (count < totalProcess) - { - boolean foundSafeSystem = false; - for (int m = 0; m < totalProcess; m++) - { - if (finishProcesses[m] == false) - { - int j; - - for (j = 0; j < totalResources; j++) - if (needArray[m][j] > workArray[j]) - break; - - if (j == totalResources) - { - for (int k = 0 ; k < totalResources ; k++) - workArray[k] += allocationArray[m][k]; - - safeSequenceArray[count++] = m; - - finishProcesses[m] = true; - - foundSafeSystem = true; - } - } - } - - // If we could not find a next process in safe sequence. - if (foundSafeSystem == false) - { - System.out.print("The system is not in the safe state because lack of resources"); - return false; - } - } - - System.out.print("The system is in safe sequence and the sequence is as follows: "); - for (int i = 0; i < totalProcess ; i++) - System.out.print("P"+safeSequenceArray[i] + " "); - - return true; - } - - /** - * This is main method of Banker's Algorithm - */ - public static void main(String[] args){ - int numberOfProcesses, numberOfResources; - - Scanner sc = new Scanner(System.in); - - System.out.println("Enter total number of processes"); - numberOfProcesses = sc.nextInt(); - - System.out.println("Enter total number of resources"); - numberOfResources = sc.nextInt(); - - int processes[] = new int[numberOfProcesses]; - for(int i = 0; i < numberOfProcesses; i++){ - processes[i] = i; - } - - System.out.println("--Enter the availability of--"); - - int availableArray[] = new int[numberOfResources]; - for( int i = 0; i < numberOfResources; i++){ - System.out.println("resource "+ i +": "); - availableArray[i] = sc.nextInt(); - } - - System.out.println("--Enter the maximum matrix--"); - - int maxArray[][] = new int[numberOfProcesses][numberOfResources]; - for( int i = 0; i < numberOfProcesses; i++){ - System.out.println("For process "+ i + ": "); - for( int j = 0; j < numberOfResources; j++){ - System.out.println("Enter the maximum instances of resource "+ j); - maxArray[i][j] = sc.nextInt(); - } - } - - System.out.println("--Enter the allocation matrix--"); - - int allocationArray[][] = new int[numberOfProcesses][numberOfResources]; - for( int i = 0; i < numberOfProcesses; i++){ - System.out.println("For process "+ i + ": "); - for( int j = 0; j < numberOfResources; j++){ - System.out.println("Allocated instances of resource "+ j ); - allocationArray[i][j] = sc.nextInt(); - } - } - - checkSafeSystem(processes, availableArray, maxArray, allocationArray, numberOfProcesses, numberOfResources); - - sc.close(); - } -} - -/* - Example: - n = 5 - m = 3 - - Process Allocation Max Available - 0 1 2 0 1 2 0 1 2 - - 0 0 1 0 7 5 3 3 3 2 - 1 2 0 0 3 2 2 - 2 3 0 2 9 0 2 - 3 2 1 1 2 2 2 - 4 0 0 2 4 3 3 - - Result: The system is in safe sequence and the sequence is as follows: P1, P3, P4, P0, P2 - */ diff --git a/Others/BestFit.java b/Others/BestFit.java deleted file mode 100644 index 8eec9f615159..000000000000 --- a/Others/BestFit.java +++ /dev/null @@ -1,96 +0,0 @@ -package Others; - -import java.util.ArrayList; - -/** @author Dekas Dimitrios */ -public class BestFit { - private static final int NO_ALLOCATION = - -255; // if a process has been allocated in position -255, - // it means that it has not been actually allocated. - - /** - * Method to find the maximum valued element of an array filled with positive integers. - * - * @param array: an array filled with positive integers. - * @return the maximum valued element of the array. - */ - private static int findMaxElement(int[] array) { - int max = -1; - for (int value : array) { - if (value > max) { - max = value; - } - } - return max; - } - - /** - * Method to find the index of the memory block that is going to fit the given process based on - * the best fit algorithm. - * - * @param blocks: the array with the available memory blocks. - * @param process: the size of the process. - * @return the index of the block that fits, or -255 if no such block exists. - */ - private static int findBestFit(int[] blockSizes, int processSize) { - // Initialize minDiff with an unreachable value by a difference between a blockSize and the - // processSize. - int minDiff = findMaxElement(blockSizes); - int index = - NO_ALLOCATION; // If there is no block that can fit the process, return NO_ALLOCATION as the - // result. - for (int i = 0; - i < blockSizes.length; - i++) { // Find the most fitting memory block for the given process. - if (blockSizes[i] - processSize < minDiff && blockSizes[i] - processSize >= 0) { - minDiff = blockSizes[i] - processSize; - index = i; - } - } - return index; - } - - /** - * Method to allocate memory to blocks according to the best fit algorithm. It should return an - * ArrayList of Integers, where the index is the process ID (zero-indexed) and the value is the - * block number (also zero-indexed). - * - * @param sizeOfBlocks: an int array that contains the sizes of the memory blocks available. - * @param sizeOfProcesses: an int array that contains the sizes of the processes we need memory - * blocks for. - * @return the ArrayList filled with Integers repressenting the memory allocation that took place. - */ - static ArrayList bestFit(int[] sizeOfBlocks, int[] sizeOfProcesses) { - // The array list responsible for saving the memory allocations done by the best-fit algorithm - ArrayList memAlloc = new ArrayList<>(); - // Do this for every process - for (int processSize : sizeOfProcesses) { - int chosenBlockIdx = - findBestFit( - sizeOfBlocks, processSize); // Find the index of the memory block going to be used - memAlloc.add(chosenBlockIdx); // Store the chosen block index in the memAlloc array list - if (chosenBlockIdx - != NO_ALLOCATION) { // Only if a block was chosen to store the process in it, - sizeOfBlocks[chosenBlockIdx] -= processSize; // resize the block based on the process size - } - } - return memAlloc; - } - - /** - * Method to print the memory allocated. - * - * @param memAllocation: an ArrayList of Integer representing the memory allocation done by the - * bestFit method. - */ - public static void printMemoryAllocation(ArrayList memAllocation) { - System.out.println("Process No.\tBlock No."); - System.out.println("===========\t========="); - for (int i = 0; i < memAllocation.size(); i++) { - System.out.print(" " + i + "\t\t"); - if (memAllocation.get(i) != NO_ALLOCATION) System.out.print(memAllocation.get(i)); - else System.out.print("Not Allocated"); - System.out.println(); - } - } -} diff --git a/Others/BoyerMoore.java b/Others/BoyerMoore.java deleted file mode 100644 index 68f6aa6fde9d..000000000000 --- a/Others/BoyerMoore.java +++ /dev/null @@ -1,40 +0,0 @@ -/* this Code is the illustration of Boyer moore's voting algorithm to -find the majority element is an array that appears more than n/2 times in an array -where "n" is the length of the array. -For more information on the algorithm refer https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm - */ -package Others; -import java.util.*; - -public class BoyerMoore { - public static int findmajor(int [] a){ -int count=0; int cand=-1; -for(int i=0;i (a.length / 2)) - return cand; - return -1; -} - public static void main(String args[]){ - Scanner input=new Scanner(System.in); - int n=input.nextInt(); - int a[]=new int[n]; - for(int i=0;iBrian Kernighan’s Algorithm - *

algorithm to count the number of set bits in a given number - *

Subtraction of 1 from a number toggles all the bits (from right to left) till the - * rightmost set bit(including the rightmost set bit). So if we subtract a number by 1 and do - * bitwise & with itself i.e. (n & (n-1)), we unset the rightmost set bit. - *

If we do n & (n-1) in a loop and count the no of times loop executes we get the set bit - * count. - *

- *

Time Complexity: O(logn) - */ -public class BrianKernighanAlgorithm { - - /** - * @param num: number in which we count the set bits - * @return int: Number of set bits - */ - static int countSetBits(int num) { - int cnt = 0; - while (num != 0) { - num = num & (num - 1); - cnt++; - } - return cnt; - } - - /** @param args : command line arguments */ - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - int num = sc.nextInt(); - int setBitCount = countSetBits(num); - System.out.println(setBitCount); - sc.close(); - } -} diff --git a/Others/CRC32.java b/Others/CRC32.java deleted file mode 100644 index 23712eef164a..000000000000 --- a/Others/CRC32.java +++ /dev/null @@ -1,27 +0,0 @@ -package Others; - -import java.util.BitSet; - -/** Generates a crc32 checksum for a given string or byte array */ -public class CRC32 { - - public static void main(String[] args) { - System.out.println(Integer.toHexString(crc32("Hello World"))); - } - - public static int crc32(String str) { - return crc32(str.getBytes()); - } - - public static int crc32(byte[] data) { - BitSet bitSet = BitSet.valueOf(data); - int crc32 = 0xFFFFFFFF; // initial value - for (int i = 0; i < data.length * 8; i++) { - if (((crc32 >>> 31) & 1) != (bitSet.get(i) ? 1 : 0)) - crc32 = (crc32 << 1) ^ 0x04C11DB7; // xor with polynomial - else crc32 = (crc32 << 1); - } - crc32 = Integer.reverse(crc32); // result reflect - return crc32 ^ 0xFFFFFFFF; // final xor value - } -} diff --git a/Others/CRCAlgorithm.java b/Others/CRCAlgorithm.java deleted file mode 100644 index 3729a5ed5a33..000000000000 --- a/Others/CRCAlgorithm.java +++ /dev/null @@ -1,193 +0,0 @@ -package Others; - -import java.util.ArrayList; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; - -/** @author dimgrichr */ -public class CRCAlgorithm { - - private int correctMess; - - private int wrongMess; - - private int wrongMessCaught; - - private int wrongMessNotCaught; - - private int messSize; - - private double ber; - - private boolean messageChanged; - - private ArrayList message; - - private ArrayList dividedMessage; - - private ArrayList p; - - private Random randomGenerator; - - /** - * The algorithm's main constructor. The most significant variables, used in the algorithm, are - * set in their initial values. - * - * @param str The binary number P, in a string form, which is used by the CRC algorithm - * @param size The size of every transmitted message - * @param ber The Bit Error Rate - */ - public CRCAlgorithm(String str, int size, double ber) { - messageChanged = false; - message = new ArrayList<>(); - messSize = size; - dividedMessage = new ArrayList<>(); - p = new ArrayList<>(); - for (int i = 0; i < str.length(); i++) { - p.add(Character.getNumericValue(str.charAt(i))); - } - randomGenerator = new Random(); - correctMess = 0; - wrongMess = 0; - wrongMessCaught = 0; - wrongMessNotCaught = 0; - this.ber = ber; - } - - /** - * Returns the counter wrongMess - * - * @return wrongMess, the number of Wrong Messages - */ - public int getWrongMess() { - return wrongMess; - } - - /** - * Returns the counter wrongMessCaught - * - * @return wrongMessCaught, the number of wrong messages, which are caught by the CRC algoriithm - */ - public int getWrongMessCaught() { - return wrongMessCaught; - } - - /** - * Returns the counter wrongMessNotCaught - * - * @return wrongMessNotCaught, the number of wrong messages, which are not caught by the CRC - * algorithm - */ - public int getWrongMessNotCaught() { - return wrongMessNotCaught; - } - - /** - * Returns the counter correctMess - * - * @return correctMess, the number of the Correct Messages - */ - public int getCorrectMess() { - return correctMess; - } - - /** - * Resets some of the object's values, used on the main function, so that it can be re-used, in - * order not to waste too much memory and time, by creating new objects. - */ - public void refactor() { - messageChanged = false; - message = new ArrayList<>(); - dividedMessage = new ArrayList<>(); - } - - /** - * Random messages, consisted of 0's and 1's, are generated, so that they can later be transmitted - */ - public void generateRandomMess() { - for (int i = 0; i < messSize; i++) { - int x = ThreadLocalRandom.current().nextInt(0, 2); - message.add(x); - } - } - - /** - * The most significant part of the CRC algorithm. The message is divided by P, so the - * dividedMessage ArrayList is created. If check == true, the dividedMessaage is - * examined, in order to see if it contains any 1's. If it does, the message is considered to be - * wrong by the receiver,so the variable wrongMessCaught changes. If it does not, it is accepted, - * so one of the variables correctMess, wrongMessNotCaught, changes. If check == false, the - * diviided Message is added at the end of the ArrayList message. - * - * @param check the variable used to determine, if the message is going to be checked from the - * receiver if true, it is checked otherwise, it is not - */ - public void divideMessageWithP(boolean check) { - ArrayList x = new ArrayList<>(); - ArrayList k = (ArrayList) message.clone(); - if (!check) { - for (int i = 0; i < p.size() - 1; i++) { - k.add(0); - } - } - while (!k.isEmpty()) { - while (x.size() < p.size() && !k.isEmpty()) { - x.add(k.get(0)); - k.remove(0); - } - if (x.size() == p.size()) { - for (int i = 0; i < p.size(); i++) { - if (x.get(i) == p.get(i)) { - x.set(i, 0); - } else { - x.set(i, 1); - } - } - for (int i = 0; i < x.size() && x.get(i) != 1; i++) { - x.remove(0); - } - } - } - dividedMessage = (ArrayList) x.clone(); - if (!check) { - for (int z : dividedMessage) { - message.add(z); - } - } else { - if (dividedMessage.contains(1) && messageChanged) { - wrongMessCaught++; - } else if (!dividedMessage.contains(1) && messageChanged) { - wrongMessNotCaught++; - } else if (!messageChanged) { - correctMess++; - } - } - } - - /** - * Once the message is transmitted, some of it's elements, is possible to change from 1 to 0, or - * from 0 to 1, because of the Bit Error Rate (ber). For every element of the message, a random - * double number is created. If that number is smaller than ber, then the spesific element - * changes. On the other hand, if it's bigger than ber, it does not. Based on these changes. the - * boolean variable messageChanged, gets the value: true, or false. - */ - public void changeMess() { - for (int y : message) { - double x = randomGenerator.nextDouble(); - while (x < 0.0000 || x > 1.00000) { - x = randomGenerator.nextDouble(); - } - if (x < ber) { - messageChanged = true; - if (y == 1) { - message.set(message.indexOf(y), 0); - } else { - message.set(message.indexOf(y), 1); - } - } - } - if (messageChanged) { - wrongMess++; - } - } -} diff --git a/Others/CountChar.java b/Others/CountChar.java deleted file mode 100644 index 9136a4e686d0..000000000000 --- a/Others/CountChar.java +++ /dev/null @@ -1,24 +0,0 @@ -package Others; - -import java.util.Scanner; - -public class CountChar { - - public static void main(String[] args) { - Scanner input = new Scanner(System.in); - System.out.print("Enter your text: "); - String str = input.nextLine(); - input.close(); - System.out.println("There are " + CountCharacters(str) + " characters."); - } - - /** - * Count non space character in string - * - * @param str String to count the characters - * @return number of character in the specified string - */ - private static int CountCharacters(String str) { - return str.replaceAll("\\s", "").length(); - } -} diff --git a/Others/CountWords.java b/Others/CountWords.java deleted file mode 100644 index 746b027ebd59..000000000000 --- a/Others/CountWords.java +++ /dev/null @@ -1,44 +0,0 @@ -package Others; - -import java.util.Scanner; - -/** - * You enter a string into this program, and it will return how many words were in that particular - * string - * - * @author Marcus - */ -public class CountWords { - - public static void main(String[] args) { - Scanner input = new Scanner(System.in); - System.out.println("Enter your text: "); - String str = input.nextLine(); - - System.out.println("Your text has " + wordCount(str) + " word(s)"); - System.out.println("Your text has " + secondaryWordCount(str) + " word(s)"); - input.close(); - } - - private static int wordCount(String s) { - if (s == null || s.isEmpty()) return 0; - return s.trim().split("[\\s]+").length; - } - - /** - * counts the number of words in a sentence but ignores all potential non-alphanumeric characters - * that do not represent a word. runs in O(n) where n is the length of s - * - * @param s String: sentence with word(s) - * @return int: number of words - */ - private static int secondaryWordCount(String s) { - if (s == null || s.isEmpty()) return 0; - StringBuilder sb = new StringBuilder(); - for (char c : s.toCharArray()) { - if (Character.isLetter(c) || Character.isDigit(c)) sb.append(c); - } - s = sb.toString(); - return s.trim().split("[\\s]+").length; - } -} diff --git a/Others/Dijkstra.java b/Others/Dijkstra.java deleted file mode 100644 index 913f25b3eb2b..000000000000 --- a/Others/Dijkstra.java +++ /dev/null @@ -1,200 +0,0 @@ -package Others; - -/** - * Dijkstra's algorithm,is a graph search algorithm that solves the single-source shortest path - * problem for a graph with nonnegative edge path costs, producing a shortest path tree. - * - *

NOTE: The inputs to Dijkstra's algorithm are a directed and weighted graph consisting of 2 or - * more nodes, generally represented by an adjacency matrix or list, and a start node. - * - *

Original source of code: https://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java Also most of - * the comments are from RosettaCode. - */ -import java.util.*; - -public class Dijkstra { - private static final Graph.Edge[] GRAPH = { - // Distance from node "a" to node "b" is 7. - // In the current Graph there is no way to move the other way (e,g, from "b" to "a"), - // a new edge would be needed for that - new Graph.Edge("a", "b", 7), - new Graph.Edge("a", "c", 9), - new Graph.Edge("a", "f", 14), - new Graph.Edge("b", "c", 10), - new Graph.Edge("b", "d", 15), - new Graph.Edge("c", "d", 11), - new Graph.Edge("c", "f", 2), - new Graph.Edge("d", "e", 6), - new Graph.Edge("e", "f", 9), - }; - private static final String START = "a"; - private static final String END = "e"; - - /** main function Will run the code with "GRAPH" that was defined above. */ - public static void main(String[] args) { - Graph g = new Graph(GRAPH); - g.dijkstra(START); - g.printPath(END); - // g.printAllPaths(); - } -} - -class Graph { - // mapping of vertex names to Vertex objects, built from a set of Edges - private final Map graph; - - /** One edge of the graph (only used by Graph constructor) */ - public static class Edge { - public final String v1, v2; - public final int dist; - - public Edge(String v1, String v2, int dist) { - this.v1 = v1; - this.v2 = v2; - this.dist = dist; - } - } - - /** One vertex of the graph, complete with mappings to neighbouring vertices */ - public static class Vertex implements Comparable { - public final String name; - // MAX_VALUE assumed to be infinity - public int dist = Integer.MAX_VALUE; - public Vertex previous = null; - public final Map neighbours = new HashMap<>(); - - public Vertex(String name) { - this.name = name; - } - - private void printPath() { - if (this == this.previous) { - System.out.printf("%s", this.name); - } else if (this.previous == null) { - System.out.printf("%s(unreached)", this.name); - } else { - this.previous.printPath(); - System.out.printf(" -> %s(%d)", this.name, this.dist); - } - } - - public int compareTo(Vertex other) { - if (dist == other.dist) return name.compareTo(other.name); - - return Integer.compare(dist, other.dist); - } - - @Override - public boolean equals(Object object) { - if (this == object) return true; - if (object == null || getClass() != object.getClass()) return false; - if (!super.equals(object)) return false; - - Vertex vertex = (Vertex) object; - - if (dist != vertex.dist) return false; - if (name != null ? !name.equals(vertex.name) : vertex.name != null) return false; - if (previous != null ? !previous.equals(vertex.previous) : vertex.previous != null) - return false; - if (neighbours != null ? !neighbours.equals(vertex.neighbours) : vertex.neighbours != null) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (name != null ? name.hashCode() : 0); - result = 31 * result + dist; - result = 31 * result + (previous != null ? previous.hashCode() : 0); - result = 31 * result + (neighbours != null ? neighbours.hashCode() : 0); - return result; - } - - @Override - public String toString() { - return "(" + name + ", " + dist + ")"; - } - } - - /** Builds a graph from a set of edges */ - public Graph(Edge[] edges) { - graph = new HashMap<>(edges.length); - - // one pass to find all vertices - for (Edge e : edges) { - if (!graph.containsKey(e.v1)) graph.put(e.v1, new Vertex(e.v1)); - if (!graph.containsKey(e.v2)) graph.put(e.v2, new Vertex(e.v2)); - } - - // another pass to set neighbouring vertices - for (Edge e : edges) { - graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist); - // graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected - // graph - } - } - - /** Runs dijkstra using a specified source vertex */ - public void dijkstra(String startName) { - if (!graph.containsKey(startName)) { - System.err.printf("Graph doesn't contain start vertex \"%s\"%n", startName); - return; - } - final Vertex source = graph.get(startName); - NavigableSet q = new TreeSet<>(); - - // set-up vertices - for (Vertex v : graph.values()) { - v.previous = v == source ? source : null; - v.dist = v == source ? 0 : Integer.MAX_VALUE; - q.add(v); - } - - dijkstra(q); - } - - /** Implementation of dijkstra's algorithm using a binary heap. */ - private void dijkstra(final NavigableSet q) { - Vertex u, v; - while (!q.isEmpty()) { - // vertex with shortest distance (first iteration will return source) - u = q.pollFirst(); - if (u.dist == Integer.MAX_VALUE) - break; // we can ignore u (and any other remaining vertices) since they are unreachable - - // look at distances to each neighbour - for (Map.Entry a : u.neighbours.entrySet()) { - v = a.getKey(); // the neighbour in this iteration - - final int alternateDist = u.dist + a.getValue(); - if (alternateDist < v.dist) { // shorter path to neighbour found - q.remove(v); - v.dist = alternateDist; - v.previous = u; - q.add(v); - } - } - } - } - - /** Prints a path from the source to the specified vertex */ - public void printPath(String endName) { - if (!graph.containsKey(endName)) { - System.err.printf("Graph doesn't contain end vertex \"%s\"%n", endName); - return; - } - - graph.get(endName).printPath(); - System.out.println(); - } - - /** Prints the path from the source to every vertex (output order is not guaranteed) */ - public void printAllPaths() { - for (Vertex v : graph.values()) { - v.printPath(); - System.out.println(); - } - } -} diff --git a/Others/EulersFunction.java b/Others/EulersFunction.java deleted file mode 100644 index 1e7efeafbd0b..000000000000 --- a/Others/EulersFunction.java +++ /dev/null @@ -1,28 +0,0 @@ -package Others; - -/** - * You can read more about Euler's totient function - * - *

See https://en.wikipedia.org/wiki/Euler%27s_totient_function - */ -public class EulersFunction { - // This method returns us number of x that (x < n) and gcd(x, n) == 1 in O(sqrt(n)) time - // complexity; - public static int getEuler(int n) { - int result = n; - for (int i = 2; i * i <= n; i++) { - if (n % i == 0) { - while (n % i == 0) n /= i; - result -= result / i; - } - } - if (n > 1) result -= result / n; - return result; - } - - public static void main(String[] args) { - for (int i = 1; i < 100; i++) { - System.out.println(getEuler(i)); - } - } -} diff --git a/Others/FibbonaciSeries.java b/Others/FibbonaciSeries.java deleted file mode 100644 index 076cac53c752..000000000000 --- a/Others/FibbonaciSeries.java +++ /dev/null @@ -1,30 +0,0 @@ -package Others; - -import java.util.Scanner; - -/** - * Fibonacci sequence, and characterized by the fact that every number after the first two is the - * sum of the two preceding ones. - * - *

Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21,... - * - *

Source for the explanation: https://en.wikipedia.org/wiki/Fibonacci_number - * - * Problem Statement: print all Fibonacci numbers that are smaller than your given input N - */ -public class FibbonaciSeries { - public static void main(String[] args) { - // Get input from the user - Scanner scan = new Scanner(System.in); - int n = scan.nextInt(); - int first = 0, second = 1; - scan.close(); - while (first <= n) { - // print first fibo 0 then add second fibo into it while updating second as well - System.out.println(first); - int next = first + second; - first = second; - second = next; - } - } -} diff --git a/Others/FirstFit.java b/Others/FirstFit.java deleted file mode 100644 index 06cea111c54d..000000000000 --- a/Others/FirstFit.java +++ /dev/null @@ -1,72 +0,0 @@ -package Others; - -import java.util.ArrayList; - -/** @author Dekas Dimitrios */ -public class FirstFit { - private static final int NO_ALLOCATION = - -255; // if a process has been allocated in position -255, - // it means that it has not been actually allocated. - - /** - * Method to find the index of the memory block that is going to fit the given process based on - * the first fit algorithm. - * - * @param blocks: the array with the available memory blocks. - * @param process: the size of the process. - * @return the index of the block that fits, or -255 if no such block exists. - */ - private static int findFirstFit(int[] blockSizes, int processSize) { - for (int i = 0; i < blockSizes.length; i++) { - if (blockSizes[i] >= processSize) { - return i; - } - } - // If there is not a block that can fit the process, return -255 as the result - return NO_ALLOCATION; - } - - /** - * Method to allocate memory to blocks according to the first fit algorithm. It should return an - * ArrayList of Integers, where the index is the process ID (zero-indexed) and the value is the - * block number (also zero-indexed). - * - * @param sizeOfBlocks: an int array that contains the sizes of the memory blocks available. - * @param sizeOfProcesses: an int array that contains the sizes of the processes we need memory - * blocks for. - * @return the ArrayList filled with Integers repressenting the memory allocation that took place. - */ - static ArrayList firstFit(int[] sizeOfBlocks, int[] sizeOfProcesses) { - // The array list responsible for saving the memory allocations done by the first-fit algorithm - ArrayList memAlloc = new ArrayList<>(); - // Do this for every process - for (int processSize : sizeOfProcesses) { - int chosenBlockIdx = - findFirstFit( - sizeOfBlocks, processSize); // Find the index of the memory block going to be used - memAlloc.add(chosenBlockIdx); // Store the chosen block index in the memAlloc array list - if (chosenBlockIdx - != NO_ALLOCATION) { // Only if a block was chosen to store the process in it, - sizeOfBlocks[chosenBlockIdx] -= processSize; // resize the block based on the process size - } - } - return memAlloc; - } - - /** - * Method to print the memory allocated. - * - * @param memAllocation: an ArrayList of Integer representing the memory allocation done by the - * firstFit method. - */ - public static void printMemoryAllocation(ArrayList memAllocation) { - System.out.println("Process No.\tBlock No."); - System.out.println("===========\t========="); - for (int i = 0; i < memAllocation.size(); i++) { - System.out.print(" " + i + "\t\t"); - if (memAllocation.get(i) != NO_ALLOCATION) System.out.print(memAllocation.get(i)); - else System.out.print("Not Allocated"); - System.out.println(); - } - } -} diff --git a/Others/FloydTriangle.java b/Others/FloydTriangle.java deleted file mode 100644 index 73b988f72398..000000000000 --- a/Others/FloydTriangle.java +++ /dev/null @@ -1,18 +0,0 @@ -package Others; - -import java.util.Scanner; - -class FloydTriangle { - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - System.out.println("Enter the number of rows which you want in your Floyd Triangle: "); - int r = sc.nextInt(), n = 0; - sc.close(); - for (int i = 0; i < r; i++) { - for (int j = 0; j <= i; j++) { - System.out.print(++n + " "); - } - System.out.println(); - } - } -} diff --git a/Others/GuassLegendre.java b/Others/GuassLegendre.java deleted file mode 100644 index 4b30bdc3fa03..000000000000 --- a/Others/GuassLegendre.java +++ /dev/null @@ -1,40 +0,0 @@ -package Others; - -/** - * Guass Legendre Algorithm ref https://en.wikipedia.org/wiki/Gauss–Legendre_algorithm - * - * @author AKS1996 - */ -public class GuassLegendre { - - public static void main(String[] args) { - for (int i = 1; i <= 3; ++i) System.out.println(pi(i)); - } - - static double pi(int l) { - /* - * l: No of loops to run - */ - - double a = 1, b = Math.pow(2, -0.5), t = 0.25, p = 1; - for (int i = 0; i < l; ++i) { - double temp[] = update(a, b, t, p); - a = temp[0]; - b = temp[1]; - t = temp[2]; - p = temp[3]; - } - - return Math.pow(a + b, 2) / (4 * t); - } - - static double[] update(double a, double b, double t, double p) { - double values[] = new double[4]; - values[0] = (a + b) / 2; - values[1] = Math.sqrt(a * b); - values[2] = t - p * Math.pow(a - values[0], 2); - values[3] = 2 * p; - - return values; - } -} diff --git a/Others/Huffman.java b/Others/Huffman.java deleted file mode 100644 index 43366046bdd4..000000000000 --- a/Others/Huffman.java +++ /dev/null @@ -1,135 +0,0 @@ -import java.util.PriorityQueue; -import java.util.Scanner; -import java.util.Comparator; - -// node class is the basic structure -// of each node present in the Huffman - tree. -class HuffmanNode { - - int data; - char c; - - HuffmanNode left; - HuffmanNode right; -} - -// comparator class helps to compare the node -// on the basis of one of its attribute. -// Here we will be compared -// on the basis of data values of the nodes. -class MyComparator implements Comparator { - public int compare(HuffmanNode x, HuffmanNode y) - { - - return x.data - y.data; - } -} - -public class Huffman { - - // recursive function to print the - // huffman-code through the tree traversal. - // Here s is the huffman - code generated. - public static void printCode(HuffmanNode root, String s) - { - - // base case; if the left and right are null - // then its a leaf node and we print - // the code s generated by traversing the tree. - if (root.left - == null - && root.right - == null - && Character.isLetter(root.c)) { - - // c is the character in the node - System.out.println(root.c + ":" + s); - - return; - } - - // if we go to left then add "0" to the code. - // if we go to the right add"1" to the code. - - // recursive calls for left and - // right sub-tree of the generated tree. - printCode(root.left, s + "0"); - printCode(root.right, s + "1"); - } - - // main function - public static void main(String[] args) - { - - Scanner s = new Scanner(System.in); - - // number of characters. - int n = 6; - char[] charArray = { 'a', 'b', 'c', 'd', 'e', 'f' }; - int[] charfreq = { 5, 9, 12, 13, 16, 45 }; - - // creating a priority queue q. - // makes a min-priority queue(min-heap). - PriorityQueue q - = new PriorityQueue(n, new MyComparator()); - - for (int i = 0; i < n; i++) { - - // creating a Huffman node object - // and add it to the priority queue. - HuffmanNode hn = new HuffmanNode(); - - hn.c = charArray[i]; - hn.data = charfreq[i]; - - hn.left = null; - hn.right = null; - - // add functions adds - // the huffman node to the queue. - q.add(hn); - } - - // create a root node - HuffmanNode root = null; - - // Here we will extract the two minimum value - // from the heap each time until - // its size reduces to 1, extract until - // all the nodes are extracted. - while (q.size() > 1) { - - // first min extract. - HuffmanNode x = q.peek(); - q.poll(); - - // second min extarct. - HuffmanNode y = q.peek(); - q.poll(); - - // new node f which is equal - HuffmanNode f = new HuffmanNode(); - - // to the sum of the frequency of the two nodes - // assigning values to the f node. - f.data = x.data + y.data; - f.c = '-'; - - // first extracted node as left child. - f.left = x; - - // second extracted node as the right child. - f.right = y; - - // marking the f node as the root node. - root = f; - - // add this node to the priority-queue. - q.add(f); - } - - // print the codes by traversing the tree - printCode(root, ""); - } -} - diff --git a/Others/Implementing_auto_completing_features_using_trie.java b/Others/Implementing_auto_completing_features_using_trie.java deleted file mode 100644 index e33c6438678e..000000000000 --- a/Others/Implementing_auto_completing_features_using_trie.java +++ /dev/null @@ -1,177 +0,0 @@ -package Others; - -// Java Program to implement Auto-Complete -// Feature using Trie -class Trieac { - - // Alphabet size (# of symbols) - public static final int ALPHABET_SIZE = 26; - - // Trie node - static class TrieNode - { - TrieNode children[] = new TrieNode[ALPHABET_SIZE]; - - // isWordEnd is true if the node represents - // end of a word - boolean isWordEnd; - }; - - // Returns new trie node (initialized to NULLs) - static TrieNode getNode() { - TrieNode pNode = new TrieNode(); - pNode.isWordEnd = false; - - for(int i = 0; i < ALPHABET_SIZE; i++) - pNode.children[i] = null; - - return pNode; - } - - // If not present, inserts key into trie. If the - // key is prefix of trie node, just marks leaf node - static void insert(TrieNode root, final String key) - { - TrieNode pCrawl = root; - - for(int level = 0; level < key.length(); level++) - { - int index = (key.charAt(level) - 'a'); - if (pCrawl.children[index] == null) - pCrawl.children[index] = getNode(); - pCrawl = pCrawl.children[index]; - } - - // mark last node as leaf - pCrawl.isWordEnd = true; - } - - // Returns true if key presents in trie, else false - boolean search(TrieNode root, final String key) - { - int length = key.length(); - TrieNode pCrawl = root; - - for (int level = 0; level < length; level++) - { - int index = (key.charAt(level) - 'a'); - - if (pCrawl.children[index] == null) - pCrawl = pCrawl.children[index]; - } - - return (pCrawl != null && pCrawl.isWordEnd); - } - - // Returns 0 if current node has a child - // If all children are NULL, return 1. - static boolean isLastNode(TrieNode root) - { - for (int i = 0; i < ALPHABET_SIZE; i++) - if (root.children[i] != null) - return false; - return true; - } - - // Recursive function to print auto-suggestions - // for given node. - static void suggestionsRec(TrieNode root, String currPrefix) - { - // found a string in Trie with the given prefix - if (root.isWordEnd) - { - System.out.println(currPrefix); - } - - // All children struct node pointers are NULL - if (isLastNode(root)) - return; - - for (int i = 0; i < ALPHABET_SIZE; i++) - { - if (root.children[i] != null) - { - // append current character to currPrefix string - currPrefix += (char)(97 + i); - - // recur over the rest - suggestionsRec(root.children[i], currPrefix); - } - } - } - - // Fucntion to print suggestions for - // given query prefix. - static int printAutoSuggestions(TrieNode root, - final String query) - { - TrieNode pCrawl = root; - - // Check if prefix is present and find the - // the node (of last level) with last character - // of given string. - int level; - int n = query.length(); - - for (level = 0; level < n; level++) - { - int index = (query.charAt(level) - 'a'); - - // no string in the Trie has this prefix - if (pCrawl.children[index] == null) - return 0; - - pCrawl = pCrawl.children[index]; - } - - // If prefix is present as a word. - boolean isWord = (pCrawl.isWordEnd == true); - - // If prefix is last node of tree (has no - // children) - boolean isLast = isLastNode(pCrawl); - - // If prefix is present as a word, but - // there is no subtree below the last - // matching node. - if (isWord && isLast) - { - System.out.println(query); - return -1; - } - - // If there are are nodes below last - // matching character. - if (!isLast) - { - String prefix = query; - suggestionsRec(pCrawl, prefix); - return 1; - } - - return 0; - } - - // Driver code - public static void main(String[] args) - { - TrieNode root = getNode(); - insert(root, "hello"); - insert(root, "dog"); - insert(root, "hell"); - insert(root, "cat"); - insert(root, "a"); - insert(root, "hel"); - insert(root, "help"); - insert(root, "helps"); - insert(root, "helping"); - int comp = printAutoSuggestions(root, "hel"); - - if (comp == -1) - System.out.println("No other strings found "+ - "with this prefix\n"); - else if (comp == 0) - System.out.println("No string found with"+ - " this prefix\n"); - } -} diff --git a/Others/InsertDeleteInArray.java b/Others/InsertDeleteInArray.java deleted file mode 100644 index 20d81462136f..000000000000 --- a/Others/InsertDeleteInArray.java +++ /dev/null @@ -1,48 +0,0 @@ -package Others; - -import java.util.*; - -public class InsertDeleteInArray { - - public static void main(String[] args) { - Scanner s = new Scanner(System.in); // Input statement - System.out.println("Enter the size of the array"); - int size = s.nextInt(); - int a[] = new int[size]; - int i; - - // To enter the initial elements - for (i = 0; i < size; i++) { - System.out.println("Enter the element"); - a[i] = s.nextInt(); - } - - // To insert a new element(we are creating a new array) - System.out.println("Enter the index at which the element should be inserted"); - int insert_pos = s.nextInt(); - System.out.println("Enter the element to be inserted"); - int ins = s.nextInt(); - int size2 = size + 1; - int b[] = new int[size2]; - for (i = 0; i < size2; i++) { - if (i <= insert_pos) { - b[i] = a[i]; - } else { - b[i] = a[i - 1]; - } - } - b[insert_pos] = ins; - for (i = 0; i < size2; i++) { - System.out.println(b[i]); - } - - // To delete an element given the index - System.out.println("Enter the index at which element is to be deleted"); - int del_pos = s.nextInt(); - for (i = del_pos; i < size2 - 1; i++) { - b[i] = b[i + 1]; - } - for (i = 0; i < size2 - 1; i++) System.out.println(b[i]); - s.close(); - } -} diff --git a/Others/KMP.java b/Others/KMP.java deleted file mode 100644 index c221edf3f353..000000000000 --- a/Others/KMP.java +++ /dev/null @@ -1,53 +0,0 @@ -package Others; - -/** Implementation of Knuth–Morris–Pratt algorithm Usage: see the main function for an example */ -public class KMP { - // a working example - public static void main(String[] args) { - final String haystack = "AAAAABAAABA"; // This is the full string - final String needle = "AAAA"; // This is the substring that we want to find - KMPmatcher(haystack, needle); - } - - // find the starting index in string haystack[] that matches the search word P[] - public static void KMPmatcher(final String haystack, final String needle) { - final int m = haystack.length(); - final int n = needle.length(); - final int[] pi = computePrefixFunction(needle); - int q = 0; - for (int i = 0; i < m; i++) { - while (q > 0 && haystack.charAt(i) != needle.charAt(q)) { - q = pi[q - 1]; - } - - if (haystack.charAt(i) == needle.charAt(q)) { - q++; - } - - if (q == n) { - System.out.println("Pattern starts: " + (i + 1 - n)); - q = pi[q - 1]; - } - } - } - - // return the prefix function - private static int[] computePrefixFunction(final String P) { - final int n = P.length(); - final int[] pi = new int[n]; - pi[0] = 0; - int q = 0; - for (int i = 1; i < n; i++) { - while (q > 0 && P.charAt(q) != P.charAt(i)) { - q = pi[q - 1]; - } - - if (P.charAt(q) == P.charAt(i)) { - q++; - } - - pi[i] = q; - } - return pi; - } -} diff --git a/Others/KochSnowflake.java b/Others/KochSnowflake.java deleted file mode 100644 index 3ec76ae1b730..000000000000 --- a/Others/KochSnowflake.java +++ /dev/null @@ -1,234 +0,0 @@ -package Others; - -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import javax.imageio.ImageIO; - -/** - * The Koch snowflake is a fractal curve and one of the earliest fractals to have been described. - * The Koch snowflake can be built up iteratively, in a sequence of stages. The first stage is an - * equilateral triangle, and each successive stage is formed by adding outward bends to each side of - * the previous stage, making smaller equilateral triangles. This can be achieved through the - * following steps for each line: 1. divide the line segment into three segments of equal length. 2. - * draw an equilateral triangle that has the middle segment from step 1 as its base and points - * outward. 3. remove the line segment that is the base of the triangle from step 2. (description - * adapted from https://en.wikipedia.org/wiki/Koch_snowflake ) (for a more detailed explanation and - * an implementation in the Processing language, see - * https://natureofcode.com/book/chapter-8-fractals/ #84-the-koch-curve-and-the-arraylist-technique - * ). - */ -public class KochSnowflake { - - public static void main(String[] args) { - // Test Iterate-method - ArrayList vectors = new ArrayList(); - vectors.add(new Vector2(0, 0)); - vectors.add(new Vector2(1, 0)); - ArrayList result = Iterate(vectors, 1); - - assert result.get(0).x == 0; - assert result.get(0).y == 0; - - assert result.get(1).x == 1. / 3; - assert result.get(1).y == 0; - - assert result.get(2).x == 1. / 2; - assert result.get(2).y == Math.sin(Math.PI / 3) / 3; - - assert result.get(3).x == 2. / 3; - assert result.get(3).y == 0; - - assert result.get(4).x == 1; - assert result.get(4).y == 0; - - // Test GetKochSnowflake-method - int imageWidth = 600; - double offsetX = imageWidth / 10.; - double offsetY = imageWidth / 3.7; - BufferedImage image = GetKochSnowflake(imageWidth, 5); - - // The background should be white - assert image.getRGB(0, 0) == new Color(255, 255, 255).getRGB(); - - // The snowflake is drawn in black and this is the position of the first vector - assert image.getRGB((int) offsetX, (int) offsetY) == new Color(0, 0, 0).getRGB(); - - // Save image - try { - ImageIO.write(image, "png", new File("KochSnowflake.png")); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Go through the number of iterations determined by the argument "steps". Be careful with high - * values (above 5) since the time to calculate increases exponentially. - * - * @param initialVectors The vectors composing the shape to which the algorithm is applied. - * @param steps The number of iterations. - * @return The transformed vectors after the iteration-steps. - */ - public static ArrayList Iterate(ArrayList initialVectors, int steps) { - ArrayList vectors = initialVectors; - for (int i = 0; i < steps; i++) { - vectors = IterationStep(vectors); - } - - return vectors; - } - - /** - * Method to render the Koch snowflake to a image. - * - * @param imageWidth The width of the rendered image. - * @param steps The number of iterations. - * @return The image of the rendered Koch snowflake. - */ - public static BufferedImage GetKochSnowflake(int imageWidth, int steps) { - if (imageWidth <= 0) { - throw new IllegalArgumentException("imageWidth should be greater than zero"); - } - - double offsetX = imageWidth / 10.; - double offsetY = imageWidth / 3.7; - Vector2 vector1 = new Vector2(offsetX, offsetY); - Vector2 vector2 = - new Vector2(imageWidth / 2, Math.sin(Math.PI / 3) * imageWidth * 0.8 + offsetY); - Vector2 vector3 = new Vector2(imageWidth - offsetX, offsetY); - ArrayList initialVectors = new ArrayList(); - initialVectors.add(vector1); - initialVectors.add(vector2); - initialVectors.add(vector3); - initialVectors.add(vector1); - ArrayList vectors = Iterate(initialVectors, steps); - return GetImage(vectors, imageWidth, imageWidth); - } - - /** - * Loops through each pair of adjacent vectors. Each line between two adjacent vectors is divided - * into 4 segments by adding 3 additional vectors in-between the original two vectors. The vector - * in the middle is constructed through a 60 degree rotation so it is bent outwards. - * - * @param vectors The vectors composing the shape to which the algorithm is applied. - * @return The transformed vectors after the iteration-step. - */ - private static ArrayList IterationStep(ArrayList vectors) { - ArrayList newVectors = new ArrayList(); - for (int i = 0; i < vectors.size() - 1; i++) { - Vector2 startVector = vectors.get(i); - Vector2 endVector = vectors.get(i + 1); - newVectors.add(startVector); - Vector2 differenceVector = endVector.subtract(startVector).multiply(1. / 3); - newVectors.add(startVector.add(differenceVector)); - newVectors.add(startVector.add(differenceVector).add(differenceVector.rotate(60))); - newVectors.add(startVector.add(differenceVector.multiply(2))); - } - - newVectors.add(vectors.get(vectors.size() - 1)); - return newVectors; - } - - /** - * Utility-method to render the Koch snowflake to an image. - * - * @param vectors The vectors defining the edges to be rendered. - * @param imageWidth The width of the rendered image. - * @param imageHeight The height of the rendered image. - * @return The image of the rendered edges. - */ - private static BufferedImage GetImage( - ArrayList vectors, int imageWidth, int imageHeight) { - BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); - Graphics2D g2d = image.createGraphics(); - - // Set the background white - g2d.setBackground(Color.WHITE); - g2d.fillRect(0, 0, imageWidth, imageHeight); - - // Draw the edges - g2d.setColor(Color.BLACK); - BasicStroke bs = new BasicStroke(1); - g2d.setStroke(bs); - for (int i = 0; i < vectors.size() - 1; i++) { - int x1 = (int) vectors.get(i).x; - int y1 = (int) vectors.get(i).y; - int x2 = (int) vectors.get(i + 1).x; - int y2 = (int) vectors.get(i + 1).y; - - g2d.drawLine(x1, y1, x2, y2); - } - - return image; - } - - /** Inner class to handle the vector calculations. */ - private static class Vector2 { - - double x, y; - - public Vector2(double x, double y) { - this.x = x; - this.y = y; - } - - @Override - public String toString() { - return String.format("[%f, %f]", this.x, this.y); - } - - /** - * Vector addition - * - * @param vector The vector to be added. - * @return The sum-vector. - */ - public Vector2 add(Vector2 vector) { - double x = this.x + vector.x; - double y = this.y + vector.y; - return new Vector2(x, y); - } - - /** - * Vector subtraction - * - * @param vector The vector to be subtracted. - * @return The difference-vector. - */ - public Vector2 subtract(Vector2 vector) { - double x = this.x - vector.x; - double y = this.y - vector.y; - return new Vector2(x, y); - } - - /** - * Vector scalar multiplication - * - * @param scalar The factor by which to multiply the vector. - * @return The scaled vector. - */ - public Vector2 multiply(double scalar) { - double x = this.x * scalar; - double y = this.y * scalar; - return new Vector2(x, y); - } - - /** - * Vector rotation (see https://en.wikipedia.org/wiki/Rotation_matrix) - * - * @param angleInDegrees The angle by which to rotate the vector. - * @return The rotated vector. - */ - public Vector2 rotate(double angleInDegrees) { - double radians = angleInDegrees * Math.PI / 180; - double ca = Math.cos(radians); - double sa = Math.sin(radians); - double x = ca * this.x - sa * this.y; - double y = sa * this.x + ca * this.y; - return new Vector2(x, y); - } - } -} diff --git a/Others/Krishnamurthy.java b/Others/Krishnamurthy.java deleted file mode 100644 index d7a48522537f..000000000000 --- a/Others/Krishnamurthy.java +++ /dev/null @@ -1,27 +0,0 @@ -package Others; - -import java.util.Scanner; - -class Krishnamurthy { - static int fact(int n) { - int i, p = 1; - for (i = n; i >= 1; i--) p = p * i; - return p; - } - - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - int a, b, s = 0; - System.out.print("Enter the number : "); - a = sc.nextInt(); - int n = a; - while (a > 0) { - b = a % 10; - s = s + fact(b); - a = a / 10; - } - if (s == n) System.out.print(n + " is a krishnamurthy number"); - else System.out.print(n + " is not a krishnamurthy number"); - sc.close(); - } -} diff --git a/Others/LinearCongruentialGenerator.java b/Others/LinearCongruentialGenerator.java deleted file mode 100644 index d735d6a663e0..000000000000 --- a/Others/LinearCongruentialGenerator.java +++ /dev/null @@ -1,62 +0,0 @@ -package Others; - -/*** - * A pseudorandom number generator. - * - * @author Tobias Carryer - * @date October 10, 2017 - */ -public class LinearCongruentialGenerator { - - private double a, c, m, previousValue; - - /*** - * These parameters are saved and used when nextNumber() is called. - * The current timestamp in milliseconds is used as the seed. - * - * @param multiplier - * @param increment - * @param modulo The maximum number that can be generated (exclusive). A common value is 2^32. - */ - public LinearCongruentialGenerator(double multiplier, double increment, double modulo) { - this(System.currentTimeMillis(), multiplier, increment, modulo); - } - - /*** - * These parameters are saved and used when nextNumber() is called. - * - * @param seed - * @param multiplier - * @param increment - * @param modulo The maximum number that can be generated (exclusive). A common value is 2^32. - */ - public LinearCongruentialGenerator( - double seed, double multiplier, double increment, double modulo) { - this.previousValue = seed; - this.a = multiplier; - this.c = increment; - this.m = modulo; - } - - /** - * The smallest number that can be generated is zero. The largest number that can be generated is - * modulo-1. modulo is set in the constructor. - * - * @return a pseudorandom number. - */ - public double nextNumber() { - previousValue = (a * previousValue + c) % m; - return previousValue; - } - - public static void main(String[] args) { - // Show the LCG in action. - // Decisive proof that the LCG works could be made by adding each number - // generated to a Set while checking for duplicates. - LinearCongruentialGenerator lcg = - new LinearCongruentialGenerator(1664525, 1013904223, Math.pow(2.0, 32.0)); - for (int i = 0; i < 512; i++) { - System.out.println(lcg.nextNumber()); - } - } -} diff --git a/Others/LowestBasePalindrome.java b/Others/LowestBasePalindrome.java deleted file mode 100644 index b6d169887524..000000000000 --- a/Others/LowestBasePalindrome.java +++ /dev/null @@ -1,142 +0,0 @@ -package Others; - -import java.util.InputMismatchException; -import java.util.Scanner; - -/** - * Class for finding the lowest base in which a given integer is a palindrome. Includes auxiliary - * methods for converting between bases and reversing strings. - * - *

NOTE: There is potential for error, see note at line 63. - * - * @author RollandMichael - * @version 2017.09.28 - */ -public class LowestBasePalindrome { - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - int n = 0; - while (true) { - try { - System.out.print("Enter number: "); - n = in.nextInt(); - break; - } catch (InputMismatchException e) { - System.out.println("Invalid input!"); - in.next(); - } - } - System.out.println(n + " is a palindrome in base " + lowestBasePalindrome(n)); - System.out.println(base2base(Integer.toString(n), 10, lowestBasePalindrome(n))); - in.close(); - } - - /** - * Given a number in base 10, returns the lowest base in which the number is represented by a - * palindrome (read the same left-to-right and right-to-left). - * - * @param num A number in base 10. - * @return The lowest base in which num is a palindrome. - */ - public static int lowestBasePalindrome(int num) { - int base, num2 = num; - int digit; - char digitC; - boolean foundBase = false; - String newNum = ""; - String digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - while (!foundBase) { - // Try from bases 2 to num-1 - for (base = 2; base < num2; base++) { - newNum = ""; - while (num > 0) { - // Obtain the first digit of n in the current base, - // which is equivalent to the integer remainder of (n/base). - // The next digit is obtained by dividing n by the base and - // continuing the process of getting the remainder. This is done - // until n is <=0 and the number in the new base is obtained. - digit = (num % base); - num /= base; - // If the digit isn't in the set of [0-9][A-Z] (beyond base 36), its character - // form is just its value in ASCII. - - // NOTE: This may cause problems, as the capital letters are ASCII values - // 65-90. It may cause false positives when one digit is, for instance 10 and assigned - // 'A' from the character array and the other is 65 and also assigned 'A'. - - // Regardless, the character is added to the representation of n - // in the current base. - if (digit >= digits.length()) { - digitC = (char) (digit); - newNum += digitC; - continue; - } - newNum += digits.charAt(digit); - } - // Num is assigned back its original value for the next iteration. - num = num2; - // Auxiliary method reverses the number. - String reverse = reverse(newNum); - // If the number is read the same as its reverse, then it is a palindrome. - // The current base is returned. - if (reverse.equals(newNum)) { - foundBase = true; - return base; - } - } - } - // If all else fails, n is always a palindrome in base n-1. ("11") - return num - 1; - } - - private static String reverse(String str) { - String reverse = ""; - for (int i = str.length() - 1; i >= 0; i--) { - reverse += str.charAt(i); - } - return reverse; - } - - private static String base2base(String n, int b1, int b2) { - // Declare variables: decimal value of n, - // character of base b1, character of base b2, - // and the string that will be returned. - int decimalValue = 0, charB2; - char charB1; - String output = ""; - // Go through every character of n - for (int i = 0; i < n.length(); i++) { - // store the character in charB1 - charB1 = n.charAt(i); - // if it is a non-number, convert it to a decimal value >9 and store it in charB2 - if (charB1 >= 'A' && charB1 <= 'Z') charB2 = 10 + (charB1 - 'A'); - // Else, store the integer value in charB2 - else charB2 = charB1 - '0'; - // Convert the digit to decimal and add it to the - // decimalValue of n - decimalValue = decimalValue * b1 + charB2; - } - - // Converting the decimal value to base b2: - // A number is converted from decimal to another base - // by continuously dividing by the base and recording - // the remainder until the quotient is zero. The number in the - // new base is the remainders, with the last remainder - // being the left-most digit. - - // While the quotient is NOT zero: - while (decimalValue != 0) { - // If the remainder is a digit < 10, simply add it to - // the left side of the new number. - if (decimalValue % b2 < 10) output = Integer.toString(decimalValue % b2) + output; - // If the remainder is >= 10, add a character with the - // corresponding value to the new number. (A = 10, B = 11, C = 12, ...) - else output = (char) ((decimalValue % b2) + 55) + output; - // Divide by the new base again - decimalValue /= b2; - } - return output; - } -} diff --git a/Others/Mandelbrot.java b/Others/Mandelbrot.java deleted file mode 100644 index 940245fbae3a..000000000000 --- a/Others/Mandelbrot.java +++ /dev/null @@ -1,192 +0,0 @@ -package Others; - -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; -import javax.imageio.ImageIO; - -/** - * The Mandelbrot set is the set of complex numbers "c" for which the series "z_(n+1) = z_n * z_n + - * c" does not diverge, i.e. remains bounded. Thus, a complex number "c" is a member of the - * Mandelbrot set if, when starting with "z_0 = 0" and applying the iteration repeatedly, the - * absolute value of "z_n" remains bounded for all "n > 0". Complex numbers can be written as "a + - * b*i": "a" is the real component, usually drawn on the x-axis, and "b*i" is the imaginary - * component, usually drawn on the y-axis. Most visualizations of the Mandelbrot set use a - * color-coding to indicate after how many steps in the series the numbers outside the set cross the - * divergence threshold. Images of the Mandelbrot set exhibit an elaborate and infinitely - * complicated boundary that reveals progressively ever-finer recursive detail at increasing - * magnifications, making the boundary of the Mandelbrot set a fractal curve. (description adapted - * from https://en.wikipedia.org/wiki/Mandelbrot_set ) (see also - * https://en.wikipedia.org/wiki/Plotting_algorithms_for_the_Mandelbrot_set ) - */ -public class Mandelbrot { - - public static void main(String[] args) { - // Test black and white - BufferedImage blackAndWhiteImage = getImage(800, 600, -0.6, 0, 3.2, 50, false); - - // Pixel outside the Mandelbrot set should be white. - assert blackAndWhiteImage.getRGB(0, 0) == new Color(255, 255, 255).getRGB(); - - // Pixel inside the Mandelbrot set should be black. - assert blackAndWhiteImage.getRGB(400, 300) == new Color(0, 0, 0).getRGB(); - - // Test color-coding - BufferedImage coloredImage = getImage(800, 600, -0.6, 0, 3.2, 50, true); - - // Pixel distant to the Mandelbrot set should be red. - assert coloredImage.getRGB(0, 0) == new Color(255, 0, 0).getRGB(); - - // Pixel inside the Mandelbrot set should be black. - assert coloredImage.getRGB(400, 300) == new Color(0, 0, 0).getRGB(); - - // Save image - try { - ImageIO.write(coloredImage, "png", new File("Mandelbrot.png")); - } catch (IOException e) { - e.printStackTrace(); - } - } - - /** - * Method to generate the image of the Mandelbrot set. Two types of coordinates are used: - * image-coordinates that refer to the pixels and figure-coordinates that refer to the complex - * numbers inside and outside the Mandelbrot set. The figure-coordinates in the arguments of this - * method determine which section of the Mandelbrot set is viewed. The main area of the Mandelbrot - * set is roughly between "-1.5 < x < 0.5" and "-1 < y < 1" in the figure-coordinates. - * - * @param imageWidth The width of the rendered image. - * @param imageHeight The height of the rendered image. - * @param figureCenterX The x-coordinate of the center of the figure. - * @param figureCenterY The y-coordinate of the center of the figure. - * @param figureWidth The width of the figure. - * @param maxStep Maximum number of steps to check for divergent behavior. - * @param useDistanceColorCoding Render in color or black and white. - * @return The image of the rendered Mandelbrot set. - */ - public static BufferedImage getImage( - int imageWidth, - int imageHeight, - double figureCenterX, - double figureCenterY, - double figureWidth, - int maxStep, - boolean useDistanceColorCoding) { - if (imageWidth <= 0) { - throw new IllegalArgumentException("imageWidth should be greater than zero"); - } - - if (imageHeight <= 0) { - throw new IllegalArgumentException("imageHeight should be greater than zero"); - } - - if (maxStep <= 0) { - throw new IllegalArgumentException("maxStep should be greater than zero"); - } - - BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); - double figureHeight = figureWidth / imageWidth * imageHeight; - - // loop through the image-coordinates - for (int imageX = 0; imageX < imageWidth; imageX++) { - for (int imageY = 0; imageY < imageHeight; imageY++) { - // determine the figure-coordinates based on the image-coordinates - double figureX = figureCenterX + ((double) imageX / imageWidth - 0.5) * figureWidth; - double figureY = figureCenterY + ((double) imageY / imageHeight - 0.5) * figureHeight; - - double distance = getDistance(figureX, figureY, maxStep); - - // color the corresponding pixel based on the selected coloring-function - image.setRGB( - imageX, - imageY, - useDistanceColorCoding - ? colorCodedColorMap(distance).getRGB() - : blackAndWhiteColorMap(distance).getRGB()); - } - } - - return image; - } - - /** - * Black and white color-coding that ignores the relative distance. The Mandelbrot set is black, - * everything else is white. - * - * @param distance Distance until divergence threshold - * @return The color corresponding to the distance. - */ - private static Color blackAndWhiteColorMap(double distance) { - return distance >= 1 ? new Color(0, 0, 0) : new Color(255, 255, 255); - } - - /** - * Color-coding taking the relative distance into account. The Mandelbrot set is black. - * - * @param distance Distance until divergence threshold. - * @return The color corresponding to the distance. - */ - private static Color colorCodedColorMap(double distance) { - if (distance >= 1) { - return new Color(0, 0, 0); - } else { - // simplified transformation of HSV to RGB - // distance determines hue - double hue = 360 * distance; - double saturation = 1; - double val = 255; - int hi = (int) (Math.floor(hue / 60)) % 6; - double f = hue / 60 - Math.floor(hue / 60); - - int v = (int) val; - int p = 0; - int q = (int) (val * (1 - f * saturation)); - int t = (int) (val * (1 - (1 - f) * saturation)); - - switch (hi) { - case 0: - return new Color(v, t, p); - case 1: - return new Color(q, v, p); - case 2: - return new Color(p, v, t); - case 3: - return new Color(p, q, v); - case 4: - return new Color(t, p, v); - default: - return new Color(v, p, q); - } - } - } - - /** - * Return the relative distance (ratio of steps taken to maxStep) after which the complex number - * constituted by this x-y-pair diverges. Members of the Mandelbrot set do not diverge so their - * distance is 1. - * - * @param figureX The x-coordinate within the figure. - * @param figureX The y-coordinate within the figure. - * @param maxStep Maximum number of steps to check for divergent behavior. - * @return The relative distance as the ratio of steps taken to maxStep. - */ - private static double getDistance(double figureX, double figureY, int maxStep) { - double a = figureX; - double b = figureY; - int currentStep = 0; - for (int step = 0; step < maxStep; step++) { - currentStep = step; - double aNew = a * a - b * b + figureX; - b = 2 * a * b + figureY; - a = aNew; - - // divergence happens for all complex number with an absolute value - // greater than 4 (= divergence threshold) - if (a * a + b * b > 4) { - break; - } - } - return (double) currentStep / (maxStep - 1); - } -} diff --git a/Others/PageRank.java b/Others/PageRank.java deleted file mode 100644 index fc4fed0fcae3..000000000000 --- a/Others/PageRank.java +++ /dev/null @@ -1,94 +0,0 @@ -package Others; - -import java.util.*; - -class PageRank { - public static void main(String args[]) { - int nodes, i, j; - Scanner in = new Scanner(System.in); - System.out.print("Enter the Number of WebPages: "); - nodes = in.nextInt(); - PageRank p = new PageRank(); - System.out.println("Enter the Adjacency Matrix with 1->PATH & 0->NO PATH Between two WebPages: "); - for (i = 1; i <= nodes; i++) - for (j = 1; j <= nodes; j++) { - p.path[i][j] = in.nextInt(); - if (j == i) - p.path[i][j] = 0; - } - p.calc(nodes); - } - - public int path[][] = new int[10][10]; - public double pagerank[] = new double[10]; - - public void calc(double totalNodes) { - - double InitialPageRank; - double OutgoingLinks = 0; - double DampingFactor = 0.85; - double TempPageRank[] = new double[10]; - int ExternalNodeNumber; - int InternalNodeNumber; - int k = 1; // For Traversing - int ITERATION_STEP = 1; - InitialPageRank = 1 / totalNodes; - System.out.printf( - " Total Number of Nodes :" + totalNodes + "\t Initial PageRank of All Nodes :" + InitialPageRank + "\n"); - - // 0th ITERATION _ OR _ INITIALIZATION PHASE // - - for (k = 1; k <= totalNodes; k++) { - this.pagerank[k] = InitialPageRank; - } - System.out.printf("\n Initial PageRank Values , 0th Step \n"); - - for (k = 1; k <= totalNodes; k++) { - System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); - } - - while (ITERATION_STEP <= 2) // Iterations - { - // Store the PageRank for All Nodes in Temporary Array - for (k = 1; k <= totalNodes; k++) { - TempPageRank[k] = this.pagerank[k]; - this.pagerank[k] = 0; - } - - for (InternalNodeNumber = 1; InternalNodeNumber <= totalNodes; InternalNodeNumber++) { - for (ExternalNodeNumber = 1; ExternalNodeNumber <= totalNodes; ExternalNodeNumber++) { - if (this.path[ExternalNodeNumber][InternalNodeNumber] == 1) { - k = 1; - OutgoingLinks = 0; // Count the Number of Outgoing Links for each ExternalNodeNumber - while (k <= totalNodes) { - if (this.path[ExternalNodeNumber][k] == 1) { - OutgoingLinks = OutgoingLinks + 1; // Counter for Outgoing Links - } - k = k + 1; - } - // Calculate PageRank - this.pagerank[InternalNodeNumber] += TempPageRank[ExternalNodeNumber] * (1 / OutgoingLinks); - } - } - System.out.printf("\n After " + ITERATION_STEP + "th Step \n"); - - for (k = 1; k <= totalNodes; k++) - System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); - - ITERATION_STEP = ITERATION_STEP + 1; - } - - // Add the Damping Factor to PageRank - for (k = 1; k <= totalNodes; k++) { - this.pagerank[k] = (1 - DampingFactor) + DampingFactor * this.pagerank[k]; - } - - // Display PageRank - System.out.printf("\n Final Page Rank : \n"); - for (k = 1; k <= totalNodes; k++) { - System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); - } - - } - } -} diff --git a/Others/PasswordGen.java b/Others/PasswordGen.java deleted file mode 100644 index 018cffe6bacd..000000000000 --- a/Others/PasswordGen.java +++ /dev/null @@ -1,44 +0,0 @@ -package Others; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Random; - -/** - * Creates a random password from ASCII letters Given password length bounds - * - * @author AKS1996 - * @date 2017.10.25 - */ -class PasswordGen { - public static void main(String args[]) { - String password = generatePassword(8, 16); - System.out.print("Password: " + password); - } - - static String generatePassword(int min_length, int max_length) { - Random random = new Random(); - - String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - String lower = "abcdefghijklmnopqrstuvwxyz"; - String numbers = "0123456789"; - String specialChars = "!@#$%^&*(){}?"; - - String allChars = upper + lower + numbers + specialChars; - - List letters = new ArrayList(); - for (char c : allChars.toCharArray()) letters.add(c); - - // Inbuilt method to randomly shuffle a elements of a list - Collections.shuffle(letters); - StringBuilder password = new StringBuilder(); - - // Note that size of the password is also random - for (int i = random.nextInt(max_length - min_length) + min_length; i > 0; --i) { - password.append(letters.get(random.nextInt(letters.size()))); - } - - return password.toString(); - } -} diff --git a/Others/PerlinNoise.java b/Others/PerlinNoise.java deleted file mode 100644 index 4c1ad993a134..000000000000 --- a/Others/PerlinNoise.java +++ /dev/null @@ -1,168 +0,0 @@ -package Others; - -import java.util.Random; -import java.util.Scanner; - -/** - * For detailed info and implementation see: Perlin-Noise - */ -public class PerlinNoise { - /** - * @param width width of noise array - * @param height height of noise array - * @param octaveCount numbers of layers used for blending noise - * @param persistence value of impact each layer get while blending - * @param seed used for randomizer - * @return float array containing calculated "Perlin-Noise" values - */ - static float[][] generatePerlinNoise( - int width, int height, int octaveCount, float persistence, long seed) { - final float[][] base = new float[width][height]; - final float[][] perlinNoise = new float[width][height]; - final float[][][] noiseLayers = new float[octaveCount][][]; - - Random random = new Random(seed); - // fill base array with random values as base for noise - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - base[x][y] = random.nextFloat(); - } - } - - // calculate octaves with different roughness - for (int octave = 0; octave < octaveCount; octave++) { - noiseLayers[octave] = generatePerlinNoiseLayer(base, width, height, octave); - } - - float amplitude = 1f; - float totalAmplitude = 0f; - - // calculate perlin noise by blending each layer together with specific persistence - for (int octave = octaveCount - 1; octave >= 0; octave--) { - amplitude *= persistence; - totalAmplitude += amplitude; - - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - // adding each value of the noise layer to the noise - // by increasing amplitude the rougher noises will have more impact - perlinNoise[x][y] += noiseLayers[octave][x][y] * amplitude; - } - } - } - - // normalize values so that they stay between 0..1 - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - perlinNoise[x][y] /= totalAmplitude; - } - } - - return perlinNoise; - } - - /** - * @param base base random float array - * @param width width of noise array - * @param height height of noise array - * @param octave current layer - * @return float array containing calculated "Perlin-Noise-Layer" values - */ - static float[][] generatePerlinNoiseLayer(float[][] base, int width, int height, int octave) { - float[][] perlinNoiseLayer = new float[width][height]; - - // calculate period (wavelength) for different shapes - int period = 1 << octave; // 2^k - float frequency = 1f / period; // 1/2^k - - for (int x = 0; x < width; x++) { - // calculates the horizontal sampling indices - int x0 = (x / period) * period; - int x1 = (x0 + period) % width; - float horizintalBlend = (x - x0) * frequency; - - for (int y = 0; y < height; y++) { - // calculates the vertical sampling indices - int y0 = (y / period) * period; - int y1 = (y0 + period) % height; - float verticalBlend = (y - y0) * frequency; - - // blend top corners - float top = interpolate(base[x0][y0], base[x1][y0], horizintalBlend); - - // blend bottom corners - float bottom = interpolate(base[x0][y1], base[x1][y1], horizintalBlend); - - // blend top and bottom interpolation to get the final blend value for this cell - perlinNoiseLayer[x][y] = interpolate(top, bottom, verticalBlend); - } - } - - return perlinNoiseLayer; - } - - /** - * @param a value of point a - * @param b value of point b - * @param alpha determine which value has more impact (closer to 0 -> a, closer to 1 -> b) - * @return interpolated value - */ - static float interpolate(float a, float b, float alpha) { - return a * (1 - alpha) + alpha * b; - } - - public static void main(String[] args) { - Scanner in = new Scanner(System.in); - - final int width; - final int height; - final int octaveCount; - final float persistence; - final long seed; - final String charset; - final float[][] perlinNoise; - - System.out.println("Width (int): "); - width = in.nextInt(); - - System.out.println("Height (int): "); - height = in.nextInt(); - - System.out.println("Octave count (int): "); - octaveCount = in.nextInt(); - - System.out.println("Persistence (float): "); - persistence = in.nextFloat(); - - System.out.println("Seed (long): "); - seed = in.nextLong(); - - System.out.println("Charset (String): "); - charset = in.next(); - - perlinNoise = generatePerlinNoise(width, height, octaveCount, persistence, seed); - final char[] chars = charset.toCharArray(); - final int length = chars.length; - final float step = 1f / length; - // output based on charset - for (int x = 0; x < width; x++) { - for (int y = 0; y < height; y++) { - float value = step; - float noiseValue = perlinNoise[x][y]; - - for (char c : chars) { - if (noiseValue <= value) { - System.out.print(c); - break; - } - - value += step; - } - } - - System.out.println(); - } - in.close(); - } -} diff --git a/Others/QueueUsingTwoStacks.java b/Others/QueueUsingTwoStacks.java deleted file mode 100644 index cc39b29b55d0..000000000000 --- a/Others/QueueUsingTwoStacks.java +++ /dev/null @@ -1,168 +0,0 @@ -package Others; - -import java.util.Stack; - -/** - * This implements Queue using two Stacks. - * - *

Big O Runtime: insert(): O(1) remove(): O(1) amortized isEmpty(): O(1) - * - *

A queue data structure functions the same as a real world queue. The elements that are added - * first are the first to be removed. New elements are added to the back/rear of the queue. - * - * @author sahilb2 (https://www.github.com/sahilb2) - */ -class QueueWithStack { - - // Stack to keep track of elements inserted into the queue - private Stack inStack; - // Stack to keep track of elements to be removed next in queue - private Stack outStack; - - /** Constructor */ - public QueueWithStack() { - this.inStack = new Stack<>(); - this.outStack = new Stack<>(); - } - - /** - * Inserts an element at the rear of the queue - * - * @param x element to be added - */ - public void insert(Object x) { - // Insert element into inStack - this.inStack.push(x); - } - - /** - * Remove an element from the front of the queue - * - * @return the new front of the queue - */ - public Object remove() { - if (this.outStack.isEmpty()) { - // Move all elements from inStack to outStack (preserving the order) - while (!this.inStack.isEmpty()) { - this.outStack.push(this.inStack.pop()); - } - } - return this.outStack.pop(); - } - - /** - * Peek at the element from the front of the queue - * - * @return the front element of the queue - */ - public Object peekFront() { - if (this.outStack.isEmpty()) { - // Move all elements from inStack to outStack (preserving the order) - while (!this.inStack.isEmpty()) { - this.outStack.push(this.inStack.pop()); - } - } - return this.outStack.peek(); - } - - /** - * Peek at the element from the back of the queue - * - * @return the back element of the queue - */ - public Object peekBack() { - return this.inStack.peek(); - } - - /** - * Returns true if the queue is empty - * - * @return true if the queue is empty - */ - public boolean isEmpty() { - return (this.inStack.isEmpty() && this.outStack.isEmpty()); - } - - /** - * Returns true if the inStack is empty. - * - * @return true if the inStack is empty. - */ - public boolean isInStackEmpty() { - return (inStack.size() == 0); - } - - /** - * Returns true if the outStack is empty. - * - * @return true if the outStack is empty. - */ - public boolean isOutStackEmpty() { - return (outStack.size() == 0); - } -} - -/** - * This class is the example for the Queue class - * - * @author sahilb2 (https://www.github.com/sahilb2) - */ -public class QueueUsingTwoStacks { - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String args[]) { - QueueWithStack myQueue = new QueueWithStack(); - myQueue.insert(1); - System.out.println(myQueue.peekBack()); // Will print 1 - // instack: [(top) 1] - // outStack: [] - myQueue.insert(2); - System.out.println(myQueue.peekBack()); // Will print 2 - // instack: [(top) 2, 1] - // outStack: [] - myQueue.insert(3); - System.out.println(myQueue.peekBack()); // Will print 3 - // instack: [(top) 3, 2, 1] - // outStack: [] - myQueue.insert(4); - System.out.println(myQueue.peekBack()); // Will print 4 - // instack: [(top) 4, 3, 2, 1] - // outStack: [] - - System.out.println(myQueue.isEmpty()); // Will print false - - System.out.println(myQueue.remove()); // Will print 1 - System.out.println((myQueue.isInStackEmpty()) ? "null" : myQueue.peekBack()); // Will print NULL - // instack: [] - // outStack: [(top) 2, 3, 4] - - myQueue.insert(5); - System.out.println(myQueue.peekFront()); // Will print 2 - // instack: [(top) 5] - // outStack: [(top) 2, 3, 4] - - myQueue.remove(); - System.out.println(myQueue.peekFront()); // Will print 3 - // instack: [(top) 5] - // outStack: [(top) 3, 4] - myQueue.remove(); - System.out.println(myQueue.peekFront()); // Will print 4 - // instack: [(top) 5] - // outStack: [(top) 4] - myQueue.remove(); - // instack: [(top) 5] - // outStack: [] - System.out.println(myQueue.peekFront()); // Will print 5 - // instack: [] - // outStack: [(top) 5] - myQueue.remove(); - // instack: [] - // outStack: [] - - System.out.println(myQueue.isEmpty()); // Will print true - } -} diff --git a/Others/RabinKarp.java b/Others/RabinKarp.java deleted file mode 100644 index 6f9adf8a25f9..000000000000 --- a/Others/RabinKarp.java +++ /dev/null @@ -1,81 +0,0 @@ -package Others; - -/** @author Prateek Kumar Oraon (https://github.com/prateekKrOraon) */ -import java.util.Scanner; - -// An implementation of Rabin-Karp string matching algorithm -// Program will simply end if there is no match -public class RabinKarp { - - public static Scanner scanner = null; - public static final int d = 256; - - public static void main(String[] args) { - - scanner = new Scanner(System.in); - System.out.println("Enter String"); - String text = scanner.nextLine(); - System.out.println("Enter pattern"); - String pattern = scanner.nextLine(); - - int q = 101; - searchPat(text, pattern, q); - } - - private static void searchPat(String text, String pattern, int q) { - - int m = pattern.length(); - int n = text.length(); - int t = 0; - int p = 0; - int h = 1; - int j = 0; - int i = 0; - - h = (int) Math.pow(d, m - 1) % q; - - for (i = 0; i < m; i++) { - // hash value is calculated for each character and then added with the hash value of the next - // character for pattern - // as well as the text for length equal to the length of pattern - p = (d * p + pattern.charAt(i)) % q; - t = (d * t + text.charAt(i)) % q; - } - - for (i = 0; i <= n - m; i++) { - - // if the calculated hash value of the pattern and text matches then - // all the characters of the pattern is matched with the text of length equal to length of the - // pattern - // if all matches then pattern exist in string - // if not then the hash value of the first character of the text is subtracted and hash value - // of the next character after the end - // of the evaluated characters is added - if (p == t) { - - // if hash value matches then the individual characters are matched - for (j = 0; j < m; j++) { - - // if not matched then break out of the loop - if (text.charAt(i + j) != pattern.charAt(j)) break; - } - - // if all characters are matched then pattern exist in the string - if (j == m) { - System.out.println("Pattern found at index " + i); - } - } - - // if i movements = new ArrayList(); - public StringBuilder stringBuilder = new StringBuilder(); - - public ArrayList Stack1 = new ArrayList(); - public ArrayList Stack2 = new ArrayList(); - public ArrayList Stack3 = new ArrayList(); - - public void updateStacks() { - if (game_counter != movements.size()) { - String temp = movements.get(game_counter); - System.out.println(temp); - if (temp.charAt(1) == 'A') { - if (temp.charAt(2) == 'B') { - int x = Stack1.get(Stack1.size() - 1); - Stack1.remove(Stack1.size() - 1); - Stack2.add(x); - } - } - if (temp.charAt(1) == 'C') { - if (temp.charAt(2) == 'B') { - int x = Stack3.get(Stack3.size() - 1); - Stack3.remove(Stack3.size() - 1); - Stack2.add(x); - } - } - - if (temp.charAt(1) == 'B') { - if (temp.charAt(2) == 'C') { - int x = Stack2.get(Stack2.size() - 1); - Stack2.remove(Stack2.size() - 1); - Stack3.add(x); - } else if (temp.charAt(2) == 'A') { - int x = Stack2.get(Stack2.size() - 1); - Stack2.remove(Stack2.size() - 1); - Stack1.add(x); - } - } - revalidate(); - repaint(); - game_counter++; - } - } - - public void paint(Graphics canvas) { - super.paint(canvas); - - // Drawing pedestels - for (int i = 0; i < 3; i++) { - canvas.drawRect(30 + i * 230, 670, 200, 20); - canvas.setColor(new Color(76, 174, 227)); // Blue Accent - canvas.fillRect(30 + i * 230, 670, 200, 20); - - canvas.fillRect(130 + i * 230 - 2, 670 - 170, 4, 170); - canvas.setColor(new Color(150, 0, 0)); // Arseny - canvas.fillRect(130 + i * 230 - 2, 670 - 170, 4, 170); - } - - // Disks in stack1 - for (int i = 1; i <= Stack1.size(); i++) { - canvas.drawRect(130 - Stack1.get(i - 1) * 10, 670 - i * 12, Stack1.get(i - 1) * 20, 10); - canvas.setColor(new Color(64, 26, 0)); // Brown Wolfers - canvas.fillRect(130 - Stack1.get(i - 1) * 10, 670 - i * 12, Stack1.get(i - 1) * 20, 10); - } - - // Disks in stack2 - for (int i = 1; i <= Stack2.size(); i++) { - canvas.drawRect(360 - Stack2.get(i - 1) * 10, 670 - i * 12, Stack2.get(i - 1) * 20, 10); - canvas.setColor(new Color(64, 26, 0)); // Brown Wolfers - canvas.fillRect(360 - Stack2.get(i - 1) * 10, 670 - i * 12, Stack2.get(i - 1) * 20, 10); - } - - // Disks in stack3 - for (int i = 1; i <= Stack3.size(); i++) { - canvas.drawRect(590 - Stack3.get(i - 1) * 10, 670 - i * 12, Stack3.get(i - 1) * 20, 10); - canvas.setColor(new Color(64, 26, 0)); // Brown Wolfers - canvas.fillRect(590 - Stack3.get(i - 1) * 10, 670 - i * 12, Stack3.get(i - 1) * 20, 10); - } - } - - // Function to initialize the widget properties and the frame. - public void initialize() { - - move_button.setIcon(new ImageIcon("../Resources/rsz_move.png")); - move_button.setBounds(130, 0, 50, 50); - - auto_button.setIcon(new ImageIcon("../Resources/rsz_loop.png")); - auto_button.setBounds(260, 0, 50, 50); - - replay_button.setIcon(new ImageIcon("../Resources/rsz_replay.jpg")); - replay_button.setBounds(390, 0, 50, 50); - - exit_button.setIcon(new ImageIcon("../Resources/rsz_exit.png")); - exit_button.setBounds(520, 0, 50, 50); - - add(move_button); - add(exit_button); - add(replay_button); - add(auto_button); - - setLayout(null); - setSize(720, 720); - setVisible(true); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - } - // Main cnstructor. - Hanoi() { - super("restricted tower of hanoi"); - initialize(); - - // MOVE BUTTON ACTION LISTENER - move_button.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - updateStacks(); - } - }); - - // EXIT BUTTON ACTION LISTENER - exit_button.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - System.exit(0); - } - }); - - // REPLAY BUTTON ACTION LISTENER - replay_button.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - startGame(); - repaint(); - } - }); - - // AUTOMATIC PLAY BUTTON ACTION LISTENER - auto_button.addActionListener( - new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - timer.start(); - if (game_counter == movements.size()) { - timer.stop(); - } - } - }); - } - - Timer timer = - new Timer( - ONE_SECOND, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - updateStacks(); - } - }); - - public void startGame() { - - System.out.println("New Game Started"); - timer.stop(); - - Stack1 = new ArrayList(); - Stack2 = new ArrayList(); - Stack3 = new ArrayList(); - - movements = new ArrayList(); - game_counter = 0; - - for (int i = 0; i < number_of_disks; i++) { - Stack1.add(number_of_disks - i); - } - - towerOfHanoi(number_of_disks, 'A', 'C', 'B'); - } - - public static void main(String args[]) { - Hanoi tower = new Hanoi(); - int number = Integer.parseInt(args[0]); - tower.number_of_disks = number; - tower.startGame(); - /*for(int i=0;i stack = new Stack<>(); - - // Main function - public static void main(String[] args) { - // To Create a Dummy Stack containing integers from 0-9 - for (int i = 0; i < 10; i++) { - stack.push(i); - } - System.out.println("STACK"); - - // To print that dummy Stack - for (int k = 9; k >= 0; k--) { - System.out.println(k); - } - - // Reverse Function called - reverseUsingRecursion(stack); - - System.out.println("REVERSED STACK : "); - // To print reversed stack - while (!stack.isEmpty()) { - System.out.println(stack.pop()); - } - } - - // Function Used to reverse Stack Using Recursion - private static void reverseUsingRecursion(Stack stack) { - if (stack.isEmpty()) // If stack is empty then return - { - return; - } - /* All items are stored in call stack until we reach the end*/ - - int temptop = stack.peek(); - stack.pop(); - reverseUsingRecursion(stack); // Recursion call - insertAtEnd(temptop); // Insert items held in call stack one by one into stack - } - - // Function used to insert element at the end of stack - private static void insertAtEnd(int temptop) { - if (stack.isEmpty()) { - stack.push(temptop); // If stack is empty push the element - } else { - int temp = stack.peek(); /* All the items are stored in call stack until we reach end*/ - stack.pop(); - - insertAtEnd(temptop); // Recursive call - - stack.push(temp); - } - } -} diff --git a/Others/RootPrecision.java b/Others/RootPrecision.java deleted file mode 100644 index 4f9f86965c2b..000000000000 --- a/Others/RootPrecision.java +++ /dev/null @@ -1,36 +0,0 @@ -package Others; - -import java.util.Scanner; - -public class RootPrecision { - - public static void main(String[] args) { - // take input - Scanner scn = new Scanner(System.in); - - // N is the input number - int N = scn.nextInt(); - - // P is precision value for eg - P is 3 in 2.564 and 5 in 3.80870. - int P = scn.nextInt(); - System.out.println(squareRoot(N, P)); - - scn.close(); - } - - public static double squareRoot(int N, int P) { - // rv means return value - double rv; - - double root = Math.pow(N, 0.5); - - // calculate precision to power of 10 and then multiply it with root value. - int precision = (int) Math.pow(10, P); - root = root * precision; - /*typecast it into integer then divide by precision and again typecast into double - so as to have decimal points upto P precision */ - - rv = (int) root; - return rv / precision; - } -} diff --git a/Others/RotateMatriceBy90Degree.java b/Others/RotateMatriceBy90Degree.java deleted file mode 100644 index 1c5419a3acb9..000000000000 --- a/Others/RotateMatriceBy90Degree.java +++ /dev/null @@ -1,60 +0,0 @@ -package Others; - -/** - * Given a matrix of size n x n We have to rotate this matrix by 90 Degree Here is the algorithm for - * this problem . - */ -import java.util.*; - -class Rotate_by_90_degree { - public static void main(String[] args) { - Scanner sc = new Scanner(System.in); - int t = sc.nextInt(); - - while (t-- > 0) { - int n = sc.nextInt(); - int[][] arr = new int[n][n]; - - for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) arr[i][j] = sc.nextInt(); - - Rotate g = new Rotate(); - g.rotate(arr); - printMatrix(arr); - } - sc.close(); - } - - static void printMatrix(int arr[][]) { - for (int i = 0; i < arr.length; i++) { - for (int j = 0; j < arr[0].length; j++) System.out.print(arr[i][j] + " "); - System.out.println(""); - } - } -} - -/** Class containing the algo to roate matrix by 90 degree */ -class Rotate { - static void rotate(int a[][]) { - int n = a.length; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - if (i > j) { - int temp = a[i][j]; - a[i][j] = a[j][i]; - a[j][i] = temp; - } - } - } - int i = 0, k = n - 1; - while (i < k) { - for (int j = 0; j < n; j++) { - int temp = a[i][j]; - a[i][j] = a[k][j]; - a[k][j] = temp; - } - - i++; - k--; - } - } -} diff --git a/Others/SJF.java b/Others/SJF.java deleted file mode 100644 index 9eb9e1844daf..000000000000 --- a/Others/SJF.java +++ /dev/null @@ -1,184 +0,0 @@ -package Others; -/** - * - * - *

Shortest job first.

- * - *

Shortest job first (SJF) or shortest job next, is a scheduling policy that selects the waiting - * process with the smallest execution time to execute next Shortest Job first has the advantage of - * having minimum average waiting time among all scheduling algorithms. It is a Greedy Algorithm. It - * may cause starvation if shorter processes keep coming. This problem has been solved using the - * concept of aging. - * - * @author shivg7706 - * @since 2018/10/27 - */ -import java.util.*; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.Scanner; - -class Process { - - public int pid; - public int arrivalTime; - public int burstTime; - public int priority; - public int turnAroundTime; - public int waitTime; - public int remainingTime; -} - -class Schedule { - - private int noOfProcess; - private int timer = 0; - private ArrayList processes; - private ArrayList remainingProcess; - private ArrayList gantChart; - private float burstAll; - private Map> arrivals; - - Schedule() { - Scanner in = new Scanner(System.in); - - processes = new ArrayList(); - remainingProcess = new ArrayList(); - - gantChart = new ArrayList<>(); - arrivals = new HashMap<>(); - - System.out.print("Enter the no. of processes: "); - noOfProcess = in.nextInt(); - System.out.println("Enter the arrival, burst and priority of processes"); - for (int i = 0; i < noOfProcess; i++) { - Process p = new Process(); - p.pid = i; - p.arrivalTime = in.nextInt(); - p.burstTime = in.nextInt(); - p.priority = in.nextInt(); - p.turnAroundTime = 0; - p.waitTime = 0; - p.remainingTime = p.burstTime; - - if (arrivals.get(p.arrivalTime) == null) { - arrivals.put(p.arrivalTime, new ArrayList()); - } - arrivals.get(p.arrivalTime).add(p); - processes.add(p); - burstAll += p.burstTime; - } - in.close(); - } - - void startScheduling() { - - processes.sort( - new Comparator() { - @Override - public int compare(Process a, Process b) { - return a.arrivalTime - b.arrivalTime; - } - }); - - while (!(arrivals.size() == 0 && remainingProcess.size() == 0)) { - removeFinishedProcess(); - if (arrivals.get(timer) != null) { - remainingProcess.addAll(arrivals.get(timer)); - arrivals.remove(timer); - } - - remainingProcess.sort( - new Comparator() { - private int alpha = 6; - private int beta = 1; - - @Override - public int compare(Process a, Process b) { - int aRem = a.remainingTime; - int bRem = b.remainingTime; - int aprior = a.priority; - int bprior = b.priority; - return (alpha * aRem + beta * aprior) - (alpha * bRem + beta * bprior); - } - }); - - int k = timeElapsed(timer); - ageing(k); - timer++; - } - - System.out.println("Total time required: " + (timer - 1)); - } - - void removeFinishedProcess() { - ArrayList completed = new ArrayList(); - for (int i = 0; i < remainingProcess.size(); i++) { - if (remainingProcess.get(i).remainingTime == 0) { - completed.add(i); - } - } - - for (int i = 0; i < completed.size(); i++) { - int pid = remainingProcess.get(completed.get(i)).pid; - processes.get(pid).waitTime = remainingProcess.get(completed.get(i)).waitTime; - remainingProcess.remove(remainingProcess.get(completed.get(i))); - } - } - - public int timeElapsed(int i) { - if (!remainingProcess.isEmpty()) { - gantChart.add(i, remainingProcess.get(0).pid); - remainingProcess.get(0).remainingTime--; - return 1; - } - return 0; - } - - public void ageing(int k) { - for (int i = k; i < remainingProcess.size(); i++) { - remainingProcess.get(i).waitTime++; - if (remainingProcess.get(i).waitTime % 7 == 0) { - remainingProcess.get(i).priority--; - } - } - } - - public void solve() { - System.out.println("Gant chart "); - for (int i = 0; i < gantChart.size(); i++) { - System.out.print(gantChart.get(i) + " "); - } - System.out.println(); - - float waitTimeTot = 0; - float tatTime = 0; - - for (int i = 0; i < noOfProcess; i++) { - processes.get(i).turnAroundTime = processes.get(i).waitTime + processes.get(i).burstTime; - - waitTimeTot += processes.get(i).waitTime; - tatTime += processes.get(i).turnAroundTime; - - System.out.println( - "Process no.: " - + i - + " Wait time: " - + processes.get(i).waitTime - + " Turn Around Time: " - + processes.get(i).turnAroundTime); - } - - System.out.println("Average Waiting Time: " + waitTimeTot / noOfProcess); - System.out.println("Average TAT Time: " + tatTime / noOfProcess); - System.out.println("Throughput: " + (float) noOfProcess / (timer - 1)); - } -} - -public class SJF { - public static void main(String[] args) { - Schedule s = new Schedule(); - s.startScheduling(); - s.solve(); - } -} diff --git a/Others/SieveOfEratosthenes.java b/Others/SieveOfEratosthenes.java deleted file mode 100644 index a4293cc3439b..000000000000 --- a/Others/SieveOfEratosthenes.java +++ /dev/null @@ -1,76 +0,0 @@ -package Others; - -import java.util.Arrays; - -/** - * Sieve of Eratosthenes is an ancient algorithm for finding all prime numbers up to any given limit. - * It does so by iteratively marking as composite (i.e., not prime) the multiples of each prime, - * starting with the first prime number, 2. - * The multiples of a given prime are generated as a sequence of numbers starting from that prime, - * with constant difference between them that is equal to that prime. - * This is the sieve's key distinction from using trial division to sequentially test each - * candidate number for divisibility by each prime. - * Once all the multiples of each discovered prime have been marked as composites, the remaining - * unmarked numbers are primes. - *

- * Poetry about Sieve of Eratosthenes: - *

Sift the Two's and Sift the Three's:

- *

The Sieve of Eratosthenes.

- *

When the multiples sublime,

- *

The numbers that remain are Prime.

- * - * @see Wiki - */ -public class SieveOfEratosthenes { - - /** - * @param n The number till which we have to check for prime Prints all the prime numbers till n. - * Should be more than 1. - * @return array of all prime numbers between 0 to n - */ - public static int[] findPrimesTill(int n) { - // Create array where index is number and value is flag - is that number a prime or not. - // size of array is n + 1 cause in Java array indexes starts with 0 - Type[] numbers = new Type[n + 1]; - - // Start with assumption that all numbers except 0 and 1 are primes. - Arrays.fill(numbers, Type.PRIME); - numbers[0] = numbers[1] = Type.NOT_PRIME; - - double cap = Math.sqrt(n); - // Main algorithm: mark all numbers which are multiples of some other values as not prime - for (int i = 2; i <= cap; i++) { - if (numbers[i] == Type.PRIME) { - for (int j = 2; i * j <= n; j++) { - numbers[i * j] = Type.NOT_PRIME; - } - } - } - - //Write all primes to result array - int primesCount = (int) Arrays.stream(numbers) - .filter(element -> element == Type.PRIME) - .count(); - int[] primes = new int[primesCount]; - - int primeIndex = 0; - for (int i = 0; i < n + 1; i++) { - if(numbers[i] == Type.PRIME) { - primes[primeIndex++] = i; - } - } - - return primes; - } - - private enum Type { - PRIME, NOT_PRIME - } - - public static void main(String[] args) { - int n = 100; - System.out.println("Searching for all primes from zero to " + n); - int[] primes = findPrimesTill(n); - System.out.println("Found: " + Arrays.toString(primes)); - } -} diff --git a/Others/SkylineProblem.java b/Others/SkylineProblem.java deleted file mode 100644 index 5be6501c9cc2..000000000000 --- a/Others/SkylineProblem.java +++ /dev/null @@ -1,132 +0,0 @@ -package Others; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Scanner; - -public class SkylineProblem { - Building[] building; - int count; - - public void run() { - Scanner sc = new Scanner(System.in); - - int num = sc.nextInt(); - this.building = new Building[num]; - - for (int i = 0; i < num; i++) { - String input = sc.next(); - String[] data = input.split(","); - this.add(Integer.parseInt(data[0]), Integer.parseInt(data[1]), Integer.parseInt(data[2])); - } - this.print(this.findSkyline(0, num - 1)); - - sc.close(); - } - - public void add(int left, int height, int right) { - building[count++] = new Building(left, height, right); - } - - public void print(ArrayList skyline) { - Iterator it = skyline.iterator(); - - while (it.hasNext()) { - Skyline temp = it.next(); - System.out.print(temp.coordinates + "," + temp.height); - if (it.hasNext()) { - System.out.print(","); - } - } - } - - public ArrayList findSkyline(int start, int end) { - if (start == end) { - ArrayList list = new ArrayList<>(); - list.add(new Skyline(building[start].left, building[start].height)); - list.add(new Skyline(building[end].right, 0)); - - return list; - } - - int mid = (start + end) / 2; - - ArrayList sky1 = this.findSkyline(start, mid); - ArrayList sky2 = this.findSkyline(mid + 1, end); - - return this.mergeSkyline(sky1, sky2); - } - - public ArrayList mergeSkyline(ArrayList sky1, ArrayList sky2) { - int currentH1 = 0, currentH2 = 0; - ArrayList skyline = new ArrayList<>(); - int maxH = 0; - - while (!sky1.isEmpty() && !sky2.isEmpty()) { - if (sky1.get(0).coordinates < sky2.get(0).coordinates) { - int currentX = sky1.get(0).coordinates; - currentH1 = sky1.get(0).height; - - if (currentH1 < currentH2) { - sky1.remove(0); - if (maxH != currentH2) skyline.add(new Skyline(currentX, currentH2)); - } else { - maxH = currentH1; - sky1.remove(0); - skyline.add(new Skyline(currentX, currentH1)); - } - } else { - int currentX = sky2.get(0).coordinates; - currentH2 = sky2.get(0).height; - - if (currentH2 < currentH1) { - sky2.remove(0); - if (maxH != currentH1) skyline.add(new Skyline(currentX, currentH1)); - } else { - maxH = currentH2; - sky2.remove(0); - skyline.add(new Skyline(currentX, currentH2)); - } - } - } - - while (!sky1.isEmpty()) { - skyline.add(sky1.get(0)); - sky1.remove(0); - } - - while (!sky2.isEmpty()) { - skyline.add(sky2.get(0)); - sky2.remove(0); - } - - return skyline; - } - - public class Skyline { - public int coordinates; - public int height; - - public Skyline(int coordinates, int height) { - this.coordinates = coordinates; - this.height = height; - } - } - - public class Building { - public int left; - public int height; - public int right; - - public Building(int left, int height, int right) { - this.left = left; - this.height = height; - this.right = right; - } - } - - public static void main(String[] args) { - SkylineProblem skylineProblem = new SkylineProblem(); - skylineProblem.run(); - } -} diff --git a/Others/StackPostfixNotation.java b/Others/StackPostfixNotation.java deleted file mode 100644 index 63b4d3c76a3a..000000000000 --- a/Others/StackPostfixNotation.java +++ /dev/null @@ -1,42 +0,0 @@ -package Others; - -import java.util.*; - -public class StackPostfixNotation { - public static void main(String[] args) { - Scanner scanner = new Scanner(System.in); - String post = scanner.nextLine(); // Takes input with spaces in between eg. "1 21 +" - System.out.println(postfixEvaluate(post)); - scanner.close(); - } - - // Evaluates the given postfix expression string and returns the result. - public static int postfixEvaluate(String exp) { - Stack s = new Stack(); - Scanner tokens = new Scanner(exp); - - while (tokens.hasNext()) { - if (tokens.hasNextInt()) { - s.push(tokens.nextInt()); // If int then push to stack - } else { // else pop top two values and perform the operation - int num2 = s.pop(); - int num1 = s.pop(); - String op = tokens.next(); - - if (op.equals("+")) { - s.push(num1 + num2); - } else if (op.equals("-")) { - s.push(num1 - num2); - } else if (op.equals("*")) { - s.push(num1 * num2); - } else { - s.push(num1 / num2); - } - - // "+", "-", "*", "/" - } - } - tokens.close(); - return s.pop(); - } -} diff --git a/Others/StringMatchFiniteAutomata.java b/Others/StringMatchFiniteAutomata.java deleted file mode 100644 index f534fa812bf8..000000000000 --- a/Others/StringMatchFiniteAutomata.java +++ /dev/null @@ -1,83 +0,0 @@ -package Others; - -/** @author Prateek Kumar Oraon (https://github.com/prateekKrOraon) */ -import java.util.Scanner; - -// An implementaion of string matching using finite automata -public class StringMatchFiniteAutomata { - - public static final int CHARS = 256; - public static int[][] FA; - public static Scanner scanner = null; - - public static void main(String[] args) { - - scanner = new Scanner(System.in); - System.out.println("Enter String"); - String text = scanner.nextLine(); - System.out.println("Enter pattern"); - String pat = scanner.nextLine(); - - searchPat(text, pat); - - scanner.close(); - } - - public static void searchPat(String text, String pat) { - - int m = pat.length(); - int n = text.length(); - - FA = new int[m + 1][CHARS]; - - computeFA(pat, m, FA); - - int state = 0; - for (int i = 0; i < n; i++) { - state = FA[state][text.charAt(i)]; - - if (state == m) { - System.out.println("Pattern found at index " + (i - m + 1)); - } - } - } - - // Computes finite automata for the partern - public static void computeFA(String pat, int m, int[][] FA) { - - for (int state = 0; state <= m; ++state) { - for (int x = 0; x < CHARS; ++x) { - FA[state][x] = getNextState(pat, m, state, x); - } - } - } - - public static int getNextState(String pat, int m, int state, int x) { - - // if current state is less than length of pattern - // and input character of pattern matches the character in the alphabet - // then automata goes to next state - if (state < m && x == pat.charAt(state)) { - return state + 1; - } - - for (int ns = state; ns > 0; ns--) { - - if (pat.charAt(ns - 1) == x) { - - for (int i = 0; i < ns - 1; i++) { - - if (pat.charAt(i) != pat.charAt(state - ns + i + 1)) { - break; - } - - if (i == ns - 1) { - return ns; - } - } - } - } - - return 0; - } -} diff --git a/Others/ThreeSum.java b/Others/ThreeSum.java deleted file mode 100644 index 9524bb6f54e4..000000000000 --- a/Others/ThreeSum.java +++ /dev/null @@ -1,47 +0,0 @@ -package Others; - -import java.util.Arrays; -import java.util.Scanner; - -/** - * To find triplet equals to given sum in complexity O(n*log(n)) - * - *

Array must be sorted - * - * @author Ujjawal Joshi - * @date 2020.05.18 - *

Test Cases: Input: 6 //Length of array 12 3 4 1 6 9 target=24 Output:3 9 12 Explanation: - * There is a triplet (12, 3 and 9) present in the array whose sum is 24. - */ -class ThreeSum { - public static void main(String args[]) { - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); // Length of an array - - int a[] = new int[n]; - - for (int i = 0; i < n; i++) { - a[i] = sc.nextInt(); - } - System.out.println("Target"); - int n_find = sc.nextInt(); - - Arrays.sort(a); // Sort the array if array is not sorted - - for (int i = 0; i < n; i++) { - - int l = i + 1, r = n - 1; - - while (l < r) { - if (a[i] + a[l] + a[r] == n_find) { - System.out.println(a[i] + " " + a[l] + " " + a[r]); - break; - } // if you want all the triplets write l++;r--; insted of break; - else if (a[i] + a[l] + a[r] < n_find) l++; - else r--; - } - } - - sc.close(); - } -} diff --git a/Others/TopKWords.java b/Others/TopKWords.java deleted file mode 100644 index 98a683e5dbfb..000000000000 --- a/Others/TopKWords.java +++ /dev/null @@ -1,86 +0,0 @@ -package Others; - -import java.io.*; -import java.util.*; - -/* display the most frequent K words in the file and the times it appear -in the file – shown in order (ignore case and periods) */ - -public class TopKWords { - static class CountWords { - private String fileName; - - public CountWords(String fileName) { - this.fileName = fileName; - } - - public Map getDictionary() { - Map dictionary = new HashMap<>(); - FileInputStream fis = null; - - try { - - fis = new FileInputStream(fileName); // open the file - int in = 0; - String s = ""; // init a empty word - in = fis.read(); // read one character - - while (-1 != in) { - if (Character.isLetter((char) in)) { - s += (char) in; // if get a letter, append to s - } else { - // this branch means an entire word has just been read - if (s.length() > 0) { - // see whether word exists or not - if (dictionary.containsKey(s)) { - // if exist, count++ - dictionary.put(s, dictionary.get(s) + 1); - } else { - // if not exist, initiate count of this word with 1 - dictionary.put(s, 1); - } - } - s = ""; // reInit a empty word - } - in = fis.read(); - } - return dictionary; - } catch (IOException e) { - e.printStackTrace(); - } finally { - try { - // you always have to close the I/O streams - if (fis != null) fis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - return null; - } - } - - public static void main(String[] args) { - // you can replace the filePath with yours - CountWords cw = new CountWords("/Users/lisanaaa/Desktop/words.txt"); - Map dictionary = - cw.getDictionary(); // get the words dictionary: {word: frequency} - - // we change the map to list for convenient sort - List> list = new ArrayList<>(dictionary.entrySet()); - - // sort by lambda valueComparator - list.sort(Comparator.comparing(m -> m.getValue())); - - Scanner input = new Scanner(System.in); - int k = input.nextInt(); - while (k > list.size()) { - System.out.println("Retype a number, your number is too large"); - input = new Scanner(System.in); - k = input.nextInt(); - } - for (int i = 0; i < k; i++) { - System.out.println(list.get(list.size() - i - 1)); - } - input.close(); - } -} diff --git a/Others/TowerOfHanoi.java b/Others/TowerOfHanoi.java deleted file mode 100644 index c339739cc79e..000000000000 --- a/Others/TowerOfHanoi.java +++ /dev/null @@ -1,26 +0,0 @@ -package Others; - -import java.util.Scanner; - -class TowerOfHanoi { - public static void shift(int n, String startPole, String intermediatePole, String endPole) { - // if n becomes zero the program returns thus ending the loop. - if (n != 0) { - // Shift function is called in recursion for swapping the n-1 disc from the startPole to the - // intermediatePole - shift(n - 1, startPole, endPole, intermediatePole); - System.out.format("Move %d from %s to %s\n", n, startPole, endPole); // Result Printing - // Shift function is called in recursion for swapping the n-1 disc from the intermediatePole - // to the endPole - shift(n - 1, intermediatePole, startPole, endPole); - } - } - - public static void main(String[] args) { - System.out.print("Enter number of discs on Pole 1: "); - Scanner scanner = new Scanner(System.in); - int numberOfDiscs = scanner.nextInt(); // input of number of discs on pole 1 - shift(numberOfDiscs, "Pole1", "Pole2", "Pole3"); // Shift function called - scanner.close(); - } -} diff --git a/Others/TwoPointers.java b/Others/TwoPointers.java deleted file mode 100644 index ee38192d630c..000000000000 --- a/Others/TwoPointers.java +++ /dev/null @@ -1,50 +0,0 @@ -package Others; - -import java.util.Arrays; - -/** - * The two pointer technique is a useful tool to utilize when searching for pairs in a sorted array. - * - *

link: https://www.geeksforgeeks.org/two-pointers-technique/ - */ -class TwoPointers { - - public static void main(String[] args) { - int[] arr = {10, 20, 35, 50, 75, 80}; - int key = 70; - assert isPairedSum(arr, key); /* 20 + 60 == 70 */ - - arr = new int[] {1, 2, 3, 4, 5, 6, 7}; - key = 13; - assert isPairedSum(arr, key); /* 6 + 7 == 13 */ - - key = 14; - assert !isPairedSum(arr, key); - } - - /** - * Given a sorted array arr (sorted in ascending order). Find if there exists any pair of elements - * such that their sum is equal to key. - * - * @param arr the array contains elements - * @param key the number to search - * @return {@code true} if there exists a pair of elements, {@code false} otherwise. - */ - private static boolean isPairedSum(int[] arr, int key) { - /* array sorting is necessary for this algorithm to function correctly */ - Arrays.sort(arr); - int i = 0; /* index of first element */ - int j = arr.length - 1; /* index of last element */ - - while (i < j) { - if (arr[i] + arr[j] == key) { - return true; - } else if (arr[i] + arr[j] < key) { - i++; - } else { - j--; - } - } - return false; - } -} diff --git a/Others/WorstFit.java b/Others/WorstFit.java deleted file mode 100644 index 23753b28fef2..000000000000 --- a/Others/WorstFit.java +++ /dev/null @@ -1,80 +0,0 @@ -package Others; - -import java.util.ArrayList; - -/** @author Dekas Dimitrios */ -public class WorstFit { - private static final int NO_ALLOCATION = - -255; // if a process has been allocated in position -255, - // it means that it has not been actually allocated. - - /** - * Method to find the index of the memory block that is going to fit the given process based on - * the worst fit algorithm. - * - * @param blocks: the array with the available memory blocks. - * @param process: the size of the process. - * @return the index of the block that fits, or -255 if no such block exists. - */ - private static int findWorstFit(int[] blockSizes, int processSize) { - int max = -1; - int index = -1; - for (int i = 0; - i < blockSizes.length; - i++) { // Find the index of the biggest memory block available. - if (blockSizes[i] > max) { - max = blockSizes[i]; - index = i; - } - } - // If the biggest memory block cannot fit the process, return -255 as the result - if (processSize > blockSizes[index]) { - return NO_ALLOCATION; - } - return index; - } - - /** - * Method to allocate memory to blocks according to the worst fit algorithm. It should return an - * ArrayList of Integers, where the index is the process ID (zero-indexed) and the value is the - * block number (also zero-indexed). - * - * @param sizeOfBlocks: an int array that contains the sizes of the memory blocks available. - * @param sizeOfProcesses: an int array that contains the sizes of the processes we need memory - * blocks for. - * @return the ArrayList filled with Integers repressenting the memory allocation that took place. - */ - static ArrayList worstFit(int[] sizeOfBlocks, int[] sizeOfProcesses) { - // The array list responsible for saving the memory allocations done by the worst-fit algorithm - ArrayList memAlloc = new ArrayList<>(); - // Do this for every process - for (int processSize : sizeOfProcesses) { - int chosenBlockIdx = - findWorstFit( - sizeOfBlocks, processSize); // Find the index of the memory block going to be used - memAlloc.add(chosenBlockIdx); // Store the chosen block index in the memAlloc array list - if (chosenBlockIdx - != NO_ALLOCATION) { // Only if a block was chosen to store the process in it, - sizeOfBlocks[chosenBlockIdx] -= processSize; // resize the block based on the process size - } - } - return memAlloc; - } - - /** - * Method to print the memory allocated. - * - * @param memAllocation: an ArrayList of Integer representing the memory allocation done by the - * worstFit method. - */ - public static void printMemoryAllocation(ArrayList memAllocation) { - System.out.println("Process No.\tBlock No."); - System.out.println("===========\t========="); - for (int i = 0; i < memAllocation.size(); i++) { - System.out.print(" " + i + "\t\t"); - if (memAllocation.get(i) != NO_ALLOCATION) System.out.print(memAllocation.get(i)); - else System.out.print("Not Allocated"); - System.out.println(); - } - } -} diff --git a/Searches/BinarySearch.java b/Searches/BinarySearch.java deleted file mode 100644 index 52e5cc998401..000000000000 --- a/Searches/BinarySearch.java +++ /dev/null @@ -1,92 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Arrays; -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.IntStream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * Binary search is one of the most popular algorithms The algorithm finds the position of a target - * value within a sorted array - * - *

Worst-case performance O(log n) Best-case performance O(1) Average performance O(log n) - * Worst-case space complexity O(1) - * - * @author Varun Upadhyay (https://github.com/varunu28) - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SearchAlgorithm - * @see IterativeBinarySearch - */ -class BinarySearch implements SearchAlgorithm { - - /** - * @param array is an array where the element should be found - * @param key is an element which should be found - * @param is any comparable type - * @return index of the element - */ - @Override - public > int find(T[] array, T key) { - return search(array, key, 0, array.length); - } - - /** - * This method implements the Generic Binary Search - * - * @param array The array to make the binary search - * @param key The number you are looking for - * @param left The lower bound - * @param right The upper bound - * @return the location of the key - */ - private > int search(T array[], T key, int left, int right) { - if (right < left) return -1; // this means that the key not found - - // find median - int median = (left + right) >>> 1; - int comp = key.compareTo(array[median]); - - if (comp == 0) { - return median; - } else if (comp < 0) { - return search(array, key, left, median - 1); - } else { - return search(array, key, median + 1, right); - } - } - - // Driver Program - public static void main(String[] args) { - // Just generate data - Random r = ThreadLocalRandom.current(); - - int size = 100; - int maxElement = 100000; - - Integer[] integers = - IntStream.generate(() -> r.nextInt(maxElement)) - .limit(size) - .sorted() - .boxed() - .toArray(Integer[]::new); - - // The element that should be found - int shouldBeFound = integers[r.nextInt(size - 1)]; - - BinarySearch search = new BinarySearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.println( - format( - "Should be found: %d. Found %d at index %d. An array length %d", - shouldBeFound, integers[atIndex], atIndex, size)); - - int toCheck = Arrays.binarySearch(integers, shouldBeFound); - System.out.println( - format( - "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); - } -} diff --git a/Searches/InterpolationSearch.java b/Searches/InterpolationSearch.java deleted file mode 100644 index 50e8686f6ddd..000000000000 --- a/Searches/InterpolationSearch.java +++ /dev/null @@ -1,70 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Arrays; -import java.util.Random; -import java.util.stream.IntStream; - -/** - * Interpolation search algorithm implementation - * - *

Worst-case performance O(n) Best-case performance O(1) Average performance O(log(log(n))) if - * the elements are uniformly distributed if not O(n) Worst-case space complexity O(1) - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - */ -class InterpolationSearch { - - /** - * @param array is a sorted array - * @param key is a value what shoulb be found in the array - * @return an index if the array contains the key unless -1 - */ - public int find(int array[], int key) { - // Find indexes of two corners - int start = 0, end = (array.length - 1); - - // Since array is sorted, an element present - // in array must be in range defined by corner - while (start <= end && key >= array[start] && key <= array[end]) { - // Probing the position with keeping - // uniform distribution in mind. - int pos = start + (((end - start) / (array[end] - array[start])) * (key - array[start])); - - // Condition of target found - if (array[pos] == key) return pos; - - // If key is larger, key is in upper part - if (array[pos] < key) start = pos + 1; - - // If key is smaller, x is in lower part - else end = pos - 1; - } - return -1; - } - - // Driver method - public static void main(String[] args) { - Random r = new Random(); - int size = 100; - int maxElement = 100000; - int[] integers = IntStream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(); - - // the element that should be found - Integer shouldBeFound = integers[r.nextInt(size - 1)]; - - InterpolationSearch search = new InterpolationSearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.println( - String.format( - "Should be found: %d. Found %d at index %d. An array length %d", - shouldBeFound, integers[atIndex], atIndex, size)); - - int toCheck = Arrays.binarySearch(integers, shouldBeFound); - System.out.println( - format( - "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); - } -} diff --git a/Searches/IterativeBinarySearch.java b/Searches/IterativeBinarySearch.java deleted file mode 100644 index 651f3bfa43d7..000000000000 --- a/Searches/IterativeBinarySearch.java +++ /dev/null @@ -1,80 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Arrays; -import java.util.Random; -import java.util.stream.Stream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * Binary search is one of the most popular algorithms This class represents iterative version - * {@link BinarySearch} Iterative binary search is likely to have lower constant factors because it - * doesn't involve the overhead of manipulating the call stack. But in java the recursive version - * can be optimized by the compiler to this version. - * - *

Worst-case performance O(log n) Best-case performance O(1) Average performance O(log n) - * Worst-case space complexity O(1) - * - * @author Gabriele La Greca : https://github.com/thegabriele97 - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SearchAlgorithm - * @see BinarySearch - */ -public final class IterativeBinarySearch implements SearchAlgorithm { - - /** - * This method implements an iterative version of binary search algorithm - * - * @param array a sorted array - * @param key the key to search in array - * @return the index of key in the array or -1 if not found - */ - @Override - public > int find(T[] array, T key) { - int l, r, k, cmp; - - l = 0; - r = array.length - 1; - - while (l <= r) { - k = (l + r) >>> 1; - cmp = key.compareTo(array[k]); - - if (cmp == 0) { - return k; - } else if (cmp < 0) { - r = --k; - } else { - l = ++k; - } - } - - return -1; - } - - // Only a main method for test purpose - public static void main(String[] args) { - Random r = new Random(); - int size = 100; - int maxElement = 100000; - Integer[] integers = - Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new); - - // the element that should be found - Integer shouldBeFound = integers[r.nextInt(size - 1)]; - - IterativeBinarySearch search = new IterativeBinarySearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.println( - String.format( - "Should be found: %d. Found %d at index %d. An array length %d", - shouldBeFound, integers[atIndex], atIndex, size)); - - int toCheck = Arrays.binarySearch(integers, shouldBeFound); - System.out.println( - format( - "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); - } -} diff --git a/Searches/IterativeTernarySearch.java b/Searches/IterativeTernarySearch.java deleted file mode 100644 index 92cefb9f1806..000000000000 --- a/Searches/IterativeTernarySearch.java +++ /dev/null @@ -1,75 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Arrays; -import java.util.Random; -import java.util.stream.Stream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * A iterative version of a ternary search algorithm This is better way to implement the ternary - * search, because a recursive version adds some overhead to a stack. But in java the compile can - * transform the recursive version to iterative implicitly, so there are no much differences between - * these two algorithms - * - *

Worst-case performance Θ(log3(N)) Best-case performance O(1) Average performance Θ(log3(N)) - * Worst-case space complexity O(1) - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SearchAlgorithm - * @see TernarySearch - * @since 2018-04-13 - */ -public class IterativeTernarySearch implements SearchAlgorithm { - - @Override - public > int find(T[] array, T key) { - int left = 0; - int right = array.length - 1; - - while (right > left) { - - int leftCmp = array[left].compareTo(key); - int rightCmp = array[right].compareTo(key); - if (leftCmp == 0) return left; - if (rightCmp == 0) return right; - - int leftThird = left + (right - left) / 3 + 1; - int rightThird = right - (right - left) / 3 - 1; - - if (array[leftThird].compareTo(key) <= 0) { - left = leftThird; - } else { - right = rightThird; - } - } - - return -1; - } - - public static void main(String[] args) { - // just generate data - Random r = new Random(); - int size = 100; - int maxElement = 100000; - Integer[] integers = - Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new); - - // the element that should be found - Integer shouldBeFound = integers[r.nextInt(size - 1)]; - - IterativeTernarySearch search = new IterativeTernarySearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.println( - format( - "Should be found: %d. Found %d at index %d. An array length %d", - shouldBeFound, integers[atIndex], atIndex, size)); - - int toCheck = Arrays.binarySearch(integers, shouldBeFound); - System.out.println( - format( - "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); - } -} diff --git a/Searches/JumpSearch.java b/Searches/JumpSearch.java deleted file mode 100644 index 9026180b3dc2..000000000000 --- a/Searches/JumpSearch.java +++ /dev/null @@ -1,42 +0,0 @@ -package Searches; - -import DevUtils.Searches.SearchAlgorithm; - -public class JumpSearch implements SearchAlgorithm { - - public static void main(String[] args) { - JumpSearch jumpSearch = new JumpSearch(); - Integer[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - for (int i = 0; i < array.length; i++) { - assert jumpSearch.find(array, i) == i; - } - assert jumpSearch.find(array, -1) == -1; - assert jumpSearch.find(array, 11) == -1; - } - - /** - * Jump Search algorithm implements - * - * @param array the array contains elements - * @param key to be searched - * @return index of {@code key} if found, otherwise -1 - */ - @Override - public > int find(T[] array, T key) { - int length = array.length; /* length of array */ - int blockSize = (int) Math.sqrt(length); /* block size to be jumped */ - - int limit = blockSize; - while (key.compareTo(array[limit]) > 0 && limit < array.length - 1) { - limit = Math.min(limit + blockSize, array.length - 1); - } - - for (int i = limit - blockSize; i <= limit; i++) { - if (array[i] == key) { - /* execute linear search */ - return i; - } - } - return -1; /* not found */ - } -} diff --git a/Searches/LinearSearch.java b/Searches/LinearSearch.java deleted file mode 100644 index bef0c3361617..000000000000 --- a/Searches/LinearSearch.java +++ /dev/null @@ -1,58 +0,0 @@ -package Searches; - -import java.util.Random; -import java.util.stream.Stream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * Linear search is the easiest search algorithm It works with sorted and unsorted arrays (an binary - * search works only with sorted array) This algorithm just compares all elements of an array to - * find a value - * - *

Worst-case performance O(n) Best-case performance O(1) Average performance O(n) Worst-case - * space complexity - * - * @author Varun Upadhyay (https://github.com/varunu28) - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see BinarySearch - * @see SearchAlgorithm - */ -public class LinearSearch implements SearchAlgorithm { - - /** - * Generic Linear search method - * - * @param array List to be searched - * @param value Key being searched for - * @return Location of the key - */ - @Override - public > int find(T[] array, T value) { - for (int i = 0; i < array.length; i++) { - if (array[i].compareTo(value) == 0) { - return i; - } - } - return -1; - } - - public static void main(String[] args) { - // just generate data - Random r = new Random(); - int size = 200; - int maxElement = 100; - Integer[] integers = - Stream.generate(() -> r.nextInt(maxElement)).limit(size).toArray(Integer[]::new); - - // the element that should be found - Integer shouldBeFound = integers[r.nextInt(size - 1)]; - - LinearSearch search = new LinearSearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.println( - String.format( - "Should be found: %d. Found %d at index %d. An array length %d", - shouldBeFound, integers[atIndex], atIndex, size)); - } -} diff --git a/Searches/LowerBound.java b/Searches/LowerBound.java deleted file mode 100644 index b18a2078112a..000000000000 --- a/Searches/LowerBound.java +++ /dev/null @@ -1,98 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.IntStream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * The LowerBound method is used to return an index pointing to the first element in the range - * [first, last) which has a value not less than val, i.e. the index of the next smallest number - * just greater than or equal to that number. If there are multiple values that are equal to val it - * returns the index of the first such value. - * - *

This is an extension of BinarySearch. - * - *

Worst-case performance O(log n) Best-case performance O(1) Average performance O(log n) - * Worst-case space complexity O(1) - * - * @author Pratik Padalia (https://github.com/15pratik) - * @see SearchAlgorithm - * @see BinarySearch - */ -class LowerBound implements SearchAlgorithm { - - // Driver Program - public static void main(String[] args) { - // Just generate data - Random r = ThreadLocalRandom.current(); - - int size = 100; - int maxElement = 100000; - - Integer[] integers = - IntStream.generate(() -> r.nextInt(maxElement)) - .limit(size) - .sorted() - .boxed() - .toArray(Integer[]::new); - - // The element for which the lower bound is to be found - int val = integers[r.nextInt(size - 1)] + 1; - - LowerBound search = new LowerBound(); - int atIndex = search.find(integers, val); - - System.out.println( - format( - "Val: %d. Lower Bound Found %d at index %d. An array length %d", - val, integers[atIndex], atIndex, size)); - - boolean toCheck = integers[atIndex] >= val || integers[size - 1] < val; - System.out.println( - format( - "Lower Bound found at an index: %d. Is greater or max element: %b", atIndex, toCheck)); - } - - /** - * @param array is an array where the LowerBound value is to be found - * @param key is an element for which the LowerBound is to be found - * @param is any comparable type - * @return index of the LowerBound element - */ - @Override - public > int find(T[] array, T key) { - return search(array, key, 0, array.length - 1); - } - - /** - * This method implements the Generic Binary Search - * - * @param array The array to make the binary search - * @param key The number you are looking for - * @param left The lower bound - * @param right The upper bound - * @return the location of the key - */ - private > int search(T[] array, T key, int left, int right) { - if (right <= left) { - return left; - } - - // find median - int median = (left + right) >>> 1; - int comp = key.compareTo(array[median]); - - if (comp == 0) { - return median; - } else if (comp < 0) { - // median position can be a possible solution - return search(array, key, left, median); - } else { - // key we are looking is greater, so we must look on the right of median position - return search(array, key, median + 1, right); - } - } -} diff --git a/Searches/PerfectBinarySearch.java b/Searches/PerfectBinarySearch.java deleted file mode 100644 index 3e72a9606203..000000000000 --- a/Searches/PerfectBinarySearch.java +++ /dev/null @@ -1,29 +0,0 @@ -package Searches; - -class PerfectBinarySearch { - - static int binarySearch(int[] arr, int target) { - int low = 0; - int high = arr.length - 1; - - while (low <= high) { - int mid = (low + high) / 2; - - if (arr[mid] == target) { - return mid; - } else if (arr[mid] > target) { - high = mid - 1; - } else { - low = mid + 1; - } - } - return -1; - } - - public static void main(String[] args) { - PerfectBinarySearch BinarySearch = new PerfectBinarySearch(); - int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - assert BinarySearch.binarySearch(array, -1) == -1; - assert BinarySearch.binarySearch(array, 11) == -1; - } -} diff --git a/Searches/SaddlebackSearch.java b/Searches/SaddlebackSearch.java deleted file mode 100644 index dca560566477..000000000000 --- a/Searches/SaddlebackSearch.java +++ /dev/null @@ -1,69 +0,0 @@ -package Searches; - -import java.util.Scanner; - -/** - * Program to perform Saddleback Search Given a sorted 2D array(elements are sorted across every row - * and column, assuming ascending order) of size n*m we can search a given element in O(n+m) - * - *

we start from bottom left corner if the current element is greater than the given element then - * we move up else we move right Sample Input: 5 5 ->Dimensions -10 -5 -3 4 9 -6 -2 0 5 10 -4 -1 1 6 - * 12 2 3 7 8 13 100 120 130 140 150 140 ->element to be searched output: 4 3 // first value is row, - * second one is column - * - * @author Nishita Aggarwal - */ -public class SaddlebackSearch { - - /** - * This method performs Saddleback Search - * - * @param arr The **Sorted** array in which we will search the element. - * @param row the current row. - * @param col the current column. - * @param key the element that we want to search for. - * @return The index(row and column) of the element if found. Else returns -1 -1. - */ - private static int[] find(int arr[][], int row, int col, int key) { - - // array to store the answer row and column - int ans[] = {-1, -1}; - if (row < 0 || col >= arr[row].length) { - return ans; - } - if (arr[row][col] == key) { - ans[0] = row; - ans[1] = col; - return ans; - } - // if the current element is greater than the given element then we move up - else if (arr[row][col] > key) { - return find(arr, row - 1, col, key); - } - // else we move right - return find(arr, row, col + 1, key); - } - - /** - * Main method - * - * @param args Command line arguments - */ - public static void main(String[] args) { - // TODO Auto-generated method stub - Scanner sc = new Scanner(System.in); - int arr[][]; - int i, j, rows = sc.nextInt(), col = sc.nextInt(); - arr = new int[rows][col]; - for (i = 0; i < rows; i++) { - for (j = 0; j < col; j++) { - arr[i][j] = sc.nextInt(); - } - } - int ele = sc.nextInt(); - // we start from bottom left corner - int ans[] = find(arr, rows - 1, 0, ele); - System.out.println(ans[0] + " " + ans[1]); - sc.close(); - } -} diff --git a/Searches/TernarySearch.java b/Searches/TernarySearch.java deleted file mode 100644 index e01c0ad7065f..000000000000 --- a/Searches/TernarySearch.java +++ /dev/null @@ -1,98 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Arrays; -import java.util.Random; -import java.util.stream.Stream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * A ternary search algorithm is a technique in computer science for finding the minimum or maximum - * of a unimodal function The algorithm determines either that the minimum or maximum cannot be in - * the first third of the domain or that it cannot be in the last third of the domain, then repeats - * on the remaining third. - * - *

Worst-case performance Θ(log3(N)) Best-case performance O(1) Average performance Θ(log3(N)) - * Worst-case space complexity O(1) - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SearchAlgorithm - * @see IterativeBinarySearch - */ -public class TernarySearch implements SearchAlgorithm { - - /** - * @param arr The **Sorted** array in which we will search the element. - * @param value The value that we want to search for. - * @return The index of the element if found. Else returns -1. - */ - @Override - public > int find(T[] arr, T value) { - return ternarySearch(arr, value, 0, arr.length - 1); - } - - /** - * @param arr The **Sorted** array in which we will search the element. - * @param key The value that we want to search for. - * @param start The starting index from which we will start Searching. - * @param end The ending index till which we will Search. - * @return Returns the index of the Element if found. Else returns -1. - */ - private > int ternarySearch(T[] arr, T key, int start, int end) { - if (start > end) { - return -1; - } - /* First boundary: add 1/3 of length to start */ - int mid1 = start + (end - start) / 3; - /* Second boundary: add 2/3 of length to start */ - int mid2 = start + 2 * (end - start) / 3; - - if (key.compareTo(arr[mid1]) == 0) { - return mid1; - } else if (key.compareTo(arr[mid2]) == 0) { - return mid2; - } - - /* Search the first (1/3) rd part of the array.*/ - - else if (key.compareTo(arr[mid1]) < 0) { - return ternarySearch(arr, key, start, --mid1); - } - /* Search 3rd (1/3)rd part of the array */ - - else if (key.compareTo(arr[mid2]) > 0) { - return ternarySearch(arr, key, ++mid2, end); - } - /* Search middle (1/3)rd part of the array */ - - else { - return ternarySearch(arr, key, mid1, mid2); - } - } - - public static void main(String[] args) { - // just generate data - Random r = new Random(); - int size = 100; - int maxElement = 100000; - Integer[] integers = - Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new); - - // the element that should be found - Integer shouldBeFound = integers[r.nextInt(size - 1)]; - - TernarySearch search = new TernarySearch(); - int atIndex = search.find(integers, shouldBeFound); - - System.out.println( - format( - "Should be found: %d. Found %d at index %d. An array length %d", - shouldBeFound, integers[atIndex], atIndex, size)); - - int toCheck = Arrays.binarySearch(integers, shouldBeFound); - System.out.println( - format( - "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); - } -} diff --git a/Searches/UpperBound.java b/Searches/UpperBound.java deleted file mode 100644 index 106a37af1c94..000000000000 --- a/Searches/UpperBound.java +++ /dev/null @@ -1,96 +0,0 @@ -package Searches; - -import static java.lang.String.format; - -import java.util.Random; -import java.util.concurrent.ThreadLocalRandom; -import java.util.stream.IntStream; -import DevUtils.Searches.SearchAlgorithm; - -/** - * The UpperBound method is used to return an index pointing to the first element in the range - * [first, last) which has a value greater than val, or the last index if no such element exists - * i.e. the index of the next smallest number just greater than that number. If there are multiple - * values that are equal to val it returns the index of the first such value. - * - *

This is an extension of BinarySearch. - * - *

Worst-case performance O(log n) Best-case performance O(1) Average performance O(log n) - * Worst-case space complexity O(1) - * - * @author Pratik Padalia (https://github.com/15pratik) - * @see SearchAlgorithm - * @see BinarySearch - */ -class UpperBound implements SearchAlgorithm { - - // Driver Program - public static void main(String[] args) { - // Just generate data - Random r = ThreadLocalRandom.current(); - - int size = 100; - int maxElement = 100000; - - Integer[] integers = - IntStream.generate(() -> r.nextInt(maxElement)) - .limit(size) - .sorted() - .boxed() - .toArray(Integer[]::new); - - // The element for which the upper bound is to be found - int val = integers[r.nextInt(size - 1)] + 1; - - UpperBound search = new UpperBound(); - int atIndex = search.find(integers, val); - - System.out.println( - format( - "Val: %d. Upper Bound Found %d at index %d. An array length %d", - val, integers[atIndex], atIndex, size)); - - boolean toCheck = integers[atIndex] > val || integers[size - 1] < val; - System.out.println( - format( - "Upper Bound found at an index: %d. Is greater or max element: %b", atIndex, toCheck)); - } - - /** - * @param array is an array where the UpperBound value is to be found - * @param key is an element for which the UpperBound is to be found - * @param is any comparable type - * @return index of the UpperBound element - */ - @Override - public > int find(T[] array, T key) { - return search(array, key, 0, array.length - 1); - } - - /** - * This method implements the Generic Binary Search - * - * @param array The array to make the binary search - * @param key The number you are looking for - * @param left The lower bound - * @param right The upper bound - * @return the location of the key - */ - private > int search(T[] array, T key, int left, int right) { - if (right <= left) { - return left; - } - - // find median - int median = (left + right) >>> 1; - int comp = key.compareTo(array[median]); - - if (comp < 0) { - // key is smaller, median position can be a possible solution - return search(array, key, left, median); - } else { - // key we are looking is greater, so we must look on the right of median position - return search(array, key, median + 1, right); - } - } -} diff --git a/Sorts/BitonicSort.java b/Sorts/BitonicSort.java deleted file mode 100644 index e75ef118a377..000000000000 --- a/Sorts/BitonicSort.java +++ /dev/null @@ -1,74 +0,0 @@ -package Sorts; - -/* Java program for Bitonic Sort. Note that this program -works only when size of input is a power of 2. */ -public class BitonicSort { - /* The parameter dir indicates the sorting direction, - ASCENDING or DESCENDING; if (a[i] > a[j]) agrees - with the direction, then a[i] and a[j] are - interchanged. */ - void compAndSwap(int a[], int i, int j, int dir) { - if ((a[i] > a[j] && dir == 1) || (a[i] < a[j] && dir == 0)) { - // Swapping elements - int temp = a[i]; - a[i] = a[j]; - a[j] = temp; - } - } - - /* It recursively sorts a bitonic sequence in ascending - order, if dir = 1, and in descending order otherwise - (means dir=0). The sequence to be sorted starts at - index position low, the parameter cnt is the number - of elements to be sorted.*/ - void bitonicMerge(int a[], int low, int cnt, int dir) { - if (cnt > 1) { - int k = cnt / 2; - for (int i = low; i < low + k; i++) compAndSwap(a, i, i + k, dir); - bitonicMerge(a, low, k, dir); - bitonicMerge(a, low + k, k, dir); - } - } - - /* This funcion first produces a bitonic sequence by - recursively sorting its two halves in opposite sorting - orders, and then calls bitonicMerge to make them in - the same order */ - void bitonicSort(int a[], int low, int cnt, int dir) { - if (cnt > 1) { - int k = cnt / 2; - - // sort in ascending order since dir here is 1 - bitonicSort(a, low, k, 1); - - // sort in descending order since dir here is 0 - bitonicSort(a, low + k, k, 0); - - // Will merge whole sequence in ascending order - // since dir=1. - bitonicMerge(a, low, cnt, dir); - } - } - - /*Caller of bitonicSort for sorting the entire array - of length N in ASCENDING order */ - void sort(int a[], int N, int up) { - bitonicSort(a, 0, N, up); - } - - /* A utility function to print array of size n */ - static void printArray(int arr[]) { - int n = arr.length; - for (int i = 0; i < n; ++i) System.out.print(arr[i] + " "); - System.out.println(); - } - - public static void main(String args[]) { - int a[] = {3, 7, 4, 8, 6, 2, 1, 5}; - int up = 1; - BitonicSort ob = new BitonicSort(); - ob.sort(a, a.length, up); - System.out.println("\nSorted array"); - printArray(a); - } -} diff --git a/Sorts/BogoSort.java b/Sorts/BogoSort.java deleted file mode 100644 index fc746480f235..000000000000 --- a/Sorts/BogoSort.java +++ /dev/null @@ -1,52 +0,0 @@ -package Sorts; - -import java.util.Random; - -/** - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SortAlgorithm - */ -public class BogoSort implements SortAlgorithm { - - private static final Random random = new Random(); - - private static > boolean isSorted(T[] array) { - for (int i = 0; i < array.length - 1; i++) { - if (SortUtils.less(array[i + 1], array[i])) return false; - } - return true; - } - - // Randomly shuffles the array - private static void nextPermutation(T[] array) { - int length = array.length; - - for (int i = 0; i < array.length; i++) { - int randomIndex = i + random.nextInt(length - i); - SortUtils.swap(array, randomIndex, i); - } - } - - public > T[] sort(T[] array) { - while (!isSorted(array)) { - nextPermutation(array); - } - return array; - } - - // Driver Program - public static void main(String[] args) { - // Integer Input - Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - - BogoSort bogoSort = new BogoSort(); - - // print a sorted array - SortUtils.print(bogoSort.sort(integers)); - - // String Input - String[] strings = {"c", "a", "e", "b", "d"}; - - SortUtils.print(bogoSort.sort(strings)); - } -} diff --git a/Sorts/BubbleSort.java b/Sorts/BubbleSort.java deleted file mode 100644 index 7fd6afc50a28..000000000000 --- a/Sorts/BubbleSort.java +++ /dev/null @@ -1,55 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.*; - -/** - * @author Varun Upadhyay (https://github.com/varunu28) - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SortAlgorithm - */ -class BubbleSort implements SortAlgorithm { - - /** - * Implements generic bubble sort algorithm. - * - * @param array the array to be sorted. - * @param the type of elements in the array. - * @return the sorted array. - */ - @Override - public > T[] sort(T[] array) { - for (int i = 1, size = array.length; i < size; ++i) { - boolean swapped = false; - for (int j = 0; j < size - i; ++j) { - if (greater(array[j], array[j + 1])) { - swap(array, j, j + 1); - swapped = true; - } - } - if (!swapped) { - break; - } - } - return array; - } - - /** Driver Code */ - public static void main(String[] args) { - - Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - BubbleSort bubbleSort = new BubbleSort(); - bubbleSort.sort(integers); - - for (int i = 0; i < integers.length - 1; ++i) { - assert integers[i] <= integers[i + 1]; - } - print(integers); /* output: [1, 4, 6, 9, 12, 23, 54, 78, 231] */ - - String[] strings = {"c", "a", "e", "b", "d"}; - bubbleSort.sort(strings); - for (int i = 0; i < strings.length - 1; i++) { - assert strings[i].compareTo(strings[i + 1]) <= 0; - } - print(bubbleSort.sort(strings)); /* output: [a, b, c, d, e] */ - } -} diff --git a/Sorts/BubbleSortRecursion.java b/Sorts/BubbleSortRecursion.java deleted file mode 100644 index ce51b1bfe29c..000000000000 --- a/Sorts/BubbleSortRecursion.java +++ /dev/null @@ -1,53 +0,0 @@ -package Sorts; - -import java.util.Random; - -/** BubbleSort algorithm implements using recursion */ -public class BubbleSortRecursion implements SortAlgorithm { - public static void main(String[] args) { - Integer[] array = new Integer[10]; - - Random random = new Random(); - /* generate 10 random numbers from -50 to 49 */ - for (int i = 0; i < array.length; ++i) { - array[i] = random.nextInt(100) - 50; - } - - BubbleSortRecursion bubbleSortRecursion = new BubbleSortRecursion(); - bubbleSortRecursion.sort(array); - - /* check array is sorted or not */ - for (int i = 0; i < array.length - 1; ++i) { - assert (array[i].compareTo(array[i + 1]) <= 0); - } - } - - /** - * @param unsorted - an array should be sorted - * @return sorted array - */ - @Override - public > T[] sort(T[] unsorted) { - bubbleSort(unsorted, unsorted.length); - return unsorted; - } - - /** - * BubbleSort algorithm implements using recursion - * - * @param unsorted array contains elements - * @param len length of given array - */ - private static > void bubbleSort(T[] unsorted, int len) { - boolean swapped = false; /* flag to check if array is sorted or not */ - for (int i = 0; i < len - 1; ++i) { - if (SortUtils.greater(unsorted[i], unsorted[i + 1])) { - SortUtils.swap(unsorted, i, i + 1); - swapped = true; - } - } - if (swapped) { - bubbleSort(unsorted, len - 1); - } - } -} diff --git a/Sorts/BucketSort.java b/Sorts/BucketSort.java deleted file mode 100644 index 66795f7f3c89..000000000000 --- a/Sorts/BucketSort.java +++ /dev/null @@ -1,112 +0,0 @@ -package Sorts; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Random; - -/** Wikipedia: https://en.wikipedia.org/wiki/Bucket_sort */ -public class BucketSort { - public static void main(String[] args) { - int[] arr = new int[10]; - - /* generate 10 random numbers from -50 to 49 */ - Random random = new Random(); - for (int i = 0; i < arr.length; ++i) { - arr[i] = random.nextInt(100) - 50; - } - - bucketSort(arr); - - /* check array is sorted or not */ - for (int i = 0, limit = arr.length - 1; i < limit; ++i) { - assert arr[i] <= arr[i + 1]; - } - } - - /** - * BucketSort algorithms implements - * - * @param arr the array contains elements - */ - private static void bucketSort(int[] arr) { - /* get max value of arr */ - int max = max(arr); - - /* get min value of arr */ - int min = min(arr); - - /* number of buckets */ - int numberOfBuckets = max - min + 1; - - List> buckets = new ArrayList<>(numberOfBuckets); - - /* init buckets */ - for (int i = 0; i < numberOfBuckets; ++i) { - buckets.add(new ArrayList<>()); - } - - /* store elements to buckets */ - for (int value : arr) { - int hash = hash(value, min, numberOfBuckets); - buckets.get(hash).add(value); - } - - /* sort individual bucket */ - for (List bucket : buckets) { - Collections.sort(bucket); - } - - /* concatenate buckets to origin array */ - int index = 0; - for (List bucket : buckets) { - for (int value : bucket) { - arr[index++] = value; - } - } - } - - /** - * Get index of bucket which of our elements gets placed into it. - * - * @param elem the element of array to be sorted - * @param min min value of array - * @param numberOfBucket the number of bucket - * @return index of bucket - */ - private static int hash(int elem, int min, int numberOfBucket) { - return (elem - min) / numberOfBucket; - } - - /** - * Calculate max value of array - * - * @param arr the array contains elements - * @return max value of given array - */ - public static int max(int[] arr) { - int max = arr[0]; - for (int value : arr) { - if (value > max) { - max = value; - } - } - return max; - } - - /** - * Calculate min value of array - * - * @param arr the array contains elements - * @return min value of given array - */ - public static int min(int[] arr) { - int min = arr[0]; - for (int value : arr) { - if (value < min) { - min = value; - } - } - return min; - } -} diff --git a/Sorts/CocktailShakerSort.java b/Sorts/CocktailShakerSort.java deleted file mode 100644 index 12f1e4f38e6b..000000000000 --- a/Sorts/CocktailShakerSort.java +++ /dev/null @@ -1,57 +0,0 @@ -package Sorts; - -/** - * @author Mateus Bizzo (https://github.com/MattBizzo) - * @author Podshivalov Nikita (https://github.com/nikitap492) - */ -class CocktailShakerSort implements SortAlgorithm { - - /** - * This method implements the Generic Cocktail Shaker Sort - * - * @param array The array to be sorted Sorts the array in increasing order - */ - @Override - public > T[] sort(T[] array) { - - int length = array.length; - int left = 0; - int right = length - 1; - int swappedLeft, swappedRight; - while (left < right) { - // front - swappedRight = 0; - for (int i = left; i < right; i++) { - if (SortUtils.less(array[i + 1], array[i])) { - SortUtils.swap(array, i, i + 1); - swappedRight = i; - } - } - // back - right = swappedRight; - swappedLeft = length - 1; - for (int j = right; j > left; j--) { - if (SortUtils.less(array[j], array[j - 1])) { - SortUtils.swap(array, j - 1, j); - swappedLeft = j; - } - } - left = swappedLeft; - } - return array; - } - - // Driver Program - public static void main(String[] args) { - // Integer Input - Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - CocktailShakerSort shakerSort = new CocktailShakerSort(); - - // Output => 1 4 6 9 12 23 54 78 231 - SortUtils.print(shakerSort.sort(integers)); - - // String Input - String[] strings = {"c", "a", "e", "b", "d"}; - SortUtils.print(shakerSort.sort(strings)); - } -} diff --git a/Sorts/CombSort.java b/Sorts/CombSort.java deleted file mode 100644 index 44afb3c288aa..000000000000 --- a/Sorts/CombSort.java +++ /dev/null @@ -1,71 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.*; - -/** - * Comb Sort algorithm implementation - * - *

Best-case performance O(n * log(n)) Worst-case performance O(n ^ 2) Worst-case space - * complexity O(1) - * - *

Comb sort improves on bubble sort. - * - * @author Sandeep Roy (https://github.com/sandeeproy99) - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see BubbleSort - * @see SortAlgorithm - */ -class CombSort implements SortAlgorithm { - - // To find gap between elements - private int nextGap(int gap) { - // Shrink gap by Shrink factor - gap = (gap * 10) / 13; - return (gap < 1) ? 1 : gap; - } - - /** - * Function to sort arr[] using Comb - * - * @param arr - an array should be sorted - * @return sorted array - */ - @Override - public > T[] sort(T[] arr) { - int size = arr.length; - - // initialize gap - int gap = size; - - // Initialize swapped as true to make sure that loop runs - boolean swapped = true; - - // Keep running while gap is more than 1 and last iteration caused a swap - while (gap != 1 || swapped) { - // Find next gap - gap = nextGap(gap); - - // Initialize swapped as false so that we can check if swap happened or not - swapped = false; - - // Compare all elements with current gap - for (int i = 0; i < size - gap; i++) { - if (less(arr[i + gap], arr[i])) { - // Swap arr[i] and arr[i+gap] - swapped = swap(arr, i, i + gap); - } - } - } - return arr; - } - - // Driver method - public static void main(String[] args) { - CombSort ob = new CombSort(); - Integer[] arr = {8, 4, 1, 56, 3, -44, -1, 0, 36, 34, 8, 12, -66, -78, 23, -6, 28, 0}; - ob.sort(arr); - - System.out.println("sorted array"); - print(arr); - } -} diff --git a/Sorts/CountingSort.java b/Sorts/CountingSort.java deleted file mode 100644 index 37a6c4e3a7a5..000000000000 --- a/Sorts/CountingSort.java +++ /dev/null @@ -1,96 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.print; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; - -import java.util.*; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -/** - * @author Youssef Ali (https://github.com/youssefAli11997) - * @author Podshivalov Nikita (https://github.com/nikitap492) - */ -class CountingSort implements SortAlgorithm { - - @Override - public > T[] sort(T[] unsorted) { - return sort(Arrays.asList(unsorted)).toArray(unsorted); - } - - /** - * This method implements the Generic Counting Sort - * - * @param list The list to be sorted - *

Sorts the list in increasing order The method uses list elements as keys in the - * frequency map - */ - @Override - public > List sort(List list) { - - Map frequency = new TreeMap<>(); - // The final output array - List sortedArray = new ArrayList<>(list.size()); - - // Counting the frequency of @param array elements - list.forEach(v -> frequency.put(v, frequency.getOrDefault(v, 0) + 1)); - - // Filling the sortedArray - for (Map.Entry element : frequency.entrySet()) { - for (int j = 0; j < element.getValue(); j++) { - sortedArray.add(element.getKey()); - } - } - - return sortedArray; - } - - /** - * Stream Counting Sort The same as method {@link CountingSort#sort(List)} } but this method uses - * stream API - * - * @param list The list to be sorted - */ - private static > List streamSort(List list) { - return list.stream() - .collect(toMap(k -> k, v -> 1, (v1, v2) -> v1 + v2, TreeMap::new)) - .entrySet() - .stream() - .flatMap(entry -> IntStream.rangeClosed(1, entry.getValue()).mapToObj(t -> entry.getKey())) - .collect(toList()); - } - - // Driver Program - public static void main(String[] args) { - // Integer Input - List unsortedInts = - Stream.of(4, 23, 6, 78, 1, 54, 23, 1, 9, 231, 9, 12).collect(toList()); - CountingSort countingSort = new CountingSort(); - - System.out.println("Before Sorting:"); - print(unsortedInts); - - // Output => 1 1 4 6 9 9 12 23 23 54 78 231 - System.out.println("After Sorting:"); - print(countingSort.sort(unsortedInts)); - System.out.println("After Sorting By Streams:"); - print(streamSort(unsortedInts)); - - System.out.println("\n------------------------------\n"); - - // String Input - List unsortedStrings = - Stream.of("c", "a", "e", "b", "d", "a", "f", "g", "c").collect(toList()); - - System.out.println("Before Sorting:"); - print(unsortedStrings); - - // Output => a a b c c d e f g - System.out.println("After Sorting:"); - print(countingSort.sort(unsortedStrings)); - - System.out.println("After Sorting By Streams:"); - print(streamSort(unsortedStrings)); - } -} diff --git a/Sorts/CycleSort.java b/Sorts/CycleSort.java deleted file mode 100644 index 20543665ea14..000000000000 --- a/Sorts/CycleSort.java +++ /dev/null @@ -1,71 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.less; -import static Sorts.SortUtils.print; - -/** @author Podshivalov Nikita (https://github.com/nikitap492) */ -class CycleSort implements SortAlgorithm { - - @Override - public > T[] sort(T[] arr) { - int n = arr.length; - - // traverse array elements - for (int j = 0; j <= n - 2; j++) { - // initialize item as starting point - T item = arr[j]; - - // Find position where we put the item. - int pos = j; - for (int i = j + 1; i < n; i++) if (less(arr[i], item)) pos++; - - // If item is already in correct position - if (pos == j) continue; - - // ignore all duplicate elements - while (item.compareTo(arr[pos]) == 0) pos += 1; - - // put the item to it's right position - if (pos != j) { - item = replace(arr, pos, item); - } - - // Rotate rest of the cycle - while (pos != j) { - pos = j; - - // Find position where we put the element - for (int i = j + 1; i < n; i++) - if (less(arr[i], item)) { - pos += 1; - } - - // ignore all duplicate elements - while (item.compareTo(arr[pos]) == 0) pos += 1; - - // put the item to it's right position - if (item != arr[pos]) { - item = replace(arr, pos, item); - } - } - } - - return arr; - } - - private > T replace(T[] arr, int pos, T item) { - T temp = item; - item = arr[pos]; - arr[pos] = temp; - return item; - } - - public static void main(String[] args) { - Integer arr[] = {4, 23, 6, 78, 1, 26, 11, 23, 0, -6, 3, 54, 231, 9, 12}; - CycleSort cycleSort = new CycleSort(); - cycleSort.sort(arr); - - System.out.println("After sort : "); - print(arr); - } -} diff --git a/Sorts/GnomeSort.java b/Sorts/GnomeSort.java deleted file mode 100644 index 3bf7213b38eb..000000000000 --- a/Sorts/GnomeSort.java +++ /dev/null @@ -1,42 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.*; - -/** - * Implementation of gnome sort - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @since 2018-04-10 - */ -public class GnomeSort implements SortAlgorithm { - - @Override - public > T[] sort(T[] arr) { - int i = 1; - int j = 2; - while (i < arr.length) { - if (less(arr[i - 1], arr[i])) i = j++; - else { - swap(arr, i - 1, i); - if (--i == 0) { - i = j++; - } - } - } - - return null; - } - - public static void main(String[] args) { - Integer[] integers = {4, 23, 6, 78, 1, 26, 11, 23, 0, -6, 3, 54, 231, 9, 12}; - String[] strings = {"c", "a", "e", "b", "d", "dd", "da", "zz", "AA", "aa", "aB", "Hb", "Z"}; - GnomeSort gnomeSort = new GnomeSort(); - - gnomeSort.sort(integers); - gnomeSort.sort(strings); - - System.out.println("After sort : "); - print(integers); - print(strings); - } -} diff --git a/Sorts/HeapSort.java b/Sorts/HeapSort.java deleted file mode 100644 index 29f14bab658e..000000000000 --- a/Sorts/HeapSort.java +++ /dev/null @@ -1,121 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.*; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * Heap Sort Algorithm Implements MinHeap - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - */ -public class HeapSort implements SortAlgorithm { - - private static class Heap> { - /** Array to store heap */ - private T[] heap; - - /** - * Constructor - * - * @param heap array of unordered integers - */ - public Heap(T[] heap) { - this.heap = heap; - } - - /** - * Heapifies subtree from top as root to last as last child - * - * @param rootIndex index of root - * @param lastChild index of last child - */ - private void heapSubtree(int rootIndex, int lastChild) { - int leftIndex = rootIndex * 2 + 1; - int rightIndex = rootIndex * 2 + 2; - T root = heap[rootIndex]; - if (rightIndex <= lastChild) { // if has right and left children - T left = heap[leftIndex]; - T right = heap[rightIndex]; - if (less(left, right) && less(left, root)) { - swap(heap, leftIndex, rootIndex); - heapSubtree(leftIndex, lastChild); - } else if (less(right, root)) { - swap(heap, rightIndex, rootIndex); - heapSubtree(rightIndex, lastChild); - } - } else if (leftIndex <= lastChild) { // if no right child, but has left child - T left = heap[leftIndex]; - if (less(left, root)) { - swap(heap, leftIndex, rootIndex); - heapSubtree(leftIndex, lastChild); - } - } - } - - /** - * Makes heap with root as root - * - * @param root index of root of heap - */ - private void makeMinHeap(int root) { - int leftIndex = root * 2 + 1; - int rightIndex = root * 2 + 2; - boolean hasLeftChild = leftIndex < heap.length; - boolean hasRightChild = rightIndex < heap.length; - if (hasRightChild) { // if has left and right - makeMinHeap(leftIndex); - makeMinHeap(rightIndex); - heapSubtree(root, heap.length - 1); - } else if (hasLeftChild) { - heapSubtree(root, heap.length - 1); - } - } - - /** - * Gets the root of heap - * - * @return root of heap - */ - private T getRoot(int size) { - swap(heap, 0, size); - heapSubtree(0, size - 1); - return heap[size]; // return old root - } - } - - @Override - public > T[] sort(T[] unsorted) { - return sort(Arrays.asList(unsorted)).toArray(unsorted); - } - - @Override - public > List sort(List unsorted) { - int size = unsorted.size(); - - @SuppressWarnings("unchecked") - Heap heap = new Heap<>(unsorted.toArray((T[]) new Comparable[unsorted.size()])); - - heap.makeMinHeap(0); // make min heap using index 0 as root. - List sorted = new ArrayList<>(size); - while (size > 0) { - T min = heap.getRoot(--size); - sorted.add(min); - } - - return sorted; - } - - /** - * Main method - * - * @param args the command line arguments - */ - public static void main(String[] args) { - Integer[] heap = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - HeapSort heapSort = new HeapSort(); - print(heapSort.sort(heap)); - } -} diff --git a/Sorts/InsertionSort.java b/Sorts/InsertionSort.java deleted file mode 100644 index 2114067ab692..000000000000 --- a/Sorts/InsertionSort.java +++ /dev/null @@ -1,41 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.less; -import static Sorts.SortUtils.print; - -class InsertionSort implements SortAlgorithm { - - /** - * Generic insertion sort algorithm in increasing order. - * - * @param array the array to be sorted. - * @param the class of array. - * @return sorted array. - */ - @Override - public > T[] sort(T[] array) { - for (int i = 1; i < array.length; i++) { - T insertValue = array[i]; - int j; - for (j = i - 1; j >= 0 && less(insertValue, array[j]); j--) { - array[j + 1] = array[j]; - } - if (j != i - 1) { - array[j + 1] = insertValue; - } - } - return array; - } - - /** Driver Code */ - public static void main(String[] args) { - Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - InsertionSort sort = new InsertionSort(); - sort.sort(integers); - print(integers); /* [1, 4, 6, 9, 12, 23, 54, 78, 231] */ - - String[] strings = {"c", "a", "e", "b", "d"}; - sort.sort(strings); - print(strings); /* [a, b, c, d, e] */ - } -} diff --git a/Sorts/MergeSort.java b/Sorts/MergeSort.java deleted file mode 100644 index 57892bc6bc46..000000000000 --- a/Sorts/MergeSort.java +++ /dev/null @@ -1,88 +0,0 @@ -package Sorts; - -/** - * Generic merge sort algorithm. - * - * @see SortAlgorithm - */ -class MergeSort implements SortAlgorithm { - - /** - * Generic merge sort algorithm implements. - * - * @param unsorted the array which should be sorted. - * @param Comparable class. - * @return sorted array. - */ - @Override - public > T[] sort(T[] unsorted) { - doSort(unsorted, 0, unsorted.length - 1); - return unsorted; - } - - /** - * @param arr the array to be sorted. - * @param left the first index of the array. - * @param right the last index of the array. - */ - private static > void doSort(T[] arr, int left, int right) { - if (left < right) { - int mid = (left + right) >>> 1; - doSort(arr, left, mid); - doSort(arr, mid + 1, right); - merge(arr, left, mid, right); - } - } - - /** - * Merges two parts of an array. - * - * @param arr the array to be merged. - * @param left the first index of the array. - * @param mid the middle index of the array. - * @param right the last index of the array merges two parts of an array in increasing order. - */ - private static > void merge(T[] arr, int left, int mid, int right) { - int length = right - left + 1; - @SuppressWarnings("unchecked") - T[] temp = (T[]) new Comparable[length]; - int i = left; - int j = mid + 1; - int k = 0; - - while (i <= mid && j <= right) { - if (arr[i].compareTo(arr[j]) <= 0) { - temp[k++] = arr[i++]; - } else { - temp[k++] = arr[j++]; - } - } - - while (i <= mid) { - temp[k++] = arr[i++]; - } - - while (j <= right) { - temp[k++] = arr[j++]; - } - - System.arraycopy(temp, 0, arr, left, length); - } - - /** Driver code */ - public static void main(String[] args) { - MergeSort mergeSort = new MergeSort(); - - Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - mergeSort.sort(arr); - for (int i = 0; i < arr.length - 1; ++i) { - assert arr[i] <= arr[i + 1]; - } - - String[] stringArray = {"c", "a", "e", "b", "d"}; - mergeSort.sort(stringArray); - for (int i = 0; i < stringArray.length - 1; ++i) { - assert arr[i].compareTo(arr[i + 1]) <= 0; - } - } -} diff --git a/Sorts/MergeSortNoExtraSpace.java b/Sorts/MergeSortNoExtraSpace.java deleted file mode 100644 index 282082ece03b..000000000000 --- a/Sorts/MergeSortNoExtraSpace.java +++ /dev/null @@ -1,75 +0,0 @@ -package Sorts; -import java.util.Arrays; -import java.util.*; - -/*This code implements the mergeSort algorithm without extra space -For understanding about mergesort visit :https://www.geeksforgeeks.org/merge-sort/ - */ -public class MergeSortNoExtraSpace { - public static void call_merge_sort(int a[],int n) - { - int maxele = Arrays.stream(a).max().getAsInt() + 1; - merge_sort(a,0,n-1,maxele); - } - public static void merge_sort(int a[],int start , int end,int maxele){ //this function divides the array into 2 halves - - if(start> T[] sort(T[] array) { - int size = array.length; - - for (int i = 0; i < size; i++) { - T max = array[0]; - int index = 0; - for (int j = 0; j < size - i; j++) { - if (less(max, array[j])) { - max = array[j]; - index = j; - } - } - flip(array, index, array.length - 1 - i); - } - return array; - } - - public static void main(String[] args) { - - Integer[] arr = { - 10, 9, 8, 7, 6, 15, 14, 7, 4, 3, 8, 6, 3, 1, 2, -2, -5, -8, -3, -1, 13, 12, 11, 5, 4, 3, 2, 1 - }; - PancakeSort pancakeSort = new PancakeSort(); - System.out.println("After sorting:"); - pancakeSort.sort(arr); - print(arr); - } -} diff --git a/Sorts/QuickSort.java b/Sorts/QuickSort.java deleted file mode 100644 index b88b1dec5ce4..000000000000 --- a/Sorts/QuickSort.java +++ /dev/null @@ -1,97 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.*; - -/** - * @author Varun Upadhyay (https://github.com/varunu28) - * @author Podshivalov Nikita (https://github.com/nikitap492) - * @see SortAlgorithm - */ -class QuickSort implements SortAlgorithm { - - /** - * This method implements the Generic Quick Sort - * - * @param array The array to be sorted Sorts the array in increasing order - */ - @Override - public > T[] sort(T[] array) { - doSort(array, 0, array.length - 1); - return array; - } - - /** - * The sorting process - * - * @param left The first index of an array - * @param right The last index of an array - * @param array The array to be sorted - */ - private static > void doSort(T[] array, int left, int right) { - if (left < right) { - int pivot = randomPartition(array, left, right); - doSort(array, left, pivot - 1); - doSort(array, pivot, right); - } - } - - /** - * Ramdomize the array to avoid the basically ordered sequences - * - * @param array The array to be sorted - * @param left The first index of an array - * @param right The last index of an array - * @return the partition index of the array - */ - private static > int randomPartition(T[] array, int left, int right) { - int randomIndex = left + (int) (Math.random() * (right - left + 1)); - swap(array, randomIndex, right); - return partition(array, left, right); - } - - /** - * This method finds the partition index for an array - * - * @param array The array to be sorted - * @param left The first index of an array - * @param right The last index of an array Finds the partition index of an array - */ - private static > int partition(T[] array, int left, int right) { - int mid = (left + right) >>> 1; - T pivot = array[mid]; - - while (left <= right) { - while (less(array[left], pivot)) { - ++left; - } - while (less(pivot, array[right])) { - --right; - } - if (left <= right) { - swap(array, left, right); - ++left; - --right; - } - } - return left; - } - - // Driver Program - public static void main(String[] args) { - - // For integer input - Integer[] array = {3, 4, 1, 32, 0, 1, 5, 12, 2, 5, 7, 8, 9, 2, 44, 111, 5}; - - QuickSort quickSort = new QuickSort(); - quickSort.sort(array); - - // Output => 0 1 1 2 2 3 4 5 5 5 7 8 9 12 32 44 111 - print(array); - - String[] stringArray = {"c", "a", "e", "b", "d"}; - quickSort.sort(stringArray); - - // Output => a b c d e - print(stringArray); - } -} diff --git a/Sorts/RadixSort.java b/Sorts/RadixSort.java deleted file mode 100644 index 83515fc03bb2..000000000000 --- a/Sorts/RadixSort.java +++ /dev/null @@ -1,49 +0,0 @@ -package Sorts; - -import java.util.Arrays; - -class RadixSort { - - private static int getMax(int[] arr, int n) { - int mx = arr[0]; - for (int i = 1; i < n; i++) if (arr[i] > mx) mx = arr[i]; - return mx; - } - - private static void countSort(int[] arr, int n, int exp) { - int[] output = new int[n]; - int i; - int[] count = new int[10]; - Arrays.fill(count, 0); - - for (i = 0; i < n; i++) count[(arr[i] / exp) % 10]++; - - for (i = 1; i < 10; i++) count[i] += count[i - 1]; - - for (i = n - 1; i >= 0; i--) { - output[count[(arr[i] / exp) % 10] - 1] = arr[i]; - count[(arr[i] / exp) % 10]--; - } - - for (i = 0; i < n; i++) arr[i] = output[i]; - } - - private static void radixsort(int[] arr, int n) { - - int m = getMax(arr, n); - - for (int exp = 1; m / exp > 0; exp *= 10) countSort(arr, n, exp); - } - - static void print(int[] arr, int n) { - for (int i = 0; i < n; i++) System.out.print(arr[i] + " "); - } - - public static void main(String[] args) { - int[] arr = {170, 45, 75, 90, 802, 24, 2, 66}; - int n = arr.length; - radixsort(arr, n); - print(arr, n); - } -} -// Written by James Mc Dermott(theycallmemac) diff --git a/Sorts/SelectionSort.java b/Sorts/SelectionSort.java deleted file mode 100644 index df0e4767231f..000000000000 --- a/Sorts/SelectionSort.java +++ /dev/null @@ -1,47 +0,0 @@ -package Sorts; - -public class SelectionSort implements SortAlgorithm { - - /** - * Generic selection sort algorithm in increasing order. - * - * @param arr the array to be sorted. - * @param the class of array. - * @return sorted array. - */ - @Override - public > T[] sort(T[] arr) { - int n = arr.length; - for (int i = 0; i < n - 1; i++) { - int minIndex = i; - for (int j = i + 1; j < n; j++) { - if (arr[minIndex].compareTo(arr[j]) > 0) { - minIndex = j; - } - } - if (minIndex != i) { - T temp = arr[i]; - arr[i] = arr[minIndex]; - arr[minIndex] = temp; - } - } - return arr; - } - - /** Driver Code */ - public static void main(String[] args) { - - Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - SelectionSort selectionSort = new SelectionSort(); - Integer[] sorted = selectionSort.sort(arr); - for (int i = 0; i < sorted.length - 1; ++i) { - assert sorted[i] <= sorted[i + 1]; - } - - String[] strings = {"c", "a", "e", "b", "d"}; - String[] sortedStrings = selectionSort.sort(strings); - for (int i = 0; i < sortedStrings.length - 1; ++i) { - assert strings[i].compareTo(strings[i + 1]) <= 0; - } - } -} diff --git a/Sorts/ShellSort.java b/Sorts/ShellSort.java deleted file mode 100644 index eaf51e448d3e..000000000000 --- a/Sorts/ShellSort.java +++ /dev/null @@ -1,48 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.*; - -public class ShellSort implements SortAlgorithm { - - /** - * Implements generic shell sort. - * - * @param array the array to be sorted. - * @param the type of elements in the array. - * @return the sorted array. - */ - @Override - public > T[] sort(T[] array) { - int length = array.length; - int gap = 1; - - /* Calculate gap for optimization purpose */ - while (gap < length / 3) { - gap = 3 * gap + 1; - } - - for (; gap > 0; gap /= 3) { - for (int i = gap; i < length; i++) { - int j; - T temp = array[i]; - for (j = i; j >= gap && less(temp, array[j - gap]); j -= gap) { - array[j] = array[j - gap]; - } - array[j] = temp; - } - } - return array; - } - - /* Driver Code */ - public static void main(String[] args) { - Integer[] toSort = {4, 23, 6, 78, 1, 54, 231, 9, 12}; - - ShellSort sort = new ShellSort(); - sort.sort(toSort); - for (int i = 0; i < toSort.length - 1; ++i) { - assert toSort[i] <= toSort[i + 1]; - } - print(toSort); - } -} diff --git a/Sorts/SortAlgorithm.java b/Sorts/SortAlgorithm.java deleted file mode 100644 index d686cea95911..000000000000 --- a/Sorts/SortAlgorithm.java +++ /dev/null @@ -1,31 +0,0 @@ -package Sorts; - -import java.util.Arrays; -import java.util.List; - -/** - * The common interface of most sorting algorithms - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - */ -public interface SortAlgorithm { - - /** - * Main method arrays sorting algorithms - * - * @param unsorted - an array should be sorted - * @return a sorted array - */ - > T[] sort(T[] unsorted); - - /** - * Auxiliary method for algorithms what wanted to work with lists from JCF - * - * @param unsorted - a list should be sorted - * @return a sorted list - */ - @SuppressWarnings("unchecked") - default > List sort(List unsorted) { - return Arrays.asList(sort(unsorted.toArray((T[]) new Comparable[unsorted.size()]))); - } -} diff --git a/Sorts/SortUtils.java b/Sorts/SortUtils.java deleted file mode 100644 index 33be8879796b..000000000000 --- a/Sorts/SortUtils.java +++ /dev/null @@ -1,92 +0,0 @@ -package Sorts; - -import java.util.Arrays; -import java.util.List; - -/** - * The class contains util methods - * - * @author Podshivalov Nikita (https://github.com/nikitap492) - */ -final class SortUtils { - - /** - * Helper method for swapping places in array - * - * @param array The array which elements we want to swap - * @param idx index of the first element - * @param idy index of the second element - */ - static boolean swap(T[] array, int idx, int idy) { - T swap = array[idx]; - array[idx] = array[idy]; - array[idy] = swap; - return true; - } - - /** - * This method checks if first element is less than the other element - * - * @param v first element - * @param w second element - * @return true if the first element is less than the second element - */ - static > boolean less(T v, T w) { - return v.compareTo(w) < 0; - } - - /** - * This method checks if first element is greater than the other element - * - * @param v first element - * @param w second element - * @return true if the first element is greater than the second element - */ - static > boolean greater(T v, T w) { - return v.compareTo(w) > 0; - } - - /** - * This method checks if first element is greater than or equal the other element - * - * @param v first element - * @param w second element - * @return true if the first element is greater than or equal the second element - */ - static > boolean greaterOrEqual(T v, T w) { - return v.compareTo(w) >= 0; - } - - /** - * Prints a list - * - * @param toPrint - a list which should be printed - */ - static void print(List toPrint) { - toPrint.stream().map(Object::toString).map(str -> str + " ").forEach(System.out::print); - - System.out.println(); - } - - /** - * Prints an array - * - * @param toPrint - an array which should be printed - */ - static void print(Object[] toPrint) { - System.out.println(Arrays.toString(toPrint)); - } - - /** - * Swaps all position from {@param left} to @{@param right} for {@param array} - * - * @param array is an array - * @param left is a left flip border of the array - * @param right is a right flip border of the array - */ - static > void flip(T[] array, int left, int right) { - while (left <= right) { - swap(array, left++, right--); - } - } -} diff --git a/Sorts/TimSort.java b/Sorts/TimSort.java deleted file mode 100644 index 8a6c5e11b401..000000000000 --- a/Sorts/TimSort.java +++ /dev/null @@ -1,188 +0,0 @@ -package Sorts; - -import java.util.Random; - -/** - * @author [Hemanth Kotagiri](https://github.com/hemanth-kotagiri) - * @see [Tim Sort](https://en.wikipedia.org/wiki/Tim_sort) - */ -class TimSort { - int array[]; - int array_length; - int RUN = 32; - - /** - * @brief A constructor which takes in the array specified by the user. - * @param array : Array given by the user. - */ - public TimSort(int[] array) { - this.array = array; - this.array_length = array.length; - } - - /** - * @brief A constructor which takes in an array length and randomly initializes an array. - * @param array_length length given by the user. - */ - public TimSort(int array_length) { - Random rand = new Random(); - - this.array_length = array_length; - this.array = new int[this.array_length]; - - for (int i = 0; i < this.array_length; i++) { - int random_number = rand.nextInt(1000); - this.array[i] = random_number; - } - } - - /** - * @brief A method to change the size of the run. - * @param run : Value specified by the user to change the run. - */ - public void change_run(int run) { - this.RUN = run; - } - - /** - * @brief A default constructor when no parameters are given. Initializes the array length to be - * 100. Generates a random number array of size 100. - */ - public TimSort() { - this.array_length = 100; - this.array = new int[this.array_length]; - - Random rand = new Random(); - for (int i = 0; i < this.array_length; i++) { - int random_number = rand.nextInt(1000); - this.array[i] = random_number; - } - } - - /** - * @brief Performs Insertion Sort Algorithm on given array with bounded indices. - * @param array: The array on which the algorithm is to be performed. - * @param start_idx: The starting index from which the algorithm is to be performed. - * @param end_idx: The ending index at which the algorithm needs to stop sorting. - */ - public void insertion_sort(int[] array, int start_idx, int end_idx) { - for (int i = 0; i < array.length; i++) { - int current_element = array[i]; - int j = i - 1; - while (j >= 0 && array[j] > current_element) { - array[j + 1] = array[j]; - j--; - } - array[j + 1] = current_element; - } - } - - /** - * @brief A method to merge two runs(chunks of array). - * @param array: The origin array which is to be sorted. - * @param start: Starting index of the first run(chunk). - * @param mid: The ending index of the first run(chunk). - * @param end: Ending index of the second run(chunk). - */ - public void merge_runs(int array[], int start, int mid, int end) { - - int first_array_size = mid - start + 1, second_array_size = end - mid; - int array1[] = new int[first_array_size], array2[] = new int[second_array_size]; - int i = 0, j = 0, k = 0; - - // Building the two sub arrays from the array to merge later - for (i = 0; i < first_array_size; i++) array1[i] = array[start + i]; - for (i = 0; i < second_array_size; i++) array2[i] = array[mid + 1 + i]; - - i = 0; - j = 0; - k = start; - - while (i < first_array_size && j < second_array_size) { - if (array1[i] <= array2[j]) { - array[k] = array1[i]; - i++; - } else { - array[k] = array2[j]; - j++; - } - k++; - } - - while (i < first_array_size) { - array[k] = array1[i]; - k++; - i++; - } - - while (j < second_array_size) { - array[k] = array2[j]; - k++; - j++; - } - } - - /** @brief Tim Sort Algorithm method. */ - public void algorithm() { - // Before Sorting - System.out.println("Before sorting the array: "); - this.showArrayElements(); - System.out.println(); - - // Applying insertion sort on RUNS. - for (int i = 0; i < this.array_length; i += this.RUN) - this.insertion_sort(this.array, i, Math.min(i + this.RUN, (this.array_length - 1))); - - for (int split = this.RUN; split < this.array_length; split = 2 * split) { - for (int start_idx = 0; start_idx < this.array_length; start_idx += 2 * split) { - int mid = start_idx + split - 1; - int end_idx = Math.min((start_idx + 2 * split - 1), (this.array_length - 1)); - - this.merge_runs(this.array, start_idx, mid, end_idx); - } - } - // After sorting - System.out.println("After sorting the array: "); - this.showArrayElements(); - System.out.println(); - } - - /** @brief A method to show the elements inside the array. */ - public void showArrayElements() { - for (int i = 0; i < this.array.length; i++) { - System.out.print(this.array[i] + " "); - } - System.out.println(); - } - - /** @brief A method to test the sorting algorithm */ - static void test() { - int[] array = {4, 1, 3, 17, 12, 11, 8}; - TimSort sorterObj1 = new TimSort(); - TimSort sorterObj2 = new TimSort(50); - TimSort sorterObj3 = new TimSort(array); - - sorterObj1.algorithm(); - sorterObj2.algorithm(); - sorterObj3.algorithm(); - - // Testing the first array - for (int i = 0; i < sorterObj1.array_length - 1; i++) { - assert ((sorterObj1.array[i] <= sorterObj1.array[i + 1])) : "Array is not sorted"; - } - - // Testing the second array. - for (int i = 0; i < sorterObj2.array_length - 1; i++) { - assert ((sorterObj2.array[i] <= sorterObj2.array[i + 1])) : "Array is not sorted"; - } - - // Testing the third array. - for (int i = 0; i < sorterObj3.array_length - 1; i++) { - assert ((sorterObj3.array[i] <= sorterObj3.array[i + 1])) : "Array is not sorted"; - } - } - - public static void main(String[] args) { - test(); - } -} diff --git a/Sorts/TreeSort.java b/Sorts/TreeSort.java deleted file mode 100644 index 126625db8fe3..000000000000 --- a/Sorts/TreeSort.java +++ /dev/null @@ -1,113 +0,0 @@ -package Sorts; - -import static Sorts.SortUtils.print; - -import java.util.List; - -/** - *

Implementation of the Tree Sort algorithm

- * - *

- * Tree Sort: A sorting algorithm which constructs a Binary Search Tree - * using the unsorted data and then outputs the data by inorder traversal - * of the tree. - * - * Reference: https://en.wikipedia.org/wiki/Tree_sort - *

- * - * @author Madhur Panwar (https://github.com/mdrpanwar) - */ -public class TreeSort implements SortAlgorithm { - - @Override - public > T[] sort(T[] unsortedArray) { - return doTreeSortArray(unsortedArray); - } - - @Override - public > List sort(List unsortedList) { - return doTreeSortList(unsortedList); - } - - private > T[] doTreeSortArray(T[] unsortedArray) { - // create a generic BST tree - DataStructures.Trees.BSTRecursiveGeneric tree = new DataStructures.Trees.BSTRecursiveGeneric(); - - // add all elements to the tree - for(T element: unsortedArray) { - tree.add(element); - } - - // get the sorted list by inorder traversal of the tree - List sortedList = tree.inorderSort(); - - // add the elements back to the initial array - int i = 0; - for(T element: sortedList) { - unsortedArray[i++] = element; - } - - // return the array - return unsortedArray; - } - - private > List doTreeSortList(List unsortedList) { - // create a generic BST tree - DataStructures.Trees.BSTRecursiveGeneric tree = new DataStructures.Trees.BSTRecursiveGeneric(); - - // add all elements to the tree - for(T element: unsortedList) { - tree.add(element); - } - - // get the sorted list by inorder traversal of the tree and return it - return tree.inorderSort(); - } - - public static void main(String[] args) { - TreeSort treeSort = new TreeSort(); - - // ==== Integer Array ======= - System.out.println("Testing for Integer Array...."); - Integer[] a = { 3, -7, 45, 1, 343, -5, 2, 9 }; - System.out.print(String.format("%-10s", "unsorted: ")); - print(a); - a = treeSort.sort(a); - System.out.print(String.format("%-10s", "sorted: ")); - print(a); - System.out.println(); - - // ==== Integer List ======= - System.out.println("Testing for Integer List...."); - List intList = List.of(3, -7, 45, 1, 343, -5, 2, 9); - System.out.print(String.format("%-10s", "unsorted: ")); - print(intList); - intList = treeSort.sort(intList); - System.out.print(String.format("%-10s", "sorted: ")); - print(intList); - System.out.println(); - - - // ==== String Array ======= - System.out.println("Testing for String Array...."); - String[] b = { "banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple" }; - System.out.print(String.format("%-10s", "unsorted: ")); - print(b); - b = treeSort.sort(b); - System.out.print(String.format("%-10s", "sorted: ")); - print(b); - System.out.println(); - - // ==== String List ======= - System.out.println("Testing for String List...."); - List stringList = List.of("banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"); - System.out.print(String.format("%-10s", "unsorted: ")); - print(stringList); - stringList = treeSort.sort(stringList); - System.out.print(String.format("%-10s", "sorted: ")); - print(stringList); - - } - -} - diff --git a/Strings/Alphabetical.java b/Strings/Alphabetical.java deleted file mode 100644 index 366b59fe548b..000000000000 --- a/Strings/Alphabetical.java +++ /dev/null @@ -1,33 +0,0 @@ -package Strings; - -/** - * Alphabetical order is a system whereby character strings are placed in order based on the - * position of the characters in the conventional ordering of an alphabet. Wikipedia: - * https://en.wikipedia.org/wiki/Alphabetical_order - */ -class Alphabetical { - - public static void main(String[] args) { - assert !isAlphabetical("123abc"); - assert isAlphabetical("aBC"); - assert isAlphabetical("abc"); - assert !isAlphabetical("xyzabc"); - assert isAlphabetical("abcxyz"); - } - - /** - * Check if a string is alphabetical order or not - * - * @param s a string - * @return {@code true} if given string is alphabetical order, otherwise {@code false} - */ - public static boolean isAlphabetical(String s) { - s = s.toLowerCase(); - for (int i = 0; i < s.length() - 1; ++i) { - if (!Character.isLetter(s.charAt(i)) || !(s.charAt(i) <= s.charAt(i + 1))) { - return false; - } - } - return true; - } -} diff --git a/Strings/CharactersSame.java b/Strings/CharactersSame.java deleted file mode 100644 index 5c4b5b4a2854..000000000000 --- a/Strings/CharactersSame.java +++ /dev/null @@ -1,27 +0,0 @@ -package Strings; - -public class CharactersSame { - - /** Driver Code */ - public static void main(String[] args) { - assert isAllCharactersSame(""); - assert !isAllCharactersSame("aab"); - assert isAllCharactersSame("aaa"); - assert isAllCharactersSame("11111"); - } - - /** - * check if all the characters of a string are same - * - * @param s the string to check - * @return {@code true} if all characters of a string are same, otherwise {@code false} - */ - public static boolean isAllCharactersSame(String s) { - for (int i = 1, length = s.length(); i < length; ++i) { - if (s.charAt(i) != s.charAt(0)) { - return false; - } - } - return true; - } -} diff --git a/Strings/CheckAnagrams.java b/Strings/CheckAnagrams.java deleted file mode 100644 index 1bbeed4016c6..000000000000 --- a/Strings/CheckAnagrams.java +++ /dev/null @@ -1,52 +0,0 @@ -package Strings; - -import java.util.HashMap; -import java.util.Map; - -/** - * Two strings are anagrams if they are made of the same letters arranged differently (ignoring the - * case). - */ -public class CheckAnagrams { - public static void main(String[] args) { - assert isAnagrams("Silent", "Listen"); - assert isAnagrams("This is a string", "Is this a string"); - assert !isAnagrams("There", "Their"); - } - - /** - * Check if two strings are anagrams or not - * - * @param s1 the first string - * @param s2 the second string - * @return {@code true} if two string are anagrams, otherwise {@code false} - */ - public static boolean isAnagrams(String s1, String s2) { - int l1 = s1.length(); - int l2 = s2.length(); - s1 = s1.toLowerCase(); - s2 = s2.toLowerCase(); - Map charAppearances = new HashMap<>(); - - for (int i = 0; i < l1; i++) { - char c = s1.charAt(i); - int numOfAppearances = charAppearances.getOrDefault(c, 0); - charAppearances.put(c, numOfAppearances + 1); - } - - for (int i = 0; i < l2; i++) { - char c = s2.charAt(i); - if (!charAppearances.containsKey(c)) { - return false; - } - charAppearances.put(c, charAppearances.get(c) - 1); - } - - for (int cnt : charAppearances.values()) { - if (cnt != 0) { - return false; - } - } - return true; - } -} diff --git a/Strings/CheckVowels.java b/Strings/CheckVowels.java deleted file mode 100644 index d9ad0b7be50f..000000000000 --- a/Strings/CheckVowels.java +++ /dev/null @@ -1,51 +0,0 @@ -package Strings; - -/** - * Vowel Count is a system whereby character strings are placed in order based on the position of - * the characters in the conventional ordering of an alphabet. Wikipedia: - * https://en.wikipedia.org/wiki/Alphabetical_order - */ -class CheckVowels { - public static void main(String[] args) { - assert !hasVowels("This is a strings"); - assert hasVowels("Hello World"); - assert hasVowels("Java is fun"); - assert !hasVowels("123hi"); - assert hasVowels("Coding vs Programming"); - } - - /** - * Check if a string is has vowels or not - * - * @param input a string - * @return {@code true} if given string has vowels, otherwise {@code false} - */ - public static boolean hasVowels(String input) { - if (input.matches("[AEIOUaeiou]")) { - countVowels(input); - return true; - } - return false; - } - /** - * count the number of vowels - * - * @param input a string prints the count of vowels - */ - public static void countVowels(String input) { - input = input.toLowerCase(); - int count = 0; - int i = 0; - while (i < input.length()) { - if (input.charAt(i) == 'a' - || input.charAt(i) == 'e' - || input.charAt(i) == 'i' - || input.charAt(i) == 'o' - || input.charAt(i) == 'u') { - count++; - } - i++; - } - System.out.println(count); - } -} diff --git a/Strings/HorspoolSearch.java b/Strings/HorspoolSearch.java deleted file mode 100644 index 880633a82427..000000000000 --- a/Strings/HorspoolSearch.java +++ /dev/null @@ -1,172 +0,0 @@ -package Strings; - -import java.util.HashMap; - -/** - * This class is not thread safe
- *
- * (From wikipedia) In computer science, the Boyer–Moore–Horspool algorithm or Horspool's algorithm - * is an algorithm for finding substrings in strings. It was published by Nigel Horspool in 1980. - *
- * Wikipedia - * page
- *
- * - *

An explanation:
- * - *

The Horspool algorithm is a simplification of the Boyer-Moore algorithm in that it uses only - * one of the two heuristic methods for increasing the number of characters shifted when finding a - * bad match in the text. This method is usually called the "bad symbol" or "bad character" shift. - * The bad symbol shift method is classified as an input enhancement method in the theory of - * algorithms. Input enhancement is (from wikipedia) the principle that processing a given input to - * a problem and altering it in a specific way will increase runtime efficiency or space efficiency, - * or both. Both algorithms try to match the pattern and text comparing the pattern symbols to the - * text's from right to left.
- *
- * - *

In the bad symbol shift method, a table is created prior to the search, called the "bad symbol - * table". The bad symbol table contains the shift values for any symbol in the text and pattern. - * For these symbols, the value is the length of the pattern, if the symbol is not in the first - * (length - 1) of the pattern. Else it is the distance from its rightmost occurrence in the pattern - * to the last symbol of the pattern. In practice, we only calculate the values for the ones that - * exist in the first (length - 1) of the pattern.
- *
- * - *

For more details on the algorithm and the more advanced Boyer-Moore I recommend checking out - * the wikipedia page and professor Anany Levitin's book: Introduction To The Design And Analysis Of - * Algorithms. - */ -public class HorspoolSearch { - - private static HashMap shiftValues; // bad symbol table - private static Integer patternLength; - private static int comparisons = 0; // total comparisons in the current/last search - - /** - * Case sensitive version version of the algorithm - * - * @param pattern the pattern to be searched for (needle) - * @param text the text being searched in (haystack) - * @return -1 if not found or first index of the pattern in the text - */ - public static int findFirst(String pattern, String text) { - return firstOccurrence(pattern, text, true); - } - - /** - * Case insensitive version version of the algorithm - * - * @param pattern the pattern to be searched for (needle) - * @param text the text being searched in (haystack) - * @return -1 if not found or first index of the pattern in the text - */ - public static int findFirstInsensitive(String pattern, String text) { - return firstOccurrence(pattern, text, false); - } - - /** - * Utility method that returns comparisons made by last run (mainly for tests) - * - * @return number of character comparisons of the last search - */ - public static Integer getLastComparisons() { - return HorspoolSearch.comparisons; - } - - /** - * Fairly standard implementation of the Horspool algorithm. Only the index of the last character - * of the pattern on the text is saved and shifted by the appropriate amount when a mismatch is - * found. The algorithm stops at the first match or when the entire text has been exhausted. - * - * @param pattern String to be matched in the text - * @param text text String - * @return index of first occurrence of the pattern in the text - */ - private static int firstOccurrence(String pattern, String text, boolean caseSensitive) { - shiftValues = calcShiftValues(pattern); // build the bad symbol table - comparisons = 0; // reset comparisons - - int textIndex = - pattern.length() - 1; // align pattern with text start and get index of the last character - - // while pattern is not out of text bounds - while (textIndex < text.length()) { - - // try to match pattern with current part of the text starting from last character - int i = pattern.length() - 1; - while (i >= 0) { - comparisons++; - char patternChar = pattern.charAt(i); - char textChar = text.charAt((textIndex + i) - (pattern.length() - 1)); - if (!charEquals(patternChar, textChar, caseSensitive)) { // bad character, shift pattern - textIndex += getShiftValue(text.charAt(textIndex)); - break; - } - i--; - } - - // check for full match - if (i == -1) { - return textIndex - pattern.length() + 1; - } - } - - // text exhausted, return failure - return -1; - } - - /** - * Compares the argument characters - * - * @param c1 first character - * @param c2 second character - * @param caseSensitive boolean determining case sensitivity of comparison - * @return truth value of the equality comparison - */ - private static boolean charEquals(char c1, char c2, boolean caseSensitive) { - if (caseSensitive) { - return c1 == c2; - } - return Character.toLowerCase(c1) == Character.toLowerCase(c2); - } - - /** - * Builds the bad symbol table required to run the algorithm. The method starts from the second to - * last character of the pattern and moves to the left. When it meets a new character, it is by - * definition its rightmost occurrence and therefore puts the distance from the current index to - * the index of the last character into the table. If the character is already in the table, then - * it is not a rightmost occurrence, so it continues. - * - * @param pattern basis for the bad symbol table - * @return the bad symbol table - */ - private static HashMap calcShiftValues(String pattern) { - patternLength = pattern.length(); - HashMap table = new HashMap<>(); - - for (int i = pattern.length() - 2; - i >= 0; - i--) { // length - 2 is the index of the second to last character - char c = pattern.charAt(i); - int finalI = i; - table.computeIfAbsent(c, k -> pattern.length() - 1 - finalI); - } - - return table; - } - - /** - * Helper function that uses the bad symbol shift table to return the appropriate shift value for - * a given character - * - * @param c character - * @return shift value that corresponds to the character argument - */ - private static Integer getShiftValue(char c) { - if (shiftValues.get(c) != null) { - return shiftValues.get(c); - } else { - return patternLength; - } - } -} diff --git a/Strings/List_all_Possible_Words_From_Phone_Digits.java b/Strings/List_all_Possible_Words_From_Phone_Digits.java deleted file mode 100644 index 8c6d2d8edeb7..000000000000 --- a/Strings/List_all_Possible_Words_From_Phone_Digits.java +++ /dev/null @@ -1,64 +0,0 @@ -package Strings; -import java.util.*; - -public class List_all_Possible_Words_From_Phone_Digits { - - static Character[][] numberToCharMap; - -private static List printWords(int[] numbers, - int len, - int numIndex, - String s) -{ - if(len == numIndex) - { - return new ArrayList<>(Collections.singleton(s)); - } - - List stringList = new ArrayList<>(); - - for(int i = 0; - i < numberToCharMap[numbers[numIndex]].length; i++) - { - String sCopy = - String.copyValueOf(s.toCharArray()); - sCopy = sCopy.concat( - numberToCharMap[numbers[numIndex]][i].toString()); - stringList.addAll(printWords(numbers, len, - numIndex + 1, - sCopy)); - } - return stringList; -} - -private static void printWords(int[] numbers) -{ - generateNumberToCharMap(); - List stringList = - printWords(numbers, numbers.length, 0, ""); - stringList.stream().forEach(System.out :: println); -} - -private static void generateNumberToCharMap() -{ - numberToCharMap = new Character[10][5]; - numberToCharMap[0] = new Character[]{'\0'}; - numberToCharMap[1] = new Character[]{'\0'}; - numberToCharMap[2] = new Character[]{'a','b','c'}; - numberToCharMap[3] = new Character[]{'d','e','f'}; - numberToCharMap[4] = new Character[]{'g','h','i'}; - numberToCharMap[5] = new Character[]{'j','k','l'}; - numberToCharMap[6] = new Character[]{'m','n','o'}; - numberToCharMap[7] = new Character[]{'p','q','r','s'}; - numberToCharMap[8] = new Character[]{'t','u','v'}; - numberToCharMap[9] = new Character[]{'w','x','y','z'}; -} - -// Driver code -public static void main(String[] args) -{ - int number[] = {2, 3, 4}; - printWords(number); -} -} - \ No newline at end of file diff --git a/Strings/Lower.java b/Strings/Lower.java deleted file mode 100644 index 203fddf54b6f..000000000000 --- a/Strings/Lower.java +++ /dev/null @@ -1,28 +0,0 @@ -package Strings; - -public class Lower { - - /** Driver Code */ - public static void main(String[] args) { - String[] strings = {"ABC", "ABC123", "abcABC", "abc123ABC"}; - for (String s : strings) { - assert toLowerCase(s).equals(s.toLowerCase()); - } - } - - /** - * Converts all of the characters in this {@code String} to lower case - * - * @param s the string to convert - * @return the {@code String}, converted to lowercase. - */ - public static String toLowerCase(String s) { - char[] values = s.toCharArray(); - for (int i = 0; i < values.length; ++i) { - if (Character.isLetter(values[i]) && Character.isUpperCase(values[i])) { - values[i] = Character.toLowerCase(values[i]); - } - } - return new String(values); - } -} diff --git a/Strings/Palindrome.java b/Strings/Palindrome.java deleted file mode 100644 index 5457eaa351f9..000000000000 --- a/Strings/Palindrome.java +++ /dev/null @@ -1,64 +0,0 @@ -package Strings; - -/** Wikipedia: https://en.wikipedia.org/wiki/Palindrome */ -class Palindrome { - - /** Driver Code */ - public static void main(String[] args) { - String[] palindromes = {null, "", "aba", "123321"}; - for (String s : palindromes) { - assert isPalindrome(s) && isPalindromeRecursion(s) && isPalindrome1(s); - } - - String[] notPalindromes = {"abb", "abc", "abc123"}; - for (String s : notPalindromes) { - assert !isPalindrome(s) && !isPalindromeRecursion(s) && !isPalindrome1(s); - } - } - - /** - * Check if a string is palindrome string or not - * - * @param s a string to check - * @return {@code true} if given string is palindrome, otherwise {@code false} - */ - public static boolean isPalindrome(String s) { - return (s == null || s.length() <= 1) || s.equals(new StringBuilder(s).reverse().toString()); - } - - /** - * Check if a string is palindrome string or not using recursion - * - * @param s a string to check - * @return {@code true} if given string is palindrome, otherwise {@code false} - */ - public static boolean isPalindromeRecursion(String s) { - if (s == null || s.length() <= 1) { - return true; - } - - if (s.charAt(0) != s.charAt(s.length() - 1)) { - return false; - } - - return isPalindrome(s.substring(1, s.length() - 1)); - } - - /** - * Check if a string is palindrome string or not another way - * - * @param s a string to check - * @return {@code true} if given string is palindrome, otherwise {@code false} - */ - public static boolean isPalindrome1(String s) { - if (s == null || s.length() <= 1) { - return true; - } - for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { - if (s.charAt(i) != s.charAt(j)) { - return false; - } - } - return true; - } -} diff --git a/Strings/Pangram.java b/Strings/Pangram.java deleted file mode 100644 index e434d50c4740..000000000000 --- a/Strings/Pangram.java +++ /dev/null @@ -1,35 +0,0 @@ -package Strings; - -/** Wikipedia: https://en.wikipedia.org/wiki/Pangram */ -public class Pangram { - - /** Driver Code */ - public static void main(String[] args) { - assert isPangram("The quick brown fox jumps over the lazy dog"); - assert !isPangram("The quick brown fox jumps over the azy dog"); /* not exists l character */ - } - - /** - * Check if a string is a pangram string or not - * - * @param s string to check - * @return {@code true} if given string is pangram, otherwise {@code false} - */ - public static boolean isPangram(String s) { - boolean[] marked = new boolean[26]; /* by default all letters don't exists */ - char[] values = s.toCharArray(); - for (char value : values) { - if (Character.isLetter(value)) { - int index = Character.isUpperCase(value) ? value - 'A' : value - 'a'; - marked[index] = true; /* mark current character exists */ - } - } - - for (boolean b : marked) { - if (!b) { - return false; - } - } - return true; - } -} diff --git a/Strings/ReverseString.java b/Strings/ReverseString.java deleted file mode 100644 index 8a4d7962d4bf..000000000000 --- a/Strings/ReverseString.java +++ /dev/null @@ -1,41 +0,0 @@ -package Strings; - -/** Reverse String using different version */ -public class ReverseString { - - public static void main(String[] args) { - assert reverse("abc123").equals("321cba"); - assert reverse2("abc123").equals("321cba"); - } - - /** - * easiest way to reverses the string str and returns it - * - * @param str string to be reversed - * @return reversed string - */ - public static String reverse(String str) { - return new StringBuilder(str).reverse().toString(); - } - - /** - * second way to reverses the string str and returns it - * - * @param str string to be reversed - * @return reversed string - */ - public static String reverse2(String str) { - - if (str == null || str.isEmpty()) { - return str; - } - - char[] value = str.toCharArray(); - for (int i = 0, j = str.length() - 1; i < j; i++, j--) { - char temp = value[i]; - value[i] = value[j]; - value[j] = temp; - } - return new String(value); - } -} diff --git a/Strings/Rotation.java b/Strings/Rotation.java deleted file mode 100644 index 4ee1cb1c7964..000000000000 --- a/Strings/Rotation.java +++ /dev/null @@ -1,58 +0,0 @@ -package Strings; - -/** - * Given a string, moving several characters in front of the string to the end of the string. For - * example, move the two characters'a' and 'b' in front of the string "abcdef" to the end of the - * string, so that the original string becomes the string "cdefab" - */ -public class Rotation { - public static void main(String[] args) { - assert rotation("abcdef", 2).equals("cdefab"); - - char[] values = "abcdef".toCharArray(); - rotation(values, 2); - assert new String(values).equals("cdefab"); - } - - /** - * Move {@code n} characters in front of given string to the end of string time complexity: O(n) - * space complexity: O(n) - * - * @param s given string - * @param n the total characters to be moved - * @return string after rotation - */ - public static String rotation(String s, int n) { - return s.substring(n) + s.substring(0, n); - } - - /** - * Move {@code n} characters in front of given character array to the end of array time - * complexity: O(n) space complexity: O(1) - * - * @param values given character array - * @param n the total characters to be moved - */ - public static void rotation(char[] values, int n) { - reverse(values, 0, n - 1); - reverse(values, n, values.length - 1); - reverse(values, 0, values.length - 1); - } - - /** - * Reverse character array - * - * @param values character array - * @param from begin index of given array - * @param to end index of given array - */ - public static void reverse(char[] values, int from, int to) { - while (from < to) { - char temp = values[from]; - values[from] = values[to]; - values[to] = temp; - from++; - to--; - } - } -} diff --git a/Strings/Upper.java b/Strings/Upper.java deleted file mode 100644 index 4367d8b6fea1..000000000000 --- a/Strings/Upper.java +++ /dev/null @@ -1,28 +0,0 @@ -package Strings; - -public class Upper { - - /** Driver Code */ - public static void main(String[] args) { - String[] strings = {"ABC", "ABC123", "abcABC", "abc123ABC"}; - for (String s : strings) { - assert toUpperCase(s).equals(s.toUpperCase()); - } - } - - /** - * Converts all of the characters in this {@code String} to upper case - * - * @param s the string to convert - * @return the {@code String}, converted to uppercase. - */ - public static String toUpperCase(String s) { - char[] values = s.toCharArray(); - for (int i = 0; i < values.length; ++i) { - if (Character.isLetter(values[i]) && Character.isLowerCase(values[i])) { - values[i] = Character.toUpperCase(values[i]); - } - } - return new String(values); - } -} diff --git a/pom.xml b/pom.xml new file mode 100644 index 000000000000..0f08a6740c49 --- /dev/null +++ b/pom.xml @@ -0,0 +1,13 @@ + + + 4.0.0 + com.thealgorithms + Java + 1.0-SNAPSHOT + jar + + UTF-8 + 11 + 11 + + \ No newline at end of file diff --git a/AudioFilters/IIRFilter.java b/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java similarity index 77% rename from AudioFilters/IIRFilter.java rename to src/main/java/com/thealgorithms/audiofilters/IIRFilter.java index 96508f497111..0de145f60c67 100644 --- a/AudioFilters/IIRFilter.java +++ b/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java @@ -1,12 +1,13 @@ -package AudioFilters; +package com.thealgorithms.audiofilters; /** - * N-Order IIR Filter - * Assumes inputs are normalized to [-1, 1] + * N-Order IIR Filter Assumes inputs are normalized to [-1, 1] * - * Based on the difference equation from https://en.wikipedia.org/wiki/Infinite_impulse_response + * Based on the difference equation from + * https://en.wikipedia.org/wiki/Infinite_impulse_response */ public class IIRFilter { + private final int order; private final double[] coeffsA; private final double[] coeffsB; @@ -25,8 +26,8 @@ public IIRFilter(int order) throws IllegalArgumentException { } this.order = order; - coeffsA = new double[order+1]; - coeffsB = new double[order+1]; + coeffsA = new double[order + 1]; + coeffsB = new double[order + 1]; // Sane defaults coeffsA[0] = 1.0; @@ -38,10 +39,11 @@ public IIRFilter(int order) throws IllegalArgumentException { /** * Set coefficients + * * @param aCoeffs Denominator coefficients * @param bCoeffs Numerator coefficients - * @throws IllegalArgumentException if {@code aCoeffs} or {@code bCoeffs} is not of size {@code order}, - * or if {@code aCoeffs[0]} is 0.0 + * @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 { if (aCoeffs.length != order) { @@ -73,14 +75,14 @@ public double process(double sample) { // 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]; // Feedback - for (int i = order-1; i > 0; i--) { - historyX[i] = historyX[i-1]; - historyY[i] = historyY[i-1]; + for (int i = order - 1; i > 0; i--) { + historyX[i] = historyX[i - 1]; + historyY[i] = historyY[i - 1]; } historyX[0] = sample; diff --git a/Backtracking/KnightsTour.java b/src/main/java/com/thealgorithms/backtracking/KnightsTour.java similarity index 77% rename from Backtracking/KnightsTour.java rename to src/main/java/com/thealgorithms/backtracking/KnightsTour.java index d6e454b68ebd..e337df8f6e8e 100644 --- a/Backtracking/KnightsTour.java +++ b/src/main/java/com/thealgorithms/backtracking/KnightsTour.java @@ -1,4 +1,4 @@ -package Backtracking; +package com.thealgorithms.backtracking; import java.util.*; @@ -23,10 +23,10 @@ 51 46 55 44 53 4 21 12 */ - public class KnightsTour { + private final static int base = 12; - private final static int[][] moves = {{1,-2},{2,-1},{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2}}; // Possible moves by knight on chess + private final static int[][] moves = {{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 @@ -34,31 +34,38 @@ public static void main(String[] args) { grid = new int[base][base]; total = (base - 4) * (base - 4); - for (int r = 0; r < base; r++) - for (int c = 0; c < base; c++) - if (r < 2 || r > base - 3 || c < 2 || c > base - 3) + for (int r = 0; r < base; r++) { + for (int c = 0; c < base; c++) { + if (r < 2 || r > base - 3 || c < 2 || c > base - 3) { grid[r][c] = -1; + } + } + } int row = 2 + (int) (Math.random() * (base - 4)); int col = 2 + (int) (Math.random() * (base - 4)); grid[row][col] = 1; - if (solve(row, col, 2)) + if (solve(row, col, 2)) { printResult(); - else System.out.println("no result"); + } else { + System.out.println("no result"); + } } // Return True when solvable private static boolean solve(int row, int column, int count) { - if (count > total) + if (count > total) { return true; + } List neighbor = neighbors(row, column); - if (neighbor.isEmpty() && count != total) + if (neighbor.isEmpty() && count != total) { return false; + } Collections.sort(neighbor, new Comparator() { public int compare(int[] a, int[] b) { @@ -70,8 +77,9 @@ public int compare(int[] a, int[] b) { 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; } @@ -96,9 +104,11 @@ private static List neighbors(int row, int column) { // Returns the total count of neighbors private static int countNeighbors(int row, int column) { int num = 0; - for (int[] m : moves) - if (grid[row + m[1]][column + m[0]] == 0) + for (int[] m : moves) { + if (grid[row + m[1]][column + m[0]] == 0) { num++; + } + } return num; } @@ -106,9 +116,11 @@ private static int countNeighbors(int row, int column) { private static boolean orphanDetected(int count, int row, int column) { if (count < total - 1) { List neighbor = neighbors(row, column); - for (int[] nb : neighbor) - if (countNeighbors(nb[0], nb[1]) == 0) + for (int[] nb : neighbor) { + if (countNeighbors(nb[0], nb[1]) == 0) { return true; + } + } } return false; } @@ -117,7 +129,9 @@ private static boolean orphanDetected(int count, int row, int column) { private static void printResult() { for (int[] row : grid) { for (int i : row) { - if (i == -1) continue; + if (i == -1) { + continue; + } System.out.printf("%2d ", i); } System.out.println(); diff --git a/Backtracking/NQueens.java b/src/main/java/com/thealgorithms/backtracking/NQueens.java similarity index 66% rename from Backtracking/NQueens.java rename to src/main/java/com/thealgorithms/backtracking/NQueens.java index 597e35a2fe36..fb0138d10d20 100644 --- a/Backtracking/NQueens.java +++ b/src/main/java/com/thealgorithms/backtracking/NQueens.java @@ -1,63 +1,36 @@ -package Backtracking; +package com.thealgorithms.backtracking; import java.util.ArrayList; import java.util.List; /** - * Problem statement: - * Given a N x N chess board. Return all arrangements in which N queens can be placed on the board such no two queens attack - * each other. - * Ex. N = 6 - * Solution= There are 4 possible ways - * Arrangement: 1 - * ".Q....", - * "...Q..", - * ".....Q", - * "Q.....", - * "..Q...", - * "....Q." + * Problem statement: Given a N x N chess board. Return all arrangements in + * which N queens can be placed on the board such no two queens attack each + * other. Ex. N = 6 Solution= There are 4 possible ways Arrangement: 1 ".Q....", + * "...Q..", ".....Q", "Q.....", "..Q...", "....Q." *

- * Arrangement: 2 - * "..Q...", - * ".....Q", - * ".Q....", - * "....Q.", - * "Q.....", - * "...Q.." + * Arrangement: 2 "..Q...", ".....Q", ".Q....", "....Q.", "Q.....", "...Q.." *

- * Arrangement: 3 - * "...Q..", - * "Q.....", - * "....Q.", - * ".Q....", - * ".....Q", - * "..Q..." + * Arrangement: 3 "...Q..", "Q.....", "....Q.", ".Q....", ".....Q", "..Q..." *

- * Arrangement: 4 - * "....Q.", - * "..Q...", - * "Q.....", - * ".....Q", - * "...Q..", - * ".Q...." + * Arrangement: 4 "....Q.", "..Q...", "Q.....", ".....Q", "...Q..", ".Q...." * - * Solution: - * Brute Force approach: + * Solution: Brute Force approach: * - * Generate all possible arrangement to place N queens on N*N board. - * Check each board if queens are placed safely. - * If it is safe, include arrangement in solution set. Otherwise ignore it + * Generate all possible arrangement to place N queens on N*N board. Check each + * board if queens are placed safely. If it is safe, include arrangement in + * solution set. Otherwise ignore it * - * Optimized solution: - * This can be solved using backtracking in below steps + * Optimized solution: This can be solved using backtracking in below steps * - * Start with first column and place queen on first row - * Try placing queen in a row on second column - * If placing second queen in second column attacks any of the previous queens, change the row in second column - * otherwise move to next column and try to place next queen - * In case if there is no rows where a queen can be placed such that it doesn't attack previous queens, then go back to previous column and change row of previous queen. - * Keep doing this until last queen is not placed safely. - * If there is no such way then return an empty list as solution + * Start with first column and place queen on first row Try placing queen in a + * row on second column If placing second queen in second column attacks any of + * the previous queens, change the row in second column otherwise move to next + * column and try to place next queen In case if there is no rows where a queen + * can be placed such that it doesn't attack previous queens, then go back to + * previous column and change row of previous queen. Keep doing this until last + * queen is not placed safely. If there is no such way then return an empty list + * as solution */ public class NQueens { @@ -86,6 +59,7 @@ public static void placeQueens(final int queens) { /** * This is backtracking function which tries to place queen recursively + * * @param boardSize: size of chess board * @param solutions: this holds all possible arrangements * @param columns: columns[i] = rowId where queen is placed in ith column. @@ -117,12 +91,13 @@ private static void getSolution(int boardSize, List> solutions, int } /** - * This function checks if queen can be placed at row = rowIndex in column = columnIndex safely + * This function checks if queen can be placed at row = rowIndex in column = + * columnIndex safely + * * @param columns: columns[i] = rowId where queen is placed in ith column. * @param rowIndex: row in which queen has to be placed * @param columnIndex: column in which queen is being placed - * @return true: if queen can be placed safely - * false: otherwise + * @return true: if queen can be placed safely false: otherwise */ private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) { for (int i = 0; i < columnIndex; i++) { diff --git a/src/main/java/com/thealgorithms/backtracking/PowerSum.java b/src/main/java/com/thealgorithms/backtracking/PowerSum.java new file mode 100644 index 000000000000..bbaf83ecaa98 --- /dev/null +++ b/src/main/java/com/thealgorithms/backtracking/PowerSum.java @@ -0,0 +1,55 @@ +package com.thealgorithms.backtracking; + +import java.util.Scanner; + +/* + * 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. + */ +public class PowerSum { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.println("Enter the number and the power"); + int N = sc.nextInt(); + int X = sc.nextInt(); + PowerSum ps = new PowerSum(); + int count = ps.powSum(N, X); + //printing the answer. + System.out.println("Number of combinations of different natural number's raised to " + X + " having sum " + N + " are : "); + System.out.println(count); + sc.close(); + } + private int count = 0, sum = 0; + + public int powSum(int N, int X) { + Sum(N, X, 1); + return count; + } + + //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 == 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. + 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. + 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. + Sum(N, X, i + 1); + } + } + + //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); + } +} diff --git a/src/main/java/com/thealgorithms/ciphers/AES.java b/src/main/java/com/thealgorithms/ciphers/AES.java new file mode 100644 index 000000000000..879523af37bc --- /dev/null +++ b/src/main/java/com/thealgorithms/ciphers/AES.java @@ -0,0 +1,611 @@ +package com.thealgorithms.ciphers; + +import java.math.BigInteger; +import java.util.Scanner; + +/** + * This class is build to demonstrate the application of the AES-algorithm on a + * single 128-Bit block of data. + */ +public class AES { + + /** + * Precalculated values for x to the power of 2 in Rijndaels galois field. + * Used as 'RCON' during the key expansion. + */ + private static final int[] RCON = { + 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, + 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, + 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, + 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, + 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, + 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, + 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, + 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, + 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, + 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, + 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, + 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, + 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, + 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d + }; + + /** + * Rijndael S-box Substitution table used for encryption in the subBytes + * step, as well as the key expansion. + */ + private static final int[] SBOX = { + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 + }; + + /** + * Inverse Rijndael S-box Substitution table used for decryption in the + * subBytesDec step. + */ + private static final int[] INVERSE_SBOX = { + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D + }; + + /** + * Precalculated lookup table for galois field multiplication by 2 used in + * the MixColums step during encryption. + */ + private static final int[] MULT2 = { + 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e, + 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, + 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e, + 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e, + 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, + 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, + 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05, + 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25, + 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, + 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65, + 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85, + 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, + 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5, + 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5 + }; + + /** + * Precalculated lookup table for galois field multiplication by 3 used in + * the MixColums step during encryption. + */ + private static final int[] MULT3 = { + 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11, + 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, + 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71, + 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41, + 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, + 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1, + 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1, + 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, + 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a, + 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba, + 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, + 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda, + 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a, + 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, + 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a, + 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a + }; + + /** + * Precalculated lookup table for galois field multiplication by 9 used in + * the MixColums step during decryption. + */ + private static final int[] MULT9 = { + 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77, + 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7, + 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, + 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc, + 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01, + 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91, + 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a, + 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa, + 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b, + 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b, + 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0, + 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30, + 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed, + 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d, + 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6, + 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46 + }; + + /** + * Precalculated lookup table for galois field multiplication by 11 used in + * the MixColums step during decryption. + */ + private static final int[] MULT11 = { + 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69, + 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9, + 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12, + 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2, + 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f, + 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f, + 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4, + 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54, + 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e, + 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e, + 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5, + 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55, + 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68, + 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8, + 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13, + 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3 + }; + + /** + * Precalculated lookup table for galois field multiplication by 13 used in + * the MixColums step during decryption. + */ + private static final int[] MULT13 = { + 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b, + 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b, + 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0, + 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20, + 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26, + 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6, + 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d, + 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d, + 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91, + 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41, + 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a, + 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa, + 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc, + 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c, + 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47, + 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97 + }; + + /** + * Precalculated lookup table for galois field multiplication by 14 used in + * the MixColums step during decryption. + */ + private static final int[] MULT14 = { + 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a, + 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba, + 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81, + 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61, + 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7, + 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17, + 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c, + 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc, + 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b, + 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb, + 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0, + 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20, + 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6, + 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56, + 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d, + 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d + }; + + /** + * Subroutine of the Rijndael key expansion. + */ + public static BigInteger scheduleCore(BigInteger t, int rconCounter) { + StringBuilder rBytes = new StringBuilder(t.toString(16)); + + // Add zero padding + while (rBytes.length() < 8) { + rBytes.insert(0, "0"); + } + + // rotate the first 16 bits to the back + String rotatingBytes = rBytes.substring(0, 2); + String fixedBytes = rBytes.substring(2); + + rBytes = new StringBuilder(fixedBytes + rotatingBytes); + + // 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)); + + int currentByte = Integer.parseInt(currentByteBits.toString(), 16); + currentByte = SBOX[currentByte]; + + // add the current RCON value to the first byte + if (i == 0) { + currentByte = currentByte ^ RCON[rconCounter]; + } + + currentByteBits = new StringBuilder(Integer.toHexString(currentByte)); + + // Add zero padding + while (currentByteBits.length() < 2) { + currentByteBits.insert(0, '0'); + } + + // replace bytes in original string + rBytes = new StringBuilder(rBytes.substring(0, i * 2) + currentByteBits + rBytes.substring((i + 1) * 2)); + } + + // t = new BigInteger(rBytes, 16); + // return t; + return new BigInteger(rBytes.toString(), 16); + } + + /** + * Returns an array of 10 + 1 round keys that are calculated by using + * Rijndael key schedule + * + * @return array of 10 + 1 round keys + */ + public static BigInteger[] keyExpansion(BigInteger initialKey) { + BigInteger[] roundKeys = { + initialKey, + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"), + new BigInteger("0"),}; + + // initialize rcon iteration + int rconCounter = 1; + + for (int i = 1; i < 11; i++) { + + // get the previous 32 bits the key + 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)) + .divide(new BigInteger("100000000", 16)), + roundKeys[i - 1] + .remainder(new BigInteger("1000000000000000000000000", 16)) + .divide(new BigInteger("10000000000000000", 16)), + roundKeys[i - 1].divide(new BigInteger("1000000000000000000000000", 16)),}; + + // run schedule core + t = scheduleCore(t, rconCounter); + rconCounter += 1; + + // Calculate partial round key + BigInteger t0 = t.xor(prevKey[3]); + BigInteger t1 = t0.xor(prevKey[2]); + BigInteger t2 = t1.xor(prevKey[1]); + BigInteger t3 = t2.xor(prevKey[0]); + + // Join round key segments + t2 = t2.multiply(new BigInteger("100000000", 16)); + t1 = t1.multiply(new BigInteger("10000000000000000", 16)); + t0 = t0.multiply(new BigInteger("1000000000000000000000000", 16)); + roundKeys[i] = t0.add(t1).add(t2).add(t3); + } + return roundKeys; + } + + /** + * representation of the input 128-bit block as an array of 8-bit integers. + * + * @param block of 128-bit integers + * @return array of 8-bit integers + */ + public static int[] splitBlockIntoCells(BigInteger block) { + + int[] cells = new int[16]; + StringBuilder blockBits = new StringBuilder(block.toString(2)); + + // Append leading 0 for full "128-bit" string + while (blockBits.length() < 128) { + blockBits.insert(0, '0'); + } + + // split 128 to 8 bit cells + for (int i = 0; i < cells.length; i++) { + String cellBits = blockBits.substring(8 * i, 8 * (i + 1)); + cells[i] = Integer.parseInt(cellBits, 2); + } + + return cells; + } + + /** + * Returns the 128-bit BigInteger representation of the input of an array of + * 8-bit integers. + * + * @param cells that we need to merge + * @return block of merged cells + */ + 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])); + + // Append leading 0 for full "8-bit" strings + while (cellBits.length() < 8) { + cellBits.insert(0, '0'); + } + + blockBits.append(cellBits); + } + + return new BigInteger(blockBits.toString(), 2); + } + + /** + * @return ciphertext XOR key + */ + public static BigInteger addRoundKey(BigInteger ciphertext, BigInteger key) { + return ciphertext.xor(key); + } + + /** + * substitutes 8-Bit long substrings of the input using the S-Box and + * returns the result. + * + * @return subtraction Output + */ + public static BigInteger subBytes(BigInteger ciphertext) { + + int[] cells = splitBlockIntoCells(ciphertext); + + for (int i = 0; i < 16; i++) { + cells[i] = SBOX[cells[i]]; + } + + return mergeCellsIntoBlock(cells); + } + + /** + * substitutes 8-Bit long substrings of the input using the inverse S-Box + * for decryption and returns the result. + * + * @return subtraction Output + */ + public static BigInteger subBytesDec(BigInteger ciphertext) { + + int[] cells = splitBlockIntoCells(ciphertext); + + for (int i = 0; i < 16; i++) { + cells[i] = INVERSE_SBOX[cells[i]]; + } + + return mergeCellsIntoBlock(cells); + } + + /** + * Cell permutation step. Shifts cells within the rows of the input and + * returns the result. + */ + public static BigInteger shiftRows(BigInteger ciphertext) { + int[] cells = splitBlockIntoCells(ciphertext); + int[] output = new int[16]; + + // do nothing in the first row + output[0] = cells[0]; + output[4] = cells[4]; + output[8] = cells[8]; + output[12] = cells[12]; + + // shift the second row backwards by one cell + output[1] = cells[5]; + output[5] = cells[9]; + output[9] = cells[13]; + output[13] = cells[1]; + + // shift the third row backwards by two cell + output[2] = cells[10]; + output[6] = cells[14]; + output[10] = cells[2]; + output[14] = cells[6]; + + // shift the forth row backwards by tree cell + output[3] = cells[15]; + output[7] = cells[3]; + output[11] = cells[7]; + output[15] = cells[11]; + + return mergeCellsIntoBlock(output); + } + + /** + * Cell permutation step for decryption . Shifts cells within the rows of + * the input and returns the result. + */ + public static BigInteger shiftRowsDec(BigInteger ciphertext) { + int[] cells = splitBlockIntoCells(ciphertext); + int[] output = new int[16]; + + // do nothing in the first row + output[0] = cells[0]; + output[4] = cells[4]; + output[8] = cells[8]; + output[12] = cells[12]; + + // shift the second row forwards by one cell + output[1] = cells[13]; + output[5] = cells[1]; + output[9] = cells[5]; + output[13] = cells[9]; + + // shift the third row forwards by two cell + output[2] = cells[10]; + output[6] = cells[14]; + output[10] = cells[2]; + output[14] = cells[6]; + + // shift the forth row forwards by tree cell + output[3] = cells[7]; + output[7] = cells[11]; + output[11] = cells[15]; + output[15] = cells[3]; + + return mergeCellsIntoBlock(output); + } + + /** + * Applies the Rijndael MixColumns to the input and returns the result. + */ + public static BigInteger mixColumns(BigInteger ciphertext) { + + int[] cells = splitBlockIntoCells(ciphertext); + int[] outputCells = new int[16]; + + for (int i = 0; i < 4; i++) { + int[] row = {cells[i * 4], cells[i * 4 + 1], cells[i * 4 + 2], 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]]; + } + return mergeCellsIntoBlock(outputCells); + } + + /** + * Applies the inverse Rijndael MixColumns for decryption to the input and + * returns the result. + */ + public static BigInteger mixColumnsDec(BigInteger ciphertext) { + + int[] cells = splitBlockIntoCells(ciphertext); + int[] outputCells = new int[16]; + + for (int i = 0; i < 4; i++) { + int[] row = {cells[i * 4], cells[i * 4 + 1], cells[i * 4 + 2], 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]]; + } + return mergeCellsIntoBlock(outputCells); + } + + /** + * Encrypts the plaintext with the key and returns the result + * + * @param plainText which we want to encrypt + * @param key the key for encrypt + * @return EncryptedText + */ + public static BigInteger encrypt(BigInteger plainText, BigInteger key) { + BigInteger[] roundKeys = keyExpansion(key); + + // Initial round + plainText = addRoundKey(plainText, roundKeys[0]); + + // Main rounds + for (int i = 1; i < 10; i++) { + plainText = subBytes(plainText); + plainText = shiftRows(plainText); + plainText = mixColumns(plainText); + plainText = addRoundKey(plainText, roundKeys[i]); + } + + // Final round + plainText = subBytes(plainText); + plainText = shiftRows(plainText); + plainText = addRoundKey(plainText, roundKeys[10]); + + return plainText; + } + + /** + * Decrypts the ciphertext with the key and returns the result + * + * @param cipherText The Encrypted text which we want to decrypt + * @return decryptedText + */ + public static BigInteger decrypt(BigInteger cipherText, BigInteger key) { + + BigInteger[] roundKeys = keyExpansion(key); + + // Invert final round + cipherText = addRoundKey(cipherText, roundKeys[10]); + cipherText = shiftRowsDec(cipherText); + cipherText = subBytesDec(cipherText); + + // Invert main rounds + for (int i = 9; i > 0; i--) { + cipherText = addRoundKey(cipherText, roundKeys[i]); + cipherText = mixColumnsDec(cipherText); + cipherText = shiftRowsDec(cipherText); + cipherText = subBytesDec(cipherText); + } + + // Invert initial round + cipherText = addRoundKey(cipherText, roundKeys[0]); + + return cipherText; + } + + 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 :"); + char choice = input.nextLine().charAt(0); + String in; + switch (choice) { + case 'E', 'e' -> { + System.out.println("Choose a plaintext block (128-Bit Integer in base 16):"); + in = input.nextLine(); + BigInteger plaintext = new BigInteger(in, 16); + System.out.println("Choose a Key (128-Bit Integer in base 16):"); + in = input.nextLine(); + BigInteger encryptionKey = new BigInteger(in, 16); + System.out.println( + "The encrypted message is: \n" + encrypt(plaintext, encryptionKey).toString(16)); + } + case 'D', 'd' -> { + System.out.println("Enter your ciphertext block (128-Bit Integer in base 16):"); + in = input.nextLine(); + BigInteger ciphertext = new BigInteger(in, 16); + System.out.println("Choose a Key (128-Bit Integer in base 16):"); + in = input.nextLine(); + BigInteger decryptionKey = new BigInteger(in, 16); + System.out.println( + "The deciphered message is:\n" + decrypt(ciphertext, decryptionKey).toString(16)); + } + default -> + System.out.println("** End **"); + } + } + } +} diff --git a/Ciphers/AESEncryption.java b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java similarity index 81% rename from Ciphers/AESEncryption.java rename to src/main/java/com/thealgorithms/ciphers/AESEncryption.java index 9857b49d0e36..81fa79cc90f4 100644 --- a/Ciphers/AESEncryption.java +++ b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java @@ -1,21 +1,23 @@ -package Ciphers; +package com.thealgorithms.ciphers; import javax.crypto.*; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; /** - * This example program shows how AES encryption and decryption can be done in Java. Please note - * that secret key and encrypted text is unreadable binary and hence in the following program we - * display it in hexadecimal format of the underlying bytes. + * This example program shows how AES encryption and decryption can be done in + * Java. Please note that secret key and encrypted text is unreadable binary and + * hence in the following program we display it in hexadecimal format of the + * underlying bytes. */ public class AESEncryption { private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); /** - * 1. Generate a plain text for encryption 2. Get a secret key (printed in hexadecimal form). In - * actual use this must by encrypted and kept safe. The same key is required for decryption. + * 1. Generate a plain text for encryption 2. Get a secret key (printed in + * hexadecimal form). In actual use this must by encrypted and kept safe. + * The same key is required for decryption. */ public static void main(String[] args) throws Exception { String plainText = "Hello World"; @@ -30,7 +32,8 @@ public static void main(String[] args) throws Exception { } /** - * gets the AES encryption key. In your actual programs, this should be safely stored. + * gets the AES encryption key. In your actual programs, this should be + * safely stored. * * @return secKey (Secret key that we encrypt using it) * @throws NoSuchAlgorithmException (from KeyGenrator) @@ -45,10 +48,10 @@ public static SecretKey getSecretEncryptionKey() throws NoSuchAlgorithmException * Encrypts plainText in AES using the secret key * * @return byteCipherText (The encrypted text) - * @throws NoSuchPaddingException (from Cipher) - * @throws NoSuchAlgorithmException (from Cipher) - * @throws InvalidKeyException (from Cipher) - * @throws BadPaddingException (from Cipher) + * @throws NoSuchPaddingException (from Cipher) + * @throws NoSuchAlgorithmException (from Cipher) + * @throws InvalidKeyException (from Cipher) + * @throws BadPaddingException (from Cipher) * @throws IllegalBlockSizeException (from Cipher) */ public static byte[] encryptText(String plainText, SecretKey secKey) @@ -76,8 +79,9 @@ public static String decryptText(byte[] byteCipherText, SecretKey secKey) } /** - * Convert a binary byte array into readable hex form Old library is deprecated on OpenJdk 11 and - * this is faster regarding other solution is using StringBuilder + * Convert a binary byte array into readable hex form Old library is + * deprecated on OpenJdk 11 and this is faster regarding other solution is + * using StringBuilder * * @return hexHash */ diff --git a/Ciphers/AffineCipher.java b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java similarity index 93% rename from Ciphers/AffineCipher.java rename to src/main/java/com/thealgorithms/ciphers/AffineCipher.java index d84fb8432ffe..d08c50533fd7 100644 --- a/Ciphers/AffineCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java @@ -1,4 +1,4 @@ -package Ciphers; +package com.thealgorithms.ciphers; class AffineCipher { @@ -46,8 +46,8 @@ static String decryptCipher(String cipher) { {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'); + msg = msg + (char) (((a_inv + * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A'); } else //else simply append space character { msg += cipher.charAt(i); @@ -70,4 +70,3 @@ public static void main(String[] args) { } } - diff --git a/Ciphers/Caesar.java b/src/main/java/com/thealgorithms/ciphers/Caesar.java similarity index 93% rename from Ciphers/Caesar.java rename to src/main/java/com/thealgorithms/ciphers/Caesar.java index 70f6b5266a68..03e823f2a4f0 100644 --- a/Ciphers/Caesar.java +++ b/src/main/java/com/thealgorithms/ciphers/Caesar.java @@ -1,10 +1,11 @@ -package Ciphers; +package com.thealgorithms.ciphers; import java.util.Scanner; /** - * A Java implementation of Caesar Cipher. /It is a type of substitution cipher in which each letter - * in the plaintext is replaced by a letter some fixed number of positions down the alphabet. / + * A Java implementation of Caesar Cipher. /It is a type of substitution cipher + * in which each letter in the plaintext is replaced by a letter some fixed + * number of positions down the alphabet. / * * @author FAHRI YARDIMCI * @author khalil2535 @@ -12,7 +13,8 @@ public class Caesar { /** - * Encrypt text by shifting every Latin char by add number shift for ASCII Example : A + 1 -> B + * Encrypt text by shifting every Latin char by add number shift for ASCII + * Example : A + 1 -> B * * @return Encrypted message */ @@ -46,7 +48,8 @@ public static String encode(String message, int shift) { } /** - * Decrypt message by shifting back every Latin char to previous the ASCII Example : B - 1 -> A + * Decrypt message by shifting back every Latin char to previous the ASCII + * Example : B - 1 -> A * * @return message */ diff --git a/Ciphers/ColumnarTranspositionCipher.java b/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java similarity index 89% rename from Ciphers/ColumnarTranspositionCipher.java rename to src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java index ab5df61ea336..4c699a28eba0 100644 --- a/Ciphers/ColumnarTranspositionCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java @@ -1,4 +1,4 @@ -package Ciphers; +package com.thealgorithms.ciphers; import java.util.Objects; @@ -12,17 +12,18 @@ 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 = '≈'; /** * Encrypts a certain String with the Columnar Transposition Cipher Rule * - * @param word Word being encrypted + * @param word Word being encrypted * @param keyword String with keyword being used - * @return a String with the word encrypted by the Columnar Transposition Cipher Rule + * @return a String with the word encrypted by the Columnar Transposition + * Cipher Rule */ public static String encrpyter(String word, String keyword) { ColumnarTranspositionCipher.keyword = keyword; @@ -41,10 +42,12 @@ public static String encrpyter(String word, String keyword) { /** * Encrypts a certain String with the Columnar Transposition Cipher Rule * - * @param word Word being encrypted - * @param keyword String with keyword being used - * @param abecedarium String with the abecedarium being used. null for default one - * @return a String with the word encrypted by the Columnar Transposition Cipher Rule + * @param word Word being encrypted + * @param keyword String with keyword being used + * @param abecedarium String with the abecedarium being used. null for + * default one + * @return a String with the word encrypted by the Columnar Transposition + * Cipher Rule */ public static String encrpyter(String word, String keyword, String abecedarium) { ColumnarTranspositionCipher.keyword = keyword; @@ -61,9 +64,11 @@ public static String encrpyter(String word, String keyword, String abecedarium) } /** - * Decrypts a certain encrypted String with the Columnar Transposition Cipher Rule + * Decrypts a certain encrypted String with the Columnar Transposition + * Cipher Rule * - * @return a String decrypted with the word encrypted by the Columnar Transposition Cipher Rule + * @return a String decrypted with the word encrypted by the Columnar + * Transposition Cipher Rule */ public static String decrypter() { StringBuilder wordDecrypted = new StringBuilder(); @@ -76,9 +81,11 @@ public static String decrypter() { } /** - * Builds a table with the word to be encrypted in rows by the Columnar Transposition Cipher Rule + * Builds a table with the word to be encrypted in rows by the Columnar + * Transposition Cipher Rule * - * @return An Object[][] with the word to be encrypted filled in rows and columns + * @return An Object[][] with the word to be encrypted filled in rows and + * columns */ private static Object[][] tableBuilder(String word) { Object[][] table = new Object[numberOfRows(word) + 1][keyword.length()]; @@ -100,11 +107,11 @@ private static Object[][] tableBuilder(String word) { } /** - * Determines the number of rows the table should have regarding the Columnar Transposition Cipher - * Rule + * Determines the number of rows the table should have regarding the + * Columnar Transposition Cipher Rule * - * @return an int with the number of rows that the table should have in order to respect the - * Columnar Transposition Cipher Rule. + * @return an int with the number of rows that the table should have in + * order to respect the Columnar Transposition Cipher Rule. */ private static int numberOfRows(String word) { if (word.length() / keyword.length() > word.length() / keyword.length()) { @@ -193,7 +200,7 @@ public static void main(String[] args) { System.out.println("Word being encryped ->>> " + wordBeingEncrypted); System.out.println( "Word encrypted ->>> " - + ColumnarTranspositionCipher.encrpyter(wordBeingEncrypted, keywordForExample)); + + ColumnarTranspositionCipher.encrpyter(wordBeingEncrypted, keywordForExample)); System.out.println("Word decryped ->>> " + ColumnarTranspositionCipher.decrypter()); System.out.println("\n### Encrypted Table ###"); showTable(); diff --git a/Ciphers/HillCipher.java b/src/main/java/com/thealgorithms/ciphers/HillCipher.java similarity index 93% rename from Ciphers/HillCipher.java rename to src/main/java/com/thealgorithms/ciphers/HillCipher.java index 2150576ffc00..c0f6aef12ea8 100644 --- a/Ciphers/HillCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/HillCipher.java @@ -1,165 +1,170 @@ -package Ciphers; - -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. - * @author Ojasva Jain - */ - -public class HillCipher { - static Scanner in = new Scanner(System.in); - - /* Following function encrypts the message - */ - static void encrypt(String message) { - message = message.toUpperCase(); - // Get key matrix - System.out.println("Enter key matrix size"); - int n = in.nextInt(); - System.out.println("Enter Key/encryptionKey matrix "); - int keyMatrix[][] = new int[n][n]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - keyMatrix[i][j] = in.nextInt(); - } - } - //check if det = 0 - if (determinant(keyMatrix, n) % 26 == 0) { - System.out.println("Invalid key, as determinant = 0. Program Terminated"); - return; - } - - int[][] messageVector = new int[n][1]; - String CipherText = ""; - int cipherMatrix[][] = new int[n][1]; - int j = 0; - while (j < message.length()) { - for (int i = 0; i < n; i++) { - if (j >= message.length()) { - messageVector[i][0] = 23; - } else - messageVector[i][0] = (message.charAt(j)) % 65; - System.out.println(messageVector[i][0]); - j++; - } - int x, i; - for (i = 0; i < n; i++) { - cipherMatrix[i][0] = 0; - - for (x = 0; x < n; x++) { - cipherMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0]; - } - System.out.println(cipherMatrix[i][0]); - cipherMatrix[i][0] = cipherMatrix[i][0] % 26; - } - for (i = 0; i < n; i++) - CipherText += (char) (cipherMatrix[i][0] + 65); - } - System.out.println("Ciphertext: " + CipherText); - } - - //Following function decrypts a message - static void decrypt(String message) { - message = message.toUpperCase(); - // Get key matrix - System.out.println("Enter key matrix size"); - int n = in.nextInt(); - System.out.println("Enter inverseKey/decryptionKey matrix "); - int keyMatrix[][] = new int[n][n]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - keyMatrix[i][j] = in.nextInt(); - } - } - //check if det = 0 - if (determinant(keyMatrix, n) % 26 == 0) { - System.out.println("Invalid key, as determinant = 0. Program Terminated"); - return; - } - //solving for the required plaintext message - int[][] messageVector = new int[n][1]; - String PlainText = ""; - int plainMatrix[][] = new int[n][1]; - int j = 0; - while (j < message.length()) { - for (int i = 0; i < n; i++) { - if (j >= message.length()) { - messageVector[i][0] = 23; - } else - messageVector[i][0] = (message.charAt(j)) % 65; - System.out.println(messageVector[i][0]); - j++; - } - int x, i; - for (i = 0; i < n; i++) { - plainMatrix[i][0] = 0; - - for (x = 0; x < n; x++) { - plainMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0]; - } - - plainMatrix[i][0] = plainMatrix[i][0] % 26; - } - for (i = 0; i < n; i++) - PlainText += (char) (plainMatrix[i][0] + 65); - } - System.out.println("Plaintext: " + PlainText); - } - - // Determinant calculator - public static int determinant(int a[][], int n) { - int det = 0, sign = 1, p = 0, q = 0; - - if (n == 1) { - det = a[0][0]; - } else { - int b[][] = new int[n - 1][n - 1]; - for (int x = 0; x < n; x++) { - p = 0; - q = 0; - for (int i = 1; i < n; i++) { - for (int j = 0; j < n; j++) { - if (j != x) { - b[p][q++] = a[i][j]; - if (q % (n - 1) == 0) { - p++; - q = 0; - } - } - } - } - det = det + a[0][x] * determinant(b, n - 1) * sign; - sign = -sign; - } - } - return det; - } - - // Function to implement Hill Cipher - static void hillcipher(String message) { - message.toUpperCase(); - System.out.println("What do you want to process from the message?"); - System.out.println("Press 1: To Encrypt"); - System.out.println("Press 2: To Decrypt"); - short sc = in.nextShort(); - if (sc == 1) - encrypt(message); - else if (sc == 2) - decrypt(message); - else - System.out.println("Invalid input, program terminated."); - } - - // Driver code - public static void main(String[] args) { - // Get the message to be encrypted - System.out.println("Enter message"); - String message = in.nextLine(); - hillcipher(message); - } -} +package com.thealgorithms.ciphers; + +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. + * @author Ojasva Jain + */ +public class HillCipher { + + static Scanner in = new Scanner(System.in); + + /* Following function encrypts the message + */ + static void encrypt(String message) { + message = message.toUpperCase(); + // Get key matrix + System.out.println("Enter key matrix size"); + int n = in.nextInt(); + System.out.println("Enter Key/encryptionKey matrix "); + int keyMatrix[][] = new int[n][n]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + keyMatrix[i][j] = in.nextInt(); + } + } + //check if det = 0 + if (determinant(keyMatrix, n) % 26 == 0) { + System.out.println("Invalid key, as determinant = 0. Program Terminated"); + return; + } + + int[][] messageVector = new int[n][1]; + String CipherText = ""; + int cipherMatrix[][] = new int[n][1]; + int j = 0; + while (j < message.length()) { + for (int i = 0; i < n; i++) { + if (j >= message.length()) { + messageVector[i][0] = 23; + } else { + messageVector[i][0] = (message.charAt(j)) % 65; + } + System.out.println(messageVector[i][0]); + j++; + } + int x, i; + for (i = 0; i < n; i++) { + cipherMatrix[i][0] = 0; + + for (x = 0; x < n; x++) { + cipherMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0]; + } + System.out.println(cipherMatrix[i][0]); + cipherMatrix[i][0] = cipherMatrix[i][0] % 26; + } + for (i = 0; i < n; i++) { + CipherText += (char) (cipherMatrix[i][0] + 65); + } + } + System.out.println("Ciphertext: " + CipherText); + } + + //Following function decrypts a message + static void decrypt(String message) { + message = message.toUpperCase(); + // Get key matrix + System.out.println("Enter key matrix size"); + int n = in.nextInt(); + System.out.println("Enter inverseKey/decryptionKey matrix "); + int keyMatrix[][] = new int[n][n]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + keyMatrix[i][j] = in.nextInt(); + } + } + //check if det = 0 + if (determinant(keyMatrix, n) % 26 == 0) { + System.out.println("Invalid key, as determinant = 0. Program Terminated"); + return; + } + //solving for the required plaintext message + int[][] messageVector = new int[n][1]; + String PlainText = ""; + int plainMatrix[][] = new int[n][1]; + int j = 0; + while (j < message.length()) { + for (int i = 0; i < n; i++) { + if (j >= message.length()) { + messageVector[i][0] = 23; + } else { + messageVector[i][0] = (message.charAt(j)) % 65; + } + System.out.println(messageVector[i][0]); + j++; + } + int x, i; + for (i = 0; i < n; i++) { + plainMatrix[i][0] = 0; + + for (x = 0; x < n; x++) { + plainMatrix[i][0] += keyMatrix[i][x] * messageVector[x][0]; + } + + plainMatrix[i][0] = plainMatrix[i][0] % 26; + } + for (i = 0; i < n; i++) { + PlainText += (char) (plainMatrix[i][0] + 65); + } + } + System.out.println("Plaintext: " + PlainText); + } + + // Determinant calculator + public static int determinant(int a[][], int n) { + int det = 0, sign = 1, p = 0, q = 0; + + if (n == 1) { + det = a[0][0]; + } else { + int b[][] = new int[n - 1][n - 1]; + for (int x = 0; x < n; x++) { + p = 0; + q = 0; + for (int i = 1; i < n; i++) { + for (int j = 0; j < n; j++) { + if (j != x) { + b[p][q++] = a[i][j]; + if (q % (n - 1) == 0) { + p++; + q = 0; + } + } + } + } + det = det + a[0][x] * determinant(b, n - 1) * sign; + sign = -sign; + } + } + return det; + } + + // Function to implement Hill Cipher + static void hillcipher(String message) { + message.toUpperCase(); + System.out.println("What do you want to process from the message?"); + System.out.println("Press 1: To Encrypt"); + System.out.println("Press 2: To Decrypt"); + short sc = in.nextShort(); + if (sc == 1) { + encrypt(message); + } else if (sc == 2) { + decrypt(message); + } else { + System.out.println("Invalid input, program terminated."); + } + } + + // Driver code + public static void main(String[] args) { + // Get the message to be encrypted + System.out.println("Enter message"); + String message = in.nextLine(); + hillcipher(message); + } +} diff --git a/Ciphers/ProductCipher.java b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java similarity index 98% rename from Ciphers/ProductCipher.java rename to src/main/java/com/thealgorithms/ciphers/ProductCipher.java index ce6b088d7dac..39683b3e79b3 100644 --- a/Ciphers/ProductCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java @@ -1,4 +1,4 @@ -package Ciphers; +package com.thealgorithms.ciphers; import java.util.Scanner; diff --git a/Ciphers/RSA.java b/src/main/java/com/thealgorithms/ciphers/RSA.java similarity index 98% rename from Ciphers/RSA.java rename to src/main/java/com/thealgorithms/ciphers/RSA.java index e7f94be21feb..27b4b457f5bb 100644 --- a/Ciphers/RSA.java +++ b/src/main/java/com/thealgorithms/ciphers/RSA.java @@ -1,4 +1,4 @@ -package Ciphers; +package com.thealgorithms.ciphers; import javax.swing.*; import java.math.BigInteger; diff --git a/Ciphers/SimpleSubCipher.java b/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java similarity index 82% rename from Ciphers/SimpleSubCipher.java rename to src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java index 2e47700fdcb2..56e5baf38447 100644 --- a/Ciphers/SimpleSubCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java @@ -1,16 +1,15 @@ -package ciphers; +package com.thealgorithms.ciphers; import java.util.HashMap; import java.util.Map; /** - * The simple substitution cipher is a cipher that has been in use for many hundreds of years - * (an excellent history is given in Simon Singhs 'the Code Book'). - * It basically consists of substituting every plaintext character for a different ciphertext character. - * It differs from the Caesar cipher in that the cipher alphabet is not simply the alphabet shifted, - * it is completely jumbled. + * The simple substitution cipher is a cipher that has been in use for many + * hundreds of years (an excellent history is given in Simon Singhs 'the Code + * Book'). It basically consists of substituting every plaintext character for a + * different ciphertext character. It differs from the Caesar cipher in that the + * cipher alphabet is not simply the alphabet shifted, it is completely jumbled. */ - public class SimpleSubCipher { /** @@ -39,17 +38,19 @@ public static String encode(String message, String cipherSmall) { } for (int i = 0; i < message.length(); i++) { - if (Character.isAlphabetic(message.charAt(i))) + if (Character.isAlphabetic(message.charAt(i))) { encoded += cipherMap.get(message.charAt(i)); - else + } else { encoded += message.charAt(i); + } } return encoded; } /** - * Decrypt message by replacing each element with its opposite character in cipher. + * Decrypt message by replacing each element with its opposite character in + * cipher. * * @param encryptedMessage * @param cipherSmall @@ -58,7 +59,6 @@ public static String encode(String message, String cipherSmall) { public static String decode(String encryptedMessage, String cipherSmall) { String decoded = ""; - Map cipherMap = new HashMap(); char beginSmallLetter = 'a'; @@ -73,10 +73,11 @@ public static String decode(String encryptedMessage, String cipherSmall) { } for (int i = 0; i < encryptedMessage.length(); i++) { - if (Character.isAlphabetic(encryptedMessage.charAt(i))) + if (Character.isAlphabetic(encryptedMessage.charAt(i))) { decoded += cipherMap.get(encryptedMessage.charAt(i)); - else + } else { decoded += encryptedMessage.charAt(i); + } } return decoded; diff --git a/Ciphers/SimpleSubstitutionCipher.java b/src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java similarity index 76% rename from Ciphers/SimpleSubstitutionCipher.java rename to src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java index 7b924b0eb0e7..ac68c7a4a907 100644 --- a/Ciphers/SimpleSubstitutionCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/SimpleSubstitutionCipher.java @@ -1,14 +1,14 @@ -package Ciphers; +package com.thealgorithms.ciphers; import java.util.HashMap; import java.util.Map; /** - * The simple substitution cipher is a cipher that has been in use for many hundreds of years (an - * excellent history is given in Simon Singhs 'the Code Book'). It basically consists of - * substituting every plaintext character for a different ciphertext character. It differs from the - * Caesar cipher in that the cipher alphabet is not simply the alphabet shifted, it is completely - * jumbled. + * The simple substitution cipher is a cipher that has been in use for many + * hundreds of years (an excellent history is given in Simon Singhs 'the Code + * Book'). It basically consists of substituting every plaintext character for a + * different ciphertext character. It differs from the Caesar cipher in that the + * cipher alphabet is not simply the alphabet shifted, it is completely jumbled. * * @author Hassan Elseoudy */ @@ -38,15 +38,19 @@ public static String encode(String message, String cipherSmall) { } for (int i = 0; i < message.length(); i++) { - if (Character.isAlphabetic(message.charAt(i))) encoded.append(cipherMap.get(message.charAt(i))); - else encoded.append(message.charAt(i)); + if (Character.isAlphabetic(message.charAt(i))) { + encoded.append(cipherMap.get(message.charAt(i))); + } else { + encoded.append(message.charAt(i)); + } } return encoded.toString(); } /** - * Decrypt message by replacing each element with its opposite character in cipher. + * Decrypt message by replacing each element with its opposite character in + * cipher. * * @return message */ @@ -67,9 +71,11 @@ public static String decode(String encryptedMessage, String cipherSmall) { } for (int i = 0; i < encryptedMessage.length(); i++) { - if (Character.isAlphabetic(encryptedMessage.charAt(i))) + if (Character.isAlphabetic(encryptedMessage.charAt(i))) { decoded.append(cipherMap.get(encryptedMessage.charAt(i))); - else decoded.append(encryptedMessage.charAt(i)); + } else { + decoded.append(encryptedMessage.charAt(i)); + } } return decoded.toString(); diff --git a/Ciphers/Vigenere.java b/src/main/java/com/thealgorithms/ciphers/Vigenere.java similarity index 98% rename from Ciphers/Vigenere.java rename to src/main/java/com/thealgorithms/ciphers/Vigenere.java index 680ae31ecc4f..ced26792cd5b 100644 --- a/Ciphers/Vigenere.java +++ b/src/main/java/com/thealgorithms/ciphers/Vigenere.java @@ -1,4 +1,4 @@ -package Ciphers; +package com.thealgorithms.ciphers; /** * A Java implementation of Vigenere Cipher. diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java new file mode 100644 index 000000000000..5c0722e0d4c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java @@ -0,0 +1,145 @@ +package com.thealgorithms.conversions; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.InputMismatchException; +import java.util.Scanner; + +/** + * Class for converting from "any" base to "any" other base, when "any" means + * from 2-36. Works by going from base 1 to decimal to base 2. Includes + * auxiliary method for determining whether a number is valid for a given base. + * + * @author Michael Rolland + * @version 2017.10.10 + */ +public class AnyBaseToAnyBase { + + /** + * Smallest and largest base you want to accept as valid input + */ + static final int MINIMUM_BASE = 2; + + static final int MAXIMUM_BASE = 36; + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + String n; + int b1, b2; + while (true) { + try { + System.out.print("Enter number: "); + n = in.next(); + 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!"); + continue; + } + if (!validForBase(n, b1)) { + System.out.println("The number is invalid for this base!"); + continue; + } + System.out.print( + "Enter end base (between " + MINIMUM_BASE + " and " + MAXIMUM_BASE + "): "); + b2 = in.nextInt(); + if (b2 > MAXIMUM_BASE || b2 < MINIMUM_BASE) { + System.out.println("Invalid base!"); + continue; + } + break; + } catch (InputMismatchException e) { + System.out.println("Invalid input."); + in.next(); + } + } + System.out.println(base2base(n, b1, b2)); + in.close(); + } + + /** + * Checks if a number (as a String) is valid for a given base. + */ + public static boolean validForBase(String n, int base) { + char[] validDigits = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', + 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' + }; + // digitsForBase contains all the valid digits for the base given + char[] digitsForBase = Arrays.copyOfRange(validDigits, 0, base); + + // Convert character array into set for convenience of contains() method + HashSet digitsList = new HashSet<>(); + for (int i = 0; i < digitsForBase.length; i++) { + digitsList.add(digitsForBase[i]); + } + + // Check that every digit in n is within the list of valid digits for that base. + for (char c : n.toCharArray()) { + if (!digitsList.contains(c)) { + return false; + } + } + + return true; + } + + /** + * Method to convert any integer from base b1 to base b2. Works by + * converting from b1 to decimal, then decimal to b2. + * + * @param n The integer to be converted. + * @param b1 Beginning base. + * @param b2 End base. + * @return n in base b2. + */ + public static String base2base(String n, int b1, int b2) { + // Declare variables: decimal value of n, + // character of base b1, character of base b2, + // and the string that will be returned. + int decimalValue = 0, charB2; + char charB1; + String output = ""; + // Go through every character of n + for (int i = 0; i < n.length(); i++) { + // store the character in charB1 + charB1 = n.charAt(i); + // if it is a non-number, convert it to a decimal value >9 and store it in charB2 + if (charB1 >= 'A' && charB1 <= 'Z') { + charB2 = 10 + (charB1 - 'A'); + } // Else, store the integer value in charB2 + else { + charB2 = charB1 - '0'; + } + // Convert the digit to decimal and add it to the + // decimalValue of n + decimalValue = decimalValue * b1 + charB2; + } + + // Converting the decimal value to base b2: + // A number is converted from decimal to another base + // by continuously dividing by the base and recording + // the remainder until the quotient is zero. The number in the + // new base is the remainders, with the last remainder + // being the left-most digit. + if (0 == decimalValue) { + return "0"; + } + // While the quotient is NOT zero: + while (decimalValue != 0) { + // If the remainder is a digit < 10, simply add it to + // the left side of the new number. + if (decimalValue % b2 < 10) { + output = Integer.toString(decimalValue % b2) + output; + } // If the remainder is >= 10, add a character with the + // corresponding value to the new number. (A = 10, B = 11, C = 12, ...) + else { + output = (char) ((decimalValue % b2) + 55) + output; + } + // Divide by the new base again + decimalValue /= b2; + } + return output; + } +} diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java new file mode 100644 index 000000000000..837b35305c80 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java @@ -0,0 +1,54 @@ +package com.thealgorithms.conversions; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +// Driver program +public class AnyBaseToDecimal { + + public static void main(String[] args) { + assert convertToDecimal("1010", 2) == Integer.valueOf("1010", 2); + assert convertToDecimal("777", 8) == Integer.valueOf("777", 8); + assert convertToDecimal("999", 10) == Integer.valueOf("999", 10); + assert convertToDecimal("ABCDEF", 16) == Integer.valueOf("ABCDEF", 16); + assert convertToDecimal("XYZ", 36) == Integer.valueOf("XYZ", 36); + } + + /** + * Convert any radix to decimal number + * + * @param s the string to be convert + * @param radix the radix + * @return decimal of bits + * @throws NumberFormatException if {@code bits} or {@code radix} is invalid + */ + public static int convertToDecimal(String s, int radix) { + int num = 0; + int pow = 1; + + for (int i = s.length() - 1; i >= 0; i--) { + int digit = valOfChar(s.charAt(i)); + if (digit >= radix) { + throw new NumberFormatException("For input string " + s); + } + num += valOfChar(s.charAt(i)) * pow; + pow *= radix; + } + return num; + } + + /** + * Convert character to integer + * + * @param c the character + * @return represented digit of given character + * @throws NumberFormatException if {@code ch} is not UpperCase or Digit + * character. + */ + public static int valOfChar(char c) { + if (!(Character.isUpperCase(c) || Character.isDigit(c))) { + throw new NumberFormatException("invalid character :" + c); + } + return Character.isDigit(c) ? c - '0' : c - 'A' + 10; + } +} diff --git a/src/main/java/com/thealgorithms/conversions/AnytoAny.java b/src/main/java/com/thealgorithms/conversions/AnytoAny.java new file mode 100644 index 000000000000..3eed1fce0fa6 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/AnytoAny.java @@ -0,0 +1,30 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; +// given a source number , source base, destination base, this code can give you the destination +// number. +// sn ,sb,db ---> ()dn . this is what we have to do . + +public class AnytoAny { + + public static void main(String[] args) { + Scanner scn = new Scanner(System.in); + int sn = scn.nextInt(); + int sb = scn.nextInt(); + int db = scn.nextInt(); + int m = 1, dec = 0, dn = 0; + while (sn != 0) { + dec = dec + (sn % 10) * m; + m *= sb; + sn /= 10; + } + m = 1; + while (dec != 0) { + dn = dn + (dec % db) * m; + m *= 10; + dec /= db; + } + System.out.println(dn); + scn.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java new file mode 100644 index 000000000000..95de43c54ae8 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java @@ -0,0 +1,29 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * This class converts a Binary number to a Decimal number + */ +class BinaryToDecimal { + + /** + * Main Method + * + * @param args Command line arguments + */ + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + int binNum, binCopy, d, s = 0, power = 0; + System.out.print("Binary number: "); + binNum = sc.nextInt(); + binCopy = binNum; + while (binCopy != 0) { + d = binCopy % 10; + s += d * (int) Math.pow(2, power++); + binCopy /= 10; + } + System.out.println("Decimal equivalent:" + s); + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java new file mode 100644 index 000000000000..c942cbb7d843 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java @@ -0,0 +1,57 @@ +package com.thealgorithms.conversions; + +import java.util.*; + +/** + * Converts any Binary Number to a Hexadecimal Number + * + * @author Nishita Aggarwal + */ +public class BinaryToHexadecimal { + + /** + * This method converts a binary number to a hexadecimal number. + * + * @param binary The binary number + * @return The hexadecimal number + */ + static String binToHex(int binary) { + // hm to store hexadecimal codes for binary numbers within the range: 0000 to 1111 i.e. for + // decimal numbers 0 to 15 + HashMap hm = new HashMap<>(); + // String to store hexadecimal code + String hex = ""; + int i; + for (i = 0; i < 10; i++) { + hm.put(i, String.valueOf(i)); + } + for (i = 10; i < 16; i++) { + hm.put(i, String.valueOf((char) ('A' + i - 10))); + } + int currbit; + while (binary != 0) { + int code4 = 0; // to store decimal equivalent of number formed by 4 decimal digits + for (i = 0; i < 4; i++) { + currbit = binary % 10; + binary = binary / 10; + code4 += currbit * Math.pow(2, i); + } + hex = hm.get(code4) + hex; + } + return hex; + } + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.println("Enter binary number:"); + int binary = sc.nextInt(); + String hex = binToHex(binary); + System.out.println("Hexadecimal Code:" + hex); + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java b/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java new file mode 100644 index 000000000000..b0d6b32fd63b --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java @@ -0,0 +1,47 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Binary number to an Octal Number + * + * @author Zachary Jones + */ +public class BinaryToOctal { + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + System.out.println("Input the binary number: "); + int b = sc.nextInt(); + System.out.println("Octal equivalent: " + convertBinaryToOctal(b)); + sc.close(); + } + + /** + * This method converts a binary number to an octal number. + * + * @param binary The binary number + * @return The octal number + */ + public static String convertBinaryToOctal(int binary) { + String octal = ""; + int currBit = 0, j = 1; + while (binary != 0) { + int code3 = 0; + for (int i = 0; i < 3; i++) { + currBit = binary % 10; + binary = binary / 10; + code3 += currBit * j; + j *= 2; + } + octal = code3 + octal; + j = 1; + } + return octal; + } +} diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java new file mode 100644 index 000000000000..8ef4737b17c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java @@ -0,0 +1,67 @@ +package com.thealgorithms.conversions; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +// Driver Program +public class DecimalToAnyBase { + + public static void main(String[] args) throws Exception { + 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(); + + System.out.println("Enter the base below: "); + 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)); + + br.close(); + } + + /** + * This method produces a String value of any given input decimal in any + * base + * + * @param inp Decimal of which we need the value in base in String format + * @return string format of the converted value in the given base + */ + public static String convertToAnyBase(int inp, int base) { + ArrayList charArr = new ArrayList<>(); + + while (inp > 0) { + charArr.add(reVal(inp % base)); + inp /= base; + } + + StringBuilder str = new StringBuilder(charArr.size()); + + for (Character ch : charArr) { + str.append(ch); + } + + return str.reverse().toString(); + } + + /** + * This method produces character value of the input integer and returns it + * + * @param num integer of which we need the character value of + * @return character value of input integer + */ + public static char reVal(int num) { + if (num >= 0 && num <= 9) { + return (char) (num + '0'); + } else { + return (char) (num - 10 + 'A'); + } + } +} diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java b/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java new file mode 100644 index 000000000000..35cec4079ed6 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java @@ -0,0 +1,55 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * This class converts a Decimal number to a Binary number + */ +class DecimalToBinary { + + /** + * Main Method + * + * @param args Command Line Arguments + */ + public static void main(String args[]) { + conventionalConversion(); + bitwiseConversion(); + } + + /** + * This method converts a decimal number to a binary number using a + * conventional algorithm. + */ + 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: "); + n = input.nextInt(); + while (n != 0) { + d = n % 2; + b = b + d * (int) Math.pow(10, c++); + n /= 2; + } // converting decimal to binary + System.out.println("\tBinary number: " + b); + input.close(); + } + + /** + * This method converts a decimal number to a binary number using a bitwise + * algorithm + */ + public static void bitwiseConversion() { + int n, b = 0, c = 0, d; + Scanner input = new Scanner(System.in); + System.out.printf("Bitwise conversion.%n Enter the decimal number: "); + n = input.nextInt(); + while (n != 0) { + d = (n & 1); + b += d * (int) Math.pow(10, c++); + n >>= 1; + } + System.out.println("\tBinary number: " + b); + input.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java b/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java new file mode 100644 index 000000000000..83129406cf29 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java @@ -0,0 +1,34 @@ +package com.thealgorithms.conversions; + +// hex = [0 - 9] -> [A - F] +class DecimalToHexaDecimal { + + private static final int sizeOfIntInHalfBytes = 8; + private static final int numberOfBitsInAHalfByte = 4; + private static final int halfByte = 0x0F; + private static final char[] hexDigits = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + // Returns the hex value of the dec entered in the parameter. + public static String decToHex(int dec) { + StringBuilder hexBuilder = new StringBuilder(sizeOfIntInHalfBytes); + hexBuilder.setLength(sizeOfIntInHalfBytes); + for (int i = sizeOfIntInHalfBytes - 1; i >= 0; --i) { + int j = dec & halfByte; + hexBuilder.setCharAt(i, hexDigits[j]); + dec >>= numberOfBitsInAHalfByte; + } + return hexBuilder.toString().toLowerCase(); + } + + // Test above function. + public static void main(String[] args) { + System.out.println("Test..."); + int dec = 305445566; + String libraryDecToHex = Integer.toHexString(dec); + String decToHex = decToHex(dec); + System.out.println("Result from the library : " + libraryDecToHex); + System.out.println("Result decToHex method : " + decToHex); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java b/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java new file mode 100644 index 000000000000..0f72f462c753 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java @@ -0,0 +1,32 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * This class converts Decimal numbers to Octal Numbers + */ +public class DecimalToOctal { + + /** + * Main Method + * + * @param args Command line Arguments + */ + + // enter in a decimal value to get Octal output + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n, k, d, s = 0, c = 0; + System.out.print("Decimal number: "); + n = sc.nextInt(); + k = n; + while (k != 0) { + d = k % 8; + s += d * (int) Math.pow(10, c++); + k /= 8; + } + + System.out.println("Octal equivalent:" + s); + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/HexToOct.java b/src/main/java/com/thealgorithms/conversions/HexToOct.java new file mode 100644 index 000000000000..92057c953b60 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/HexToOct.java @@ -0,0 +1,74 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Hexadecimal Number to Octal + * + * @author Tanmay Joshi + */ +public class HexToOct { + + /** + * This method converts a Hexadecimal number to a decimal number + * + * @param s The Hexadecimal Number + * @return The Decimal number + */ + public static int hex2decimal(String s) { + String str = "0123456789ABCDEF"; + s = s.toUpperCase(); + int val = 0; + for (int i = 0; i < s.length(); i++) { + char a = s.charAt(i); + int n = str.indexOf(a); + val = 16 * val + n; + } + return val; + } + + /** + * This method converts a Decimal number to a octal number + * + * @param q The Decimal Number + * @return The Octal number + */ + public static int decimal2octal(int q) { + int now; + int i = 1; + int octnum = 0; + while (q > 0) { + now = q % 8; + octnum = (now * (int) (Math.pow(10, i))) + octnum; + q /= 8; + i++; + } + octnum /= 10; + return octnum; + } + + /** + * Main method that gets the hex input from user and converts it into octal. + * + * @param args arguments + */ + public static void main(String args[]) { + String hexadecnum; + int decnum, octalnum; + Scanner scan = new Scanner(System.in); + + System.out.print("Enter Hexadecimal Number : "); + hexadecnum = scan.nextLine(); + + // first convert hexadecimal to decimal + decnum + = hex2decimal( + hexadecnum); // Pass the string to the hex2decimal function and get the decimal form in + // variable decnum + + // convert decimal to octal + octalnum = decimal2octal(decnum); + System.out.println("Number in octal: " + octalnum); + scan.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java b/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java new file mode 100644 index 000000000000..ef070ae7986a --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java @@ -0,0 +1,34 @@ +package com.thealgorithms.conversions; + +// Hex [0-9],[A-F] -> Binary [0,1] +public class HexaDecimalToBinary { + + private final int LONG_BITS = 8; + + public void convert(String numHex) { + // String a HexaDecimal: + int conHex = Integer.parseInt(numHex, 16); + // Hex a Binary: + String binary = Integer.toBinaryString(conHex); + // Output: + System.out.println(numHex + " = " + completeDigits(binary)); + } + + public String completeDigits(String binNum) { + for (int i = binNum.length(); i < LONG_BITS; i++) { + binNum = "0" + binNum; + } + return binNum; + } + + public static void main(String[] args) { + + // Testing Numbers: + String[] hexNums = {"1", "A1", "ef", "BA", "AA", "BB", "19", "01", "02", "03", "04"}; + HexaDecimalToBinary objConvert = new HexaDecimalToBinary(); + + for (String num : hexNums) { + objConvert.convert(num); + } + } +} diff --git a/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java b/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java new file mode 100644 index 000000000000..cb9d7fafde8f --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java @@ -0,0 +1,37 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +public class HexaDecimalToDecimal { + + // convert hexadecimal to decimal + public static int getHexaToDec(String hex) { + String digits = "0123456789ABCDEF"; + hex = hex.toUpperCase(); + int val = 0; + for (int i = 0; i < hex.length(); i++) { + int d = digits.indexOf(hex.charAt(i)); + val = 16 * val + d; + } + return val; + } + + // Main method gets the hexadecimal input from user and converts it into Decimal output. + public static void main(String args[]) { + String hexa_Input; + int dec_output; + Scanner scan = new Scanner(System.in); + + System.out.print("Enter Hexadecimal Number : "); + hexa_Input = scan.nextLine(); + + // convert hexadecimal to decimal + dec_output = getHexaToDec(hexa_Input); + /* + Pass the string to the getHexaToDec function + and it returns the decimal form in the variable dec_output. + */ + System.out.println("Number in Decimal: " + dec_output); + scan.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java b/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java new file mode 100644 index 000000000000..53c07d58c4fd --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java @@ -0,0 +1,40 @@ +package com.thealgorithms.conversions; + +/** + * Converting Integers into Roman Numerals + * + *

+ * ('I', 1); ('IV',4); ('V', 5); ('IX',9); ('X', 10); ('XL',40); ('L', 50); + * ('XC',90); ('C', 100); ('D', 500); ('M', 1000); + */ +public class IntegerToRoman { + + private static int[] allArabianRomanNumbers + = new int[]{1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + private static String[] allRomanNumbers + = new String[]{"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; + + // Value must be > 0 + public static String integerToRoman(int num) { + if (num <= 0) { + return ""; + } + + StringBuilder builder = new StringBuilder(); + + for (int a = 0; a < allArabianRomanNumbers.length; a++) { + int times = num / allArabianRomanNumbers[a]; + for (int b = 0; b < times; b++) { + builder.append(allRomanNumbers[a]); + } + + num -= times * allArabianRomanNumbers[a]; + } + + return builder.toString(); + } + + public static void main(String[] args) { + System.out.println(IntegerToRoman.integerToRoman(2131)); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java b/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java new file mode 100644 index 000000000000..978adee4b7db --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java @@ -0,0 +1,47 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Octal Number to a Decimal Number + * + * @author Zachary Jones + */ +public class OctalToDecimal { + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + System.out.print("Octal Input: "); + String inputOctal = sc.nextLine(); + int result = convertOctalToDecimal(inputOctal); + if (result != -1) { + System.out.println("Result convertOctalToDecimal : " + result); + } + sc.close(); + } + + /** + * This method converts an octal number to a decimal number. + * + * @param inputOctal The octal number + * @return The decimal number + */ + public static int convertOctalToDecimal(String inputOctal) { + + try { + // Actual conversion of Octal to Decimal: + Integer outputDecimal = Integer.parseInt(inputOctal, 8); + return outputDecimal; + } catch (NumberFormatException ne) { + // Printing a warning message if the input is not a valid octal + // number: + System.out.println("Invalid Input, Expecting octal number 0-7"); + return -1; + } + } +} diff --git a/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java new file mode 100644 index 000000000000..f757ef4e9aca --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java @@ -0,0 +1,64 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Octal Number to HexaDecimal + * + * @author Tanmay Joshi + */ +public class OctalToHexadecimal { + + /** + * This method converts a Octal number to a decimal number + * + * @param s The Octal Number + * @return The Decimal number + */ + public static int octToDec(String s) { + int i = 0; + for (int j = 0; j < s.length(); j++) { + char num = s.charAt(j); + num -= '0'; + i *= 8; + i += num; + } + return i; + } + + /** + * This method converts a Decimal number to a Hexadecimal number + * + * @param d The Decimal Number + * @return The Hexadecimal number + */ + public static String decimalToHex(int d) { + String digits = "0123456789ABCDEF"; + if (d <= 0) { + return "0"; + } + String hex = ""; + while (d > 0) { + int digit = d % 16; + hex = digits.charAt(digit) + hex; + d = d / 16; + } + return hex; + } + + public static void main(String args[]) { + + Scanner input = new Scanner(System.in); + System.out.print("Enter the Octal number: "); + // Take octal number as input from user in a string + String oct = input.next(); + + // Pass the octal number to function and get converted decimal form + int decimal = octToDec(oct); + + // Pass the decimal number to function and get converted Hex form of the number + String hex = decimalToHex(decimal); + System.out.println("The Hexadecimal equivalant is: " + hex); + input.close(); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java new file mode 100644 index 000000000000..81e28919d368 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java @@ -0,0 +1,167 @@ +package com.thealgorithms.conversions; + +import java.util.Arrays; + +/** + * The RGB color model is an additive color model in which red, green, and blue + * light are added together in various ways to reproduce a broad array of + * colors. The name of the model comes from the initials of the three additive + * primary colors, red, green, and blue. Meanwhile, the HSV representation + * models how colors appear under light. In it, colors are represented using + * three components: hue, saturation and (brightness-)value. This class provides + * methods for converting colors from one representation to the other. + * (description adapted from https://en.wikipedia.org/wiki/RGB_color_model and + * https://en.wikipedia.org/wiki/HSL_and_HSV). + */ +public class RgbHsvConversion { + + public static void main(String[] args) { + // 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}); + + // 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}); + } + + /** + * Conversion from the HSV-representation to the RGB-representation. + * + * @param hue Hue of the color. + * @param saturation Saturation of the color. + * @param value Brightness-value of the color. + * @return The tuple of RGB-components. + */ + 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"); + } + + if (saturation < 0 || saturation > 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"); + } + + double chroma = value * saturation; + double hueSection = hue / 60; + double secondLargestComponent = chroma * (1 - Math.abs(hueSection % 2 - 1)); + double matchValue = value - chroma; + + return getRgbBySection(hueSection, chroma, matchValue, secondLargestComponent); + } + + /** + * Conversion from the RGB-representation to the HSV-representation. + * + * @param red Red-component of the color. + * @param green Green-component of the color. + * @param blue Blue-component of the color. + * @return The tuple of HSV-components. + */ + 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"); + } + + if (green < 0 || green > 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"); + } + + double dRed = (double) red / 255; + double dGreen = (double) green / 255; + double dBlue = (double) blue / 255; + double value = Math.max(Math.max(dRed, dGreen), dBlue); + double chroma = value - Math.min(Math.min(dRed, dGreen), dBlue); + double saturation = value == 0 ? 0 : chroma / value; + double hue; + + if (chroma == 0) { + hue = 0; + } else if (value == dRed) { + hue = 60 * (0 + (dGreen - dBlue) / chroma); + } else if (value == dGreen) { + hue = 60 * (2 + (dBlue - dRed) / chroma); + } else { + hue = 60 * (4 + (dRed - dGreen) / chroma); + } + + hue = (hue + 360) % 360; + + return new double[]{hue, saturation, value}; + } + + private static boolean approximatelyEqualHsv(double[] hsv1, double[] hsv2) { + boolean bHue = Math.abs(hsv1[0] - hsv2[0]) < 0.2; + boolean bSaturation = Math.abs(hsv1[1] - hsv2[1]) < 0.002; + boolean bValue = Math.abs(hsv1[2] - hsv2[2]) < 0.002; + + return bHue && bSaturation && bValue; + } + + private static int[] getRgbBySection( + double hueSection, double chroma, double matchValue, double secondLargestComponent) { + int red; + int green; + int blue; + + if (hueSection >= 0 && hueSection <= 1) { + red = convertToInt(chroma + matchValue); + green = convertToInt(secondLargestComponent + matchValue); + blue = convertToInt(matchValue); + } else if (hueSection > 1 && hueSection <= 2) { + red = convertToInt(secondLargestComponent + matchValue); + green = convertToInt(chroma + matchValue); + blue = convertToInt(matchValue); + } else if (hueSection > 2 && hueSection <= 3) { + red = convertToInt(matchValue); + green = convertToInt(chroma + matchValue); + blue = convertToInt(secondLargestComponent + matchValue); + } else if (hueSection > 3 && hueSection <= 4) { + red = convertToInt(matchValue); + green = convertToInt(secondLargestComponent + matchValue); + blue = convertToInt(chroma + matchValue); + } else if (hueSection > 4 && hueSection <= 5) { + red = convertToInt(secondLargestComponent + matchValue); + green = convertToInt(matchValue); + blue = convertToInt(chroma + matchValue); + } else { + red = convertToInt(chroma + matchValue); + green = convertToInt(matchValue); + blue = convertToInt(secondLargestComponent + matchValue); + } + + return new int[]{red, green, blue}; + } + + private static int convertToInt(double input) { + return (int) Math.round(255 * input); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/RomanToInteger.java b/src/main/java/com/thealgorithms/conversions/RomanToInteger.java new file mode 100644 index 000000000000..77b35b257891 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/RomanToInteger.java @@ -0,0 +1,67 @@ +package com.thealgorithms.conversions; + +import java.util.*; + +public class RomanToInteger { + + private static Map map + = new HashMap() { + /** + * */ + private static final long serialVersionUID = 87605733047260530L; + + { + put('I', 1); + put('V', 5); + put('X', 10); + put('L', 50); + put('C', 100); + put('D', 500); + put('M', 1000); + } + }; + // Roman Number = Roman Numerals + + /** + * This function convert Roman number into Integer + * + * @param A Roman number string + * @return integer + */ + public static int romanToInt(String A) { + + A = A.toUpperCase(); + char prev = ' '; + + int sum = 0; + + int newPrev = 0; + for (int i = A.length() - 1; i >= 0; i--) { + char c = A.charAt(i); + + if (prev != ' ') { + // checking current Number greater then previous or not + newPrev = map.get(prev) > newPrev ? map.get(prev) : newPrev; + } + + int currentNum = map.get(c); + + // if current number greater then prev max previous then add + if (currentNum >= newPrev) { + sum += currentNum; + } else { + // subtract upcoming number until upcoming number not greater then prev max + sum -= currentNum; + } + + prev = c; + } + + return sum; + } + + public static void main(String[] args) { + int sum = romanToInt("MDCCCIV"); + System.out.println(sum); + } +} diff --git a/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java b/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java new file mode 100644 index 000000000000..0929496a1fe6 --- /dev/null +++ b/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java @@ -0,0 +1,42 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts turkish character to latin character + * + * @author Özgün Gökşenli + */ +public class TurkishToLatinConversion { + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + System.out.println("Input the string: "); + String b = sc.next(); + System.out.println("Converted: " + convertTurkishToLatin(b)); + sc.close(); + } + + /** + * This method converts a turkish character to latin character. + * + * @param param String paramter + * @return String + */ + public static String convertTurkishToLatin(String param) { + char[] turkishChars + = new char[]{0x131, 0x130, 0xFC, 0xDC, 0xF6, 0xD6, 0x15F, 0x15E, 0xE7, 0xC7, 0x11F, 0x11E}; + char[] latinChars = new char[]{'i', 'I', 'u', 'U', 'o', 'O', 's', 'S', 'c', 'C', 'g', 'G'}; + for (int i = 0; i < turkishChars.length; i++) { + param + = param.replaceAll( + new String(new char[]{turkishChars[i]}), new String(new char[]{latinChars[i]})); + } + return param; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/bags/Bag.java b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java new file mode 100644 index 000000000000..1d03e5cf46a3 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java @@ -0,0 +1,129 @@ +package com.thealgorithms.datastructures.bags; + +import java.util.Iterator; +import java.util.NoSuchElementException; + +/** + * Collection which does not allow removing elements (only collect and iterate) + * + * @param - the generic type of an element in this bag + */ +public class Bag implements Iterable { + + private Node firstElement; // first element of the bag + private int size; // size of bag + + private static class Node { + + private Element content; + private Node nextElement; + } + + /** + * Create an empty bag + */ + public Bag() { + firstElement = null; + size = 0; + } + + /** + * @return true if this bag is empty, false otherwise + */ + public boolean isEmpty() { + return firstElement == null; + } + + /** + * @return the number of elements + */ + public int size() { + return size; + } + + /** + * @param element - the element to add + */ + public void add(Element element) { + Node oldfirst = firstElement; + firstElement = new Node<>(); + firstElement.content = element; + firstElement.nextElement = oldfirst; + size++; + } + + /** + * Checks if the bag contains a specific element + * + * @param element which you want to look for + * @return true if bag contains element, otherwise false + */ + public boolean contains(Element element) { + Iterator iterator = this.iterator(); + while (iterator.hasNext()) { + if (iterator.next().equals(element)) { + return true; + } + } + return false; + } + + /** + * @return an iterator that iterates over the elements in this bag in + * arbitrary order + */ + public Iterator iterator() { + return new ListIterator<>(firstElement); + } + + @SuppressWarnings("hiding") + private class ListIterator implements Iterator { + + private Node currentElement; + + public ListIterator(Node firstElement) { + currentElement = firstElement; + } + + public boolean hasNext() { + return currentElement != null; + } + + /** + * remove is not allowed in a bag + */ + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + public Element next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + Element element = currentElement.content; + currentElement = currentElement.nextElement; + return element; + } + } + + /** + * main-method for testing + */ + public static void main(String[] args) { + Bag bag = new Bag<>(); + + bag.add("1"); + bag.add("1"); + bag.add("2"); + + System.out.println("size of bag = " + bag.size()); + for (String s : bag) { + System.out.println(s); + } + + System.out.println(bag.contains(null)); + System.out.println(bag.contains("1")); + System.out.println(bag.contains("3")); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java new file mode 100644 index 000000000000..200322478a8e --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java @@ -0,0 +1,133 @@ +package com.thealgorithms.datastructures.buffers; + +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +public class CircularBuffer { + + private char[] _buffer; + public final int _buffer_size; + private int _write_index = 0; + private int _read_index = 0; + private AtomicInteger _readable_data = new AtomicInteger(0); + + public CircularBuffer(int buffer_size) { + if (!IsPowerOfTwo(buffer_size)) { + throw new IllegalArgumentException(); + } + this._buffer_size = buffer_size; + _buffer = new char[buffer_size]; + } + + private boolean IsPowerOfTwo(int i) { + return (i & (i - 1)) == 0; + } + + private int getTrueIndex(int i) { + return i % _buffer_size; + } + + public Character readOutChar() { + Character result = null; + + // if we have data to read + if (_readable_data.get() > 0) { + + result = Character.valueOf(_buffer[getTrueIndex(_read_index)]); + _readable_data.decrementAndGet(); + _read_index++; + } + + return result; + } + + public boolean writeToCharBuffer(char c) { + boolean result = false; + + // if we can write to the buffer + if (_readable_data.get() < _buffer_size) { + // write to buffer + _buffer[getTrueIndex(_write_index)] = c; + _readable_data.incrementAndGet(); + _write_index++; + result = true; + } + + return result; + } + + private static class TestWriteWorker implements Runnable { + + String _alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"; + Random _random = new Random(); + CircularBuffer _buffer; + + public TestWriteWorker(CircularBuffer cb) { + this._buffer = cb; + } + + private char getRandomChar() { + return _alphabet.charAt(_random.nextInt(_alphabet.length())); + } + + public void run() { + while (!Thread.interrupted()) { + if (!_buffer.writeToCharBuffer(getRandomChar())) { + Thread.yield(); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + return; + } + } + } + } + } + + private static class TestReadWorker implements Runnable { + + CircularBuffer _buffer; + + public TestReadWorker(CircularBuffer cb) { + this._buffer = cb; + } + + @Override + public void run() { + System.out.println("Printing Buffer:"); + while (!Thread.interrupted()) { + Character c = _buffer.readOutChar(); + if (c != null) { + System.out.print(c.charValue()); + } else { + Thread.yield(); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + System.out.println(); + return; + } + } + } + } + } + + public static void main(String[] args) throws InterruptedException { + int buffer_size = 1024; + // create circular buffer + CircularBuffer cb = new CircularBuffer(buffer_size); + + // create threads that read and write the buffer. + Thread write_thread = new Thread(new TestWriteWorker(cb)); + Thread read_thread = new Thread(new TestReadWorker(cb)); + read_thread.start(); + write_thread.start(); + + // wait some amount of time + Thread.sleep(10000); + + // interrupt threads and exit + write_thread.interrupt(); + read_thread.interrupt(); + } +} diff --git a/DataStructures/Caches/LRUCache.java b/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java similarity index 94% rename from DataStructures/Caches/LRUCache.java rename to src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java index 033aad60099b..b905499bf814 100644 --- a/DataStructures/Caches/LRUCache.java +++ b/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java @@ -1,4 +1,4 @@ -package DataStructures.Caches; +package com.thealgorithms.datastructures.caches; import java.util.HashMap; import java.util.Map; @@ -6,16 +6,16 @@ /** * Least recently used (LRU) *

- * Discards the least recently used items first. - * This algorithm requires keeping track of what was used when, - * which is expensive if one wants to make sure the algorithm always discards - * the least recently used item. + * Discards the least recently used items first. This algorithm requires keeping + * track of what was used when, which is expensive if one wants to make sure the + * algorithm always discards the least recently used item. * https://en.wikipedia.org/wiki/Cache_replacement_policies#Least_recently_used_(LRU) * * @param key type * @param value type */ public class LRUCache { + private final Map> data = new HashMap<>(); private Entry head; private Entry tail; @@ -120,6 +120,7 @@ private void addNewEntry(Entry newEntry) { } static final class Entry { + private Entry preEntry; private Entry nextEntry; private I key; diff --git a/DataStructures/Caches/MRUCache.java b/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java similarity index 98% rename from DataStructures/Caches/MRUCache.java rename to src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java index e31564775a3f..5d77865ce9aa 100644 --- a/DataStructures/Caches/MRUCache.java +++ b/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java @@ -1,4 +1,4 @@ -package DataStructures.Caches; +package com.thealgorithms.datastructures.caches; import java.util.HashMap; import java.util.Map; @@ -6,13 +6,15 @@ /** * Most recently used (MRU) *

- * In contrast to Least Recently Used (LRU), MRU discards the most recently used items first. + * In contrast to Least Recently Used (LRU), MRU discards the most recently used + * items first. * https://en.wikipedia.org/wiki/Cache_replacement_policies#Most_recently_used_(MRU) * * @param key type * @param value type */ public class MRUCache { + private final Map> data = new HashMap<>(); private Entry head; private Entry tail; @@ -32,7 +34,6 @@ private void setCapacity(int newCapacity) { this.cap = newCapacity; } - private void checkCapacity(int capacity) { if (capacity <= 0) { throw new RuntimeException("capacity must greater than 0!"); @@ -117,6 +118,7 @@ private void moveEntryToLast(Entry entry) { } static final class Entry { + private Entry preEntry; private Entry nextEntry; private I key; diff --git a/DataStructures/DisjointSets/DisjointSets.java b/src/main/java/com/thealgorithms/datastructures/disjointsets/DisjointSets.java similarity index 90% rename from DataStructures/DisjointSets/DisjointSets.java rename to src/main/java/com/thealgorithms/datastructures/disjointsets/DisjointSets.java index d4d462803a63..281b0cb202bb 100644 --- a/DataStructures/DisjointSets/DisjointSets.java +++ b/src/main/java/com/thealgorithms/datastructures/disjointsets/DisjointSets.java @@ -1,9 +1,12 @@ -package DataStructures.DisjointSets; +package com.thealgorithms.datastructures.disjointsets; public class DisjointSets { + public Node MakeSet(T x) { return new Node(x); - }; + } + + ; public Node FindSet(Node node) { if (node != node.parent) { @@ -29,4 +32,4 @@ public void UnionSet(Node x, Node y) { ny.rank++; } } -} \ No newline at end of file +} diff --git a/DataStructures/DisjointSets/Node.java b/src/main/java/com/thealgorithms/datastructures/disjointsets/Node.java similarity index 75% rename from DataStructures/DisjointSets/Node.java rename to src/main/java/com/thealgorithms/datastructures/disjointsets/Node.java index 8e6bb6547395..f2054331dc14 100644 --- a/DataStructures/DisjointSets/Node.java +++ b/src/main/java/com/thealgorithms/datastructures/disjointsets/Node.java @@ -1,9 +1,11 @@ -package DataStructures.DisjointSets; +package com.thealgorithms.datastructures.disjointsets; public class Node { + public int rank; public Node parent; public T data; + public Node(T data) { this.data = data; parent = this; diff --git a/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java b/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java new file mode 100644 index 000000000000..fb7783575e57 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java @@ -0,0 +1,222 @@ +package com.thealgorithms.datastructures.dynamicarray; + +import java.util.*; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * This class implements a dynamic array + * + * @param the type that each index of the array will hold + */ +public class DynamicArray implements Iterable { + + private static final int DEFAULT_CAPACITY = 16; + + private int capacity; + private int size; + private Object[] elements; + + /** + * constructor + * + * @param capacity the starting length of the desired array + */ + public DynamicArray(final int capacity) { + this.size = 0; + this.capacity = capacity; + this.elements = new Object[this.capacity]; + } + + /** + * No-args constructor + */ + public DynamicArray() { + this(DEFAULT_CAPACITY); + } + + /** + * Adds an element to the array If full, creates a copy array twice the size + * of the current one + * + * @param element the element of type to be added to the array + */ + public void add(final E element) { + if (this.size == this.elements.length) { + this.elements = Arrays.copyOf(this.elements, newCapacity(2 * this.capacity)); + } + + this.elements[this.size] = element; + size++; + } + + /** + * Places element of type at the desired index + * + * @param index the index for the element to be placed + * @param element the element to be inserted + */ + public void put(final int index, E element) { + this.elements[index] = element; + } + + /** + * get method for element at a given index returns null if the index is + * empty + * + * @param index the desired index of the element + * @return the element at the specified index + */ + public E get(final int index) { + return getElement(index); + } + + /** + * Removes an element from the array + * + * @param index the index of the element to be removed + * @return the element removed + */ + public E remove(final int index) { + final E oldElement = getElement(index); + fastRemove(this.elements, index); + + if (this.capacity > DEFAULT_CAPACITY && size * 4 <= this.capacity) { + this.elements = Arrays.copyOf(this.elements, newCapacity(this.capacity / 2)); + } + return oldElement; + } + + /** + * get method for size field + * + * @return int size + */ + public int getSize() { + return this.size; + } + + /** + * isEmpty helper method + * + * @return boolean true if the array contains no elements, false otherwise + */ + public boolean isEmpty() { + return this.size == 0; + } + + public Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + private void fastRemove(final Object[] elements, final int index) { + final int newSize = this.size - 1; + + if (newSize > index) { + System.arraycopy(elements, index + 1, elements, index, newSize - index); + } + + elements[this.size = newSize] = null; + } + + private E getElement(final int index) { + return (E) this.elements[index]; + } + + private int newCapacity(int capacity) { + this.capacity = capacity; + return this.capacity; + } + + /** + * returns a String representation of this object + * + * @return String a String representing the array + */ + @Override + public String toString() { + return Arrays.toString(Arrays.stream(this.elements).filter(Objects::nonNull).toArray()); + } + + /** + * Creates and returns a new Dynamic Array Iterator + * + * @return Iterator a Dynamic Array Iterator + */ + @Override + public Iterator iterator() { + return new DynamicArrayIterator(); + } + + private class DynamicArrayIterator implements Iterator { + + private int cursor; + + @Override + public boolean hasNext() { + return this.cursor != size; + } + + @Override + public E next() { + if (this.cursor > DynamicArray.this.size) { + throw new NoSuchElementException(); + } + + if (this.cursor > DynamicArray.this.elements.length) { + throw new ConcurrentModificationException(); + } + + final E element = DynamicArray.this.getElement(this.cursor); + this.cursor++; + + return element; + } + + @Override + public void remove() { + if (this.cursor < 0) { + throw new IllegalStateException(); + } + + DynamicArray.this.remove(this.cursor); + this.cursor--; + } + + @Override + public void forEachRemaining(Consumer action) { + Objects.requireNonNull(action); + + for (int i = 0; i < DynamicArray.this.size; i++) { + action.accept(DynamicArray.this.getElement(i)); + } + } + } + + /** + * This class is the driver for the DynamicArray class it tests a variety + * of methods and prints the output + */ + public static void main(String[] args) { + DynamicArray names = new DynamicArray<>(); + names.add("Peubes"); + names.add("Marley"); + + for (String name : names) { + System.out.println(name); + } + + names.stream().forEach(System.out::println); + + System.out.println(names); + + System.out.println(names.getSize()); + + names.remove(0); + + for (String name : names) { + System.out.println(name); + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java b/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java new file mode 100644 index 000000000000..610b364b35fb --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java @@ -0,0 +1,185 @@ +/* + Time Complexity = O(E), where E is equal to the number of edges + */ +package com.thealgorithms.datastructures.graphs; + +import java.util.*; + +public class A_Star { + + private static class Graph { + // Graph's structure can be changed only applying changes to this class. + + private ArrayList> graph; + + // Initialise ArrayLists in Constructor + public Graph(int size) { + this.graph = new ArrayList<>(); + for (int i = 0; i < size; i++) { + this.graph.set(i, new ArrayList<>()); + } + } + + private ArrayList getNeighbours(int from) { + return this.graph.get(from); + } + + // Graph is bidirectional, for just one direction remove second instruction of this method. + private void addEdge(Edge edge) { + this.graph.get(edge.getFrom()).add(new Edge(edge.getFrom(), edge.getTo(), edge.getWeight())); + this.graph.get(edge.getTo()).add(new Edge(edge.getTo(), edge.getFrom(), edge.getWeight())); + } + } + + private static class Edge { + + private int from; + private int to; + private int weight; + + public Edge(int from, int to, int weight) { + this.from = from; + this.to = to; + this.weight = weight; + } + + public int getFrom() { + return from; + } + + public int getTo() { + return to; + } + + public int getWeight() { + return weight; + } + } + + // class to iterate during the algorithm execution, and also used to return the solution. + private static class PathAndDistance { + + private int distance; // distance advanced so far. + private ArrayList path; // list of visited nodes in this path. + private int estimated; // heuristic value associated to the last node od the path (current node). + + public PathAndDistance(int distance, ArrayList path, int estimated) { + this.distance = distance; + this.path = path; + this.estimated = estimated; + } + + public int getDistance() { + return distance; + } + + public ArrayList getPath() { + return path; + } + + public int getEstimated() { + return estimated; + } + + private void printSolution() { + if (this.path != null) { + System.out.println( + "Optimal path: " + this.path + ", distance: " + this.distance); + } else { + System.out.println("There is no path available to connect the points"); + } + } + } + + private static void initializeGraph(Graph graph, ArrayList 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))); + } + /* + .x. node + (y) cost + - or | or / bidirectional connection + + ( 98)- .7. -(86)- .4. + | + ( 85)- .17. -(142)- .18. -(92)- .8. -(87)- .11. + | + . 1. -------------------- (160) + | \ | + (211) \ .6. + | \ | + . 5. (101)-.13. -(138) (115) + | | | / + ( 99) ( 97) | / + | | | / + .12. -(151)- .15. -(80)- .14. | / + | | | | / + ( 71) (140) (146)- .2. -(120) + | | | + .19. -( 75)- . 0. .10. -(75)- .3. + | | + (118) ( 70) + | | + .16. -(111)- .9. + */ + } + + public static void main(String[] args) { + // heuristic function optimistic values + int[] heuristic = { + 366, 0, 160, 242, 161, 178, 77, 151, 226, 244, 241, 234, 380, 98, 193, 253, 329, 80, 199, 374 + }; + + Graph graph = new Graph(20); + ArrayList 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) { + // 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 queue + = new PriorityQueue<>(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)); + + boolean solutionFound = false; + 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. + if (currentPosition == to) { + solutionFound = true; + } else { + for (Edge edge : graph.getNeighbours(currentPosition)) { + if (!currentData.getPath().contains(edge.getTo())) { // Avoid Cycles + ArrayList 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()])); + } + } + } + } + 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 + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java b/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java new file mode 100644 index 000000000000..2a86dec2c6c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java @@ -0,0 +1,173 @@ +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*/ { + + int vertex, edge; + private Edge edges[]; + private int index = 0; + + BellmanFord(int v, int e) { + vertex = v; + edge = e; + edges = new Edge[e]; + } + + class Edge { + + int u, v; + int w; + + /** + * @param u Source Vertex + * @param v End vertex + * @param c Weight + */ + public Edge(int a, int b, int c) { + u = a; + v = b; + w = c; + } + } + + /** + * @param p[] Parent array which shows updates in edges + * @param i Current vertex under consideration + */ + void printPath(int p[], int i) { + if (p[i] == -1) // Found the path back to parent + { + return; + } + printPath(p, p[i]); + System.out.print(i + " "); + } + + public static void main(String args[]) { + BellmanFord obj = new BellmanFord(0, 0); // Dummy object to call nonstatic variables + obj.go(); + } + + public void + go() // Interactive run for understanding the class first time. Assumes source vertex is 0 and + // shows distance to all vertices + { + 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"); + v = sc.nextInt(); + e = sc.nextInt(); + Edge arr[] = new Edge[e]; // Array of edges + System.out.println("Input edges"); + for (i = 0; i < e; i++) { + u = sc.nextInt(); + ve = sc.nextInt(); + 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 + // and all vertices + int p[] = new int[v]; // Parent array for holding the paths + for (i = 0; i < v; i++) { + dist[i] = Integer.MAX_VALUE; // Initializing distance values + } + dist[0] = 0; + p[0] = -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) { + dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update + p[arr[j].v] = arr[j].u; + } + } + } + // 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) { + neg = 1; + System.out.println("Negative cycle"); + break; + } + } + if (neg == 0) // Go ahead and show results of computation + { + System.out.println("Distances are: "); + for (i = 0; i < v; i++) { + System.out.println(i + " " + dist[i]); + } + System.out.println("Path followed:"); + for (i = 0; i < v; i++) { + System.out.print("0 "); + printPath(p, i); + System.out.println(); + } + } + sc.close(); + } + + /** + * @param source Starting vertex + * @param end Ending vertex + * @param Edge Array of edges + */ + public void show( + int source, + int end, + Edge arr[]) // Just shows results of computation, if graph is passed to it. The graph should + // be created by using addEdge() method and passed by calling getEdgeArray() method + { + 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 + // and all vertices + int p[] = new int[v]; // Parent array for holding the paths + for (i = 0; i < v; i++) { + dist[i] = Integer.MAX_VALUE; // Initializing distance values + } + dist[source] = 0; + 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) { + dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update + p[arr[j].v] = arr[j].u; + } + } + } + // 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) { + neg = 1; + System.out.println("Negative cycle"); + break; + } + } + if (neg == 0) // Go ahead and show results of computaion + { + System.out.println("Distance is: " + dist[end]); + System.out.println("Path followed:"); + System.out.print(source + " "); + printPath(p, end); + System.out.println(); + } + } + + /** + * @param x Source Vertex + * @param y End vertex + * @param z Weight + */ + public void addEdge(int x, int y, int z) // Adds unidirectional edge + { + edges[index++] = new Edge(x, y, z); + } + + public Edge[] getEdgeArray() { + return edges; + } +} diff --git a/DataStructures/Graphs/BipartiteGrapfDFS.java b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java similarity index 61% rename from DataStructures/Graphs/BipartiteGrapfDFS.java rename to src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java index 472f20f10fdc..7985bcb04e03 100644 --- a/DataStructures/Graphs/BipartiteGrapfDFS.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java @@ -1,4 +1,4 @@ -package DataStructures.Graphs; +package com.thealgorithms.datastructures.graphs; import java.io.BufferedReader; import java.io.IOException; @@ -7,74 +7,73 @@ import java.util.Arrays; /** - * Given an adjacency list of a graph adj of V no. - * of vertices having 0 based index. - * Check whether the graph is bipartite or not. - * - * Input : - * {{0, 1, 0, 1}, - * {1, 0, 1, 0}, - * {0, 1, 0, 1}, - * {1, 0, 1, 0}} - * + * Given an adjacency list of a graph adj of V no. of vertices having 0 based + * index. Check whether the graph is bipartite or not. + * + * Input : {{0, 1, 0, 1}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}} + * * Output : YES */ public class BipartiteGrapfDFS { - private static boolean bipartite(int V, ArrayList>adj, int[] color, int node){ - if(color[node] == -1){ + + private static boolean bipartite(int V, ArrayList> adj, int[] color, int node) { + if (color[node] == -1) { color[node] = 1; } - for(Integer it : adj.get(node)){ - if(color[it] == -1){ - color[it] = 1-color[node]; - if(bipartite(V, adj, color, it)== false) return false; - } - else if(color[it] == color[node]){ + for (Integer it : adj.get(node)) { + if (color[it] == -1) { + color[it] = 1 - color[node]; + if (bipartite(V, adj, color, it) == false) { + return false; + } + } else if (color[it] == color[node]) { return false; } } return true; } - public static boolean isBipartite(int V, ArrayList> adj) - { + + public static boolean isBipartite(int V, ArrayList> adj) { // Code here - int[] color = new int[V+1]; + int[] color = new int[V + 1]; Arrays.fill(color, -1); - - for(int i =0; i< V; i++){ - if(color[i] == -1){ - if(!bipartite(V, adj, color, i)){ + + for (int i = 0; i < V; i++) { + if (color[i] == -1) { + if (!bipartite(V, adj, color, i)) { return false; } } } return true; } + public static void main(String[] args) throws IOException { BufferedReader read = new BufferedReader(new InputStreamReader(System.in)); int t = Integer.parseInt(read.readLine().trim()); - while(t-- > 0) { + while (t-- > 0) { String[] S = read.readLine().trim().split(" "); int V = Integer.parseInt(S[0]); int E = Integer.parseInt(S[1]); - + ArrayList> adj = new ArrayList<>(); - for(int i =0;i < V; i++) { + for (int i = 0; i < V; i++) { adj.add(new ArrayList<>()); } - for(int i = 0; i < E; i++) { + for (int i = 0; i < E; i++) { String[] s = read.readLine().trim().split(" "); int u = Integer.parseInt(s[0]); int v = Integer.parseInt(s[1]); adj.get(u).add(v); adj.get(v).add(u); } - + boolean ans = isBipartite(V, adj); - if(ans) + if (ans) { System.out.println("YES"); - else + } else { System.out.println("NO"); + } } } } diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java b/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java new file mode 100644 index 000000000000..b0add255f59a --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java @@ -0,0 +1,143 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +/** + * A class that counts the number of different connected components in a graph + * + * @author Lukas Keul, Florian Mercks + */ +class Graph> { + + class Node { + + E name; + + public Node(E name) { + this.name = name; + } + } + + class Edge { + + Node startNode, endNode; + + public Edge(Node startNode, Node endNode) { + this.startNode = startNode; + this.endNode = endNode; + } + } + + ArrayList edgeList; + ArrayList nodeList; + + public Graph() { + edgeList = new ArrayList(); + nodeList = new ArrayList(); + } + + /** + * Adds a new Edge to the graph. If the nodes aren't yet in nodeList, they + * will be added to it. + * + * @param startNode the starting Node from the edge + * @param endNode the ending Node from the edge + */ + public void addEdge(E startNode, E endNode) { + Node start = null, end = null; + for (Node node : nodeList) { + if (startNode.compareTo(node.name) == 0) { + start = node; + } else if (endNode.compareTo(node.name) == 0) { + end = node; + } + } + if (start == null) { + start = new Node(startNode); + nodeList.add(start); + } + if (end == null) { + end = new Node(endNode); + nodeList.add(end); + } + + edgeList.add(new Edge(start, end)); + } + + /** + * Main method used for counting the connected components. Iterates through + * the array of nodes to do a depth first search to get all nodes of the + * graph from the actual node. These nodes are added to the array + * markedNodes and will be ignored if they are chosen in the nodeList. + * + * @return returns the amount of unconnected graphs + */ + public int countGraphs() { + int count = 0; + Set markedNodes = new HashSet(); + + for (Node n : nodeList) { + if (!markedNodes.contains(n)) { + markedNodes.add(n); + markedNodes.addAll(depthFirstSearch(n, new ArrayList())); + count++; + } + } + + return count; + } + + /** + * Implementation of depth first search. + * + * @param n the actual visiting node + * @param visited A list of already visited nodes in the depth first search + * @return returns a set of visited nodes + */ + public ArrayList depthFirstSearch(Node n, ArrayList visited) { + visited.add(n); + for (Edge e : edgeList) { + if (e.startNode.equals(n) && !visited.contains(e.endNode)) { + depthFirstSearch(e.endNode, visited); + } + } + return visited; + } +} + +public class ConnectedComponent { + + public static void main(String[] args) { + Graph graphChars = new Graph<>(); + + // Graph 1 + graphChars.addEdge('a', 'b'); + graphChars.addEdge('a', 'e'); + graphChars.addEdge('b', 'e'); + graphChars.addEdge('b', 'c'); + graphChars.addEdge('c', 'd'); + graphChars.addEdge('d', 'a'); + + graphChars.addEdge('x', 'y'); + graphChars.addEdge('x', 'z'); + + graphChars.addEdge('w', 'w'); + + Graph graphInts = new Graph<>(); + + // Graph 2 + graphInts.addEdge(1, 2); + graphInts.addEdge(2, 3); + graphInts.addEdge(2, 4); + graphInts.addEdge(3, 5); + + graphInts.addEdge(7, 8); + 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()); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java b/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java new file mode 100644 index 000000000000..5d5bd3c7469c --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java @@ -0,0 +1,88 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.Scanner; + +class Cycle { + + private int nodes, edges; + private int[][] adjacencyMatrix; + private boolean[] visited; + ArrayList> cycles = new ArrayList>(); + + public Cycle() { + Scanner in = new Scanner(System.in); + System.out.print("Enter the no. of nodes: "); + nodes = in.nextInt(); + System.out.print("Enter the no. of Edges: "); + edges = in.nextInt(); + + adjacencyMatrix = new int[nodes][nodes]; + visited = new boolean[nodes]; + + for (int i = 0; i < nodes; i++) { + visited[i] = false; + } + + System.out.println("Enter the details of each edges "); + + for (int i = 0; i < edges; i++) { + int start, end; + start = in.nextInt(); + end = in.nextInt(); + adjacencyMatrix[start][end] = 1; + } + in.close(); + } + + public void start() { + for (int i = 0; i < nodes; i++) { + ArrayList temp = new ArrayList<>(); + dfs(i, i, temp); + for (int j = 0; j < nodes; j++) { + adjacencyMatrix[i][j] = 0; + adjacencyMatrix[j][i] = 0; + } + } + } + + private void dfs(Integer start, Integer curr, ArrayList temp) { + temp.add(curr); + visited[curr] = true; + for (int i = 0; i < nodes; i++) { + if (adjacencyMatrix[curr][i] == 1) { + if (i == start) { + cycles.add(new ArrayList(temp)); + } else { + if (!visited[i]) { + dfs(start, i, temp); + } + } + } + } + + if (temp.size() > 0) { + temp.remove(temp.size() - 1); + } + visited[curr] = false; + } + + public void printAll() { + for (int i = 0; i < cycles.size(); i++) { + for (int j = 0; j < cycles.get(i).size(); j++) { + System.out.print(cycles.get(i).get(j) + " -> "); + } + System.out.println(cycles.get(i).get(0)); + System.out.println(); + } + } +} + +public class Cycles { + + public static void main(String[] args) { + Cycle c = new Cycle(); + c.start(); + c.printAll(); + } +} diff --git a/DataStructures/Graphs/DIJSKSTRAS_ALGORITHM.java b/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java similarity index 51% rename from DataStructures/Graphs/DIJSKSTRAS_ALGORITHM.java rename to src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java index 928281602765..e852b5ebba51 100644 --- a/DataStructures/Graphs/DIJSKSTRAS_ALGORITHM.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java @@ -1,69 +1,70 @@ /* Refer https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/ for better understanding -*/ -package DataStructures.Graphs; + */ +package com.thealgorithms.datastructures.graphs; -class dijkstras{ +class dijkstras { - int k=9; - int minDist(int dist[], Boolean Set[]) - { + int k = 9; + + int minDist(int dist[], Boolean Set[]) { int min = Integer.MAX_VALUE, min_index = -1; - - for (int r = 0; r < k; r++) + + for (int r = 0; r < k; r++) { if (Set[r] == false && dist[r] <= min) { min = dist[r]; min_index = r; } - + } + return min_index; } - void print(int dist[]) - { + void print(int dist[]) { System.out.println("Vertex \t\t Distance"); - for (int i = 0; i < k; i++) + for (int i = 0; i < k; i++) { System.out.println(i + " \t " + dist[i]); + } } - void dijkstra(int graph[][], int src) - { - int dist[] = new int[k]; + + void dijkstra(int graph[][], int src) { + int dist[] = new int[k]; Boolean Set[] = new Boolean[k]; - + for (int i = 0; i < k; i++) { dist[i] = Integer.MAX_VALUE; Set[i] = false; } - + dist[src] = 0; - + for (int c = 0; c < k - 1; c++) { - + int u = minDist(dist, Set); - + 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]) + + 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]) { dist[v] = dist[u] + graph[u][v]; + } + } } - + print(dist); } - - 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 } }; + + 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}}; dijkstras t = new dijkstras(); t.dijkstra(graph, 0); }//main @@ -82,4 +83,4 @@ public static void main(String[] args) 6 9 7 8 8 14 -*/ + */ diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java b/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java new file mode 100644 index 000000000000..6a3eb41e9424 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java @@ -0,0 +1,77 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.Scanner; + +public class FloydWarshall { + + private int DistanceMatrix[][]; + private int numberofvertices; // number of vertices in the graph + 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 + // 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 + { + for (int source = 1; source <= numberofvertices; source++) { + for (int destination = 1; destination <= numberofvertices; destination++) { + DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination]; + } + } + 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]) // if the new distance calculated is less then the earlier shortest + // calculated distance it get replaced as new shortest distance + { + DistanceMatrix[source][destination] + = DistanceMatrix[source][intermediate] + DistanceMatrix[intermediate][destination]; + } + } + } + } + for (int source = 1; source <= numberofvertices; source++) { + System.out.print("\t" + source); + } + System.out.println(); + for (int source = 1; source <= numberofvertices; source++) { + System.out.print(source + "\t"); + for (int destination = 1; destination <= numberofvertices; destination++) { + System.out.print(DistanceMatrix[source][destination] + "\t"); + } + System.out.println(); + } + } + + public static void main(String... arg) { + 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]; + System.out.println("Enter the Weighted Matrix for the graph"); + for (int source = 1; source <= numberOfVertices; source++) { + for (int destination = 1; destination <= numberOfVertices; destination++) { + adjacencyMatrix[source][destination] = scan.nextInt(); + if (source == destination) { + adjacencyMatrix[source][destination] = 0; + continue; + } + if (adjacencyMatrix[source][destination] == 0) { + adjacencyMatrix[source][destination] = INFINITY; + } + } + } + System.out.println("The Transitive Closure of the Graph"); + FloydWarshall floydwarshall = new FloydWarshall(numberOfVertices); + floydwarshall.floydwarshall(adjacencyMatrix); + scan.close(); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java b/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java new file mode 100644 index 000000000000..11c1e8cd2294 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java @@ -0,0 +1,137 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; + +class AdjacencyListGraph> { + + ArrayList verticies; + + public AdjacencyListGraph() { + verticies = new ArrayList<>(); + } + + private class Vertex { + + E data; + ArrayList adjacentVerticies; + + public Vertex(E data) { + adjacentVerticies = new ArrayList<>(); + this.data = data; + } + + public boolean addAdjacentVertex(Vertex to) { + for (Vertex v : adjacentVerticies) { + if (v.data.compareTo(to.data) == 0) { + return false; // the edge already exists + } + } + return adjacentVerticies.add(to); // this will return true; + } + + public boolean removeAdjacentVertex(E to) { + // use indexes here so it is possible to + // remove easily without implementing + // equals method that ArrayList.remove(Object o) uses + for (int i = 0; i < adjacentVerticies.size(); i++) { + if (adjacentVerticies.get(i).data.compareTo(to) == 0) { + adjacentVerticies.remove(i); + return true; + } + } + return false; + } + } + + /** + * this method removes an edge from the graph between two specified + * verticies + * + * @param from the data of the vertex the edge is from + * @param to the data of the vertex the edge is going to + * @return returns false if the edge doesn't exist, returns true if the edge + * exists and is removed + */ + public boolean removeEdge(E from, E to) { + Vertex fromV = null; + for (Vertex v : verticies) { + if (from.compareTo(v.data) == 0) { + fromV = v; + break; + } + } + if (fromV == null) { + return false; + } + return fromV.removeAdjacentVertex(to); + } + + /** + * this method adds an edge to the graph between two specified verticies + * + * @param from the data of the vertex the edge is from + * @param to the data of the vertex the edge is going to + * @return returns true if the edge did not exist, return false if it + * already did + */ + public boolean addEdge(E from, E to) { + Vertex fromV = null, toV = null; + for (Vertex v : verticies) { + if (from.compareTo(v.data) == 0) { // see if from vertex already exists + fromV = v; + } else if (to.compareTo(v.data) == 0) { // see if to vertex already exists + toV = v; + } + if (fromV != null && toV != null) { + break; // both nodes exist so stop searching + } + } + if (fromV == null) { + fromV = new Vertex(from); + verticies.add(fromV); + } + if (toV == null) { + toV = new Vertex(to); + verticies.add(toV); + } + return fromV.addAdjacentVertex(toV); + } + + /** + * this gives a list of verticies in the graph and their adjacencies + * + * @return returns a string describing this graph + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (Vertex v : verticies) { + sb.append("Vertex: "); + sb.append(v.data); + sb.append("\n"); + sb.append("Adjacent verticies: "); + for (Vertex v2 : v.adjacentVerticies) { + sb.append(v2.data); + sb.append(" "); + } + sb.append("\n"); + } + return sb.toString(); + } +} + +public class Graphs { + + public static void main(String args[]) { + AdjacencyListGraph graph = new AdjacencyListGraph<>(); + assert graph.addEdge(1, 2); + assert graph.addEdge(1, 5); + assert graph.addEdge(2, 5); + assert !graph.addEdge(1, 2); + assert graph.addEdge(2, 3); + assert graph.addEdge(3, 4); + assert graph.addEdge(4, 1); + assert !graph.addEdge(2, 3); + System.out.println(graph); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java new file mode 100644 index 000000000000..4f1d2c2af3d9 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java @@ -0,0 +1,154 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.Map; +import java.util.LinkedHashMap; +import java.util.HashMap; +import java.util.Set; +import java.util.Queue; +import java.util.LinkedList; + +/** + * An algorithm that sorts a graph in toplogical order. + */ +/** + * A class that represents the adjaceny list of a graph + */ +class AdjacencyList> { + + Map> adj; + + AdjacencyList() { + adj = new LinkedHashMap>(); + } + + /** + * This function adds an Edge to the adjaceny list + * + * @param from , the vertex the edge is from + * @param to, the vertex the edge is going to + */ + void addEdge(E from, E to) { + try { + adj.get(from).add(to); + } catch (Exception E) { + adj.put(from, new ArrayList()); + adj.get(from).add(to); + } + if (!adj.containsKey(to)) { + adj.put(to, new ArrayList()); + } + } + + /** + * @param v, A vertex in a graph + * @return returns an ArrayList of all the adjacents of vertex v + */ + ArrayList getAdjacents(E v) { + return adj.get(v); + } + + /** + * @return returns a set of all vertices in the graph + */ + Set getVertices() { + return adj.keySet(); + } + + /** + * Prints the adjacency list + */ + void printGraph() { + for (E vertex : adj.keySet()) { + System.out.print(vertex + " : "); + for (E adjacent : adj.get(vertex)) { + System.out.print(adjacent + " "); + } + System.out.println(); + } + } +} + +class TopologicalSort> { + + AdjacencyList graph; + Map inDegree; + + TopologicalSort(AdjacencyList graph) { + this.graph = graph; + } + + /** + * Calculates the in degree of all vertices + */ + void calculateInDegree() { + inDegree = new HashMap<>(); + for (E vertex : graph.getVertices()) { + if (!inDegree.containsKey(vertex)) { + inDegree.put(vertex, 0); + } + for (E adjacent : graph.getAdjacents(vertex)) { + try { + inDegree.put(adjacent, inDegree.get(adjacent) + 1); + } catch (Exception e) { + inDegree.put(adjacent, 1); + } + } + } + } + + /** + * Returns an ArrayList with vertices arranged in topological order + */ + ArrayList topSortOrder() { + calculateInDegree(); + Queue q = new LinkedList(); + + for (E vertex : inDegree.keySet()) { + if (inDegree.get(vertex) == 0) { + q.add(vertex); + } + } + + ArrayList answer = new ArrayList<>(); + + while (!q.isEmpty()) { + E current = q.poll(); + answer.add(current); + for (E adjacent : graph.getAdjacents(current)) { + inDegree.put(adjacent, inDegree.get(adjacent) - 1); + if (inDegree.get(adjacent) == 0) { + q.add(adjacent); + } + } + } + + return answer; + + } +} + +/** + * A driver class that sorts a given graph in topological order. + */ +public class KahnsAlgorithm { + + public static void main(String[] args) { + + //Graph definition and initialization + AdjacencyList graph = new AdjacencyList<>(); + graph.addEdge("a", "b"); + graph.addEdge("c", "a"); + graph.addEdge("a", "d"); + graph.addEdge("b", "d"); + graph.addEdge("c", "u"); + graph.addEdge("u", "b"); + + TopologicalSort topSort = new TopologicalSort<>(graph); + + //Printing the order + for (String s : topSort.topSortOrder()) { + System.out.print(s + " "); + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java new file mode 100644 index 000000000000..a0856c819511 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java @@ -0,0 +1,104 @@ +package com.thealgorithms.datastructures.graphs; + +// Problem -> Connect all the edges with the minimum cost. +// Possible Solution -> Kruskal Algorithm (KA), KA finds the minimum-spanning-tree, which means, the +// group of edges with the minimum sum of their weights that connect the whole graph. +// The graph needs to be connected, because if there are nodes impossible to reach, there are no +// edges that could connect every node in the graph. +// KA is a Greedy Algorithm, because edges are analysed based on their weights, that is why a +// Priority Queue is used, to take first those less weighted. +// This implementations below has some changes compared to conventional ones, but they are explained +// all along the code. +import java.util.Comparator; +import java.util.HashSet; +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 + private static class Edge { + + private int from; + private int to; + private int weight; + + public Edge(int from, int to, int weight) { + this.from = from; + this.to = to; + this.weight = weight; + } + } + + private static void addEdge(HashSet[] graph, int from, int to, int weight) { + graph[from].add(new Edge(from, to, weight)); + } + + public static void main(String[] args) { + HashSet[] graph = new HashSet[7]; + for (int i = 0; i < graph.length; i++) { + graph[i] = new HashSet<>(); + } + addEdge(graph, 0, 1, 2); + addEdge(graph, 0, 2, 3); + addEdge(graph, 0, 3, 3); + addEdge(graph, 1, 2, 4); + addEdge(graph, 2, 3, 5); + addEdge(graph, 1, 4, 3); + addEdge(graph, 2, 4, 1); + addEdge(graph, 3, 5, 7); + addEdge(graph, 4, 5, 8); + addEdge(graph, 5, 6, 9); + + 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); + } + } + + Kruskal k = new Kruskal(); + HashSet[] solGraph = k.kruskal(graph); + + 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); + } + } + } + + public HashSet[] kruskal(HashSet[] graph) { + int nodes = graph.length; + int[] captain = new int[nodes]; + // captain of i, stores the set with all the connected nodes to i + HashSet[] connectedGroups = new HashSet[nodes]; + HashSet[] minGraph = new HashSet[nodes]; + PriorityQueue edges = new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight))); + for (int i = 0; i < nodes; i++) { + minGraph[i] = new HashSet<>(); + connectedGroups[i] = new HashSet<>(); + connectedGroups[i].add(i); + captain[i] = i; + edges.addAll(graph[i]); + } + int connectedElements = 0; + // as soon as two sets merge all the elements, the algorithm must stop + 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)) { + // merge sets of the captains of each point connected by the edge + 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]); + // add Edge to minimal graph + addEdge(minGraph, edge.from, edge.to, edge.weight); + // count how many elements have been merged + connectedElements = connectedGroups[captain[edge.from]].size(); + } + } + return minGraph; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java b/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java new file mode 100644 index 000000000000..49b9a41e9768 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java @@ -0,0 +1,349 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.List; +import java.util.Queue; +import java.util.ArrayList; +import java.util.LinkedList; + +/** + * Implementation of a graph in a matrix form Also known as an adjacency matrix + * representation [Adjacency matrix - + * Wikipedia](https://en.wikipedia.org/wiki/Adjacency_matrix) + * + * @author Unknown + */ +public class MatrixGraphs { + + public static void main(String args[]) { + AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10); + graph.addEdge(1, 2); + graph.addEdge(1, 5); + graph.addEdge(2, 5); + graph.addEdge(1, 2); + graph.addEdge(2, 3); + graph.addEdge(3, 4); + graph.addEdge(4, 1); + graph.addEdge(2, 3); + graph.addEdge(3, 9); + graph.addEdge(9, 1); + graph.addEdge(9, 8); + graph.addEdge(1, 8); + graph.addEdge(5, 6); + System.out.println("The graph matrix:"); + System.out.println(graph); + System.out.println("Depth first order beginning at node '1':"); + System.out.println(graph.depthFirstOrder(1)); + System.out.println("Breadth first order beginning at node '1':"); + System.out.println(graph.breadthFirstOrder(1)); + } +} + +/** + * AdjacencyMatrixGraph Implementation + */ +class AdjacencyMatrixGraph { + + /** + * The number of vertices in the graph + */ + private int _numberOfVertices; + + /** + * The number of edges in the graph + */ + private int _numberOfEdges; + + /** + * The adjacency matrix for the graph + */ + private int[][] _adjacency; + + /** + * Static variables to define whether or not an edge exists in the adjacency + * matrix + */ + static final int EDGE_EXIST = 1; + static final int EDGE_NONE = 0; + + /** + * Constructor + */ + public AdjacencyMatrixGraph(int givenNumberOfVertices) { + this.setNumberOfVertices(givenNumberOfVertices); + this.setNumberOfEdges(0); + 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; + } + } + } + + /** + * Updates the number of vertices in the graph + * + * @param newNumberOfVertices the new number of vertices + */ + private void setNumberOfVertices(int newNumberOfVertices) { + this._numberOfVertices = newNumberOfVertices; + } + + /** + * Getter for `this._numberOfVertices` + * + * @return the number of vertices in the graph + */ + public int numberOfVertices() { + return this._numberOfVertices; + } + + /** + * Updates the number of edges in the graph + * + * @param newNumberOfEdges + * + */ + private void setNumberOfEdges(int newNumberOfEdges) { + this._numberOfEdges = newNumberOfEdges; + } + + /** + * Getter for `this._numberOfEdges` + * + * @return the number of edges + */ + public int numberOfEdges() { + return this._numberOfEdges; + } + + /** + * Sets a new matrix as the adjacency matrix + * + * @param newAdjacency the new adjaceny matrix + */ + private void setAdjacency(int[][] newAdjacency) { + this._adjacency = newAdjacency; + } + + /** + * Getter for the adjacency matrix + * + * @return the adjacency matrix + */ + private int[][] adjacency() { + return this._adjacency; + } + + /** + * Checks if two vertices are connected by an edge + * + * @param from the parent vertex to check for adjacency + * @param to the child vertex to check for adjacency + * @return whether or not the vertices are adjancent + */ + private boolean adjacencyOfEdgeDoesExist(int from, int to) { + return (this.adjacency()[from][to] != AdjacencyMatrixGraph.EDGE_NONE); + } + + /** + * Checks if a particular vertex exists in a graph + * + * @param aVertex the vertex to check for existence + * @return whether or not the vertex exists + */ + public boolean vertexDoesExist(int aVertex) { + if (aVertex >= 0 && aVertex < this.numberOfVertices()) { + return true; + } else { + return false; + } + } + + /** + * Checks if two vertices are connected by an edge + * + * @param from the parent vertex to check for adjacency + * @param to the child vertex to check for adjacency + * @return whether or not the vertices are adjancent + */ + public boolean edgeDoesExist(int from, int to) { + if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) { + return (this.adjacencyOfEdgeDoesExist(from, to)); + } + + return false; + } + + /** + * This method adds an edge to the graph between two specified vertices + * + * @param from the data of the vertex the edge is from + * @param to the data of the vertex the edge is going to + * @return returns true if the edge did not exist, return false if it + * already did + */ + public boolean addEdge(int from, int to) { + if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) { + if (!this.adjacencyOfEdgeDoesExist(from, to)) { + this.adjacency()[from][to] = AdjacencyMatrixGraph.EDGE_EXIST; + this.adjacency()[to][from] = AdjacencyMatrixGraph.EDGE_EXIST; + this.setNumberOfEdges(this.numberOfEdges() + 1); + return true; + } + } + + return false; + } + + /** + * this method removes an edge from the graph between two specified vertices + * + * @param from the data of the vertex the edge is from + * @param to the data of the vertex the edge is going to + * @return returns false if the edge doesn't exist, returns true if the edge + * exists and is removed + */ + public boolean removeEdge(int from, int to) { + if (!this.vertexDoesExist(from) || !this.vertexDoesExist(to)) { + if (this.adjacencyOfEdgeDoesExist(from, to)) { + this.adjacency()[from][to] = AdjacencyMatrixGraph.EDGE_NONE; + this.adjacency()[to][from] = AdjacencyMatrixGraph.EDGE_NONE; + this.setNumberOfEdges(this.numberOfEdges() - 1); + return true; + } + } + return false; + } + + /** + * This method returns a list of the vertices in a depth first order + * beginning with the specified vertex + * + * @param startVertex the vertex to begin the traversal + * @return the list of the ordered vertices + */ + public List depthFirstOrder(int startVertex) { + // If the startVertex is invalid, return an empty list + if (startVertex >= _numberOfVertices || startVertex < 0) { + return new ArrayList(); + } + + // Create an array to track the visited vertices + boolean[] visited = new boolean[_numberOfVertices]; + + // Create a list to keep track of the order of our traversal + ArrayList orderList = new ArrayList(); + + // Perform our DFS algorithm + depthFirstOrder(startVertex, visited, orderList); + + return orderList; + } + + /** + * Helper method for public depthFirstOrder(int) that will perform a depth + * first traversal recursively on the graph + * + * @param currentVertex the currently exploring vertex + * @param visited the array of values denoting whether or not that vertex + * has been visited + * @param orderList the list to add vertices to as they are visited + */ + private void depthFirstOrder(int currentVertex, boolean[] visited, List orderList) { + // If this vertex has already been visited, do nothing and return + if (visited[currentVertex]) { + return; + } + + // Visit the currentVertex by marking it as visited and adding it + // to the orderList + visited[currentVertex] = true; + orderList.add(currentVertex); + + // Get the adjacency array for this vertex + int[] adjacent = _adjacency[currentVertex]; + for (int i = 0; i < adjacent.length; i++) // If an edge exists between the currentVertex and the vertex + // we are considering exploring, recurse on it + { + if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) { + depthFirstOrder(i, visited, orderList); + } + } + } + + /** + * This method returns a list of the vertices in a breadth first order + * beginning with the specified vertex + * + * @param startVertex the vertext to begin the traversal + * @return the list of the ordered vertices + */ + public List breadthFirstOrder(int startVertex) { + // If the specified startVertex is invalid, return an empty list + if (startVertex >= _numberOfVertices || startVertex < 0) { + return new ArrayList(); + } + + // Create an array to keep track of the visited vertices + boolean[] visited = new boolean[_numberOfVertices]; + + // Create a list to keep track of the ordered vertices + ArrayList orderList = new ArrayList(); + + // Create a queue for our BFS algorithm and add the startVertex + // to the queue + Queue queue = new LinkedList(); + queue.add(startVertex); + + // Continue until the queue is empty + while (!queue.isEmpty()) { + // Remove the first vertex in the queue + int currentVertex = queue.poll(); + + // If we've visited this vertex, skip it + if (visited[currentVertex]) { + continue; + } + + // We now visit this vertex by adding it to the orderList and + // marking it as visited + orderList.add(currentVertex); + visited[currentVertex] = true; + + // Get the adjacency array for the currentVertex and + // check each node + int[] adjacent = _adjacency[currentVertex]; + for (int vertex = 0; vertex < adjacent.length; vertex++) // If an edge exists between the current vertex and the + // vertex we are considering exploring, we add it to the queue + { + if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) { + queue.add(vertex); + } + } + } + + return orderList; + } + + /** + * this gives a list of vertices in the graph and their adjacencies + * + * @return returns a string describing this graph + */ + public String toString() { + String s = " "; + for (int i = 0; i < this.numberOfVertices(); i++) { + s = s + String.valueOf(i) + " "; + } + s = s + " \n"; + + for (int i = 0; i < this.numberOfVertices(); i++) { + s = s + String.valueOf(i) + " : "; + for (int j = 0; j < this.numberOfVertices(); j++) { + s = s + String.valueOf(this._adjacency[i][j]) + " "; + } + s = s + "\n"; + } + return s; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java b/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java new file mode 100644 index 000000000000..80bb1025a4b9 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java @@ -0,0 +1,104 @@ +package com.thealgorithms.datastructures.graphs; + +/** + * A Java program for Prim's Minimum Spanning Tree (MST) algorithm. adjacency + * matrix representation of the graph + */ +class PrimMST { + // Number of vertices in the graph + + private static final int V = 5; + + // A utility function to find the vertex with minimum key + // value, from the set of vertices not yet included in MST + int minKey(int key[], Boolean mstSet[]) { + // Initialize min value + int min = Integer.MAX_VALUE, min_index = -1; + + for (int v = 0; v < V; v++) { + if (mstSet[v] == false && key[v] < min) { + min = key[v]; + min_index = v; + } + } + + return min_index; + } + + // A utility function to print the constructed MST stored in + // parent[] + 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]]); + } + } + + // Function to construct and print MST for a graph represented + // using adjacency matrix representation + void primMST(int graph[][]) { + // Array to store constructed MST + int parent[] = new int[V]; + + // Key values used to pick minimum weight edge in cut + int key[] = new int[V]; + + // To represent set of vertices not yet included in MST + Boolean mstSet[] = new Boolean[V]; + + // Initialize all keys as INFINITE + for (int i = 0; i < V; i++) { + key[i] = Integer.MAX_VALUE; + mstSet[i] = false; + } + + // Always include first 1st vertex in MST. + key[0] = 0; // Make key 0 so that this vertex is + // picked as first vertex + parent[0] = -1; // First node is always root of MST + + // The MST will have V vertices + for (int count = 0; count < V - 1; count++) { + // Pick thd minimum key vertex from the set of vertices + // not yet included in MST + int u = minKey(key, mstSet); + + // Add the picked vertex to the MST Set + mstSet[u] = true; + + // 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++) // graph[u][v] is non zero only for adjacent vertices of m + // mstSet[v] is false for vertices not yet included in MST + // Update the key only if graph[u][v] is smaller than key[v] + { + if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) { + parent[v] = u; + key[v] = graph[u][v]; + } + } + } + + // print the constructed MST + printMST(parent, V, graph); + } + + public static void main(String[] args) { + /* Let us create the following graph + 2 3 + (0)--(1)--(2) + | / \ | + 6| 8/ \5 |7 + | / \ | + (3)-------(4) + 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},}; + + // Print the solution + t.primMST(graph); + } +} diff --git a/DataStructures/Graphs/README.md b/src/main/java/com/thealgorithms/datastructures/graphs/README.md similarity index 100% rename from DataStructures/Graphs/README.md rename to src/main/java/com/thealgorithms/datastructures/graphs/README.md diff --git a/DataStructures/HashMap/Readme.md b/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md similarity index 100% rename from DataStructures/HashMap/Readme.md rename to src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java new file mode 100644 index 000000000000..247244da5316 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java @@ -0,0 +1,150 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +public class HashMap { + + private int hsize; + private LinkedList[] buckets; + + public HashMap(int hsize) { + buckets = new LinkedList[hsize]; + for (int i = 0; i < hsize; i++) { + buckets[i] = new LinkedList(); + // Java requires explicit initialisaton of each object + } + this.hsize = hsize; + } + + public int hashing(int key) { + int hash = key % hsize; + if (hash < 0) { + hash += hsize; + } + return hash; + } + + public void insertHash(int key) { + int hash = hashing(key); + buckets[hash].insert(key); + } + + public void deleteHash(int key) { + int hash = hashing(key); + + buckets[hash].delete(key); + } + + public void displayHashtable() { + for (int i = 0; i < hsize; i++) { + System.out.printf("Bucket %d :", i); + System.out.println(buckets[i].display()); + } + } + + public static class LinkedList { + + private Node first; + + public LinkedList() { + first = null; + } + + public void insert(int key) { + if (isEmpty()) { + first = new Node(key); + return; + } + + Node temp = findEnd(first); + temp.setNext(new Node(key)); + } + + private Node findEnd(Node n) { + if (n.getNext() == null) { + return n; + } else { + return findEnd(n.getNext()); + } + } + + public Node findKey(int key) { + if (!isEmpty()) { + return findKey(first, key); + } else { + System.out.println("List is empty"); + return null; + } + } + + private Node findKey(Node n, int key) { + if (n.getKey() == key) { + return n; + } else if (n.getNext() == null) { + System.out.println("Key not found"); + return null; + } else { + return findKey(n.getNext(), key); + } + } + + public void delete(int key) { + if (!isEmpty()) { + if (first.getKey() == key) { + first = null; + } else { + delete(first, key); + } + } else { + System.out.println("List is empty"); + } + } + + private void delete(Node n, int key) { + if (n.getNext().getKey() == key) { + if (n.getNext().getNext() == null) { + n.setNext(null); + } else { + n.setNext(n.getNext().getNext()); + } + } + } + + public String display() { + return display(first); + } + + private String display(Node n) { + if (n == null) { + return "null"; + } else { + return n.getKey() + "->" + display(n.getNext()); + } + } + + public boolean isEmpty() { + return first == null; + } + } + + public static class Node { + + private Node next; + private int key; + + public Node(int key) { + next = null; + this.key = key; + } + + public Node getNext() { + return next; + } + + public int getKey() { + return key; + } + + public void setNext(Node next) { + this.next = next; + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapLinearProbing.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapLinearProbing.java new file mode 100644 index 000000000000..8d950311e18b --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapLinearProbing.java @@ -0,0 +1,200 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.*; + +/** + * This class is an implementation of a hash table using linear probing It uses + * a dynamic array to lengthen the size of the hash table when load factor > .7 + */ +public class HashMapLinearProbing { + + private int hsize; // size of the hash table + private Integer[] buckets; // array representing the table + private Integer AVAILABLE; + private int size; // amount of elements in the hash table + + /** + * Constructor initializes buckets array, hsize, and creates dummy object + * for AVAILABLE + * + * @param hsize the desired size of the hash map + */ + public HashMapLinearProbing(int hsize) { + this.buckets = new Integer[hsize]; + this.hsize = hsize; + this.AVAILABLE = Integer.MIN_VALUE; + this.size = 0; + } + + /** + * The Hash Function takes a given key and finds an index based on its data + * + * @param key the desired key to be converted + * @return int an index corresponding to the key + */ + public int hashing(int key) { + int hash = key % hsize; + if (hash < 0) { + hash += hsize; + } + return hash; + } + + /** + * inserts the key into the hash map by wrapping it as an Integer object + * + * @param key the desired key to be inserted in the hash map + */ + public void insertHash(int key) { + Integer wrappedInt = key; + int hash = hashing(key); + + if (isFull()) { + System.out.println("Hash table is full"); + return; + } + + for (int i = 0; i < hsize; i++) { + if (buckets[hash] == null || buckets[hash] == AVAILABLE) { + buckets[hash] = wrappedInt; + size++; + return; + } + + if (hash + 1 < hsize) { + hash++; + } else { + hash = 0; + } + } + } + + /** + * deletes a key from the hash map and adds an available placeholder + * + * @param key the desired key to be deleted + */ + public void deleteHash(int key) { + Integer wrappedInt = key; + int hash = hashing(key); + + if (isEmpty()) { + System.out.println("Table is empty"); + return; + } + + for (int i = 0; i < hsize; i++) { + if (buckets[hash] != null && buckets[hash].equals(wrappedInt)) { + buckets[hash] = AVAILABLE; + size--; + return; + } + + if (hash + 1 < hsize) { + hash++; + } else { + hash = 0; + } + } + System.out.println("Key " + key + " not found"); + } + + /** + * Displays the hash table line by line + */ + public void displayHashtable() { + for (int i = 0; i < hsize; i++) { + if (buckets[i] == null || buckets[i] == AVAILABLE) { + System.out.println("Bucket " + i + ": Empty"); + } else { + System.out.println("Bucket " + i + ": " + buckets[i].toString()); + } + } + } + + /** + * Finds the index of location based on an inputed key + * + * @param key the desired key to be found + * @return int the index where the key is located + */ + public int findHash(int key) { + Integer wrappedInt = key; + int hash = hashing(key); + + if (isEmpty()) { + System.out.println("Table is empty"); + return -1; + } + + for (int i = 0; i < hsize; i++) { + try { + if (buckets[hash].equals(wrappedInt)) { + buckets[hash] = AVAILABLE; + return hash; + } + } catch (Exception E) { + } + + if (hash + 1 < hsize) { + hash++; + } else { + hash = 0; + } + } + System.out.println("Key " + key + " not found"); + return -1; + } + + private void lengthenTable() { + buckets = Arrays.copyOf(buckets, hsize * 2); + hsize *= 2; + System.out.println("Table size is now: " + hsize); + } + + /** + * Checks the load factor of the hash table if greater than .7, + * automatically lengthens table to prevent further collisions + */ + public void checkLoadFactor() { + double factor = (double) size / hsize; + if (factor > .7) { + System.out.println("Load factor is " + factor + ", lengthening table"); + lengthenTable(); + } else { + System.out.println("Load factor is " + factor); + } + } + + /** + * isFull returns true if the hash map is full and false if not full + * + * @return boolean is Empty + */ + public boolean isFull() { + boolean response = true; + for (int i = 0; i < hsize; i++) { + if (buckets[i] == null || buckets[i] == AVAILABLE) { + response = false; + break; + } + } + return response; + } + + /** + * isEmpty returns true if the hash map is empty and false if not empty + * + * @return boolean is Empty + */ + public boolean isEmpty() { + boolean response = true; + for (int i = 0; i < hsize; i++) { + if (buckets[i] != null) { + response = false; + break; + } + } + return response; + } +} diff --git a/DataStructures/HashMap/Hashing/Intersection b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection similarity index 95% rename from DataStructures/HashMap/Hashing/Intersection rename to src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection index 8b54eeae1a95..ffec70f26704 100644 --- a/DataStructures/HashMap/Hashing/Intersection +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection @@ -1,4 +1,4 @@ -package DataStructures.HashMap.Hashing; +package com.thealgorithms.datastructures.hashmap.hashing; /* * this is algo which implies common mathematical set theory concept * called intersection in which result is common values of both the sets diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java new file mode 100644 index 000000000000..7a2a54ae6d3e --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java @@ -0,0 +1,48 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.Scanner; + +public class Main { + + public static void main(String[] args) { + + int choice, key; + + HashMap h = new HashMap(7); + Scanner In = new Scanner(System.in); + + while (true) { + System.out.println("Enter your Choice :"); + System.out.println("1. Add Key"); + System.out.println("2. Delete Key"); + System.out.println("3. Print Table"); + System.out.println("4. Exit"); + + 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; + } + } + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainLinearProbing.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainLinearProbing.java new file mode 100644 index 000000000000..1a987db59d27 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainLinearProbing.java @@ -0,0 +1,60 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.Scanner; + +public class MainLinearProbing { + + public static void main(String[] args) { + + int choice, key; + + HashMapLinearProbing h = new HashMapLinearProbing(7); + Scanner In = new Scanner(System.in); + + while (true) { + System.out.println("Enter your Choice :"); + System.out.println("1. Add Key"); + System.out.println("2. Delete Key"); + System.out.println("3. Print Table"); + System.out.println("4. Exit"); + System.out.println("5. Search and print key index"); + System.out.println("6. Check load factor"); + + 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 5: { + System.out.println("Enter the Key to find and print: "); + key = In.nextInt(); + System.out.println("Key: " + key + " is at index: " + h.findHash(key)); + break; + } + case 6: { + h.checkLoadFactor(); + break; + } + } + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java b/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java new file mode 100644 index 000000000000..f18e4d4a960f --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java @@ -0,0 +1,13 @@ +package com.thealgorithms.datastructures.heaps; + +/** + * @author Nicolas Renard Exception to be thrown if the getElement method is + * used on an empty heap. + */ +@SuppressWarnings("serial") +public class EmptyHeapException extends Exception { + + public EmptyHeapException(String message) { + super(message); + } +} diff --git a/DataStructures/Heaps/GenericHeap b/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap similarity index 100% rename from DataStructures/Heaps/GenericHeap rename to src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java b/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java new file mode 100644 index 000000000000..da0795158cb3 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java @@ -0,0 +1,45 @@ +package com.thealgorithms.datastructures.heaps; + +/** + * Interface common to heap data structures.
+ * + *

+ * Heaps are tree-like data structures that allow storing elements in a specific + * way. Each node corresponds to an element and has one parent node (except for + * the root) and at most two children nodes. Every element contains a key, and + * those keys indicate how the tree shall be built. For instance, for a + * min-heap, the key of a node shall be greater than or equal to its parent's + * and lower than or equal to its children's (the opposite rule applies to a + * max-heap). + * + *

+ * All heap-related operations (inserting or deleting an element, extracting the + * min or max) are performed in O(log n) time. + * + * @author Nicolas Renard + */ +public interface Heap { + + /** + * @return the top element in the heap, the one with lowest key for min-heap + * or with the highest key for max-heap + * @throws EmptyHeapException if heap is empty + */ + HeapElement getElement() throws EmptyHeapException; + + /** + * Inserts an element in the heap. Adds it to then end and toggle it until + * it finds its right position. + * + * @param element an instance of the HeapElement class. + */ + void insertElement(HeapElement element); + + /** + * Delete an element in the heap. + * + * @param elementIndex int containing the position in the heap of the + * element to be deleted. + */ + void deleteElement(int elementIndex); +} diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java b/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java new file mode 100644 index 000000000000..5d31a2bdc0a4 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java @@ -0,0 +1,138 @@ +package com.thealgorithms.datastructures.heaps; + +/** + * Class for heap elements.
+ * + *

+ * A heap element contains two attributes: a key which will be used to build the + * tree (int or double, either primitive type or object) and any kind of + * IMMUTABLE object the user sees fit to carry any information he/she likes. Be + * aware that the use of a mutable object might jeopardize the integrity of this + * information. + * + * @author Nicolas Renard + */ +public class HeapElement { + + private final double key; + private final Object additionalInfo; + + // Constructors + /** + * @param key : a number of primitive type 'double' + * @param info : any kind of IMMUTABLE object. May be null, since the + * purpose is only to carry additional information of use for the user + */ + public HeapElement(double key, Object info) { + this.key = key; + this.additionalInfo = info; + } + + /** + * @param key : a number of primitive type 'int' + * @param info : any kind of IMMUTABLE object. May be null, since the + * purpose is only to carry additional information of use for the user + */ + public HeapElement(int key, Object info) { + this.key = key; + this.additionalInfo = info; + } + + /** + * @param key : a number of object type 'Integer' + * @param info : any kind of IMMUTABLE object. May be null, since the + * purpose is only to carry additional information of use for the user + */ + public HeapElement(Integer key, Object info) { + this.key = key; + this.additionalInfo = info; + } + + /** + * @param key : a number of object type 'Double' + * @param info : any kind of IMMUTABLE object. May be null, since the + * purpose is only to carry additional information of use for the user + */ + public HeapElement(Double key, Object info) { + this.key = key; + this.additionalInfo = info; + } + + /** + * @param key : a number of primitive type 'double' + */ + public HeapElement(double key) { + this.key = key; + this.additionalInfo = null; + } + + /** + * @param key : a number of primitive type 'int' + */ + public HeapElement(int key) { + this.key = key; + this.additionalInfo = null; + } + + /** + * @param key : a number of object type 'Integer' + */ + public HeapElement(Integer key) { + this.key = key; + this.additionalInfo = null; + } + + /** + * @param key : a number of object type 'Double' + */ + public HeapElement(Double key) { + this.key = key; + this.additionalInfo = null; + } + + // Getters + /** + * @return the object containing the additional info provided by the user. + */ + public Object getInfo() { + return additionalInfo; + } + + /** + * @return the key value of the element + */ + public double getKey() { + return key; + } + + // Overridden object methods + public String toString() { + return "Key: " + key + " - " + additionalInfo.toString(); + } + + /** + * @param otherHeapElement + * @return true if the keys on both elements are identical and the + * additional info objects are identical. + */ + @Override + public boolean equals(Object o) { + if (o != null) { + if (!(o instanceof HeapElement)) { + return false; + } + HeapElement otherHeapElement = (HeapElement) o; + return (this.key == otherHeapElement.key) + && (this.additionalInfo.equals(otherHeapElement.additionalInfo)); + } + return false; + } + + @Override + public int hashCode() { + int result = 0; + result = 31 * result + (int) key; + result = 31 * result + (additionalInfo != null ? additionalInfo.hashCode() : 0); + return result; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java new file mode 100644 index 000000000000..13eb7a20cbbc --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java @@ -0,0 +1,134 @@ +package com.thealgorithms.datastructures.heaps; + +import java.util.ArrayList; +import java.util.List; + +/** + * Heap tree where a node's key is higher than or equal to its parent's and + * lower than or equal to its children's. + * + * @author Nicolas Renard + */ +public class MaxHeap implements Heap { + + private final List maxHeap; + + public MaxHeap(List listElements) { + maxHeap = new ArrayList<>(); + for (HeapElement heapElement : listElements) { + if (heapElement != null) { + insertElement(heapElement); + } else { + System.out.println("Null element. Not added to heap"); + } + } + if (maxHeap.size() == 0) { + System.out.println("No element has been added, empty heap."); + } + } + + /** + * Get the element at a given index. The key for the list is equal to index + * value - 1 + * + * @param elementIndex index + * @return heapElement + */ + public HeapElement getElement(int elementIndex) { + if ((elementIndex <= 0) || (elementIndex > maxHeap.size())) { + throw new IndexOutOfBoundsException("Index out of heap range"); + } + return maxHeap.get(elementIndex - 1); + } + + // Get the key of the element at a given index + private double getElementKey(int elementIndex) { + return maxHeap.get(elementIndex - 1).getKey(); + } + + // Swaps two elements in the heap + private void swap(int index1, int index2) { + HeapElement temporaryElement = maxHeap.get(index1 - 1); + maxHeap.set(index1 - 1, maxHeap.get(index2 - 1)); + maxHeap.set(index2 - 1, temporaryElement); + } + + // Toggle an element up to its right place as long as its key is lower than its parent's + private void toggleUp(int elementIndex) { + double key = maxHeap.get(elementIndex - 1).getKey(); + while (getElementKey((int) Math.floor(elementIndex / 2.0)) < key) { + swap(elementIndex, (int) Math.floor(elementIndex / 2.0)); + elementIndex = (int) Math.floor(elementIndex / 2.0); + } + } + + // Toggle an element down to its right place as long as its key is higher + // 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()))); + 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))) { + 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()))); + } + } + + private HeapElement extractMax() { + HeapElement result = maxHeap.get(0); + deleteElement(0); + return result; + } + + @Override + public void insertElement(HeapElement element) { + maxHeap.add(element); + toggleUp(maxHeap.size()); + } + + @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(); + } + if ((elementIndex > maxHeap.size()) || (elementIndex <= 0)) { + throw new IndexOutOfBoundsException("Index out of heap range"); + } + // The last element in heap replaces the one to be deleted + 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))) { + toggleUp(elementIndex); + } // ... or down ? + else if (((2 * elementIndex <= maxHeap.size()) + && (getElementKey(elementIndex) < getElementKey(elementIndex * 2))) + || ((2 * elementIndex < maxHeap.size()) + && (getElementKey(elementIndex) < getElementKey(elementIndex * 2)))) { + toggleDown(elementIndex); + } + } + + @Override + public HeapElement getElement() throws EmptyHeapException { + try { + return extractMax(); + } catch (Exception e) { + throw new EmptyHeapException("Heap is empty. Error retrieving element"); + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java new file mode 100644 index 000000000000..37434d207725 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java @@ -0,0 +1,128 @@ +package com.thealgorithms.datastructures.heaps; + +import java.util.ArrayList; +import java.util.List; + +/** + * Heap tree where a node's key is higher than or equal to its parent's and + * lower than or equal to its children's. + * + * @author Nicolas Renard + */ +public class MinHeap implements Heap { + + private final List minHeap; + + public MinHeap(List listElements) { + minHeap = new ArrayList<>(); + for (HeapElement heapElement : listElements) { + if (heapElement != null) { + insertElement(heapElement); + } else { + System.out.println("Null element. Not added to heap"); + } + } + if (minHeap.size() == 0) { + System.out.println("No element has been added, empty heap."); + } + } + + // Get the element at a given index. The key for the list is equal to index value - 1 + public HeapElement getElement(int elementIndex) { + if ((elementIndex <= 0) || (elementIndex > minHeap.size())) { + throw new IndexOutOfBoundsException("Index out of heap range"); + } + return minHeap.get(elementIndex - 1); + } + + // Get the key of the element at a given index + private double getElementKey(int elementIndex) { + return minHeap.get(elementIndex - 1).getKey(); + } + + // Swaps two elements in the heap + private void swap(int index1, int index2) { + HeapElement temporaryElement = minHeap.get(index1 - 1); + minHeap.set(index1 - 1, minHeap.get(index2 - 1)); + minHeap.set(index2 - 1, temporaryElement); + } + + // Toggle an element up to its right place as long as its key is lower than its parent's + private void toggleUp(int elementIndex) { + double key = minHeap.get(elementIndex - 1).getKey(); + while (getElementKey((int) Math.floor(elementIndex / 2.0)) > key) { + swap(elementIndex, (int) Math.floor(elementIndex / 2.0)); + elementIndex = (int) Math.floor(elementIndex / 2.0); + } + } + + // Toggle an element down to its right place as long as its key is higher + // 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()))); + 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))) { + 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()))); + } + } + + private HeapElement extractMin() { + HeapElement result = minHeap.get(0); + deleteElement(0); + return result; + } + + @Override + public void insertElement(HeapElement element) { + minHeap.add(element); + toggleUp(minHeap.size()); + } + + @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(); + } + if ((elementIndex > minHeap.size()) || (elementIndex <= 0)) { + throw new IndexOutOfBoundsException("Index out of heap range"); + } + // The last element in heap replaces the one to be deleted + 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))) { + toggleUp(elementIndex); + } // ... or down ? + else if (((2 * elementIndex <= minHeap.size()) + && (getElementKey(elementIndex) > getElementKey(elementIndex * 2))) + || ((2 * elementIndex < minHeap.size()) + && (getElementKey(elementIndex) > getElementKey(elementIndex * 2)))) { + toggleDown(elementIndex); + } + } + + @Override + public HeapElement getElement() throws EmptyHeapException { + try { + return extractMin(); + } catch (Exception e) { + throw new EmptyHeapException("Heap is empty. Error retrieving element"); + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java b/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java new file mode 100644 index 000000000000..114159234aab --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java @@ -0,0 +1,138 @@ +package com.thealgorithms.datastructures.heaps; + +/** + * Minimum Priority Queue It is a part of heap data structure A heap is a + * specific tree based data structure in which all the nodes of tree are in a + * specific order. that is the children are arranged in some respect of their + * parents, can either be greater or less than the parent. This makes it a min + * priority queue or max priority queue. + * + *

+ * + *

+ * Functions: insert, delete, peek, isEmpty, print, heapSort, sink + */ +public class MinPriorityQueue { + + private int[] heap; + private int capacity; + private int size; + + // calss the constructor and initializes the capacity + MinPriorityQueue(int c) { + this.capacity = c; + this.size = 0; + this.heap = new int[c + 1]; + } + + // inserts the key at the end and rearranges it + // so that the binary heap is in appropriate order + public void insert(int key) { + if (this.isFull()) { + return; + } + this.heap[this.size + 1] = key; + int k = this.size + 1; + while (k > 1) { + if (this.heap[k] < this.heap[k / 2]) { + int temp = this.heap[k]; + this.heap[k] = this.heap[k / 2]; + this.heap[k / 2] = temp; + } + k = k / 2; + } + this.size++; + } + + // returns the highest priority value + public int peek() { + return this.heap[1]; + } + + // returns boolean value whether the heap is empty or not + public boolean isEmpty() { + if (0 == this.size) { + return true; + } + return false; + } + + // returns boolean value whether the heap is full or not + public boolean isFull() { + if (this.size == this.capacity) { + return true; + } + return false; + } + + // prints the heap + public void print() { + for (int i = 1; i <= this.capacity; i++) { + System.out.print(this.heap[i] + " "); + } + System.out.println(); + } + + // heap sorting can be done by performing + // delete function to the number of times of the size of the heap + // it returns reverse sort because it is a min priority queue + public void heapSort() { + for (int i = 1; i < this.capacity; i++) { + this.delete(); + } + } + + // this function reorders the heap after every delete function + private void sink() { + int k = 1; + 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]) { + break; + } else if (2 * k + 1 > this.size) { + break; + } + } + 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; + } else { + minIndex = k; + } + } + int temp = this.heap[k]; + this.heap[k] = this.heap[minIndex]; + this.heap[minIndex] = temp; + k = minIndex; + } + } + + // deletes the highest priority value from the heap + public int delete() { + int min = this.heap[1]; + this.heap[1] = this.heap[this.size]; + this.heap[this.size] = min; + this.size--; + this.sink(); + return min; + } + + public static void main(String[] args) { + // testing + MinPriorityQueue q = new MinPriorityQueue(8); + q.insert(5); + q.insert(2); + q.insert(4); + q.insert(1); + q.insert(7); + q.insert(6); + q.insert(3); + q.insert(8); + q.print(); // [ 1, 2, 3, 5, 7, 6, 4, 8 ] + q.heapSort(); + q.print(); // [ 8, 7, 6, 5, 4, 3, 2, 1 ] + } +} diff --git a/DataStructures/Heaps/Readme.md b/src/main/java/com/thealgorithms/datastructures/heaps/Readme.md similarity index 100% rename from DataStructures/Heaps/Readme.md rename to src/main/java/com/thealgorithms/datastructures/heaps/Readme.md diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java new file mode 100644 index 000000000000..c5dd7f91ac3a --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java @@ -0,0 +1,104 @@ +package com.thealgorithms.datastructures.lists; + +public class CircleLinkedList { + + private static class Node { + + Node next; + E value; + + private Node(E value, Node next) { + this.value = value; + this.next = next; + } + } + + // For better O.O design this should be private allows for better black box design + private int size; + // this will point to dummy node; + private Node head = null; + private Node tail = null; // keeping a tail pointer to keep track of the end of list + + // constructer for class.. here we will make a dummy node for circly linked list implementation + // with reduced error catching as our list will never be empty; + public CircleLinkedList() { + // creation of the dummy node + head = new Node(null, head); + tail = head; + size = 0; + } + + // getter for the size... needed because size is private. + public int getSize() { + return size; + } + + // for the sake of simplistiy this class will only contain the append function or addLast other + // add functions can be implemented however this is the basses of them all really. + 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"); + } + // head.next points to the last element; + if (tail == null) { + tail = new Node(value, head); + head.next = tail; + } else { + tail.next = new Node(value, head); + tail = tail.next; + } + size++; + } + + // utility function for teraversing the list + public String toString() { + Node p = head.next; + String s = "[ "; + while (p != head) { + s += p.value; + s += " , "; + p = p.next; + } + return s + " ]"; + } + + public static void main(String args[]) { + CircleLinkedList cl = new CircleLinkedList(); + cl.append(12); + System.out.println(cl); + cl.append(23); + System.out.println(cl); + cl.append(34); + System.out.println(cl); + cl.append(56); + System.out.println(cl); + cl.remove(3); + System.out.println(cl); + } + + public E remove(int pos) { + if (pos > size || pos < 0) { + // catching errors + 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. + Node before = head; + for (int i = 1; i <= pos; i++) { + before = before.next; + } + Node destroy = before.next; + E saved = destroy.value; + // assigning the next reference to the the element following the element we want to remove... + // the last element will be assigned to the head. + before.next = before.next.next; + // scrubbing + if (destroy == tail) { + tail = before; + } + destroy = null; + size--; + return saved; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java b/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java new file mode 100644 index 000000000000..8d864bc8caae --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java @@ -0,0 +1,30 @@ +package com.thealgorithms.datastructures.lists; + +public class CountSinglyLinkedListRecursion extends SinglyLinkedList { + + public static void main(String[] args) { + CountSinglyLinkedListRecursion list = new CountSinglyLinkedListRecursion(); + for (int i = 1; i <= 5; ++i) { + list.insert(i); + } + assert list.count() == 5; + } + + /** + * Calculate the count of the list manually using recursion. + * + * @param head head of the list. + * @return count of the list. + */ + private int countRecursion(Node head) { + return head == null ? 0 : 1 + countRecursion(head.next); + } + + /** + * Returns the count of the list. + */ + @Override + public int count() { + return countRecursion(getHead()); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java b/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java new file mode 100644 index 000000000000..ac3724406798 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java @@ -0,0 +1,105 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.Scanner; + +public class CreateAndDetectLoop { + + /** + * Prints the linked list. + * + * @param head head node of the linked list + */ + static void printList(Node head) { + Node cur = head; + + while (cur != null) { + System.out.print(cur.value + " "); + cur = cur.next; + } + } + + /** + * Creates a loop in the linked list. + * + * @see + * + * GeeksForGeeks: Make a loop at K-th position + * @param head head node of the linked list + * @param k position of node where loop is to be created + */ + static void createLoop(Node head, int k) { + if (head == null) { + return; + } + Node temp = head; + int count = 1; + while (count < k) { // Traverse the list till the kth node + temp = temp.next; + count++; + } + + Node connectedPoint = temp; + + while (temp.next != null) // Traverse remaining nodes + { + temp = temp.next; + } + + temp.next = connectedPoint; // Connect last node to k-th element + } + + /** + * Detects the presence of a loop in the linked list. + * + * @see + * + * Floyd's Cycle Detection Algorithm + * + * @param head the head node of the linked list + * + * @return true if loop exists else false + */ + static boolean detectLoop(Node head) { + Node sptr = head; + Node fptr = head; + + while (fptr != null && fptr.next != null) { + sptr = sptr.next; + fptr = fptr.next.next; + if (fptr == sptr) { + return true; + } + } + + return false; + } + + public static void main(String[] args) { + SinglyLinkedList singlyLinkedList = new SinglyLinkedList(); + Scanner sc = new Scanner(System.in); + + System.out.println("Enter the number of elements to be inserted: "); + int n = sc.nextInt(); + System.out.printf("Enter the %d elements: \n", n); + while (n-- > 0) { + singlyLinkedList.insert(sc.nextInt()); + } + + System.out.print("Given list: "); + printList(singlyLinkedList.getHead()); + System.out.println(); + + System.out.println("Enter the location to generate loop: "); + int k = sc.nextInt(); + + createLoop(singlyLinkedList.getHead(), k); + + if (detectLoop(singlyLinkedList.getHead())) { + System.out.println("Loop found"); + } else { + System.out.println("No loop found"); + } + + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java new file mode 100644 index 000000000000..b0149feccdd7 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java @@ -0,0 +1,200 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.Objects; + +/** + * This class implements a Cursor Linked List. + * + * A CursorLinkedList is an array version of a Linked List. Essentially you have + * an array of list nodes but instead of each node containing a pointer to the + * next item in the linked list, each node element in the array contains the + * index for the next node element. + * + */ +public class CursorLinkedList { + + private static class Node { + + T element; + int next; + + Node(T element, int next) { + this.element = element; + this.next = next; + } + } + + private final int os; + private int head; + private final Node[] cursorSpace; + private int count; + private static final int CURSOR_SPACE_SIZE = 100; + + { + // init at loading time + cursorSpace = new Node[CURSOR_SPACE_SIZE]; + for (int i = 0; i < CURSOR_SPACE_SIZE; i++) { + cursorSpace[i] = new Node<>(null, i + 1); + } + cursorSpace[CURSOR_SPACE_SIZE - 1].next = 0; + } + + public CursorLinkedList() { + os = 0; + count = 0; + head = -1; + } + + public void printList() { + + if (head != -1) { + + int start = head; + while (start != -1) { + + T element = cursorSpace[start].element; + System.out.println(element.toString()); + start = cursorSpace[start].next; + } + } + } + + /** + * @return the logical index of the element within the list , not the actual + * index of the [cursorSpace] array + */ + public int indexOf(T element) { + + Objects.requireNonNull(element); + Node iterator = cursorSpace[head]; + for (int i = 0; i < count; i++) { + if (iterator.element.equals(element)) { + return i; + } + iterator = cursorSpace[iterator.next]; + } + + return -1; + } + + /** + * @param position , the logical index of the element , not the actual one + * within the [cursorSpace] array . this method should be used to get the + * index give by indexOf() method. + * @return + */ + public T get(int position) { + + if (position >= 0 && position < count) { + + int start = head; + int counter = 0; + while (start != -1) { + + T element = cursorSpace[start].element; + if (counter == position) { + return element; + } + + start = cursorSpace[start].next; + counter++; + } + } + + return null; + } + + public void removeByIndex(int index) { + + if (index >= 0 && index < count) { + + T element = get(index); + remove(element); + } + } + + public void remove(T element) { + + Objects.requireNonNull(element); + + // case element is in the head + T temp_element = cursorSpace[head].element; + int temp_next = cursorSpace[head].next; + if (temp_element.equals(element)) { + free(head); + head = temp_next; + } else { // otherwise cases + + int prev_index = head; + int current_index = cursorSpace[prev_index].next; + + while (current_index != -1) { + + T current_element = cursorSpace[current_index].element; + if (current_element.equals(element)) { + cursorSpace[prev_index].next = cursorSpace[current_index].next; + free(current_index); + break; + } + + prev_index = current_index; + current_index = cursorSpace[prev_index].next; + } + } + + count--; + } + + private void free(int index) { + + Node os_node = cursorSpace[os]; + int os_next = os_node.next; + cursorSpace[os].next = index; + cursorSpace[index].element = null; + cursorSpace[index].next = os_next; + } + + public void append(T element) { + + Objects.requireNonNull(element); + int availableIndex = alloc(); + cursorSpace[availableIndex].element = element; + + if (head == -1) { + head = availableIndex; + } + + int iterator = head; + while (cursorSpace[iterator].next != -1) { + iterator = cursorSpace[iterator].next; + } + + cursorSpace[iterator].next = availableIndex; + cursorSpace[availableIndex].next = -1; + + count++; + } + + /** + * @return the index of the next available node + */ + private int alloc() { + + // 1- get the index at which the os is pointing + int availableNodeIndex = cursorSpace[os].next; + + if (availableNodeIndex == 0) { + throw new OutOfMemoryError(); + } + + // 2- make the os point to the next of the @var{availableNodeIndex} + int availableNext = cursorSpace[availableNodeIndex].next; + cursorSpace[os].next = availableNext; + + // this to indicate an end of the list , helpful at testing since any err + // would throw an outOfBoundException + cursorSpace[availableNodeIndex].next = -1; + + return availableNodeIndex; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java new file mode 100644 index 000000000000..095904fdf1b8 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java @@ -0,0 +1,397 @@ +package com.thealgorithms.datastructures.lists; + +/** + * This class implements a DoublyLinkedList. This is done using the classes + * LinkedList and Link. + * + *

+ * A linked list is similar to an array, it holds values. However, links in a + * linked list do not have indexes. With a linked list you do not need to + * predetermine it's size as it grows and shrinks as it is edited. This is an + * example of a double ended, doubly linked list. Each link references the next + * link and the previous one. + * + * @author Unknown + */ +public class DoublyLinkedList { + + /** + * Head refers to the front of the list + */ + private Link head; + /** + * Tail refers to the back of the list + */ + private Link tail; + + /** + * Size refers to the number of elements present in the list + */ + private int size; + + /** + * Default Constructor + */ + public DoublyLinkedList() { + head = null; + tail = null; + size = 0; + } + + /** + * Constructs a list containing the elements of the array + * + * @param array the array whose elements are to be placed into this list + * @throws NullPointerException if the specified collection is null + */ + public DoublyLinkedList(int[] array) { + if (array == null) { + throw new NullPointerException(); + } + for (int i : array) { + insertTail(i); + } + size = array.length; + } + + /** + * Insert an element at the head + * + * @param x Element to be inserted + */ + public void insertHead(int x) { + Link newLink = new Link(x); // Create a new link with a value attached to it + if (isEmpty()) // Set the first element added to be the tail + { + tail = newLink; + } else { + head.previous = newLink; // newLink <-- currenthead(head) + } + newLink.next = head; // newLink <--> currenthead(head) + head = newLink; // newLink(head) <--> oldhead + ++size; + } + + /** + * Insert an element at the tail + * + * @param x Element to be inserted + */ + public void insertTail(int x) { + Link newLink = new Link(x); + newLink.next = null; // currentTail(tail) newlink --> + if (isEmpty()) { // Check if there are no elements in list then it adds first element + tail = newLink; + head = tail; + } else { + tail.next = newLink; // currentTail(tail) --> newLink --> + newLink.previous = tail; // currentTail(tail) <--> newLink --> + tail = newLink; // oldTail <--> newLink(tail) --> + } + ++size; + } + + /** + * Insert an element at the index + * + * @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) { + if (index > size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + if (index == 0) { + insertHead(x); + } else { + if (index == size) { + insertTail(x); + } else { + Link newLink = new Link(x); + Link previousLink = head; // + for (int i = 1; i < index; i++) { // Loop to reach the index + previousLink = previousLink.next; + } + // previousLink is the Link at index - 1 from start + previousLink.next.previous = newLink; + newLink.next = previousLink.next; + newLink.previous = previousLink; + previousLink.next = newLink; + } + } + ++size; + } + + /** + * Delete the element at the head + * + * @return The new head + */ + public Link deleteHead() { + Link temp = head; + head = head.next; // oldHead <--> 2ndElement(head) + + if (head == null) { + tail = null; + } else { + head.previous + = null; // oldHead --> 2ndElement(head) nothing pointing at old head so will be removed + } + --size; + return temp; + } + + /** + * Delete the element at the tail + * + * @return The new tail + */ + public Link deleteTail() { + Link temp = tail; + tail = tail.previous; // 2ndLast(tail) <--> oldTail --> null + + if (tail == null) { + head = null; + } else { + tail.next = null; // 2ndLast(tail) --> null + } + --size; + return temp; + } + + /** + * Delete the element from somewhere in the list + * + * @param x element to be deleted + * @return Link deleted + */ + public void delete(int x) { + Link current = head; + + while (current.value != x) { // Find the position to delete + 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!"); + } + } + + if (current == head) { + deleteHead(); + } else if (current == tail) { + deleteTail(); + } else { // Before: 1 <--> 2(current) <--> 3 + current.previous.next = current.next; // 1 --> 3 + current.next.previous = current.previous; // 1 <--> 3 + } + --size; + } + + /** + * Inserts element and reorders + * + * @param x Element to be added + */ + public void insertOrdered(int x) { + Link newLink = new Link(x); + Link current = head; + while (current != null && x > current.value) // Find the position to insert + { + current = current.next; + } + + if (current == head) { + insertHead(x); + } else if (current == null) { + insertTail(x); + } else { // Before: 1 <--> 2(current) <--> 3 + newLink.previous = current.previous; // 1 <-- newLink + current.previous.next = newLink; // 1 <--> newLink + newLink.next = current; // 1 <--> newLink --> 2(current) <--> 3 + current.previous = newLink; // 1 <--> newLink <--> 2(current) <--> 3 + } + ++size; + } + + /** + * Deletes the passed node from the current list + * + * @param z Element to be deleted + */ + public void deleteNode(Link z) { + if (z.next == null) { + deleteTail(); + } else if (z == head) { + deleteHead(); + } else { // before <-- 1 <--> 2(z) <--> 3 --> + z.previous.next = z.next; // 1 --> 3 + z.next.previous = z.previous; // 1 <--> 3 + } + --size; + } + + public static void removeDuplicates(DoublyLinkedList l) { + Link linkOne = l.head; + while (linkOne.next != null) { // list is present + Link linkTwo = linkOne.next; // second link for comparison + while (linkTwo.next != null) { + if (linkOne.value == linkTwo.value) // if there are duplicates values then + { + l.delete(linkTwo.value); // delete the link + } + linkTwo = linkTwo.next; // go to next link + } + linkOne = linkOne.next; // go to link link to iterate the whole list again + } + } + + /** + * Reverses the list in place + * + * @param l the DoublyLinkedList to reverse + */ + public void reverse() { + // Keep references to the head and tail + Link thisHead = this.head; + Link thisTail = this.tail; + + // Flip the head and tail references + this.head = thisTail; + this.tail = thisHead; + + // While the link we're visiting is not null, flip the + // next and previous links + Link nextLink = thisHead; + while (nextLink != null) { + Link nextLinkNext = nextLink.next; + Link nextLinkPrevious = nextLink.previous; + nextLink.next = nextLinkPrevious; + nextLink.previous = nextLinkNext; + + // Now, we want to go to the next link + nextLink = nextLinkNext; + } + } + + /** + * Clears List + */ + public void clearList() { + head = null; + tail = null; + size = 0; + } + + /** + * Returns true if list is empty + * + * @return true if list is empty + */ + public boolean isEmpty() { + return (head == null); + } + + /** + * Prints contents of the list + */ + public void display() { // Prints contents of the list + Link current = head; + while (current != null) { + current.displayLink(); + current = current.next; + } + System.out.println(); + } + + /** + * Prints the contents of the list in reverse order + */ + public void displayBackwards() { + Link current = tail; + while (current != null) { + current.displayLink(); + current = current.previous; + } + System.out.println(); + } +} + +/** + * This class is used to implement the nodes of the linked list. + * + * @author Unknown + */ +class Link { + + /** + * Value of node + */ + public int value; + /** + * This points to the link in front of the new link + */ + public Link next; + /** + * This points to the link behind the new link + */ + public Link previous; + + /** + * Constructor + * + * @param value Value of node + */ + public Link(int value) { + this.value = value; + } + + /** + * Displays the node + */ + public void displayLink() { + System.out.print(value + " "); + } + + /** + * Main Method + * + * @param args Command line arguments + */ + public static void main(String args[]) { + DoublyLinkedList myList = new DoublyLinkedList(); + myList.insertHead(13); + myList.insertHead(7); + myList.insertHead(10); + myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) --> + myList.displayBackwards(); + + myList.insertTail(11); + myList.display(); // <-- 10(head) <--> 7 <--> 13 <--> 11(tail) --> + myList.displayBackwards(); + + myList.deleteTail(); + myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) --> + myList.displayBackwards(); + + myList.delete(7); + myList.display(); // <-- 10(head) <--> 13(tail) --> + myList.displayBackwards(); + + myList.insertOrdered(23); + myList.insertOrdered(67); + myList.insertOrdered(3); + myList.display(); // <-- 3(head) <--> 10 <--> 13 <--> 23 <--> 67(tail) --> + myList.insertElementByIndex(5, 1); + myList.display(); // <-- 3(head) <--> 5 <--> 10 <--> 13 <--> 23 <--> 67(tail) --> + myList.displayBackwards(); + myList.reverse(); // <-- 67(head) <--> 23 <--> 13 <--> 10 <--> 5 <--> 3(tail) --> + myList.display(); + + myList.clearList(); + myList.display(); + myList.displayBackwards(); + myList.insertHead(20); + myList.display(); + myList.displayBackwards(); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java new file mode 100644 index 000000000000..80b36b8e4ab1 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java @@ -0,0 +1,63 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author https://github.com/shellhub + */ +public class MergeSortedArrayList { + + public static void main(String[] args) { + List listA = new ArrayList<>(); + List listB = new ArrayList<>(); + List listC = new ArrayList<>(); + + /* init ListA and List B */ + for (int i = 1; i <= 10; i += 2) { + listA.add(i); + /* listA: [1, 3, 5, 7, 9] */ + listB.add(i + 1); + /* listB: [2, 4, 6, 8, 10] */ + } + + /* merge listA and listB to listC */ + merge(listA, listB, listC); + + System.out.println("listA: " + listA); + System.out.println("listB: " + listB); + System.out.println("listC: " + listC); + } + + /** + * merge two sorted ArrayList + * + * @param listA the first list to merge + * @param listB the second list to merge + * @param listC the result list after merging + */ + public static void merge(List listA, List listB, List listC) { + int pa = 0; + /* the index of listA */ + int pb = 0; + /* the index of listB */ + + while (pa < listA.size() && pb < listB.size()) { + if (listA.get(pa) <= listB.get(pb)) { + listC.add(listA.get(pa++)); + } else { + listC.add(listB.get(pb++)); + } + } + + /* copy left element of listA to listC */ + while (pa < listA.size()) { + listC.add(listA.get(pa++)); + } + + /* copy left element of listB to listC */ + while (pb < listB.size()) { + listC.add(listB.get(pb++)); + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java new file mode 100644 index 000000000000..2bee945c9db6 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java @@ -0,0 +1,51 @@ +package com.thealgorithms.datastructures.lists; + +public class MergeSortedSinglyLinkedList extends SinglyLinkedList { + + public static void main(String[] args) { + SinglyLinkedList listA = new SinglyLinkedList(); + SinglyLinkedList listB = new SinglyLinkedList(); + + for (int i = 2; i <= 10; i += 2) { + listA.insert(i); + listB.insert(i - 1); + } + 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"); + } + + /** + * Merge two sorted SingleLinkedList + * + * @param listA the first sorted list + * @param listB the second sored list + * @return merged sorted list + */ + public static SinglyLinkedList merge(SinglyLinkedList listA, SinglyLinkedList listB) { + Node headA = listA.getHead(); + Node headB = listB.getHead(); + + int size = listA.size() + listB.size(); + + Node head = new Node(); + Node tail = head; + while (headA != null && headB != null) { + if (headA.value <= headB.value) { + tail.next = headA; + headA = headA.next; + } else { + tail.next = headB; + headB = headB.next; + } + tail = tail.next; + } + if (headA == null) { + tail.next = headB; + } + if (headB == null) { + tail.next = headA; + } + return new SinglyLinkedList(head.next, size); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java b/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java new file mode 100644 index 000000000000..9a06b4a6587f --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java @@ -0,0 +1,57 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.PriorityQueue; + +/** + * @author Arun Pandey (https://github.com/pandeyarun709) + */ +public class Merge_K_SortedLinkedlist { + + /** + * This function merge K sorted LinkedList + * + * @param a array of LinkedList + * @param N size of array + * @return node + */ + Node mergeKList(Node[] a, int N) { + // Min Heap + PriorityQueue min = new PriorityQueue<>(Comparator.comparingInt(x -> x.data)); + + // adding head of all linkedList in min heap + min.addAll(Arrays.asList(a).subList(0, N)); + + // Make new head among smallest heads in K linkedList + Node head = min.poll(); + min.add(head.next); + Node curr = head; + + // merging LinkedList + while (!min.isEmpty()) { + + Node temp = min.poll(); + curr.next = temp; + curr = temp; + + // Add Node in min Heap only if temp.next is not null + if (temp.next != null) { + min.add(temp.next); + } + } + + return head; + } + + private class Node { + + private int data; + private Node next; + + public Node(int d) { + this.data = d; + next = null; + } + } +} diff --git a/DataStructures/Lists/README.md b/src/main/java/com/thealgorithms/datastructures/lists/README.md similarity index 100% rename from DataStructures/Lists/README.md rename to src/main/java/com/thealgorithms/datastructures/lists/README.md diff --git a/DataStructures/Lists/RemoveDuplicateNodes.java b/src/main/java/com/thealgorithms/datastructures/lists/RemoveDuplicateNodes.java similarity index 96% rename from DataStructures/Lists/RemoveDuplicateNodes.java rename to src/main/java/com/thealgorithms/datastructures/lists/RemoveDuplicateNodes.java index 944f7b1746e0..268951f12171 100644 --- a/DataStructures/Lists/RemoveDuplicateNodes.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/RemoveDuplicateNodes.java @@ -1,4 +1,4 @@ -package DataStructures.Lists; +package com.thealgorithms.datastructures.lists; public class RemoveDuplicateNodes { @@ -48,4 +48,4 @@ public static void main(String arg[]) { head = instance.deleteDuplicates(head); instance.print(head); } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java b/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java new file mode 100644 index 000000000000..c6e38cebdcb3 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java @@ -0,0 +1,33 @@ +package com.thealgorithms.datastructures.lists; + +public class SearchSinglyLinkedListRecursion extends SinglyLinkedList { + + public static void main(String[] args) { + SearchSinglyLinkedListRecursion list = new SearchSinglyLinkedListRecursion(); + for (int i = 1; i <= 10; ++i) { + list.insert(i); + } + + for (int i = 1; i <= 10; ++i) { + assert list.search(i); + } + assert !list.search(-1) && !list.search(100); + } + + /** + * Test if the value key is present in the list using recursion. + * + * @param node the head node. + * @param key the value to be searched. + * @return {@code true} if key is present in the list, otherwise + * {@code false}. + */ + private boolean searchRecursion(Node node, int key) { + return node != null && (node.value == key || searchRecursion(node.next, key)); + } + + @Override + public boolean search(int key) { + return searchRecursion(getHead(), key); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java new file mode 100644 index 000000000000..ae06688bcf46 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java @@ -0,0 +1,376 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.StringJoiner; + +/** + * https://en.wikipedia.org/wiki/Linked_list + */ +public class SinglyLinkedList { + + /** + * Head refer to the front of the list + */ + private Node head; + + /** + * Size of SinglyLinkedList + */ + private int size; + + /** + * Init SinglyLinkedList + */ + public SinglyLinkedList() { + head = null; + size = 0; + } + + /** + * Init SinglyLinkedList with specified head node and size + * + * @param head the head node of list + * @param size the size of list + */ + public SinglyLinkedList(Node head, int size) { + this.head = head; + this.size = size; + } + + /** + * Inserts an element at the head of the list + * + * @param x element to be added + */ + public void insertHead(int x) { + insertNth(x, 0); + } + + /** + * Insert an element at the tail of the list + * + * @param data element to be added + */ + public void insert(int data) { + insertNth(data, size); + } + + /** + * Inserts a new node at a specified position of the list + * + * @param data data to be stored in a new node + * @param position position at which a new node is to be inserted + */ + public void insertNth(int data, int position) { + checkBounds(position, 0, size); + Node newNode = new Node(data); + if (head == null) { + /* the list is empty */ + head = newNode; + size++; + return; + } else if (position == 0) { + /* insert at the head of the list */ + newNode.next = head; + head = newNode; + size++; + return; + } + Node cur = head; + for (int i = 0; i < position - 1; ++i) { + cur = cur.next; + } + newNode.next = cur.next; + cur.next = newNode; + size++; + } + + /** + * Detects if there is a loop in the singly linked list using floy'd turtle + * and hare algorithm. + * + */ + public boolean detectLoop() { + Node currentNodeFast = head; + Node currentNodeSlow = head; + boolean flag = false; + while (currentNodeFast != null && currentNodeFast.next != null && currentNodeSlow != null && currentNodeSlow.next != null) { + currentNodeFast = currentNodeFast.next.next; + currentNodeSlow = currentNodeSlow.next; + if (currentNodeFast == currentNodeSlow) { + flag = true; + break; + } + } + return flag; + } + + /** + * Swaps nodes of two given values a and b. + * + */ + public void swapNodes(int a, int b) { + Node currentNode = head; + Node temp = null; + while (currentNode != null) { + if (currentNode.next.value == a) { + temp = currentNode.next; + } + if (currentNode.next.value == b) { + currentNode.next = temp; + } + currentNode = currentNode.next; + } + } + + /** + * Reverse a singly linked list from a given node till the end + * + */ + Node reverseList(Node node) { + Node prev = null, curr = node, next; + while (curr != null) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + node = prev; + return node; + } + + /** + * Deletes a node at the head + */ + public void deleteHead() { + deleteNth(0); + } + + /** + * Deletes an element at the tail + */ + public void delete() { + deleteNth(size - 1); + } + + /** + * Deletes an element at Nth position + */ + public void deleteNth(int position) { + checkBounds(position, 0, size - 1); + if (position == 0) { + Node destroy = head; + head = head.next; + destroy = null; + /* clear to let GC do its work */ + size--; + return; + } + Node cur = head; + for (int i = 0; i < position - 1; ++i) { + cur = cur.next; + } + + Node destroy = cur.next; + cur.next = cur.next.next; + destroy = null; // clear to let GC do its work + + size--; + } + + /** + * @param position to check position + * @param low low index + * @param high high index + * @throws IndexOutOfBoundsException if {@code position} not in range + * {@code low} to {@code high} + */ + public void checkBounds(int position, int low, int high) { + if (position > high || position < low) { + throw new IndexOutOfBoundsException(position + ""); + } + } + + /** + * Clear all nodes in the list + */ + public void clear() { + Node cur = head; + while (cur != null) { + Node prev = cur; + cur = cur.next; + prev = null; // clear to let GC do its work + } + head = null; + size = 0; + } + + /** + * Checks if the list is empty + * + * @return {@code true} if list is empty, otherwise {@code false}. + */ + public boolean isEmpty() { + return size == 0; + } + + /** + * Returns the size of the linked list. + * + * @return the size of the list. + */ + public int size() { + return size; + } + + /** + * Get head of the list. + * + * @return head of the list. + */ + public Node getHead() { + return head; + } + + /** + * Calculate the count of the list manually + * + * @return count of the list + */ + public int count() { + int count = 0; + Node cur = head; + while (cur != null) { + cur = cur.next; + count++; + } + return count; + } + + /** + * Test if the value key is present in the list. + * + * @param key the value to be searched. + * @return {@code true} if key is present in the list, otherwise + * {@code false}. + */ + public boolean search(int key) { + Node cur = head; + while (cur != null) { + if (cur.value == key) { + return true; + } + cur = cur.next; + } + return false; + } + + /** + * Return element at special index. + * + * @param index given index of element + * @return element at special index. + */ + public int getNth(int index) { + checkBounds(index, 0, size - 1); + Node cur = head; + for (int i = 0; i < index; ++i) { + cur = cur.next; + } + return cur.value; + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner("->"); + Node cur = head; + while (cur != null) { + joiner.add(cur.value + ""); + cur = cur.next; + } + return joiner.toString(); + } + + /** + * Driver Code + */ + public static void main(String[] arg) { + SinglyLinkedList list = new SinglyLinkedList(); + assert list.isEmpty(); + assert list.size() == 0 && list.count() == 0; + assert list.toString().equals(""); + + /* Test insert function */ + list.insertHead(5); + list.insertHead(7); + list.insertHead(10); + list.insert(3); + list.insertNth(1, 4); + assert list.toString().equals("10->7->5->3->1"); + + /* Test search function */ + 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; + + /* Test delete function */ + list.deleteHead(); + list.deleteNth(1); + list.delete(); + assert list.toString().equals("7->3"); + + assert list.size == 2 && list.size() == list.count(); + + list.clear(); + assert list.isEmpty(); + + try { + list.delete(); + assert false; + /* this should not happen */ + } catch (Exception e) { + assert true; + /* this should happen */ + } + } +} + +/** + * This class is the nodes of the SinglyLinked List. They consist of a value and + * a pointer to the node after them. + */ +class Node { + + /** + * The value of the node + */ + int value; + + /** + * Point to the next node + */ + Node next; + + Node() { + } + + /** + * Constructor + * + * @param value Value to be put in the node + */ + Node(int value) { + this(value, null); + } + + /** + * Constructor + * + * @param value Value to be put in the node + * @param next Reference to the next node + */ + Node(int value, Node next) { + this.value = value; + this.next = next; + } +} diff --git a/DataStructures/Queues/CircularQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java similarity index 52% rename from DataStructures/Queues/CircularQueue.java rename to src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java index 355cd8724c1d..06a7e5d40337 100644 --- a/DataStructures/Queues/CircularQueue.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java @@ -1,11 +1,11 @@ -package DataStructures.Queues; +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) - public class CircularQueue { + public static void main(String[] args) { - circularQueue cq= new circularQueue(5); + circularQueue cq = new circularQueue(5); System.out.println(cq.isEmpty()); System.out.println(cq.isFull()); cq.enQueue(1); @@ -30,67 +30,70 @@ public static void main(String[] args) { } } -class circularQueue{ + +class circularQueue { + int[] arr; int topOfQueue; int beginningOfQueue; int size; - public circularQueue(int size){ - arr=new int[size]; - topOfQueue=-1; - beginningOfQueue=-1; - this.size=size; + + public circularQueue(int size) { + arr = new int[size]; + topOfQueue = -1; + beginningOfQueue = -1; + this.size = size; } - public boolean isEmpty(){ - if(beginningOfQueue==-1){ + + public boolean isEmpty() { + if (beginningOfQueue == -1) { return true; - }else{ + } else { return false; } } - public boolean isFull(){ - if(topOfQueue+1==beginningOfQueue){ + public boolean isFull() { + if (topOfQueue + 1 == beginningOfQueue) { return true; - }else if(topOfQueue==size-1 && beginningOfQueue==0){ + } else if (topOfQueue == size - 1 && beginningOfQueue == 0) { return true; - }else{ + } else { return false; } } - public void enQueue(int value){ - if(isFull()){ + public void enQueue(int value) { + if (isFull()) { System.out.println("The Queue is full!"); - } - else if(isEmpty()) { - beginningOfQueue=0; + } else if (isEmpty()) { + beginningOfQueue = 0; topOfQueue++; - arr[topOfQueue]=value; - System.out.println(value+" has been successfully inserted!"); - }else{ - if(topOfQueue+1==size){ - topOfQueue=0; - }else{ + arr[topOfQueue] = value; + System.out.println(value + " has been successfully inserted!"); + } else { + if (topOfQueue + 1 == size) { + topOfQueue = 0; + } else { topOfQueue++; } - arr[topOfQueue]=value; - System.out.println(value+" has been successfully inserted!"); + arr[topOfQueue] = value; + System.out.println(value + " has been successfully inserted!"); } } - public int deQueue(){ - if(isEmpty()){ + public int deQueue() { + if (isEmpty()) { System.out.println("The Queue is Empty!"); return -1; - }else{ - int res= arr[beginningOfQueue]; - arr[beginningOfQueue]=Integer.MIN_VALUE; - if(beginningOfQueue==topOfQueue){ - beginningOfQueue=topOfQueue=-1; - }else if(beginningOfQueue+1==size){ - beginningOfQueue=0; - }else{ + } else { + int res = arr[beginningOfQueue]; + arr[beginningOfQueue] = Integer.MIN_VALUE; + if (beginningOfQueue == topOfQueue) { + beginningOfQueue = topOfQueue = -1; + } else if (beginningOfQueue + 1 == size) { + beginningOfQueue = 0; + } else { beginningOfQueue++; } return res; @@ -98,20 +101,18 @@ public int deQueue(){ } - public int peek(){ - if(isEmpty()){ + public int peek() { + if (isEmpty()) { System.out.println("The Queue is Empty!"); return -1; - }else{ + } else { return arr[beginningOfQueue]; } } - public void deleteQueue(){ - arr=null; + public void deleteQueue() { + arr = null; System.out.println("The Queue is deleted!"); } } - - diff --git a/src/main/java/com/thealgorithms/datastructures/queues/Deques.java b/src/main/java/com/thealgorithms/datastructures/queues/Deques.java new file mode 100644 index 000000000000..06d7c5995111 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/queues/Deques.java @@ -0,0 +1,273 @@ +package com.thealgorithms.datastructures.queues; + +/** + * A [deque](https://en.wikipedia.org/wiki/Double-ended_queue) is short for a + * double ended queue pronounced "deck" and sometimes referred to as a head-tail + * linked list. A deque is a data structure based on a doubly linked list, but + * only supports adding and removal of nodes from the beginning and the end of + * the list. + * + * @author [Ian Cowan](https://github.com/iccowan) + */ +public class Deques { + + /** + * Node for the deque + */ + class DequeNode { + + /** + * Value of the node + */ + S val; + + /** + * Next node in the deque from this node + */ + DequeNode next = null; + + /** + * Previous node in the deque from this node + */ + DequeNode prev = null; + + /** + * Constructor + */ + DequeNode(S val) { + this.val = val; + } + } + + /** + * Head of the deque + */ + DequeNode head = null; + + /** + * Tail of the deque + */ + DequeNode tail = null; + + /** + * Size of the deque + */ + int size = 0; + + /** + * Adds the specified value to the head of the deque + * + * @param val Value to add to the deque + */ + public void addFirst(T val) { + // Create a new node with the given value + DequeNode newNode = new DequeNode(val); + + // Add the node + if (head == null) { + // If the deque is empty, add the node as the head and tail + head = newNode; + tail = newNode; + } else { + // If the deque is not empty, insert the node as the new head + newNode.next = head; + head.prev = newNode; + head = newNode; + } + + size++; + } + + /** + * Adds the specified value to the tail of the deque + * + * @param val Value to add to the deque + */ + public void addLast(T val) { + // Create a new node with the given value + DequeNode newNode = new DequeNode(val); + + // Add the node + if (tail == null) { + // If the deque is empty, add the node as the head and tail + head = newNode; + tail = newNode; + } else { + // If the deque is not empty, insert the node as the new tail + newNode.prev = tail; + tail.next = newNode; + tail = newNode; + } + + size++; + } + + /** + * Removes and returns the first (head) value in the deque + * + * @return the value of the head of the deque + */ + public T pollFirst() { + // If the head is null, return null + if (head == null) { + return null; + } + + // First, let's get the value of the old head + T oldHeadVal = head.val; + + // Now, let's remove the head + if (head == tail) { + // If there is only one node, remove it + head = null; + tail = null; + } else { + // If there is more than one node, fix the references + head.next.prev = null; + DequeNode oldHead = head; + head = head.next; + + // Can be considered unnecessary... + // Unlinking the old head to make sure there are no random + // references possibly affecting garbage collection + oldHead.next = null; + } + + size--; + return oldHeadVal; + } + + /** + * Removes and returns the last (tail) value in the deque + * + * @return the value of the tail of the deque + */ + public T pollLast() { + // If the tail is null, return null + if (tail == null) { + return null; + } + + // Let's get the value of the old tail + T oldTailVal = tail.val; + + // Now, remove the tail + if (head == tail) { + // If there is only one node, remove it + head = null; + tail = null; + } else { + // If there is more than one node, fix the references + tail.prev.next = null; + DequeNode oldTail = tail; + tail = tail.prev; + + // Similarly to above, can be considered unnecessary + // See `pollFirst()` for explanation + oldTail.prev = null; + } + + size--; + return oldTailVal; + } + + /** + * Returns the first (head) value of the deque WITHOUT removing + * + * @return the value of the head of the deque + */ + public T peekFirst() { + return head.val; + } + + /** + * Returns the last (tail) value of the deque WITHOUT removing + * + * @return the value of the tail of the deque + */ + public T peekLast() { + return tail.val; + } + + /** + * Returns the size of the deque + * + * @return the size of the deque + */ + public int size() { + return size; + } + + /** + * Returns whether or not the deque is empty + * + * @return whether or not the deque is empty + */ + public boolean isEmpty() { + return head == null; + } + + /** + * Returns a stringified deque in a pretty form: + * + *

+ * Head -> 1 <-> 2 <-> 3 <- Tail + * + * @return the stringified deque + */ + @Override + public String toString() { + String dequeString = "Head -> "; + DequeNode currNode = head; + while (currNode != null) { + dequeString += currNode.val; + + if (currNode.next != null) { + dequeString += " <-> "; + } + + currNode = currNode.next; + } + + dequeString += " <- Tail"; + + return dequeString; + } + + public static void main(String[] args) { + Deques myDeque = new Deques(); + for (int i = 0; i < 42; i++) { + if (i / 42.0 < 0.5) { + myDeque.addFirst(i); + } else { + myDeque.addLast(i); + } + } + + System.out.println(myDeque); + System.out.println("Size: " + myDeque.size()); + System.out.println(); + + myDeque.pollFirst(); + myDeque.pollFirst(); + myDeque.pollLast(); + System.out.println(myDeque); + System.out.println("Size: " + myDeque.size()); + System.out.println(); + + int dequeSize = myDeque.size(); + for (int i = 0; i < dequeSize; i++) { + int removing = -1; + if (i / 39.0 < 0.5) { + removing = myDeque.pollFirst(); + } else { + removing = myDeque.pollLast(); + } + + System.out.println("Removing: " + removing); + } + + System.out.println(myDeque); + System.out.println(myDeque.size()); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java new file mode 100644 index 000000000000..b9331569e131 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java @@ -0,0 +1,87 @@ +package com.thealgorithms.datastructures.queues; + +import java.util.ArrayList; + +/** + * This class implements a GenericArrayListQueue. + * + * A GenericArrayListQueue data structure functions the same as any + * specific-typed queue. The GenericArrayListQueue holds elements of types + * to-be-specified at runtime. The elements that are added first are the first + * to be removed (FIFO). New elements are added to the back/rear of the queue. + */ +public class GenericArrayListQueue { + + /** + * The generic ArrayList for the queue T is the generic element + */ + ArrayList _queue = new ArrayList<>(); + + /** + * Checks if the queue has elements (not empty). + * + * @return True if the queue has elements. False otherwise. + */ + private boolean hasElements() { + return !_queue.isEmpty(); + } + + /** + * Checks what's at the front of the queue. + * + * @return If queue is not empty, element at the front of the queue. + * Otherwise, null + */ + public T peek() { + T result = null; + if (this.hasElements()) { + result = _queue.get(0); + } + return result; + } + + /** + * Inserts an element of type T to the queue. + * + * @param element of type T to be added + * @return True if the element was added successfully + */ + public boolean add(T element) { + return _queue.add(element); + } + + /** + * Retrieve what's at the front of the queue + * + * @return If queue is not empty, element retrieved. Otherwise, null + */ + public T pull() { + T result = null; + if (this.hasElements()) { + result = _queue.remove(0); + } + return result; + } + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + GenericArrayListQueue queue = new GenericArrayListQueue<>(); + System.out.println("Running..."); + assert queue.peek() == null; + assert queue.pull() == null; + assert queue.add(1); + assert queue.peek() == 1; + assert queue.add(2); + assert queue.peek() == 1; + assert queue.pull() == 1; + assert queue.peek() == 2; + assert queue.pull() == 2; + assert queue.peek() == null; + assert queue.pull() == null; + System.out.println("Finished."); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java new file mode 100644 index 000000000000..770582b78e18 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java @@ -0,0 +1,178 @@ +package com.thealgorithms.datastructures.queues; + +import java.util.NoSuchElementException; + +public class LinkedQueue { + + class Node { + + int data; + Node next; + + public Node() { + this(0); + } + + public Node(int data) { + this(data, null); + } + + public Node(int data, Node next) { + this.data = data; + this.next = next; + } + } + + /** + * Front of Queue + */ + private Node front; + + /** + * Rear of Queue + */ + private Node rear; + + /** + * Size of Queue + */ + private int size; + + /** + * Init LinkedQueue + */ + public LinkedQueue() { + front = rear = new Node(); + } + + /** + * Check if queue is empty + * + * @return true if queue is empty, otherwise false + */ + public boolean isEmpty() { + return size == 0; + } + + /** + * Add element to rear of queue + * + * @param data insert value + * @return true if add successfully + */ + public boolean enqueue(int data) { + Node newNode = new Node(data); + rear.next = newNode; + rear = newNode; + /* make rear point at last node */ + size++; + return true; + } + + /** + * Remove element at the front of queue + * + * @return element at the front of queue + */ + public int dequeue() { + if (isEmpty()) { + throw new NoSuchElementException("queue is empty"); + } + Node destroy = front.next; + int retValue = destroy.data; + front.next = front.next.next; + destroy = null; + /* clear let GC do it's work */ + size--; + + if (isEmpty()) { + front = rear; + } + + return retValue; + } + + /** + * Peek element at the front of queue without removing + * + * @return element at the front + */ + public int peekFront() { + if (isEmpty()) { + throw new NoSuchElementException("queue is empty"); + } + return front.next.data; + } + + /** + * Peek element at the rear of queue without removing + * + * @return element at the front + */ + public int peekRear() { + if (isEmpty()) { + throw new NoSuchElementException("queue is empty"); + } + return rear.data; + } + + /** + * Return size of queue + * + * @return size of queue + */ + public int size() { + return size; + } + + /** + * Clear all nodes in queue + */ + public void clear() { + while (!isEmpty()) { + dequeue(); + } + } + + @Override + public String toString() { + if (isEmpty()) { + return "[]"; + } + StringBuilder builder = new StringBuilder(); + Node cur = front.next; + builder.append("["); + while (cur != null) { + builder.append(cur.data).append(", "); + cur = cur.next; + } + builder.replace(builder.length() - 2, builder.length(), "]"); + return builder.toString(); + } + + /* Driver Code */ + public static void main(String[] args) { + LinkedQueue queue = new LinkedQueue(); + assert queue.isEmpty(); + + queue.enqueue(1); + /* 1 */ + queue.enqueue(2); + /* 1 2 */ + queue.enqueue(3); + /* 1 2 3 */ + System.out.println(queue); + /* [1, 2, 3] */ + + assert queue.size() == 3; + assert queue.dequeue() == 1; + assert queue.peekFront() == 2; + assert queue.peekRear() == 3; + + queue.clear(); + assert queue.isEmpty(); + + System.out.println(queue); + /* [] */ + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java b/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java new file mode 100644 index 000000000000..cf651dcee359 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java @@ -0,0 +1,129 @@ +package com.thealgorithms.datastructures.queues; + +/** + * This class implements a PriorityQueue. + * + *

+ * A priority queue adds elements into positions based on their priority. So the + * most important elements are placed at the front/on the top. In this example I + * give numbers that are bigger, a higher priority. Queues in theory have no + * fixed size but when using an array implementation it does. + */ +class PriorityQueue { + + /** + * The max size of the queue + */ + private int maxSize; + /** + * The array for the queue + */ + private int[] queueArray; + /** + * How many items are in the queue + */ + private int nItems; + + /** + * Constructor + * + * @param size Size of the queue + */ + public PriorityQueue(int size) { + maxSize = size; + queueArray = new int[size]; + nItems = 0; + } + + /** + * Inserts an element in it's appropriate place + * + * @param value Value to be inserted + */ + public void insert(int value) { + if (isFull()) { + throw new RuntimeException("Queue is full"); + } else { + int j = nItems - 1; // index of last element + while (j >= 0 && queueArray[j] > value) { + queueArray[j + 1] = queueArray[j]; // Shifts every element up to make room for insertion + j--; + } + queueArray[j + 1] = value; // Once the correct position is found the value is inserted + nItems++; + } + } + + /** + * Remove the element from the front of the queue + * + * @return The element removed + */ + public int remove() { + return queueArray[--nItems]; + } + + /** + * Checks what's at the front of the queue + * + * @return element at the front of the queue + */ + public int peek() { + return queueArray[nItems - 1]; + } + + /** + * Returns true if the queue is empty + * + * @return true if the queue is empty + */ + public boolean isEmpty() { + return (nItems == 0); + } + + /** + * Returns true if the queue is full + * + * @return true if the queue is full + */ + public boolean isFull() { + return (nItems == maxSize); + } + + /** + * Returns the number of elements in the queue + * + * @return number of elements in the queue + */ + public int getSize() { + return nItems; + } +} + +/** + * This class implements the PriorityQueue class above. + * + * @author Unknown + */ +public class PriorityQueues { + + /** + * Main method + * + * @param args Command Line Arguments + */ + public static void main(String[] args) { + PriorityQueue myQueue = new PriorityQueue(4); + myQueue.insert(10); + myQueue.insert(2); + myQueue.insert(5); + myQueue.insert(3); + // [2, 3, 5, 10] Here higher numbers have higher priority, so they are on the top + + for (int i = 3; i >= 0; i--) { + System.out.print( + myQueue.remove() + " "); // will print the queue in reverse order [10, 5, 3, 2] + } + // As you can see, a Priority Queue can be used as a sorting algotithm + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/queues/Queues.java b/src/main/java/com/thealgorithms/datastructures/queues/Queues.java new file mode 100644 index 000000000000..47de89928628 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/queues/Queues.java @@ -0,0 +1,182 @@ +package com.thealgorithms.datastructures.queues; + +/** + * This implements Queues by using the class Queue. + * + * A queue data structure functions the same as a real world queue. The elements + * that are added first are the first to be removed. New elements are added to + * the back/rear of the queue. + */ +class Queue { + + /** + * Default initial capacity. + */ + private static final int DEFAULT_CAPACITY = 10; + + /** + * Max size of the queue + */ + private int maxSize; + /** + * The array representing the queue + */ + private int[] queueArray; + /** + * Front of the queue + */ + private int front; + /** + * Rear of the queue + */ + private int rear; + /** + * How many items are in the queue + */ + private int nItems; + + /** + * init with DEFAULT_CAPACITY + */ + public Queue() { + this(DEFAULT_CAPACITY); + } + + /** + * Constructor + * + * @param size Size of the new queue + */ + public Queue(int size) { + maxSize = size; + queueArray = new int[size]; + front = 0; + rear = -1; + nItems = 0; + } + + /** + * Inserts an element at the rear of the queue + * + * @param x element to be added + * @return True if the element was added successfully + */ + public boolean insert(int x) { + if (isFull()) { + return false; + } + // If the back of the queue is the end of the array wrap around to the front + rear = (rear + 1) % maxSize; + queueArray[rear] = x; + nItems++; + return true; + } + + /** + * Remove an element from the front of the queue + * + * @return the new front of the queue + */ + public int remove() { + if (isEmpty()) { + return -1; + } + int temp = queueArray[front]; + front = (front + 1) % maxSize; + nItems--; + return temp; + } + + /** + * Checks what's at the front of the queue + * + * @return element at the front of the queue + */ + public int peekFront() { + return queueArray[front]; + } + + /** + * Checks what's at the rear of the queue + * + * @return element at the rear of the queue + */ + public int peekRear() { + return queueArray[rear]; + } + + /** + * Returns true if the queue is empty + * + * @return true if the queue is empty + */ + public boolean isEmpty() { + return nItems == 0; + } + + /** + * Returns true if the queue is full + * + * @return true if the queue is full + */ + public boolean isFull() { + return nItems == maxSize; + } + + /** + * Returns the number of elements in the queue + * + * @return number of elements in the queue + */ + public int getSize() { + return nItems; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int i = front;; i = ++i % maxSize) { + sb.append(queueArray[i]).append(", "); + if (i == rear) { + break; + } + } + sb.replace(sb.length() - 2, sb.length(), "]"); + return sb.toString(); + } +} + +/** + * This class is the example for the Queue class + * + * @author Unknown + */ +public class Queues { + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + Queue myQueue = new Queue(4); + myQueue.insert(10); + myQueue.insert(2); + myQueue.insert(5); + myQueue.insert(3); + // [10(front), 2, 5, 3(rear)] + + System.out.println(myQueue.isFull()); // Will print true + + myQueue.remove(); // Will make 2 the new front, making 10 no longer part of the queue + // [10, 2(front), 5, 3(rear)] + + myQueue.insert(7); // Insert 7 at the rear which will get 0 index because of wrap around + // [7(rear), 2(front), 5, 3] + + System.out.println(myQueue.peekFront()); // Will print 2 + System.out.println(myQueue.peekRear()); // Will print 7 + System.out.println(myQueue.toString()); // Will print [2, 5, 3, 7] + } +} diff --git a/DataStructures/Queues/README.md b/src/main/java/com/thealgorithms/datastructures/queues/README.md similarity index 100% rename from DataStructures/Queues/README.md rename to src/main/java/com/thealgorithms/datastructures/queues/README.md diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java b/src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java new file mode 100644 index 000000000000..d0342d53955e --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/BalancedBrackets.java @@ -0,0 +1,82 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.Stack; + +/** + * The nested brackets problem is a problem that determines if a sequence of + * brackets are properly nested. A sequence of brackets s is considered properly + * nested if any of the following conditions are true: - s is empty - s has the + * form (U) or [U] or {U} where U is a properly nested string - s has the form + * VW where V and W are properly nested strings For example, the string + * "()()[()]" is properly nested but "[(()]" is not. The function called + * is_balanced takes as input a string S which is a sequence of brackets and + * returns true if S is nested and false otherwise. + * + * @author akshay sharma + * @author khalil2535 + * @author shellhub + */ +class BalancedBrackets { + + /** + * Check if {@code leftBracket} and {@code rightBracket} is paired or not + * + * @param leftBracket left bracket + * @param rightBracket right bracket + * @return {@code true} if {@code leftBracket} and {@code rightBracket} is + * paired, otherwise {@code false} + */ + public static boolean isPaired(char leftBracket, char rightBracket) { + char[][] pairedBrackets = { + {'(', ')'}, + {'[', ']'}, + {'{', '}'}, + {'<', '>'} + }; + for (char[] pairedBracket : pairedBrackets) { + if (pairedBracket[0] == leftBracket && pairedBracket[1] == rightBracket) { + return true; + } + } + return false; + } + + /** + * Check if {@code brackets} is balanced + * + * @param brackets the brackets + * @return {@code true} if {@code brackets} is balanced, otherwise + * {@code false} + */ + public static boolean isBalanced(String brackets) { + if (brackets == null) { + throw new IllegalArgumentException("brackets is null"); + } + Stack 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 */ + return false; + } + } + return bracketsStack.isEmpty(); + } + + public static void main(String[] args) { + assert isBalanced("[()]{}{[()()]()}"); + assert !isBalanced("[(])"); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java new file mode 100644 index 000000000000..1a71bf6928e3 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/DecimalToAnyUsingStack.java @@ -0,0 +1,44 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.Stack; + +public class DecimalToAnyUsingStack { + + public static void main(String[] args) { + assert convert(0, 2).equals("0"); + assert convert(30, 2).equals("11110"); + assert convert(30, 8).equals("36"); + assert convert(30, 10).equals("30"); + assert convert(30, 16).equals("1E"); + } + + /** + * Convert decimal number to another radix + * + * @param number the number to be converted + * @param radix the radix + * @return another radix + * @throws ArithmeticException if number or radius is + * invalid + */ + 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)); + } + char[] tables = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + Stack bits = new Stack<>(); + do { + bits.push(tables[number % radix]); + number = number / radix; + } while (number != 0); + + StringBuilder result = new StringBuilder(); + while (!bits.isEmpty()) { + result.append(bits.pop()); + } + return result.toString(); + } +} diff --git a/DataStructures/Stacks/DuplicateBrackets.java b/src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java similarity index 75% rename from DataStructures/Stacks/DuplicateBrackets.java rename to src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java index dc25d4ea5cbb..1195dea36622 100644 --- a/DataStructures/Stacks/DuplicateBrackets.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/DuplicateBrackets.java @@ -1,34 +1,32 @@ +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. // 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.' // ((a + b) + (c + d)) -> false // (a + b) + ((c + d)) -> true - - -import java.io.*; import java.util.*; public class DuplicateBrackets { - public static boolean check(String str){ + public static boolean check(String str) { Stack st = new Stack<>(); - - for(int i=0;i0 && st.peek()!='('){ + } else { + while (st.size() > 0 && st.peek() != '(') { st.pop(); } st.pop(); } - - }else{ + + } else { st.push(ch); } // System.out.println(st); diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java b/src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java new file mode 100644 index 000000000000..cb19249a5e5b --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/InfixToPostfix.java @@ -0,0 +1,56 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.Stack; + +public class InfixToPostfix { + + public static void main(String[] args) throws Exception { + assert "32+".equals(infix2PostFix("3+2")); + assert "123++".equals(infix2PostFix("1+(2+3)")); + assert "34+5*6-".equals(infix2PostFix("(3+4)*5-6")); + } + + public static String infix2PostFix(String infixExpression) throws Exception { + if (!BalancedBrackets.isBalanced(infixExpression)) { + throw new Exception("invalid expression"); + } + StringBuilder output = new StringBuilder(); + Stack stack = new Stack<>(); + for (char element : infixExpression.toCharArray()) { + if (Character.isLetterOrDigit(element)) { + output.append(element); + } else if (element == '(') { + stack.push(element); + } else if (element == ')') { + while (!stack.isEmpty() && stack.peek() != '(') { + output.append(stack.pop()); + } + stack.pop(); + } else { + while (!stack.isEmpty() && precedence(element) <= precedence(stack.peek())) { + output.append(stack.pop()); + } + stack.push(element); + } + } + while (!stack.isEmpty()) { + output.append(stack.pop()); + } + return output.toString(); + } + + private static int precedence(char operator) { + switch (operator) { + case '+': + case '-': + return 0; + case '*': + case '/': + return 1; + case '^': + return 2; + default: + return -1; + } + } +} diff --git a/DataStructures/Stacks/MaximumMinimumWindow.java b/src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java similarity index 61% rename from DataStructures/Stacks/MaximumMinimumWindow.java rename to src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java index e321e65d7965..74090db6bf25 100644 --- a/DataStructures/Stacks/MaximumMinimumWindow.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/MaximumMinimumWindow.java @@ -1,11 +1,12 @@ -package DataStructures.Stacks; +package com.thealgorithms.datastructures.stacks; import java.util.Arrays; import java.util.Stack; /** - * Given an integer array. The task is to find the maximum of the minimum of every window size in the array. - * Note: Window size varies from 1 to the size of the Array. + * Given an integer array. The task is to find the maximum of the minimum of + * every window size in the array. Note: Window size varies from 1 to the size + * of the Array. *

* For example, *

@@ -15,20 +16,22 @@ * So the answer for the above would be : 70 30 20 10 10 10 10 *

* We need to consider window sizes from 1 to length of array in each iteration. - * So in the iteration 1 the windows would be [10], [20], [30], [50], [10], [70], [30]. - * Now we need to check the minimum value in each window. Since the window size is 1 here the minimum element would be the number itself. - * Now the maximum out of these is the result in iteration 1. - * In the second iteration we need to consider window size 2, so there would be [10,20], [20,30], [30,50], [50,10], [10,70], [70,30]. - * Now the minimum of each window size would be [10,20,30,10,10] and the maximum out of these is 30. - * Similarly we solve for other window sizes. + * So in the iteration 1 the windows would be [10], [20], [30], [50], [10], + * [70], [30]. Now we need to check the minimum value in each window. Since the + * window size is 1 here the minimum element would be the number itself. Now the + * maximum out of these is the result in iteration 1. In the second iteration we + * need to consider window size 2, so there would be [10,20], [20,30], [30,50], + * [50,10], [10,70], [70,30]. Now the minimum of each window size would be + * [10,20,30,10,10] and the maximum out of these is 30. Similarly we solve for + * other window sizes. * * @author sahil */ public class MaximumMinimumWindow { /** - * This function contains the logic of finding maximum of minimum for every window size - * using Stack Data Structure. + * This function contains the logic of finding maximum of minimum for every + * window size using Stack Data Structure. * * @param arr Array containing the numbers * @param n Length of the array @@ -44,31 +47,37 @@ public static int[] calculateMaxOfMin(int[] arr, int n) { } for (int i = 0; i < n; i++) { - while (!s.empty() && arr[s.peek()] >= arr[i]) + while (!s.empty() && arr[s.peek()] >= arr[i]) { s.pop(); + } - if (!s.empty()) + if (!s.empty()) { left[i] = s.peek(); + } s.push(i); } - while (!s.empty()) + while (!s.empty()) { s.pop(); + } for (int i = n - 1; i >= 0; i--) { - while (!s.empty() && arr[s.peek()] >= arr[i]) + while (!s.empty() && arr[s.peek()] >= arr[i]) { s.pop(); + } - if (!s.empty()) + if (!s.empty()) { right[i] = s.peek(); + } s.push(i); } int ans[] = new int[n + 1]; - for (int i = 0; i <= n; i++) + for (int i = 0; i <= n; i++) { ans[i] = 0; + } for (int i = 0; i < n; i++) { int len = right[i] - left[i] - 1; @@ -76,12 +85,14 @@ public static int[] calculateMaxOfMin(int[] arr, int n) { ans[len] = Math.max(ans[len], arr[i]); } - for (int i = n - 1; i >= 1; i--) + for (int i = n - 1; i >= 1; i--) { ans[i] = Math.max(ans[i], ans[i + 1]); + } // Print the result - for (int i = 1; i <= n; i++) + for (int i = 1; i <= n; i++) { System.out.print(ans[i] + " "); + } return ans; } diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java new file mode 100644 index 000000000000..a492a300ab29 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java @@ -0,0 +1,180 @@ +package com.thealgorithms.datastructures.stacks; + +/** + * Implementation of a stack using nodes. Unlimited size, no arraylist. + * + * @author Kyler Smith, 2017 + */ +public class NodeStack { + + /** + * Entry point for the program. + */ + public static void main(String[] args) { + NodeStack Stack = new NodeStack(); + + Stack.push(3); + Stack.push(4); + Stack.push(5); + System.out.println("Testing :"); + Stack.print(); // prints : 5 4 3 + + Integer x = Stack.pop(); // x = 5 + Stack.push(1); + Stack.push(8); + Integer y = Stack.peek(); // y = 8 + System.out.println("Testing :"); + Stack.print(); // prints : 8 1 4 3 + + System.out.println("Testing :"); + System.out.println("x : " + x); + System.out.println("y : " + y); + } + + /** + * Information each node should contain. + * + * @value data : information of the value in the node + * @value head : the head of the stack + * @value next : the next value from this node + * @value previous : the last value from this node + * @value size : size of the stack + */ + private Item data; + + private static NodeStack head; + private NodeStack next; + private NodeStack previous; + private static int size = 0; + + /** + * Constructors for the NodeStack. + */ + public NodeStack() { + } + + private NodeStack(Item item) { + this.data = item; + } + + /** + * Put a value onto the stack. + * + * @param item : value to be put on the stack. + */ + public void push(Item item) { + + NodeStack newNs = new NodeStack(item); + + if (this.isEmpty()) { + NodeStack.setHead(new NodeStack<>(item)); + newNs.setNext(null); + newNs.setPrevious(null); + } else { + newNs.setPrevious(NodeStack.head); + NodeStack.head.setNext(newNs); + NodeStack.head.setHead(newNs); + } + + NodeStack.setSize(NodeStack.getSize() + 1); + } + + /** + * Value to be taken off the stack. + * + * @return item : value that is returned. + */ + public Item pop() { + + Item item = (Item) NodeStack.head.getData(); + + NodeStack.head.setHead(NodeStack.head.getPrevious()); + NodeStack.head.setNext(null); + + NodeStack.setSize(NodeStack.getSize() - 1); + + return item; + } + + /** + * Value that is next to be taken off the stack. + * + * @return item : the next value that would be popped off the stack. + */ + public Item peek() { + return (Item) NodeStack.head.getData(); + } + + /** + * If the stack is empty or there is a value in. + * + * @return boolean : whether or not the stack has anything in it. + */ + public boolean isEmpty() { + return NodeStack.getSize() == 0; + } + + /** + * Returns the size of the stack. + * + * @return int : number of values in the stack. + */ + public int size() { + return NodeStack.getSize(); + } + + /** + * Print the contents of the stack in the following format. + * + *

+ * x <- head (next out) y z <- tail (first in) . . . + */ + public void print() { + for (NodeStack n = NodeStack.head; n != null; n = n.previous) { + System.out.println(n.getData().toString()); + } + } + + /** + * Getters and setters (private) + */ + private NodeStack getHead() { + return NodeStack.head; + } + + private static void setHead(NodeStack ns) { + NodeStack.head = ns; + } + + private NodeStack getNext() { + return next; + } + + private void setNext(NodeStack next) { + this.next = next; + } + + private NodeStack getPrevious() { + return previous; + } + + private void setPrevious(NodeStack previous) { + this.previous = previous; + } + + private static int getSize() { + return size; + } + + private static void setSize(int size) { + NodeStack.size = size; + } + + private Item getData() { + return this.data; + } + + private void setData(Item item) { + this.data = item; + } +} diff --git a/DataStructures/Stacks/README.md b/src/main/java/com/thealgorithms/datastructures/stacks/README.md similarity index 100% rename from DataStructures/Stacks/README.md rename to src/main/java/com/thealgorithms/datastructures/stacks/README.md diff --git a/DataStructures/Stacks/ReverseStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java similarity index 79% rename from DataStructures/Stacks/ReverseStack.java rename to src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java index 8db3fb7c3ac1..9d253fb37d2b 100644 --- a/DataStructures/Stacks/ReverseStack.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java @@ -1,17 +1,16 @@ -package DataStructures.Stacks; +package com.thealgorithms.datastructures.stacks; import java.util.Scanner; import java.util.Stack; /** - * Reversal of a stack using recursion. + * Reversal of a stack using recursion. * * @author Ishika Agarwal, 2021 */ - public class ReverseStack { - public static void main(String args[]){ + 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"); @@ -19,20 +18,21 @@ public static void main(String args[]){ int i; Stack stack = new Stack(); System.out.println("Enter the stack elements"); - for(i = 0; i < n ; i++) + for (i = 0; i < n; i++) { stack.push(sc.nextInt()); + } sc.close(); reverseStack(stack); System.out.println("The reversed stack is:"); - while(!stack.isEmpty()){ - System.out.print(stack.peek()+","); + while (!stack.isEmpty()) { + System.out.print(stack.peek() + ","); stack.pop(); } } private static void reverseStack(Stack stack) { - if(stack.isEmpty()){ + if (stack.isEmpty()) { return; } @@ -45,13 +45,13 @@ private static void reverseStack(Stack stack) { reverseStack(stack); //Insert the topmost element to the bottom of the stack - insertAtBottom(stack,element); + insertAtBottom(stack, element); } private static void insertAtBottom(Stack stack, int element) { - - if(stack.isEmpty()){ + + if (stack.isEmpty()) { //When stack is empty, insert the element so it will be present at the bottom of the stack stack.push(element); return; @@ -60,11 +60,11 @@ private static void insertAtBottom(Stack stack, int element) { 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. - */ + */ stack.pop(); insertAtBottom(stack, element); stack.push(ele); } - + } diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java b/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java new file mode 100644 index 000000000000..cb2cb25e9e0c --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java @@ -0,0 +1,173 @@ +package com.thealgorithms.datastructures.stacks; + +/** + * This class implements a Stack using a regular array. + * + *

+ * A stack is exactly what it sounds like. An element gets added to the top of + * the stack and only the element on the top may be removed. This is an example + * of an array implementation of a Stack. So an element can only be + * added/removed from the end of the array. In theory stack have no fixed size, + * but with an array implementation it does. + */ +public class StackArray { + + /** + * Driver Code + */ + public static void main(String[] args) { + // Declare a stack of maximum size 4 + StackArray myStackArray = new StackArray(4); + + assert myStackArray.isEmpty(); + assert !myStackArray.isFull(); + + // Populate the stack + myStackArray.push(5); + myStackArray.push(8); + myStackArray.push(2); + myStackArray.push(9); + + assert !myStackArray.isEmpty(); + assert myStackArray.isFull(); + assert myStackArray.peek() == 9; + assert myStackArray.pop() == 9; + assert myStackArray.peek() == 2; + assert myStackArray.size() == 3; + } + + /** + * Default initial capacity. + */ + private static final int DEFAULT_CAPACITY = 10; + + /** + * The max size of the Stack + */ + private int maxSize; + + /** + * The array representation of the Stack + */ + private int[] stackArray; + + /** + * The top of the stack + */ + private int top; + + /** + * init Stack with DEFAULT_CAPACITY + */ + public StackArray() { + this(DEFAULT_CAPACITY); + } + + /** + * Constructor + * + * @param size Size of the Stack + */ + public StackArray(int size) { + maxSize = size; + stackArray = new int[maxSize]; + top = -1; + } + + /** + * Adds an element to the top of the stack + * + * @param value The element added + */ + public void push(int value) { + if (!isFull()) { // Checks for a full stack + top++; + stackArray[top] = value; + } else { + resize(maxSize * 2); + push(value); // don't forget push after resizing + } + } + + /** + * Removes the top element of the stack and returns the value you've removed + * + * @return value popped off the Stack + */ + public int pop() { + if (!isEmpty()) { // Checks for an empty stack + return stackArray[top--]; + } + + if (top < maxSize / 4) { + resize(maxSize / 2); + return pop(); // don't forget pop after resizing + } else { + System.out.println("The stack is already empty"); + return -1; + } + } + + /** + * Returns the element at the top of the stack + * + * @return element at the top of the stack + */ + public int peek() { + if (!isEmpty()) { // Checks for an empty stack + return stackArray[top]; + } else { + System.out.println("The stack is empty, cant peek"); + return -1; + } + } + + private void resize(int newSize) { + int[] transferArray = new int[newSize]; + + for (int i = 0; i < stackArray.length; i++) { + transferArray[i] = stackArray[i]; + } + // This reference change might be nice in here + stackArray = transferArray; + maxSize = newSize; + } + + /** + * Returns true if the stack is empty + * + * @return true if the stack is empty + */ + public boolean isEmpty() { + return (top == -1); + } + + /** + * Returns true if the stack is full + * + * @return true if the stack is full + */ + public boolean isFull() { + return (top + 1 == maxSize); + } + + /** + * Deletes everything in the Stack + * + *

+ * Doesn't delete elements in the array but if you call push method after + * calling makeEmpty it will overwrite previous values + */ + public void makeEmpty() { // Doesn't delete elements in the array but if you call + top = -1; // push method after calling makeEmpty it will overwrite previous values + } + + /** + * Return size of stack + * + * @return size of stack + */ + public int size() { + return top + 1; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java b/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java new file mode 100644 index 000000000000..9506ae385733 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java @@ -0,0 +1,116 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.ArrayList; +import java.util.EmptyStackException; + +/** + * This class implements a Stack using an ArrayList. + * + *

+ * A stack is exactly what it sounds like. An element gets added to the top of + * the stack and only the element on the top may be removed. + * + *

+ * This is an ArrayList Implementation of a stack, where size is not a problem + * we can extend the stack as much as we want. + */ +public class StackArrayList { + + /** + * Driver Code + */ + public static void main(String[] args) { + StackArrayList stack = new StackArrayList(); + assert stack.isEmpty(); + + for (int i = 1; i <= 5; ++i) { + stack.push(i); + assert stack.size() == i; + } + + assert stack.size() == 5; + assert stack.peek() == 5 && stack.pop() == 5 && stack.peek() == 4; + + /* pop elements at the top of this stack one by one */ + while (!stack.isEmpty()) { + stack.pop(); + } + assert stack.isEmpty(); + + try { + stack.pop(); + assert false; + /* this should not happen */ + } catch (EmptyStackException e) { + assert true; + /* this should happen */ + } + } + + /** + * ArrayList representation of the stack + */ + private ArrayList stack; + + /** + * Constructor + */ + public StackArrayList() { + stack = new ArrayList<>(); + } + + /** + * Adds value to the end of list which is the top for stack + * + * @param value value to be added + */ + public void push(int value) { + stack.add(value); + } + + /** + * Removes the element at the top of this stack and returns + * + * @return Element popped + * @throws EmptyStackException if the stack is empty. + */ + public int pop() { + if (isEmpty()) { + throw new EmptyStackException(); + } + + /* remove the element on the top of the stack */ + return stack.remove(stack.size() - 1); + } + + /** + * Test if the stack is empty. + * + * @return {@code true} if this stack is empty, {@code false} otherwise. + */ + public boolean isEmpty() { + return stack.isEmpty(); + } + + /** + * Return the element at the top of this stack without removing it from the + * stack. + * + * @return the element at the top of this stack. + */ + public int peek() { + if (isEmpty()) { + throw new EmptyStackException(); + } + return stack.get(stack.size() - 1); + } + + /** + * Return size of this stack. + * + * @return size of this stack. + */ + public int size() { + return stack.size(); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java b/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java new file mode 100644 index 000000000000..d350bb2d5565 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java @@ -0,0 +1,142 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.NoSuchElementException; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +// An implementation of a Stack using a Linked List +class StackOfLinkedList { + + public static void main(String[] args) { + + LinkedListStack stack = new LinkedListStack(); + stack.push(1); + stack.push(2); + stack.push(3); + stack.push(4); + stack.push(5); + + System.out.println(stack); + + System.out.println("Size of stack currently is: " + stack.getSize()); + + assert stack.pop() == 5; + assert stack.pop() == 4; + + System.out.println("Top element of stack currently is: " + stack.peek()); + } +} + +// A node class +class Node { + + public int data; + public Node next; + + public Node(int data) { + this.data = data; + this.next = null; + } +} + +/** + * A class which implements a stack using a linked list + * + *

+ * Contains all the stack methods : push, pop, printStack, isEmpty + */ +class LinkedListStack { + + /** + * Top of stack + */ + Node head; + + /** + * Size of stack + */ + private int size; + + /** + * Init properties + */ + public LinkedListStack() { + head = null; + size = 0; + } + + /** + * Add element at top + * + * @param x to be added + * @return true if add successfully + */ + public boolean push(int x) { + Node newNode = new Node(x); + newNode.next = head; + head = newNode; + size++; + return true; + } + + /** + * Pop element at top of stack + * + * @return element at top of stack + * @throws NoSuchElementException if stack is empty + */ + public int pop() { + if (size == 0) { + throw new NoSuchElementException("Empty stack. Nothing to pop"); + } + Node destroy = head; + head = head.next; + int retValue = destroy.data; + destroy = null; // clear to let GC do it's work + size--; + return retValue; + } + + /** + * Peek element at top of stack + * + * @return element at top of stack + * @throws NoSuchElementException if stack is empty + */ + public int peek() { + if (size == 0) { + throw new NoSuchElementException("Empty stack. Nothing to pop"); + } + return head.data; + } + + @Override + public String toString() { + Node cur = head; + StringBuilder builder = new StringBuilder(); + while (cur != null) { + builder.append(cur.data).append("->"); + cur = cur.next; + } + return builder.replace(builder.length() - 2, builder.length(), "").toString(); + } + + /** + * Check if stack is empty + * + * @return true if stack is empty, otherwise false + */ + public boolean isEmpty() { + return size == 0; + } + + /** + * Return size of stack + * + * @return size of stack + */ + public int getSize() { + return size; + } +} diff --git a/DataStructures/Trees/AVLSimple b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple similarity index 98% rename from DataStructures/Trees/AVLSimple rename to src/main/java/com/thealgorithms/datastructures/trees/AVLSimple index ea286660bc63..8eb7191cc017 100644 --- a/DataStructures/Trees/AVLSimple +++ b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple @@ -1,5 +1,5 @@ -package DataStructures.Trees; +package com.thealgorithms.datastructures.trees; /* * Avl is algo that balance itself while adding new alues to tree diff --git a/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java b/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java new file mode 100644 index 000000000000..9551c2bd9732 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java @@ -0,0 +1,255 @@ +package com.thealgorithms.datastructures.trees; + +public class AVLTree { + + private Node root; + + private class Node { + + private int key; + private int balance; + private int height; + private Node left, right, parent; + + Node(int k, Node p) { + key = k; + parent = p; + } + } + + public boolean insert(int key) { + if (root == null) { + root = new Node(key, null); + } else { + Node n = root; + Node parent; + while (true) { + if (n.key == key) { + return false; + } + + parent = n; + + boolean goLeft = n.key > key; + n = goLeft ? n.left : n.right; + + if (n == null) { + if (goLeft) { + parent.left = new Node(key, parent); + } else { + parent.right = new Node(key, parent); + } + rebalance(parent); + break; + } + } + } + return true; + } + + private void delete(Node node) { + if (node.left == null && node.right == null) { + if (node.parent == null) { + root = null; + } else { + Node parent = node.parent; + if (parent.left == node) { + parent.left = null; + } else { + parent.right = null; + } + rebalance(parent); + } + return; + } + if (node.left != null) { + Node child = node.left; + while (child.right != null) { + child = child.right; + } + node.key = child.key; + delete(child); + } else { + Node child = node.right; + while (child.left != null) { + child = child.left; + } + node.key = child.key; + delete(child); + } + } + + public void delete(int delKey) { + if (root == null) { + return; + } + Node node = root; + Node child = root; + + while (child != null) { + node = child; + child = delKey >= node.key ? node.right : node.left; + if (delKey == node.key) { + delete(node); + return; + } + } + } + + private void rebalance(Node n) { + setBalance(n); + + if (n.balance == -2) { + if (height(n.left.left) >= height(n.left.right)) { + n = rotateRight(n); + } else { + n = rotateLeftThenRight(n); + } + + } else if (n.balance == 2) { + if (height(n.right.right) >= height(n.right.left)) { + n = rotateLeft(n); + } else { + n = rotateRightThenLeft(n); + } + } + + if (n.parent != null) { + rebalance(n.parent); + } else { + root = n; + } + } + + private Node rotateLeft(Node a) { + + Node b = a.right; + b.parent = a.parent; + + a.right = b.left; + + if (a.right != null) { + a.right.parent = a; + } + + b.left = a; + a.parent = b; + + if (b.parent != null) { + if (b.parent.right == a) { + b.parent.right = b; + } else { + b.parent.left = b; + } + } + + setBalance(a, b); + + return b; + } + + private Node rotateRight(Node a) { + + Node b = a.left; + b.parent = a.parent; + + a.left = b.right; + + if (a.left != null) { + a.left.parent = a; + } + + b.right = a; + a.parent = b; + + if (b.parent != null) { + if (b.parent.right == a) { + b.parent.right = b; + } else { + b.parent.left = b; + } + } + + setBalance(a, b); + + return b; + } + + private Node rotateLeftThenRight(Node n) { + n.left = rotateLeft(n.left); + return rotateRight(n); + } + + private Node rotateRightThenLeft(Node n) { + n.right = rotateRight(n.right); + return rotateLeft(n); + } + + private int height(Node n) { + if (n == null) { + return -1; + } + return n.height; + } + + private void setBalance(Node... nodes) { + for (Node n : nodes) { + reheight(n); + n.balance = height(n.right) - height(n.left); + } + } + + public void printBalance() { + printBalance(root); + } + + private void printBalance(Node n) { + if (n != null) { + printBalance(n.left); + System.out.printf("%s ", n.balance); + printBalance(n.right); + } + } + + private void reheight(Node node) { + if (node != null) { + node.height = 1 + Math.max(height(node.left), height(node.right)); + } + } + + public boolean search(int key) { + Node result = searchHelper(this.root, key); + if (result != null) { + return true; + } + + return false; + } + + private Node searchHelper(Node root, int key) { + // root is null or key is present at root + if (root == null || root.key == key) { + return root; + } + + // key is greater than root's key + if (root.key > key) { + return searchHelper(root.left, key); // call the function on the node's left child + } + // key is less than root's key then + // call the function on the node's right child as it is greater + return searchHelper(root.right, key); + } + + public static void main(String[] args) { + AVLTree tree = new AVLTree(); + + System.out.println("Inserting values 1 to 10"); + for (int i = 1; i < 10; i++) { + tree.insert(i); + } + + System.out.print("Printing balance: "); + tree.printBalance(); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java b/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java new file mode 100644 index 000000000000..72d0f0de4f50 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java @@ -0,0 +1,309 @@ +package com.thealgorithms.datastructures.trees; + +/** + * + * + *

Binary Search Tree (Iterative)

+ * + *

+ * An implementation of BST iteratively. Binary Search Tree is a binary tree + * which satisfies three properties: left child is less than root node, right + * child is grater than root node, both left and right childs must themselves be + * a BST. + * + * @author [Lakhan Nad](https://github.com/Lakhan-Nad) + */ +import java.util.Stack; + +public class BSTIterative { + + /** + * Reference for the node of BST. + */ + private Node root; + + /** + * Default Constructor Initializes the root of BST with null. + */ + BSTIterative() { + root = null; + } + + /** + * main function for tests + */ + public static void main(String[] args) { + BSTIterative tree = new BSTIterative(); + tree.add(3); + tree.add(2); + tree.add(9); + assert !tree.find(4) : "4 is not yet present in BST"; + assert tree.find(2) : "2 should be present in BST"; + tree.remove(2); + assert !tree.find(2) : "2 was just deleted from BST"; + tree.remove(1); + assert !tree.find(1) : "Since 1 was not present so find deleting would do no change"; + tree.add(30); + tree.add(40); + assert tree.find(40) : "40 was inserted but not found"; + /* + Will print following order + 3 9 30 40 + */ + tree.inorder(); + } + + /** + * A method to insert a new value in BST. If the given value is already + * present in BST the insertion is ignored. + * + * @param data the value to be inserted + */ + public void add(int data) { + Node parent = null; + Node temp = this.root; + int rightOrLeft = -1; + /* Finds the proper place this node can + * be placed in according to rules of BST. + */ + while (temp != null) { + if (temp.data > data) { + parent = temp; + temp = parent.left; + rightOrLeft = 0; + } else if (temp.data < data) { + parent = temp; + temp = parent.right; + rightOrLeft = 1; + } else { + System.out.println(data + " is already present in BST."); + return; // if data already present we ignore insertion + } + } + /* Creates a newNode with the value passed + * Since this data doesn't already exists + */ + Node newNode = new Node(data); + /* If the parent node is null + * then the insertion is to be done in + * root itself. + */ + if (parent == null) { + this.root = newNode; + } else { + /* Check if insertion is to be made in + * left or right subtree. + */ + if (rightOrLeft == 0) { + parent.left = newNode; + } else { + parent.right = newNode; + } + } + } + + /** + * A method to delete the node in BST. If node is present it will be deleted + * + * @param data the value that needs to be deleted + */ + public void remove(int data) { + Node parent = null; + Node temp = this.root; + int rightOrLeft = -1; + /* Find the parent of the node and node itself + * That is to be deleted. + * parent variable store parent + * temp stores node itself. + * rightOrLeft use to keep track weather child + * is left or right subtree + */ + while (temp != null) { + if (temp.data == data) { + break; + } else if (temp.data > data) { + parent = temp; + temp = parent.left; + rightOrLeft = 0; + } else { + parent = temp; + temp = parent.right; + rightOrLeft = 1; + } + } + /* If temp is null than node with given value is not + * present in our tree. + */ + if (temp != null) { + Node replacement; // used to store the new values for replacing nodes + if (temp.right == null && temp.left == null) { // Leaf node Case + replacement = null; + } else if (temp.right == null) { // Node with only right child + replacement = temp.left; + temp.left = null; + } else if (temp.left == null) { // Node with only left child + replacement = temp.right; + temp.right = null; + } else { + /* If both left and right child are present + * we replace this nodes data with + * leftmost node's data in its right subtree + * to maintain the balance of BST. + * And then delete that node + */ + if (temp.right.left == null) { + temp.data = temp.right.data; + replacement = temp; + temp.right = temp.right.right; + } else { + Node parent2 = temp.right; + Node child = temp.right.left; + while (child.left != null) { + parent2 = child; + child = parent2.left; + } + temp.data = child.data; + parent2.left = child.right; + replacement = temp; + } + } + /* Change references of parent after + * deleting the child. + */ + if (parent == null) { + this.root = replacement; + } else { + if (rightOrLeft == 0) { + parent.left = replacement; + } else { + parent.right = replacement; + } + } + } + } + + /** + * A method for inorder traversal of BST. + */ + public void inorder() { + if (this.root == null) { + System.out.println("This BST is empty."); + return; + } + System.out.println("Inorder traversal of this tree is:"); + Stack st = new Stack(); + Node cur = this.root; + while (cur != null || !st.empty()) { + while (cur != null) { + st.push(cur); + cur = cur.left; + } + cur = st.pop(); + System.out.print(cur.data + " "); + cur = cur.right; + } + System.out.println(); // for next line + } + + /** + * A method used to print postorder traversal of BST. + */ + public void postorder() { + if (this.root == null) { + System.out.println("This BST is empty."); + return; + } + System.out.println("Postorder traversal of this tree is:"); + Stack st = new Stack(); + Node cur = this.root, temp2; + while (cur != null || !st.empty()) { + if (cur != null) { + st.push(cur); + cur = cur.left; + } else { + temp2 = st.peek(); + if (temp2.right != null) { + cur = temp2.right; + } else { + st.pop(); + while (!st.empty() && st.peek().right == temp2) { + System.out.print(temp2.data + " "); + temp2 = st.pop(); + } + System.out.print(temp2.data + " "); + } + } + } + System.out.println(); // for next line + } + + /** + * Method used to display preorder traversal of BST. + */ + public void preorder() { + if (this.root == null) { + System.out.println("This BST is empty."); + return; + } + System.out.println("Preorder traversal of this tree is:"); + Stack st = new Stack(); + st.push(this.root); + Node temp; + while (!st.empty()) { + temp = st.pop(); + System.out.print(temp.data + " "); + if (temp.right != null) { + st.push(temp.right); + } + if (temp.left != null) { + st.push(temp.left); + } + } + System.out.println(); // for next line + } + + /** + * A method to check if given data exists in out Binary Search Tree. + * + * @param data the value that needs to be searched for + * @return boolean representing if the value was find + */ + public boolean find(int data) { + Node temp = this.root; + /* Check if node exists + */ + while (temp != null) { + if (temp.data > data) { + temp = temp.left; + } else if (temp.data < data) { + temp = temp.right; + } else { + /* If found return true + */ + System.out.println(data + " is present in the BST."); + return true; + } + } + System.out.println(data + " not found."); + return false; + } + + /** + * The Node class used for building binary search tree + */ + private static class Node { + + int data; + Node left; + Node right; + + /** + * Constructor with data as parameter + */ + Node(int d) { + data = d; + left = null; + right = null; + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java b/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java new file mode 100644 index 000000000000..4d3640fc85e7 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java @@ -0,0 +1,266 @@ +package com.thealgorithms.datastructures.trees; + +/** + * + * + *

Binary Search Tree (Recursive)

+ * + * An implementation of BST recursively. In recursive implementation the checks + * are down the tree First root is checked if not found then its childs are + * checked Binary Search Tree is a binary tree which satisfies three properties: + * left child is less than root node, right child is grater than root node, both + * left and right childs must themselves be a BST. + * + *

+ * I have made public functions as methods and to actually implement recursive + * approach I have used private methods + * + * @author [Lakhan Nad](https://github.com/Lakhan-Nad) + */ +public class BSTRecursive { + + /** + * only data member is root of BST + */ + private Node root; + + /** + * Constructor use to initialize node as null + */ + BSTRecursive() { + root = null; + } + + /** + * main function for tests + */ + public static void main(String[] args) { + BSTRecursive tree = new BSTRecursive(); + tree.add(5); + tree.add(10); + tree.add(9); + assert !tree.find(4) : "4 is not yet present in BST"; + assert tree.find(10) : "10 should be present in BST"; + tree.remove(9); + assert !tree.find(9) : "9 was just deleted from BST"; + tree.remove(1); + assert !tree.find(1) : "Since 1 was not present so find deleting would do no change"; + tree.add(20); + tree.add(70); + assert tree.find(70) : "70 was inserted but not found"; + /* + Will print in following order + 5 10 20 70 + */ + tree.inorder(); + } + + /** + * Recursive method to delete a data if present in BST. + * + * @param node the current node to search for data + * @param data the value to be deleted + * @return Node the updated value of root parameter after delete operation + */ + private Node delete(Node node, int data) { + if (node == null) { + System.out.println("No such data present in BST."); + } else if (node.data > data) { + node.left = delete(node.left, data); + } else if (node.data < data) { + node.right = delete(node.right, data); + } else { + if (node.right == null && node.left == null) { // If it is leaf node + node = null; + } else if (node.left == null) { // If only right node is present + Node temp = node.right; + node.right = null; + node = temp; + } else if (node.right == null) { // Only left node is present + Node temp = node.left; + node.left = null; + node = temp; + } else { // both child are present + Node temp = node.right; + // Find leftmost child of right subtree + while (temp.left != null) { + temp = temp.left; + } + node.data = temp.data; + node.right = delete(node.right, temp.data); + } + } + return node; + } + + /** + * Recursive insertion of value in BST. + * + * @param node to check if the data can be inserted in current node or its + * subtree + * @param data the value to be inserted + * @return the modified value of the root parameter after insertion + */ + private Node insert(Node node, int data) { + if (node == null) { + node = new Node(data); + } else if (node.data > data) { + node.left = insert(node.left, data); + } else if (node.data < data) { + node.right = insert(node.right, data); + } + return node; + } + + /** + * Recursively print Preorder traversal of the BST + * + * @param node the root node + */ + private void preOrder(Node node) { + if (node == null) { + return; + } + System.out.print(node.data + " "); + if (node.left != null) { + preOrder(node.left); + } + if (node.right != null) { + preOrder(node.right); + } + } + + /** + * Recursively print Postorder travesal of BST. + * + * @param node the root node + */ + private void postOrder(Node node) { + if (node == null) { + return; + } + if (node.left != null) { + postOrder(node.left); + } + if (node.right != null) { + postOrder(node.right); + } + System.out.print(node.data + " "); + } + + /** + * Recursively print Inorder traversal of BST. + * + * @param node the root node + */ + private void inOrder(Node node) { + if (node == null) { + return; + } + if (node.left != null) { + inOrder(node.left); + } + System.out.print(node.data + " "); + if (node.right != null) { + inOrder(node.right); + } + } + + /** + * Serach recursively if the given value is present in BST or not. + * + * @param node the current node to check + * @param data the value to be checked + * @return boolean if data is present or not + */ + private boolean search(Node node, int data) { + if (node == null) { + return false; + } else if (node.data == data) { + return true; + } else if (node.data > data) { + return search(node.left, data); + } else { + return search(node.right, data); + } + } + + /** + * add in BST. if the value is not already present it is inserted or else no + * change takes place. + * + * @param data the value to be inserted + */ + public void add(int data) { + this.root = insert(this.root, data); + } + + /** + * If data is present in BST delete it else do nothing. + * + * @param data the value to be removed + */ + public void remove(int data) { + this.root = delete(this.root, data); + } + + /** + * To call inorder traversal on tree + */ + public void inorder() { + System.out.println("Inorder traversal of this tree is:"); + inOrder(this.root); + System.out.println(); // for next line + } + + /** + * To call postorder traversal on tree + */ + public void postorder() { + System.out.println("Postorder traversal of this tree is:"); + postOrder(this.root); + System.out.println(); // for next li + } + + /** + * To call preorder traversal on tree. + */ + public void preorder() { + System.out.println("Preorder traversal of this tree is:"); + preOrder(this.root); + System.out.println(); // for next li + } + + /** + * To check if given value is present in tree or not. + * + * @param data the data to be found for + */ + public boolean find(int data) { + if (search(this.root, data)) { + System.out.println(data + " is present in given BST."); + return true; + } + System.out.println(data + " not found."); + return false; + } + + /** + * The Node class used for building binary search tree + */ + private static class Node { + + int data; + Node left; + Node right; + + /** + * Constructor with data as parameter + */ + Node(int d) { + data = d; + left = null; + right = null; + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java b/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java new file mode 100644 index 000000000000..6299b1be1322 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java @@ -0,0 +1,319 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.List; + +/** + *

Binary Search Tree (Recursive) Generic Type Implementation

+ * + *

+ * A recursive implementation of generic type BST. + * + * Reference: https://en.wikipedia.org/wiki/Binary_search_tree + *

+ * + * @author [Madhur Panwar](https://github.com/mdrpanwar) + */ +public class BSTRecursiveGeneric> { + + /** + * only data member is root of BST + */ + private Node root; + + /** + * Constructor use to initialize node as null + */ + public BSTRecursiveGeneric() { + root = null; + } + + /** + * main function for testing + */ + public static void main(String[] args) { + System.out.println("Testing for integer data..."); + // Integer + BSTRecursiveGeneric integerTree = new BSTRecursiveGeneric(); + + 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"; + integerTree.remove(9); + 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"; + integerTree.add(20); + integerTree.add(70); + assert integerTree.find(70) : "70 was inserted but not found"; + /* + Will print in following order + 5 10 20 70 + */ + integerTree.inorder(); + System.out.println(); + System.out.println("Testing for string data..."); + // String + BSTRecursiveGeneric stringTree = new BSTRecursiveGeneric(); + + 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"; + stringTree.remove("date"); + 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"; + stringTree.add("india"); + stringTree.add("hills"); + assert stringTree.find("hills") : "hills was inserted but not found"; + /* + Will print in following order + banana hills india pineapple + */ + stringTree.inorder(); + + } + + /** + * Recursive method to delete a data if present in BST. + * + * @param node the node under which to (recursively) search for data + * @param data the value to be deleted + * @return Node the updated value of root parameter after delete operation + */ + private Node delete(Node node, T data) { + if (node == null) { + System.out.println("No such data present in BST."); + } else if (node.data.compareTo(data) > 0) { + node.left = delete(node.left, data); + } else if (node.data.compareTo(data) < 0) { + node.right = delete(node.right, data); + } else { + if (node.right == null && node.left == null) { // If it is leaf node + node = null; + } else if (node.left == null) { // If only right node is present + Node temp = node.right; + node.right = null; + node = temp; + } else if (node.right == null) { // Only left node is present + Node temp = node.left; + node.left = null; + node = temp; + } else { // both child are present + Node temp = node.right; + // Find leftmost child of right subtree + while (temp.left != null) { + temp = temp.left; + } + node.data = temp.data; + node.right = delete(node.right, temp.data); + } + } + return node; + } + + /** + * Recursive insertion of value in BST. + * + * @param node to check if the data can be inserted in current node or its + * subtree + * @param data the value to be inserted + * @return the modified value of the root parameter after insertion + */ + private Node insert(Node node, T data) { + if (node == null) { + node = new Node<>(data); + } else if (node.data.compareTo(data) > 0) { + node.left = insert(node.left, data); + } else if (node.data.compareTo(data) < 0) { + node.right = insert(node.right, data); + } + return node; + } + + /** + * Recursively print Preorder traversal of the BST + * + * @param node the root node + */ + private void preOrder(Node node) { + if (node == null) { + return; + } + System.out.print(node.data + " "); + if (node.left != null) { + preOrder(node.left); + } + if (node.right != null) { + preOrder(node.right); + } + } + + /** + * Recursively print Postorder traversal of BST. + * + * @param node the root node + */ + private void postOrder(Node node) { + if (node == null) { + return; + } + if (node.left != null) { + postOrder(node.left); + } + if (node.right != null) { + postOrder(node.right); + } + System.out.print(node.data + " "); + } + + /** + * Recursively print Inorder traversal of BST. + * + * @param node the root node + */ + private void inOrder(Node node) { + if (node == null) { + return; + } + if (node.left != null) { + inOrder(node.left); + } + System.out.print(node.data + " "); + if (node.right != null) { + inOrder(node.right); + } + } + + /** + * Recursively traverse the tree using inorder traversal and keep adding + * elements to argument list. + * + * @param node the root node + * @param sortedList the list to add the srted elements into + */ + private void inOrderSort(Node node, List sortedList) { + if (node == null) { + return; + } + if (node.left != null) { + inOrderSort(node.left, sortedList); + } + sortedList.add(node.data); + if (node.right != null) { + inOrderSort(node.right, sortedList); + } + } + + /** + * Serach recursively if the given value is present in BST or not. + * + * @param node the node under which to check + * @param data the value to be checked + * @return boolean if data is present or not + */ + private boolean search(Node node, T data) { + if (node == null) { + return false; + } else if (node.data.compareTo(data) == 0) { + return true; + } else if (node.data.compareTo(data) > 0) { + return search(node.left, data); + } else { + return search(node.right, data); + } + } + + /** + * add in BST. if the value is not already present it is inserted or else no + * change takes place. + * + * @param data the value to be inserted + */ + public void add(T data) { + this.root = insert(this.root, data); + } + + /** + * If data is present in BST delete it else do nothing. + * + * @param data the value to be removed + */ + public void remove(T data) { + this.root = delete(this.root, data); + } + + /** + * To call inorder traversal on tree + */ + public void inorder() { + System.out.println("Inorder traversal of this tree is:"); + inOrder(this.root); + System.out.println(); // for next line + } + + /** + * return a sorted list by traversing the tree elements using inorder + * traversal + */ + public List inorderSort() { + List sortedList = new ArrayList<>(); + inOrderSort(this.root, sortedList); + return sortedList; + } + + /** + * To call postorder traversal on tree + */ + public void postorder() { + System.out.println("Postorder traversal of this tree is:"); + postOrder(this.root); + System.out.println(); // for next line + } + + /** + * To call preorder traversal on tree. + */ + public void preorder() { + System.out.println("Preorder traversal of this tree is:"); + preOrder(this.root); + System.out.println(); // for next line + } + + /** + * To check if given value is present in tree or not. + * + * @param data the data to be found for + */ + public boolean find(T data) { + if (search(this.root, data)) { + System.out.println(data + " is present in given BST."); + return true; + } + System.out.println(data + " not found."); + return false; + } + + /** + * The generic Node class used for building binary search tree + */ + private static class Node { + + T data; + Node left; + Node right; + + /** + * Constructor with data as parameter + */ + Node(T d) { + data = d; + left = null; + right = null; + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java b/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java new file mode 100644 index 000000000000..6d1c166644a2 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java @@ -0,0 +1,334 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Queue; +import java.util.LinkedList; + +/** + * This entire class is used to build a Binary Tree data structure. There is the + * Node Class and the Tree Class, both explained below. + */ +/** + * A binary tree is a data structure in which an element has two + * successors(children). The left child is usually smaller than the parent, and + * the right child is usually bigger. + * + * @author Unknown + */ +public class BinaryTree { + + /** + * This class implements the nodes that will go on the Binary Tree. They + * consist of the data in them, the node to the left, the node to the right, + * and the parent from which they came from. + * + * @author Unknown + */ + static class Node { + + /** + * Data for the node + */ + public int data; + /** + * The Node to the left of this one + */ + public Node left; + /** + * The Node to the right of this one + */ + public Node right; + /** + * The parent of this node + */ + public Node parent; + + /** + * Constructor of Node + * + * @param value Value to put in the node + */ + public Node(int value) { + data = value; + left = null; + right = null; + parent = null; + } + } + + /** + * The root of the Binary Tree + */ + private Node root; + + /** + * Constructor + */ + public BinaryTree() { + root = null; + } + + /** + * Parameterized Constructor + */ + public BinaryTree(Node root) { + this.root = root; + } + + /** + * Method to find a Node with a certain value + * + * @param key Value being looked for + * @return The node if it finds it, otherwise returns the parent + */ + public Node find(int key) { + Node current = root; + while (current != null) { + if (key < current.data) { + if (current.left == null) { + return current; // The key isn't exist, returns the parent + } + current = current.left; + } else if (key > current.data) { + if (current.right == null) { + return current; + } + current = current.right; + } else { // If you find the value return it + return current; + } + } + return null; + } + + /** + * Inserts certain value into the Binary Tree + * + * @param value Value to be inserted + */ + public void put(int value) { + Node newNode = new Node(value); + if (root == null) { + root = newNode; + } else { + // This will return the soon to be parent of the value you're inserting + Node parent = find(value); + + // This if/else assigns the new node to be either the left or right child of the parent + if (value < parent.data) { + parent.left = newNode; + parent.left.parent = parent; + return; + } else { + parent.right = newNode; + parent.right.parent = parent; + return; + } + } + } + + /** + * Deletes a given value from the Binary Tree + * + * @param value Value to be deleted + * @return If the value was deleted + */ + public boolean remove(int value) { + // temp is the node to be deleted + Node temp = find(value); + + // If the value doesn't exist + if (temp.data != value) { + return false; + } + + // No children + 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 + else if (temp.parent.data < temp.data) { + temp.parent.right = null; + } else { + temp.parent.left = null; + } + return true; + } // Two children + else if (temp.left != null && temp.right != null) { + Node successor = findSuccessor(temp); + + // The left tree of temp is made the left tree of the successor + successor.left = temp.left; + successor.left.parent = successor; + + // If the successor has a right child, the child's grandparent is it's new parent + if (successor.parent != temp) { + if (successor.right != null) { + successor.right.parent = successor.parent; + successor.parent.left = successor.right; + successor.right = temp.right; + successor.right.parent = successor; + } else { + successor.parent.left = null; + successor.right = temp.right; + successor.right.parent = successor; + } + } + + if (temp == root) { + successor.parent = null; + root = successor; + return true; + } // If you're not deleting the root + else { + successor.parent = temp.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 { + temp.parent.left = successor; + } + return true; + } + } // One child + else { + // If it has a right child + if (temp.right != null) { + if (temp == root) { + root = temp.right; + return true; + } + + temp.right.parent = temp.parent; + + // Assigns temp to left or right child + if (temp.data < temp.parent.data) { + temp.parent.left = temp.right; + } else { + temp.parent.right = temp.right; + } + return true; + } // If it has a left child + else { + if (temp == root) { + root = temp.left; + return true; + } + + temp.left.parent = temp.parent; + + // Assigns temp to left or right side + if (temp.data < temp.parent.data) { + temp.parent.left = temp.left; + } else { + temp.parent.right = temp.left; + } + return true; + } + } + } + + /** + * This method finds the Successor to the Node given. Move right once and go + * left down the tree as far as you can + * + * @param n Node that you want to find the Successor of + * @return The Successor of the node + */ + public Node findSuccessor(Node n) { + if (n.right == null) { + return n; + } + Node current = n.right; + Node parent = n.right; + while (current != null) { + parent = current; + current = current.left; + } + return parent; + } + + /** + * Returns the root of the Binary Tree + * + * @return the root of the Binary Tree + */ + public Node getRoot() { + return root; + } + + /** + * Prints leftChild - root - rightChild This is the equivalent of a depth + * first search + * + * @param localRoot The local root of the binary tree + */ + public void inOrder(Node localRoot) { + if (localRoot != null) { + inOrder(localRoot.left); + System.out.print(localRoot.data + " "); + inOrder(localRoot.right); + } + } + + /** + * Prints root - leftChild - rightChild + * + * @param localRoot The local root of the binary tree + */ + public void preOrder(Node localRoot) { + if (localRoot != null) { + System.out.print(localRoot.data + " "); + preOrder(localRoot.left); + preOrder(localRoot.right); + } + } + + /** + * Prints rightChild - leftChild - root + * + * @param localRoot The local root of the binary tree + */ + public void postOrder(Node localRoot) { + if (localRoot != null) { + postOrder(localRoot.left); + postOrder(localRoot.right); + System.out.print(localRoot.data + " "); + } + } + + /** + * Prints the tree in a breadth first search order This is similar to + * pre-order traversal, but instead of being implemented with a stack (or + * recursion), it is implemented with a queue + * + * @param localRoot The local root of the binary tree + */ + public void bfs(Node localRoot) { + // Create a queue for the order of the nodes + Queue queue = new LinkedList(); + + // If the give root is null, then we don't add to the queue + // and won't do anything + if (localRoot != null) { + queue.add(localRoot); + } + + // Continue until the queue is empty + while (!queue.isEmpty()) { + // Get the next node on the queue to visit + localRoot = queue.remove(); + + // Print the data from the node we are visiting + System.out.print(localRoot.data + " "); + + // Add the children to the queue if not null + if (localRoot.right != null) { + queue.add(localRoot.right); + } + if (localRoot.left != null) { + queue.add(localRoot.left); + } + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java b/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java new file mode 100644 index 000000000000..a6878c75981d --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java @@ -0,0 +1,70 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; + +/** + * Problem Statement Ceil value for any number x in a collection is a number y + * which is either equal to x or the least greater number than x. + * + * Problem: Given a binary search tree containing positive integer values. Find + * ceil value for a given key in O(lg(n)) time. In case if it is not present + * return -1. + * + * Ex.1. [30,20,40,10,25,35,50] represents level order traversal of a binary + * search tree. Find ceil for 10. Answer: 20 + * + * Ex.2. [30,20,40,10,25,35,50] represents level order traversal of a binary + * search tree. Find ceil for 22 Answer: 25 + * + * Ex.2. [30,20,40,10,25,35,50] represents level order traversal of a binary + * search tree. Find ceil for 52 Answer: -1 + */ +/** + * + * Solution 1: Brute Force Solution: Do an inorder traversal and save result + * into an array. Iterate over the array to get an element equal to or greater + * than current key. Time Complexity: O(n) Space Complexity: O(n) for auxillary + * array to save inorder representation of tree. + *

+ *

+ * Solution 2: Brute Force Solution: Do an inorder traversal and save result + * into an array.Since array is sorted do a binary search over the array to get + * an element equal to or greater than current key. Time Complexity: O(n) for + * traversal of tree and O(lg(n)) for binary search in array. Total = O(n) Space + * Complexity: O(n) for auxillary array to save inorder representation of tree. + *

+ *

+ * Solution 3: Optimal We can do a DFS search on given tree in following + * fashion. i) if root is null then return null because then ceil doesn't exist + * ii) If key is lesser than root value than ceil will be in right subtree so + * call recursively on right subtree iii) if key is greater than current root, + * then either a) the root is ceil b) ceil is in left subtree: call for left + * subtree. If left subtree returns a non null value then that will be ceil + * otherwise the root is ceil + */ +public class CeilInBinarySearchTree { + + public static Node getCeil(Node root, int key) { + if (root == null) { + return null; + } + + // if root value is same as key than root is the ceiling + if (root.data == key) { + return root; + } + + // if root value is lesser than key then ceil must be in right subtree + if (root.data < key) { + return getCeil(root.right, key); + } + + // if root value is greater than key then ceil can be in left subtree or if + // it is not in left subtree then current node will be ceil + Node result = getCeil(root.left, key); + + // if result is null it means that there is no ceil in children subtrees + // and the root is the ceil otherwise the returned node is the ceil. + return result == null ? root : result; + } +} diff --git a/DataStructures/Trees/CheckIfBinaryTreeBalanced.java b/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java similarity index 78% rename from DataStructures/Trees/CheckIfBinaryTreeBalanced.java rename to src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java index 694ceb652411..a60de7be6e2b 100644 --- a/DataStructures/Trees/CheckIfBinaryTreeBalanced.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java @@ -1,54 +1,63 @@ -package DataStructures.Trees; +package com.thealgorithms.datastructures.trees; import java.util.Stack; import java.util.HashMap; /** - * This class will check if a BinaryTree is balanced. - * A balanced binary tree is defined as a binary tree where - * the differenced in height between the left and right - * subtree of each node differs by at most one. - * - * This can be done in both an iterative and recursive - * fashion. Below, `isBalancedRecursive()` is - * implemented in a recursive fashion, and - * `isBalancedIterative()` is implemented in an - * iterative fashion. - * + * This class will check if a BinaryTree is balanced. A balanced binary tree is + * defined as a binary tree where the differenced in height between the left and + * right subtree of each node differs by at most one. + * + * This can be done in both an iterative and recursive fashion. Below, + * `isBalancedRecursive()` is implemented in a recursive fashion, and + * `isBalancedIterative()` is implemented in an iterative fashion. + * * @author [Ian Cowan](https://github.com/iccowan) */ - public class CheckIfBinaryTreeBalanced { +public class CheckIfBinaryTreeBalanced { /** * This class implements the BinaryTree for these algorithms */ class BinaryTree { - /** The root node of the binary tree */ + + /** + * The root node of the binary tree + */ BTNode root = null; } - + /** * This class implements the nodes for the binary tree */ class BTNode { - /** The value of the node */ + + /** + * The value of the node + */ int value; - /** The left child of the node */ + /** + * The left child of the node + */ BTNode left = null; - /** The right child of the node */ + /** + * The right child of the node + */ BTNode right = null; - - /** Constructor */ - BTNode (int value) { + + /** + * Constructor + */ + BTNode(int value) { this.value = value; } } /** - * Recursive is BT balanced implementation - * + * Recursive is BT balanced implementation + * * @param binaryTree The binary tree to check if balanced */ public boolean isBalancedRecursive(BinaryTree binaryTree) { @@ -66,7 +75,7 @@ public boolean isBalancedRecursive(BinaryTree binaryTree) { * Private helper method to keep track of the depth and balance during * recursion. We effectively perform a modified post-order traversal where * we are looking at the heights of both children of each node in the tree - * + * * @param node The current node to explore * @param depth The current depth of the node * @param isBalanced The array of length 1 keeping track of our balance @@ -75,8 +84,9 @@ 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! - if (node == null || ! isBalanced[0]) + if (node == null || !isBalanced[0]) { return 0; + } // Visit the left and right children, incrementing their depths by 1 int leftHeight = isBalancedRecursive(node.left, depth + 1, isBalanced); @@ -84,8 +94,9 @@ private int isBalancedRecursive(BTNode node, int depth, boolean[] isBalanced) { // If the height of either of the left or right subtrees differ by more // than 1, we cannot be balanced - if (Math.abs(leftHeight - rightHeight) > 1) + if (Math.abs(leftHeight - rightHeight) > 1) { isBalanced[0] = false; + } // The height of our tree is the maximum of the heights of the left // and right subtrees plus one @@ -116,14 +127,14 @@ public boolean isBalancedIterative(BinaryTree binaryTree) { // - the node stack is empty and the node we explore is null // AND // - the tree is still balanced - while (! (nodeStack.isEmpty() && node == null) && isBalanced) { + while (!(nodeStack.isEmpty() && node == null) && isBalanced) { // If the node is not null, we push it to the stack and continue // to the left if (node != null) { nodeStack.push(node); node = node.left; - // Once we hit a node that is null, we are as deep as we can go - // to the left + // Once we hit a node that is null, we are as deep as we can go + // to the left } else { // Find the last node we put on the stack node = nodeStack.peek(); @@ -138,17 +149,20 @@ public boolean isBalancedIterative(BinaryTree binaryTree) { // If the right and left children are not null, we must // have already explored them and have a height // for them so let's get that - if (node.left != null) + if (node.left != null) { leftHeight = subtreeHeights.get(node.left); - - if (node.right != null) + } + + if (node.right != null) { rightHeight = subtreeHeights.get(node.right); - + } + // If the difference in the height of the right subtree // and left subtree differs by more than 1, we cannot be // balanced - if (Math.abs(rightHeight - leftHeight) > 1) + if (Math.abs(rightHeight - leftHeight) > 1) { isBalanced = false; + } // The height of the subtree containing this node is the // max of the left and right subtree heighs plus 1 @@ -160,8 +174,8 @@ public boolean isBalancedIterative(BinaryTree binaryTree) { // Current visiting node is now null node = null; - // If the right child node of this node has not been visited - // and is not null, we need to get that child node on the stack + // If the right child node of this node has not been visited + // and is not null, we need to get that child node on the stack } else { node = node.right; } @@ -173,20 +187,8 @@ public boolean isBalancedIterative(BinaryTree binaryTree) { } /** - * Generates the following unbalanced binary tree for testing - * 0 - * / \ - * / \ - * 0 0 - * / / \ - * / / \ - * 0 0 0 - * / \ - * / \ - * 0 0 - * / - * / - * 0 + * Generates the following unbalanced binary tree for testing 0 / \ / \ 0 0 + * / / \ / / \ 0 0 0 / \ / \ 0 0 / / 0 */ private BinaryTree buildUnbalancedTree() { BinaryTree tree = new BinaryTree(); @@ -213,17 +215,8 @@ private BinaryTree buildUnbalancedTree() { } /** - * Generates the following balanced binary tree for testing - * 0 - * / \ - * / \ - * 0 0 - * / \ / \ - * / 0 / \ - * 0 0 0 - * / / - * / / - * 0 0 + * Generates the following balanced binary tree for testing 0 / \ / \ 0 0 / + * \ / \ / 0 / \ 0 0 0 / / / / 0 0 */ private BinaryTree buildBalancedTree() { BinaryTree tree = new BinaryTree(); @@ -271,4 +264,4 @@ public static void main(String[] args) { System.out.println("isBalancedIB: " + isBalancedIB); System.out.println("isBalancedIU: " + isBalancedIU); } - } \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CreateBSTFromSortedArray.java b/src/main/java/com/thealgorithms/datastructures/trees/CreateBSTFromSortedArray.java new file mode 100644 index 000000000000..5fd12c99537d --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/CreateBSTFromSortedArray.java @@ -0,0 +1,44 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; + +/** + * Given a sorted array. Create a balanced binary search tree from it. + * + * Steps: 1. Find the middle element of array. This will act as root 2. Use the + * left half recursively to create left subtree 3. Use the right half + * recursively to create right subtree + */ +public class CreateBSTFromSortedArray { + + public static void main(String[] args) { + test(new int[]{}); + test(new int[]{1, 2, 3}); + test(new int[]{1, 2, 3, 4, 5}); + test(new int[]{1, 2, 3, 4, 5, 6, 7}); + } + + private static void test(int[] array) { + BinaryTree root = new BinaryTree(createBst(array, 0, array.length - 1)); + System.out.println("\n\nPreorder Traversal: "); + root.preOrder(root.getRoot()); + System.out.println("\nInorder Traversal: "); + root.inOrder(root.getRoot()); + System.out.println("\nPostOrder Traversal: "); + root.postOrder(root.getRoot()); + } + + private static Node createBst(int[] array, int start, int end) { + // No element left. + if (start > end) { + return null; + } + int mid = start + (end - start) / 2; + + // middle element will be the root + Node root = new Node(array[mid]); + root.left = createBst(array, start, mid - 1); + root.right = createBst(array, mid + 1, end); + return root; + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java b/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java new file mode 100644 index 000000000000..bcd00776e7b9 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java @@ -0,0 +1,94 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.HashMap; +import java.util.Map; +import com.thealgorithms.datastructures.trees.BinaryTree.Node; + +/** + * Approach: Naive Solution: Create root node from first value present in + * preorder traversal. Look for the index of root node's value in inorder + * traversal. That will tell total nodes present in left subtree and right + * subtree. Based on that index create left and right subtree. Complexity: Time: + * O(n^2) for each node there is iteration to find index in inorder array Space: + * Stack size = O(height) = O(lg(n)) + * + * Optimized Solution: Instead of iterating over inorder array to find index of + * root value, create a hashmap and find out the index of root value. + * Complexity: Time: O(n) hashmap reduced iteration to find index in inorder + * array Space: O(n) space taken by hashmap + * + */ +public class CreateBinaryTreeFromInorderPreorder { + + public static void main(String[] args) { + test(new Integer[]{}, new Integer[]{}); // empty tree + test(new Integer[]{1}, new Integer[]{1}); // single node tree + test(new Integer[]{1, 2, 3, 4}, new Integer[]{1, 2, 3, 4}); // right skewed tree + test(new Integer[]{1, 2, 3, 4}, new Integer[]{4, 3, 2, 1}); // left skewed tree + test(new Integer[]{3, 9, 20, 15, 7}, new Integer[]{9, 3, 15, 20, 7}); // normal tree + } + + private static void test(final Integer[] preorder, final Integer[] inorder) { + System.out.println("\n===================================================="); + System.out.println("Naive Solution..."); + BinaryTree root = new BinaryTree(createTree(preorder, inorder, 0, 0, inorder.length)); + System.out.println("Preorder Traversal: "); + root.preOrder(root.getRoot()); + System.out.println("\nInorder Traversal: "); + root.inOrder(root.getRoot()); + System.out.println("\nPostOrder Traversal: "); + root.postOrder(root.getRoot()); + + Map map = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + map.put(inorder[i], i); + } + BinaryTree optimizedRoot = new BinaryTree(createTreeOptimized(preorder, inorder, 0, 0, inorder.length, map)); + System.out.println("\n\nOptimized solution..."); + System.out.println("Preorder Traversal: "); + optimizedRoot.preOrder(root.getRoot()); + System.out.println("\nInorder Traversal: "); + optimizedRoot.inOrder(root.getRoot()); + System.out.println("\nPostOrder Traversal: "); + optimizedRoot.postOrder(root.getRoot()); + } + + private static Node createTree(final Integer[] preorder, final Integer[] inorder, + final int preStart, final int inStart, final int size) { + if (size == 0) { + return null; + } + + Node root = new Node(preorder[preStart]); + int i = inStart; + while (preorder[preStart] != inorder[i]) { + i++; + } + 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); + return root; + + } + + private static Node createTreeOptimized(final Integer[] preorder, final Integer[] inorder, + final int preStart, final int inStart, final int size, + final Map inorderMap) { + if (size == 0) { + return null; + } + + Node root = new Node(preorder[preStart]); + int i = inorderMap.get(preorder[preStart]); + int leftNodesCount = i - inStart; + int rightNodesCount = size - leftNodesCount - 1; + root.left = createTreeOptimized(preorder, inorder, preStart + 1, inStart, + leftNodesCount, inorderMap); + root.right = createTreeOptimized(preorder, inorder, preStart + leftNodesCount + 1, + i + 1, rightNodesCount, inorderMap); + return root; + } + +} diff --git a/DataStructures/Trees/FenwickTree.java b/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java similarity index 94% rename from DataStructures/Trees/FenwickTree.java rename to src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java index 65b6eb07f920..e44984b1b9a7 100644 --- a/DataStructures/Trees/FenwickTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java @@ -1,15 +1,16 @@ -package DataStructures.Trees; +package com.thealgorithms.datastructures.trees; public class FenwickTree { + private int n; private int fen_t[]; - + /* Constructor which takes the size of the array as a parameter */ public FenwickTree(int n) { this.n = n; this.fen_t = new int[n + 1]; } - + /* A function which will add the element val at index i*/ public void update(int i, int val) { // As index starts from 0, increment the index by 1 @@ -19,7 +20,7 @@ public void update(int i, int val) { i += i & (-i); } } - + /* A function which will return the cumulative sum from index 1 to index i*/ public int query(int i) { // As index starts from 0, increment the index by 1 @@ -31,4 +32,4 @@ public int query(int i) { } return cumSum; } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java b/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java new file mode 100644 index 000000000000..922cd62fcb2e --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java @@ -0,0 +1,242 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Scanner; + +/** + * A generic tree is a tree which can have as many children as it can be It + * might be possible that every node present is directly connected to root node. + * + *

+ * In this code Every function has two copies: one function is helper function + * which can be called from main and from that function a private function is + * called which will do the actual work. I have done this, while calling from + * main one have to give minimum parameters. + */ +public class GenericTree { + + private class Node { + + int data; + ArrayList child = new ArrayList<>(); + } + + private Node root; + private int size; + + public GenericTree() { // Constructor + Scanner scn = new Scanner(System.in); + root = create_treeG(null, 0, scn); + } + + private Node create_treeG(Node node, int childindx, Scanner scn) { + // display + if (node == null) { + System.out.println("Enter root's data"); + } else { + System.out.println("Enter data of parent of index " + node.data + " " + childindx); + } + // input + node = new Node(); + node.data = scn.nextInt(); + System.out.println("number of children"); + int number = scn.nextInt(); + for (int i = 0; i < number; i++) { + Node child = create_treeG(node, i, scn); + size++; + node.child.add(child); + } + return node; + } + + /** + * Function to display the generic tree + */ + public void display() { // Helper function + display_1(root); + } + + private void display_1(Node parent) { + System.out.print(parent.data + "=>"); + for (int i = 0; i < parent.child.size(); i++) { + System.out.print(parent.child.get(i).data + " "); + } + System.out.println("."); + for (int i = 0; i < parent.child.size(); i++) { + display_1(parent.child.get(i)); + } + } + + /** + * One call store the size directly but if you are asked compute size this + * function to calculate size goes as follows + * + * @return size + */ + public int size2call() { + return size2(root); + } + + public int size2(Node roott) { + int sz = 0; + for (int i = 0; i < roott.child.size(); i++) { + sz += size2(roott.child.get(i)); + } + return sz + 1; + } + + /** + * Function to compute maximum value in the generic tree + * + * @return maximum value + */ + public int maxcall() { + int maxi = root.data; + return max(root, maxi); + } + + private int max(Node roott, int maxi) { + if (maxi < roott.data) { + maxi = roott.data; + } + for (int i = 0; i < roott.child.size(); i++) { + maxi = max(roott.child.get(i), maxi); + } + + return maxi; + } + + /** + * Function to compute HEIGHT of the generic tree + * + * @return height + */ + public int heightcall() { + return height(root) - 1; + } + + private int height(Node node) { + int h = 0; + for (int i = 0; i < node.child.size(); i++) { + int k = height(node.child.get(i)); + if (k > h) { + h = k; + } + } + return h + 1; + } + + /** + * Function to find whether a number is present in the generic tree or not + * + * @param info number + * @return present or not + */ + public boolean findcall(int info) { + return find(root, info); + } + + private boolean find(Node node, int info) { + if (node.data == info) { + return true; + } + for (int i = 0; i < node.child.size(); i++) { + if (find(node.child.get(i), info)) { + return true; + } + } + return false; + } + + /** + * Function to calculate depth of generic tree + * + * @param dep depth + */ + public void depthcaller(int dep) { + depth(root, dep); + } + + public void depth(Node node, int dep) { + if (dep == 0) { + System.out.println(node.data); + return; + } + for (int i = 0; i < node.child.size(); i++) { + depth(node.child.get(i), dep - 1); + } + return; + } + + /** + * Function to print generic tree in pre-order + */ + public void preordercall() { + preorder(root); + System.out.println("."); + } + + private void preorder(Node node) { + System.out.print(node.data + " "); + for (int i = 0; i < node.child.size(); i++) { + preorder(node.child.get(i)); + } + } + + /** + * Function to print generic tree in post-order + */ + public void postordercall() { + postorder(root); + System.out.println("."); + } + + private void postorder(Node node) { + for (int i = 0; i < node.child.size(); i++) { + postorder(node.child.get(i)); + } + System.out.print(node.data + " "); + } + + /** + * Function to print generic tree in level-order + */ + public void levelorder() { + LinkedList q = new LinkedList<>(); + q.addLast(root); + while (!q.isEmpty()) { + int k = q.getFirst().data; + System.out.print(k + " "); + + for (int i = 0; i < q.getFirst().child.size(); i++) { + q.addLast(q.getFirst().child.get(i)); + } + q.removeFirst(); + } + System.out.println("."); + } + + /** + * Function to remove all leaves of generic tree + */ + public void removeleavescall() { + removeleaves(root); + } + + private void removeleaves(Node node) { + ArrayList arr = new ArrayList<>(); + for (int i = 0; i < node.child.size(); i++) { + if (node.child.get(i).child.size() == 0) { + arr.add(i); + // node.child.remove(i); + // i--; + } else { + removeleaves(node.child.get(i)); + } + } + for (int i = arr.size() - 1; i >= 0; i--) { + node.child.remove(arr.get(i) + 0); + } + } +} diff --git a/DataStructures/Trees/LCA.java b/src/main/java/com/thealgorithms/datastructures/trees/LCA.java similarity index 77% rename from DataStructures/Trees/LCA.java rename to src/main/java/com/thealgorithms/datastructures/trees/LCA.java index ffadd6a97f15..193e89d2772f 100644 --- a/DataStructures/Trees/LCA.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/LCA.java @@ -1,25 +1,27 @@ -package DataStructures.Trees; +package com.thealgorithms.datastructures.trees; import java.util.ArrayList; import java.util.Scanner; public class LCA { + private static Scanner scanner = new Scanner(System.in); - public static void main(String[] args){ + + public static void main(String[] args) { //The adjacency list representation of a tree: ArrayList> adj = new ArrayList<>(); //v is the number of vertices and e is the number of edges - int v = scanner.nextInt(), e = v-1; + int v = scanner.nextInt(), e = v - 1; - for(int i=0;i()); } //Storing the given tree as an adjacency list int to, from; - for(int i=0;i> adj, int s, int p, int[] parent, int[] depth){ - for(int adjacent: adj.get(s)){ - if(adjacent!=p){ + private static void dfs(ArrayList> adj, int s, int p, int[] parent, int[] depth) { + for (int adjacent : adj.get(s)) { + if (adjacent != p) { parent[adjacent] = s; depth[adjacent] = 1 + depth[s]; - dfs(adj,adjacent,s,parent,depth); + dfs(adj, adjacent, s, parent, depth); } } } /** * Method to calculate Lowest Common Ancestor + * * @param v1 The first vertex * @param v2 The second vertex * @param depth An array with depths of all vertices * @param parent An array with parents of all vertices * @return Returns a vertex that is LCA of v1 and v2 */ - private static int getLCA(int v1, int v2, int[] depth, int[] parent){ - if(depth[v1] < depth[v2]){ + private static int getLCA(int v1, int v2, int[] depth, int[] parent) { + if (depth[v1] < depth[v2]) { int temp = v1; v1 = v2; v2 = temp; } - while(depth[v1]!=depth[v2]){ + while (depth[v1] != depth[v2]) { v1 = parent[v1]; } - if(v1==v2) return v1; - while(v1!=v2){ + if (v1 == v2) { + return v1; + } + while (v1 != v2) { v1 = parent[v1]; v2 = parent[v2]; } @@ -104,4 +110,4 @@ private static int getLCA(int v1, int v2, int[] depth, int[] parent){ * 9 4 * Output: * 2 - */ \ No newline at end of file + */ diff --git a/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java new file mode 100644 index 000000000000..64ce1f4bb6c1 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java @@ -0,0 +1,58 @@ +package com.thealgorithms.datastructures.trees; + +public class LevelOrderTraversal { + + class Node { + + int data; + Node left, right; + + public Node(int item) { + data = item; + left = right = null; + } + } + + // Root of the Binary Tree + Node root; + + public LevelOrderTraversal(Node root) { + this.root = root; + } + + /* function to print level order traversal of tree*/ + void printLevelOrder() { + int h = height(root); + int i; + for (i = 1; i <= h; i++) { + printGivenLevel(root, i); + } + } + + /* Compute the "height" of a tree -- the number of + nodes along the longest path from the root node + down to the farthest leaf node.*/ + int height(Node root) { + if (root == null) { + return 0; + } else { + /** + * Return the height of larger subtree + */ + return Math.max(height(root.left), height(root.right)) + 1; + } + } + + /* Print nodes at the given level */ + void printGivenLevel(Node root, int level) { + if (root == null) { + return; + } + if (level == 1) { + System.out.print(root.data + " "); + } else if (level > 1) { + printGivenLevel(root.left, level - 1); + printGivenLevel(root.right, level - 1); + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalQueue.java b/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalQueue.java new file mode 100644 index 000000000000..c32b6653bcb0 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalQueue.java @@ -0,0 +1,46 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.LinkedList; +import java.util.Queue; + +/* Class to print Level Order Traversal */ +public class LevelOrderTraversalQueue { + + /* Class to represent Tree node */ + class Node { + + int data; + Node left, right; + + public Node(int item) { + data = item; + left = null; + right = null; + } + } + + /* Given a binary tree. Print its nodes in level order + using array for implementing queue */ + void printLevelOrder(Node root) { + Queue queue = new LinkedList(); + queue.add(root); + while (!queue.isEmpty()) { + + /* poll() removes the present head. + For more information on poll() visit + http://www.tutorialspoint.com/java/util/linkedlist_poll.htm */ + Node tempNode = queue.poll(); + System.out.print(tempNode.data + " "); + + /*Enqueue left child */ + if (tempNode.left != null) { + queue.add(tempNode.left); + } + + /*Enqueue right child */ + if (tempNode.right != null) { + queue.add(tempNode.right); + } + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java b/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java new file mode 100644 index 000000000000..2fcfd1827d1e --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java @@ -0,0 +1,112 @@ +package com.thealgorithms.datastructures.trees; // Java program to print top view of Binary tree + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; + +// Class for a tree node +class TreeNode { + // Members + + int key; + TreeNode left, right; + + // Constructor + public TreeNode(int key) { + this.key = key; + left = right = null; + } +} + +// A class to represent a queue item. The queue is used to do Level +// order traversal. Every Queue item contains node and horizontal +// distance of node from root +class QItem { + + TreeNode node; + int hd; + + public QItem(TreeNode n, int h) { + node = n; + hd = h; + } +} + +// Class for a Binary Tree +class Tree { + + TreeNode root; + + // Constructors + public Tree() { + root = null; + } + + public Tree(TreeNode n) { + root = n; + } + + // This method prints nodes in top view of binary tree + public void printTopView() { + // base case + if (root == null) { + return; + } + + // Creates an empty hashset + HashSet set = new HashSet<>(); + + // Create a queue and add root to it + Queue Q = new LinkedList(); + Q.add(new QItem(root, 0)); // Horizontal distance of root is 0 + + // Standard BFS or level order traversal loop + while (!Q.isEmpty()) { + // Remove the front item and get its details + QItem qi = Q.remove(); + int hd = qi.hd; + TreeNode n = qi.node; + + // If this is the first node at its horizontal distance, + // then this node is in top view + if (!set.contains(hd)) { + set.add(hd); + System.out.print(n.key + " "); + } + + // Enqueue left and right children of current node + if (n.left != null) { + Q.add(new QItem(n.left, hd - 1)); + } + if (n.right != null) { + Q.add(new QItem(n.right, hd + 1)); + } + } + } +} + +// Driver class to test above methods +public class PrintTopViewofTree { + + public static void main(String[] args) { + /* Create following Binary Tree + 1 + / \ + 2 3 + \ + 4 + \ + 5 + \ + 6*/ + TreeNode root = new TreeNode(1); + root.left = new TreeNode(2); + root.right = new TreeNode(3); + root.left.right = new TreeNode(4); + root.left.right.right = new TreeNode(5); + root.left.right.right.right = new TreeNode(6); + Tree t = new Tree(root); + System.out.println("Following are nodes in top view of Binary Tree"); + t.printTopView(); + } +} diff --git a/DataStructures/Trees/README.md b/src/main/java/com/thealgorithms/datastructures/trees/README.md similarity index 100% rename from DataStructures/Trees/README.md rename to src/main/java/com/thealgorithms/datastructures/trees/README.md diff --git a/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java b/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java new file mode 100644 index 000000000000..49d585be58e5 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java @@ -0,0 +1,340 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Scanner; + +/** + * @author jack870131 + */ +public class RedBlackBST { + + private final int R = 0; + private final int B = 1; + + private class Node { + + int key = -1, color = B; + Node left = nil, right = nil, p = nil; + + Node(int key) { + this.key = key; + } + } + + private final Node nil = new Node(-1); + private Node root = nil; + + public void printTree(Node node) { + if (node == nil) { + return; + } + printTree(node.left); + System.out.print( + ((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); + printTree(node.right); + } + + public void printTreepre(Node node) { + if (node == nil) { + return; + } + System.out.print( + ((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); + printTree(node.left); + printTree(node.right); + } + + private Node findNode(Node findNode, Node node) { + if (root == nil) { + return null; + } + if (findNode.key < node.key) { + if (node.left != nil) { + return findNode(findNode, node.left); + } + } else if (findNode.key > node.key) { + if (node.right != nil) { + return findNode(findNode, node.right); + } + } else if (findNode.key == node.key) { + return node; + } + return null; + } + + private void insert(Node node) { + Node temp = root; + if (root == nil) { + root = node; + node.color = B; + node.p = nil; + } else { + node.color = R; + while (true) { + if (node.key < temp.key) { + if (temp.left == nil) { + temp.left = node; + node.p = temp; + break; + } else { + temp = temp.left; + } + } else if (node.key >= temp.key) { + if (temp.right == nil) { + temp.right = node; + node.p = temp; + break; + } else { + temp = temp.right; + } + } + } + fixTree(node); + } + } + + private void fixTree(Node node) { + while (node.p.color == R) { + Node y = nil; + if (node.p == node.p.p.left) { + y = node.p.p.right; + + if (y != nil && y.color == R) { + node.p.color = B; + y.color = B; + node.p.p.color = R; + node = node.p.p; + continue; + } + if (node == node.p.right) { + node = node.p; + rotateLeft(node); + } + node.p.color = B; + node.p.p.color = R; + rotateRight(node.p.p); + } else { + y = node.p.p.left; + if (y != nil && y.color == R) { + node.p.color = B; + y.color = B; + node.p.p.color = R; + node = node.p.p; + continue; + } + if (node == node.p.left) { + node = node.p; + rotateRight(node); + } + node.p.color = B; + node.p.p.color = R; + rotateLeft(node.p.p); + } + } + root.color = B; + } + + void rotateLeft(Node node) { + if (node.p != nil) { + if (node == node.p.left) { + node.p.left = node.right; + } else { + node.p.right = node.right; + } + node.right.p = node.p; + node.p = node.right; + if (node.right.left != nil) { + node.right.left.p = node; + } + node.right = node.right.left; + node.p.left = node; + } else { + Node right = root.right; + root.right = right.left; + right.left.p = root; + root.p = right; + right.left = root; + right.p = nil; + root = right; + } + } + + void rotateRight(Node node) { + if (node.p != nil) { + if (node == node.p.left) { + node.p.left = node.left; + } else { + node.p.right = node.left; + } + + node.left.p = node.p; + node.p = node.left; + if (node.left.right != nil) { + node.left.right.p = node; + } + node.left = node.left.right; + node.p.right = node; + } else { + Node left = root.left; + root.left = root.left.right; + left.right.p = root; + root.p = left; + left.right = root; + left.p = nil; + root = left; + } + } + + void transplant(Node target, Node with) { + if (target.p == nil) { + root = with; + } else if (target == target.p.left) { + target.p.left = with; + } else { + target.p.right = with; + } + with.p = target.p; + } + + Node treeMinimum(Node subTreeRoot) { + while (subTreeRoot.left != nil) { + subTreeRoot = subTreeRoot.left; + } + return subTreeRoot; + } + + boolean delete(Node z) { + if ((z = findNode(z, root)) == null) { + return false; + } + Node x; + Node y = z; + int yorigcolor = y.color; + + if (z.left == nil) { + x = z.right; + transplant(z, z.right); + } else if (z.right == nil) { + x = z.left; + transplant(z, z.left); + } else { + y = treeMinimum(z.right); + yorigcolor = y.color; + x = y.right; + if (y.p == z) { + x.p = y; + } else { + transplant(y, y.right); + y.right = z.right; + y.right.p = y; + } + transplant(z, y); + y.left = z.left; + y.left.p = y; + y.color = z.color; + } + if (yorigcolor == B) { + deleteFixup(x); + } + return true; + } + + void deleteFixup(Node x) { + while (x != root && x.color == B) { + if (x == x.p.left) { + Node w = x.p.right; + if (w.color == R) { + w.color = B; + x.p.color = R; + rotateLeft(x.p); + w = x.p.right; + } + if (w.left.color == B && w.right.color == B) { + w.color = R; + x = x.p; + continue; + } else if (w.right.color == B) { + w.left.color = B; + w.color = R; + rotateRight(w); + w = x.p.right; + } + if (w.right.color == R) { + w.color = x.p.color; + x.p.color = B; + w.right.color = B; + rotateLeft(x.p); + x = root; + } + } else { + Node w = x.p.left; + if (w.color == R) { + w.color = B; + x.p.color = R; + rotateRight(x.p); + w = x.p.left; + } + if (w.right.color == B && w.left.color == B) { + w.color = R; + x = x.p; + continue; + } else if (w.left.color == B) { + w.right.color = B; + w.color = R; + rotateLeft(w); + w = x.p.left; + } + if (w.left.color == R) { + w.color = x.p.color; + x.p.color = B; + w.left.color = B; + rotateRight(x.p); + x = root; + } + } + } + x.color = B; + } + + public void insertDemo() { + Scanner scan = new Scanner(System.in); + while (true) { + System.out.println("Add items"); + + int item; + Node node; + + item = scan.nextInt(); + while (item != -999) { + node = new Node(item); + insert(node); + item = scan.nextInt(); + } + printTree(root); + System.out.println("Pre order"); + printTreepre(root); + break; + } + scan.close(); + } + + public void deleteDemo() { + Scanner scan = new Scanner(System.in); + System.out.println("Delete items"); + int item; + Node node; + item = scan.nextInt(); + node = new Node(item); + System.out.print("Deleting item " + item); + if (delete(node)) { + System.out.print(": deleted!"); + } else { + System.out.print(": does not exist!"); + } + + System.out.println(); + printTree(root); + System.out.println("Pre order"); + printTreepre(root); + scan.close(); + } +} diff --git a/DataStructures/Trees/SegmentTree.java b/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java similarity index 80% rename from DataStructures/Trees/SegmentTree.java rename to src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java index 5b6dd972ac0f..674c6a85385a 100644 --- a/DataStructures/Trees/SegmentTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java @@ -1,10 +1,11 @@ -package DataStructures.Trees; +package com.thealgorithms.datastructures.trees; public class SegmentTree { + private int seg_t[]; private int n; private int arr[]; - + /* Constructor which takes the size of the array and the array as a parameter*/ public SegmentTree(int n, int arr[]) { this.n = n; @@ -16,66 +17,65 @@ public SegmentTree(int n, int arr[]) { this.n = n; constructTree(arr, 0, n - 1, 0); } - + /* A function which will create the segment tree*/ public int constructTree(int[] arr, int start, int end, int index) { if (start == end) { this.seg_t[index] = arr[start]; return arr[start]; } - + int mid = start + (end - start) / 2; - this.seg_t[index] = constructTree(arr, start, mid, index*2 + 1) + - constructTree(arr, mid + 1, end, index*2 + 2); + this.seg_t[index] = constructTree(arr, start, mid, index * 2 + 1) + + constructTree(arr, mid + 1, end, index * 2 + 2); return this.seg_t[index]; } - - + /* A function which will update the value at a index i. This will be called by the update function internally*/ private void updateTree(int start, int end, int index, int diff, int seg_index) { if (index < start || index > end) { return; } - + this.seg_t[seg_index] += diff; if (start != end) { int mid = start + (end - start) / 2; - updateTree(start, mid, index, diff, seg_index*2 + 1); - updateTree(mid + 1, end, index, diff, seg_index*2 + 2); + updateTree(start, mid, index, diff, seg_index * 2 + 1); + updateTree(mid + 1, end, index, diff, seg_index * 2 + 2); } } - + /* A function to update the value at a particular index*/ public void update(int index, int value) { if (index < 0 || index > n) { return; } - + int diff = value - arr[index]; arr[index] = value; updateTree(0, n - 1, index, diff, 0); } - + /* A function to get the sum of the elements from index l to index r. This will be called internally*/ private int getSumTree(int start, int end, int q_start, int q_end, int seg_index) { if (q_start <= start && q_end >= end) { return this.seg_t[seg_index]; } - + if (q_start > end || q_end < start) { return 0; } - - int mid = start + (end - start)/2; - return getSumTree(start, mid, q_start, q_end, seg_index*2 + 1) + getSumTree(mid + 1, end, q_start, q_end, seg_index*2 + 2); + + int mid = start + (end - start) / 2; + return getSumTree(start, mid, q_start, q_end, seg_index * 2 + 1) + getSumTree(mid + 1, end, q_start, q_end, seg_index * 2 + 2); } - + /* A function to query the sum of the subarray [start...end]*/ public int getSum(int start, int end) { if (start < 0 || end > n || start > end) { return 0; } - return getSumTree(0, n-1, start, end, 0); + return getSumTree(0, n - 1, start, end, 0); } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/TreeTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/TreeTraversal.java new file mode 100644 index 000000000000..586f740b1b14 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/TreeTraversal.java @@ -0,0 +1,120 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.LinkedList; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +// Driver Program +public class TreeTraversal { + + public static void main(String[] args) { + Node tree = new Node(5); + tree.insert(3); + tree.insert(2); + tree.insert(7); + tree.insert(4); + tree.insert(6); + tree.insert(8); + + // Prints 5 3 2 4 7 6 8 + System.out.println("Pre order traversal:"); + tree.printPreOrder(); + System.out.println(); + // Prints 2 3 4 5 6 7 8 + System.out.println("In order traversal:"); + tree.printInOrder(); + System.out.println(); + // Prints 2 4 3 6 8 7 5 + System.out.println("Post order traversal:"); + tree.printPostOrder(); + System.out.println(); + // Prints 5 3 7 2 4 6 8 + System.out.println("Level order traversal:"); + tree.printLevelOrder(); + System.out.println(); + } +} + +/** + * The Node class which initializes a Node of a tree Consists of all 4 traversal + * methods: printInOrder, printPostOrder, printPreOrder & printLevelOrder + * printInOrder: LEFT -> ROOT -> RIGHT printPreOrder: ROOT -> LEFT -> RIGHT + * printPostOrder: LEFT -> RIGHT -> ROOT printLevelOrder: Prints by level + * (starting at root), from left to right. + */ +class Node { + + Node left, right; + int data; + + public Node(int data) { + this.data = data; + } + + public void insert(int value) { + if (value < data) { + if (left == null) { + left = new Node(value); + } else { + left.insert(value); + } + } else { + if (right == null) { + right = new Node(value); + } else { + right.insert(value); + } + } + } + + public void printInOrder() { + if (left != null) { + left.printInOrder(); + } + System.out.print(data + " "); + if (right != null) { + right.printInOrder(); + } + } + + public void printPreOrder() { + System.out.print(data + " "); + if (left != null) { + left.printPreOrder(); + } + if (right != null) { + right.printPreOrder(); + } + } + + public void printPostOrder() { + if (left != null) { + left.printPostOrder(); + } + if (right != null) { + right.printPostOrder(); + } + System.out.print(data + " "); + } + + /** + * O(n) time algorithm. Uses O(n) space to store nodes in a queue to aid in + * traversal. + */ + public void printLevelOrder() { + LinkedList queue = new LinkedList<>(); + queue.add(this); + while (queue.size() > 0) { + Node head = queue.remove(); + System.out.print(head.data + " "); + // Add children of recently-printed node to queue, if they exist. + if (head.left != null) { + queue.add(head.left); + } + if (head.right != null) { + queue.add(head.right); + } + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java b/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java new file mode 100644 index 000000000000..a650900a23ba --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java @@ -0,0 +1,144 @@ +package com.thealgorithms.datastructures.trees; + +/** + * Trie Data structure implementation without any libraries + * + * @author Dheeraj Kumar Barnwal (https://github.com/dheeraj92) + */ +import java.util.Scanner; + +public class TrieImp { + + public class TrieNode { + + TrieNode[] child; + boolean end; + + public TrieNode() { + child = new TrieNode[26]; + end = false; + } + } + + private final TrieNode root; + + public TrieImp() { + root = new TrieNode(); + } + + public void insert(String word) { + TrieNode currentNode = root; + for (int i = 0; i < word.length(); i++) { + TrieNode node = currentNode.child[word.charAt(i) - 'a']; + if (node == null) { + node = new TrieNode(); + currentNode.child[word.charAt(i) - 'a'] = node; + } + currentNode = node; + } + currentNode.end = true; + } + + public boolean search(String word) { + TrieNode currentNode = root; + for (int i = 0; i < word.length(); i++) { + char ch = word.charAt(i); + TrieNode node = currentNode.child[ch - 'a']; + if (node == null) { + return false; + } + currentNode = node; + } + return currentNode.end; + } + + public boolean delete(String word) { + TrieNode currentNode = root; + for (int i = 0; i < word.length(); i++) { + char ch = word.charAt(i); + TrieNode node = currentNode.child[ch - 'a']; + if (node == null) { + return false; + } + currentNode = node; + } + if (currentNode.end == true) { + currentNode.end = false; + return true; + } + return false; + } + + public static void sop(String print) { + System.out.println(print); + } + + /** + * Regex to check if word contains only a-z character + */ + public static boolean isValid(String word) { + return word.matches("^[a-z]+$"); + } + + public static void main(String[] args) { + TrieImp obj = new TrieImp(); + String word; + @SuppressWarnings("resource") + Scanner scan = new Scanner(System.in); + sop("string should contain only a-z character for all operation"); + while (true) { + sop("1. Insert\n2. Search\n3. Delete\n4. Quit"); + try { + int t = scan.nextInt(); + switch (t) { + case 1: + word = scan.next(); + if (isValid(word)) { + obj.insert(word); + } else { + sop("Invalid string: allowed only a-z"); + } + break; + case 2: + word = scan.next(); + boolean resS = false; + if (isValid(word)) { + resS = obj.search(word); + } else { + sop("Invalid string: allowed only a-z"); + } + if (resS) { + sop("word found"); + } else { + sop("word not found"); + } + break; + case 3: + word = scan.next(); + boolean resD = false; + if (isValid(word)) { + resD = obj.delete(word); + } else { + sop("Invalid string: allowed only a-z"); + } + if (resD) { + sop("word got deleted successfully"); + } else { + sop("word not found"); + } + break; + case 4: + sop("Quit successfully"); + System.exit(1); + break; + default: + sop("Input int from 1-4"); + break; + } + } catch (Exception e) { + String badInput = scan.next(); + sop("This is bad input: " + badInput); + } + } + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/ValidBSTOrNot.java b/src/main/java/com/thealgorithms/datastructures/trees/ValidBSTOrNot.java new file mode 100644 index 000000000000..1b9555c07650 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/ValidBSTOrNot.java @@ -0,0 +1,45 @@ +package com.thealgorithms.datastructures.trees; + +public class ValidBSTOrNot { + + class Node { + + int data; + Node left, right; + + public Node(int item) { + data = item; + left = right = null; + } + } + + // Root of the Binary Tree + + /* can give min and max value according to your code or + can write a function to find min and max value of tree. */ + + /* returns true if given search tree is binary + search tree (efficient version) */ + boolean isBST(Node root) { + return isBSTUtil(root, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + /* Returns true if the given tree is a BST and its + values are >= min and <= max. */ + boolean isBSTUtil(Node node, int min, int max) { + /* an empty tree is BST */ + if (node == null) { + return true; + } + + /* false if this node violates the min/max constraints */ + if (node.data < min || node.data > max) { + return false; + } + + /* otherwise check the subtrees recursively + tightening the min/max constraints */ + // Allow only distinct values + return (isBSTUtil(node.left, min, node.data - 1) && isBSTUtil(node.right, node.data + 1, max)); + } +} diff --git a/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java new file mode 100644 index 000000000000..18577fbc5c9a --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java @@ -0,0 +1,106 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +/* The following class implements a vertical order traversal +in a tree from top to bottom and left to right, so for a tree : + 1 + / \ + 2 3 + / \ \ + 4 5 6 + \ / \ + 7 8 10 + \ + 9 + the sequence will be : + 4 2 7 1 5 9 3 8 6 10 + */ +public class VerticalOrderTraversal { + + public static void main(String[] args) { + BinaryTree tree = new BinaryTree(); + tree.put(5); + tree.put(6); + tree.put(3); + tree.put(1); + tree.put(4); + BinaryTree.Node root = tree.getRoot(); + ArrayList ans = verticalTraversal(root); + for (int i : ans) { + System.out.print(i + " "); + } + } + + /*Function that receives a root Node and prints the tree + in Vertical Order.*/ + private static ArrayList verticalTraversal(BinaryTree.Node root) { + /*Queue to store the Nodes.*/ + Queue queue = new LinkedList<>(); + + /*Queue to store the index of particular vertical + column of a tree , with root at 0, Nodes on left + with negative index and Nodes on right with positive + index. */ + Queue index = new LinkedList<>(); + + /*Map of Integer and ArrayList to store all the + elements in a particular index in a single arrayList + that will have a key equal to the index itself. */ + Map> map = new HashMap<>(); + + /* min and max stores leftmost and right most index to + later print the tree in vertical fashion.*/ + int max = 0, min = 0; + queue.offer(root); + index.offer(0); + + while (!queue.isEmpty()) { + + if (queue.peek().left != null) { + /*Adding the left Node if it is not null + and its index by subtracting 1 from it's + parent's index*/ + queue.offer(queue.peek().left); + index.offer(index.peek() - 1); + } + if (queue.peek().right != null) { + /*Adding the right Node if it is not null + and its index by adding 1 from it's + parent's index*/ + queue.offer(queue.peek().right); + index.offer(index.peek() + 1); + } + /*If the map does not contains the index a new + ArrayList is created with the index as key.*/ + if (!map.containsKey(index.peek())) { + ArrayList a = new ArrayList<>(); + map.put(index.peek(), a); + } + /*For a index, corresponding Node data is added + to the respective ArrayList present at that + index. */ + map.get(index.peek()).add(queue.peek().data); + max = (int) Math.max(max, index.peek()); + min = (int) Math.min(min, index.peek()); + /*The Node and its index are removed + from their respective queues.*/ + index.poll(); + queue.poll(); + } + /*Finally map data is printed here which has keys + from min to max. Each ArrayList represents a + vertical column that is added in ans ArrayList.*/ + ArrayList ans = new ArrayList<>(); + for (int i = min; i <= max; i++) { + for (int j = 0; j < map.get(i).size(); j++) { + ans.add(map.get(i).get(j)); + } + } + return ans; + } +} diff --git a/DataStructures/Trees/nearestRightKey.java b/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java similarity index 91% rename from DataStructures/Trees/nearestRightKey.java rename to src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java index 228bf470d809..a056c459f000 100644 --- a/DataStructures/Trees/nearestRightKey.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java @@ -1,4 +1,4 @@ -package DataStructures.NRKTrees; +package com.thealgorithms.datastructures.trees; import java.util.Scanner; import java.util.concurrent.ThreadLocalRandom; @@ -28,14 +28,13 @@ public static NRKTree BuildTree() { public static int nearestRightKey(NRKTree root, int x0) { //Check whether tree is empty - if(root == null){ - return 0; - } - else { - if(root.data - x0 > 0){ + if (root == null) { + return 0; + } else { + if (root.data - x0 > 0) { // Go left int temp = nearestRightKey(root.left, x0); - if(temp == 0){ + if (temp == 0) { return root.data; } return temp; @@ -49,7 +48,6 @@ public static int nearestRightKey(NRKTree root, int x0) { } - class NRKTree { public NRKTree left; diff --git a/DevUtils/Nodes/LargeTreeNode.java b/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java similarity index 86% rename from DevUtils/Nodes/LargeTreeNode.java rename to src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java index 678608e735c9..1575e3649bc3 100644 --- a/DevUtils/Nodes/LargeTreeNode.java +++ b/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java @@ -1,27 +1,32 @@ -package DevUtils.Nodes; +package com.thealgorithms.devutils.nodes; import java.util.Collection; /** - * {@link TreeNode} extension that holds a {@link Collection} - * of refrences to child Nodes. - * + * {@link TreeNode} extension that holds a {@link Collection} of refrences to + * child Nodes. + * * @param The type of the data held in the Node. - * + * * @author aitorfi */ public class LargeTreeNode extends TreeNode { - /** {@link Collection} that holds the Nodes' child nodes. */ + + /** + * {@link Collection} that holds the Nodes' child nodes. + */ private Collection> childNodes; - /** Empty contructor. */ + /** + * Empty contructor. + */ public LargeTreeNode() { super(); } /** * Initializes the Nodes' data. - * + * * @param data Value to which data will be initialized. * @see TreeNode#TreeNode(Object) */ @@ -31,7 +36,7 @@ public LargeTreeNode(E data) { /** * Initializes the Nodes' data and parent node reference. - * + * * @param data Value to which data will be initialized. * @param parentNode Value to which the nodes' parent reference will be set. * @see TreeNode#TreeNode(Object, Node) @@ -42,7 +47,7 @@ public LargeTreeNode(E data, LargeTreeNode parentNode) { /** * Initializes the Nodes' data and parent and child nodes references. - * + * * @param data Value to which data will be initialized. * @param parentNode Value to which the nodes' parent reference will be set. * @param childNodes {@link Collection} of child Nodes. diff --git a/DevUtils/Nodes/Node.java b/src/main/java/com/thealgorithms/devutils/nodes/Node.java similarity index 66% rename from DevUtils/Nodes/Node.java rename to src/main/java/com/thealgorithms/devutils/nodes/Node.java index a00b79e1a07b..a10817830962 100644 --- a/DevUtils/Nodes/Node.java +++ b/src/main/java/com/thealgorithms/devutils/nodes/Node.java @@ -1,25 +1,31 @@ -package DevUtils.Nodes; +package com.thealgorithms.devutils.nodes; /** - * Base class for any node implementation which - * contains a generic type variable. - * + * Base class for any node implementation which contains a generic type + * variable. + * * All known subclasses: {@link TreeNode}, {@link SimpleNode}. - * + * * @param The type of the data held in the Node. - * + * * @author aitorfi */ public abstract class Node { - /** Generic type data stored in the Node. */ + + /** + * Generic type data stored in the Node. + */ private E data; - /** Empty constructor. */ - public Node() {} + /** + * Empty constructor. + */ + public Node() { + } /** * Initializes the Nodes' data. - * + * * @param data Value to which data will be initialized. */ public Node(E data) { diff --git a/DevUtils/Nodes/SimpleNode.java b/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java similarity index 83% rename from DevUtils/Nodes/SimpleNode.java rename to src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java index b1a112eb997a..769ffc2a9a96 100644 --- a/DevUtils/Nodes/SimpleNode.java +++ b/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java @@ -1,25 +1,29 @@ -package DevUtils.Nodes; +package com.thealgorithms.devutils.nodes; /** - * Simple Node implementation that holds - * a reference to the next Node. - * + * Simple Node implementation that holds a reference to the next Node. + * * @param The type of the data held in the Node. - * + * * @author aitorfi */ public class SimpleNode extends Node { - /** Reference to the next Node. */ + + /** + * Reference to the next Node. + */ private SimpleNode nextNode; - /** Empty contructor. */ + /** + * Empty contructor. + */ public SimpleNode() { super(); } /** * Initializes the Nodes' data. - * + * * @param data Value to which data will be initialized. * @see Node#Node(Object) */ @@ -29,7 +33,7 @@ public SimpleNode(E data) { /** * Initializes the Nodes' data and next node reference. - * + * * @param data Value to which data will be initialized. * @param nextNode Value to which the next node reference will be set. */ diff --git a/DevUtils/Nodes/SimpleTreeNode.java b/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java similarity index 84% rename from DevUtils/Nodes/SimpleTreeNode.java rename to src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java index 25611fc6b490..215f01a6ef59 100644 --- a/DevUtils/Nodes/SimpleTreeNode.java +++ b/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java @@ -1,27 +1,34 @@ -package DevUtils.Nodes; +package com.thealgorithms.devutils.nodes; /** - * Simple TreeNode extension that holds references - * to two child Nodes (left and right). - * + * Simple TreeNode extension that holds references to two child Nodes (left and + * right). + * * @param The type of the data held in the Node. - * + * * @author aitorfi */ public class SimpleTreeNode extends TreeNode { - /** Refrence to the child Node on the left. */ + + /** + * Refrence to the child Node on the left. + */ private SimpleTreeNode leftNode; - /** Refrence to the child Node on the right. */ + /** + * Refrence to the child Node on the right. + */ private SimpleTreeNode rightNode; - /** Empty contructor. */ + /** + * Empty contructor. + */ public SimpleTreeNode() { super(); } /** * Initializes the Nodes' data. - * + * * @param data Value to which data will be initialized. * @see TreeNode#TreeNode(Object) */ @@ -31,7 +38,7 @@ public SimpleTreeNode(E data) { /** * Initializes the Nodes' data and parent node reference. - * + * * @param data Value to which data will be initialized. * @param parentNode Value to which the nodes' parent reference will be set. * @see TreeNode#TreeNode(Object, Node) @@ -42,11 +49,13 @@ public SimpleTreeNode(E data, SimpleTreeNode parentNode) { /** * Initializes the Nodes' data and parent and child nodes references. - * + * * @param data Value to which data will be initialized. * @param parentNode Value to which the nodes' parent reference will be set. - * @param leftNode Value to which the nodes' left child reference will be set. - * @param rightNode Value to which the nodes' right child reference will be set. + * @param leftNode Value to which the nodes' left child reference will be + * set. + * @param rightNode Value to which the nodes' right child reference will be + * set. */ public SimpleTreeNode(E data, SimpleTreeNode parentNode, SimpleTreeNode leftNode, SimpleTreeNode rightNode) { super(data, parentNode); diff --git a/DevUtils/Nodes/TreeNode.java b/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java similarity index 83% rename from DevUtils/Nodes/TreeNode.java rename to src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java index bac29770f59f..13c9212306c1 100644 --- a/DevUtils/Nodes/TreeNode.java +++ b/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java @@ -1,22 +1,28 @@ -package DevUtils.Nodes; +package com.thealgorithms.devutils.nodes; /** - * Base class for any tree node which - * holds a reference to the parent node. - * + * Base class for any tree node which holds a reference to the parent node. + * * All known subclasses: {@link SimpleTreeNode}, {@link LargeTreeNode}. - * + * * @param The type of the data held in the Node. - * + * * @author aitorfi */ public abstract class TreeNode extends Node { - /** Refernce to the parent Node. */ + + /** + * Refernce to the parent Node. + */ private TreeNode parentNode; - /** Indicates the depth at which this node is in the tree. */ + /** + * Indicates the depth at which this node is in the tree. + */ private int depth; - /** Empty contructor. */ + /** + * Empty contructor. + */ public TreeNode() { super(); depth = 0; @@ -24,7 +30,7 @@ public TreeNode() { /** * Initializes the Nodes' data. - * + * * @param data Value to which data will be initialized. * @see Node#Node(Object) */ @@ -35,7 +41,7 @@ public TreeNode(E data) { /** * Initializes the Nodes' data and parent node reference. - * + * * @param data Value to which data will be initialized. * @param parentNode Value to which the nodes' parent reference will be set. */ diff --git a/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java b/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java new file mode 100644 index 000000000000..96da4b3f8546 --- /dev/null +++ b/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java @@ -0,0 +1,17 @@ +package com.thealgorithms.devutils.searches; + +/** + * The common interface of most searching algorithms + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +public interface SearchAlgorithm { + + /** + * @param key is an element which should be found + * @param array is an array where the element should be found + * @param Comparable type + * @return first found index of the element + */ + > int find(T array[], T key); +} diff --git a/DivideAndConquer/BinaryExponentiation.java b/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java similarity index 69% rename from DivideAndConquer/BinaryExponentiation.java rename to src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java index 623a30aebe73..ee5ad9c9fb73 100644 --- a/DivideAndConquer/BinaryExponentiation.java +++ b/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java @@ -1,4 +1,4 @@ -package DivideAndConquer; +package com.thealgorithms.divideandconquer; public class BinaryExponentiation { @@ -9,10 +9,14 @@ public static void main(String args[]) { // Function to calculate x^y // Time Complexity: O(logn) public static long calculatePower(long x, long y) { - if (y == 0) return 1; + if (y == 0) { + return 1; + } long val = calculatePower(x, y / 2); val *= val; - if (y % 2 == 1) val *= x; + if (y % 2 == 1) { + val *= x; + } return val; } } diff --git a/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java b/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java new file mode 100644 index 000000000000..9751dce61c3f --- /dev/null +++ b/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java @@ -0,0 +1,349 @@ +package com.thealgorithms.divideandconquer; + +/** + * For a set of points in a coordinates system (10000 maximum), ClosestPair + * class calculates the two closest points. + */ +public final class ClosestPair { + + /** + * Number of points + */ + int numberPoints; + /** + * Input data, maximum 10000. + */ + private Location[] array; + /** + * Minimum point coordinate. + */ + Location point1 = null; + /** + * Minimum point coordinate. + */ + Location point2 = null; + /** + * Minimum point length. + */ + private static double minNum = Double.MAX_VALUE; + + public static void setMinNum(double minNum) { + ClosestPair.minNum = minNum; + } + + public static void setSecondCount(int secondCount) { + ClosestPair.secondCount = secondCount; + } + + /** + * secondCount + */ + private static int secondCount = 0; + + /** + * Constructor. + */ + ClosestPair(int points) { + numberPoints = points; + array = new Location[numberPoints]; + } + + /** + * Location class is an auxiliary type to keep points coordinates. + */ + public static class Location { + + double x; + double y; + + /** + * @param xpar (IN Parameter) x coordinate
+ * @param ypar (IN Parameter) y coordinate
+ */ + Location(final double xpar, final double ypar) { // Save x, y coordinates + this.x = xpar; + this.y = ypar; + } + } + + public Location[] createLocation(int numberValues) { + return new Location[numberValues]; + } + + public Location buildLocation(double x, double y) { + return new Location(x, y); + } + + /** + * xPartition function: arrange x-axis. + * + * @param a (IN Parameter) array of points
+ * @param first (IN Parameter) first point
+ * @param last (IN Parameter) last point
+ * @return pivot index + */ + public int xPartition(final Location[] a, final int first, final int last) { + + Location pivot = a[last]; // pivot + int i = first - 1; + Location temp; // Temporarily store value for position transformation + for (int j = first; j <= last - 1; j++) { + if (a[j].x <= pivot.x) { // Less than or less than pivot + i++; + temp = a[i]; // array[i] <-> array[j] + a[i] = a[j]; + a[j] = temp; + } + } + i++; + temp = a[i]; // array[pivot] <-> array[i] + a[i] = a[last]; + a[last] = temp; + return i; // pivot index + } + + /** + * yPartition function: arrange y-axis. + * + * @param a (IN Parameter) array of points
+ * @param first (IN Parameter) first point
+ * @param last (IN Parameter) last point
+ * @return pivot index + */ + public int yPartition(final Location[] a, final int first, final int last) { + + Location pivot = a[last]; // pivot + int i = first - 1; + Location temp; // Temporarily store value for position transformation + for (int j = first; j <= last - 1; j++) { + if (a[j].y <= pivot.y) { // Less than or less than pivot + i++; + temp = a[i]; // array[i] <-> array[j] + a[i] = a[j]; + a[j] = temp; + } + } + i++; + temp = a[i]; // array[pivot] <-> array[i] + a[i] = a[last]; + a[last] = temp; + return i; // pivot index + } + + /** + * xQuickSort function: //x-axis Quick Sorting. + * + * @param a (IN Parameter) array of points
+ * @param first (IN Parameter) first point
+ * @param last (IN Parameter) last point
+ */ + public void xQuickSort(final Location[] a, final int first, final int last) { + + if (first < last) { + int q = xPartition(a, first, last); // pivot + xQuickSort(a, first, q - 1); // Left + xQuickSort(a, q + 1, last); // Right + } + } + + /** + * yQuickSort function: //y-axis Quick Sorting. + * + * @param a (IN Parameter) array of points
+ * @param first (IN Parameter) first point
+ * @param last (IN Parameter) last point
+ */ + public void yQuickSort(final Location[] a, final int first, final int last) { + + if (first < last) { + int q = yPartition(a, first, last); // pivot + yQuickSort(a, first, q - 1); // Left + yQuickSort(a, q + 1, last); // Right + } + } + + /** + * closestPair function: find closest pair. + * + * @param a (IN Parameter) array stored before divide
+ * @param indexNum (IN Parameter) number coordinates divideArray
+ * @return minimum distance
+ */ + public double closestPair(final Location[] a, final int indexNum) { + + Location[] divideArray = new Location[indexNum]; + System.arraycopy(a, 0, divideArray, 0, indexNum); // Copy previous array + int divideX = indexNum / 2; // Intermediate value for divide + Location[] leftArray = new Location[divideX]; // divide - left array + // divide-right array + Location[] rightArray = new Location[indexNum - divideX]; + if (indexNum <= 3) { // If the number of coordinates is 3 or less + return bruteForce(divideArray); + } + // divide-left array + System.arraycopy(divideArray, 0, leftArray, 0, divideX); + // divide-right array + System.arraycopy(divideArray, divideX, rightArray, 0, indexNum - divideX); + + double minLeftArea; // Minimum length of left array + double minRightArea; // Minimum length of right array + double minValue; // Minimum lengt + + minLeftArea = closestPair(leftArray, divideX); // recursive closestPair + minRightArea = closestPair(rightArray, indexNum - divideX); + // window size (= minimum length) + minValue = Math.min(minLeftArea, minRightArea); + + // Create window. Set the size for creating a window + // and creating a new array for the coordinates in the window + for (int i = 0; i < indexNum; i++) { + double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x); + if (xGap < minValue) { + ClosestPair.setSecondCount(secondCount + 1); // size of the array + } else { + if (divideArray[i].x > divideArray[divideX].x) { + break; + } + } + } + // new array for coordinates in window + Location[] firstWindow = new Location[secondCount]; + int k = 0; + for (int i = 0; i < indexNum; i++) { + double xGap = Math.abs(divideArray[divideX].x - divideArray[i].x); + if (xGap < minValue) { // if it's inside a window + firstWindow[k] = divideArray[i]; // put in an array + k++; + } else { + if (divideArray[i].x > divideArray[divideX].x) { + break; + } + } + } + yQuickSort(firstWindow, 0, secondCount - 1); // Sort by y coordinates + /* Coordinates in Window */ + double length; + // size comparison within window + for (int i = 0; i < secondCount - 1; i++) { + for (int j = (i + 1); j < secondCount; j++) { + double xGap = Math.abs(firstWindow[i].x - firstWindow[j].x); + double yGap = Math.abs(firstWindow[i].y - firstWindow[j].y); + if (yGap < minValue) { + length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2)); + // If measured distance is less than current min distance + if (length < minValue) { + // Change minimum distance to current distance + minValue = length; + // Conditional for registering final coordinate + if (length < minNum) { + ClosestPair.setMinNum(length); + point1 = firstWindow[i]; + point2 = firstWindow[j]; + } + } + } else { + break; + } + } + } + ClosestPair.setSecondCount(0); + return minValue; + } + + /** + * bruteForce function: When the number of coordinates is less than 3. + * + * @param arrayParam (IN Parameter) array stored before divide
+ * @return
+ */ + public double bruteForce(final Location[] arrayParam) { + + double minValue = Double.MAX_VALUE; // minimum distance + double length; + double xGap; // Difference between x coordinates + double yGap; // Difference between y coordinates + double result = 0; + + if (arrayParam.length == 2) { + // Difference between x coordinates + xGap = (arrayParam[0].x - arrayParam[1].x); + // Difference between y coordinates + yGap = (arrayParam[0].y - arrayParam[1].y); + // distance between coordinates + length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2)); + // Conditional statement for registering final coordinate + if (length < minNum) { + ClosestPair.setMinNum(length); + } + point1 = arrayParam[0]; + point2 = arrayParam[1]; + result = length; + } + if (arrayParam.length == 3) { + for (int i = 0; i < arrayParam.length - 1; i++) { + for (int j = (i + 1); j < arrayParam.length; j++) { + // Difference between x coordinates + xGap = (arrayParam[i].x - arrayParam[j].x); + // Difference between y coordinates + yGap = (arrayParam[i].y - arrayParam[j].y); + // distance between coordinates + length = Math.sqrt(Math.pow(xGap, 2) + Math.pow(yGap, 2)); + // If measured distance is less than current min distance + if (length < minValue) { + // Change minimum distance to current distance + minValue = length; + if (length < minNum) { + // Registering final coordinate + ClosestPair.setMinNum(length); + point1 = arrayParam[i]; + point2 = arrayParam[j]; + } + } + } + } + result = minValue; + } + return result; // If only one point returns 0. + } + + /** + * main function: execute class. + * + * @param args (IN Parameter)
+ */ + public static void main(final String[] args) { + + // Input data consists of one x-coordinate and one y-coordinate + ClosestPair cp = new ClosestPair(12); + cp.array[0] = cp.buildLocation(2, 3); + cp.array[1] = cp.buildLocation(2, 16); + cp.array[2] = cp.buildLocation(3, 9); + cp.array[3] = cp.buildLocation(6, 3); + cp.array[4] = cp.buildLocation(7, 7); + cp.array[5] = cp.buildLocation(19, 4); + cp.array[6] = cp.buildLocation(10, 11); + cp.array[7] = cp.buildLocation(15, 2); + cp.array[8] = cp.buildLocation(15, 19); + cp.array[9] = cp.buildLocation(16, 11); + cp.array[10] = cp.buildLocation(17, 13); + cp.array[11] = cp.buildLocation(9, 12); + + System.out.println("Input data"); + System.out.println("Number of points: " + cp.array.length); + for (int i = 0; i < cp.array.length; i++) { + System.out.println("x: " + cp.array[i].x + ", y: " + cp.array[i].y); + } + + cp.xQuickSort(cp.array, 0, cp.array.length - 1); // Sorting by x value + + double result; // minimum distance + + result = cp.closestPair(cp.array, cp.array.length); + // ClosestPair start + // minimum distance coordinates and distance output + System.out.println("Output Data"); + System.out.println("(" + cp.point1.x + ", " + cp.point1.y + ")"); + System.out.println("(" + cp.point2.x + ", " + cp.point2.y + ")"); + System.out.println("Minimum Distance : " + result); + } +} diff --git a/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java b/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java new file mode 100644 index 000000000000..def2731ac7db --- /dev/null +++ b/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java @@ -0,0 +1,186 @@ +package com.thealgorithms.divideandconquer; + +import java.util.ArrayList; +import java.util.Comparator; + +/** + * @author dimgrichr + *

+ * Space complexity: O(n) Time complexity: O(nlogn), because it is a divide and + * conquer algorithm + */ +public class SkylineAlgorithm { + + private ArrayList points; + + /** + * Main constructor of the application. ArrayList points gets created, which + * represents the sum of all edges. + */ + public SkylineAlgorithm() { + points = new ArrayList<>(); + } + + /** + * @return points, the ArrayList that includes all points. + */ + public ArrayList getPoints() { + return points; + } + + /** + * The main divide and conquer, and also recursive algorithm. It gets an + * ArrayList full of points as an argument. If the size of that ArrayList is + * 1 or 2, the ArrayList is returned as it is, or with one less point (if + * the initial size is 2 and one of it's points, is dominated by the other + * one). On the other hand, if the ArrayList's size is bigger than 2, the + * function is called again, twice, with arguments the corresponding half of + * the initial ArrayList each time. Once the flashback has ended, the + * function produceFinalSkyLine gets called, in order to produce the final + * skyline, and return it. + * + * @param list, the initial list of points + * @return leftSkyLine, the combination of first half's and second half's + * skyline + * @see Point + */ + public ArrayList produceSubSkyLines(ArrayList list) { + + // part where function exits flashback + int size = list.size(); + if (size == 1) { + return list; + } else if (size == 2) { + if (list.get(0).dominates(list.get(1))) { + list.remove(1); + } else { + if (list.get(1).dominates(list.get(0))) { + list.remove(0); + } + } + return list; + } + + // recursive part of the function + ArrayList leftHalf = new ArrayList<>(); + ArrayList rightHalf = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + if (i < list.size() / 2) { + leftHalf.add(list.get(i)); + } else { + rightHalf.add(list.get(i)); + } + } + ArrayList leftSubSkyLine = produceSubSkyLines(leftHalf); + ArrayList rightSubSkyLine = produceSubSkyLines(rightHalf); + + // skyline is produced + return produceFinalSkyLine(leftSubSkyLine, rightSubSkyLine); + } + + /** + * The first half's skyline gets cleared from some points that are not part + * of the final skyline (Points with same x-value and different y=values. + * The point with the smallest y-value is kept). Then, the minimum y-value + * of the points of first half's skyline is found. That helps us to clear + * the second half's skyline, because, the points of second half's skyline + * that have greater y-value of the minimum y-value that we found before, + * are dominated, so they are not part of the final skyline. Finally, the + * "cleaned" first half's and second half's skylines, are combined, + * producing the final skyline, which is returned. + * + * @param left the skyline of the left part of points + * @param right the skyline of the right part of points + * @return left the final skyline + */ + public ArrayList produceFinalSkyLine(ArrayList left, ArrayList right) { + + // dominated points of ArrayList left are removed + for (int i = 0; i < left.size() - 1; i++) { + if (left.get(i).x == left.get(i + 1).x && left.get(i).y > left.get(i + 1).y) { + left.remove(i); + i--; + } + } + + // minimum y-value is found + int min = left.get(0).y; + for (int i = 1; i < left.size(); i++) { + if (min > left.get(i).y) { + min = left.get(i).y; + if (min == 1) { + i = left.size(); + } + } + } + + // dominated points of ArrayList right are removed + for (int i = 0; i < right.size(); i++) { + if (right.get(i).y >= min) { + right.remove(i); + i--; + } + } + + // final skyline found and returned + left.addAll(right); + return left; + } + + public static class Point { + + private int x; + private int y; + + /** + * The main constructor of Point Class, used to represent the 2 + * Dimension points. + * + * @param x the point's x-value. + * @param y the point's y-value. + */ + public Point(int x, int y) { + this.x = x; + this.y = y; + } + + /** + * @return x, the x-value + */ + public int getX() { + return x; + } + + /** + * @return y, the y-value + */ + public int getY() { + return y; + } + + /** + * Based on the skyline theory, it checks if the point that calls the + * function dominates the argument point. + * + * @param p1 the point that is compared + * @return true if the point wich calls the function dominates p1 false + * otherwise. + */ + public boolean dominates(Point p1) { + // checks if p1 is dominated + return (this.x < p1.x && this.y <= p1.y) || (this.x <= p1.x && this.y < p1.y); + } + } + + /** + * It is used to compare the 2 Dimension points, based on their x-values, in + * order get sorted later. + */ + class XComparator implements Comparator { + + @Override + public int compare(Point a, Point b) { + return Integer.compare(a.x, b.x); + } + } +} diff --git a/DivideAndConquer/StrassenMatrixMultiplication.java b/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java similarity index 73% rename from DivideAndConquer/StrassenMatrixMultiplication.java rename to src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java index 6bd48b524a1a..579ad4d517c0 100644 --- a/DivideAndConquer/StrassenMatrixMultiplication.java +++ b/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java @@ -1,23 +1,19 @@ -package DivideAndConquer; +package com.thealgorithms.divideandconquer; // Java Program to Implement Strassen Algorithm - // Class Strassen matrix multiplication public class StrassenMatrixMultiplication { - + // Method 1 // Function to multiply matrices - public int[][] multiply(int[][] A, int[][] B) - { + public int[][] multiply(int[][] A, int[][] B) { int n = A.length; int[][] R = new int[n][n]; - - if (n == 1) + if (n == 1) { R[0][0] = A[0][0] * B[0][0]; - - else { + } else { // Dividing Matrix into parts // by storing sub-parts to variables int[][] A11 = new int[n / 2][n / 2]; @@ -28,54 +24,53 @@ public int[][] multiply(int[][] A, int[][] B) int[][] B12 = new int[n / 2][n / 2]; int[][] B21 = new int[n / 2][n / 2]; int[][] B22 = new int[n / 2][n / 2]; - + // Dividing matrix A into 4 parts split(A, A11, 0, 0); split(A, A12, 0, n / 2); split(A, A21, n / 2, 0); split(A, A22, n / 2, n / 2); - + // Dividing matrix B into 4 parts split(B, B11, 0, 0); split(B, B12, 0, n / 2); split(B, B21, n / 2, 0); split(B, B22, n / 2, n / 2); - + // Using Formulas as described in algorithm - // M1:=(A1+A3)×(B1+B2) int[][] M1 - = multiply(add(A11, A22), add(B11, B22)); - + = multiply(add(A11, A22), add(B11, B22)); + // M2:=(A2+A4)×(B3+B4) int[][] M2 = multiply(add(A21, A22), B11); - + // M3:=(A1−A4)×(B1+A4) int[][] M3 = multiply(A11, sub(B12, B22)); - + // M4:=A1×(B2−B4) int[][] M4 = multiply(A22, sub(B21, B11)); - + // M5:=(A3+A4)×(B1) int[][] M5 = multiply(add(A11, A12), B22); - + // M6:=(A1+A2)×(B4) int[][] M6 - = multiply(sub(A21, A11), add(B11, B12)); - + = multiply(sub(A21, A11), add(B11, B12)); + // M7:=A4×(B3−B1) int[][] M7 - = multiply(sub(A12, A22), add(B21, B22)); - + = multiply(sub(A12, A22), add(B21, B22)); + // P:=M2+M3−M6−M7 int[][] C11 = add(sub(add(M1, M4), M5), M7); - + // Q:=M4+M6 int[][] C12 = add(M3, M5); - + // R:=M5+M7 int[][] C21 = add(M2, M4); - + // S:=M1−M3−M4−M5 int[][] C22 = add(sub(add(M1, M3), M2), M6); @@ -87,96 +82,98 @@ public int[][] multiply(int[][] A, int[][] B) return R; } - + // Method 2 // Function to subtract two matrices - public int[][] sub(int[][] A, int[][] B) - { + public int[][] sub(int[][] A, int[][] B) { int n = A.length; int[][] C = new int[n][n]; - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { C[i][j] = A[i][j] - B[i][j]; + } + } return C; } - + // Method 3 // Function to add two matrices - public int[][] add(int[][] A, int[][] B) - { + public int[][] add(int[][] A, int[][] B) { int n = A.length; int[][] C = new int[n][n]; - for (int i = 0; i < n; i++) - for (int j = 0; j < n; j++) + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { C[i][j] = A[i][j] + B[i][j]; + } + } return C; } - + // Method 4 // Function to split parent matrix // into child matrices - public void split(int[][] P, int[][] C, int iB, int jB) - { - for (int i1 = 0, i2 = iB; i1 < C.length; i1++, i2++) - for (int j1 = 0, j2 = jB; j1 < C.length; j1++, j2++) + public void split(int[][] P, int[][] C, int iB, int jB) { + for (int i1 = 0, i2 = iB; i1 < C.length; i1++, i2++) { + for (int j1 = 0, j2 = jB; j1 < C.length; j1++, j2++) { C[i1][j1] = P[i2][j2]; + } + } } - + // Method 5 // Function to join child matrices // into (to) parent matrix - public void join(int[][] C, int[][] P, int iB, int jB) - - { - for (int i1 = 0, i2 = iB; i1 < C.length; i1++, i2++) - for (int j1 = 0, j2 = jB; j1 < C.length; j1++, j2++) + public void join(int[][] C, int[][] P, int iB, int jB) { + for (int i1 = 0, i2 = iB; i1 < C.length; i1++, i2++) { + for (int j1 = 0, j2 = jB; j1 < C.length; j1++, j2++) { P[i2][j2] = C[i1][j1]; + } + } } - + // Method 5 // Main driver method - public static void main(String[] args) - { + public static void main(String[] args) { System.out.println("Strassen Multiplication Algorithm Implementation For Matrix Multiplication :\n"); StrassenMatrixMultiplication s = new StrassenMatrixMultiplication(); - + // Size of matrix // Considering size as 4 in order to illustrate int N = 4; - + // Matrix A // Custom input to matrix - int[][] A = { { 1, 2, 5, 4 }, - { 9, 3, 0, 6 }, - { 4, 6, 3, 1 }, - { 0, 2, 0, 6 } }; - + int[][] A = {{1, 2, 5, 4}, + {9, 3, 0, 6}, + {4, 6, 3, 1}, + {0, 2, 0, 6}}; + // Matrix B // Custom input to matrix - int[][] B = { { 1, 0, 4, 1 }, - { 1, 2, 0, 2 }, - { 0, 3, 1, 3 }, - { 1, 8, 1, 2 } }; - + int[][] B = {{1, 0, 4, 1}, + {1, 2, 0, 2}, + {0, 3, 1, 3}, + {1, 8, 1, 2}}; + // Matrix C computations - // Matrix C calling method to get Result int[][] C = s.multiply(A, B); - + System.out.println("\nProduct of matrices A and B : "); - + // Print the output for (int i = 0; i < N; i++) { - for (int j = 0; j < N; j++) + for (int j = 0; j < N; j++) { System.out.print(C[i][j] + " "); + } System.out.println(); } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java b/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java new file mode 100644 index 000000000000..dfb75717b970 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java @@ -0,0 +1,83 @@ +package com.thealgorithms.dynamicprogramming; + +/* +* this is an important Algo in which +* we have starting and ending of board and we have to reach +* we have to count no. of ways +* that help to reach end point i.e number by rolling dice +* which have 1 to 6 digits + +Test Case: +here target is 10 + +int n=10; + startAlgo(); + System.out.println(bpR(0,n)); + System.out.println(endAlgo()+"ms"); + int[] strg=new int [n+1]; + startAlgo(); + System.out.println(bpRS(0,n,strg)); + System.out.println(endAlgo()+"ms"); + startAlgo(); + System.out.println(bpIS(0,n,strg)); + System.out.println(endAlgo()+"ms"); + + + + */ +public class BoardPath { + + public static long startTime; + public static long endTime; + + public static void startAlgo() { + startTime = System.currentTimeMillis(); + } + + public static long endAlgo() { + endTime = System.currentTimeMillis(); + return endTime - startTime; + } + + public static int bpR(int start, int end) { + if (start == end) { + return 1; + } else if (start > end) { + return 0; + } + int count = 0; + for (int dice = 1; dice <= 6; dice++) { + count += bpR(start + dice, end); + } + return count; + } + + public static int bpRS(int curr, int end, int strg[]) { + if (curr == end) { + return 1; + } else if (curr > end) { + return 0; + } + if (strg[curr] != 0) { + return strg[curr]; + } + int count = 0; + for (int dice = 1; dice <= 6; dice++) { + count += bpRS(curr + dice, end, strg); + } + strg[curr] = count; + return count; + } + + public static int bpIS(int curr, int end, int[] strg) { + strg[end] = 1; + for (int i = end - 1; i >= 0; i--) { + int count = 0; + for (int dice = 1; dice <= 6 && dice + i < strg.length; dice++) { + count += strg[i + dice]; + } + strg[i] = count; + } + return strg[0]; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java new file mode 100644 index 000000000000..b4c9875427cb --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java @@ -0,0 +1,44 @@ +package com.thealgorithms.dynamicprogramming; + +/* A Naive recursive implementation +of 0-1 Knapsack problem */ +public class BruteForceKnapsack { + + // A utility function that returns + // maximum of two integers + static int max(int a, int b) { + return (a > b) ? a : b; + } + + // Returns the maximum value that + // can be put in a knapsack of + // capacity W + static int knapSack(int W, int wt[], int val[], int n) { + // Base Case + if (n == 0 || W == 0) { + return 0; + } + + // If weight of the nth item is + // more than Knapsack capacity W, + // then this item cannot be included + // in the optimal solution + if (wt[n - 1] > W) { + return knapSack(W, wt, val, n - 1); + } // Return the maximum of two cases: + // (1) nth item included + // (2) not included + else { + return max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1), knapSack(W, wt, val, n - 1)); + } + } + + // Driver code + public static void main(String args[]) { + int val[] = new int[]{60, 100, 120}; + int wt[] = new int[]{10, 20, 30}; + int W = 50; + int n = val.length; + System.out.println(knapSack(W, wt, val, n)); + } +} diff --git a/DynamicProgramming/CatalanNumber.java b/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java similarity index 50% rename from DynamicProgramming/CatalanNumber.java rename to src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java index 156654cecad3..8f7d9c779b5f 100644 --- a/DynamicProgramming/CatalanNumber.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java @@ -1,29 +1,27 @@ -package DynamicProgramming; +package com.thealgorithms.dynamicprogramming; /** - * This file contains an implementation of finding the nth CATALAN NUMBER using dynamic programming - * Wikipedia: https://en.wikipedia.org/wiki/Catalan_number - * - * Time Complexity: O(n^2) - * Space Complexity: O(n) - * - * @author AMRITESH ANAND (https://github.com/amritesh19) + * This file contains an implementation of finding the nth CATALAN NUMBER using + * dynamic programming Wikipedia: https://en.wikipedia.org/wiki/Catalan_number + * + * Time Complexity: O(n^2) Space Complexity: O(n) + * + * @author AMRITESH ANAND (https://github.com/amritesh19) */ - import java.util.Scanner; public class CatalanNumber { - /** - * This method finds the nth Catalan number - * - * @param n input n which determines the nth Catalan number - * n should be less than equal to 50 as 50th Catalan number is 6,533,841,209,031,609,592 - * for n > 50, BigInteger class should be used instead long - * - * @return catalanArray[n] the nth Catalan number - */ - static long findNthCatalan(int n){ + /** + * This method finds the nth Catalan number + * + * @param n input n which determines the nth Catalan number n should be less + * than equal to 50 as 50th Catalan number is 6,533,841,209,031,609,592 for + * n > 50, BigInteger class should be used instead long + * + * @return catalanArray[n] the nth Catalan number + */ + static long findNthCatalan(int n) { // Array to store the results of subproblems i.e Catalan numbers from [1...n-1] long catalanArray[] = new long[n + 1]; @@ -33,12 +31,12 @@ static long findNthCatalan(int n){ catalanArray[1] = 1; /** - * The Catalan numbers satisfy the recurrence relation - * C₀=1 and Cn = Σ (Ci * Cn-1-i), i = 0 to n-1 , n > 0 - */ - for(int i = 2; i <= n; i++){ + * The Catalan numbers satisfy the recurrence relation C₀=1 and Cn = Σ + * (Ci * Cn-1-i), i = 0 to n-1 , n > 0 + */ + for (int i = 2; i <= n; i++) { catalanArray[i] = 0; - for(int j = 0; j < i; j++){ + for (int j = 0; j < i; j++) { catalanArray[i] += catalanArray[j] * catalanArray[i - j - 1]; } } @@ -53,8 +51,7 @@ public static void main(String[] args) { System.out.println("Enter the number n to find nth Catalan number (n <= 50)"); int n = sc.nextInt(); System.out.println(n + "th Catalan number is " + findNthCatalan(n)); - + sc.close(); } } - diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java b/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java new file mode 100644 index 000000000000..40aba3d9ea7c --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java @@ -0,0 +1,85 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +public class CoinChange { + + // Driver Program + public static void main(String[] args) { + + int amount = 12; + int[] coins = {2, 4, 5}; + + System.out.println( + "Number of combinations of getting change for " + amount + " is: " + change(coins, amount)); + System.out.println( + "Minimum number of coins required for amount :" + + amount + + " is: " + + minimumCoins(coins, amount)); + } + + /** + * This method finds the number of combinations of getting change for a + * given amount and change coins + * + * @param coins The list of coins + * @param amount The amount for which we need to find the change Finds the + * number of combinations of change + */ + public static int change(int[] coins, int amount) { + + int[] combinations = new int[amount + 1]; + combinations[0] = 1; + + for (int coin : coins) { + for (int i = coin; i < amount + 1; i++) { + combinations[i] += combinations[i - coin]; + } + // Uncomment the below line to see the state of combinations for each coin + // printAmount(combinations); + } + + return combinations[amount]; + } + + /** + * This method finds the minimum number of coins needed for a given amount. + * + * @param coins The list of coins + * @param amount The amount for which we need to find the minimum number of + * coins. Finds the the minimum number of coins that make a given value. + */ + public static int minimumCoins(int[] coins, int amount) { + // minimumCoins[i] will store the minimum coins needed for amount i + int[] minimumCoins = new int[amount + 1]; + + minimumCoins[0] = 0; + + for (int i = 1; i <= amount; i++) { + minimumCoins[i] = Integer.MAX_VALUE; + } + for (int i = 1; i <= amount; i++) { + for (int coin : coins) { + if (coin <= i) { + int sub_res = minimumCoins[i - coin]; + if (sub_res != Integer.MAX_VALUE && sub_res + 1 < minimumCoins[i]) { + minimumCoins[i] = sub_res + 1; + } + } + } + } + // Uncomment the below line to see the state of combinations for each coin + // printAmount(minimumCoins); + return minimumCoins[amount]; + } + + // A basic print method which prints all the contents of the array + public static void printAmount(int[] arr) { + for (int i = 0; i < arr.length; i++) { + System.out.print(arr[i] + " "); + } + System.out.println(); + } +} diff --git a/DynamicProgramming/DiceThrow.java b/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java similarity index 58% rename from DynamicProgramming/DiceThrow.java rename to src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java index 415f4a63c9cc..fd272f8e5779 100644 --- a/DynamicProgramming/DiceThrow.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java @@ -1,54 +1,53 @@ -package DynamicProgramming; +package com.thealgorithms.dynamicprogramming; // Given N dice each with M faces, numbered from 1 to M, find the number of ways to get sum X. // X is the summation of values on each face when all the dice are thrown. /* The Naive approach is to find all the possible combinations of values from n dice and keep on counting the results that sum to X. This can be done using recursion. */ - // The above recursion solution exhibits overlapping subproblems. /* Hence, storing the results of the solved sub-problems saves time. And it can be done using Dynamic Programming(DP). Following is implementation of Dynamic Programming approach. */ - - // Code ----> // Java program to find number of ways to get sum 'x' with 'n' // dice where every dice has 'm' faces - class DP { + /* The main function that returns the number of ways to get sum 'x' with 'n' dice and 'm' with m faces. */ - public static long findWays(int m, int n, int x){ - - /* Create a table to store the results of subproblems. + public static long findWays(int m, int n, int x) { + + /* Create a table to store the results of subproblems. One extra row and column are used for simplicity (Number of dice is directly used as row index and sum is directly used as column index). The entries in 0th row and 0th column are never used. */ - long[][] table = new long[n+1][x+1]; - - /* Table entries for only one dice */ - for(int j = 1; j <= m && j <= x; j++) - table[1][j] = 1; - - /* Fill rest of the entries in table using recursive relation + long[][] table = new long[n + 1][x + 1]; + + /* Table entries for only one dice */ + for (int j = 1; j <= m && j <= x; j++) { + table[1][j] = 1; + } + + /* Fill rest of the entries in table using recursive relation i: number of dice, j: sum */ - for(int i = 2; i <= n;i ++){ - for(int j = 1; j <= x; j++){ - for(int k = 1; k < j && k <= m; k++) - table[i][j] += table[i-1][j-k]; + for (int i = 2; i <= n; i++) { + for (int j = 1; j <= x; j++) { + for (int k = 1; k < j && k <= m; k++) { + table[i][j] += table[i - 1][j - k]; } + } } - + return table[n][x]; } - - public static void main (String[] args) { - System.out.println(findWays(4, 2, 1)); - System.out.println(findWays(2, 2, 3)); - System.out.println(findWays(6, 3, 8)); - System.out.println(findWays(4, 2, 5)); - System.out.println(findWays(4, 3, 5)); + + public static void main(String[] args) { + System.out.println(findWays(4, 2, 1)); + System.out.println(findWays(2, 2, 3)); + System.out.println(findWays(6, 3, 8)); + System.out.println(findWays(4, 2, 5)); + System.out.println(findWays(4, 3, 5)); } } @@ -59,7 +58,6 @@ public static void main (String[] args) { 21 4 6 -*/ - + */ // Time Complexity: O(m * n * x) where m is number of faces, n is number of dice and x is given sum. diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java new file mode 100644 index 000000000000..6f4df8f634d4 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/DyanamicProgrammingKnapsack.java @@ -0,0 +1,41 @@ +package com.thealgorithms.dynamicprogramming; + +// A Dynamic Programming based solution +// for 0-1 Knapsack problem +public class DyanamicProgrammingKnapsack { + + static int max(int a, int b) { + return (a > b) ? a : b; + } + + // Returns the maximum value that can + // be put in a knapsack of capacity W + static int knapSack(int W, int wt[], int val[], int n) { + int i, w; + int K[][] = new int[n + 1][W + 1]; + + // Build table K[][] in bottom up manner + for (i = 0; i <= n; i++) { + for (w = 0; w <= W; w++) { + if (i == 0 || w == 0) { + K[i][w] = 0; + } else if (wt[i - 1] <= w) { + K[i][w] = max(val[i - 1] + K[i - 1][w - wt[i - 1]], K[i - 1][w]); + } else { + K[i][w] = K[i - 1][w]; + } + } + } + + return K[n][W]; + } + + // Driver code + public static void main(String args[]) { + int val[] = new int[]{60, 100, 120}; + int wt[] = new int[]{10, 20, 30}; + int W = 50; + int n = val.length; + System.out.println(knapSack(W, wt, val, n)); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java b/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java new file mode 100644 index 000000000000..b99d016c0a27 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java @@ -0,0 +1,120 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * A DynamicProgramming based solution for Edit Distance problem In Java + * Description of Edit Distance with an Example: + * + *

+ * Edit distance is a way of quantifying how dissimilar two strings (e.g., + * words) are to one another, by counting the minimum number of operations + * required to transform one string into the other. The distance operations are + * the removal, insertion, or substitution of a character in the string. + * + *

+ * + *

+ * The Distance between "kitten" and "sitting" is 3. A minimal edit script that + * transforms the former into the latter is: + * + *

+ * kitten → sitten (substitution of "s" for "k") sitten → sittin (substitution + * of "i" for "e") sittin → sitting (insertion of "g" at the end). + * + * @author SUBHAM SANGHAI + */ +import java.util.Scanner; + +public class EditDistance { + + public static int minDistance(String word1, String word2) { + int len1 = word1.length(); + int len2 = word2.length(); + // len1+1, len2+1, because finally return dp[len1][len2] + int[][] dp = new int[len1 + 1][len2 + 1]; + /* If second string is empty, the only option is to + insert all characters of first string into second*/ + for (int i = 0; i <= len1; i++) { + dp[i][0] = i; + } + /* If first string is empty, the only option is to + insert all characters of second string into first*/ + for (int j = 0; j <= len2; j++) { + dp[0][j] = j; + } + // iterate though, and check last char + for (int i = 0; i < len1; i++) { + char c1 = word1.charAt(i); + for (int j = 0; j < len2; j++) { + char c2 = word2.charAt(j); + // if last two chars equal + if (c1 == c2) { + // update dp value for +1 length + dp[i + 1][j + 1] = dp[i][j]; + } else { + /* if two characters are different , + then take the minimum of the various operations(i.e insertion,removal,substitution)*/ + int replace = dp[i][j] + 1; + int insert = dp[i][j + 1] + 1; + int delete = dp[i + 1][j] + 1; + + int min = replace > insert ? insert : replace; + min = delete > min ? min : delete; + dp[i + 1][j + 1] = min; + } + } + } + /* return the final answer , after traversing through both the strings*/ + return dp[len1][len2]; + } + + public static void main(String[] args) { + Scanner input = new Scanner(System.in); + String s1, s2; + System.out.println("Enter the First String"); + s1 = input.nextLine(); + System.out.println("Enter the Second String"); + s2 = input.nextLine(); + // ans stores the final Edit Distance between the two strings + int ans = minDistance(s1, s2); + System.out.println( + "The minimum Edit Distance between \"" + s1 + "\" and \"" + s2 + "\" is " + ans); + input.close(); + } + + // edit distance problem + public static int editDistance(String s1, String s2) { + int[][] storage = new int[s1.length() + 1][s2.length() + 1]; + return editDistance(s1, s2, storage); + + } + + public static int editDistance(String s1, String s2, int[][] storage) { + int m = s1.length(); + int n = s2.length(); + if (storage[m][n] > 0) { + return storage[m][n]; + + } + if (m == 0) { + storage[m][n] = n; + return storage[m][n]; + + } + if (n == 0) { + storage[m][n] = m; + return storage[m][n]; + + } + if (s1.charAt(0) == s2.charAt(0)) { + storage[m][n] = editDistance(s1.substring(1), s2.substring(1), storage); + return storage[m][n]; + + } else { + int op1 = editDistance(s1, s2.substring(1), storage); + int op2 = editDistance(s1.substring(1), s2, storage); + int op3 = editDistance(s1.substring(1), s2.substring(1), storage); + storage[m][n] = 1 + Math.min(op1, Math.min(op2, op3)); + return storage[m][n]; + } + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java b/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java new file mode 100644 index 000000000000..4bcca33e7c33 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java @@ -0,0 +1,48 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * DynamicProgramming solution for the Egg Dropping Puzzle + */ +public class EggDropping { + + // min trials with n eggs and m floors + private static int minTrials(int n, int m) { + + int[][] eggFloor = new int[n + 1][m + 1]; + int result, x; + + for (int i = 1; i <= n; i++) { + eggFloor[i][0] = 0; // Zero trial for zero floor. + eggFloor[i][1] = 1; // One trial for one floor + } + + // j trials for only 1 egg + for (int j = 1; j <= m; j++) { + eggFloor[1][j] = j; + } + + // Using bottom-up approach in DP + for (int i = 2; i <= n; i++) { + for (int j = 2; j <= m; j++) { + eggFloor[i][j] = Integer.MAX_VALUE; + for (x = 1; x <= j; x++) { + result = 1 + Math.max(eggFloor[i - 1][x - 1], eggFloor[i][j - x]); + + // choose min of all values for particular x + if (result < eggFloor[i][j]) { + eggFloor[i][j] = result; + } + } + } + } + + return eggFloor[n][m]; + } + + public static void main(String args[]) { + int n = 2, m = 4; + // result outputs min no. of trials in worst case for n eggs and m floors + int result = minTrials(n, m); + System.out.println(result); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java b/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java new file mode 100644 index 000000000000..ac97ba004197 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java @@ -0,0 +1,96 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +public class Fibonacci { + + private static Map map = new HashMap<>(); + + public static void main(String[] args) { + + // Methods all returning [0, 1, 1, 2, 3, 5, ...] for n = [0, 1, 2, 3, 4, 5, ...] + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + + System.out.println(fibMemo(n)); + System.out.println(fibBotUp(n)); + System.out.println(fibOptimized(n)); + sc.close(); + } + + /** + * This method finds the nth fibonacci number using memoization technique + * + * @param n The input n for which we have to determine the fibonacci number + * Outputs the nth fibonacci number + */ + public static int fibMemo(int n) { + if (map.containsKey(n)) { + return map.get(n); + } + + int f; + + if (n <= 1) { + f = n; + } else { + f = fibMemo(n - 1) + fibMemo(n - 2); + map.put(n, f); + } + return f; + } + + /** + * This method finds the nth fibonacci number using bottom up + * + * @param n The input n for which we have to determine the fibonacci number + * Outputs the nth fibonacci number + */ + public static int fibBotUp(int n) { + + Map fib = new HashMap<>(); + + for (int i = 0; i <= n; i++) { + int f; + if (i <= 1) { + f = i; + } else { + f = fib.get(i - 1) + fib.get(i - 2); + } + fib.put(i, f); + } + + return fib.get(n); + } + + /** + * This method finds the nth fibonacci number using bottom up + * + * @param n The input n for which we have to determine the fibonacci number + * Outputs the nth fibonacci number + *

+ * This is optimized version of Fibonacci Program. Without using Hashmap and + * recursion. It saves both memory and time. Space Complexity will be O(1) + * Time Complexity will be O(n) + *

+ * Whereas , the above functions will take O(n) Space. + * @author Shoaib Rayeen (https://github.com/shoaibrayeen) + */ + public static int fibOptimized(int n) { + if (n == 0) { + return 0; + } + int prev = 0, res = 1, next; + for (int i = 2; i <= n; i++) { + next = prev + res; + prev = res; + res = next; + } + return res; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java b/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java new file mode 100644 index 000000000000..63ec477c4590 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java @@ -0,0 +1,76 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.LinkedList; +import java.util.Queue; +import java.util.Vector; + +public class FordFulkerson { + + static final int INF = 987654321; + // edges + static int V; + static int[][] capacity, flow; + + public static void main(String[] args) { + System.out.println("V : 6"); + V = 6; + capacity = new int[V][V]; + + capacity[0][1] = 12; + capacity[0][3] = 13; + capacity[1][2] = 10; + capacity[2][3] = 13; + capacity[2][4] = 3; + capacity[2][5] = 15; + capacity[3][2] = 7; + capacity[3][4] = 15; + capacity[4][5] = 17; + + System.out.println("Max capacity in networkFlow : " + networkFlow(0, 5)); + } + + private static int networkFlow(int source, int sink) { + flow = new int[V][V]; + int totalFlow = 0; + while (true) { + Vector parent = new Vector<>(V); + for (int i = 0; i < V; i++) { + parent.add(-1); + } + Queue q = new LinkedList<>(); + parent.set(source, source); + q.add(source); + while (!q.isEmpty() && parent.get(sink) == -1) { + int here = q.peek(); + q.poll(); + for (int there = 0; there < V; ++there) { + if (capacity[here][there] - flow[here][there] > 0 && parent.get(there) == -1) { + q.add(there); + parent.set(there, here); + } + } + } + if (parent.get(sink) == -1) { + break; + } + + int amount = INF; + String printer = "path : "; + StringBuilder sb = new StringBuilder(); + for (int p = sink; p != source; p = parent.get(p)) { + amount = Math.min(capacity[parent.get(p)][p] - flow[parent.get(p)][p], amount); + sb.append(p + "-"); + } + sb.append(source); + for (int p = sink; p != source; p = parent.get(p)) { + flow[parent.get(p)][p] += amount; + flow[p][parent.get(p)] -= amount; + } + totalFlow += amount; + printer += sb.reverse() + " / max flow : " + totalFlow; + System.out.println(printer); + } + + return totalFlow; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java b/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java new file mode 100644 index 000000000000..364d16a3e9f5 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java @@ -0,0 +1,54 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Scanner; + +/** + * Program to implement Kadane’s Algorithm to calculate maximum contiguous + * subarray sum of an array Time Complexity: O(n) + * + * @author Nishita Aggarwal + */ +public class KadaneAlgorithm { + + /** + * This method implements Kadane's Algorithm + * + * @param arr The input array + * @return The maximum contiguous subarray sum of the array + */ + static int largestContiguousSum(int arr[]) { + int i, len = arr.length, cursum = 0, maxsum = Integer.MIN_VALUE; + if (len == 0) // empty array + { + return 0; + } + for (i = 0; i < len; i++) { + cursum += arr[i]; + if (cursum > maxsum) { + maxsum = cursum; + } + if (cursum <= 0) { + cursum = 0; + } + } + return maxsum; + } + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n, arr[], i; + n = sc.nextInt(); + arr = new int[n]; + for (i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + int maxContSum = largestContiguousSum(arr); + System.out.println(maxContSum); + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java new file mode 100644 index 000000000000..c4d990e4fb58 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java @@ -0,0 +1,38 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * A DynamicProgramming based solution for 0-1 Knapsack problem + */ +public class Knapsack { + + private static int knapSack(int W, int wt[], int val[], int n) throws IllegalArgumentException { + if (wt == null || val == null) { + throw new IllegalArgumentException(); + } + int i, w; + int rv[][] = new int[n + 1][W + 1]; // rv means return value + + // Build table rv[][] in bottom up manner + for (i = 0; i <= n; i++) { + for (w = 0; w <= W; w++) { + if (i == 0 || w == 0) { + rv[i][w] = 0; + } else if (wt[i - 1] <= w) { + rv[i][w] = Math.max(val[i - 1] + rv[i - 1][w - wt[i - 1]], rv[i - 1][w]); + } else { + rv[i][w] = rv[i - 1][w]; + } + } + } + + return rv[n][W]; + } + + // Driver program to test above function + public static void main(String args[]) { + int val[] = new int[]{50, 100, 130}; + int wt[] = new int[]{10, 20, 40}; + int W = 50; + System.out.println(knapSack(W, wt, val, val.length)); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java new file mode 100644 index 000000000000..d2e2e9c045fc --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java @@ -0,0 +1,51 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + +/** + * Recursive Solution for 0-1 knapsack with memoization + */ +public class KnapsackMemoization { + + private static int[][] t; + + // Returns the maximum value that can + // be put in a knapsack of capacity W + public static int knapsack(int[] wt, int[] value, int W, int n) { + if (t[n][W] != -1) { + return t[n][W]; + } + if (n == 0 || W == 0) { + return 0; + } + if (wt[n - 1] <= W) { + t[n - 1][W - wt[n - 1]] = knapsack(wt, value, W - wt[n - 1], n - 1); + // Include item in the bag. In that case add the value of the item and call for the remaining items + int tmp1 = value[n - 1] + t[n - 1][W - wt[n - 1]]; + // Don't include the nth item in the bag anl call for remaining item without reducing the weight + int tmp2 = knapsack(wt, value, W, n - 1); + t[n - 1][W] = tmp2; + // include the larger one + int tmp = tmp1 > tmp2 ? tmp1 : tmp2; + t[n][W] = tmp; + return tmp; + // If Weight for the item is more than the desired weight then don't include it + // Call for rest of the n-1 items + } else if (wt[n - 1] > W) { + t[n][W] = knapsack(wt, value, W, n - 1); + return t[n][W]; + } + return -1; + } + + // Driver code + public static void main(String args[]) { + int[] wt = {1, 3, 4, 5}; + int[] value = {1, 4, 5, 7}; + int W = 10; + t = new int[wt.length + 1][W + 1]; + Arrays.stream(t).forEach(a -> Arrays.fill(a, -1)); + int res = knapsack(wt, value, W, wt.length); + System.out.println("Maximum knapsack value " + res); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java b/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java new file mode 100644 index 000000000000..be36d9535064 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java @@ -0,0 +1,53 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * @author Kshitij VERMA (github.com/kv19971) LEVENSHTEIN DISTANCE dyamic + * programming implementation to show the difference between two strings + * (https://en.wikipedia.org/wiki/Levenshtein_distance) + */ +public class LevenshteinDistance { + + private static int minimum(int a, int b, int c) { + if (a < b && a < c) { + return a; + } else if (b < a && b < c) { + return b; + } else { + return c; + } + } + + private static int calculate_distance(String a, String b) { + int len_a = a.length() + 1; + int len_b = b.length() + 1; + int[][] distance_mat = new int[len_a][len_b]; + for (int i = 0; i < len_a; i++) { + distance_mat[i][0] = i; + } + for (int j = 0; j < len_b; j++) { + distance_mat[0][j] = j; + } + for (int i = 0; i < len_a; i++) { + for (int j = 0; j < len_b; j++) { + int cost; + if (a.charAt(i) == b.charAt(j)) { + cost = 0; + } else { + cost = 1; + } + distance_mat[i][j] + = minimum(distance_mat[i - 1][j], distance_mat[i - 1][j - 1], distance_mat[i][j - 1]) + + cost; + } + } + return distance_mat[len_a - 1][len_b - 1]; + } + + public static void main(String[] args) { + String a = ""; // enter your string here + String b = ""; // enter your string here + + System.out.print("Levenshtein distance between " + a + " and " + b + " is: "); + System.out.println(calculate_distance(a, b)); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java new file mode 100644 index 000000000000..47e55eceb8cb --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java @@ -0,0 +1,70 @@ +package com.thealgorithms.dynamicprogramming; + +/* + + * Problem Statement: - + * Find Longest Alternating Subsequence + + * A sequence {x1, x2, .. xn} is alternating sequence if its elements satisfy one of the following relations : + + x1 < x2 > x3 < x4 > x5 < …. xn or + x1 > x2 < x3 > x4 < x5 > …. xn + */ +public class LongestAlternatingSubsequence { + + /* Function to return longest alternating subsequence length*/ + static int AlternatingLength(int arr[], int n) { + /* + + las[i][0] = Length of the longest + alternating subsequence ending at + index i and last element is + greater than its previous element + + las[i][1] = Length of the longest + alternating subsequence ending at + index i and last element is + smaller than its previous + element + + */ + int las[][] = new int[n][2]; // las = LongestAlternatingSubsequence + + for (int i = 0; i < n; i++) { + las[i][0] = las[i][1] = 1; + } + + int result = 1; // Initialize result + + /* Compute values in bottom up manner */ + for (int i = 1; i < n; i++) { + + /* Consider all elements as previous of arr[i]*/ + for (int j = 0; j < i; j++) { + + /* If arr[i] is greater, then check with las[j][1] */ + if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1) { + las[i][0] = las[j][1] + 1; + } + + /* If arr[i] is smaller, then check with las[j][0]*/ + if (arr[j] > arr[i] && las[i][1] < las[j][0] + 1) { + las[i][1] = las[j][0] + 1; + } + } + + /* Pick maximum of both values at index i */ + if (result < Math.max(las[i][0], las[i][1])) { + result = Math.max(las[i][0], las[i][1]); + } + } + + return result; + } + + public static void main(String[] args) { + int arr[] = {10, 22, 9, 33, 49, 50, 31, 60}; + int n = arr.length; + System.out.println("Length of Longest " + "alternating subsequence is " + AlternatingLength(arr, n)); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java new file mode 100644 index 000000000000..d28c0fe152e8 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java @@ -0,0 +1,72 @@ +package com.thealgorithms.dynamicprogramming; + +class LongestCommonSubsequence { + + public static String getLCS(String str1, String str2) { + + // At least one string is null + if (str1 == null || str2 == null) { + return null; + } + + // At least one string is empty + if (str1.length() == 0 || str2.length() == 0) { + return ""; + } + + String[] arr1 = str1.split(""); + String[] arr2 = str2.split(""); + + // lcsMatrix[i][j] = LCS of first i elements of arr1 and first j characters of arr2 + int[][] lcsMatrix = new int[arr1.length + 1][arr2.length + 1]; + + for (int i = 0; i < arr1.length + 1; i++) { + lcsMatrix[i][0] = 0; + } + for (int j = 1; j < arr2.length + 1; j++) { + lcsMatrix[0][j] = 0; + } + for (int i = 1; i < arr1.length + 1; i++) { + for (int j = 1; j < arr2.length + 1; j++) { + if (arr1[i - 1].equals(arr2[j - 1])) { + lcsMatrix[i][j] = lcsMatrix[i - 1][j - 1] + 1; + } else { + lcsMatrix[i][j] + = lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1] ? lcsMatrix[i - 1][j] : lcsMatrix[i][j - 1]; + } + } + } + return lcsString(str1, str2, lcsMatrix); + } + + public static String lcsString(String str1, String str2, int[][] lcsMatrix) { + StringBuilder lcs = new StringBuilder(); + int i = str1.length(), j = str2.length(); + while (i > 0 && j > 0) { + if (str1.charAt(i - 1) == str2.charAt(j - 1)) { + lcs.append(str1.charAt(i - 1)); + i--; + j--; + } else if (lcsMatrix[i - 1][j] > lcsMatrix[i][j - 1]) { + i--; + } else { + j--; + } + } + return lcs.reverse().toString(); + } + + public static void main(String[] args) { + String str1 = "DSGSHSRGSRHTRD"; + String str2 = "DATRGAGTSHS"; + String lcs = getLCS(str1, str2); + + // Print LCS + if (lcs != null) { + System.out.println("String 1: " + str1); + System.out.println("String 2: " + str2); + System.out.println("LCS: " + lcs); + System.out.println("LCS length: " + lcs.length()); + } + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java new file mode 100644 index 000000000000..ecf6ad6c41cc --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java @@ -0,0 +1,110 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Scanner; + +/** + * @author Afrizal Fikri (https://github.com/icalF) + */ +public class LongestIncreasingSubsequence { + + public static void main(String[] args) { + + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + + int arr[] = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + System.out.println(LIS(arr)); + System.out.println(findLISLen(arr)); + sc.close(); + } + + private static int upperBound(int[] ar, int l, int r, int key) { + while (l < r - 1) { + int m = (l + r) >>> 1; + if (ar[m] >= key) { + r = m; + } else { + l = m; + } + } + + return r; + } + + private static int LIS(int[] array) { + int N = array.length; + if (N == 0) { + return 0; + } + + int[] tail = new int[N]; + + // always points empty slot in tail + int length = 1; + + tail[0] = array[0]; + for (int i = 1; i < N; i++) { + + // new smallest value + if (array[i] < tail[0]) { + tail[0] = array[i]; + } // array[i] extends largest subsequence + else if (array[i] > tail[length - 1]) { + tail[length++] = array[i]; + } // array[i] will become end candidate of an existing subsequence or + // Throw away larger elements in all LIS, to make room for upcoming grater elements than + // array[i] + // (and also, array[i] would have already appeared in one of LIS, identify the location and + // replace it) + else { + tail[upperBound(tail, -1, length - 1, array[i])] = array[i]; + } + } + + return length; + } + + /** + * @author Alon Firestein (https://github.com/alonfirestein) + */ + // A function for finding the length of the LIS algorithm in O(nlogn) complexity. + public static int findLISLen(int a[]) { + int size = a.length; + int arr[] = new int[size]; + arr[0] = a[0]; + int lis = 1; + for (int i = 1; i < size; i++) { + int index = binarySearchBetween(arr, lis, a[i]); + arr[index] = a[i]; + if (index > lis) { + lis++; + } + } + return lis; + } + // O(logn) + + private static int binarySearchBetween(int[] t, int end, int key) { + int left = 0; + int right = end; + if (key < t[0]) { + return 0; + } + if (key > t[end]) { + return end + 1; + } + while (left < right - 1) { + int middle = (left + right) / 2; + if (t[middle] < key) { + left = middle; + } else { + right = middle; + } + } + return right; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java new file mode 100644 index 000000000000..5a0f8b2e7e86 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java @@ -0,0 +1,61 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Algorithm explanation + * https://www.educative.io/edpresso/longest-palindromic-subsequence-algorithm + */ +public class LongestPalindromicSubsequence { + + public static void main(String[] args) { + String a = "BBABCBCAB"; + String b = "BABCBAB"; + + String aLPS = LPS(a); + String bLPS = LPS(b); + + System.out.println(a + " => " + aLPS); + System.out.println(b + " => " + bLPS); + } + + public static String LPS(String original) throws IllegalArgumentException { + StringBuilder reverse = new StringBuilder(original); + reverse = reverse.reverse(); + return recursiveLPS(original, reverse.toString()); + } + + private static String recursiveLPS(String original, String reverse) { + String bestResult = ""; + + // no more chars, then return empty + if (original.length() == 0 || reverse.length() == 0) { + bestResult = ""; + } else { + + // if the last chars match, then remove it from both strings and recur + if (original.charAt(original.length() - 1) == reverse.charAt(reverse.length() - 1)) { + String bestSubResult + = recursiveLPS( + original.substring(0, original.length() - 1), + reverse.substring(0, reverse.length() - 1)); + + bestResult = reverse.charAt(reverse.length() - 1) + bestSubResult; + } else { + // otherwise (1) ignore the last character of reverse, and recur on original and updated + // reverse again + // (2) ignore the last character of original and recur on the updated original and reverse + // again + // then select the best result from these two subproblems. + + String bestSubResult1 = recursiveLPS(original, reverse.substring(0, reverse.length() - 1)); + String bestSubResult2 = recursiveLPS(original.substring(0, original.length() - 1), reverse); + if (bestSubResult1.length() > bestSubResult2.length()) { + bestResult = bestSubResult1; + } else { + bestResult = bestSubResult2; + } + } + } + + return bestResult; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java new file mode 100644 index 000000000000..4452700fddec --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java @@ -0,0 +1,54 @@ +package com.thealgorithms.dynamicprogramming; + +/* + * Algorithm explanation https://leetcode.com/problems/longest-palindromic-substring/ + */ +public class LongestPalindromicSubstring { + + public static void main(String[] args) { + String a = "babad"; + String b = "cbbd"; + + String aLPS = LPS(a); + String bLPS = LPS(b); + + System.out.println(a + " => " + aLPS); + System.out.println(b + " => " + bLPS); + } + + private static String LPS(String input) { + if (input == null || input.length() == 0) { + return input; + } + boolean arr[][] = new boolean[input.length()][input.length()]; + int start = 0, end = 0; + for (int g = 0; g < input.length(); g++) { + for (int i = 0, j = g; j < input.length(); i++, j++) { + + if (g == 0) { + arr[i][j] = true; + } else if (g == 1) { + if (input.charAt(i) == input.charAt(j)) { + arr[i][j] = true; + } else { + arr[i][j] = false; + } + } else { + + if (input.charAt(i) == input.charAt(j) && arr[i + 1][j - 1]) { + arr[i][j] = true; + } else { + arr[i][j] = false; + } + } + + if (arr[i][j]) { + start = i; + end = j; + } + } + } + return input.substring(start, end + 1); + } + +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java new file mode 100644 index 000000000000..5a4202b8be81 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java @@ -0,0 +1,58 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Scanner; + +/** + * Given a string containing just the characters '(' and ')', find the length of + * the longest valid (well-formed) parentheses substring. + * + * @author Libin Yang (https://github.com/yanglbme) + * @since 2018/10/5 + */ +public class LongestValidParentheses { + + public static int getLongestValidParentheses(String s) { + if (s == null || s.length() < 2) { + return 0; + } + char[] chars = s.toCharArray(); + int n = chars.length; + int[] res = new int[n]; + res[0] = 0; + res[1] = chars[1] == ')' && chars[0] == '(' ? 2 : 0; + + int max = res[1]; + + for (int i = 2; i < n; ++i) { + if (chars[i] == ')') { + if (chars[i - 1] == '(') { + res[i] = res[i - 2] + 2; + } else { + int index = i - res[i - 1] - 1; + if (index >= 0 && chars[index] == '(') { + // ()(()) + res[i] = res[i - 1] + 2 + (index - 1 >= 0 ? res[index - 1] : 0); + } + } + } + max = Math.max(max, res[i]); + } + + return max; + } + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + while (true) { + String str = sc.nextLine(); + if ("quit".equals(str)) { + break; + } + + System.out.println("Len is: " + getLongestValidParentheses(str)); + } + + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java new file mode 100644 index 000000000000..152d602c599e --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java @@ -0,0 +1,139 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Scanner; + +public class MatrixChainMultiplication { + + private static Scanner scan = new Scanner(System.in); + private static ArrayList mArray = new ArrayList<>(); + private static int size; + private static int[][] m; + private static int[][] s; + private static int[] p; + + public static void main(String[] args) { + int count = 1; + while (true) { + String[] mSize = input("input size of matrix A(" + count + ") ( ex. 10 20 ) : "); + int col = Integer.parseInt(mSize[0]); + if (col == 0) { + break; + } + int row = Integer.parseInt(mSize[1]); + + Matrix matrix = new Matrix(count, col, row); + mArray.add(matrix); + count++; + } + for (Matrix m : mArray) { + System.out.format("A(%d) = %2d x %2d%n", m.count(), m.col(), m.row()); + } + + size = mArray.size(); + m = new int[size + 1][size + 1]; + s = new int[size + 1][size + 1]; + p = new int[size + 1]; + + for (int i = 0; i < size + 1; i++) { + Arrays.fill(m[i], -1); + Arrays.fill(s[i], -1); + } + + for (int i = 0; i < p.length; i++) { + p[i] = i == 0 ? mArray.get(i).col() : mArray.get(i - 1).row(); + } + + matrixChainOrder(); + for (int i = 0; i < size; i++) { + System.out.print("-------"); + } + System.out.println(); + printArray(m); + for (int i = 0; i < size; i++) { + System.out.print("-------"); + } + System.out.println(); + printArray(s); + for (int i = 0; i < size; i++) { + System.out.print("-------"); + } + System.out.println(); + + System.out.println("Optimal solution : " + m[1][size]); + System.out.print("Optimal parens : "); + printOptimalParens(1, size); + } + + private static void printOptimalParens(int i, int j) { + if (i == j) { + System.out.print("A" + i); + } else { + System.out.print("("); + printOptimalParens(i, s[i][j]); + printOptimalParens(s[i][j] + 1, j); + System.out.print(")"); + } + } + + private static void printArray(int[][] array) { + for (int i = 1; i < size + 1; i++) { + for (int j = 1; j < size + 1; j++) { + System.out.print(String.format("%7d", array[i][j])); + } + System.out.println(); + } + } + + private static void matrixChainOrder() { + for (int i = 1; i < size + 1; i++) { + m[i][i] = 0; + } + + for (int l = 2; l < size + 1; l++) { + for (int i = 1; i < size - l + 2; i++) { + int j = i + l - 1; + m[i][j] = Integer.MAX_VALUE; + + for (int k = i; k < j; k++) { + int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]; + if (q < m[i][j]) { + m[i][j] = q; + s[i][j] = k; + } + } + } + } + } + + private static String[] input(String string) { + System.out.print(string); + return (scan.nextLine().split(" ")); + } +} + +class Matrix { + + private int count; + private int col; + private int row; + + Matrix(int count, int col, int row) { + this.count = count; + this.col = col; + this.row = row; + } + + int count() { + return count; + } + + int col() { + return col; + } + + int row() { + return row; + } +} diff --git a/DynamicProgramming/MatrixChainRecursiveTopDownMemoisation.java b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java similarity index 51% rename from DynamicProgramming/MatrixChainRecursiveTopDownMemoisation.java rename to src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java index 448c8b541364..6ccdbf98b7d6 100644 --- a/DynamicProgramming/MatrixChainRecursiveTopDownMemoisation.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java @@ -1,56 +1,47 @@ -package DynamicProgramming; - -// Matrix-chain Multiplication -// Problem Statement -// we have given a chain A1,A2,...,Ani of n matrices, where for i = 1,2,...,n, -// matrix Ai has dimension pi−1 ×pi -// , fully parenthesize the product A1A2 ···An in a way that -// minimizes the number of scalar multiplications. - -public class MatrixChainRecursiveTopDownMemoisation -{ - static int Memoized_Matrix_Chain(int p[]) { - int n = p.length ; - int m[][] = new int[n][n]; - for (int i = 0; i < n; i++) { - for (int j = 0; j < n; j++) { - m[i][j] = Integer.MAX_VALUE; - } - } - return Lookup_Chain(m, p, 1, n-1); - } - - static int Lookup_Chain(int m[][],int p[],int i, int j) - { - if ( i == j ) - { - m[i][j] = 0; - return m[i][j]; - } - if ( m[i][j] < Integer.MAX_VALUE ) - { - return m[i][j]; - } - - else - { - for ( int k = i ; k b) ? a : b; + } + + // Returns the value of maximum profit + static int knapSackRec(int W, int wt[], int val[], int n, int[][] dp) { + + // Base condition + if (n == 0 || W == 0) { + return 0; + } + + if (dp[n][W] != -1) { + return dp[n][W]; + } + + if (wt[n - 1] > W) // Store the value of function call + // stack in table before return + { + return dp[n][W] = knapSackRec(W, wt, val, n - 1, dp); + } else // Return value of table after storing + { + return dp[n][W] + = max( + (val[n - 1] + knapSackRec(W - wt[n - 1], wt, val, n - 1, dp)), + knapSackRec(W, wt, val, n - 1, dp)); + } + } + + static int knapSack(int W, int wt[], int val[], int N) { + + // Declare the table dynamically + int dp[][] = new int[N + 1][W + 1]; + + // Loop to initially filled the + // table with -1 + for (int i = 0; i < N + 1; i++) { + for (int j = 0; j < W + 1; j++) { + dp[i][j] = -1; + } + } + + return knapSackRec(W, wt, val, N, dp); + } + + // Driver Code + public static void main(String[] args) { + int val[] = {60, 100, 120}; + int wt[] = {10, 20, 30}; + + int W = 50; + int N = val.length; + + System.out.println(knapSack(W, wt, val, N)); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java new file mode 100644 index 000000000000..04adb0cebdd0 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java @@ -0,0 +1,81 @@ +package com.thealgorithms.dynamicprogramming; + +/* +Given the following grid with length m and width n: +\---\---\---\ (n) +\ 1 \ 3 \ 1 \ +\---\---\---\ +\ 1 \ 5 \ 1 \ +\---\---\---\ +\ 4 \ 2 \ 1 \ +\---\---\---\ +(m) +Find the path where its sum is the smallest. + +All numbers given are positive. +The Time Complexity of your algorithm should be smaller than or equal to O(mn). +The Space Complexity of your algorithm should be smaller than or equal to O(mn). +You can only move from the top left corner to the down right corner. +You can only move one step down or right. + +EXAMPLE: +INPUT: grid = [[1,3,1],[1,5,1],[4,2,1]] +OUTPUT: 7 +EXPLANATIONS: 1 + 3 + 1 + 1 + 1 = 7 + +For more information see https://www.geeksforgeeks.org/maximum-path-sum-matrix/ + */ +public class MinimumPathSum { + + public void testRegular() { + int[][] grid = { + {1, 3, 1}, + {1, 5, 1}, + {4, 2, 1} + }; + System.out.println(minimumPathSum(grid)); + } + + public void testLessColumns() { + int[][] grid = { + {1, 2}, + {5, 6}, + {1, 1} + }; + System.out.println(minimumPathSum(grid)); + } + + public void testLessRows() { + int[][] grid = { + {2, 3, 3}, + {7, 2, 1} + }; + System.out.println(minimumPathSum(grid)); + } + + public void testOneRowOneColumn() { + int[][] grid = {{2}}; + System.out.println(minimumPathSum(grid)); + } + + public static int minimumPathSum(int[][] grid) { + int m = grid.length, n = grid[0].length; + if (n == 0) { + return 0; + } + int[][] dp = new int[m][n]; + dp[0][0] = grid[0][0]; + for (int i = 0; i < n - 1; i++) { + dp[0][i + 1] = dp[0][i] + grid[0][i + 1]; + } + for (int i = 0; i < m - 1; i++) { + dp[i + 1][0] = dp[i][0] + grid[i + 1][0]; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j]; + } + } + return dp[m - 1][n - 1]; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java new file mode 100644 index 000000000000..c6f8f18b8a1a --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java @@ -0,0 +1,88 @@ +package com.thealgorithms.dynamicprogramming; +// Partition a set into two subsets such that the difference of subset sums is minimum + +/* +Input: arr[] = {1, 6, 11, 5} +Output: 1 +Explanation: +Subset1 = {1, 5, 6}, sum of Subset1 = 12 +Subset2 = {11}, sum of Subset2 = 11 + +Input: arr[] = {36, 7, 46, 40} +Output: 23 +Explanation: +Subset1 = {7, 46} ; sum of Subset1 = 53 +Subset2 = {36, 40} ; sum of Subset2 = 76 + */ +public class MinimumSumPartition { + + public static int subSet(int[] arr) { + int n = arr.length; + int sum = getSum(arr); + boolean[][] dp = new boolean[n + 1][sum + 1]; + for (int i = 0; i <= n; i++) { + dp[i][0] = true; + } + for (int j = 0; j <= sum; j++) { + dp[0][j] = false; + } + + // fill dp array + for (int i = 1; i <= n; i++) { + for (int j = 1; j <= sum; j++) { + if (arr[i - 1] < j) { + dp[i][j] = dp[i - 1][j - arr[i - 1]] || dp[i - 1][j]; + } else if (arr[i - 1] == j) { + dp[i][j] = true; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + } + + // fill the index array + int[] index = new int[sum]; + int p = 0; + for (int i = 0; i <= sum / 2; i++) { + if (dp[n][i]) { + index[p++] = i; + } + } + + return getMin(index, sum); + } + + /** + * Calculate sum of array elements + * + * @param arr the array + * @return sum of given array + */ + public static int getSum(int[] arr) { + int sum = 0; + for (int temp : arr) { + sum += temp; + } + return sum; + } + + public static int getMin(int[] arr, int sum) { + if (arr.length == 0) { + return 0; + } + int min = Integer.MAX_VALUE; + for (int temp : arr) { + min = Math.min(min, sum - 2 * temp); + } + return min; + } + + /** + * Driver Code + */ + public static void main(String[] args) { + assert subSet(new int[]{1, 6, 11, 5}) == 1; + assert subSet(new int[]{36, 7, 46, 40}) == 23; + assert subSet(new int[]{1, 2, 3, 9}) == 3; + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java b/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java new file mode 100644 index 000000000000..46fbbb6569c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java @@ -0,0 +1,91 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Scanner; + +/** + * @file @brief Implements [Palindrome + * Partitioning](https://leetcode.com/problems/palindrome-partitioning-ii/) + * algorithm, giving you the minimum number of partitions you need to make + * + * @details palindrome partitioning uses dynamic programming and goes to all the + * possible partitions to find the minimum you are given a string and you need + * to give minimum number of partitions needed to divide it into a number of + * palindromes [Palindrome Partitioning] + * (https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/) overall time + * complexity O(n^2) For example: example 1:- String : "nitik" Output : 2 => "n + * | iti | k" For example: example 2:- String : "ababbbabbababa" Output : 3 => + * "aba | b | bbabb | ababa" + * @author [Syed] (https://github.com/roeticvampire) + */ +public class PalindromicPartitioning { + + public static int minimalpartitions(String word) { + int len = word.length(); + /* We Make two arrays to create a bottom-up solution. + minCuts[i] = Minimum number of cuts needed for palindrome partitioning of substring word[0..i] + isPalindrome[i][j] = true if substring str[i..j] is palindrome + Base Condition: C[i] is 0 if P[0][i]= true + */ + int[] minCuts = new int[len]; + boolean[][] isPalindrome = new boolean[len][len]; + + int i, j, L; // different looping variables + + // Every substring of length 1 is a palindrome + for (i = 0; i < len; i++) { + isPalindrome[i][i] = true; + } + + /* L is substring length. Build the solution in bottom up manner by considering all substrings of length starting from 2 to n. */ + for (L = 2; L <= len; L++) { + // For substring of length L, set different possible starting indexes + for (i = 0; i < len - L + 1; i++) { + j = i + L - 1; // Ending index + // If L is 2, then we just need to + // compare two characters. Else need to + // check two corner characters and value + // of P[i+1][j-1] + if (L == 2) { + isPalindrome[i][j] = (word.charAt(i) == word.charAt(j)); + } else { + if ((word.charAt(i) == word.charAt(j)) && isPalindrome[i + 1][j - 1]) { + isPalindrome[i][j] = true; + } else { + isPalindrome[i][j] = false; + } + + } + } + } + + //We find the minimum for each index + for (i = 0; i < len; i++) { + if (isPalindrome[0][i] == true) { + minCuts[i] = 0; + } else { + minCuts[i] = Integer.MAX_VALUE; + for (j = 0; j < i; j++) { + if (isPalindrome[j + 1][i] == true && 1 + minCuts[j] < minCuts[i]) { + minCuts[i] = 1 + minCuts[j]; + } + } + } + } + + // Return the min cut value for complete + // string. i.e., str[0..n-1] + return minCuts[len - 1]; + } + + public static void main(String[] args) { + Scanner input = new Scanner(System.in); + String word; + System.out.println("Enter the First String"); + word = input.nextLine(); + // ans stores the final minimal cut count needed for partitioning + int ans = minimalpartitions(word); + System.out.println( + "The minimum cuts needed to partition \"" + word + "\" into palindromes is " + ans); + input.close(); + } +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java new file mode 100644 index 000000000000..d9ab4c419511 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java @@ -0,0 +1,171 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Given a text and wildcard pattern implement a wildcard pattern matching + * algorithm that finds if wildcard is matched with text. The matching should + * cover the entire text ?-> matches single characters *-> match the sequence of + * characters + * + */ +/** + * For calculation of Time and Space Complexity. Let N be length of src and M be + * length of pat + * + */ +public class RegexMatching { + + // Method 1: Using Recursion + // Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space + static boolean regexRecursion(String src, String pat) { + if (src.length() == 0 && pat.length() == 0) { + return true; + } + if (src.length() != 0 && pat.length() == 0) { + return false; + } + if (src.length() == 0 && pat.length() != 0) { + for (int i = 0; i < pat.length(); i++) { + if (pat.charAt(i) != '*') { + return false; + } + } + return true; + } + char chs = src.charAt(0); + char chp = pat.charAt(0); + + String ros = src.substring(1); + String rop = pat.substring(1); + + boolean ans; + if (chs == chp || chp == '?') { + ans = regexRecursion(ros, rop); + } else if (chp == '*') { + boolean blank = regexRecursion(src, rop); + boolean multiple = regexRecursion(ros, pat); + ans = blank || multiple; + } else { + ans = false; + } + return ans; + } + + // Method 2: Using Recursion and breaking string using virtual index + // Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space + static boolean regexRecursion(String src, String pat, int svidx, int pvidx) { + if (src.length() == svidx && pat.length() == pvidx) { + return true; + } + if (src.length() != svidx && pat.length() == pvidx) { + return false; + } + if (src.length() == svidx && pat.length() != pvidx) { + for (int i = pvidx; i < pat.length(); i++) { + if (pat.charAt(i) != '*') { + return false; + } + } + return true; + } + char chs = src.charAt(svidx); + char chp = pat.charAt(pvidx); + + boolean ans; + if (chs == chp || chp == '?') { + ans = regexRecursion(src, pat, svidx + 1, pvidx + 1); + } else if (chp == '*') { + boolean blank = regexRecursion(src, pat, svidx, pvidx + 1); + boolean multiple = regexRecursion(src, pat, svidx + 1, pvidx); + ans = blank || multiple; + } else { + ans = false; + } + return ans; + } + + // Method 3: Top-Down DP(Memoization) + // Time Complexity=0(N*M) Space Complexity=0(N*M)+Recursion Extra Space + static boolean regexRecursion(String src, String pat, int svidx, int pvidx, int[][] strg) { + if (src.length() == svidx && pat.length() == pvidx) { + return true; + } + if (src.length() != svidx && pat.length() == pvidx) { + return false; + } + if (src.length() == svidx && pat.length() != pvidx) { + for (int i = pvidx; i < pat.length(); i++) { + if (pat.charAt(i) != '*') { + return false; + } + } + return true; + } + if (strg[svidx][pvidx] != 0) { + return strg[svidx][pvidx] == 1 ? false : true; + } + char chs = src.charAt(svidx); + char chp = pat.charAt(pvidx); + + boolean ans; + if (chs == chp || chp == '?') { + ans = regexRecursion(src, pat, svidx + 1, pvidx + 1, strg); + } else if (chp == '*') { + boolean blank = regexRecursion(src, pat, svidx, pvidx + 1, strg); + boolean multiple = regexRecursion(src, pat, svidx + 1, pvidx, strg); + ans = blank || multiple; + } else { + ans = false; + } + strg[svidx][pvidx] = ans == false ? 1 : 2; + return ans; + } + + // Method 4: Bottom-Up DP(Tabulation) + // Time Complexity=0(N*M) Space Complexity=0(N*M) + static boolean regexBU(String src, String pat) { + + boolean strg[][] = new boolean[src.length() + 1][pat.length() + 1]; + strg[src.length()][pat.length()] = true; + for (int row = src.length(); row >= 0; row--) { + for (int col = pat.length() - 1; col >= 0; col--) { + if (row == src.length()) { + if (pat.charAt(col) == '*') { + strg[row][col] = strg[row][col + 1]; + } else { + strg[row][col] = false; + } + } else { + char chs = src.charAt(row); + char chp = pat.charAt(col); + + boolean ans; + if (chs == chp || chp == '?') { + ans = strg[row + 1][col + 1]; + } else if (chp == '*') { + boolean blank = strg[row][col + 1]; + boolean multiple = strg[row + 1][col]; + ans = blank || multiple; + } else { + ans = false; + } + strg[row][col] = ans; + } + } + } + return strg[0][0]; + } + + public static void main(String[] args) { + + String src = "aa"; + String pat = "*"; + System.out.println("Method 1: " + regexRecursion(src, pat)); + System.out.println("Method 2: " + regexRecursion(src, pat, 0, 0)); + System.out.println("Method 3: " + regexRecursion(src, pat, 0, 0, new int[src.length()][pat.length()])); + System.out.println("Method 4: " + regexBU(src, pat)); + + } + +} +// Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/ +// Question Link : https://practice.geeksforgeeks.org/problems/wildcard-pattern-matching/1 diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java b/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java new file mode 100644 index 000000000000..58c122c485c6 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java @@ -0,0 +1,32 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * A DynamicProgramming solution for Rod cutting problem Returns the best + * obtainable price for a rod of length n and price[] as prices of different + * pieces + */ +public class RodCutting { + + private static int cutRod(int[] price, int n) { + int val[] = new int[n + 1]; + val[0] = 0; + + for (int i = 1; i <= n; i++) { + int max_val = Integer.MIN_VALUE; + for (int j = 0; j < i; j++) { + max_val = Math.max(max_val, price[j] + val[i - j - 1]); + } + + val[i] = max_val; + } + + return val[n]; + } + + // main function to test + public static void main(String args[]) { + int[] arr = new int[]{2, 5, 13, 19, 20}; + int result = cutRod(arr, arr.length); + System.out.println("Maximum Obtainable Value is " + result); + } +} diff --git a/DynamicProgramming/ShortestCommonSupersequenceLength.java b/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java similarity index 70% rename from DynamicProgramming/ShortestCommonSupersequenceLength.java rename to src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java index 8948bde5025c..4b067d9fde72 100644 --- a/DynamicProgramming/ShortestCommonSupersequenceLength.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java @@ -1,61 +1,57 @@ -package DynamicProgramming; +package com.thealgorithms.dynamicprogramming; // Java program to find length of the shortest supersequence class ShortestSuperSequence { - + // Function to find length of the // shortest supersequence of X and Y. - static int shortestSuperSequence(String X, String Y) - { + static int shortestSuperSequence(String X, String Y) { int m = X.length(); int n = Y.length(); - + // find lcs int l = lcs(X, Y, m, n); - + // Result is sum of input string // lengths - length of lcs return (m + n - l); } - + // Returns length of LCS // for X[0..m - 1], Y[0..n - 1] - static int lcs(String X, String Y, int m, int n) - { + static int lcs(String X, String Y, int m, int n) { int[][] L = new int[m + 1][n + 1]; int i, j; - + // Following steps build L[m + 1][n + 1] // in bottom up fashion. Note that // L[i][j] contains length of LCS // of X[0..i - 1]and Y[0..j - 1] for (i = 0; i <= m; i++) { for (j = 0; j <= n; j++) { - if (i == 0 || j == 0) + if (i == 0 || j == 0) { L[i][j] = 0; - - else if (X.charAt(i - 1) == Y.charAt(j - 1)) + } else if (X.charAt(i - 1) == Y.charAt(j - 1)) { L[i][j] = L[i - 1][j - 1] + 1; - - else + } else { L[i][j] = Math.max(L[i - 1][j], - L[i][j - 1]); + L[i][j - 1]); + } } } - + // L[m][n] contains length of LCS // for X[0..n - 1] and Y[0..m - 1] return L[m][n]; } - + // Driver code - public static void main(String args[]) - { + public static void main(String args[]) { String X = "AGGTAB"; String Y = "GXTXAYB"; - + System.out.println("Length of the shortest " - + "supersequence is " - + shortestSuperSequence(X, Y)); + + "supersequence is " + + shortestSuperSequence(X, Y)); } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java new file mode 100644 index 000000000000..1da65ce68401 --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java @@ -0,0 +1,48 @@ +package com.thealgorithms.dynamicprogramming; + +public class SubsetSum { + + /** + * Driver Code + */ + public static void main(String[] args) { + int[] arr = new int[]{50, 4, 10, 15, 34}; + assert subsetSum(arr, 64); + /* 4 + 10 + 15 + 34 = 64 */ + assert subsetSum(arr, 99); + /* 50 + 15 + 34 = 99 */ + assert !subsetSum(arr, 5); + assert !subsetSum(arr, 66); + } + + /** + * Test if a set of integers contains a subset that sum to a given integer. + * + * @param arr the array contains integers. + * @param sum target sum of subset. + * @return {@code true} if subset exists, otherwise {@code false}. + */ + private static boolean subsetSum(int[] arr, int sum) { + int n = arr.length; + boolean[][] isSum = new boolean[n + 2][sum + 1]; + + isSum[n + 1][0] = true; + for (int i = 1; i <= sum; i++) { + isSum[n + 1][i] = false; + } + + for (int i = n; i > 0; i--) { + isSum[i][0] = true; + for (int j = 1; j <= arr[i - 1] - 1; j++) { + if (j <= sum) { + isSum[i][j] = isSum[i + 1][j]; + } + } + for (int j = arr[i - 1]; j <= sum; j++) { + isSum[i][j] = (isSum[i + 1][j] || isSum[i + 1][j - arr[i - 1]]); + } + } + + return isSum[1][sum]; + } +} diff --git a/DynamicProgramming/Sum_Of_Subset.java b/src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java similarity index 79% rename from DynamicProgramming/Sum_Of_Subset.java rename to src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java index 7faa116006d5..c40c65dbb886 100644 --- a/DynamicProgramming/Sum_Of_Subset.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/Sum_Of_Subset.java @@ -1,20 +1,20 @@ -package DynamicProgramming; +package com.thealgorithms.dynamicprogramming; public class Sum_Of_Subset { - public static void main(String[] args){ - - int[] arr = { 7, 3, 2, 5, 8 }; + + public static void main(String[] args) { + + int[] arr = {7, 3, 2, 5, 8}; int Key = 14; - + if (subsetSum(arr, arr.length - 1, Key)) { System.out.print("Yes, that sum exists"); - } - else { + } else { System.out.print("Nope, that number does not exist"); } } - public static boolean subsetSum(int[] arr, int num, int Key) - { + + public static boolean subsetSum(int[] arr, int num, int Key) { if (Key == 0) { return true; } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java b/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java new file mode 100644 index 000000000000..dc45a795b2dd --- /dev/null +++ b/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java @@ -0,0 +1,88 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Imagine you have a collection of N wines placed next to each other on the + * shelf. The price of ith wine is pi(Prices of different wines are different). + * Because wine gets better every year supposing today is year 1, on year y the + * price would be y*pi i.e y times the value of the initial year. You want to + * sell all wines but you have to sell one wine per year. One more constraint on + * each year you are allowed to sell either leftmost or rightmost wine on the + * shelf. You are not allowed to reorder. You have to find the maximum profit + * + */ +public class WineProblem { + + // Method 1: Using Recursion + // Time Complexity=0(2^N) Space Complexity=Recursion extra space + public static int WPRecursion(int[] arr, int si, int ei) { + int n = arr.length; + int year = (n - (ei - si + 1)) + 1; + if (si == ei) { + return arr[si] * year; + } + + int start = WPRecursion(arr, si + 1, ei) + arr[si] * year; + int end = WPRecursion(arr, si, ei - 1) + arr[ei] * year; + + int ans = Math.max(start, end); + + return ans; + } + + // Method 2: Top-Down DP(Memoization) + // Time Complexity=0(N*N) Space Complexity=0(N*N)+Recursion extra space + public static int WPTD(int[] arr, int si, int ei, int[][] strg) { + int n = arr.length; + int year = (n - (ei - si + 1)) + 1; + if (si == ei) { + return arr[si] * year; + } + + if (strg[si][ei] != 0) { + return strg[si][ei]; + } + int start = WPTD(arr, si + 1, ei, strg) + arr[si] * year; + int end = WPTD(arr, si, ei - 1, strg) + arr[ei] * year; + + int ans = Math.max(start, end); + + strg[si][ei] = ans; + + return ans; + } + + // Method 3: Bottom-Up DP(Tabulation) + // Time Complexity=0(N*N/2)->0(N*N) Space Complexity=0(N*N) + public static int WPBU(int[] arr) { + int n = arr.length; + int[][] strg = new int[n][n]; + + for (int slide = 0; slide <= n - 1; slide++) { + for (int si = 0; si <= n - slide - 1; si++) { + int ei = si + slide; + int year = (n - (ei - si + 1)) + 1; + if (si == ei) { + strg[si][ei] = arr[si] * year; + } else { + int start = strg[si + 1][ei] + arr[si] * year; + int end = strg[si][ei - 1] + arr[ei] * year; + + strg[si][ei] = Math.max(start, end); + + } + } + } + return strg[0][n - 1]; + } + + public static void main(String[] args) { + int[] arr = {2, 3, 5, 1, 4}; + System.out.println("Method 1: " + WPRecursion(arr, 0, arr.length - 1)); + System.out.println("Method 2: " + WPTD(arr, 0, arr.length - 1, new int[arr.length][arr.length])); + System.out.println("Method 3: " + WPBU(arr)); + + } + +} +// Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/ +// Question Link : https://www.geeksforgeeks.org/maximum-profit-sale-wines/ diff --git a/Maths/ADTFraction.java b/src/main/java/com/thealgorithms/maths/ADTFraction.java similarity index 98% rename from Maths/ADTFraction.java rename to src/main/java/com/thealgorithms/maths/ADTFraction.java index f585a81f2bc8..ca70ba0e0291 100644 --- a/Maths/ADTFraction.java +++ b/src/main/java/com/thealgorithms/maths/ADTFraction.java @@ -1,6 +1,7 @@ -package Maths; +package com.thealgorithms.maths; public class ADTFraction { + public static void main(String[] args) { // TODO code application logic here diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteMax.java b/src/main/java/com/thealgorithms/maths/AbsoluteMax.java new file mode 100644 index 000000000000..b67b5991ce0a --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/AbsoluteMax.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; + +/** + * description: + * + *

+ * absMax([0, 5, 1, 11]) = 11, absMax([3 , -10, -2]) = -10 + */ +public class AbsoluteMax { + + public static void main(String[] args) { + int[] testnums = {-2, 0, 16}; + assert absMax(testnums) == 16; + + int[] numbers = {3, -10, -2}; + System.out.println("absMax(" + Arrays.toString(numbers) + ") = " + absMax(numbers)); + } + + /** + * get the value, return the absolute max value + * + * @param numbers contains elements + * @return the absolute max value + */ + public static int absMax(int[] numbers) { + int absMaxValue = numbers[0]; + for (int i = 1, length = numbers.length; i < length; ++i) { + if (Math.abs(numbers[i]) > Math.abs(absMaxValue)) { + absMaxValue = numbers[i]; + } + } + return absMaxValue; + } +} diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteMin.java b/src/main/java/com/thealgorithms/maths/AbsoluteMin.java new file mode 100644 index 000000000000..bdb8eb1a9740 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/AbsoluteMin.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; + +/** + * description: + * + *

+ * absMin([0, 5, 1, 11]) = 0, absMin([3 , -10, -2]) = -2 + */ +public class AbsoluteMin { + + public static void main(String[] args) { + int[] testnums = {4, 0, 16}; + assert absMin(testnums) == 0; + + int[] numbers = {3, -10, -2}; + System.out.println("absMin(" + Arrays.toString(numbers) + ") = " + absMin(numbers)); + } + + /** + * get the value, returns the absolute min value min + * + * @param numbers contains elements + * @return the absolute min value + */ + public static int absMin(int[] numbers) { + int absMinValue = numbers[0]; + for (int i = 1, length = numbers.length; i < length; ++i) { + if (Math.abs(numbers[i]) < Math.abs(absMinValue)) { + absMinValue = numbers[i]; + } + } + return absMinValue; + } +} diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteValue.java b/src/main/java/com/thealgorithms/maths/AbsoluteValue.java new file mode 100644 index 000000000000..dfd00f862900 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/AbsoluteValue.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +import java.util.Random; + +public class AbsoluteValue { + + public static void main(String[] args) { + Random random = new Random(); + + /* test 1000 random numbers */ + for (int i = 1; i <= 1000; ++i) { + int randomNumber = random.nextInt(); + assert absVal(randomNumber) == Math.abs(randomNumber); + } + } + + /** + * If value is less than zero, make value positive. + * + * @param value a number + * @return the absolute value of a number + */ + public static int absVal(int value) { + return value < 0 ? -value : value; + } +} diff --git a/src/main/java/com/thealgorithms/maths/AliquotSum.java b/src/main/java/com/thealgorithms/maths/AliquotSum.java new file mode 100644 index 000000000000..329bcf2f9984 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/AliquotSum.java @@ -0,0 +1,34 @@ +package com.thealgorithms.maths; + +/** + * In number theory, the aliquot sum s(n) of a positive integer n is the sum of + * all proper divisors of n, that is, all divisors of n other than n itself. For + * example, the proper divisors of 15 (that is, the positive divisors of 15 that + * are not equal to 15) are 1, 3 and 5, so the aliquot sum of 15 is 9 i.e. (1 + + * 3 + 5). Wikipedia: https://en.wikipedia.org/wiki/Aliquot_sum + */ +public class AliquotSum { + + public static void main(String[] args) { + assert aliquotSum(1) == 0; + assert aliquotSum(6) == 6; + assert aliquotSum(15) == 9; + assert aliquotSum(19) == 1; + } + + /** + * Finds the aliquot sum of an integer number + * + * @param number a positive integer + * @return aliquot sum of given {@code number} + */ + public static int aliquotSum(int number) { + int sum = 0; + for (int i = 1, limit = number / 2; i <= limit; ++i) { + if (number % i == 0) { + sum += i; + } + } + return sum; + } +} diff --git a/src/main/java/com/thealgorithms/maths/AmicableNumber.java b/src/main/java/com/thealgorithms/maths/AmicableNumber.java new file mode 100644 index 000000000000..2cc13f3e1e44 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/AmicableNumber.java @@ -0,0 +1,93 @@ +package com.thealgorithms.maths; + +/** + * Amicable numbers are two different numbers so related that the sum of the + * proper divisors of each is equal to the other number. (A proper divisor of a + * number is a positive factor of that number other than the number itself. For + * example, the proper divisors of 6 are 1, 2, and 3.) A pair of amicable + * numbers constitutes an aliquot sequence of period 2. It is unknown if there + * are infinitely many pairs of amicable numbers. * + * + *

+ * link: https://en.wikipedia.org/wiki/Amicable_numbers * + * + *

+ * Simple Example : (220,284) 220 is divisible by {1,2,4,5,10,11,20,22,44,55,110 + * } <- Sum = 284 + * 284 is divisible by -> 1,2,4,71,142 and the Sum of that is. Yes right you + * probably expected it 220 + */ +public class AmicableNumber { + + public static void main(String[] args) { + + AmicableNumber.findAllInRange(1, 3000); + /* Res -> Int Range of 1 till 3000there are 3Amicable_numbers These are 1: = ( 220,284) 2: = ( 1184,1210) + 3: = ( 2620,2924) So it worked */ + + } + + /** + * @param startValue + * @param stopValue + * @return + */ + static void findAllInRange(int startValue, int stopValue) { + + /* the 2 for loops are to avoid to double check tuple. For example (200,100) and (100,200) is the same calculation + * also to avoid is to check the number with it self. a number with itself is always a AmicableNumber + * */ + StringBuilder res = new StringBuilder(); + int countofRes = 0; + + for (int i = startValue; i < stopValue; i++) { + for (int j = i + 1; j <= stopValue; j++) { + if (isAmicableNumber(i, j)) { + countofRes++; + res.append("" + countofRes + ": = ( " + i + "," + j + ")" + "\t"); + } + } + } + res.insert( + 0, + "Int Range of " + + startValue + + " till " + + stopValue + + " there are " + + countofRes + + " Amicable_numbers.These are \n "); + System.out.println(res.toString()); + } + + /** + * Check if {@code numberOne and numberTwo } are AmicableNumbers or not + * + * @param numberOne numberTwo + * @return {@code true} if {@code numberOne numberTwo} isAmicableNumbers + * otherwise false + */ + static boolean isAmicableNumber(int numberOne, int numberTwo) { + + return ((recursiveCalcOfDividerSum(numberOne, numberOne) == numberTwo + && numberOne == recursiveCalcOfDividerSum(numberTwo, numberTwo))); + } + + /** + * calculated in recursive calls the Sum of all the Dividers beside it self + * + * @param number div = the next to test dividely by using the modulo + * operator + * @return sum of all the dividers + */ + static int recursiveCalcOfDividerSum(int number, int div) { + + if (div == 1) { + return 0; + } else if (number % --div == 0) { + return recursiveCalcOfDividerSum(number, div) + div; + } else { + return recursiveCalcOfDividerSum(number, div); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/Area.java b/src/main/java/com/thealgorithms/maths/Area.java new file mode 100644 index 000000000000..31375f400402 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Area.java @@ -0,0 +1,164 @@ +package com.thealgorithms.maths; + +/** + * Find the area of various geometric shapes + */ +public class Area { + + public static void main(String[] args) { + + /* test cube */ + assert Double.compare(surfaceAreaCube(1), 6.0) == 0; + + /* test sphere */ + assert Double.compare(surfaceAreaSphere(5), 314.1592653589793) == 0; + assert Double.compare(surfaceAreaSphere(1), 12.566370614359172) == 0; + + /* test rectangle */ + assert Double.compare(surfaceAreaRectangle(10, 20), 200.0) == 0; + + /* test square */ + assert Double.compare(surfaceAreaSquare(10), 100.0) == 0; + + /* test triangle */ + assert Double.compare(surfaceAreaTriangle(10, 10), 50.0) == 0; + + /* test parallelogram */ + assert Double.compare(surfaceAreaParallelogram(10, 20), 200.0) == 0; + + /* test trapezium */ + assert Double.compare(surfaceAreaTrapezium(10, 20, 30), 450.0) == 0; + + /* test circle */ + assert Double.compare(surfaceAreaCircle(20), 1256.6370614359173) == 0; + + /* test cylinder */ + assert Double.compare(surfaceAreaCylinder(1, 2), 18.84955592153876) == 0; + + /* test hemisphere */ + assert Double.compare(surfaceAreaHemisphere(5), 235.61944901923448) == 0; + assert Double.compare(surfaceAreaHemisphere(1), 9.42477796076938) == 0; + + /* test cone */ + assert Double.compare(surfaceAreaCone(6, 8), 301.59289474462014) == 0; + assert Double.compare(surfaceAreaCone(10, 24), 1130.9733552923256) == 0; + + } + + /** + * Calculate the surface area of a cube. + * + * @param sideLength side length of cube + * @return surface area of given cube + */ + private static double surfaceAreaCube(double sideLength) { + return 6 * sideLength * sideLength; + } + + /** + * Calculate the surface area of a sphere. + * + * @param radius radius of sphere + * @return surface area of given sphere + */ + private static double surfaceAreaSphere(double radius) { + return 4 * Math.PI * radius * radius; + } + + /** + * Calculate the area of a rectangle + * + * @param length length of rectangle + * @param width width of rectangle + * @return area of given rectangle + */ + private static double surfaceAreaRectangle(double length, double width) { + return length * width; + } + + /** + * Calculate surface area of a cylinder + * + * @param radius radius of the floor + * @param height height of the cylinder. + * @return volume of given cylinder + */ + private static double surfaceAreaCylinder(double radius, double height) { + return 2 * (Math.PI * radius * radius + Math.PI * radius * height); + } + + /** + * Calculate the area of a square + * + * @param sideLength side length of square + * @return area of given square + */ + private static double surfaceAreaSquare(double sideLength) { + return sideLength * sideLength; + } + + /** + * Calculate the area of a triangle + * + * @param base base of triangle + * @param height height of triangle + * @return area of given triangle + */ + private static double surfaceAreaTriangle(double base, double height) { + return base * height / 2; + } + + /** + * Calculate the area of a parallelogram + * + * @param base base of parallelogram + * @param height height of parallelogram + * @return area of given parallelogram + */ + private static double surfaceAreaParallelogram(double base, double height) { + return base * height; + } + + /** + * Calculate the area of a trapezium + * + * @param base1 upper base of trapezium + * @param base2 bottom base of trapezium + * @param height height of trapezium + * @return area of given trapezium + */ + private static double surfaceAreaTrapezium(double base1, double base2, double height) { + return (base1 + base2) * height / 2; + } + + /** + * Calculate the area of a circle + * + * @param radius radius of circle + * @return area of given circle + */ + private static double surfaceAreaCircle(double radius) { + return Math.PI * radius * radius; + } + + /** + * Calculate the surface area of a hemisphere. + * + * @param radius radius of hemisphere + * @return surface area of given hemisphere + */ + private static double surfaceAreaHemisphere(double radius) { + return 3 * Math.PI * radius * radius; + } + + /** + * Calculate the surface area of a cone. + * + * @param radius radius of cone. + * @param height of cone. + * @return surface area of given cone. + */ + private static double surfaceAreaCone(double radius, double height) { + return Math.PI * radius * (radius + Math.pow((height * height + radius * radius), 0.5)); + } +} diff --git a/src/main/java/com/thealgorithms/maths/Armstrong.java b/src/main/java/com/thealgorithms/maths/Armstrong.java new file mode 100644 index 000000000000..df65ba750b01 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Armstrong.java @@ -0,0 +1,46 @@ +package com.thealgorithms.maths; + +/** + * An Armstrong number is equal to the sum of the cubes of its digits. For + * example, 370 is an Armstrong number because 3*3*3 + 7*7*7 + 0*0*0 = 370. An + * Armstrong number is often called Narcissistic number. + */ +public class Armstrong { + + public static void main(String[] args) { + assert (isArmStrong(0)); + assert (isArmStrong(1)); + assert (isArmStrong(153)); + assert (isArmStrong(1634)); + assert (isArmStrong(371)); + assert (!isArmStrong(200)); + } + + /** + * Checks whether a given number is an armstrong number or not. + * + * @param number number to check + * @return {@code true} if given number is armstrong number, {@code false} + * otherwise + */ + private static boolean isArmStrong(int number) { + int sum = 0; + int temp = number; + int numberOfDigits = 0; + while (temp != 0) { + numberOfDigits++; + temp /= 10; + } + temp = number; + /* copy number again */ + while (number > 0) { + int remainder = number % 10; + int power = 1; + for (int i = 1; i <= numberOfDigits; power *= remainder, ++i) + ; + sum = sum + power; + number /= 10; + } + return sum == temp; + } +} diff --git a/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java b/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java new file mode 100644 index 000000000000..2444a3628b41 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java @@ -0,0 +1,56 @@ +package com.thealgorithms.maths; + +/** + * A number is said to be an Automorphic, if it is present in the last digit(s) + * of its square. Example- Let the number be 25, its square is 625. Since, + * 25(The input number) is present in the last two digits of its square(625), it + * is an Automorphic Number. + */ +import java.io.*; + +public class AutomorphicNumber { + + //returns True if the number is a Automorphic number and False if it is not an Automorphic number + public static boolean isAutomorphic(int n) { + int m, c, r, p, k; + c = 0; + /** + * m = Temporary variable to store a copy of the number entered by the + * user. n = The number entered by the user c = Count the digits of the + * number entered by user. p = To calculate the square of the number. k + * = Support variable to count the digits of the number + */ + double s; + m = n; + p = m * m; //Calculating square of the number + do { + k = n / 10; + c = c + 1; //Counting the digits of the number entered by user. + n = k; + } while (n != 0); + s = Math.pow(10, c); + r = p % (int) s; + if (m == r) //Checking if the original number entered is present at the end of the square + { + return true; + } else { + return false; + } + } + + /** + * Method to check if number is Automorphic Number or Not 1) Input - Enter a + * Number: 25 Output - It is an Automorphic Number. 2) Input - Enter a + * Number: 7 Output - It is not an Automorphic Number. + */ + public static void main(String args[]) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + System.out.println("Enter a Number: "); + int n = Integer.parseInt(br.readLine()); + if (isAutomorphic(n)) { + System.out.println("It is an Automorphic Number."); + } else { + System.out.println("It is not an Automorphic Number."); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/Average.java b/src/main/java/com/thealgorithms/maths/Average.java new file mode 100644 index 000000000000..3413f09aa29d --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Average.java @@ -0,0 +1,46 @@ +package com.thealgorithms.maths; + +/** + * Calculate average of a list of numbers + */ +public class Average { + + private static final double SMALL_VALUE = 0.00001f; + + public static void main(String[] args) { + assert Math.abs(average(new double[]{3, 6, 9, 12, 15, 18, 21}) - 12) < SMALL_VALUE; + assert Math.abs(average(new double[]{5, 10, 15, 20, 25, 30, 35}) - 20) < SMALL_VALUE; + assert Math.abs(average(new double[]{1, 2, 3, 4, 5, 6, 7, 8}) - 4.5) < SMALL_VALUE; + int[] array = {2, 4, 10}; + assert average(array) == 5; + } + + /** + * Calculate average of a list of numbers + * + * @param numbers array to store numbers + * @return mean of given numbers + */ + public static double average(double[] numbers) { + double sum = 0; + for (double number : numbers) { + sum += number; + } + return sum / numbers.length; + } + + /** + * find average value of int array + * + * @param array the array contains element and the sum does not excess long + * value limit + * @return average value + */ + public static int average(int[] array) { + long sum = 0; + for (int i = 0; i < array.length; ++i) { + sum += array[i]; + } + return (int) (sum / array.length); + } +} diff --git a/src/main/java/com/thealgorithms/maths/BinaryPow.java b/src/main/java/com/thealgorithms/maths/BinaryPow.java new file mode 100644 index 000000000000..64b4e34fdee5 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/BinaryPow.java @@ -0,0 +1,49 @@ +package com.thealgorithms.maths; + +public class BinaryPow { + + /** + * Calculate a^p using binary exponentiation + * [Binary-Exponentiation](https://cp-algorithms.com/algebra/binary-exp.html) + * + * @param a the base for exponentiation + * @param p the exponent - must be greater than 0 + * @return a^p + */ + public static int binPow(int a, int p) { + int res = 1; + while (p > 0) { + if ((p & 1) == 1) { + res = res * a; + } + a = a * a; + p >>>= 1; + } + return res; + } + + /** + * Function for testing binary exponentiation + * + * @param a the base + * @param p the exponent + */ + public static void test(int a, int p) { + int res = binPow(a, p); + assert res == (int) Math.pow(a, p) : "Incorrect Implementation"; + System.out.println(a + "^" + p + ": " + res); + } + + /** + * Main Function to call tests + * + * @param args System Line Arguments + */ + public static void main(String[] args) { + // prints 2^15: 32768 + test(2, 15); + + // prints 3^9: 19683 + test(3, 9); + } +} diff --git a/src/main/java/com/thealgorithms/maths/Ceil.java b/src/main/java/com/thealgorithms/maths/Ceil.java new file mode 100644 index 000000000000..2263f9e6dc04 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Ceil.java @@ -0,0 +1,31 @@ +package com.thealgorithms.maths; + +import java.util.Random; + +public class Ceil { + + public static void main(String[] args) { + Random random = new Random(); + for (int i = 1; i <= 1000; ++i) { + double randomNumber = random.nextDouble(); + assert ceil(randomNumber) == Math.ceil(randomNumber); + } + } + + /** + * Returns the smallest (closest to negative infinity) + * + * @param number the number + * @return the smallest (closest to negative infinity) of given + * {@code number} + */ + public static double ceil(double number) { + if (number - (int) number == 0) { + return number; + } else if (number - (int) number > 0) { + return (int) (number + 1); + } else { + return (int) number; + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java b/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java new file mode 100644 index 000000000000..9b35ead01303 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java @@ -0,0 +1,61 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; + +/** + * Class for circular convolution of two discrete signals using the convolution + * theorem. + * + * @author Ioannis Karavitsis + * @version 1.0 + */ +public class CircularConvolutionFFT { + + /** + * This method pads the signal with zeros until it reaches the new size. + * + * @param x The signal to be padded. + * @param newSize The new size of the signal. + */ + private static void padding(ArrayList x, int newSize) { + if (x.size() < newSize) { + int diff = newSize - x.size(); + for (int i = 0; i < diff; i++) { + x.add(new FFT.Complex()); + } + } + } + + /** + * Discrete circular convolution function. It uses the convolution theorem + * for discrete signals: convolved = IDFT(DFT(a)*DFT(b)). Then we use the + * FFT algorithm for faster calculations of the two DFTs and the final IDFT. + * + *

+ * More info: https://en.wikipedia.org/wiki/Convolution_theorem + * + * @param a The first signal. + * @param b The other signal. + * @return The convolved signal. + */ + public static ArrayList fftCircularConvolution( + ArrayList a, ArrayList b) { + int convolvedSize + = Math.max( + a.size(), b.size()); // The two signals must have the same size equal to the bigger one + padding(a, convolvedSize); // Zero padding the smaller signal + padding(b, convolvedSize); + + /* Find the FFTs of both signal. Here we use the Bluestein algorithm because we want the FFT to have the same length with the signal and not bigger */ + FFTBluestein.fftBluestein(a, false); + FFTBluestein.fftBluestein(b, false); + ArrayList convolved = new ArrayList<>(); + + for (int i = 0; i < a.size(); i++) { + convolved.add(a.get(i).multiply(b.get(i))); // FFT(a)*FFT(b) + } + FFTBluestein.fftBluestein(convolved, true); // IFFT + + return convolved; + } +} diff --git a/src/main/java/com/thealgorithms/maths/Combinations.java b/src/main/java/com/thealgorithms/maths/Combinations.java new file mode 100644 index 000000000000..eee9b9fc81c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Combinations.java @@ -0,0 +1,77 @@ +package com.thealgorithms.maths; + +/** + * @see Combination + */ +public class Combinations { + + public static void main(String[] args) { + assert combinations(1, 1) == 1; + assert combinations(10, 5) == 252; + assert combinations(6, 3) == 20; + assert combinations(20, 5) == 15504; + + // Since, 200 is a big number its factorial will go beyond limits of long even when 200C5 can be saved in a long + // variable. So below will fail + // assert combinations(200, 5) == 2535650040l; + assert combinationsOptimized(100, 0) == 1; + assert combinationsOptimized(1, 1) == 1; + assert combinationsOptimized(10, 5) == 252; + assert combinationsOptimized(6, 3) == 20; + assert combinationsOptimized(20, 5) == 15504; + assert combinationsOptimized(200, 5) == 2535650040l; + } + + /** + * Calculate of factorial + * + * @param n the number + * @return factorial of given number + */ + public static long factorial(int n) { + if (n < 0) { + throw new IllegalArgumentException("number is negative"); + } + return n == 0 || n == 1 ? 1 : n * factorial(n - 1); + } + + /** + * Calculate combinations + * + * @param n first number + * @param k second number + * @return combinations of given {@code n} and {@code k} + */ + public static long combinations(int n, int k) { + return factorial(n) / (factorial(k) * factorial(n - k)); + } + + /** + * The above method can exceed limit of long (overflow) when factorial(n) is + * larger than limits of long variable. Thus even if nCk is within range of + * long variable above reason can lead to incorrect result. This is an + * optimized version of computing combinations. Observations: nC(k + 1) = (n + * - k) * nCk / (k + 1) We know the value of nCk when k = 1 which is nCk = n + * Using this base value and above formula we can compute the next term + * nC(k+1) + * + * @param n + * @param k + * @return nCk + */ + public static long combinationsOptimized(int n, int k) { + if (n < 0 || k < 0) { + throw new IllegalArgumentException("n or k can't be negative"); + } + if (n < k) { + throw new IllegalArgumentException("n can't be smaller than k"); + } + // nC0 is always 1 + long solution = 1; + for (int i = 0; i < k; i++) { + long next = (n - i) * solution / (i + 1); + solution = next; + } + return solution; + } +} diff --git a/src/main/java/com/thealgorithms/maths/Convolution.java b/src/main/java/com/thealgorithms/maths/Convolution.java new file mode 100644 index 000000000000..8a89d31ad3c5 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Convolution.java @@ -0,0 +1,45 @@ +package com.thealgorithms.maths; + +/** + * Class for linear convolution of two discrete signals + * + * @author Ioannis Karavitsis + * @version 1.0 + */ +public class Convolution { + + /** + * Discrete linear convolution function. Both input signals and the output + * signal must start from 0. If you have a signal that has values before 0 + * then shift it to start from 0. + * + * @param A The first discrete signal + * @param B The second discrete signal + * @return The convolved signal + */ + public static double[] convolution(double[] A, double[] B) { + double[] convolved = new double[A.length + B.length - 1]; + + /* + The discrete convolution of two signals A and B is defined as: + + A.length + C[i] = Σ (A[k]*B[i-k]) + k=0 + + It's obvious that: 0 <= k <= A.length , 0 <= i <= A.length + B.length - 2 and 0 <= i-k <= B.length - 1 + From the last inequality we get that: i - B.length + 1 <= k <= i and thus we get the conditions below. + */ + for (int i = 0; i < convolved.length; i++) { + convolved[i] = 0; + int k = Math.max(i - B.length + 1, 0); + + while (k < i + 1 && k < A.length) { + convolved[i] += A[k] * B[i - k]; + k++; + } + } + + return convolved; + } +} diff --git a/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java b/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java new file mode 100644 index 000000000000..d7c94b7a1764 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java @@ -0,0 +1,67 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; + +/** + * Class for linear convolution of two discrete signals using the convolution + * theorem. + * + * @author Ioannis Karavitsis + * @version 1.0 + */ +public class ConvolutionFFT { + + /** + * This method pads the signal with zeros until it reaches the new size. + * + * @param x The signal to be padded. + * @param newSize The new size of the signal. + */ + private static void padding(ArrayList x, int newSize) { + if (x.size() < newSize) { + int diff = newSize - x.size(); + for (int i = 0; i < diff; i++) { + x.add(new FFT.Complex()); + } + } + } + + /** + * Discrete linear convolution function. It uses the convolution theorem for + * discrete signals convolved: = IDFT(DFT(a)*DFT(b)). This is true for + * circular convolution. In order to get the linear convolution of the two + * signals we first pad the two signals to have the same size equal to the + * convolved signal (a.size() + b.size() - 1). Then we use the FFT algorithm + * for faster calculations of the two DFTs and the final IDFT. + * + *

+ * More info: https://en.wikipedia.org/wiki/Convolution_theorem + * https://ccrma.stanford.edu/~jos/ReviewFourier/FFT_Convolution.html + * + * @param a The first signal. + * @param b The other signal. + * @return The convolved signal. + */ + public static ArrayList convolutionFFT( + ArrayList a, ArrayList b) { + int convolvedSize = a.size() + b.size() - 1; // The size of the convolved signal + padding(a, convolvedSize); // Zero padding both signals + padding(b, convolvedSize); + + /* Find the FFTs of both signals (Note that the size of the FFTs will be bigger than the convolvedSize because of the extra zero padding in FFT algorithm) */ + FFT.fft(a, false); + FFT.fft(b, false); + ArrayList convolved = new ArrayList<>(); + + for (int i = 0; i < a.size(); i++) { + convolved.add(a.get(i).multiply(b.get(i))); // FFT(a)*FFT(b) + } + FFT.fft(convolved, true); // IFFT + convolved + .subList(convolvedSize, convolved.size()) + .clear(); // Remove the remaining zeros after the convolvedSize. These extra zeros came from + // paddingPowerOfTwo() method inside the fft() method. + + return convolved; + } +} diff --git a/Maths/DeterminantOfMatrix.java b/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java similarity index 50% rename from Maths/DeterminantOfMatrix.java rename to src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java index f5ed09ca167d..fc695876b1ea 100644 --- a/Maths/DeterminantOfMatrix.java +++ b/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java @@ -1,61 +1,55 @@ -package Maths; -import java.util.*; - -/* -* @author Ojasva Jain -* Determinant of Matrix Wikipedia link : https://en.wikipedia.org/wiki/Determinant -*/ -public class DeterminantOfMatrix -{ - // Determinant calculator - //@return determinant of the input matrix - static int determinant(int a[][], int n) - { - int det = 0, sign = 1, p = 0, q = 0; - if(n==1) - { - det = a[0][0]; - } - else - { - int b[][] = new int[n-1][n-1]; - for(int x = 0 ; x < n ; x++) - { - p=0;q=0; - for(int i = 1;i < n; i++) - { - for(int j = 0; j < n;j++) - { - if(j != x) - { - b[p][q++] = a[i][j]; - if(q % (n-1) == 0) - { - p++; - q=0; - } - } - } - } - det = det + a[0][x] *determinant(b, n-1) * sign; - sign = -sign; - } - } - return det; - } - //Driver Method - public static void main(String [] args){ - Scanner in = new Scanner(System.in); - //Input Matrix - System.out.println("Enter matrix size (Square matrix only)"); - int n = in.nextInt(); - System.out.println("Enter matrix"); - int a [][] = new int [n][n]; - for(int i=0;i 0) - { - - // Extracting Last digit of the number - int rem = temp % 10; - - // Calculating sum of digits. - sum_of_digits += rem; - - // Removing the last digit - temp /= 10; - } - - //If the cube root of the number is not equal to the sum of its digits we return false. - if (cube_root != sum_of_digits) - return false; - - return true; - } - - /** Method to check if number is Dudeney Number or Not - * 1) Input - Enter a Number: 512 - * Output - It is a Dudeney Number. - * 2) Input - Enter a Number: 125 - * Output - It is not a Dudeney Number. - */ - public static void main(String args[]) throws IOException - { - BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); - System.out.println("Enter a Number: "); - int n=Integer.parseInt(br.readLine()); - if(isDudeney(n)) - { - System.out.println("It is a Dudeney Number."); - } - else - { - System.out.println("It is not a Dudeney Number."); - } - } -} \ No newline at end of file +/** + * A number is said to be Dudeney if the sum of the digits, is the cube root of the entered number. + * Example- Let the number be 512, its sum of digits is 5+1+2=8. The cube root of 512 is also 8. + * Since, the sum of the digits is equal to the cube root of the entered number; + * it is a Dudeney Number. + */ +package com.thealgorithms.maths; + +import java.io.*; + +public class DudeneyNumber { + + //returns True if the number is a Dudeney number and False if it is not a Dudeney number. + public static boolean isDudeney(int n) { + // Calculating Cube Root + int cube_root = (int) (Math.round((Math.pow(n, 1.0 / 3.0)))); + // If the number is not a perfect cube the method returns false. + if (cube_root * cube_root * cube_root != n) { + return false; + } + int sum_of_digits = 0;// Stores the sums of the digit of the entered number + int temp = n;//A temporary variable to store the entered number + // Loop to calculate sum of the digits. + while (temp > 0) { + + // Extracting Last digit of the number + int rem = temp % 10; + + // Calculating sum of digits. + sum_of_digits += rem; + + // Removing the last digit + temp /= 10; + } + + //If the cube root of the number is not equal to the sum of its digits we return false. + if (cube_root != sum_of_digits) { + return false; + } + + return true; + } + + /** + * Method to check if number is Dudeney Number or Not 1) Input - Enter a + * Number: 512 Output - It is a Dudeney Number. 2) Input - Enter a Number: + * 125 Output - It is not a Dudeney Number. + */ + public static void main(String args[]) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + System.out.println("Enter a Number: "); + int n = Integer.parseInt(br.readLine()); + if (isDudeney(n)) { + System.out.println("It is a Dudeney Number."); + } else { + System.out.println("It is not a Dudeney Number."); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/EulerMethod.java b/src/main/java/com/thealgorithms/maths/EulerMethod.java new file mode 100644 index 000000000000..c4b154bb2808 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/EulerMethod.java @@ -0,0 +1,112 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.function.BiFunction; + +/** + * In mathematics and computational science, the Euler method (also called + * forward Euler method) is a first-order numerical procedure for solving + * ordinary differential equations (ODEs) with a given initial value. It is the + * most basic explicit method for numerical integration of ordinary differential + * equations. The method proceeds in a series of steps. At each step the y-value + * is calculated by evaluating the differential equation at the previous step, + * multiplying the result with the step-size and adding it to the last y-value: + * y_n+1 = y_n + stepSize * f(x_n, y_n). (description adapted from + * https://en.wikipedia.org/wiki/Euler_method ) (see also: + * https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ ) + */ +public class EulerMethod { + + /** + * Illustrates how the algorithm is used in 3 examples and prints the + * results to the console. + */ + public static void main(String[] args) { + System.out.println("example 1:"); + BiFunction exampleEquation1 = (x, y) -> x; + ArrayList points1 = eulerFull(0, 4, 0.1, 0, exampleEquation1); + assert points1.get(points1.size() - 1)[1] == 7.800000000000003; + points1.forEach( + point -> System.out.println(String.format("x: %1$f; y: %2$f", point[0], point[1]))); + + // example from https://en.wikipedia.org/wiki/Euler_method + System.out.println("\n\nexample 2:"); + BiFunction exampleEquation2 = (x, y) -> y; + ArrayList points2 = eulerFull(0, 4, 0.1, 1, exampleEquation2); + assert points2.get(points2.size() - 1)[1] == 45.25925556817596; + points2.forEach( + point -> System.out.println(String.format("x: %1$f; y: %2$f", point[0], point[1]))); + + // example from https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ + System.out.println("\n\nexample 3:"); + BiFunction exampleEquation3 = (x, y) -> x + y + x * y; + ArrayList points3 = eulerFull(0, 0.1, 0.025, 1, exampleEquation3); + assert points3.get(points3.size() - 1)[1] == 1.1116729841674804; + points3.forEach( + point -> System.out.println(String.format("x: %1$f; y: %2$f", point[0], point[1]))); + } + + /** + * calculates the next y-value based on the current value of x, y and the + * stepSize the console. + * + * @param xCurrent Current x-value. + * @param stepSize Step-size on the x-axis. + * @param yCurrent Current y-value. + * @param differentialEquation The differential equation to be solved. + * @return The next y-value. + */ + public static double eulerStep( + double xCurrent, + double stepSize, + double yCurrent, + BiFunction differentialEquation) { + if (stepSize <= 0) { + throw new IllegalArgumentException("stepSize should be greater than zero"); + } + double yNext = yCurrent + stepSize * differentialEquation.apply(xCurrent, yCurrent); + return yNext; + } + + /** + * Loops through all the steps until xEnd is reached, adds a point for each + * step and then returns all the points + * + * @param xStart First x-value. + * @param xEnd Last x-value. + * @param stepSize Step-size on the x-axis. + * @param yStart First y-value. + * @param differentialEquation The differential equation to be solved. + * @return The points constituting the solution of the differential + * equation. + */ + public static ArrayList eulerFull( + double xStart, + double xEnd, + double stepSize, + double yStart, + BiFunction differentialEquation) { + if (xStart >= xEnd) { + throw new IllegalArgumentException("xEnd should be greater than xStart"); + } + if (stepSize <= 0) { + throw new IllegalArgumentException("stepSize should be greater than zero"); + } + + ArrayList points = new ArrayList(); + double[] firstPoint = {xStart, yStart}; + points.add(firstPoint); + double yCurrent = yStart; + double xCurrent = xStart; + + while (xCurrent < xEnd) { + // Euler method for next step + yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation); + xCurrent += stepSize; + double[] point = {xCurrent, yCurrent}; + points.add(point); + } + + return points; + } +} diff --git a/src/main/java/com/thealgorithms/maths/FFT.java b/src/main/java/com/thealgorithms/maths/FFT.java new file mode 100644 index 000000000000..56bb89de7543 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FFT.java @@ -0,0 +1,270 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Class for calculating the Fast Fourier Transform (FFT) of a discrete signal + * using the Cooley-Tukey algorithm. + * + * @author Ioannis Karavitsis + * @version 1.0 + */ +public class FFT { + + /** + * This class represents a complex number and has methods for basic + * operations. + * + *

+ * More info: + * https://introcs.cs.princeton.edu/java/32class/Complex.java.html + */ + static class Complex { + + private double real, img; + + /** + * Default Constructor. Creates the complex number 0. + */ + public Complex() { + real = 0; + img = 0; + } + + /** + * Constructor. Creates a complex number. + * + * @param r The real part of the number. + * @param i The imaginary part of the number. + */ + public Complex(double r, double i) { + real = r; + img = i; + } + + /** + * Returns the real part of the complex number. + * + * @return The real part of the complex number. + */ + public double getReal() { + return real; + } + + /** + * Returns the imaginary part of the complex number. + * + * @return The imaginary part of the complex number. + */ + public double getImaginary() { + return img; + } + + /** + * Adds this complex number to another. + * + * @param z The number to be added. + * @return The sum. + */ + public Complex add(Complex z) { + Complex temp = new Complex(); + temp.real = this.real + z.real; + temp.img = this.img + z.img; + return temp; + } + + /** + * Subtracts a number from this complex number. + * + * @param z The number to be subtracted. + * @return The difference. + */ + public Complex subtract(Complex z) { + Complex temp = new Complex(); + temp.real = this.real - z.real; + temp.img = this.img - z.img; + return temp; + } + + /** + * Multiplies this complex number by another. + * + * @param z The number to be multiplied. + * @return The product. + */ + public Complex multiply(Complex z) { + Complex temp = new Complex(); + temp.real = this.real * z.real - this.img * z.img; + temp.img = this.real * z.img + this.img * z.real; + return temp; + } + + /** + * Multiplies this complex number by a scalar. + * + * @param n The real number to be multiplied. + * @return The product. + */ + public Complex multiply(double n) { + Complex temp = new Complex(); + temp.real = this.real * n; + temp.img = this.img * n; + return temp; + } + + /** + * Finds the conjugate of this complex number. + * + * @return The conjugate. + */ + public Complex conjugate() { + Complex temp = new Complex(); + temp.real = this.real; + temp.img = -this.img; + return temp; + } + + /** + * Finds the magnitude of the complex number. + * + * @return The magnitude. + */ + public double abs() { + return Math.hypot(this.real, this.img); + } + + /** + * Divides this complex number by another. + * + * @param z The divisor. + * @return The quotient. + */ + public Complex divide(Complex z) { + Complex temp = new Complex(); + temp.real = (this.real * z.real + this.img * z.img) / (z.abs() * z.abs()); + temp.img = (this.img * z.real - this.real * z.img) / (z.abs() * z.abs()); + return temp; + } + + /** + * Divides this complex number by a scalar. + * + * @param n The divisor which is a real number. + * @return The quotient. + */ + public Complex divide(double n) { + Complex temp = new Complex(); + temp.real = this.real / n; + temp.img = this.img / n; + return temp; + } + } + + /** + * Iterative In-Place Radix-2 Cooley-Tukey Fast Fourier Transform Algorithm + * with Bit-Reversal. The size of the input signal must be a power of 2. If + * it isn't then it is padded with zeros and the output FFT will be bigger + * than the input signal. + * + *

+ * More info: + * https://www.algorithm-archive.org/contents/cooley_tukey/cooley_tukey.html + * https://www.geeksforgeeks.org/iterative-fast-fourier-transformation-polynomial-multiplication/ + * https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm + * https://cp-algorithms.com/algebra/fft.html + * + * @param x The discrete signal which is then converted to the FFT or the + * IFFT of signal x. + * @param inverse True if you want to find the inverse FFT. + */ + public static void fft(ArrayList x, boolean inverse) { + /* Pad the signal with zeros if necessary */ + paddingPowerOfTwo(x); + int N = x.size(); + + /* Find the log2(N) */ + int log2N = 0; + while ((1 << log2N) < N) { + log2N++; + } + + /* Swap the values of the signal with bit-reversal method */ + int reverse; + for (int i = 0; i < N; i++) { + reverse = reverseBits(i, log2N); + if (i < reverse) { + Collections.swap(x, i, reverse); + } + } + + int direction = inverse ? -1 : 1; + + /* Main loop of the algorithm */ + for (int len = 2; len <= N; len *= 2) { + double angle = -2 * Math.PI / len * direction; + Complex wlen = new Complex(Math.cos(angle), Math.sin(angle)); + for (int i = 0; i < N; i += len) { + Complex w = new Complex(1, 0); + for (int j = 0; j < len / 2; j++) { + Complex u = x.get(i + j); + Complex v = w.multiply(x.get(i + j + len / 2)); + x.set(i + j, u.add(v)); + x.set(i + j + len / 2, u.subtract(v)); + w = w.multiply(wlen); + } + } + } + + /* Divide by N if we want the inverse FFT */ + if (inverse) { + for (int i = 0; i < x.size(); i++) { + Complex z = x.get(i); + x.set(i, z.divide(N)); + } + } + } + + /** + * This function reverses the bits of a number. It is used in Cooley-Tukey + * FFT algorithm. + * + *

+ * E.g. num = 13 = 00001101 in binary log2N = 8 Then reversed = 176 = + * 10110000 in binary + * + *

+ * More info: https://cp-algorithms.com/algebra/fft.html + * https://www.geeksforgeeks.org/write-an-efficient-c-program-to-reverse-bits-of-a-number/ + * + * @param num The integer you want to reverse its bits. + * @param log2N The number of bits you want to reverse. + * @return The reversed number + */ + private static int reverseBits(int num, int log2N) { + int reversed = 0; + for (int i = 0; i < log2N; i++) { + if ((num & (1 << i)) != 0) { + reversed |= 1 << (log2N - 1 - i); + } + } + return reversed; + } + + /** + * This method pads an ArrayList with zeros in order to have a size equal to + * the next power of two of the previous size. + * + * @param x The ArrayList to be padded. + */ + private static void paddingPowerOfTwo(ArrayList x) { + int n = 1; + int oldSize = x.size(); + while (n < oldSize) { + n *= 2; + } + for (int i = 0; i < n - oldSize; i++) { + x.add(new Complex()); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/FFTBluestein.java b/src/main/java/com/thealgorithms/maths/FFTBluestein.java new file mode 100644 index 000000000000..b15143094997 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FFTBluestein.java @@ -0,0 +1,67 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; + +/** + * Class for calculating the Fast Fourier Transform (FFT) of a discrete signal + * using the Bluestein's algorithm. + * + * @author Ioannis Karavitsis + * @version 1.0 + */ +public class FFTBluestein { + + /** + * Bluestein's FFT Algorithm. + * + *

+ * More info: + * https://en.wikipedia.org/wiki/Chirp_Z-transform#Bluestein.27s_algorithm + * http://tka4.org/materials/lib/Articles-Books/Numerical%20Algorithms/Hartley_Trasform/Bluestein%27s%20FFT%20algorithm%20-%20Wikipedia,%20the%20free%20encyclopedia.htm + * + * @param x The discrete signal which is then converted to the FFT or the + * IFFT of signal x. + * @param inverse True if you want to find the inverse FFT. + */ + public static void fftBluestein(ArrayList x, boolean inverse) { + int N = x.size(); + int bnSize = 2 * N - 1; + int direction = inverse ? -1 : 1; + ArrayList an = new ArrayList<>(); + ArrayList bn = new ArrayList<>(); + + /* Initialization of the b(n) sequence (see Wikipedia's article above for the symbols used)*/ + for (int i = 0; i < bnSize; i++) { + bn.add(new FFT.Complex()); + } + + for (int i = 0; i < N; i++) { + double angle = (i - N + 1) * (i - N + 1) * Math.PI / N * direction; + bn.set(i, new FFT.Complex(Math.cos(angle), Math.sin(angle))); + bn.set(bnSize - i - 1, new FFT.Complex(Math.cos(angle), Math.sin(angle))); + } + + /* Initialization of the a(n) sequence */ + for (int i = 0; i < N; i++) { + double angle = -i * i * Math.PI / N * direction; + an.add(x.get(i).multiply(new FFT.Complex(Math.cos(angle), Math.sin(angle)))); + } + + ArrayList convolution = ConvolutionFFT.convolutionFFT(an, bn); + + /* The final multiplication of the convolution with the b*(k) factor */ + for (int i = 0; i < N; i++) { + double angle = -1 * i * i * Math.PI / N * direction; + FFT.Complex bk = new FFT.Complex(Math.cos(angle), Math.sin(angle)); + x.set(i, bk.multiply(convolution.get(i + N - 1))); + } + + /* Divide by N if we want the inverse FFT */ + if (inverse) { + for (int i = 0; i < N; i++) { + FFT.Complex z = x.get(i); + x.set(i, z.divide(N)); + } + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/Factorial.java b/src/main/java/com/thealgorithms/maths/Factorial.java new file mode 100644 index 000000000000..6ba6d4159721 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Factorial.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +public class Factorial { + + /* Driver Code */ + public static void main(String[] args) { + assert factorial(0) == 1; + assert factorial(1) == 1; + assert factorial(5) == 120; + assert factorial(10) == 3628800; + } + + /** + * Calculate factorial N using iteration + * + * @param n the number + * @return the factorial of {@code n} + */ + public static long factorial(int n) { + if (n < 0) { + throw new IllegalArgumentException("number is negative"); + } + long factorial = 1; + for (int i = 1; i <= n; factorial *= i, ++i) + ; + return factorial; + } +} diff --git a/src/main/java/com/thealgorithms/maths/FactorialRecursion.java b/src/main/java/com/thealgorithms/maths/FactorialRecursion.java new file mode 100644 index 000000000000..85e03c4dd1a4 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FactorialRecursion.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +public class FactorialRecursion { + + /* Driver Code */ + public static void main(String[] args) { + assert factorial(0) == 1; + assert factorial(1) == 1; + assert factorial(2) == 2; + assert factorial(3) == 6; + assert factorial(5) == 120; + } + + /** + * Recursive FactorialRecursion Method + * + * @param n The number to factorial + * @return The factorial of the number + */ + public static long factorial(int n) { + if (n < 0) { + throw new IllegalArgumentException("number is negative"); + } + return n == 0 || n == 1 ? 1 : n * factorial(n - 1); + } +} diff --git a/Maths/FibonacciJavaStreams.java b/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java similarity index 88% rename from Maths/FibonacciJavaStreams.java rename to src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java index e11365613920..f3b031b6d9f5 100644 --- a/Maths/FibonacciJavaStreams.java +++ b/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java @@ -1,4 +1,4 @@ -package Maths; +package com.thealgorithms.maths; import java.math.BigDecimal; import java.util.List; @@ -7,8 +7,8 @@ import java.util.stream.Stream; /** - * @author: caos321 - * @date: 14 October 2021 (Thursday) + * @author: caos321 + * @date: 14 October 2021 (Thursday) */ public class FibonacciJavaStreams { @@ -26,16 +26,16 @@ public static Optional calculate(final BigDecimal index) { } final List results = Stream.iterate( - index, - x -> x.compareTo(BigDecimal.ZERO) > 0, - x -> x.subtract(BigDecimal.ONE) - ) + index, + x -> x.compareTo(BigDecimal.ZERO) > 0, + x -> x.subtract(BigDecimal.ONE) + ) .reduce( List.of(), - (list, current) -> - list.isEmpty() || list.size() < 2 - ? List.of(BigDecimal.ZERO, BigDecimal.ONE) - : List.of(list.get(1), list.get(0).add(list.get(1))), + (list, current) + -> list.isEmpty() || list.size() < 2 + ? List.of(BigDecimal.ZERO, BigDecimal.ONE) + : List.of(list.get(1), list.get(0).add(list.get(1))), (list1, list2) -> list1 ); diff --git a/src/main/java/com/thealgorithms/maths/FibonacciNumber.java b/src/main/java/com/thealgorithms/maths/FibonacciNumber.java new file mode 100644 index 000000000000..41027edfb76c --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FibonacciNumber.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +/** + * Fibonacci: 0 1 1 2 3 5 8 13 21 ... + */ +public class FibonacciNumber { + + public static void main(String[] args) { + assert isFibonacciNumber(1); + assert isFibonacciNumber(2); + assert isFibonacciNumber(21); + assert !isFibonacciNumber(9); + assert !isFibonacciNumber(10); + } + + /** + * Check if a number is perfect square number + * + * @param number the number to be checked + * @return true if {@code number} is perfect square, otherwise + * false + */ + public static boolean isPerfectSquare(int number) { + int sqrt = (int) Math.sqrt(number); + return sqrt * sqrt == number; + } + + /** + * Check if a number is fibonacci number This is true if and only if at + * least one of 5x^2+4 or 5x^2-4 is a perfect square + * + * @param number the number + * @return true if {@code number} is fibonacci number, otherwise + * false + * @link https://en.wikipedia.org/wiki/Fibonacci_number#Identification + */ + public static boolean isFibonacciNumber(int number) { + return isPerfectSquare(5 * number * number + 4) || isPerfectSquare(5 * number * number - 4); + } +} diff --git a/src/main/java/com/thealgorithms/maths/FindMax.java b/src/main/java/com/thealgorithms/maths/FindMax.java new file mode 100644 index 000000000000..a7be8690952b --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FindMax.java @@ -0,0 +1,41 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; +import java.util.Random; + +public class FindMax { + + /** + * Driver Code + */ + public static void main(String[] args) { + Random random = new Random(); + + /* random size */ + int size = random.nextInt(100) + 1; + int[] array = new int[size]; + + /* init array with random numbers */ + for (int i = 0; i < size; i++) { + array[i] = random.nextInt() % 100; + } + + assert Arrays.stream(array).max().getAsInt() == findMax(array); + } + + /** + * find max of array + * + * @param array the array contains element + * @return max value of given array + */ + public static int findMax(int[] array) { + int max = array[0]; + for (int i = 1; i < array.length; ++i) { + if (array[i] > max) { + max = array[i]; + } + } + return max; + } +} diff --git a/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java new file mode 100644 index 000000000000..c38da196f46e --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java @@ -0,0 +1,55 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; +import java.util.Random; + +public class FindMaxRecursion { + + public static void main(String[] args) { + Random rand = new Random(); + + /* rand size */ + int size = rand.nextInt(100) + 1; + int[] array = new int[size]; + + /* init array with rand numbers */ + for (int i = 0; i < size; i++) { + array[i] = rand.nextInt() % 100; + } + + assert max(array, array.length) == Arrays.stream(array).max().getAsInt(); + assert max(array, 0, array.length - 1) == Arrays.stream(array).max().getAsInt(); + } + + /** + * Get max of array using divide and conquer algorithm + * + * @param array contains elements + * @param low the index of the first element + * @param high the index of the last element + * @return max of {@code array} + */ + public static int max(int[] array, int low, int high) { + if (low == high) { + return array[low]; // or array[high] + } + + int mid = (low + high) >>> 1; + + int leftMax = max(array, low, mid); // get max in [low, mid] + int rightMax = max(array, mid + 1, high); // get max in [mid+1, high] + + return Math.max(leftMax, rightMax); + } + + /** + * Get max of array using recursion algorithm + * + * @param array contains elements + * @param len length of given array + * @return max value of {@code array} + */ + public static int max(int[] array, int len) { + return len == 1 ? array[0] : Math.max(max(array, len - 1), array[len - 1]); + } +} diff --git a/src/main/java/com/thealgorithms/maths/FindMin.java b/src/main/java/com/thealgorithms/maths/FindMin.java new file mode 100644 index 000000000000..e3be09e34644 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FindMin.java @@ -0,0 +1,41 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; +import java.util.Random; + +public class FindMin { + + /** + * Driver Code + */ + public static void main(String[] args) { + Random random = new Random(); + + /* random size */ + int size = random.nextInt(100) + 1; + int[] array = new int[size]; + + /* init array with random numbers */ + for (int i = 0; i < size; i++) { + array[i] = random.nextInt() % 100; + } + + assert Arrays.stream(array).min().getAsInt() == findMin(array); + } + + /** + * Find the minimum number of an array of numbers. + * + * @param array the array contains element + * @return min value + */ + public static int findMin(int[] array) { + int min = array[0]; + for (int i = 1; i < array.length; ++i) { + if (array[i] < min) { + min = array[i]; + } + } + return min; + } +} diff --git a/src/main/java/com/thealgorithms/maths/FindMinRecursion.java b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java new file mode 100644 index 000000000000..66400d23db3f --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/FindMinRecursion.java @@ -0,0 +1,58 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; +import java.util.Random; + +public class FindMinRecursion { + + /** + * Driver Code + */ + public static void main(String[] args) { + Random rand = new Random(); + + /* rand size */ + int size = rand.nextInt(100) + 1; + int[] array = new int[size]; + + /* init array with rand numbers */ + for (int i = 0; i < size; i++) { + array[i] = rand.nextInt() % 100; + } + + assert min(array, 0, array.length - 1) == Arrays.stream(array).min().getAsInt(); + assert min(array, array.length) == Arrays.stream(array).min().getAsInt(); + } + + /** + * Get min of array using divide and conquer algorithm + * + * @param array contains elements + * @param low the index of the first element + * @param high the index of the last element + * @return min of {@code array} + */ + public static int min(int[] array, int low, int high) { + if (low == high) { + return array[low]; // or array[high] + } + + int mid = (low + high) >>> 1; + + int leftMin = min(array, low, mid); // get min in [low, mid] + int rightMin = min(array, mid + 1, high); // get min in [mid+1, high] + + return Math.min(leftMin, rightMin); + } + + /** + * Get min of array using recursion algorithm + * + * @param array contains elements + * @param len length of given array + * @return min value of {@code array} + */ + public static int min(int[] array, int len) { + return len == 1 ? array[0] : Math.min(min(array, len - 1), array[len - 1]); + } +} diff --git a/src/main/java/com/thealgorithms/maths/Floor.java b/src/main/java/com/thealgorithms/maths/Floor.java new file mode 100644 index 000000000000..bd4df6fcb852 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Floor.java @@ -0,0 +1,31 @@ +package com.thealgorithms.maths; + +import java.util.Random; + +public class Floor { + + public static void main(String[] args) { + Random random = new Random(); + for (int i = 1; i <= 1000; ++i) { + double randomNumber = random.nextDouble(); + assert floor(randomNumber) == Math.floor(randomNumber); + } + } + + /** + * Returns the largest (closest to positive infinity) + * + * @param number the number + * @return the largest (closest to positive infinity) of given + * {@code number} + */ + public static double floor(double number) { + if (number - (int) number == 0) { + return number; + } else if (number - (int) number > 0) { + return (int) number; + } else { + return (int) number - 1; + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/GCD.java b/src/main/java/com/thealgorithms/maths/GCD.java new file mode 100644 index 000000000000..14c104b509c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/GCD.java @@ -0,0 +1,58 @@ +package com.thealgorithms.maths; + +/** + * This is Euclid's algorithm which is used to find the greatest common + * denominator Overide function name gcd + * + * @author Oskar Enmalm 3/10/17 + */ +public class GCD { + + /** + * get greatest common divisor + * + * @param num1 the first number + * @param num2 the second number + * @return gcd + */ + public static int gcd(int num1, int num2) { + if (num1 < 0 || num2 < 0) { + throw new ArithmeticException(); + } + + if (num1 == 0 || num2 == 0) { + return Math.abs(num1 - num2); + } + + while (num1 % num2 != 0) { + int remainder = num1 % num2; + num1 = num2; + num2 = remainder; + } + return num2; + } + + /** + * get greatest common divisor in array + * + * @param number contains number + * @return gcd + */ + public static int gcd(int[] number) { + int result = number[0]; + for (int i = 1; i < number.length; i++) // call gcd function (input two value) + { + result = gcd(result, number[i]); + } + + return result; + } + + public static void main(String[] args) { + int[] myIntArray = {4, 16, 32}; + + // call gcd function (input array) + System.out.println(gcd(myIntArray)); // => 4 + System.out.printf("gcd(40,24)=%d gcd(24,40)=%d%n", gcd(40, 24), gcd(24, 40)); // => 8 + } +} diff --git a/src/main/java/com/thealgorithms/maths/GCDRecursion.java b/src/main/java/com/thealgorithms/maths/GCDRecursion.java new file mode 100644 index 000000000000..df9a002be0f9 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/GCDRecursion.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +/** + * @author https://github.com/shellhub/ + */ +public class GCDRecursion { + + public static void main(String[] args) { + System.out.println(gcd(20, 15)); + /* output: 5 */ + System.out.println(gcd(10, 8)); + /* output: 2 */ + System.out.println(gcd(gcd(10, 5), gcd(5, 10))); + /* output: 5 */ + } + + /** + * get greatest common divisor + * + * @param a the first number + * @param b the second number + * @return gcd + */ + public static int gcd(int a, int b) { + + if (a < 0 || b < 0) { + throw new ArithmeticException(); + } + + if (a == 0 || b == 0) { + return Math.abs(a - b); + } + + if (a % b == 0) { + return b; + } else { + return gcd(b, a % b); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/Gaussian.java b/src/main/java/com/thealgorithms/maths/Gaussian.java new file mode 100644 index 000000000000..7279e4ba05c1 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Gaussian.java @@ -0,0 +1,71 @@ +/** + * \file + * \brief [Gaussian elimination + * method](https://en.wikipedia.org/wiki/Gaussian_elimination) + */ +package com.thealgorithms.maths; + +import java.util.*; + +/** + * Main function + */ +public class Gaussian { + + public static void main(String[] args) { + int mat_size, i, j, step; + Scanner sc = new Scanner(System.in); + + System.out.println("Matrix Size : "); + mat_size = sc.nextInt(); + + double[][] mat = new double[mat_size + 1][mat_size + 1]; + double[][] x = new double[mat_size][mat_size + 1]; + + System.out.println("Enter value of the matrix"); + System.out.println(' '); + for (i = 0; i < mat_size; i++) { + for (j = 0; j <= mat_size; j++) { + mat[i][j] = sc.nextInt(); + } + } + + // perform Gaussian elimination + for (step = 0; step < mat_size - 1; step++) { + for (i = step; i < mat_size - 1; i++) { + double a = (mat[i + 1][step] / mat[step][step]); + + for (j = step; j <= mat_size; j++) { + mat[i + 1][j] = mat[i + 1][j] - (a * mat[step][j]); + } + } + } + + System.out.println("Matrix using Gaussian Elimination method: "); + System.out.println(" "); + for (i = 0; i < mat_size; i++) { + for (j = 0; j <= mat_size; j++) { + x[i][j] = mat[i][j]; + System.out.print(mat[i][j] + " "); + } + System.out.println(); + } + System.out.println("Value of the Gaussian Elimination method: "); + System.out.println(" "); + + for (i = mat_size - 1; i >= 0; i--) { + double sum = 0; + for (j = mat_size - 1; j > i; j--) { + x[i][j] = x[j][j] * x[i][j]; + sum = x[i][j] + sum; + } + if (x[i][i] == 0) { + x[i][i] = 0; + } else { + x[i][i] = (x[i][mat_size] - sum) / (x[i][i]); + } + System.out.print("x" + i + "=" + x[i][i]); + System.out.println(" "); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/GenericRoot.java b/src/main/java/com/thealgorithms/maths/GenericRoot.java new file mode 100644 index 000000000000..04e07d14432e --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/GenericRoot.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +/* + * Algorithm explanation: https://technotip.com/6774/c-program-to-find-generic-root-of-a-number/#:~:text=Generic%20Root%3A%20of%20a%20number,get%20a%20single%2Ddigit%20output.&text=For%20Example%3A%20If%20user%20input,%2B%204%20%2B%205%20%3D%2015. + */ +public class GenericRoot { + + public static void main(String[] args) { + int number1 = 1234; + int number2 = 12345; + int result1 = genericRoot(number1); + int result2 = genericRoot(number2); + System.out.println("Generic root of " + number1 + " is: " + result1); + System.out.println("Generic root of " + number2 + " is: " + result2); + } + + private static int genericRoot(int n) { + int root = 0; + while (n > 0 || root > 9) { + if (n == 0) { + n = root; + root = 0; + } + root += n % 10; + n /= 10; + } + return root; + } +} diff --git a/Maths/HarshadNumber.java b/src/main/java/com/thealgorithms/maths/HarshadNumber.java similarity index 71% rename from Maths/HarshadNumber.java rename to src/main/java/com/thealgorithms/maths/HarshadNumber.java index 22897cf38c23..153e369fb22b 100644 --- a/Maths/HarshadNumber.java +++ b/src/main/java/com/thealgorithms/maths/HarshadNumber.java @@ -1,59 +1,56 @@ // Wikipedia for Harshad Number : https://en.wikipedia.org/wiki/Harshad_number - -package Maths; +package com.thealgorithms.maths; import java.util.Scanner; -public class HarshadNumber -{ +public class HarshadNumber { + public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Enter a number : "); long a = sc.nextLong(); - + checkHarshadNumber(a); } /** - * A function to check if a number is Harshad number or not - * - * @param a The number which should be checked - */ - public static void checkHarshadNumber (long a) { - + * A function to check if a number is Harshad number or not + * + * @param a The number which should be checked + */ + public static void checkHarshadNumber(long a) { + long b = a; int sum = 0; - + // this is just for showing the explanation else it's of no use you can ommit it int[] each = new int[Long.toString(a).length()]; - + int c = 0; - + while (b > 0) { sum += b % 10; - each[c] = (int)(b%10); + each[c] = (int) (b % 10); b /= 10; c++; } - - if (a % sum == 0){ + + if (a % sum == 0) { System.out.println(a + " is a Harshad Number"); - + // For you better explanation how is that a Harshad Number System.out.println("\nExplaination :"); - - for (int i = each.length-1; i >=0; i--){ + + for (int i = each.length - 1; i >= 0; i--) { System.out.print(each[i] + " "); if (i != 0) { System.out.print("+ "); } } - + System.out.println("= " + sum); System.out.println(sum + " × " + (a / sum) + " = " + a); - } - - else { + } else { System.out.println(a + " is not a Harshad Number"); } } diff --git a/Maths/KeithNumber.java b/src/main/java/com/thealgorithms/maths/KeithNumber.java similarity index 58% rename from Maths/KeithNumber.java rename to src/main/java/com/thealgorithms/maths/KeithNumber.java index d4a3e83c8fd0..ddad3db38d5c 100644 --- a/Maths/KeithNumber.java +++ b/src/main/java/com/thealgorithms/maths/KeithNumber.java @@ -1,53 +1,52 @@ -package Maths; +package com.thealgorithms.maths; import java.util.*; -class KeithNumber -{ +class KeithNumber { + //user-defined function that checks if the given number is Keith or not - static boolean isKeith(int x) - { + static boolean isKeith(int x) { //List stores all the digits of the X - ArrayList terms=new ArrayList(); + ArrayList terms = new ArrayList(); //n denotes the number of digits - int temp = x, n = 0; + int temp = x, n = 0; //executes until the condition becomes false - while (temp > 0) - { + while (temp > 0) { //determines the last digit of the number and add it to the List - terms.add(temp%10); + terms.add(temp % 10); //removes the last digit - temp = temp/10; + temp = temp / 10; //increments the number of digits (n) by 1 - n++; - } + n++; + } //reverse the List - Collections.reverse(terms); - int next_term = 0, i = n; + Collections.reverse(terms); + int next_term = 0, i = n; //finds next term for the series //loop executes until the condition returns true - while (next_term < x) - { - next_term = 0; + while (next_term < x) { + next_term = 0; //next term is the sum of previous n terms (it depends on number of digits the number has) - for (int j=1; j<=n; j++) - next_term = next_term + terms.get(i-j); - terms.add(next_term); - i++; - } + for (int j = 1; j <= n; j++) { + next_term = next_term + terms.get(i - j); + } + terms.add(next_term); + i++; + } //when the control comes out of the while loop, there will be two conditions: //either next_term will be equal to x or greater than x //if equal, the given number is Keith, else not - return (next_term == x); - } + return (next_term == x); + } + //driver code - public static void main(String[] args) - { + public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); - if (isKeith(n)) - System.out.println("Yes, the given number is a Keith number."); - else - System.out.println("No, the given number is not a Keith number."); - } -} \ No newline at end of file + if (isKeith(n)) { + System.out.println("Yes, the given number is a Keith number."); + } else { + System.out.println("No, the given number is not a Keith number."); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java b/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java new file mode 100644 index 000000000000..10052acda684 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java @@ -0,0 +1,56 @@ +package com.thealgorithms.maths; + +/* This is a program to check if a number is a Krishnamurthy number or not. +A number is a Krishnamurthy number if the sum of the factorials of the digits of the number is equal to the number itself. +For example, 1, 2 and 145 are Krishnamurthy numbers. +Krishnamurthy number is also referred to as a Strong number. + */ +import java.io.*; + +public class KrishnamurthyNumber { + //returns True if the number is a Krishnamurthy number and False if it is not. + + public static boolean isKMurthy(int n) { + //initialising the variable s that will store the sum of the factorials of the digits to 0 + int s = 0; + //storing the number n in a temporary variable tmp + int tmp = n; + + //Krishnamurthy numbers are positive + if (n <= 0) { + return false; + } //checking if the number is a Krishnamurthy number + else { + while (n != 0) { + //initialising the variable fact that will store the factorials of the digits + int fact = 1; + //computing factorial of each digit + for (int i = 1; i <= n % 10; i++) { + fact = fact * i; + } + //computing the sum of the factorials + s = s + fact; + //discarding the digit for which factorial has been calculated + n = n / 10; + } + + //evaluating if sum of the factorials of the digits equals the number itself + if (tmp == s) { + return true; + } else { + return false; + } + } + } + + public static void main(String args[]) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + System.out.println("Enter a number to check if it is a Krishnamurthy number: "); + int n = Integer.parseInt(br.readLine()); + if (isKMurthy(n)) { + System.out.println(n + " is a Krishnamurthy number."); + } else { + System.out.println(n + " is NOT a Krishnamurthy number."); + } + } +} diff --git a/Maths/LeonardoNumber.java b/src/main/java/com/thealgorithms/maths/LeonardoNumber.java similarity index 92% rename from Maths/LeonardoNumber.java rename to src/main/java/com/thealgorithms/maths/LeonardoNumber.java index d666cab221b9..8e05d248cc33 100644 --- a/Maths/LeonardoNumber.java +++ b/src/main/java/com/thealgorithms/maths/LeonardoNumber.java @@ -1,6 +1,7 @@ -package Maths; +package com.thealgorithms.maths; public class LeonardoNumber { + public static int leonardoNumber(int n) { if (n < 0) { return 0; diff --git a/Maths/LinearDiophantineEquationsSolver.java b/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java similarity index 84% rename from Maths/LinearDiophantineEquationsSolver.java rename to src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java index 09837cc9037c..19771f62169f 100644 --- a/Maths/LinearDiophantineEquationsSolver.java +++ b/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java @@ -1,4 +1,4 @@ -package Maths; +package com.thealgorithms.maths; import java.util.Objects; @@ -41,6 +41,7 @@ private static GcdSolutionWrapper gcd(final int a, final int b, final GcdSolutio } public static final class Solution { + public static final Solution NO_SOLUTION = new Solution(Integer.MAX_VALUE, Integer.MAX_VALUE); public static final Solution INFINITE_SOLUTIONS = new Solution(Integer.MIN_VALUE, Integer.MIN_VALUE); private int x; @@ -69,11 +70,15 @@ public void setY(int y) { @Override public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; + if (obj == this) { + return true; + } + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } var that = (Solution) obj; - return this.x == that.x && - this.y == that.y; + return this.x == that.x + && this.y == that.y; } @Override @@ -83,17 +88,19 @@ public int hashCode() { @Override public String toString() { - return "Solution[" + - "x=" + x + ", " + - "y=" + y + ']'; + return "Solution[" + + "x=" + x + ", " + + "y=" + y + ']'; } } public record Equation(int a, int b, int c) { + } public static final class GcdSolutionWrapper { + private int gcd; private Solution solution; @@ -104,11 +111,15 @@ public GcdSolutionWrapper(int gcd, Solution solution) { @Override public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; + if (obj == this) { + return true; + } + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } var that = (GcdSolutionWrapper) obj; - return this.gcd == that.gcd && - Objects.equals(this.solution, that.solution); + return this.gcd == that.gcd + && Objects.equals(this.solution, that.solution); } public int getGcd() { @@ -134,9 +145,9 @@ public int hashCode() { @Override public String toString() { - return "GcdSolutionWrapper[" + - "gcd=" + gcd + ", " + - "solution=" + solution + ']'; + return "GcdSolutionWrapper[" + + "gcd=" + gcd + ", " + + "solution=" + solution + ']'; } } diff --git a/src/main/java/com/thealgorithms/maths/LucasSeries.java b/src/main/java/com/thealgorithms/maths/LucasSeries.java new file mode 100644 index 000000000000..1ac9e55717c4 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/LucasSeries.java @@ -0,0 +1,46 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Lucas_number + */ +public class LucasSeries { + + public static void main(String[] args) { + assert lucasSeries(1) == 2 && lucasSeriesIteration(1) == 2; + assert lucasSeries(2) == 1 && lucasSeriesIteration(2) == 1; + assert lucasSeries(3) == 3 && lucasSeriesIteration(3) == 3; + assert lucasSeries(4) == 4 && lucasSeriesIteration(4) == 4; + assert lucasSeries(5) == 7 && lucasSeriesIteration(5) == 7; + assert lucasSeries(6) == 11 && lucasSeriesIteration(6) == 11; + assert lucasSeries(11) == 123 && lucasSeriesIteration(11) == 123; + } + + /** + * Calculate nth number of lucas series(2, 1, 3, 4, 7, 11, 18, 29, 47, 76, + * 123, ....) using recursion + * + * @param n nth + * @return nth number of lucas series + */ + public static int lucasSeries(int n) { + return n == 1 ? 2 : n == 2 ? 1 : lucasSeries(n - 1) + lucasSeries(n - 2); + } + + /** + * Calculate nth number of lucas series(2, 1, 3, 4, 7, 11, 18, 29, 47, 76, + * 123, ....) using iteration + * + * @param n nth + * @return nth number of lucas series + */ + public static int lucasSeriesIteration(int n) { + int previous = 2; + int current = 1; + for (int i = 1; i < n; i++) { + int next = previous + current; + previous = current; + current = next; + } + return previous; + } +} diff --git a/Maths/MagicSquare.java b/src/main/java/com/thealgorithms/maths/MagicSquare.java similarity index 62% rename from Maths/MagicSquare.java rename to src/main/java/com/thealgorithms/maths/MagicSquare.java index 289e8e7b83c4..f1b187d7a6fb 100644 --- a/Maths/MagicSquare.java +++ b/src/main/java/com/thealgorithms/maths/MagicSquare.java @@ -1,4 +1,4 @@ -package Maths; +package com.thealgorithms.maths; import java.util.*; @@ -11,25 +11,23 @@ public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.print("Input a number: "); int num = sc.nextInt(); - if ((num % 2 == 0) || (num <=0 )) - { + if ((num % 2 == 0) || (num <= 0)) { System.out.print("Input number must be odd and >0"); System.exit(0); } int[][] magic_square = new int[num][num]; - int row_num = num/2; - int col_num = num-1; + int row_num = num / 2; + int col_num = num - 1; magic_square[row_num][col_num] = 1; - for (int i = 2; i <= num*num; i++) { - if (magic_square[(row_num - 1+num) % num][(col_num + 1) % num] == 0) { - row_num = (row_num - 1+num) % num; + for (int i = 2; i <= num * num; i++) { + if (magic_square[(row_num - 1 + num) % num][(col_num + 1) % num] == 0) { + row_num = (row_num - 1 + num) % num; col_num = (col_num + 1) % num; - } - else { - col_num = (col_num - 1 +num) % num; + } else { + col_num = (col_num - 1 + num) % num; } magic_square[row_num][col_num] = i; } @@ -37,12 +35,16 @@ public static void main(String[] args) { // print the square for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { - if (magic_square[i][j] < 10) System.out.print(" "); - if (magic_square[i][j] < 100) System.out.print(" "); + if (magic_square[i][j] < 10) { + System.out.print(" "); + } + if (magic_square[i][j] < 100) { + System.out.print(" "); + } System.out.print(magic_square[i][j] + " "); } System.out.println(); } } -} \ No newline at end of file +} diff --git a/Maths/MatrixUtil.java b/src/main/java/com/thealgorithms/maths/MatrixUtil.java similarity index 63% rename from Maths/MatrixUtil.java rename to src/main/java/com/thealgorithms/maths/MatrixUtil.java index c598c6534c51..dba86b7ae3de 100644 --- a/Maths/MatrixUtil.java +++ b/src/main/java/com/thealgorithms/maths/MatrixUtil.java @@ -1,4 +1,4 @@ -package Maths; +package com.thealgorithms.maths; import java.math.BigDecimal; import java.util.Arrays; @@ -29,8 +29,8 @@ public static boolean canMultiply(final BigDecimal[][] matrix1, final BigDecimal } public static Optional operate(final BigDecimal[][] matrix1, - final BigDecimal[][] matrix2, - final BiFunction operation) { + final BigDecimal[][] matrix2, + final BiFunction operation) { if (!hasEqualSizes(matrix1, matrix2)) { return Optional.empty(); } @@ -40,8 +40,8 @@ public static Optional operate(final BigDecimal[][] matrix1, final BigDecimal[][] result = new BigDecimal[rowSize][columnSize]; - IntStream.range(0, rowSize).forEach(rowIndex -> - IntStream.range(0, columnSize).forEach(columnIndex -> { + IntStream.range(0, rowSize).forEach(rowIndex + -> IntStream.range(0, columnSize).forEach(columnIndex -> { final BigDecimal value1 = matrix1[rowIndex][columnIndex]; final BigDecimal value2 = matrix2[rowIndex][columnIndex]; @@ -71,15 +71,15 @@ public static Optional multiply(final BigDecimal[][] matrix1, fi final BigDecimal[][] result = new BigDecimal[matrix1RowSize][matrix2ColumnSize]; - IntStream.range(0, matrix1RowSize).forEach(rowIndex -> - IntStream.range(0, matrix2ColumnSize).forEach(columnIndex -> - result[rowIndex][columnIndex] = IntStream.range(0, size).mapToObj(index -> { - final BigDecimal value1 = matrix1[rowIndex][index]; - final BigDecimal value2 = matrix2[index][columnIndex]; + IntStream.range(0, matrix1RowSize).forEach(rowIndex + -> IntStream.range(0, matrix2ColumnSize).forEach(columnIndex + -> result[rowIndex][columnIndex] = IntStream.range(0, size).mapToObj(index -> { + final BigDecimal value1 = matrix1[rowIndex][index]; + final BigDecimal value2 = matrix2[index][columnIndex]; - return value1.multiply(value2); - }) - .reduce(BigDecimal.ZERO, BigDecimal::add) + return value1.multiply(value2); + }) + .reduce(BigDecimal.ZERO, BigDecimal::add) ) ); @@ -99,21 +99,19 @@ public static void assertThat(final BigDecimal[][] actual, final BigDecimal[][] public static void main(final String[] args) { { final BigDecimal[][] matrix1 = { - {new BigDecimal(3), new BigDecimal(2)}, - {new BigDecimal(0), new BigDecimal(1)}, - }; + {new BigDecimal(3), new BigDecimal(2)}, + {new BigDecimal(0), new BigDecimal(1)},}; final BigDecimal[][] matrix2 = { - {new BigDecimal(1), new BigDecimal(3)}, - {new BigDecimal(2), new BigDecimal(0)}, - }; + {new BigDecimal(1), new BigDecimal(3)}, + {new BigDecimal(2), new BigDecimal(0)},}; final BigDecimal[][] actual = add(matrix1, matrix2) .orElseThrow(() -> new AssertionError("Could not compute matrix!")); final BigDecimal[][] expected = { - {new BigDecimal(4), new BigDecimal(5)}, - {new BigDecimal(2), new BigDecimal(1)} + {new BigDecimal(4), new BigDecimal(5)}, + {new BigDecimal(2), new BigDecimal(1)} }; assertThat(actual, expected); @@ -121,21 +119,19 @@ public static void main(final String[] args) { { final BigDecimal[][] matrix1 = { - {new BigDecimal(1), new BigDecimal(4)}, - {new BigDecimal(5), new BigDecimal(6)}, - }; + {new BigDecimal(1), new BigDecimal(4)}, + {new BigDecimal(5), new BigDecimal(6)},}; final BigDecimal[][] matrix2 = { - {new BigDecimal(2), new BigDecimal(0)}, - {new BigDecimal(-2), new BigDecimal(-3)}, - }; + {new BigDecimal(2), new BigDecimal(0)}, + {new BigDecimal(-2), new BigDecimal(-3)},}; final BigDecimal[][] actual = subtract(matrix1, matrix2) .orElseThrow(() -> new AssertionError("Could not compute matrix!")); final BigDecimal[][] expected = { - {new BigDecimal(-1), new BigDecimal(4)}, - {new BigDecimal(7), new BigDecimal(9)} + {new BigDecimal(-1), new BigDecimal(4)}, + {new BigDecimal(7), new BigDecimal(9)} }; assertThat(actual, expected); @@ -143,24 +139,24 @@ public static void main(final String[] args) { { final BigDecimal[][] matrix1 = { - {new BigDecimal(1), new BigDecimal(2), new BigDecimal(3)}, - {new BigDecimal(4), new BigDecimal(5), new BigDecimal(6)}, - {new BigDecimal(7), new BigDecimal(8), new BigDecimal(9)} + {new BigDecimal(1), new BigDecimal(2), new BigDecimal(3)}, + {new BigDecimal(4), new BigDecimal(5), new BigDecimal(6)}, + {new BigDecimal(7), new BigDecimal(8), new BigDecimal(9)} }; final BigDecimal[][] matrix2 = { - {new BigDecimal(1), new BigDecimal(2)}, - {new BigDecimal(3), new BigDecimal(4)}, - {new BigDecimal(5), new BigDecimal(6)} + {new BigDecimal(1), new BigDecimal(2)}, + {new BigDecimal(3), new BigDecimal(4)}, + {new BigDecimal(5), new BigDecimal(6)} }; final BigDecimal[][] actual = multiply(matrix1, matrix2) .orElseThrow(() -> new AssertionError("Could not compute matrix!")); final BigDecimal[][] expected = { - {new BigDecimal(22), new BigDecimal(28)}, - {new BigDecimal(49), new BigDecimal(64)}, - {new BigDecimal(76), new BigDecimal(100)} + {new BigDecimal(22), new BigDecimal(28)}, + {new BigDecimal(49), new BigDecimal(64)}, + {new BigDecimal(76), new BigDecimal(100)} }; assertThat(actual, expected); diff --git a/src/main/java/com/thealgorithms/maths/MaxValue.java b/src/main/java/com/thealgorithms/maths/MaxValue.java new file mode 100644 index 000000000000..a4603533a2df --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/MaxValue.java @@ -0,0 +1,34 @@ +package com.thealgorithms.maths; + +import java.util.Random; + +public class MaxValue { + + /** + * Driver Code + */ + public static void main(String[] args) { + Random rand = new Random(); + + /* test 100 times using rand numbers */ + for (int i = 1; i <= 100; ++i) { + /* generate number from -50 to 49 */ + int a = rand.nextInt(100) - 50; + int b = rand.nextInt(100) - 50; + assert max(a, b) == Math.max(a, b); + } + } + + /** + * Returns the greater of two {@code int} values. That is, the result is the + * argument closer to the value of {@link Integer#MAX_VALUE}. If the + * arguments have the same value, the result is that same value. + * + * @param a an argument. + * @param b another argument. + * @return the larger of {@code a} and {@code b}. + */ + public static int max(int a, int b) { + return a >= b ? a : b; + } +} diff --git a/src/main/java/com/thealgorithms/maths/Median.java b/src/main/java/com/thealgorithms/maths/Median.java new file mode 100644 index 000000000000..014fd07a870c --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Median.java @@ -0,0 +1,31 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Median + */ +public class Median { + + public static void main(String[] args) { + assert median(new int[]{0}) == 0; + assert median(new int[]{1, 2}) == 1.5; + assert median(new int[]{4, 1, 3, 2}) == 2.5; + assert median(new int[]{1, 3, 3, 6, 7, 8, 9}) == 6; + assert median(new int[]{1, 2, 3, 4, 5, 6, 8, 9}) == 4.5; + } + + /** + * Calculate average median + * + * @param values number series + * @return median of given {@code values} + */ + public static double median(int[] values) { + Arrays.sort(values); + int length = values.length; + return length % 2 == 0 + ? (values[length / 2] + values[length / 2 - 1]) / 2.0 + : values[length / 2]; + } +} diff --git a/src/main/java/com/thealgorithms/maths/MinValue.java b/src/main/java/com/thealgorithms/maths/MinValue.java new file mode 100644 index 000000000000..badc6c7cfb69 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/MinValue.java @@ -0,0 +1,34 @@ +package com.thealgorithms.maths; + +import java.util.Random; + +public class MinValue { + + /** + * Driver Code + */ + public static void main(String[] args) { + Random rand = new Random(); + + /* test 100 times using rand numbers */ + for (int i = 1; i <= 100; ++i) { + /* generate number from -50 to 49 */ + int a = rand.nextInt(100) - 50; + int b = rand.nextInt(100) - 50; + assert min(a, b) == Math.min(a, b); + } + } + + /** + * Returns the smaller of two {@code int} values. That is, the result the + * argument closer to the value of {@link Integer#MIN_VALUE}. If the + * arguments have the same value, the result is that same value. + * + * @param a an argument. + * @param b another argument. + * @return the smaller of {@code a} and {@code b}. + */ + public static int min(int a, int b) { + return a <= b ? a : b; + } +} diff --git a/src/main/java/com/thealgorithms/maths/Mode.java b/src/main/java/com/thealgorithms/maths/Mode.java new file mode 100644 index 000000000000..ee06b83e53b9 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Mode.java @@ -0,0 +1,61 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; + +/* + * Find the mode of an array of numbers + * + * The mode of an array of numbers is the most frequently occurring number in the array, + * or the most frequently occurring numbers if there are multiple numbers with the same frequency + */ +public class Mode { + + public static void main(String[] args) { + + /* Test array of integers */ + assert (mode(new int[]{})) == null; + assert Arrays.equals(mode(new int[]{5}), new int[]{5}); + assert Arrays.equals(mode(new int[]{1, 2, 3, 4, 5}), new int[]{1, 2, 3, 4, 5}); + assert Arrays.equals(mode(new int[]{7, 9, 9, 4, 5, 6, 7, 7, 8}), new int[]{7}); + assert Arrays.equals(mode(new int[]{7, 9, 9, 4, 5, 6, 7, 7, 9}), new int[]{7, 9}); + } + + /* + * Find the mode of an array of integers + * + * @param numbers array of integers + * @return mode of the array + */ + public static int[] mode(int[] numbers) { + + if (numbers.length == 0) { + return null; + } + + HashMap count = new HashMap<>(); + + for (int num : numbers) { + if (count.containsKey(num)) { + + count.put(num, count.get(num) + 1); + + } else { + + count.put(num, 1); + } + } + + int max = Collections.max(count.values()); + ArrayList modes = new ArrayList<>(); + + for (int num : count.keySet()) { + if (count.get(num) == max) { + modes.add(num); + } + } + return modes.stream().mapToInt(n -> n).toArray(); + } +} diff --git a/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java b/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java new file mode 100644 index 000000000000..e0e59ded7d2c --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java @@ -0,0 +1,73 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +/* + * Find the 2 elements which are non repeating in an array + * Reason to use bitwise operator: It makes our program faster as we are operating on bits and not on + * actual numbers. + */ +public class NonRepeatingElement { + + public static void main(String[] args) { + + Scanner sc = new Scanner(System.in); + int i, res = 0; + System.out.println("Enter the number of elements in the array"); + int n = sc.nextInt(); + if ((n & 1) == 1) { + //Not allowing odd number of elements as we are expecting 2 non repeating numbers + System.out.println("Array should contain even number of elements"); + return; + } + int arr[] = new int[n]; + + System.out.println("Enter " + n + " elements in the array. NOTE: Only 2 elements should not repeat"); + for (i = 0; i < n; i++) { + arr[i] = sc.nextInt(); + } + + try { + sc.close(); + } catch (Exception e) { + System.out.println("Unable to close scanner" + e); + } + + //Find XOR of the 2 non repeating elements + for (i = 0; i < n; i++) { + res ^= arr[i]; + } + + //Finding the rightmost set bit + res = res & (-res); + int num1 = 0, num2 = 0; + + for (i = 0; i < n; i++) { + if ((res & arr[i]) > 0)//Case 1 explained below + { + num1 ^= arr[i]; + } else { + num2 ^= arr[i];//Case 2 explained below + } + } + + System.out.println("The two non repeating elements are " + num1 + " and " + num2); + + } + + /* + Explanation of the code: + let us assume we have an array [1,2,1,2,3,4] + Property of XOR: num ^ num = 0. + If we XOR all the elemnets of the array we will be left with 3 ^ 4 as 1 ^ 1 and 2 ^ 2 would give 0. + Our task is to find num1 and num2 from the result of 3 ^ 4 = 7. + We need to find two's complement of 7 and find the rightmost set bit. i.e. (num & (-num)) + Two's complement of 7 is 001 and hence res = 1. + There can be 2 options when we Bitise AND this res with all the elements in our array + 1. Result will come non zero number + 2. Result will be 0. + In the first case we will XOR our element with the first number (which is initially 0) + In the second case we will XOR our element with the second number(which is initially 0) + This is how we will get non repeating elements with the help of bitwise operators. + */ +} diff --git a/Maths/NthUglyNumber.java b/src/main/java/com/thealgorithms/maths/NthUglyNumber.java similarity index 72% rename from Maths/NthUglyNumber.java rename to src/main/java/com/thealgorithms/maths/NthUglyNumber.java index cd7674e903a3..4c040f570448 100644 --- a/Maths/NthUglyNumber.java +++ b/src/main/java/com/thealgorithms/maths/NthUglyNumber.java @@ -1,7 +1,6 @@ // Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, … shows the first 11 ugly numbers. // By convention, 1 is included. // A program to find the nth Ugly number - // Algorithm : // Initialize three-pointers two, three, and five pointing to zero. // Take 3 variables nm2, nm3, and nm5 to keep track of next multiple of 2,3 and 5. @@ -12,48 +11,47 @@ // Select the minimum value from nm2, nm3, and nm5 and increment the pointer related to it. // Store the minimum value in variable next and array. // Return next. +package com.thealgorithms.maths; - - -package Maths; import java.util.*; + class NthUglyNumber { + /* Function to get the nth ugly number*/ public long getNthUglyNo(int n) { long[] ugly = new long[n]; - int two=0, three=0, five=0; - long nm2=2, nm3=3, nm5=5; + int two = 0, three = 0, five = 0; + long nm2 = 2, nm3 = 3, nm5 = 5; long next = 1; ugly[0] = 1; - for(int i=1; i{@code b}. + */ + public static long pow(int a, int b) { + long result = 1; + for (int i = 1; i <= b; i++) { + result *= a; + } + return result; + } +} diff --git a/src/main/java/com/thealgorithms/maths/PowRecursion.java b/src/main/java/com/thealgorithms/maths/PowRecursion.java new file mode 100644 index 000000000000..e8241424c6bd --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/PowRecursion.java @@ -0,0 +1,23 @@ +package com.thealgorithms.maths; + +public class PowRecursion { + + public static void main(String[] args) { + assert Double.compare(pow(2, 0), Math.pow(2, 0)) == 0; + assert Double.compare(pow(0, 2), Math.pow(0, 2)) == 0; + assert Double.compare(pow(2, 10), Math.pow(2, 10)) == 0; + assert Double.compare(pow(10, 2), Math.pow(10, 2)) == 0; + } + + /** + * Returns the value of the first argument raised to the power of the second + * argument + * + * @param a the base. + * @param b the exponent. + * @return the value {@code a}{@code b}. + */ + public static long pow(int a, int b) { + return b == 0 ? 1 : a * pow(a, b - 1); + } +} diff --git a/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java b/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java new file mode 100644 index 000000000000..88a6b63c9597 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +/** + * A utility to check if a given number is power of two or not. For example 8,16 + * etc. + */ +public class PowerOfTwoOrNot { + + public static void main(String[] args) { + assert !checkIfPowerOfTwoOrNot(0); + assert checkIfPowerOfTwoOrNot(1); + assert checkIfPowerOfTwoOrNot(8); + assert checkIfPowerOfTwoOrNot(16); + assert checkIfPowerOfTwoOrNot(1024); + } + + /** + * Checks whether given number is power of two or not. + * + * @param number the number to check + * @return {@code true} if given number is power of two, otherwise + * {@code false} + */ + public static boolean checkIfPowerOfTwoOrNot(int number) { + return number != 0 && ((number & (number - 1)) == 0); + } +} diff --git a/src/main/java/com/thealgorithms/maths/PrimeCheck.java b/src/main/java/com/thealgorithms/maths/PrimeCheck.java new file mode 100644 index 000000000000..f2587f7026b2 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/PrimeCheck.java @@ -0,0 +1,41 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +public class PrimeCheck { + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + + System.out.print("Enter a number: "); + int n = scanner.nextInt(); + if (isPrime(n)) { + System.out.println(n + " is a prime number"); + } else { + System.out.println(n + " is not a prime number"); + } + scanner.close(); + } + + /** + * * + * Checks if a number is prime or not + * + * @param n the number + * @return {@code true} if {@code n} is prime + */ + public static boolean isPrime(int n) { + if (n == 2) { + return true; + } + if (n < 2 || n % 2 == 0) { + return false; + } + for (int i = 3, limit = (int) Math.sqrt(n); i <= limit; i += 2) { + if (n % i == 0) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/thealgorithms/maths/PrimeFactorization.java b/src/main/java/com/thealgorithms/maths/PrimeFactorization.java new file mode 100644 index 000000000000..ca6f12637c89 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/PrimeFactorization.java @@ -0,0 +1,35 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +public class PrimeFactorization { + + public static void main(String[] args) { + System.out.println("## all prime factors ##"); + Scanner scanner = new Scanner(System.in); + System.out.print("Enter a number: "); + int n = scanner.nextInt(); + System.out.print(("printing factors of " + n + " : ")); + pfactors(n); + scanner.close(); + } + + public static void pfactors(int n) { + + while (n % 2 == 0) { + System.out.print(2 + " "); + n /= 2; + } + + for (int i = 3; i <= Math.sqrt(n); i += 2) { + while (n % i == 0) { + System.out.print(i + " "); + n /= i; + } + } + + if (n > 2) { + System.out.print(n); + } + } +} diff --git a/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java b/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java new file mode 100644 index 000000000000..68932c0b76bd --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java @@ -0,0 +1,34 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Pythagorean_triple + */ +public class PythagoreanTriple { + + public static void main(String[] args) { + assert isPythagTriple(3, 4, 5); + assert isPythagTriple(5, 12, 13); + assert isPythagTriple(6, 8, 10); + assert !isPythagTriple(10, 20, 30); + assert !isPythagTriple(6, 8, 100); + assert !isPythagTriple(-1, -1, 1); + } + + /** + * Check if a,b,c are a Pythagorean Triple + * + * @param a x/y component length of a right triangle + * @param b y/x component length of a right triangle + * @param c hypotenuse length of a right triangle + * @return boolean true if a, b, c satisfy the Pythagorean theorem, + * otherwise + * false + */ + public static boolean isPythagTriple(int a, int b, int c) { + if (a <= 0 || b <= 0 || c <= 0) { + return false; + } else { + return (a * a) + (b * b) == (c * c); + } + } +} diff --git a/Maths/ReverseNumber.java b/src/main/java/com/thealgorithms/maths/ReverseNumber.java similarity index 73% rename from Maths/ReverseNumber.java rename to src/main/java/com/thealgorithms/maths/ReverseNumber.java index 6f0ffa7ca3d6..5b489d9a2cf4 100644 --- a/Maths/ReverseNumber.java +++ b/src/main/java/com/thealgorithms/maths/ReverseNumber.java @@ -1,11 +1,12 @@ -package Maths; +package com.thealgorithms.maths; import java.util.Scanner; import java.util.NoSuchElementException; import java.lang.IllegalStateException; public class ReverseNumber { - public static void main(String[] args) { + + public static void main(String[] args) { int number; int reverse = 0; @@ -16,15 +17,14 @@ public static void main(String[] args) { System.out.println("ERROR: Invalid input"); return; } - - while(number != 0) { + while (number != 0) { int remainder = number % 10; - reverse = reverse * 10 + remainder; - number = number/10; + reverse = reverse * 10 + remainder; + number = number / 10; } - System.out.println("The reverse of the given number is: " + reverse); - } + System.out.println("The reverse of the given number is: " + reverse); + } } diff --git a/Maths/RomanNumeralUtil.java b/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java similarity index 84% rename from Maths/RomanNumeralUtil.java rename to src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java index 77a8c2965932..dda07a5ae819 100644 --- a/Maths/RomanNumeralUtil.java +++ b/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java @@ -1,9 +1,10 @@ -package Maths; +package com.thealgorithms.maths; /** * Translates numbers into the Roman Numeral System. * - * @see Roman numerals + * @see Roman + * numerals * @author Sokratis Fotkatzikis * @version 1.0 */ @@ -31,9 +32,9 @@ public static String generate(int number) { ); } - return RN_M[number / 1000] + - RN_C[number % 1000 / 100] + - RN_X[number % 100 / 10] + - RN_I[number % 10]; + return RN_M[number / 1000] + + RN_C[number % 1000 / 100] + + RN_X[number % 100 / 10] + + RN_I[number % 10]; } } diff --git a/Maths/SimpsonIntegration.java b/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java similarity index 85% rename from Maths/SimpsonIntegration.java rename to src/main/java/com/thealgorithms/maths/SimpsonIntegration.java index 87a7e4d26ab0..473afc4a3702 100644 --- a/Maths/SimpsonIntegration.java +++ b/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java @@ -1,8 +1,8 @@ -package Maths; +package com.thealgorithms.maths; import java.util.TreeMap; -public class SimpsonIntegration{ +public class SimpsonIntegration { /* * Calculate definite integrals by using Composite Simpson's rule. @@ -15,7 +15,6 @@ public class SimpsonIntegration{ * I = h/3 * {f(x0) + 4*f(x1) + 2*f(x2) + 4*f(x3) + ... + 2*f(xN-2) + 4*f(xN-1) + f(xN)} * */ - public static void main(String[] args) { SimpsonIntegration integration = new SimpsonIntegration(); @@ -25,13 +24,13 @@ public static void main(String[] args) { double b = 3; // Check so that N is even - if(N%2 != 0){ + if (N % 2 != 0) { System.out.println("N must be even number for Simpsons method. Aborted"); System.exit(1); } // Calculate step h and evaluate the integral - double h = (b-a) / (double) N; + double h = (b - a) / (double) N; double integralEvaluation = integration.simpsonsMethod(N, h, a); System.out.println("The integral is equal to: " + integralEvaluation); } @@ -46,13 +45,13 @@ public static void main(String[] args) { * * @return result of the integral evaluation */ - public double simpsonsMethod(int N, double h, double a){ + public double simpsonsMethod(int N, double h, double a) { TreeMap data = new TreeMap<>(); // Key: i, Value: f(xi) double temp; double xi = a; // Initialize the variable xi = x0 + 0*h // Create the table of xi and yi points - for(int i=0; i<=N; i++){ + for (int i = 0; i <= N; i++) { temp = f(xi); // Get the value of the function at that point data.put(i, temp); xi += h; // Increase the xi to the next point @@ -60,23 +59,21 @@ public double simpsonsMethod(int N, double h, double a){ // Apply the formula double integralEvaluation = 0; - for(int i=0; i + * Wikipedia: https://en.wikipedia.org/wiki/Arithmetic_progression + */ +public class SumOfArithmeticSeries { + + public static void main(String[] args) { + + /* 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 */ + assert Double.compare(55.0, sumOfSeries(1, 1, 10)) == 0; + + /* 1 + 3 + 5 + 7 + 9 + 11 + 13 + 15 + 17 + 19 */ + assert Double.compare(100.0, sumOfSeries(1, 2, 10)) == 0; + + /* 1 + 11 + 21 + 31 + 41 + 51 + 61 + 71 + 81 + 91 */ + assert Double.compare(460.0, sumOfSeries(1, 10, 10)) == 0; + + /* 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 0.6 + 0.7 + 0.8 + 0.9 + 1.0 */ + assert Double.compare(5.5, sumOfSeries(0.1, 0.1, 10)) == 0; + + assert Double.compare(49600.0, sumOfSeries(1, 10, 100)) == 0; + } + + /** + * Calculate sum of arithmetic series + * + * @param firstTerm the initial term of an arithmetic series + * @param commonDiff the common difference of an arithmetic series + * @param numOfTerms the total terms of an arithmetic series + * @return sum of given arithmetic series + */ + private static double sumOfSeries(double firstTerm, double commonDiff, int numOfTerms) { + return numOfTerms / 2.0 * (2 * firstTerm + (numOfTerms - 1) * commonDiff); + } +} diff --git a/src/main/java/com/thealgorithms/maths/SumOfDigits.java b/src/main/java/com/thealgorithms/maths/SumOfDigits.java new file mode 100644 index 000000000000..5ac8525c1d3a --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/SumOfDigits.java @@ -0,0 +1,60 @@ +package com.thealgorithms.maths; + +public class SumOfDigits { + + public static void main(String[] args) { + assert sumOfDigits(-123) == 6 && sumOfDigitsRecursion(-123) == 6 && sumOfDigitsFast(-123) == 6; + + assert sumOfDigits(0) == 0 && sumOfDigitsRecursion(0) == 0 && sumOfDigitsFast(0) == 0; + + assert sumOfDigits(12345) == 15 + && sumOfDigitsRecursion(12345) == 15 + && sumOfDigitsFast(12345) == 15; + } + + /** + * Calculate the sum of digits of a number + * + * @param number the number contains digits + * @return sum of digits of given {@code number} + */ + public static int sumOfDigits(int number) { + number = number < 0 ? -number : number; + /* calculate abs value */ + int sum = 0; + while (number != 0) { + sum += number % 10; + number /= 10; + } + return sum; + } + + /** + * Calculate the sum of digits of a number using recursion + * + * @param number the number contains digits + * @return sum of digits of given {@code number} + */ + public static int sumOfDigitsRecursion(int number) { + number = number < 0 ? -number : number; + /* calculate abs value */ + return number < 10 ? number : number % 10 + sumOfDigitsRecursion(number / 10); + } + + /** + * Calculate the sum of digits of a number using char array + * + * @param number the number contains digits + * @return sum of digits of given {@code number} + */ + public static int sumOfDigitsFast(int number) { + number = number < 0 ? -number : number; + /* calculate abs value */ + char[] digits = (number + "").toCharArray(); + int sum = 0; + for (int i = 0; i < digits.length; ++i) { + sum += digits[i] - '0'; + } + return sum; + } +} diff --git a/Maths/TrinomialTriangle.java b/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java similarity index 91% rename from Maths/TrinomialTriangle.java rename to src/main/java/com/thealgorithms/maths/TrinomialTriangle.java index 40723d54e93d..2b7ce2a9c68d 100644 --- a/Maths/TrinomialTriangle.java +++ b/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java @@ -1,16 +1,11 @@ -package Maths; +package com.thealgorithms.maths; /** * The trinomial triangle is a variation of Pascal’s triangle. The difference * between the two is that an entry in the trinomial triangle is the sum of the * three (rather than the two in Pasacal’s triangle) entries above it - * - * Example Input: n = 4 - * Output - * 1 - * 1 1 1 - * 1 2 3 2 1 - * 1 3 6 7 6 3 1 + * + * Example Input: n = 4 Output 1 1 1 1 1 2 3 2 1 1 3 6 7 6 3 1 */ public class TrinomialTriangle { diff --git a/src/main/java/com/thealgorithms/maths/VampireNumber.java b/src/main/java/com/thealgorithms/maths/VampireNumber.java new file mode 100644 index 000000000000..bdb8a61f40bc --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/VampireNumber.java @@ -0,0 +1,80 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * n number theory, a vampire number (or true vampire number) is a composite + * natural number with an even number of digits, that can be factored into two + * natural numbers each with half as many digits as the original number and not + * both with trailing zeroes, where the two factors contain precisely all the + * digits of the original number, in any order, counting multiplicity. The first + * vampire number is 1260 = 21 × 60. * + * + *

+ * link: https://en.wikipedia.org/wiki/Vampire_number * + * + *

+ */ +public class VampireNumber { + + public static void main(String[] args) { + + test(10, 1000); + } + + static void test(int startValue, int stopValue) { + int countofRes = 1; + StringBuilder res = new StringBuilder(); + + for (int i = startValue; i <= stopValue; i++) { + for (int j = i; j <= stopValue; j++) { + // System.out.println(i+ " "+ j); + if (isVampireNumber(i, j, true)) { + countofRes++; + res.append("" + countofRes + ": = ( " + i + "," + j + " = " + i * j + ")" + "\n"); + } + } + } + System.out.println(res); + } + + static boolean isVampireNumber(int a, int b, boolean noPseudoVamireNumbers) { + + // this is for pseudoVampireNumbers pseudovampire number need not be of length n/2 digits for + // example + // 126 = 6 x 21 + if (noPseudoVamireNumbers) { + if (a * 10 <= b || b * 10 <= a) { + return false; + } + } + + String mulDigits = splitIntoDigits(a * b, 0); + String faktorDigits = splitIntoDigits(a, b); + + return mulDigits.equals(faktorDigits); + } + + // methode to Split the numbers to Digits + static String splitIntoDigits(int num, int num2) { + + StringBuilder res = new StringBuilder(); + + ArrayList digits = new ArrayList<>(); + while (num > 0) { + digits.add(num % 10); + num /= 10; + } + while (num2 > 0) { + digits.add(num2 % 10); + num2 /= 10; + } + Collections.sort(digits); + for (int i : digits) { + res.append(i); + } + + return res.toString(); + } +} diff --git a/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java b/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java new file mode 100644 index 000000000000..533cfc94d738 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java @@ -0,0 +1,127 @@ +package com.thealgorithms.maths; + +/** + * @file + * + * @brief Calculates the [Cross + * Product](https://en.wikipedia.org/wiki/Cross_product) and the magnitude of + * two mathematical 3D vectors. + * + * + * @details Cross Product of two vectors gives a vector. Direction Ratios of a + * vector are the numeric parts of the given vector. They are the tree parts of + * the vector which determine the magnitude (value) of the vector. The method of + * finding a cross product is the same as finding the determinant of an order 3 + * matrix consisting of the first row with unit vectors of magnitude 1, the + * second row with the direction ratios of the first vector and the third row + * with the direction ratios of the second vector. The magnitude of a vector is + * it's value expressed as a number. Let the direction ratios of the first + * vector, P be: a, b, c Let the direction ratios of the second vector, Q be: x, + * y, z Therefore the calculation for the cross product can be arranged as: + * + * ``` P x Q: 1 1 1 a b c x y z ``` + * + * The direction ratios (DR) are calculated as follows: 1st DR, J: (b * z) - (c + * * y) 2nd DR, A: -((a * z) - (c * x)) 3rd DR, N: (a * y) - (b * x) + * + * Therefore, the direction ratios of the cross product are: J, A, N The + * following Java Program calculates the direction ratios of the cross products + * of two vector. The program uses a function, cross() for doing so. The + * direction ratios for the first and the second vector has to be passed one by + * one seperated by a space character. + * + * Magnitude of a vector is the square root of the sum of the squares of the + * direction ratios. + * + * + * For maintaining filename consistency, Vector class has been termed as + * VectorCrossProduct + * + * @author [Syed](https://github.com/roeticvampire) + */ +public class VectorCrossProduct { + + int x; + int y; + int z; + + //Default constructor, initialises all three Direction Ratios to 0 + VectorCrossProduct() { + x = 0; + y = 0; + z = 0; + } + + /** + * constructor, initialises Vector with given Direction Ratios + * + * @param _x set to x + * @param _y set to y + * @param _z set to z + */ + VectorCrossProduct(int _x, int _y, int _z) { + x = _x; + y = _y; + z = _z; + } + + /** + * Returns the magnitude of the vector + * + * @return double + */ + double magnitude() { + return Math.sqrt(x * x + y * y + z * z); + } + + /** + * Returns the dot product of the current vector with a given vector + * + * @param b: the second vector + * @return int: the dot product + */ + int dotProduct(VectorCrossProduct b) { + return x * b.x + y * b.y + z * b.z; + } + + /** + * Returns the cross product of the current vector with a given vector + * + * @param b: the second vector + * @return vectorCrossProduct: the cross product + */ + VectorCrossProduct crossProduct(VectorCrossProduct b) { + VectorCrossProduct product = new VectorCrossProduct(); + product.x = (y * b.z) - (z * b.y); + product.y = -((x * b.z) - (z * b.x)); + product.z = (x * b.y) - (y * b.x); + return product; + } + + /** + * Display the Vector + */ + void displayVector() { + System.out.println("x : " + x + "\ty : " + y + "\tz : " + z); + } + + public static void main(String[] args) { + test(); + } + + static void test() { + //Create two vectors + VectorCrossProduct A = new VectorCrossProduct(1, -2, 3); + VectorCrossProduct B = new VectorCrossProduct(2, 0, 3); + + //Determine cross product + VectorCrossProduct crossProd = A.crossProduct(B); + crossProd.displayVector(); + + //Determine dot product + int dotProd = A.dotProduct(B); + System.out.println("Dot Product of A and B: " + dotProd); + + } + +} diff --git a/src/main/java/com/thealgorithms/maths/Volume.java b/src/main/java/com/thealgorithms/maths/Volume.java new file mode 100644 index 000000000000..6a08a6c7823c --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/Volume.java @@ -0,0 +1,92 @@ +package com.thealgorithms.maths; + + +/* Find volume of various shapes.*/ +public class Volume { + + public static void main(String[] args) { + + /* test cube */ + assert Double.compare(volumeCube(7), 343.0) == 0; + + /* test cuboid */ + assert Double.compare(volumeCuboid(2, 5, 7), 70.0) == 0; + + /* test sphere */ + assert Double.compare(volumeSphere(5), 523.5987755982989) == 0; + + /* test cylinder */ + assert Double.compare(volumeCylinder(1, 2), 12.566370614359172) == 0; + + /* test hemisphere */ + assert Double.compare(volumeHemisphere(5), 261.79938779914943) == 0; + + /* test cone */ + assert Double.compare(volumeCone(5, 7), 916.297857297023) == 0; + + } + + /** + * Calculate the volume of a cube. + * + * @param sideLength side length of cube + * @return volume of given cube + */ + private static double volumeCube(double sidelength) { + return sidelength * sidelength * sidelength; + } + + /** + * Calculate the volume of a cuboid. + * + * @param width of cuboid + * @param height of cuboid + * @param length of cuboid + * @return volume of given cuboid + */ + private static double volumeCuboid(double width, double height, double length) { + return width * height * length; + } + + /** + * Calculate the volume of a sphere. + * + * @param radius radius of sphere + * @return volume of given sphere + */ + private static double volumeSphere(double radius) { + return 4 / 3 * Math.PI * radius * radius * radius; + } + + /** + * Calculate volume of a cylinder + * + * @param radius radius of the floor + * @param height height of the cylinder. + * @return volume of given cylinder + */ + private static double volumeCylinder(double radius, double height) { + return Math.PI * radius * radius * height; + } + + /** + * Calculate the volume of a hemisphere. + * + * @param radius radius of hemisphere + * @return volume of given hemisphere + */ + private static double volumeHemisphere(double radius) { + return 2 / 3 * Math.PI * radius * radius * radius; + } + + /** + * Calculate the volume of a cone. + * + * @param radius radius of cone. + * @param height of cone. + * @return volume of given cone. + */ + private static double volumeCone(double radius, double height) { + return Math.PI * radius * radius * height / 3; + } +} diff --git a/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java b/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java new file mode 100644 index 000000000000..abbd74f6a427 --- /dev/null +++ b/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java @@ -0,0 +1,76 @@ +package com.thealgorithms.matrixexponentiation; + +import java.util.Scanner; + +/** + * @author Anirudh Buvanesh (https://github.com/anirudhb11) For more information + * see https://www.geeksforgeeks.org/matrix-exponentiation/ + * + */ +public class Fibonacci { + + // Exponentiation matrix for Fibonacci sequence + private static final int[][] fibMatrix = {{1, 1}, {1, 0}}; + private static final int[][] identityMatrix = {{1, 0}, {0, 1}}; + //First 2 fibonacci numbers + private static final int[][] baseFibNumbers = {{1}, {0}}; + + /** + * Performs multiplication of 2 matrices + * + * @param matrix1 + * @param matrix2 + * @return The product of matrix1 and matrix2 + */ + private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2) { + //Check if matrices passed can be multiplied + int rowsInMatrix1 = matrix1.length; + int columnsInMatrix1 = matrix1[0].length; + + int rowsInMatrix2 = matrix2.length; + int columnsInMatrix2 = matrix2[0].length; + + assert columnsInMatrix1 == rowsInMatrix2; + int[][] product = new int[rowsInMatrix1][columnsInMatrix2]; + for (int rowIndex = 0; rowIndex < rowsInMatrix1; rowIndex++) { + for (int colIndex = 0; colIndex < columnsInMatrix2; colIndex++) { + int matrixEntry = 0; + for (int intermediateIndex = 0; intermediateIndex < columnsInMatrix1; intermediateIndex++) { + matrixEntry += matrix1[rowIndex][intermediateIndex] * matrix2[intermediateIndex][colIndex]; + } + product[rowIndex][colIndex] = matrixEntry; + } + } + return product; + } + + /** + * Calculates the fibonacci number using matrix exponentiaition technique + * + * @param n The input n for which we have to determine the fibonacci number + * Outputs the nth * fibonacci number + * @return a 2 X 1 array as { {F_n+1}, {F_n} } + */ + public static int[][] fib(int n) { + if (n == 0) { + return Fibonacci.identityMatrix; + } else { + int[][] cachedResult = fib(n / 2); + int[][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult); + if (n % 2 == 0) { + return matrixExpResult; + } else { + return matrixMultiplication(Fibonacci.fibMatrix, matrixExpResult); + } + } + } + + public static void main(String[] args) { + // Returns [0, 1, 1, 2, 3, 5 ..] for n = [0, 1, 2, 3, 4, 5.. ] + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int[][] result = matrixMultiplication(fib(n), baseFibNumbers); + System.out.println("Fib(" + n + ") = " + result[1][0]); + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java b/src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java new file mode 100644 index 000000000000..4870ae35556b --- /dev/null +++ b/src/main/java/com/thealgorithms/minimizinglateness/MinimizingLateness.java @@ -0,0 +1,61 @@ +package com.thealgorithms.minimizinglateness; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.StringTokenizer; + +public class MinimizingLateness { + + private static class Schedule { // Schedule class + + int t = 0; // Time required for the operation to be performed + int d = 0; // Time the job should be completed + int s = 0; // Start time of the task + int f = 0; // End time of the operation + + public Schedule(int t, int d) { + this.t = t; + this.d = d; + } + } + + public static void main(String[] args) throws IOException { + StringTokenizer token; + + BufferedReader in = new BufferedReader(new FileReader("MinimizingLateness/lateness_data.txt")); + String ch = in.readLine(); + if (ch == null || ch.isEmpty()) { + in.close(); + return; + } + int indexCount = Integer.parseInt(ch); + System.out.println("Input Data : "); + System.out.println(indexCount); // number of operations + Schedule[] array = new Schedule[indexCount]; // Create an array to hold the operation + int i = 0; + while ((ch = in.readLine()) != null) { + token = new StringTokenizer(ch, " "); + // Include the time required for the operation to be performed in the array and the time it + // should be completed. + array[i] + = new Schedule(Integer.parseInt(token.nextToken()), Integer.parseInt(token.nextToken())); + i++; + System.out.println(array[i - 1].t + " " + array[i - 1].d); + } + + int tryTime = 0; // Total time worked + int lateness = 0; // Lateness + for (int j = 0; j < indexCount - 1; j++) { + array[j].s = tryTime; // Start time of the task + array[j].f = tryTime + array[j].t; // Time finished + tryTime = tryTime + array[j].t; // Add total work time + // Lateness + lateness = lateness + Math.max(0, tryTime - array[j].d); + } + System.out.println(); + System.out.println("Output Data : "); + System.out.println(lateness); + in.close(); + } +} diff --git a/MinimizingLateness/lateness_data.txt b/src/main/java/com/thealgorithms/minimizinglateness/lateness_data.txt similarity index 100% rename from MinimizingLateness/lateness_data.txt rename to src/main/java/com/thealgorithms/minimizinglateness/lateness_data.txt diff --git a/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java b/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java new file mode 100644 index 000000000000..23fd2f3ead62 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java @@ -0,0 +1,108 @@ +package com.thealgorithms.misc; + +import java.awt.Color; + +/** + * @brief A Java implementation of the offcial W3 documented procedure to + * calculate contrast ratio between colors on the web. This is used to calculate + * the readability of a foreground color on top of a background color. + * @since 2020-10-15 + * @see [Color Contrast + * Ratio](https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-procedure) + * @author [Seth Falco](https://github.com/SethFalco) + */ +public class ColorContrastRatio { + + /** + * @brief Calculates the contrast ratio between two given colors. + * @param a Any color, used to get the red, green, and blue values. + * @param b Another color, which will be compared against the first color. + * @return The contrast ratio between the two colors. + */ + public double getContrastRatio(Color a, Color b) { + final double aColorLuminance = getRelativeLuminance(a); + final double bColorLuminance = getRelativeLuminance(b); + + if (aColorLuminance > bColorLuminance) { + return (aColorLuminance + 0.05) / (bColorLuminance + 0.05); + } + + return (bColorLuminance + 0.05) / (aColorLuminance + 0.05); + } + + /** + * @brief Calculates the relative luminance of a given color. + * @param color Any color, used to get the red, green, and blue values. + * @return The relative luminance of the color. + * @see [More info on relative + * luminance.](https://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef) + */ + public double getRelativeLuminance(Color color) { + final double red = getColor(color.getRed()); + final double green = getColor(color.getGreen()); + final double blue = getColor(color.getBlue()); + + return 0.2126 * red + 0.7152 * green + 0.0722 * blue; + } + + /** + * @brief Calculates the final value for a color to be used in the relative + * luminance formula as described in step 1. + * @param color8Bit 8-bit representation of a color component value. + * @return Value for the provided color component to be used in the relative + * luminance formula. + */ + public double getColor(int color8Bit) { + final double sRgb = getColorSRgb(color8Bit); + return (sRgb <= 0.03928) ? sRgb / 12.92 : Math.pow((sRgb + 0.055) / 1.055, 2.4); + } + + /** + * @brief Calculates the Color sRGB value as denoted in step 1 of the + * procedure document. + * @param color8Bit 8-bit representation of a color component value. + * @return A percentile value of the color component. + */ + private double getColorSRgb(double color8Bit) { + return color8Bit / 255.0; + } + + /** + * You can check this example against another open-source implementation + * available on GitHub. + * + * @see [Online Contrast + * Ratio](https://contrast-ratio.com/#rgb%28226%2C%20229%2C%20248-on-rgb%2823%2C%20103%2C%20154%29) + * @see [GitHub Repository for Online Contrast + * Ratio](https://github.com/LeaVerou/contrast-ratio) + */ + private static void test() { + final ColorContrastRatio algImpl = new ColorContrastRatio(); + + final Color black = Color.BLACK; + final double blackLuminance = algImpl.getRelativeLuminance(black); + assert blackLuminance == 0 : "Test 1 Failed - Incorrect relative luminance."; + + final Color white = Color.WHITE; + final double whiteLuminance = algImpl.getRelativeLuminance(white); + assert whiteLuminance == 1 : "Test 2 Failed - Incorrect relative luminance."; + + final double highestColorRatio = algImpl.getContrastRatio(black, white); + assert highestColorRatio == 21 : "Test 3 Failed - Incorrect contrast ratio."; + + final Color foreground = new Color(23, 103, 154); + final double foregroundLuminance = algImpl.getRelativeLuminance(foreground); + assert foregroundLuminance == 0.12215748057375966 : "Test 4 Failed - Incorrect relative luminance."; + + final Color background = new Color(226, 229, 248); + final double backgroundLuminance = algImpl.getRelativeLuminance(background); + assert backgroundLuminance == 0.7898468477881603 : "Test 5 Failed - Incorrect relative luminance."; + + final double contrastRatio = algImpl.getContrastRatio(foreground, background); + assert contrastRatio == 4.878363954846178 : "Test 6 Failed - Incorrect contrast ratio."; + } + + public static void main(String args[]) { + test(); + } +} diff --git a/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java b/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java new file mode 100644 index 000000000000..856117246cea --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java @@ -0,0 +1,127 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +/* +* Wikipedia link : https://en.wikipedia.org/wiki/Invertible_matrix +* +* Here we use gauss elimination method to find the inverse of a given matrix. +* To understand gauss elimination method to find inverse of a matrix: https://www.sangakoo.com/en/unit/inverse-matrix-method-of-gaussian-elimination +* +* We can also find the inverse of a matrix + */ +public class InverseOfMatrix { + + public static void main(String argv[]) { + Scanner input = new Scanner(System.in); + System.out.println("Enter the matrix size (Square matrix only): "); + int n = input.nextInt(); + double a[][] = new double[n][n]; + System.out.println("Enter the elements of matrix: "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + a[i][j] = input.nextDouble(); + } + } + + double d[][] = invert(a); + System.out.println(); + System.out.println("The inverse is: "); + for (int i = 0; i < n; ++i) { + for (int j = 0; j < n; ++j) { + System.out.print(d[i][j] + " "); + } + System.out.println(); + } + input.close(); + } + + public static double[][] invert(double a[][]) { + int n = a.length; + double x[][] = new double[n][n]; + double b[][] = new double[n][n]; + int index[] = new int[n]; + for (int i = 0; i < n; ++i) { + b[i][i] = 1; + } + + // Transform the matrix into an upper triangle + gaussian(a, index); + + // Update the matrix b[i][j] with the ratios stored + for (int i = 0; i < n - 1; ++i) { + for (int j = i + 1; j < n; ++j) { + for (int k = 0; k < n; ++k) { + b[index[j]][k] + -= a[index[j]][i] * b[index[i]][k]; + } + } + } + + // Perform backward substitutions + for (int i = 0; i < n; ++i) { + x[n - 1][i] = b[index[n - 1]][i] / a[index[n - 1]][n - 1]; + for (int j = n - 2; j >= 0; --j) { + x[j][i] = b[index[j]][i]; + for (int k = j + 1; k < n; ++k) { + x[j][i] -= a[index[j]][k] * x[k][i]; + } + x[j][i] /= a[index[j]][j]; + } + } + return x; + } + +// Method to carry out the partial-pivoting Gaussian +// elimination. Here index[] stores pivoting order. + public static void gaussian(double a[][], int index[]) { + int n = index.length; + double c[] = new double[n]; + + // Initialize the index + for (int i = 0; i < n; ++i) { + index[i] = i; + } + + // Find the rescaling factors, one from each row + for (int i = 0; i < n; ++i) { + double c1 = 0; + for (int j = 0; j < n; ++j) { + double c0 = Math.abs(a[i][j]); + if (c0 > c1) { + c1 = c0; + } + } + c[i] = c1; + } + + // Search the pivoting element from each column + int k = 0; + for (int j = 0; j < n - 1; ++j) { + double pi1 = 0; + for (int i = j; i < n; ++i) { + double pi0 = Math.abs(a[index[i]][j]); + pi0 /= c[index[i]]; + if (pi0 > pi1) { + pi1 = pi0; + k = i; + } + } + // Interchange rows according to the pivoting order + int itmp = index[j]; + index[j] = index[k]; + index[k] = itmp; + for (int i = j + 1; i < n; ++i) { + double pj = a[index[i]][j] / a[index[j]][j]; + + // Record pivoting ratios below the diagonal + a[index[i]][j] = pj; + + // Modify other elements accordingly + for (int l = j + 1; l < n; ++l) { + a[index[i]][l] -= pj * a[index[j]][l]; + } + } + } + } +} diff --git a/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java new file mode 100644 index 000000000000..0d0024c3db18 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java @@ -0,0 +1,53 @@ +package com.thealgorithms.misc; + +import java.util.Collections; +import java.util.PriorityQueue; + +/** + * @author shrutisheoran + */ +public class MedianOfRunningArray { + + private PriorityQueue p1; + private PriorityQueue p2; + + // Constructor + public MedianOfRunningArray() { + this.p1 = new PriorityQueue<>(Collections.reverseOrder()); // Max Heap + this.p2 = new PriorityQueue<>(); // Min Heap + } + + /* + Inserting lower half of array to max Heap + and upper half to min heap + */ + public void insert(Integer e) { + p2.add(e); + if (p2.size() - p1.size() > 1) { + p1.add(p2.remove()); + } + } + + /* + Returns median at any given point + */ + public Integer median() { + if (p1.size() == p2.size()) { + return (p1.peek() + p2.peek()) / 2; + } + return p1.size() > p2.size() ? p1.peek() : p2.peek(); + } + + public static void main(String[] args) { + /* + Testing the median function + */ + + MedianOfRunningArray p = new MedianOfRunningArray(); + int arr[] = {10, 7, 4, 9, 2, 3, 11, 17, 14}; + for (int i = 0; i < 9; i++) { + p.insert(arr[i]); + System.out.print(p.median() + " "); + } + } +} diff --git a/src/main/java/com/thealgorithms/misc/PalindromePrime.java b/src/main/java/com/thealgorithms/misc/PalindromePrime.java new file mode 100644 index 000000000000..58de938394af --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/PalindromePrime.java @@ -0,0 +1,49 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +public class PalindromePrime { + + public static void main(String[] args) { // Main funtion + Scanner in = new Scanner(System.in); + System.out.println("Enter the quantity of First Palindromic Primes you want"); + int n = in.nextInt(); // Input of how many first palindromic prime we want + functioning(n); // calling function - functioning + in.close(); + } + + public static boolean prime(int num) { // checking if number is prime or not + for (int divisor = 3; divisor <= Math.sqrt(num); divisor += 2) { + if (num % divisor == 0) { + return false; // false if not prime + } + } + return true; // True if prime + } + + public static int reverse(int n) { // Returns the reverse of the number + int reverse = 0; + while (n != 0) { + reverse *= 10; + reverse += n % 10; + n /= 10; + } + return reverse; + } + + public static void functioning(int y) { + if (y == 0) { + return; + } + System.out.print(2 + "\n"); // print the first Palindromic Prime + int count = 1; + int num = 3; + while (count < y) { + if (num == reverse(num) && prime(num)) { // number is prime and it's reverse is same + count++; // counts check when to terminate while loop + System.out.print(num + "\n"); // print the Palindromic Prime + } + num += 2; // inrease iterator value by two + } + } +} diff --git a/Misc/PalindromeSinglyLinkedList.java b/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java similarity index 78% rename from Misc/PalindromeSinglyLinkedList.java rename to src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java index 06a0de41cb2c..edd270c123ea 100644 --- a/Misc/PalindromeSinglyLinkedList.java +++ b/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java @@ -1,16 +1,18 @@ -package Misc; +package com.thealgorithms.misc; import java.util.Stack; -import DataStructures.Lists.SinglyLinkedList; +import com.thealgorithms.datastructures.lists.SinglyLinkedList; /** - * A simple way of knowing if a singly linked list is palindrome is to - * push all the values into a Stack and then compare the list to popped - * vales from the Stack. - * - * See more: https://www.geeksforgeeks.org/function-to-check-if-a-singly-linked-list-is-palindrome/ + * A simple way of knowing if a singly linked list is palindrome is to push all + * the values into a Stack and then compare the list to popped vales from the + * Stack. + * + * See more: + * https://www.geeksforgeeks.org/function-to-check-if-a-singly-linked-list-is-palindrome/ */ public class PalindromeSinglyLinkedList { + public static void main(String[] args) { SinglyLinkedList linkedList = new SinglyLinkedList(); diff --git a/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java b/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java new file mode 100644 index 000000000000..dabd278b2e62 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java @@ -0,0 +1,99 @@ +package com.thealgorithms.misc; + +import java.util.*; + +public class RangeInSortedArray { + + public static void main(String[] args) { + // Testcases + assert Arrays.equals(sortedRange(new int[]{1, 2, 3, 3, 3, 4, 5}, 3), new int[]{2, 4}); + assert Arrays.equals(sortedRange(new int[]{1, 2, 3, 3, 3, 4, 5}, 4), new int[]{5, 5}); + assert Arrays.equals(sortedRange(new int[]{0, 1, 2}, 3), new int[]{-1, -1}); + } + + // Get the 1st and last occurrence index of a number 'key' in a non-decreasing array 'nums' + // Gives [-1, -1] in case element doesn't exist in array + public static int[] sortedRange(int[] nums, int key) { + int[] range = new int[]{-1, -1}; + alteredBinSearchIter(nums, key, 0, nums.length - 1, range, true); + alteredBinSearchIter(nums, key, 0, nums.length - 1, range, false); + return range; + } + + // Recursive altered binary search which searches for leftmost as well as rightmost occurrence of + // 'key' + public static void alteredBinSearch( + int[] nums, int key, int left, int right, int[] range, boolean goLeft) { + if (left > right) { + return; + } + int mid = (left + right) / 2; + if (nums[mid] > key) { + alteredBinSearch(nums, key, left, mid - 1, range, goLeft); + } else if (nums[mid] < key) { + alteredBinSearch(nums, key, mid + 1, right, range, goLeft); + } else { + if (goLeft) { + if (mid == 0 || nums[mid - 1] != key) { + range[0] = mid; + } else { + alteredBinSearch(nums, key, left, mid - 1, range, goLeft); + } + } else { + if (mid == nums.length - 1 || nums[mid + 1] != key) { + range[1] = mid; + } else { + alteredBinSearch(nums, key, mid + 1, right, range, goLeft); + } + } + } + } + + // Iterative altered binary search which searches for leftmost as well as rightmost occurrence of + // 'key' + public static void alteredBinSearchIter( + int[] nums, int key, int left, int right, int[] range, boolean goLeft) { + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] > key) { + right = mid - 1; + } else if (nums[mid] < key) { + left = mid + 1; + } else { + if (goLeft) { + if (mid == 0 || nums[mid - 1] != key) { + range[0] = mid; + return; + } else { + right = mid - 1; + } + } else { + if (mid == nums.length - 1 || nums[mid + 1] != key) { + range[1] = mid; + return; + } else { + left = mid + 1; + } + } + } + } + } + + public static int getCountLessThan(int[] nums, int key) { + return getLessThan(nums, key, 0, nums.length - 1); + } + + public static int getLessThan(int[] nums, int key, int left, int right) { + int count = 0; + while (left <= right) { + int mid = (left + right) / 2; + if (nums[mid] > key) { + right = mid - 1; + } else if (nums[mid] <= key) { + count = mid + 1; // Atleast mid+1 elements exist which are <= key + left = mid + 1; + } + } + return count; + } +} diff --git a/src/main/java/com/thealgorithms/misc/Sort012D.java b/src/main/java/com/thealgorithms/misc/Sort012D.java new file mode 100644 index 000000000000..206b52d58a2b --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/Sort012D.java @@ -0,0 +1,58 @@ +package com.thealgorithms.misc; + +import java.util.*; + +/** + * The array is divided into four sections: a[1..Lo-1] zeroes a[Lo..Mid-1] ones + * a[Mid..Hi] unknown a[Hi+1..N] twos If array [mid] =0, then swap array [mid] + * with array [low] and increment both pointers once. If array [mid] = 1, then + * no swapping is required. Increment mid pointer once. If array [mid] = 2, then + * we swap array [mid] with array [high] and decrement the high pointer once. + * For more information on the Dutch national flag algorithm refer + * https://en.wikipedia.org/wiki/Dutch_national_flag_problem + */ +public class Sort012D { + + public static void main(String args[]) { + Scanner np = new Scanner(System.in); + int n = np.nextInt(); + int a[] = new int[n]; + for (int i = 0; i < n; i++) { + a[i] = np.nextInt(); + } + sort012(a); + } + + public static void sort012(int[] a) { + int l = 0; + int h = a.length - 1; + int mid = 0; + int temp; + while (mid <= h) { + switch (a[mid]) { + case 0: { + temp = a[l]; + a[l] = a[mid]; + a[mid] = temp; + l++; + mid++; + break; + } + case 1: + mid++; + break; + case 2: { + temp = a[mid]; + a[mid] = a[h]; + a[h] = temp; + h--; + break; + } + } + } + System.out.println("the Sorted array is "); + for (int i = 0; i < a.length; i++) { + System.out.print(+a[i] + " "); + } + } +} diff --git a/Misc/Sparcity.java b/src/main/java/com/thealgorithms/misc/Sparcity.java similarity index 61% rename from Misc/Sparcity.java rename to src/main/java/com/thealgorithms/misc/Sparcity.java index a14dc05e8c18..700b8c936ef0 100644 --- a/Misc/Sparcity.java +++ b/src/main/java/com/thealgorithms/misc/Sparcity.java @@ -1,47 +1,51 @@ -package Misc; -import java.util.*; -/* -*A matrix is sparse if many of its coefficients are zero (In general if 2/3rd of matrix elements are 0, it is considered as sparse). -*The interest in sparsity arises because its exploitation can lead to enormous computational savings and because many large matrix problems that occur in practice are sparse. -* -* @author Ojasva Jain -*/ - -class Sparcity{ - /* - * @return Sparcity of matrix - * - * where sparcity = number of zeroes/total elements in matrix - * - */ - static double sparcity(double [][] mat){ - int zero =0; - //Traversing the matrix to count number of zeroes - for(int i=0;i> BruteForce(int[] nums, int target) { + List> arr = new ArrayList>(); + + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + for (int k = j + 1; k < nums.length; k++) { + if (nums[i] + nums[j] + nums[k] == target) { + List temp = new ArrayList<>(); + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(nums[k]); + Collections.sort(temp); + arr.add(temp); + } + + } + } + } + arr = new ArrayList>(new LinkedHashSet>(arr)); + return arr; + } + + public List> TwoPointer(int[] nums, int target) { + Arrays.sort(nums); + List> arr = new ArrayList>(); + int start = 0; + int end = 0; + int i = 0; + while (i < nums.length - 1) { + start = i + 1; + end = nums.length - 1; + while (start < end) { + if (nums[start] + nums[end] + nums[i] == target) { + List temp = new ArrayList<>(); + temp.add(nums[i]); + temp.add(nums[start]); + temp.add(nums[end]); + arr.add(temp); + start++; + end--; + } else if (nums[start] + nums[end] + nums[i] < target) { + start += 1; + } else { + end -= 1; + } + + } + i++; + } + Set> set = new LinkedHashSet>(arr); + return new ArrayList>(set); + } + + public List> Hashmap(int[] nums, int target) { + Arrays.sort(nums); + Set> ts = new HashSet(); + HashMap hm = new HashMap<>(); + + for (int i = 0; i < nums.length; i++) { + hm.put(nums[i], i); + } + + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + int t = target - nums[i] - nums[j]; + if (hm.containsKey(t) && hm.get(t) > j) { + List temp = new ArrayList<>(); + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(t); + ts.add(temp); + } + } + } + return new ArrayList(ts); + } + +} diff --git a/src/main/java/com/thealgorithms/misc/TwoSumProblem.java b/src/main/java/com/thealgorithms/misc/TwoSumProblem.java new file mode 100644 index 000000000000..07ec58caaa25 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/TwoSumProblem.java @@ -0,0 +1,101 @@ +package com.thealgorithms.misc; + +import java.util.*; +import java.util.stream.Collectors; + +public class TwoSumProblem { + + public static void main(String args[]) { + Scanner scan = new Scanner(System.in); + System.out.print("Enter the target sum "); + int ts = scan.nextInt(); + System.out.print("Enter the number of elements in the array "); + int n = scan.nextInt(); + System.out.println("Enter all your array elements:"); + int arr[] = new int[n]; + for (int i = 0; i < n; i++) { + arr[i] = scan.nextInt(); + } + TwoSumProblem t = new TwoSumProblem(); + System.out.println("Brute Force Approach\n" + Arrays.toString(t.BruteForce(arr, ts)) + "\n"); + System.out.println("Two Pointer Approach\n" + Arrays.toString(t.TwoPointer(arr, ts)) + "\n"); + System.out.println("Hashmap Approach\n" + Arrays.toString(t.HashMap(arr, ts))); + + } + + public int[] BruteForce(int[] nums, int target) { + //Brute Force Approach + int ans[] = new int[2]; + for (int i = 0; i < nums.length; i++) { + for (int j = i + 1; j < nums.length; j++) { + if (nums[i] + nums[j] == target) { + ans[0] = i; + ans[1] = j; + + break; + } + + } + } + + return ans; + } + + public int[] TwoPointer(int[] nums, int target) { + // HashMap Approach + int ans[] = new int[2]; + HashMap hm = new HashMap(); + for (int i = 0; i < nums.length; i++) { + hm.put(i, nums[i]); + } + HashMap temp + = hm.entrySet() + .stream() + .sorted((i1, i2) + -> i1.getValue().compareTo( + i2.getValue())) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (e1, e2) -> e1, LinkedHashMap::new)); + + int start = 0; + int end = nums.length - 1; + while (start < end) { + int currSum = (Integer) temp.values().toArray()[start] + (Integer) temp.values().toArray()[end]; + + if (currSum == target) { + ans[0] = (Integer) temp.keySet().toArray()[start]; + ans[1] = (Integer) temp.keySet().toArray()[end]; + break; + } else if (currSum > target) { + end -= 1; + } else if (currSum < target) { + start += 1; + } + + } + return ans; + + } + + public int[] HashMap(int[] nums, int target) { + //Using Hashmaps + int ans[] = new int[2]; + HashMap hm = new HashMap(); + for (int i = 0; i < nums.length; i++) { + hm.put(nums[i], i); + } + for (int i = 0; i < nums.length; i++) { + int t = target - nums[i]; + if (hm.containsKey(t) && hm.get(t) != i) { + ans[0] = i; + ans[1] = hm.get(t); + break; + } + } + + return ans; + } + +} diff --git a/src/main/java/com/thealgorithms/misc/WordBoggle.java b/src/main/java/com/thealgorithms/misc/WordBoggle.java new file mode 100644 index 000000000000..625b0321eb52 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/WordBoggle.java @@ -0,0 +1,154 @@ +package com.thealgorithms.misc; + +import java.util.*; + +public class WordBoggle { + + /** + * O(nm * 8^s + ws) time where n = width of boggle board, m = height of + * boggle board, s = length of longest word in string array, w = length of + * string array, 8 is due to 8 explorable neighbours O(nm + ws) space. + */ + public static List boggleBoard(char[][] board, String[] words) { + Trie trie = new Trie(); + for (String word : words) { + trie.add(word); + } + Set finalWords = new HashSet<>(); + boolean[][] visited = new boolean[board.length][board.length]; + for (int i = 0; i < board.length; i++) { + for (int j = 0; j < board[i].length; j++) { + explore(i, j, board, trie.root, visited, finalWords); + } + } + return new ArrayList<>(finalWords); + } + + public static void main(String[] args) { + // Testcase + List ans + = new ArrayList<>( + Arrays.asList("a", "boggle", "this", "NOTRE_PEATED", "is", "simple", "board")); + assert (boggleBoard( + new char[][]{ + {'t', 'h', 'i', 's', 'i', 's', 'a'}, + {'s', 'i', 'm', 'p', 'l', 'e', 'x'}, + {'b', 'x', 'x', 'x', 'x', 'e', 'b'}, + {'x', 'o', 'g', 'g', 'l', 'x', 'o'}, + {'x', 'x', 'x', 'D', 'T', 'r', 'a'}, + {'R', 'E', 'P', 'E', 'A', 'd', 'x'}, + {'x', 'x', 'x', 'x', 'x', 'x', 'x'}, + {'N', 'O', 'T', 'R', 'E', '_', 'P'}, + {'x', 'x', 'D', 'E', 'T', 'A', 'E'},}, + new String[]{ + "this", + "is", + "not", + "a", + "simple", + "test", + "boggle", + "board", + "REPEATED", + "NOTRE_PEATED",}) + .equals(ans)); + } + + public static void explore( + int i, + int j, + char[][] board, + TrieNode trieNode, + boolean[][] visited, + Set finalWords) { + if (visited[i][j]) { + return; + } + + char letter = board[i][j]; + if (!trieNode.children.containsKey(letter)) { + return; + } + visited[i][j] = true; + trieNode = trieNode.children.get(letter); + if (trieNode.children.containsKey('*')) { + finalWords.add(trieNode.word); + } + + List neighbors = getNeighbors(i, j, board); + for (Integer[] neighbor : neighbors) { + explore(neighbor[0], neighbor[1], board, trieNode, visited, finalWords); + } + + visited[i][j] = false; + } + + public static List getNeighbors(int i, int j, char[][] board) { + List neighbors = new ArrayList<>(); + if (i > 0 && j > 0) { + neighbors.add(new Integer[]{i - 1, j - 1}); + } + + if (i > 0 && j < board[0].length - 1) { + neighbors.add(new Integer[]{i - 1, j + 1}); + } + + if (i < board.length - 1 && j < board[0].length - 1) { + neighbors.add(new Integer[]{i + 1, j + 1}); + } + + if (i < board.length - 1 && j > 0) { + neighbors.add(new Integer[]{i + 1, j - 1}); + } + + if (i > 0) { + neighbors.add(new Integer[]{i - 1, j}); + } + + if (i < board.length - 1) { + neighbors.add(new Integer[]{i + 1, j}); + } + + if (j > 0) { + neighbors.add(new Integer[]{i, j - 1}); + } + + if (j < board[0].length - 1) { + neighbors.add(new Integer[]{i, j + 1}); + } + + return neighbors; + } +} + +// Trie used to optimize string search +class TrieNode { + + Map children = new HashMap<>(); + String word = ""; +} + +class Trie { + + TrieNode root; + char endSymbol; + + public Trie() { + this.root = new TrieNode(); + this.endSymbol = '*'; + } + + public void add(String str) { + TrieNode node = this.root; + for (int i = 0; i < str.length(); i++) { + char letter = str.charAt(i); + if (!node.children.containsKey(letter)) { + TrieNode newNode = new TrieNode(); + node.children.put(letter, newNode); + } + node = node.children.get(letter); + } + node.children.put(this.endSymbol, null); + node.word = str; + } +} diff --git a/src/main/java/com/thealgorithms/misc/matrixTranspose.java b/src/main/java/com/thealgorithms/misc/matrixTranspose.java new file mode 100644 index 000000000000..63d024082777 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/matrixTranspose.java @@ -0,0 +1,78 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +/** + * + * + *

Find the Transpose of Matrix!

+ * + * Simply take input from the user and print the matrix before the transpose and + * after the transpose. + * + *

+ * Note: Giving proper comments in your program makes it more user + * friendly and it is assumed as a high quality code. + * + * @author Rajat-Jain29 + * @version 11.0.9 + * @since 2014-03-31 + */ +public class matrixTranspose { + + public static void main(String[] args) { + /* + * This is the main method + * + * @param args Unused. + * + * @return Nothing. + */ + Scanner sc = new Scanner(System.in); + int i, j, row, column; + System.out.println("Enter the number of rows in the 2D matrix:"); + + /* + * Take input from user for how many rows to be print + */ + row = sc.nextInt(); + + System.out.println("Enter the number of columns in the 2D matrix:"); + + /* + * Take input from user for how many coloumn to be print + */ + column = sc.nextInt(); + int[][] arr = new int[row][column]; + System.out.println("Enter the elements"); + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + arr[i][j] = sc.nextInt(); + } + } + + /* + * Print matrix before the Transpose in proper way + */ + System.out.println("The matrix is:"); + for (i = 0; i < row; i++) { + for (j = 0; j < column; j++) { + System.out.print(arr[i][j] + "\t"); + } + System.out.print("\n"); + } + + /* + * Print matrix after the tranpose in proper way Transpose means Interchanging + * of rows wth column so we interchange the rows in next loop Thus at last + * matrix of transpose is obtained through user input... + */ + System.out.println("The Transpose of the given matrix is:"); + for (i = 0; i < column; i++) { + for (j = 0; j < row; j++) { + System.out.print(arr[j][i] + "\t"); + } + System.out.print("\n"); + } + } +} diff --git a/Others/BFPRT.java b/src/main/java/com/thealgorithms/others/BFPRT.java similarity index 75% rename from Others/BFPRT.java rename to src/main/java/com/thealgorithms/others/BFPRT.java index 7b2adcc746ba..6ae5db8e7ff4 100644 --- a/Others/BFPRT.java +++ b/src/main/java/com/thealgorithms/others/BFPRT.java @@ -1,4 +1,4 @@ -package Others; +package com.thealgorithms.others; import java.util.Arrays; @@ -30,9 +30,9 @@ public static int getMinKthByBFPRT(int[] arr, int k) { return bfprt(copyArr, 0, copyArr.length - 1, k - 1); } - public static int[] copyArray(int[]arr) { + public static int[] copyArray(int[] arr) { int[] copyArr = new int[arr.length]; - for(int i = 0; i < arr.length; i++) { + for (int i = 0; i < arr.length; i++) { copyArr[i] = arr[i]; } return copyArr; @@ -55,6 +55,7 @@ public static int bfprt(int[] arr, int begin, int end, int i) { /** * wikipedia: https://en.wikipedia.org/wiki/Median_of_medians . + * * @param arr an array. * @param begin begin num. * @param end end num. @@ -64,38 +65,34 @@ public static int medianOfMedians(int[] arr, int begin, int end) { int num = end - begin + 1; int offset = num % 5 == 0 ? 0 : 1; int[] mArr = new int[num / 5 + offset]; - for (int i = 0;i < mArr.length;i++) { + for (int i = 0; i < mArr.length; i++) { mArr[i] = getMedian(arr, begin + i * 5, Math.min(end, begin + i * 5 + 4)); } return bfprt(mArr, 0, mArr.length - 1, mArr.length / 2); } - public static void swap(int[]arr, int i, int j) { + public static void swap(int[] arr, int i, int j) { int swap = arr[i]; arr[i] = arr[j]; arr[j] = swap; } - public static int[] partition(int[] arr,int begin,int end,int num) - { - int small=begin-1; - int cur=begin; - int big=end+1; - while(cur!=big) - { - if (arr[cur]num) - { - swap(arr,--big,cur); + public static int[] partition(int[] arr, int begin, int end, int num) { + int small = begin - 1; + int cur = begin; + int big = end + 1; + while (cur != big) { + if (arr[cur] < num) { + swap(arr, ++small, cur++); + } else if (arr[cur] > num) { + swap(arr, --big, cur); } else { cur++; } } - int[] pivotRange=new int[2]; - pivotRange[0]=small+1; - pivotRange[1]=big-1; + int[] pivotRange = new int[2]; + pivotRange[0] = small + 1; + pivotRange[1] = big - 1; return pivotRange; } @@ -110,8 +107,8 @@ public static void insertionSort(int[] arr, int begin, int end) { if (arr == null || arr.length < 2) { return; } - for (int i = begin + 1;i != end + 1;i++) { - for (int j = i;j != begin;j--) { + for (int i = begin + 1; i != end + 1; i++) { + for (int j = i; j != begin; j--) { if (arr[j - 1] > arr[j]) { swap(arr, j - 1, j); } else { @@ -122,8 +119,8 @@ public static void insertionSort(int[] arr, int begin, int end) { } public static void main(String[] args) { - int[] arr = { 11, 9, 1, 3, 9, 2, 2, 5, 6, 5, 3, 5, 9, 7, 2, 5, 5, 1, 9 }; - int[] minK = getMinKNumsByBFPRT(arr,5); + int[] arr = {11, 9, 1, 3, 9, 2, 2, 5, 6, 5, 3, 5, 9, 7, 2, 5, 5, 1, 9}; + int[] minK = getMinKNumsByBFPRT(arr, 5); System.out.println(Arrays.toString(minK)); } } diff --git a/src/main/java/com/thealgorithms/others/BankersAlgorithm.java b/src/main/java/com/thealgorithms/others/BankersAlgorithm.java new file mode 100644 index 000000000000..5ecc27dbff9b --- /dev/null +++ b/src/main/java/com/thealgorithms/others/BankersAlgorithm.java @@ -0,0 +1,180 @@ +package com.thealgorithms.others; + +/** + * This file contains an implementation of BANKER'S ALGORITM Wikipedia: + * https://en.wikipedia.org/wiki/Banker%27s_algorithm + * + * The algorithm for finding out whether or not a system is in a safe state can + * be described as follows: 1. Let Work and Finish be vectors of length ‘m’ and + * ‘n’ respectively. Initialize: Work= Available Finish [i]=false; for + * i=1,2,……,n 2. Find an i such that both a) Finish [i]=false b) Need_i<=work + * + * if no such i exists goto step (4) 3. Work=Work + Allocation_i Finish[i]= true + * goto step(2) 4. If Finish[i]=true for all i, then the system is in safe + * state. + * + * Time Complexity: O(n*n*m) Space Complexity: O(n*m) where n = number of + * processes and m = number of resources. + * + * @author AMRITESH ANAND (https://github.com/amritesh19) + */ +import java.util.Scanner; + +public class BankersAlgorithm { + + /** + * This method finds the need of each process + */ + static void calculateNeed(int needArray[][], int maxArray[][], int allocationArray[][], int totalProcess, int totalResources) { + for (int i = 0; i < totalProcess; i++) { + for (int j = 0; j < totalResources; j++) { + needArray[i][j] = maxArray[i][j] - allocationArray[i][j]; + } + } + } + + /** + * This method find the system is in safe state or not + * + * @param processes[] int array of processes (0...n-1), size = n + * @param availableArray[] int array of number of instances of each + * resource, size = m + * @param maxArray[][] int matrix(2-D array) of maximum demand of each + * process in a system, size = n*m + * @param allocationArray[][] int matrix(2-D array) of the number of + * resources of each type currently allocated to each process, size = n*m + * @param totalProcess number of total processes, n + * @param totalResources number of total resources, m + * + * @return boolean if the system is in safe state or not + */ + static boolean checkSafeSystem(int processes[], int availableArray[], int maxArray[][], int allocationArray[][], int totalProcess, int totalResources) { + int[][] needArray = new int[totalProcess][totalResources]; + + calculateNeed(needArray, maxArray, allocationArray, totalProcess, totalResources); + + boolean[] finishProcesses = new boolean[totalProcess]; + + int[] safeSequenceArray = new int[totalProcess]; + + int[] workArray = new int[totalResources]; + + for (int i = 0; i < totalResources; i++) { + workArray[i] = availableArray[i]; + } + + int count = 0; + + // While all processes are not finished or system is not in safe state. + while (count < totalProcess) { + boolean foundSafeSystem = false; + for (int m = 0; m < totalProcess; m++) { + if (finishProcesses[m] == false) { + int j; + + for (j = 0; j < totalResources; j++) { + if (needArray[m][j] > workArray[j]) { + break; + } + } + + if (j == totalResources) { + for (int k = 0; k < totalResources; k++) { + workArray[k] += allocationArray[m][k]; + } + + safeSequenceArray[count++] = m; + + finishProcesses[m] = true; + + foundSafeSystem = true; + } + } + } + + // If we could not find a next process in safe sequence. + if (foundSafeSystem == false) { + System.out.print("The system is not in the safe state because lack of resources"); + return false; + } + } + + System.out.print("The system is in safe sequence and the sequence is as follows: "); + for (int i = 0; i < totalProcess; i++) { + System.out.print("P" + safeSequenceArray[i] + " "); + } + + return true; + } + + /** + * This is main method of Banker's Algorithm + */ + public static void main(String[] args) { + int numberOfProcesses, numberOfResources; + + Scanner sc = new Scanner(System.in); + + System.out.println("Enter total number of processes"); + numberOfProcesses = sc.nextInt(); + + System.out.println("Enter total number of resources"); + numberOfResources = sc.nextInt(); + + int processes[] = new int[numberOfProcesses]; + for (int i = 0; i < numberOfProcesses; i++) { + processes[i] = i; + } + + System.out.println("--Enter the availability of--"); + + int availableArray[] = new int[numberOfResources]; + for (int i = 0; i < numberOfResources; i++) { + System.out.println("resource " + i + ": "); + availableArray[i] = sc.nextInt(); + } + + System.out.println("--Enter the maximum matrix--"); + + int maxArray[][] = new int[numberOfProcesses][numberOfResources]; + for (int i = 0; i < numberOfProcesses; i++) { + System.out.println("For process " + i + ": "); + for (int j = 0; j < numberOfResources; j++) { + System.out.println("Enter the maximum instances of resource " + j); + maxArray[i][j] = sc.nextInt(); + } + } + + System.out.println("--Enter the allocation matrix--"); + + int allocationArray[][] = new int[numberOfProcesses][numberOfResources]; + for (int i = 0; i < numberOfProcesses; i++) { + System.out.println("For process " + i + ": "); + for (int j = 0; j < numberOfResources; j++) { + System.out.println("Allocated instances of resource " + j); + allocationArray[i][j] = sc.nextInt(); + } + } + + checkSafeSystem(processes, availableArray, maxArray, allocationArray, numberOfProcesses, numberOfResources); + + sc.close(); + } +} + +/* + Example: + n = 5 + m = 3 + + Process Allocation Max Available + 0 1 2 0 1 2 0 1 2 + + 0 0 1 0 7 5 3 3 3 2 + 1 2 0 0 3 2 2 + 2 3 0 2 9 0 2 + 3 2 1 1 2 2 2 + 4 0 0 2 4 3 3 + + Result: The system is in safe sequence and the sequence is as follows: P1, P3, P4, P0, P2 + */ diff --git a/src/main/java/com/thealgorithms/others/BestFit.java b/src/main/java/com/thealgorithms/others/BestFit.java new file mode 100644 index 000000000000..f5ee41a761fd --- /dev/null +++ b/src/main/java/com/thealgorithms/others/BestFit.java @@ -0,0 +1,106 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; + +/** + * @author Dekas Dimitrios + */ +public class BestFit { + + private static final int NO_ALLOCATION + = -255; // if a process has been allocated in position -255, + // it means that it has not been actually allocated. + + /** + * Method to find the maximum valued element of an array filled with + * positive integers. + * + * @param array: an array filled with positive integers. + * @return the maximum valued element of the array. + */ + private static int findMaxElement(int[] array) { + int max = -1; + for (int value : array) { + if (value > max) { + max = value; + } + } + return max; + } + + /** + * Method to find the index of the memory block that is going to fit the + * given process based on the best fit algorithm. + * + * @param blocks: the array with the available memory blocks. + * @param process: the size of the process. + * @return the index of the block that fits, or -255 if no such block + * exists. + */ + private static int findBestFit(int[] blockSizes, int processSize) { + // Initialize minDiff with an unreachable value by a difference between a blockSize and the + // processSize. + int minDiff = findMaxElement(blockSizes); + int index + = NO_ALLOCATION; // If there is no block that can fit the process, return NO_ALLOCATION as the + // result. + for (int i = 0; + i < blockSizes.length; + i++) { // Find the most fitting memory block for the given process. + if (blockSizes[i] - processSize < minDiff && blockSizes[i] - processSize >= 0) { + minDiff = blockSizes[i] - processSize; + index = i; + } + } + return index; + } + + /** + * Method to allocate memory to blocks according to the best fit algorithm. + * It should return an ArrayList of Integers, where the index is the process + * ID (zero-indexed) and the value is the block number (also zero-indexed). + * + * @param sizeOfBlocks: an int array that contains the sizes of the memory + * blocks available. + * @param sizeOfProcesses: an int array that contains the sizes of the + * processes we need memory blocks for. + * @return the ArrayList filled with Integers repressenting the memory + * allocation that took place. + */ + static ArrayList bestFit(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the best-fit algorithm + ArrayList memAlloc = new ArrayList<>(); + // Do this for every process + for (int processSize : sizeOfProcesses) { + int chosenBlockIdx + = findBestFit( + sizeOfBlocks, processSize); // Find the index of the memory block going to be used + memAlloc.add(chosenBlockIdx); // Store the chosen block index in the memAlloc array list + if (chosenBlockIdx + != NO_ALLOCATION) { // Only if a block was chosen to store the process in it, + sizeOfBlocks[chosenBlockIdx] -= processSize; // resize the block based on the process size + } + } + return memAlloc; + } + + /** + * Method to print the memory allocated. + * + * @param memAllocation: an ArrayList of Integer representing the memory + * allocation done by the bestFit method. + */ + public static void printMemoryAllocation(ArrayList memAllocation) { + System.out.println("Process No.\tBlock No."); + System.out.println("===========\t========="); + for (int i = 0; i < memAllocation.size(); i++) { + System.out.print(" " + i + "\t\t"); + if (memAllocation.get(i) != NO_ALLOCATION) { + System.out.print(memAllocation.get(i)); + } else { + System.out.print("Not Allocated"); + } + System.out.println(); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/BoyerMoore.java b/src/main/java/com/thealgorithms/others/BoyerMoore.java new file mode 100644 index 000000000000..62566f7359fb --- /dev/null +++ b/src/main/java/com/thealgorithms/others/BoyerMoore.java @@ -0,0 +1,48 @@ +/* this Code is the illustration of Boyer moore's voting algorithm to +find the majority element is an array that appears more than n/2 times in an array +where "n" is the length of the array. +For more information on the algorithm refer https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_majority_vote_algorithm + */ +package com.thealgorithms.others; + +import java.util.*; + +public class BoyerMoore { + + public static int findmajor(int[] a) { + int count = 0; + int cand = -1; + for (int i = 0; i < a.length; i++) { + if (count == 0) { + cand = a[i]; + count = 1; + } else { + if (a[i] == cand) { + count++; + } else { + count--; + } + } + } + for (int i = 0; i < a.length; i++) { + if (a[i] == cand) { + count++; + } + } + if (count > (a.length / 2)) { + return cand; + } + return -1; + } + + public static void main(String args[]) { + Scanner input = new Scanner(System.in); + int n = input.nextInt(); + int a[] = new int[n]; + for (int i = 0; i < n; i++) { + a[i] = input.nextInt(); + } + System.out.println("the majority element is " + findmajor(a)); + + } +} diff --git a/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java b/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java new file mode 100644 index 000000000000..8730ed76338d --- /dev/null +++ b/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java @@ -0,0 +1,48 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +/** + * @author Nishita Aggarwal + *

+ * Brian Kernighan’s Algorithm + *

+ * algorithm to count the number of set bits in a given number + *

+ * Subtraction of 1 from a number toggles all the bits (from right to left) till + * the rightmost set bit(including the rightmost set bit). So if we subtract a + * number by 1 and do bitwise & with itself i.e. (n & (n-1)), we unset the + * rightmost set bit. + *

+ * If we do n & (n-1) in a loop and count the no of times loop executes we get + * the set bit count. + *

+ *

+ * Time Complexity: O(logn) + */ +public class BrianKernighanAlgorithm { + + /** + * @param num: number in which we count the set bits + * @return int: Number of set bits + */ + static int countSetBits(int num) { + int cnt = 0; + while (num != 0) { + num = num & (num - 1); + cnt++; + } + return cnt; + } + + /** + * @param args : command line arguments + */ + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + int num = sc.nextInt(); + int setBitCount = countSetBits(num); + System.out.println(setBitCount); + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/CRC32.java b/src/main/java/com/thealgorithms/others/CRC32.java new file mode 100644 index 000000000000..561a33f4dae9 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/CRC32.java @@ -0,0 +1,31 @@ +package com.thealgorithms.others; + +import java.util.BitSet; + +/** + * Generates a crc32 checksum for a given string or byte array + */ +public class CRC32 { + + public static void main(String[] args) { + System.out.println(Integer.toHexString(crc32("Hello World"))); + } + + public static int crc32(String str) { + return crc32(str.getBytes()); + } + + public static int crc32(byte[] data) { + BitSet bitSet = BitSet.valueOf(data); + int crc32 = 0xFFFFFFFF; // initial value + for (int i = 0; i < data.length * 8; i++) { + if (((crc32 >>> 31) & 1) != (bitSet.get(i) ? 1 : 0)) { + crc32 = (crc32 << 1) ^ 0x04C11DB7; // xor with polynomial + } else { + crc32 = (crc32 << 1); + } + } + crc32 = Integer.reverse(crc32); // result reflect + return crc32 ^ 0xFFFFFFFF; // final xor value + } +} diff --git a/src/main/java/com/thealgorithms/others/CRCAlgorithm.java b/src/main/java/com/thealgorithms/others/CRCAlgorithm.java new file mode 100644 index 000000000000..3b0d2f3a3003 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/CRCAlgorithm.java @@ -0,0 +1,203 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; + +/** + * @author dimgrichr + */ +public class CRCAlgorithm { + + private int correctMess; + + private int wrongMess; + + private int wrongMessCaught; + + private int wrongMessNotCaught; + + private int messSize; + + private double ber; + + private boolean messageChanged; + + private ArrayList message; + + private ArrayList dividedMessage; + + private ArrayList p; + + private Random randomGenerator; + + /** + * The algorithm's main constructor. The most significant variables, used in + * the algorithm, are set in their initial values. + * + * @param str The binary number P, in a string form, which is used by the + * CRC algorithm + * @param size The size of every transmitted message + * @param ber The Bit Error Rate + */ + public CRCAlgorithm(String str, int size, double ber) { + messageChanged = false; + message = new ArrayList<>(); + messSize = size; + dividedMessage = new ArrayList<>(); + p = new ArrayList<>(); + for (int i = 0; i < str.length(); i++) { + p.add(Character.getNumericValue(str.charAt(i))); + } + randomGenerator = new Random(); + correctMess = 0; + wrongMess = 0; + wrongMessCaught = 0; + wrongMessNotCaught = 0; + this.ber = ber; + } + + /** + * Returns the counter wrongMess + * + * @return wrongMess, the number of Wrong Messages + */ + public int getWrongMess() { + return wrongMess; + } + + /** + * Returns the counter wrongMessCaught + * + * @return wrongMessCaught, the number of wrong messages, which are caught + * by the CRC algoriithm + */ + public int getWrongMessCaught() { + return wrongMessCaught; + } + + /** + * Returns the counter wrongMessNotCaught + * + * @return wrongMessNotCaught, the number of wrong messages, which are not + * caught by the CRC algorithm + */ + public int getWrongMessNotCaught() { + return wrongMessNotCaught; + } + + /** + * Returns the counter correctMess + * + * @return correctMess, the number of the Correct Messages + */ + public int getCorrectMess() { + return correctMess; + } + + /** + * Resets some of the object's values, used on the main function, so that it + * can be re-used, in order not to waste too much memory and time, by + * creating new objects. + */ + public void refactor() { + messageChanged = false; + message = new ArrayList<>(); + dividedMessage = new ArrayList<>(); + } + + /** + * Random messages, consisted of 0's and 1's, are generated, so that they + * can later be transmitted + */ + public void generateRandomMess() { + for (int i = 0; i < messSize; i++) { + int x = ThreadLocalRandom.current().nextInt(0, 2); + message.add(x); + } + } + + /** + * The most significant part of the CRC algorithm. The message is divided by + * P, so the dividedMessage ArrayList is created. If check == true, + * the dividedMessaage is examined, in order to see if it contains any 1's. + * If it does, the message is considered to be wrong by the receiver,so the + * variable wrongMessCaught changes. If it does not, it is accepted, so one + * of the variables correctMess, wrongMessNotCaught, changes. If check == + * false, the diviided Message is added at the end of the ArrayList + * message. + * + * @param check the variable used to determine, if the message is going to + * be checked from the receiver if true, it is checked otherwise, it is not + */ + public void divideMessageWithP(boolean check) { + ArrayList x = new ArrayList<>(); + ArrayList k = (ArrayList) message.clone(); + if (!check) { + for (int i = 0; i < p.size() - 1; i++) { + k.add(0); + } + } + while (!k.isEmpty()) { + while (x.size() < p.size() && !k.isEmpty()) { + x.add(k.get(0)); + k.remove(0); + } + if (x.size() == p.size()) { + for (int i = 0; i < p.size(); i++) { + if (x.get(i) == p.get(i)) { + x.set(i, 0); + } else { + x.set(i, 1); + } + } + for (int i = 0; i < x.size() && x.get(i) != 1; i++) { + x.remove(0); + } + } + } + dividedMessage = (ArrayList) x.clone(); + if (!check) { + for (int z : dividedMessage) { + message.add(z); + } + } else { + if (dividedMessage.contains(1) && messageChanged) { + wrongMessCaught++; + } else if (!dividedMessage.contains(1) && messageChanged) { + wrongMessNotCaught++; + } else if (!messageChanged) { + correctMess++; + } + } + } + + /** + * Once the message is transmitted, some of it's elements, is possible to + * change from 1 to 0, or from 0 to 1, because of the Bit Error Rate (ber). + * For every element of the message, a random double number is created. If + * that number is smaller than ber, then the spesific element changes. On + * the other hand, if it's bigger than ber, it does not. Based on these + * changes. the boolean variable messageChanged, gets the value: true, or + * false. + */ + public void changeMess() { + for (int y : message) { + double x = randomGenerator.nextDouble(); + while (x < 0.0000 || x > 1.00000) { + x = randomGenerator.nextDouble(); + } + if (x < ber) { + messageChanged = true; + if (y == 1) { + message.set(message.indexOf(y), 0); + } else { + message.set(message.indexOf(y), 1); + } + } + } + if (messageChanged) { + wrongMess++; + } + } +} diff --git a/src/main/java/com/thealgorithms/others/CountChar.java b/src/main/java/com/thealgorithms/others/CountChar.java new file mode 100644 index 000000000000..40c0db86b178 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/CountChar.java @@ -0,0 +1,24 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +public class CountChar { + + public static void main(String[] args) { + Scanner input = new Scanner(System.in); + System.out.print("Enter your text: "); + String str = input.nextLine(); + input.close(); + System.out.println("There are " + CountCharacters(str) + " characters."); + } + + /** + * Count non space character in string + * + * @param str String to count the characters + * @return number of character in the specified string + */ + private static int CountCharacters(String str) { + return str.replaceAll("\\s", "").length(); + } +} diff --git a/src/main/java/com/thealgorithms/others/CountWords.java b/src/main/java/com/thealgorithms/others/CountWords.java new file mode 100644 index 000000000000..66b8f148bcf1 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/CountWords.java @@ -0,0 +1,51 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +/** + * You enter a string into this program, and it will return how many words were + * in that particular string + * + * @author Marcus + */ +public class CountWords { + + public static void main(String[] args) { + Scanner input = new Scanner(System.in); + System.out.println("Enter your text: "); + String str = input.nextLine(); + + System.out.println("Your text has " + wordCount(str) + " word(s)"); + System.out.println("Your text has " + secondaryWordCount(str) + " word(s)"); + input.close(); + } + + private static int wordCount(String s) { + if (s == null || s.isEmpty()) { + return 0; + } + return s.trim().split("[\\s]+").length; + } + + /** + * counts the number of words in a sentence but ignores all potential + * non-alphanumeric characters that do not represent a word. runs in O(n) + * where n is the length of s + * + * @param s String: sentence with word(s) + * @return int: number of words + */ + private static int secondaryWordCount(String s) { + if (s == null || s.isEmpty()) { + return 0; + } + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + if (Character.isLetter(c) || Character.isDigit(c)) { + sb.append(c); + } + } + s = sb.toString(); + return s.trim().split("[\\s]+").length; + } +} diff --git a/Others/Damm.java b/src/main/java/com/thealgorithms/others/Damm.java similarity index 72% rename from Others/Damm.java rename to src/main/java/com/thealgorithms/others/Damm.java index 8334c4cad280..7e4240d7f363 100644 --- a/Others/Damm.java +++ b/src/main/java/com/thealgorithms/others/Damm.java @@ -1,25 +1,27 @@ -package Others; +package com.thealgorithms.others; import java.util.Objects; /** - * Damm algorithm is a check digit algorithm that detects all single-digit errors - * and all adjacent transposition errors. It was presented by H. Michael Damm in 2004. - * Essential part of the algorithm is a quasigroup of order 10 - * (i.e. having a 10 × 10 Latin square as the body of its operation table) - * with the special feature of being weakly totally anti-symmetric. - * Damm revealed several methods to create totally anti-symmetric quasigroups - * of order 10 and gave some examples in his doctoral dissertation. + * Damm algorithm is a check digit algorithm that detects all single-digit + * errors and all adjacent transposition errors. It was presented by H. Michael + * Damm in 2004. Essential part of the algorithm is a quasigroup of order 10 + * (i.e. having a 10 × 10 Latin square as the body of its operation table) with + * the special feature of being weakly totally anti-symmetric. Damm revealed + * several methods to create totally anti-symmetric quasigroups of order 10 and + * gave some examples in his doctoral dissertation. * - * @see Wiki. Damm algorithm + * @see Wiki. Damm + * algorithm */ public class Damm { /** - * Weakly totally anti-symmetric quasigroup of order 10. - * This table is not the only possible realisation of weak totally anti-symmetric - * quasigroup but the most common one (taken from Damm doctoral dissertation). - * All zeros lay on the diagonal because it simplifies the check digit calculation. + * Weakly totally anti-symmetric quasigroup of order 10. This table is not + * the only possible realisation of weak totally anti-symmetric quasigroup + * but the most common one (taken from Damm doctoral dissertation). All + * zeros lay on the diagonal because it simplifies the check digit + * calculation. */ private static final byte[][] DAMM_TABLE = { {0, 3, 1, 7, 5, 9, 8, 6, 4, 2}, @@ -39,8 +41,9 @@ public class Damm { * * @param digits input to check * @return true if check was successful, false otherwise - * @throws IllegalArgumentException if input parameter contains not only digits - * @throws NullPointerException if input is null + * @throws IllegalArgumentException if input parameter contains not only + * digits + * @throws NullPointerException if input is null */ public static boolean dammCheck(String digits) { checkInput(digits); @@ -55,12 +58,14 @@ public static boolean dammCheck(String digits) { } /** - * Calculate check digit for initial digits and add it tho the last position. + * Calculate check digit for initial digits and add it tho the last + * position. * * @param initialDigits initial value * @return digits with the checksum in the last position - * @throws IllegalArgumentException if input parameter contains not only digits - * @throws NullPointerException if input is null + * @throws IllegalArgumentException if input parameter contains not only + * digits + * @throws NullPointerException if input is null */ public static String addDammChecksum(String initialDigits) { checkInput(initialDigits); @@ -88,8 +93,8 @@ public static void main(String[] args) { private static void checkAndPrint(String input) { String validationResult = Damm.dammCheck(input) - ? "valid" - : "not valid"; + ? "valid" + : "not valid"; System.out.println("Input '" + input + "' is " + validationResult); } @@ -107,7 +112,7 @@ private static void checkInput(String input) { private static int[] toIntArray(String string) { return string.chars() - .map(i -> Character.digit(i, 10)) - .toArray(); + .map(i -> Character.digit(i, 10)) + .toArray(); } } diff --git a/src/main/java/com/thealgorithms/others/Dijkstra.java b/src/main/java/com/thealgorithms/others/Dijkstra.java new file mode 100644 index 000000000000..9a8b9d130254 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/Dijkstra.java @@ -0,0 +1,243 @@ +package com.thealgorithms.others; + +/** + * Dijkstra's algorithm,is a graph search algorithm that solves the + * single-source shortest path problem for a graph with nonnegative edge path + * costs, producing a shortest path tree. + * + *

+ * NOTE: The inputs to Dijkstra's algorithm are a directed and weighted graph + * consisting of 2 or more nodes, generally represented by an adjacency matrix + * or list, and a start node. + * + *

+ * Original source of code: + * https://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java Also most of the + * comments are from RosettaCode. + */ +import java.util.*; + +public class Dijkstra { + + private static final Graph.Edge[] GRAPH = { + // Distance from node "a" to node "b" is 7. + // In the current Graph there is no way to move the other way (e,g, from "b" to "a"), + // a new edge would be needed for that + new Graph.Edge("a", "b", 7), + new Graph.Edge("a", "c", 9), + new Graph.Edge("a", "f", 14), + new Graph.Edge("b", "c", 10), + new Graph.Edge("b", "d", 15), + new Graph.Edge("c", "d", 11), + new Graph.Edge("c", "f", 2), + new Graph.Edge("d", "e", 6), + new Graph.Edge("e", "f", 9),}; + private static final String START = "a"; + private static final String END = "e"; + + /** + * main function Will run the code with "GRAPH" that was defined above. + */ + public static void main(String[] args) { + Graph g = new Graph(GRAPH); + g.dijkstra(START); + g.printPath(END); + // g.printAllPaths(); + } +} + +class Graph { + // mapping of vertex names to Vertex objects, built from a set of Edges + + private final Map graph; + + /** + * One edge of the graph (only used by Graph constructor) + */ + public static class Edge { + + public final String v1, v2; + public final int dist; + + public Edge(String v1, String v2, int dist) { + this.v1 = v1; + this.v2 = v2; + this.dist = dist; + } + } + + /** + * One vertex of the graph, complete with mappings to neighbouring vertices + */ + public static class Vertex implements Comparable { + + public final String name; + // MAX_VALUE assumed to be infinity + public int dist = Integer.MAX_VALUE; + public Vertex previous = null; + public final Map neighbours = new HashMap<>(); + + public Vertex(String name) { + this.name = name; + } + + private void printPath() { + if (this == this.previous) { + System.out.printf("%s", this.name); + } else if (this.previous == null) { + System.out.printf("%s(unreached)", this.name); + } else { + this.previous.printPath(); + System.out.printf(" -> %s(%d)", this.name, this.dist); + } + } + + public int compareTo(Vertex other) { + if (dist == other.dist) { + return name.compareTo(other.name); + } + + return Integer.compare(dist, other.dist); + } + + @Override + public boolean equals(Object object) { + if (this == object) { + return true; + } + if (object == null || getClass() != object.getClass()) { + return false; + } + if (!super.equals(object)) { + return false; + } + + Vertex vertex = (Vertex) object; + + if (dist != vertex.dist) { + return false; + } + if (name != null ? !name.equals(vertex.name) : vertex.name != null) { + return false; + } + if (previous != null ? !previous.equals(vertex.previous) : vertex.previous != null) { + return false; + } + if (neighbours != null ? !neighbours.equals(vertex.neighbours) : vertex.neighbours != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + dist; + result = 31 * result + (previous != null ? previous.hashCode() : 0); + result = 31 * result + (neighbours != null ? neighbours.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "(" + name + ", " + dist + ")"; + } + } + + /** + * Builds a graph from a set of edges + */ + public Graph(Edge[] edges) { + graph = new HashMap<>(edges.length); + + // one pass to find all vertices + for (Edge e : edges) { + if (!graph.containsKey(e.v1)) { + graph.put(e.v1, new Vertex(e.v1)); + } + if (!graph.containsKey(e.v2)) { + graph.put(e.v2, new Vertex(e.v2)); + } + } + + // another pass to set neighbouring vertices + for (Edge e : edges) { + graph.get(e.v1).neighbours.put(graph.get(e.v2), e.dist); + // graph.get(e.v2).neighbours.put(graph.get(e.v1), e.dist); // also do this for an undirected + // graph + } + } + + /** + * Runs dijkstra using a specified source vertex + */ + public void dijkstra(String startName) { + if (!graph.containsKey(startName)) { + System.err.printf("Graph doesn't contain start vertex \"%s\"%n", startName); + return; + } + final Vertex source = graph.get(startName); + NavigableSet q = new TreeSet<>(); + + // set-up vertices + for (Vertex v : graph.values()) { + v.previous = v == source ? source : null; + v.dist = v == source ? 0 : Integer.MAX_VALUE; + q.add(v); + } + + dijkstra(q); + } + + /** + * Implementation of dijkstra's algorithm using a binary heap. + */ + private void dijkstra(final NavigableSet q) { + Vertex u, v; + while (!q.isEmpty()) { + // vertex with shortest distance (first iteration will return source) + u = q.pollFirst(); + if (u.dist == Integer.MAX_VALUE) { + break; // we can ignore u (and any other remaining vertices) since they are unreachable + } + // look at distances to each neighbour + for (Map.Entry a : u.neighbours.entrySet()) { + v = a.getKey(); // the neighbour in this iteration + + final int alternateDist = u.dist + a.getValue(); + if (alternateDist < v.dist) { // shorter path to neighbour found + q.remove(v); + v.dist = alternateDist; + v.previous = u; + q.add(v); + } + } + } + } + + /** + * Prints a path from the source to the specified vertex + */ + public void printPath(String endName) { + if (!graph.containsKey(endName)) { + System.err.printf("Graph doesn't contain end vertex \"%s\"%n", endName); + return; + } + + graph.get(endName).printPath(); + System.out.println(); + } + + /** + * Prints the path from the source to every vertex (output order is not + * guaranteed) + */ + public void printAllPaths() { + for (Vertex v : graph.values()) { + v.printPath(); + System.out.println(); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/EulersFunction.java b/src/main/java/com/thealgorithms/others/EulersFunction.java new file mode 100644 index 000000000000..eed7da05a0bb --- /dev/null +++ b/src/main/java/com/thealgorithms/others/EulersFunction.java @@ -0,0 +1,34 @@ +package com.thealgorithms.others; + +/** + * You can read more about Euler's totient function + * + *

+ * See https://en.wikipedia.org/wiki/Euler%27s_totient_function + */ +public class EulersFunction { + // This method returns us number of x that (x < n) and gcd(x, n) == 1 in O(sqrt(n)) time + // complexity; + + public static int getEuler(int n) { + int result = n; + for (int i = 2; i * i <= n; i++) { + if (n % i == 0) { + while (n % i == 0) { + n /= i; + } + result -= result / i; + } + } + if (n > 1) { + result -= result / n; + } + return result; + } + + public static void main(String[] args) { + for (int i = 1; i < 100; i++) { + System.out.println(getEuler(i)); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/FibbonaciSeries.java b/src/main/java/com/thealgorithms/others/FibbonaciSeries.java new file mode 100644 index 000000000000..103e943743c7 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/FibbonaciSeries.java @@ -0,0 +1,34 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +/** + * Fibonacci sequence, and characterized by the fact that every number after the + * first two is the sum of the two preceding ones. + * + *

+ * Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21,... + * + *

+ * Source for the explanation: https://en.wikipedia.org/wiki/Fibonacci_number + * + * Problem Statement: print all Fibonacci numbers that are smaller than your + * given input N + */ +public class FibbonaciSeries { + + public static void main(String[] args) { + // Get input from the user + Scanner scan = new Scanner(System.in); + int n = scan.nextInt(); + int first = 0, second = 1; + scan.close(); + while (first <= n) { + // print first fibo 0 then add second fibo into it while updating second as well + System.out.println(first); + int next = first + second; + first = second; + second = next; + } + } +} diff --git a/src/main/java/com/thealgorithms/others/FirstFit.java b/src/main/java/com/thealgorithms/others/FirstFit.java new file mode 100644 index 000000000000..c7035d66a9a0 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/FirstFit.java @@ -0,0 +1,81 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; + +/** + * @author Dekas Dimitrios + */ +public class FirstFit { + + private static final int NO_ALLOCATION + = -255; // if a process has been allocated in position -255, + // it means that it has not been actually allocated. + + /** + * Method to find the index of the memory block that is going to fit the + * given process based on the first fit algorithm. + * + * @param blocks: the array with the available memory blocks. + * @param process: the size of the process. + * @return the index of the block that fits, or -255 if no such block + * exists. + */ + private static int findFirstFit(int[] blockSizes, int processSize) { + for (int i = 0; i < blockSizes.length; i++) { + if (blockSizes[i] >= processSize) { + return i; + } + } + // If there is not a block that can fit the process, return -255 as the result + return NO_ALLOCATION; + } + + /** + * Method to allocate memory to blocks according to the first fit algorithm. + * It should return an ArrayList of Integers, where the index is the process + * ID (zero-indexed) and the value is the block number (also zero-indexed). + * + * @param sizeOfBlocks: an int array that contains the sizes of the memory + * blocks available. + * @param sizeOfProcesses: an int array that contains the sizes of the + * processes we need memory blocks for. + * @return the ArrayList filled with Integers repressenting the memory + * allocation that took place. + */ + static ArrayList firstFit(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the first-fit algorithm + ArrayList memAlloc = new ArrayList<>(); + // Do this for every process + for (int processSize : sizeOfProcesses) { + int chosenBlockIdx + = findFirstFit( + sizeOfBlocks, processSize); // Find the index of the memory block going to be used + memAlloc.add(chosenBlockIdx); // Store the chosen block index in the memAlloc array list + if (chosenBlockIdx + != NO_ALLOCATION) { // Only if a block was chosen to store the process in it, + sizeOfBlocks[chosenBlockIdx] -= processSize; // resize the block based on the process size + } + } + return memAlloc; + } + + /** + * Method to print the memory allocated. + * + * @param memAllocation: an ArrayList of Integer representing the memory + * allocation done by the firstFit method. + */ + public static void printMemoryAllocation(ArrayList memAllocation) { + System.out.println("Process No.\tBlock No."); + System.out.println("===========\t========="); + for (int i = 0; i < memAllocation.size(); i++) { + System.out.print(" " + i + "\t\t"); + if (memAllocation.get(i) != NO_ALLOCATION) { + System.out.print(memAllocation.get(i)); + } else { + System.out.print("Not Allocated"); + } + System.out.println(); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/FloydTriangle.java b/src/main/java/com/thealgorithms/others/FloydTriangle.java new file mode 100644 index 000000000000..d25ab303e3ed --- /dev/null +++ b/src/main/java/com/thealgorithms/others/FloydTriangle.java @@ -0,0 +1,19 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +class FloydTriangle { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.println("Enter the number of rows which you want in your Floyd Triangle: "); + int r = sc.nextInt(), n = 0; + sc.close(); + for (int i = 0; i < r; i++) { + for (int j = 0; j <= i; j++) { + System.out.print(++n + " "); + } + System.out.println(); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/GuassLegendre.java b/src/main/java/com/thealgorithms/others/GuassLegendre.java new file mode 100644 index 000000000000..596ca4a45e80 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/GuassLegendre.java @@ -0,0 +1,43 @@ +package com.thealgorithms.others; + +/** + * Guass Legendre Algorithm ref + * https://en.wikipedia.org/wiki/Gauss–Legendre_algorithm + * + * @author AKS1996 + */ +public class GuassLegendre { + + public static void main(String[] args) { + for (int i = 1; i <= 3; ++i) { + System.out.println(pi(i)); + } + } + + static double pi(int l) { + /* + * l: No of loops to run + */ + + double a = 1, b = Math.pow(2, -0.5), t = 0.25, p = 1; + for (int i = 0; i < l; ++i) { + double temp[] = update(a, b, t, p); + a = temp[0]; + b = temp[1]; + t = temp[2]; + p = temp[3]; + } + + return Math.pow(a + b, 2) / (4 * t); + } + + static double[] update(double a, double b, double t, double p) { + double values[] = new double[4]; + values[0] = (a + b) / 2; + values[1] = Math.sqrt(a * b); + values[2] = t - p * Math.pow(a - values[0], 2); + values[3] = 2 * p; + + return values; + } +} diff --git a/src/main/java/com/thealgorithms/others/Huffman.java b/src/main/java/com/thealgorithms/others/Huffman.java new file mode 100644 index 000000000000..3b8d12480fea --- /dev/null +++ b/src/main/java/com/thealgorithms/others/Huffman.java @@ -0,0 +1,133 @@ +package com.thealgorithms.others; + +import java.util.PriorityQueue; +import java.util.Scanner; +import java.util.Comparator; + +// node class is the basic structure +// of each node present in the Huffman - tree. +class HuffmanNode { + + int data; + char c; + + HuffmanNode left; + HuffmanNode right; +} + +// comparator class helps to compare the node +// on the basis of one of its attribute. +// Here we will be compared +// on the basis of data values of the nodes. +class MyComparator implements Comparator { + + public int compare(HuffmanNode x, HuffmanNode y) { + + return x.data - y.data; + } +} + +public class Huffman { + + // recursive function to print the + // huffman-code through the tree traversal. + // Here s is the huffman - code generated. + public static void printCode(HuffmanNode root, String s) { + + // base case; if the left and right are null + // then its a leaf node and we print + // the code s generated by traversing the tree. + if (root.left + == null + && root.right + == null + && Character.isLetter(root.c)) { + + // c is the character in the node + System.out.println(root.c + ":" + s); + + return; + } + + // if we go to left then add "0" to the code. + // if we go to the right add"1" to the code. + // recursive calls for left and + // right sub-tree of the generated tree. + printCode(root.left, s + "0"); + printCode(root.right, s + "1"); + } + + // main function + public static void main(String[] args) { + + Scanner s = new Scanner(System.in); + + // number of characters. + int n = 6; + char[] charArray = {'a', 'b', 'c', 'd', 'e', 'f'}; + int[] charfreq = {5, 9, 12, 13, 16, 45}; + + // creating a priority queue q. + // makes a min-priority queue(min-heap). + PriorityQueue q + = new PriorityQueue(n, new MyComparator()); + + for (int i = 0; i < n; i++) { + + // creating a Huffman node object + // and add it to the priority queue. + HuffmanNode hn = new HuffmanNode(); + + hn.c = charArray[i]; + hn.data = charfreq[i]; + + hn.left = null; + hn.right = null; + + // add functions adds + // the huffman node to the queue. + q.add(hn); + } + + // create a root node + HuffmanNode root = null; + + // Here we will extract the two minimum value + // from the heap each time until + // its size reduces to 1, extract until + // all the nodes are extracted. + while (q.size() > 1) { + + // first min extract. + HuffmanNode x = q.peek(); + q.poll(); + + // second min extarct. + HuffmanNode y = q.peek(); + q.poll(); + + // new node f which is equal + HuffmanNode f = new HuffmanNode(); + + // to the sum of the frequency of the two nodes + // assigning values to the f node. + f.data = x.data + y.data; + f.c = '-'; + + // first extracted node as left child. + f.left = x; + + // second extracted node as the right child. + f.right = y; + + // marking the f node as the root node. + root = f; + + // add this node to the priority-queue. + q.add(f); + } + + // print the codes by traversing the tree + printCode(root, ""); + } +} diff --git a/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java b/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java new file mode 100644 index 000000000000..b40c175f1481 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java @@ -0,0 +1,171 @@ +package com.thealgorithms.others; + +// Java Program to implement Auto-Complete +// Feature using Trie +class Trieac { + + // Alphabet size (# of symbols) + public static final int ALPHABET_SIZE = 26; + + // Trie node + static class TrieNode { + + TrieNode children[] = new TrieNode[ALPHABET_SIZE]; + + // isWordEnd is true if the node represents + // end of a word + boolean isWordEnd; + }; + + // Returns new trie node (initialized to NULLs) + static TrieNode getNode() { + TrieNode pNode = new TrieNode(); + pNode.isWordEnd = false; + + for (int i = 0; i < ALPHABET_SIZE; i++) { + pNode.children[i] = null; + } + + return pNode; + } + + // If not present, inserts key into trie. If the + // key is prefix of trie node, just marks leaf node + static void insert(TrieNode root, final String key) { + TrieNode pCrawl = root; + + for (int level = 0; level < key.length(); level++) { + int index = (key.charAt(level) - 'a'); + if (pCrawl.children[index] == null) { + pCrawl.children[index] = getNode(); + } + pCrawl = pCrawl.children[index]; + } + + // mark last node as leaf + pCrawl.isWordEnd = true; + } + + // Returns true if key presents in trie, else false + boolean search(TrieNode root, final String key) { + int length = key.length(); + TrieNode pCrawl = root; + + for (int level = 0; level < length; level++) { + int index = (key.charAt(level) - 'a'); + + if (pCrawl.children[index] == null) { + pCrawl = pCrawl.children[index]; + } + } + + return (pCrawl != null && pCrawl.isWordEnd); + } + + // Returns 0 if current node has a child + // If all children are NULL, return 1. + static boolean isLastNode(TrieNode root) { + for (int i = 0; i < ALPHABET_SIZE; i++) { + if (root.children[i] != null) { + return false; + } + } + return true; + } + + // Recursive function to print auto-suggestions + // for given node. + static void suggestionsRec(TrieNode root, String currPrefix) { + // found a string in Trie with the given prefix + if (root.isWordEnd) { + System.out.println(currPrefix); + } + + // All children struct node pointers are NULL + if (isLastNode(root)) { + return; + } + + for (int i = 0; i < ALPHABET_SIZE; i++) { + if (root.children[i] != null) { + // append current character to currPrefix string + currPrefix += (char) (97 + i); + + // recur over the rest + suggestionsRec(root.children[i], currPrefix); + } + } + } + + // Fucntion to print suggestions for + // given query prefix. + static int printAutoSuggestions(TrieNode root, + final String query) { + TrieNode pCrawl = root; + + // Check if prefix is present and find the + // the node (of last level) with last character + // of given string. + int level; + int n = query.length(); + + for (level = 0; level < n; level++) { + int index = (query.charAt(level) - 'a'); + + // no string in the Trie has this prefix + if (pCrawl.children[index] == null) { + return 0; + } + + pCrawl = pCrawl.children[index]; + } + + // If prefix is present as a word. + boolean isWord = (pCrawl.isWordEnd == true); + + // If prefix is last node of tree (has no + // children) + boolean isLast = isLastNode(pCrawl); + + // If prefix is present as a word, but + // there is no subtree below the last + // matching node. + if (isWord && isLast) { + System.out.println(query); + return -1; + } + + // If there are are nodes below last + // matching character. + if (!isLast) { + String prefix = query; + suggestionsRec(pCrawl, prefix); + return 1; + } + + return 0; + } + + // Driver code + public static void main(String[] args) { + TrieNode root = getNode(); + insert(root, "hello"); + insert(root, "dog"); + insert(root, "hell"); + insert(root, "cat"); + insert(root, "a"); + insert(root, "hel"); + insert(root, "help"); + insert(root, "helps"); + insert(root, "helping"); + int comp = printAutoSuggestions(root, "hel"); + + if (comp == -1) { + System.out.println("No other strings found " + + "with this prefix\n"); + } else if (comp == 0) { + System.out.println("No string found with" + + " this prefix\n"); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java b/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java new file mode 100644 index 000000000000..23c8671e729a --- /dev/null +++ b/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java @@ -0,0 +1,50 @@ +package com.thealgorithms.others; + +import java.util.*; + +public class InsertDeleteInArray { + + public static void main(String[] args) { + Scanner s = new Scanner(System.in); // Input statement + System.out.println("Enter the size of the array"); + int size = s.nextInt(); + int a[] = new int[size]; + int i; + + // To enter the initial elements + for (i = 0; i < size; i++) { + System.out.println("Enter the element"); + a[i] = s.nextInt(); + } + + // To insert a new element(we are creating a new array) + System.out.println("Enter the index at which the element should be inserted"); + int insert_pos = s.nextInt(); + System.out.println("Enter the element to be inserted"); + int ins = s.nextInt(); + int size2 = size + 1; + int b[] = new int[size2]; + for (i = 0; i < size2; i++) { + if (i <= insert_pos) { + b[i] = a[i]; + } else { + b[i] = a[i - 1]; + } + } + b[insert_pos] = ins; + for (i = 0; i < size2; i++) { + System.out.println(b[i]); + } + + // To delete an element given the index + System.out.println("Enter the index at which element is to be deleted"); + int del_pos = s.nextInt(); + for (i = del_pos; i < size2 - 1; i++) { + b[i] = b[i + 1]; + } + for (i = 0; i < size2 - 1; i++) { + System.out.println(b[i]); + } + s.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/KMP.java b/src/main/java/com/thealgorithms/others/KMP.java new file mode 100644 index 000000000000..b7a50dc74dd7 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/KMP.java @@ -0,0 +1,57 @@ +package com.thealgorithms.others; + +/** + * Implementation of Knuth–Morris–Pratt algorithm Usage: see the main function + * for an example + */ +public class KMP { + // a working example + + public static void main(String[] args) { + final String haystack = "AAAAABAAABA"; // This is the full string + final String needle = "AAAA"; // This is the substring that we want to find + KMPmatcher(haystack, needle); + } + + // find the starting index in string haystack[] that matches the search word P[] + public static void KMPmatcher(final String haystack, final String needle) { + final int m = haystack.length(); + final int n = needle.length(); + final int[] pi = computePrefixFunction(needle); + int q = 0; + for (int i = 0; i < m; i++) { + while (q > 0 && haystack.charAt(i) != needle.charAt(q)) { + q = pi[q - 1]; + } + + if (haystack.charAt(i) == needle.charAt(q)) { + q++; + } + + if (q == n) { + System.out.println("Pattern starts: " + (i + 1 - n)); + q = pi[q - 1]; + } + } + } + + // return the prefix function + private static int[] computePrefixFunction(final String P) { + final int n = P.length(); + final int[] pi = new int[n]; + pi[0] = 0; + int q = 0; + for (int i = 1; i < n; i++) { + while (q > 0 && P.charAt(q) != P.charAt(i)) { + q = pi[q - 1]; + } + + if (P.charAt(q) == P.charAt(i)) { + q++; + } + + pi[i] = q; + } + return pi; + } +} diff --git a/src/main/java/com/thealgorithms/others/KochSnowflake.java b/src/main/java/com/thealgorithms/others/KochSnowflake.java new file mode 100644 index 000000000000..5d160e4873a7 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/KochSnowflake.java @@ -0,0 +1,242 @@ +package com.thealgorithms.others; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import javax.imageio.ImageIO; + +/** + * The Koch snowflake is a fractal curve and one of the earliest fractals to + * have been described. The Koch snowflake can be built up iteratively, in a + * sequence of stages. The first stage is an equilateral triangle, and each + * successive stage is formed by adding outward bends to each side of the + * previous stage, making smaller equilateral triangles. This can be achieved + * through the following steps for each line: 1. divide the line segment into + * three segments of equal length. 2. draw an equilateral triangle that has the + * middle segment from step 1 as its base and points outward. 3. remove the line + * segment that is the base of the triangle from step 2. (description adapted + * from https://en.wikipedia.org/wiki/Koch_snowflake ) (for a more detailed + * explanation and an implementation in the Processing language, see + * https://natureofcode.com/book/chapter-8-fractals/ + * #84-the-koch-curve-and-the-arraylist-technique ). + */ +public class KochSnowflake { + + public static void main(String[] args) { + // Test Iterate-method + ArrayList vectors = new ArrayList(); + vectors.add(new Vector2(0, 0)); + vectors.add(new Vector2(1, 0)); + ArrayList result = Iterate(vectors, 1); + + assert result.get(0).x == 0; + assert result.get(0).y == 0; + + assert result.get(1).x == 1. / 3; + assert result.get(1).y == 0; + + assert result.get(2).x == 1. / 2; + assert result.get(2).y == Math.sin(Math.PI / 3) / 3; + + assert result.get(3).x == 2. / 3; + assert result.get(3).y == 0; + + assert result.get(4).x == 1; + assert result.get(4).y == 0; + + // Test GetKochSnowflake-method + int imageWidth = 600; + double offsetX = imageWidth / 10.; + double offsetY = imageWidth / 3.7; + BufferedImage image = GetKochSnowflake(imageWidth, 5); + + // The background should be white + assert image.getRGB(0, 0) == new Color(255, 255, 255).getRGB(); + + // The snowflake is drawn in black and this is the position of the first vector + assert image.getRGB((int) offsetX, (int) offsetY) == new Color(0, 0, 0).getRGB(); + + // Save image + try { + ImageIO.write(image, "png", new File("KochSnowflake.png")); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Go through the number of iterations determined by the argument "steps". + * Be careful with high values (above 5) since the time to calculate + * increases exponentially. + * + * @param initialVectors The vectors composing the shape to which the + * algorithm is applied. + * @param steps The number of iterations. + * @return The transformed vectors after the iteration-steps. + */ + public static ArrayList Iterate(ArrayList initialVectors, int steps) { + ArrayList vectors = initialVectors; + for (int i = 0; i < steps; i++) { + vectors = IterationStep(vectors); + } + + return vectors; + } + + /** + * Method to render the Koch snowflake to a image. + * + * @param imageWidth The width of the rendered image. + * @param steps The number of iterations. + * @return The image of the rendered Koch snowflake. + */ + public static BufferedImage GetKochSnowflake(int imageWidth, int steps) { + if (imageWidth <= 0) { + throw new IllegalArgumentException("imageWidth should be greater than zero"); + } + + double offsetX = imageWidth / 10.; + double offsetY = imageWidth / 3.7; + Vector2 vector1 = new Vector2(offsetX, offsetY); + Vector2 vector2 + = new Vector2(imageWidth / 2, Math.sin(Math.PI / 3) * imageWidth * 0.8 + offsetY); + Vector2 vector3 = new Vector2(imageWidth - offsetX, offsetY); + ArrayList initialVectors = new ArrayList(); + initialVectors.add(vector1); + initialVectors.add(vector2); + initialVectors.add(vector3); + initialVectors.add(vector1); + ArrayList vectors = Iterate(initialVectors, steps); + return GetImage(vectors, imageWidth, imageWidth); + } + + /** + * Loops through each pair of adjacent vectors. Each line between two + * adjacent vectors is divided into 4 segments by adding 3 additional + * vectors in-between the original two vectors. The vector in the middle is + * constructed through a 60 degree rotation so it is bent outwards. + * + * @param vectors The vectors composing the shape to which the algorithm is + * applied. + * @return The transformed vectors after the iteration-step. + */ + private static ArrayList IterationStep(ArrayList vectors) { + ArrayList newVectors = new ArrayList(); + for (int i = 0; i < vectors.size() - 1; i++) { + Vector2 startVector = vectors.get(i); + Vector2 endVector = vectors.get(i + 1); + newVectors.add(startVector); + Vector2 differenceVector = endVector.subtract(startVector).multiply(1. / 3); + newVectors.add(startVector.add(differenceVector)); + newVectors.add(startVector.add(differenceVector).add(differenceVector.rotate(60))); + newVectors.add(startVector.add(differenceVector.multiply(2))); + } + + newVectors.add(vectors.get(vectors.size() - 1)); + return newVectors; + } + + /** + * Utility-method to render the Koch snowflake to an image. + * + * @param vectors The vectors defining the edges to be rendered. + * @param imageWidth The width of the rendered image. + * @param imageHeight The height of the rendered image. + * @return The image of the rendered edges. + */ + private static BufferedImage GetImage( + ArrayList vectors, int imageWidth, int imageHeight) { + BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = image.createGraphics(); + + // Set the background white + g2d.setBackground(Color.WHITE); + g2d.fillRect(0, 0, imageWidth, imageHeight); + + // Draw the edges + g2d.setColor(Color.BLACK); + BasicStroke bs = new BasicStroke(1); + g2d.setStroke(bs); + for (int i = 0; i < vectors.size() - 1; i++) { + int x1 = (int) vectors.get(i).x; + int y1 = (int) vectors.get(i).y; + int x2 = (int) vectors.get(i + 1).x; + int y2 = (int) vectors.get(i + 1).y; + + g2d.drawLine(x1, y1, x2, y2); + } + + return image; + } + + /** + * Inner class to handle the vector calculations. + */ + private static class Vector2 { + + double x, y; + + public Vector2(double x, double y) { + this.x = x; + this.y = y; + } + + @Override + public String toString() { + return String.format("[%f, %f]", this.x, this.y); + } + + /** + * Vector addition + * + * @param vector The vector to be added. + * @return The sum-vector. + */ + public Vector2 add(Vector2 vector) { + double x = this.x + vector.x; + double y = this.y + vector.y; + return new Vector2(x, y); + } + + /** + * Vector subtraction + * + * @param vector The vector to be subtracted. + * @return The difference-vector. + */ + public Vector2 subtract(Vector2 vector) { + double x = this.x - vector.x; + double y = this.y - vector.y; + return new Vector2(x, y); + } + + /** + * Vector scalar multiplication + * + * @param scalar The factor by which to multiply the vector. + * @return The scaled vector. + */ + public Vector2 multiply(double scalar) { + double x = this.x * scalar; + double y = this.y * scalar; + return new Vector2(x, y); + } + + /** + * Vector rotation (see https://en.wikipedia.org/wiki/Rotation_matrix) + * + * @param angleInDegrees The angle by which to rotate the vector. + * @return The rotated vector. + */ + public Vector2 rotate(double angleInDegrees) { + double radians = angleInDegrees * Math.PI / 180; + double ca = Math.cos(radians); + double sa = Math.sin(radians); + double x = ca * this.x - sa * this.y; + double y = sa * this.x + ca * this.y; + return new Vector2(x, y); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/Krishnamurthy.java b/src/main/java/com/thealgorithms/others/Krishnamurthy.java new file mode 100644 index 000000000000..2b0c61ff99c7 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/Krishnamurthy.java @@ -0,0 +1,33 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +class Krishnamurthy { + + static int fact(int n) { + int i, p = 1; + for (i = n; i >= 1; i--) { + p = p * i; + } + return p; + } + + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + int a, b, s = 0; + System.out.print("Enter the number : "); + a = sc.nextInt(); + int n = a; + while (a > 0) { + b = a % 10; + s = s + fact(b); + a = a / 10; + } + if (s == n) { + System.out.print(n + " is a krishnamurthy number"); + } else { + System.out.print(n + " is not a krishnamurthy number"); + } + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java b/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java new file mode 100644 index 000000000000..7e097f1b09db --- /dev/null +++ b/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java @@ -0,0 +1,67 @@ +package com.thealgorithms.others; + +/** + * * + * A pseudorandom number generator. + * + * @author Tobias Carryer + * @date October 10, 2017 + */ +public class LinearCongruentialGenerator { + + private double a, c, m, previousValue; + + /** + * * + * These parameters are saved and used when nextNumber() is called. The + * current timestamp in milliseconds is used as the seed. + * + * @param multiplier + * @param increment + * @param modulo The maximum number that can be generated (exclusive). A + * common value is 2^32. + */ + public LinearCongruentialGenerator(double multiplier, double increment, double modulo) { + this(System.currentTimeMillis(), multiplier, increment, modulo); + } + + /** + * * + * These parameters are saved and used when nextNumber() is called. + * + * @param seed + * @param multiplier + * @param increment + * @param modulo The maximum number that can be generated (exclusive). A + * common value is 2^32. + */ + public LinearCongruentialGenerator( + double seed, double multiplier, double increment, double modulo) { + this.previousValue = seed; + this.a = multiplier; + this.c = increment; + this.m = modulo; + } + + /** + * The smallest number that can be generated is zero. The largest number + * that can be generated is modulo-1. modulo is set in the constructor. + * + * @return a pseudorandom number. + */ + public double nextNumber() { + previousValue = (a * previousValue + c) % m; + return previousValue; + } + + public static void main(String[] args) { + // Show the LCG in action. + // Decisive proof that the LCG works could be made by adding each number + // generated to a Set while checking for duplicates. + LinearCongruentialGenerator lcg + = new LinearCongruentialGenerator(1664525, 1013904223, Math.pow(2.0, 32.0)); + for (int i = 0; i < 512; i++) { + System.out.println(lcg.nextNumber()); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java b/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java new file mode 100644 index 000000000000..4b11134452fa --- /dev/null +++ b/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java @@ -0,0 +1,149 @@ +package com.thealgorithms.others; + +import java.util.InputMismatchException; +import java.util.Scanner; + +/** + * Class for finding the lowest base in which a given integer is a palindrome. + * Includes auxiliary methods for converting between bases and reversing + * strings. + * + *

+ * NOTE: There is potential for error, see note at line 63. + * + * @author RollandMichael + * @version 2017.09.28 + */ +public class LowestBasePalindrome { + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + int n = 0; + while (true) { + try { + System.out.print("Enter number: "); + n = in.nextInt(); + break; + } catch (InputMismatchException e) { + System.out.println("Invalid input!"); + in.next(); + } + } + System.out.println(n + " is a palindrome in base " + lowestBasePalindrome(n)); + System.out.println(base2base(Integer.toString(n), 10, lowestBasePalindrome(n))); + in.close(); + } + + /** + * Given a number in base 10, returns the lowest base in which the number is + * represented by a palindrome (read the same left-to-right and + * right-to-left). + * + * @param num A number in base 10. + * @return The lowest base in which num is a palindrome. + */ + public static int lowestBasePalindrome(int num) { + int base, num2 = num; + int digit; + char digitC; + boolean foundBase = false; + String newNum = ""; + String digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + while (!foundBase) { + // Try from bases 2 to num-1 + for (base = 2; base < num2; base++) { + newNum = ""; + while (num > 0) { + // Obtain the first digit of n in the current base, + // which is equivalent to the integer remainder of (n/base). + // The next digit is obtained by dividing n by the base and + // continuing the process of getting the remainder. This is done + // until n is <=0 and the number in the new base is obtained. + digit = (num % base); + num /= base; + // If the digit isn't in the set of [0-9][A-Z] (beyond base 36), its character + // form is just its value in ASCII. + + // NOTE: This may cause problems, as the capital letters are ASCII values + // 65-90. It may cause false positives when one digit is, for instance 10 and assigned + // 'A' from the character array and the other is 65 and also assigned 'A'. + // Regardless, the character is added to the representation of n + // in the current base. + if (digit >= digits.length()) { + digitC = (char) (digit); + newNum += digitC; + continue; + } + newNum += digits.charAt(digit); + } + // Num is assigned back its original value for the next iteration. + num = num2; + // Auxiliary method reverses the number. + String reverse = reverse(newNum); + // If the number is read the same as its reverse, then it is a palindrome. + // The current base is returned. + if (reverse.equals(newNum)) { + foundBase = true; + return base; + } + } + } + // If all else fails, n is always a palindrome in base n-1. ("11") + return num - 1; + } + + private static String reverse(String str) { + String reverse = ""; + for (int i = str.length() - 1; i >= 0; i--) { + reverse += str.charAt(i); + } + return reverse; + } + + private static String base2base(String n, int b1, int b2) { + // Declare variables: decimal value of n, + // character of base b1, character of base b2, + // and the string that will be returned. + int decimalValue = 0, charB2; + char charB1; + String output = ""; + // Go through every character of n + for (int i = 0; i < n.length(); i++) { + // store the character in charB1 + charB1 = n.charAt(i); + // if it is a non-number, convert it to a decimal value >9 and store it in charB2 + if (charB1 >= 'A' && charB1 <= 'Z') { + charB2 = 10 + (charB1 - 'A'); + } // Else, store the integer value in charB2 + else { + charB2 = charB1 - '0'; + } + // Convert the digit to decimal and add it to the + // decimalValue of n + decimalValue = decimalValue * b1 + charB2; + } + + // Converting the decimal value to base b2: + // A number is converted from decimal to another base + // by continuously dividing by the base and recording + // the remainder until the quotient is zero. The number in the + // new base is the remainders, with the last remainder + // being the left-most digit. + // While the quotient is NOT zero: + while (decimalValue != 0) { + // If the remainder is a digit < 10, simply add it to + // the left side of the new number. + if (decimalValue % b2 < 10) { + output = Integer.toString(decimalValue % b2) + output; + } // If the remainder is >= 10, add a character with the + // corresponding value to the new number. (A = 10, B = 11, C = 12, ...) + else { + output = (char) ((decimalValue % b2) + 55) + output; + } + // Divide by the new base again + decimalValue /= b2; + } + return output; + } +} diff --git a/Others/Luhn.java b/src/main/java/com/thealgorithms/others/Luhn.java similarity index 72% rename from Others/Luhn.java rename to src/main/java/com/thealgorithms/others/Luhn.java index 9ea69d1dacdb..351dc13f7341 100644 --- a/Others/Luhn.java +++ b/src/main/java/com/thealgorithms/others/Luhn.java @@ -1,31 +1,39 @@ -package Others; +package com.thealgorithms.others; import java.util.Arrays; import java.util.Objects; /** - * The Luhn algorithm or Luhn formula, also known as the "modulus 10" or "mod 10" algorithm, - * named after its creator, IBM scientist Hans Peter Luhn, is a simple checksum formula - * used to validate a variety of identification numbers. + * The Luhn algorithm or Luhn formula, also known as the "modulus 10" or "mod + * 10" algorithm, named after its creator, IBM scientist Hans Peter Luhn, is a + * simple checksum formula used to validate a variety of identification numbers. * - *

The algorithm is in the public domain and is in wide use today. - * It is specified in ISO/IEC 7812-1. It is not intended to be a cryptographically + *

+ * The algorithm is in the public domain and is in wide use today. It is + * specified in ISO/IEC 7812-1. It is not intended to be a cryptographically * secure hash function; it was designed to protect against accidental errors, - * not malicious attacks. Most credit cards and many government identification numbers - * use the algorithm as a simple method of distinguishing valid numbers from mistyped or - * otherwise incorrect numbers.

+ * not malicious attacks. Most credit cards and many government identification + * numbers use the algorithm as a simple method of distinguishing valid numbers + * from mistyped or otherwise incorrect numbers.

* - *

The Luhn algorithm will detect any single-digit error, as well as almost all - * transpositions of adjacent digits. It will not, however, detect transposition of the - * two-digit sequence 09 to 90 (or vice versa). It will detect most of the possible - * twin errors (it will not detect 22 ↔ 55, 33 ↔ 66 or 44 ↔ 77).

+ *

+ * The Luhn algorithm will detect any single-digit error, as well as almost all + * transpositions of adjacent digits. It will not, however, detect transposition + * of the two-digit sequence 09 to 90 (or vice versa). It will detect most of + * the possible twin errors (it will not detect 22 ↔ 55, 33 ↔ 66 or 44 ↔ + * 77).

* - *

The check digit is computed as follows:

+ *

+ * The check digit is computed as follows:

*
    - *
  1. Take the original number and starting from the rightmost digit moving left, double the value of every second digit (including the rightmost digit).
  2. - *
  3. Replace the resulting value at each position with the sum of the digits of this position's value or just subtract 9 from all numbers more or equal then 10.
  4. - *
  5. Sum up the resulting values from all positions (s).
  6. - *
  7. The calculated check digit is equal to {@code 10 - s % 10}.
  8. + *
  9. Take the original number and starting from the rightmost digit moving + * left, double the value of every second digit (including the rightmost + * digit).
  10. + *
  11. Replace the resulting value at each position with the sum of the digits + * of this position's value or just subtract 9 from all numbers more or equal + * then 10.
  12. + *
  13. Sum up the resulting values from all positions (s).
  14. + *
  15. The calculated check digit is equal to {@code 10 - s % 10}.
  16. *
* * @see Wiki @@ -33,8 +41,9 @@ public class Luhn { /** - * Check input digits array by Luhn algorithm. - * Initial array doesn't change while processing. + * Check input digits array by Luhn algorithm. Initial array doesn't change + * while processing. + * * @param digits array of digits from 0 to 9 * @return true if check was successful, false otherwise */ @@ -74,8 +83,8 @@ public static void main(String[] args) { private static void checkAndPrint(int[] input) { String validationResult = Luhn.luhnCheck(input) - ? "valid" - : "not valid"; + ? "valid" + : "not valid"; System.out.println("Input " + Arrays.toString(input) + " is " + validationResult); } @@ -85,7 +94,6 @@ private static void checkAndPrint(int[] input) { Business usage example ======================== */ - /** * Object representation of credit card. */ @@ -94,11 +102,11 @@ private record CreditCard(int[] digits) { private static final int DIGITS_COUNT = 16; /** - * @param cardNumber string representation of credit card number - 16 digits. - * Can have spaces for digits separation + * @param cardNumber string representation of credit card number - 16 + * digits. Can have spaces for digits separation * @return credit card object - * @throws IllegalArgumentException if input string is not 16 digits - * or if Luhn check was failed + * @throws IllegalArgumentException if input string is not 16 digits or + * if Luhn check was failed */ public static CreditCard fromString(String cardNumber) { Objects.requireNonNull(cardNumber); @@ -138,8 +146,8 @@ public String toString() { private static int[] toIntArray(String string) { return string.chars() - .map(i -> Character.digit(i, 10)) - .toArray(); + .map(i -> Character.digit(i, 10)) + .toArray(); } } diff --git a/src/main/java/com/thealgorithms/others/Mandelbrot.java b/src/main/java/com/thealgorithms/others/Mandelbrot.java new file mode 100644 index 000000000000..7e2837f1d765 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/Mandelbrot.java @@ -0,0 +1,198 @@ +package com.thealgorithms.others; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/** + * The Mandelbrot set is the set of complex numbers "c" for which the series + * "z_(n+1) = z_n * z_n + c" does not diverge, i.e. remains bounded. Thus, a + * complex number "c" is a member of the Mandelbrot set if, when starting with + * "z_0 = 0" and applying the iteration repeatedly, the absolute value of "z_n" + * remains bounded for all "n > 0". Complex numbers can be written as "a + b*i": + * "a" is the real component, usually drawn on the x-axis, and "b*i" is the + * imaginary component, usually drawn on the y-axis. Most visualizations of the + * Mandelbrot set use a color-coding to indicate after how many steps in the + * series the numbers outside the set cross the divergence threshold. Images of + * the Mandelbrot set exhibit an elaborate and infinitely complicated boundary + * that reveals progressively ever-finer recursive detail at increasing + * magnifications, making the boundary of the Mandelbrot set a fractal curve. + * (description adapted from https://en.wikipedia.org/wiki/Mandelbrot_set ) (see + * also https://en.wikipedia.org/wiki/Plotting_algorithms_for_the_Mandelbrot_set + * ) + */ +public class Mandelbrot { + + public static void main(String[] args) { + // Test black and white + BufferedImage blackAndWhiteImage = getImage(800, 600, -0.6, 0, 3.2, 50, false); + + // Pixel outside the Mandelbrot set should be white. + assert blackAndWhiteImage.getRGB(0, 0) == new Color(255, 255, 255).getRGB(); + + // Pixel inside the Mandelbrot set should be black. + assert blackAndWhiteImage.getRGB(400, 300) == new Color(0, 0, 0).getRGB(); + + // Test color-coding + BufferedImage coloredImage = getImage(800, 600, -0.6, 0, 3.2, 50, true); + + // Pixel distant to the Mandelbrot set should be red. + assert coloredImage.getRGB(0, 0) == new Color(255, 0, 0).getRGB(); + + // Pixel inside the Mandelbrot set should be black. + assert coloredImage.getRGB(400, 300) == new Color(0, 0, 0).getRGB(); + + // Save image + try { + ImageIO.write(coloredImage, "png", new File("Mandelbrot.png")); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Method to generate the image of the Mandelbrot set. Two types of + * coordinates are used: image-coordinates that refer to the pixels and + * figure-coordinates that refer to the complex numbers inside and outside + * the Mandelbrot set. The figure-coordinates in the arguments of this + * method determine which section of the Mandelbrot set is viewed. The main + * area of the Mandelbrot set is roughly between "-1.5 < x < 0.5" and "-1 < + * y < 1" in the figure-coordinates. + * + * @param imageWidth The width of the rendered image. + * @param imageHeight The height of the rendered image. + * @param figureCenterX The x-coordinate of the center of the figure. + * @param figureCenterY The y-coordinate of the center of the figure. + * @param figureWidth The width of the figure. + * @param maxStep Maximum number of steps to check for divergent behavior. + * @param useDistanceColorCoding Render in color or black and white. + * @return The image of the rendered Mandelbrot set. + */ + public static BufferedImage getImage( + int imageWidth, + int imageHeight, + double figureCenterX, + double figureCenterY, + double figureWidth, + int maxStep, + boolean useDistanceColorCoding) { + if (imageWidth <= 0) { + throw new IllegalArgumentException("imageWidth should be greater than zero"); + } + + if (imageHeight <= 0) { + throw new IllegalArgumentException("imageHeight should be greater than zero"); + } + + if (maxStep <= 0) { + throw new IllegalArgumentException("maxStep should be greater than zero"); + } + + BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); + double figureHeight = figureWidth / imageWidth * imageHeight; + + // loop through the image-coordinates + for (int imageX = 0; imageX < imageWidth; imageX++) { + for (int imageY = 0; imageY < imageHeight; imageY++) { + // determine the figure-coordinates based on the image-coordinates + double figureX = figureCenterX + ((double) imageX / imageWidth - 0.5) * figureWidth; + double figureY = figureCenterY + ((double) imageY / imageHeight - 0.5) * figureHeight; + + double distance = getDistance(figureX, figureY, maxStep); + + // color the corresponding pixel based on the selected coloring-function + image.setRGB( + imageX, + imageY, + useDistanceColorCoding + ? colorCodedColorMap(distance).getRGB() + : blackAndWhiteColorMap(distance).getRGB()); + } + } + + return image; + } + + /** + * Black and white color-coding that ignores the relative distance. The + * Mandelbrot set is black, everything else is white. + * + * @param distance Distance until divergence threshold + * @return The color corresponding to the distance. + */ + private static Color blackAndWhiteColorMap(double distance) { + return distance >= 1 ? new Color(0, 0, 0) : new Color(255, 255, 255); + } + + /** + * Color-coding taking the relative distance into account. The Mandelbrot + * set is black. + * + * @param distance Distance until divergence threshold. + * @return The color corresponding to the distance. + */ + private static Color colorCodedColorMap(double distance) { + if (distance >= 1) { + return new Color(0, 0, 0); + } else { + // simplified transformation of HSV to RGB + // distance determines hue + double hue = 360 * distance; + double saturation = 1; + double val = 255; + int hi = (int) (Math.floor(hue / 60)) % 6; + double f = hue / 60 - Math.floor(hue / 60); + + int v = (int) val; + int p = 0; + int q = (int) (val * (1 - f * saturation)); + int t = (int) (val * (1 - (1 - f) * saturation)); + + switch (hi) { + case 0: + return new Color(v, t, p); + case 1: + return new Color(q, v, p); + case 2: + return new Color(p, v, t); + case 3: + return new Color(p, q, v); + case 4: + return new Color(t, p, v); + default: + return new Color(v, p, q); + } + } + } + + /** + * Return the relative distance (ratio of steps taken to maxStep) after + * which the complex number constituted by this x-y-pair diverges. Members + * of the Mandelbrot set do not diverge so their distance is 1. + * + * @param figureX The x-coordinate within the figure. + * @param figureX The y-coordinate within the figure. + * @param maxStep Maximum number of steps to check for divergent behavior. + * @return The relative distance as the ratio of steps taken to maxStep. + */ + private static double getDistance(double figureX, double figureY, int maxStep) { + double a = figureX; + double b = figureY; + int currentStep = 0; + for (int step = 0; step < maxStep; step++) { + currentStep = step; + double aNew = a * a - b * b + figureX; + b = 2 * a * b + figureY; + a = aNew; + + // divergence happens for all complex number with an absolute value + // greater than 4 (= divergence threshold) + if (a * a + b * b > 4) { + break; + } + } + return (double) currentStep / (maxStep - 1); + } +} diff --git a/Others/MiniMaxAlgorithm.java b/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java similarity index 88% rename from Others/MiniMaxAlgorithm.java rename to src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java index 7d0dd0537f6f..f40862baab1e 100644 --- a/Others/MiniMaxAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java @@ -1,128 +1,128 @@ -package Others; - -import java.util.Arrays; -import java.util.Random; - -/** - * MiniMax is an algorithm used int artificial intelligence and game theory for - * minimizing the possible loss for the worst case scenario. - * - * See more (https://en.wikipedia.org/wiki/Minimax, - * https://www.geeksforgeeks.org/minimax-algorithm-in-game-theory-set-1-introduction/). - * - * @author aitofi (https://github.com/aitorfi) - */ -public class MiniMaxAlgorithm { - /** - * Game tree represented as an int array containing scores. Each array element - * is a leaf node. - */ - private int[] scores; - private int height; - - /** - * Initializes the scores with 8 random leaf nodes - */ - public MiniMaxAlgorithm() { - scores = getRandomScores(3, 99); - height = log2(scores.length); - } - - public static void main(String[] args) { - MiniMaxAlgorithm miniMaxAlgorith = new MiniMaxAlgorithm(); - boolean isMaximizer = true; // Specifies the player that goes first. - boolean verbose = true; // True to show each players choices. - int bestScore; - - bestScore = miniMaxAlgorith.miniMax(0, isMaximizer, 0, verbose); - - if (verbose) { - System.out.println(); - } - - System.out.println(Arrays.toString(miniMaxAlgorith.getScores())); - System.out.println( - "The best score for " + (isMaximizer ? "Maximizer" : "Minimizer") + " is " + String.valueOf(bestScore)); - } - - /** - * Returns the optimal score assuming that both players play their best. - * - * @param depth Indicates how deep we are into the game tree. - * @param isMaximizer True if it is maximizers turn; otherwise false. - * @param index Index of the leaf node that is being evaluated. - * @param verbose True to show each players choices. - * @return The optimal score for the player that made the first move. - */ - public int miniMax(int depth, boolean isMaximizer, int index, boolean verbose) { - int bestScore, score1, score2; - - if (depth == height) { // Leaf node reached. - return scores[index]; - } - - score1 = miniMax(depth + 1, !isMaximizer, index * 2, verbose); - score2 = miniMax(depth + 1, !isMaximizer, (index * 2) + 1, verbose); - - if (isMaximizer) { - // Maximizer player wants to get the maximum possible score. - bestScore = Math.max(score1, score2); - } else { - // Minimizer player wants to get the minimum possible score. - bestScore = Math.min(score1, score2); - } - - // Leaf nodes can be sequentially inspected by - // recurssively multiplying (0 * 2) and ((0 * 2) + 1): - // (0 x 2) = 0; ((0 x 2) + 1) = 1 - // (1 x 2) = 2; ((1 x 2) + 1) = 3 - // (2 x 2) = 4; ((2 x 2) + 1) = 5 ... - - if (verbose) { - System.out.println(String.format("From %02d and %02d, %s chooses %02d", score1, score2, - (isMaximizer ? "Maximizer" : "Minimizer"), bestScore)); - } - - return bestScore; - } - - /** - * Returns an array of random numbers which lenght is a power of 2. - * - * @param size The power of 2 that will determine the lenght of the array. - * @param maxScore The maximum possible score. - * @return An array of random numbers. - */ - public static int[] getRandomScores(int size, int maxScore) { - int[] randomScores = new int[(int) Math.pow(2, size)]; - Random rand = new Random(); - - for (int i = 0; i < randomScores.length; i++) { - randomScores[i] = rand.nextInt(maxScore) + 1; - } - - return randomScores; - } - - // A utility function to find Log n in base 2 - private int log2(int n) { - return (n == 1) ? 0 : log2(n / 2) + 1; - } - - public void setScores(int[] scores) { - if (scores.length % 1 == 0) { - this.scores = scores; - height = log2(this.scores.length); - } else { - System.out.println("The number of scores must be a power of 2."); - } - } - - public int[] getScores() { - return scores; - } - - public int getHeight() { - return height; - } -} \ No newline at end of file +package com.thealgorithms.others; + +import java.util.Arrays; +import java.util.Random; + +/** + * MiniMax is an algorithm used int artificial intelligence and game theory for + * minimizing the possible loss for the worst case scenario. + * + * See more (https://en.wikipedia.org/wiki/Minimax, + * https://www.geeksforgeeks.org/minimax-algorithm-in-game-theory-set-1-introduction/). + * + * @author aitofi (https://github.com/aitorfi) + */ +public class MiniMaxAlgorithm { + + /** + * Game tree represented as an int array containing scores. Each array + * element is a leaf node. + */ + private int[] scores; + private int height; + + /** + * Initializes the scores with 8 random leaf nodes + */ + public MiniMaxAlgorithm() { + scores = getRandomScores(3, 99); + height = log2(scores.length); + } + + public static void main(String[] args) { + MiniMaxAlgorithm miniMaxAlgorith = new MiniMaxAlgorithm(); + boolean isMaximizer = true; // Specifies the player that goes first. + boolean verbose = true; // True to show each players choices. + int bestScore; + + bestScore = miniMaxAlgorith.miniMax(0, isMaximizer, 0, verbose); + + if (verbose) { + System.out.println(); + } + + System.out.println(Arrays.toString(miniMaxAlgorith.getScores())); + System.out.println( + "The best score for " + (isMaximizer ? "Maximizer" : "Minimizer") + " is " + String.valueOf(bestScore)); + } + + /** + * Returns the optimal score assuming that both players play their best. + * + * @param depth Indicates how deep we are into the game tree. + * @param isMaximizer True if it is maximizers turn; otherwise false. + * @param index Index of the leaf node that is being evaluated. + * @param verbose True to show each players choices. + * @return The optimal score for the player that made the first move. + */ + public int miniMax(int depth, boolean isMaximizer, int index, boolean verbose) { + int bestScore, score1, score2; + + if (depth == height) { // Leaf node reached. + return scores[index]; + } + + score1 = miniMax(depth + 1, !isMaximizer, index * 2, verbose); + score2 = miniMax(depth + 1, !isMaximizer, (index * 2) + 1, verbose); + + if (isMaximizer) { + // Maximizer player wants to get the maximum possible score. + bestScore = Math.max(score1, score2); + } else { + // Minimizer player wants to get the minimum possible score. + bestScore = Math.min(score1, score2); + } + + // Leaf nodes can be sequentially inspected by + // recurssively multiplying (0 * 2) and ((0 * 2) + 1): + // (0 x 2) = 0; ((0 x 2) + 1) = 1 + // (1 x 2) = 2; ((1 x 2) + 1) = 3 + // (2 x 2) = 4; ((2 x 2) + 1) = 5 ... + if (verbose) { + System.out.println(String.format("From %02d and %02d, %s chooses %02d", score1, score2, + (isMaximizer ? "Maximizer" : "Minimizer"), bestScore)); + } + + return bestScore; + } + + /** + * Returns an array of random numbers which lenght is a power of 2. + * + * @param size The power of 2 that will determine the lenght of the array. + * @param maxScore The maximum possible score. + * @return An array of random numbers. + */ + public static int[] getRandomScores(int size, int maxScore) { + int[] randomScores = new int[(int) Math.pow(2, size)]; + Random rand = new Random(); + + for (int i = 0; i < randomScores.length; i++) { + randomScores[i] = rand.nextInt(maxScore) + 1; + } + + return randomScores; + } + + // A utility function to find Log n in base 2 + private int log2(int n) { + return (n == 1) ? 0 : log2(n / 2) + 1; + } + + public void setScores(int[] scores) { + if (scores.length % 1 == 0) { + this.scores = scores; + height = log2(this.scores.length); + } else { + System.out.println("The number of scores must be a power of 2."); + } + } + + public int[] getScores() { + return scores; + } + + public int getHeight() { + return height; + } +} diff --git a/src/main/java/com/thealgorithms/others/PageRank.java b/src/main/java/com/thealgorithms/others/PageRank.java new file mode 100644 index 000000000000..d9a2e648e893 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/PageRank.java @@ -0,0 +1,97 @@ +package com.thealgorithms.others; + +import java.util.*; + +class PageRank { + + public static void main(String args[]) { + int nodes, i, j; + Scanner in = new Scanner(System.in); + System.out.print("Enter the Number of WebPages: "); + nodes = in.nextInt(); + PageRank p = new PageRank(); + System.out.println("Enter the Adjacency Matrix with 1->PATH & 0->NO PATH Between two WebPages: "); + for (i = 1; i <= nodes; i++) { + for (j = 1; j <= nodes; j++) { + p.path[i][j] = in.nextInt(); + if (j == i) { + p.path[i][j] = 0; + } + } + } + p.calc(nodes); + } + + public int path[][] = new int[10][10]; + public double pagerank[] = new double[10]; + + public void calc(double totalNodes) { + + double InitialPageRank; + double OutgoingLinks = 0; + double DampingFactor = 0.85; + double TempPageRank[] = new double[10]; + int ExternalNodeNumber; + int InternalNodeNumber; + int k = 1; // For Traversing + int ITERATION_STEP = 1; + InitialPageRank = 1 / totalNodes; + System.out.printf( + " Total Number of Nodes :" + totalNodes + "\t Initial PageRank of All Nodes :" + InitialPageRank + "\n"); + + // 0th ITERATION _ OR _ INITIALIZATION PHASE // + for (k = 1; k <= totalNodes; k++) { + this.pagerank[k] = InitialPageRank; + } + System.out.printf("\n Initial PageRank Values , 0th Step \n"); + + for (k = 1; k <= totalNodes; k++) { + System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); + } + + while (ITERATION_STEP <= 2) // Iterations + { + // Store the PageRank for All Nodes in Temporary Array + for (k = 1; k <= totalNodes; k++) { + TempPageRank[k] = this.pagerank[k]; + this.pagerank[k] = 0; + } + + for (InternalNodeNumber = 1; InternalNodeNumber <= totalNodes; InternalNodeNumber++) { + for (ExternalNodeNumber = 1; ExternalNodeNumber <= totalNodes; ExternalNodeNumber++) { + if (this.path[ExternalNodeNumber][InternalNodeNumber] == 1) { + k = 1; + OutgoingLinks = 0; // Count the Number of Outgoing Links for each ExternalNodeNumber + while (k <= totalNodes) { + if (this.path[ExternalNodeNumber][k] == 1) { + OutgoingLinks = OutgoingLinks + 1; // Counter for Outgoing Links + } + k = k + 1; + } + // Calculate PageRank + this.pagerank[InternalNodeNumber] += TempPageRank[ExternalNodeNumber] * (1 / OutgoingLinks); + } + } + System.out.printf("\n After " + ITERATION_STEP + "th Step \n"); + + for (k = 1; k <= totalNodes; k++) { + System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); + } + + ITERATION_STEP = ITERATION_STEP + 1; + } + + // Add the Damping Factor to PageRank + for (k = 1; k <= totalNodes; k++) { + this.pagerank[k] = (1 - DampingFactor) + DampingFactor * this.pagerank[k]; + } + + // Display PageRank + System.out.printf("\n Final Page Rank : \n"); + for (k = 1; k <= totalNodes; k++) { + System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); + } + + } + } +} diff --git a/src/main/java/com/thealgorithms/others/PasswordGen.java b/src/main/java/com/thealgorithms/others/PasswordGen.java new file mode 100644 index 000000000000..a88d94653bbd --- /dev/null +++ b/src/main/java/com/thealgorithms/others/PasswordGen.java @@ -0,0 +1,47 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +/** + * Creates a random password from ASCII letters Given password length bounds + * + * @author AKS1996 + * @date 2017.10.25 + */ +class PasswordGen { + + public static void main(String args[]) { + String password = generatePassword(8, 16); + System.out.print("Password: " + password); + } + + static String generatePassword(int min_length, int max_length) { + Random random = new Random(); + + String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + String lower = "abcdefghijklmnopqrstuvwxyz"; + String numbers = "0123456789"; + String specialChars = "!@#$%^&*(){}?"; + + String allChars = upper + lower + numbers + specialChars; + + List letters = new ArrayList(); + for (char c : allChars.toCharArray()) { + letters.add(c); + } + + // Inbuilt method to randomly shuffle a elements of a list + Collections.shuffle(letters); + StringBuilder password = new StringBuilder(); + + // Note that size of the password is also random + for (int i = random.nextInt(max_length - min_length) + min_length; i > 0; --i) { + password.append(letters.get(random.nextInt(letters.size()))); + } + + return password.toString(); + } +} diff --git a/src/main/java/com/thealgorithms/others/PerlinNoise.java b/src/main/java/com/thealgorithms/others/PerlinNoise.java new file mode 100644 index 000000000000..88671f4aabcf --- /dev/null +++ b/src/main/java/com/thealgorithms/others/PerlinNoise.java @@ -0,0 +1,170 @@ +package com.thealgorithms.others; + +import java.util.Random; +import java.util.Scanner; + +/** + * For detailed info and implementation see: Perlin-Noise + */ +public class PerlinNoise { + + /** + * @param width width of noise array + * @param height height of noise array + * @param octaveCount numbers of layers used for blending noise + * @param persistence value of impact each layer get while blending + * @param seed used for randomizer + * @return float array containing calculated "Perlin-Noise" values + */ + static float[][] generatePerlinNoise( + int width, int height, int octaveCount, float persistence, long seed) { + final float[][] base = new float[width][height]; + final float[][] perlinNoise = new float[width][height]; + final float[][][] noiseLayers = new float[octaveCount][][]; + + Random random = new Random(seed); + // fill base array with random values as base for noise + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + base[x][y] = random.nextFloat(); + } + } + + // calculate octaves with different roughness + for (int octave = 0; octave < octaveCount; octave++) { + noiseLayers[octave] = generatePerlinNoiseLayer(base, width, height, octave); + } + + float amplitude = 1f; + float totalAmplitude = 0f; + + // calculate perlin noise by blending each layer together with specific persistence + for (int octave = octaveCount - 1; octave >= 0; octave--) { + amplitude *= persistence; + totalAmplitude += amplitude; + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + // adding each value of the noise layer to the noise + // by increasing amplitude the rougher noises will have more impact + perlinNoise[x][y] += noiseLayers[octave][x][y] * amplitude; + } + } + } + + // normalize values so that they stay between 0..1 + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + perlinNoise[x][y] /= totalAmplitude; + } + } + + return perlinNoise; + } + + /** + * @param base base random float array + * @param width width of noise array + * @param height height of noise array + * @param octave current layer + * @return float array containing calculated "Perlin-Noise-Layer" values + */ + static float[][] generatePerlinNoiseLayer(float[][] base, int width, int height, int octave) { + float[][] perlinNoiseLayer = new float[width][height]; + + // calculate period (wavelength) for different shapes + int period = 1 << octave; // 2^k + float frequency = 1f / period; // 1/2^k + + for (int x = 0; x < width; x++) { + // calculates the horizontal sampling indices + int x0 = (x / period) * period; + int x1 = (x0 + period) % width; + float horizintalBlend = (x - x0) * frequency; + + for (int y = 0; y < height; y++) { + // calculates the vertical sampling indices + int y0 = (y / period) * period; + int y1 = (y0 + period) % height; + float verticalBlend = (y - y0) * frequency; + + // blend top corners + float top = interpolate(base[x0][y0], base[x1][y0], horizintalBlend); + + // blend bottom corners + float bottom = interpolate(base[x0][y1], base[x1][y1], horizintalBlend); + + // blend top and bottom interpolation to get the final blend value for this cell + perlinNoiseLayer[x][y] = interpolate(top, bottom, verticalBlend); + } + } + + return perlinNoiseLayer; + } + + /** + * @param a value of point a + * @param b value of point b + * @param alpha determine which value has more impact (closer to 0 -> a, + * closer to 1 -> b) + * @return interpolated value + */ + static float interpolate(float a, float b, float alpha) { + return a * (1 - alpha) + alpha * b; + } + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + + final int width; + final int height; + final int octaveCount; + final float persistence; + final long seed; + final String charset; + final float[][] perlinNoise; + + System.out.println("Width (int): "); + width = in.nextInt(); + + System.out.println("Height (int): "); + height = in.nextInt(); + + System.out.println("Octave count (int): "); + octaveCount = in.nextInt(); + + System.out.println("Persistence (float): "); + persistence = in.nextFloat(); + + System.out.println("Seed (long): "); + seed = in.nextLong(); + + System.out.println("Charset (String): "); + charset = in.next(); + + perlinNoise = generatePerlinNoise(width, height, octaveCount, persistence, seed); + final char[] chars = charset.toCharArray(); + final int length = chars.length; + final float step = 1f / length; + // output based on charset + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + float value = step; + float noiseValue = perlinNoise[x][y]; + + for (char c : chars) { + if (noiseValue <= value) { + System.out.print(c); + break; + } + + value += step; + } + } + + System.out.println(); + } + in.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java b/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java new file mode 100644 index 000000000000..d699c4a6b94c --- /dev/null +++ b/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java @@ -0,0 +1,173 @@ +package com.thealgorithms.others; + +import java.util.Stack; + +/** + * This implements Queue using two Stacks. + * + *

+ * Big O Runtime: insert(): O(1) remove(): O(1) amortized isEmpty(): O(1) + * + *

+ * A queue data structure functions the same as a real world queue. The elements + * that are added first are the first to be removed. New elements are added to + * the back/rear of the queue. + * + * @author sahilb2 (https://www.github.com/sahilb2) + */ +class QueueWithStack { + + // Stack to keep track of elements inserted into the queue + private Stack inStack; + // Stack to keep track of elements to be removed next in queue + private Stack outStack; + + /** + * Constructor + */ + public QueueWithStack() { + this.inStack = new Stack<>(); + this.outStack = new Stack<>(); + } + + /** + * Inserts an element at the rear of the queue + * + * @param x element to be added + */ + public void insert(Object x) { + // Insert element into inStack + this.inStack.push(x); + } + + /** + * Remove an element from the front of the queue + * + * @return the new front of the queue + */ + public Object remove() { + if (this.outStack.isEmpty()) { + // Move all elements from inStack to outStack (preserving the order) + while (!this.inStack.isEmpty()) { + this.outStack.push(this.inStack.pop()); + } + } + return this.outStack.pop(); + } + + /** + * Peek at the element from the front of the queue + * + * @return the front element of the queue + */ + public Object peekFront() { + if (this.outStack.isEmpty()) { + // Move all elements from inStack to outStack (preserving the order) + while (!this.inStack.isEmpty()) { + this.outStack.push(this.inStack.pop()); + } + } + return this.outStack.peek(); + } + + /** + * Peek at the element from the back of the queue + * + * @return the back element of the queue + */ + public Object peekBack() { + return this.inStack.peek(); + } + + /** + * Returns true if the queue is empty + * + * @return true if the queue is empty + */ + public boolean isEmpty() { + return (this.inStack.isEmpty() && this.outStack.isEmpty()); + } + + /** + * Returns true if the inStack is empty. + * + * @return true if the inStack is empty. + */ + public boolean isInStackEmpty() { + return (inStack.size() == 0); + } + + /** + * Returns true if the outStack is empty. + * + * @return true if the outStack is empty. + */ + public boolean isOutStackEmpty() { + return (outStack.size() == 0); + } +} + +/** + * This class is the example for the Queue class + * + * @author sahilb2 (https://www.github.com/sahilb2) + */ +public class QueueUsingTwoStacks { + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String args[]) { + QueueWithStack myQueue = new QueueWithStack(); + myQueue.insert(1); + System.out.println(myQueue.peekBack()); // Will print 1 + // instack: [(top) 1] + // outStack: [] + myQueue.insert(2); + System.out.println(myQueue.peekBack()); // Will print 2 + // instack: [(top) 2, 1] + // outStack: [] + myQueue.insert(3); + System.out.println(myQueue.peekBack()); // Will print 3 + // instack: [(top) 3, 2, 1] + // outStack: [] + myQueue.insert(4); + System.out.println(myQueue.peekBack()); // Will print 4 + // instack: [(top) 4, 3, 2, 1] + // outStack: [] + + System.out.println(myQueue.isEmpty()); // Will print false + + System.out.println(myQueue.remove()); // Will print 1 + System.out.println((myQueue.isInStackEmpty()) ? "null" : myQueue.peekBack()); // Will print NULL + // instack: [] + // outStack: [(top) 2, 3, 4] + + myQueue.insert(5); + System.out.println(myQueue.peekFront()); // Will print 2 + // instack: [(top) 5] + // outStack: [(top) 2, 3, 4] + + myQueue.remove(); + System.out.println(myQueue.peekFront()); // Will print 3 + // instack: [(top) 5] + // outStack: [(top) 3, 4] + myQueue.remove(); + System.out.println(myQueue.peekFront()); // Will print 4 + // instack: [(top) 5] + // outStack: [(top) 4] + myQueue.remove(); + // instack: [(top) 5] + // outStack: [] + System.out.println(myQueue.peekFront()); // Will print 5 + // instack: [] + // outStack: [(top) 5] + myQueue.remove(); + // instack: [] + // outStack: [] + + System.out.println(myQueue.isEmpty()); // Will print true + } +} diff --git a/src/main/java/com/thealgorithms/others/RabinKarp.java b/src/main/java/com/thealgorithms/others/RabinKarp.java new file mode 100644 index 000000000000..5fee40318709 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/RabinKarp.java @@ -0,0 +1,87 @@ +package com.thealgorithms.others; + +/** + * @author Prateek Kumar Oraon (https://github.com/prateekKrOraon) + */ +import java.util.Scanner; + +// An implementation of Rabin-Karp string matching algorithm +// Program will simply end if there is no match +public class RabinKarp { + + public static Scanner scanner = null; + public static final int d = 256; + + public static void main(String[] args) { + + scanner = new Scanner(System.in); + System.out.println("Enter String"); + String text = scanner.nextLine(); + System.out.println("Enter pattern"); + String pattern = scanner.nextLine(); + + int q = 101; + searchPat(text, pattern, q); + } + + private static void searchPat(String text, String pattern, int q) { + + int m = pattern.length(); + int n = text.length(); + int t = 0; + int p = 0; + int h = 1; + int j = 0; + int i = 0; + + h = (int) Math.pow(d, m - 1) % q; + + for (i = 0; i < m; i++) { + // hash value is calculated for each character and then added with the hash value of the next + // character for pattern + // as well as the text for length equal to the length of pattern + p = (d * p + pattern.charAt(i)) % q; + t = (d * t + text.charAt(i)) % q; + } + + for (i = 0; i <= n - m; i++) { + + // if the calculated hash value of the pattern and text matches then + // all the characters of the pattern is matched with the text of length equal to length of the + // pattern + // if all matches then pattern exist in string + // if not then the hash value of the first character of the text is subtracted and hash value + // of the next character after the end + // of the evaluated characters is added + if (p == t) { + + // if hash value matches then the individual characters are matched + for (j = 0; j < m; j++) { + + // if not matched then break out of the loop + if (text.charAt(i + j) != pattern.charAt(j)) { + break; + } + } + + // if all characters are matched then pattern exist in the string + if (j == m) { + System.out.println("Pattern found at index " + i); + } + } + + // if i stack = new Stack<>(); + + // Main function + public static void main(String[] args) { + // To Create a Dummy Stack containing integers from 0-9 + for (int i = 0; i < 10; i++) { + stack.push(i); + } + System.out.println("STACK"); + + // To print that dummy Stack + for (int k = 9; k >= 0; k--) { + System.out.println(k); + } + + // Reverse Function called + reverseUsingRecursion(stack); + + System.out.println("REVERSED STACK : "); + // To print reversed stack + while (!stack.isEmpty()) { + System.out.println(stack.pop()); + } + } + + // Function Used to reverse Stack Using Recursion + private static void reverseUsingRecursion(Stack stack) { + if (stack.isEmpty()) // If stack is empty then return + { + return; + } + /* All items are stored in call stack until we reach the end*/ + + int temptop = stack.peek(); + stack.pop(); + reverseUsingRecursion(stack); // Recursion call + insertAtEnd(temptop); // Insert items held in call stack one by one into stack + } + + // Function used to insert element at the end of stack + private static void insertAtEnd(int temptop) { + if (stack.isEmpty()) { + stack.push(temptop); // If stack is empty push the element + } else { + int temp = stack.peek(); + /* All the items are stored in call stack until we reach end*/ + stack.pop(); + + insertAtEnd(temptop); // Recursive call + + stack.push(temp); + } + } +} diff --git a/src/main/java/com/thealgorithms/others/RootPrecision.java b/src/main/java/com/thealgorithms/others/RootPrecision.java new file mode 100644 index 000000000000..e22db1b99931 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/RootPrecision.java @@ -0,0 +1,36 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +public class RootPrecision { + + public static void main(String[] args) { + // take input + Scanner scn = new Scanner(System.in); + + // N is the input number + int N = scn.nextInt(); + + // P is precision value for eg - P is 3 in 2.564 and 5 in 3.80870. + int P = scn.nextInt(); + System.out.println(squareRoot(N, P)); + + scn.close(); + } + + public static double squareRoot(int N, int P) { + // rv means return value + double rv; + + double root = Math.pow(N, 0.5); + + // calculate precision to power of 10 and then multiply it with root value. + int precision = (int) Math.pow(10, P); + root = root * precision; + /*typecast it into integer then divide by precision and again typecast into double + so as to have decimal points upto P precision */ + + rv = (int) root; + return rv / precision; + } +} diff --git a/src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java b/src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java new file mode 100644 index 000000000000..3c1b349e70b8 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java @@ -0,0 +1,70 @@ +package com.thealgorithms.others; + +/** + * Given a matrix of size n x n We have to rotate this matrix by 90 Degree Here + * is the algorithm for this problem . + */ +import java.util.*; + +class Rotate_by_90_degree { + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int t = sc.nextInt(); + + while (t-- > 0) { + int n = sc.nextInt(); + int[][] arr = new int[n][n]; + + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + arr[i][j] = sc.nextInt(); + } + } + + Rotate g = new Rotate(); + g.rotate(arr); + printMatrix(arr); + } + sc.close(); + } + + static void printMatrix(int arr[][]) { + for (int i = 0; i < arr.length; i++) { + for (int j = 0; j < arr[0].length; j++) { + System.out.print(arr[i][j] + " "); + } + System.out.println(""); + } + } +} + +/** + * Class containing the algo to roate matrix by 90 degree + */ +class Rotate { + + static void rotate(int a[][]) { + int n = a.length; + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (i > j) { + int temp = a[i][j]; + a[i][j] = a[j][i]; + a[j][i] = temp; + } + } + } + int i = 0, k = n - 1; + while (i < k) { + for (int j = 0; j < n; j++) { + int temp = a[i][j]; + a[i][j] = a[k][j]; + a[k][j] = temp; + } + + i++; + k--; + } + } +} diff --git a/src/main/java/com/thealgorithms/others/SJF.java b/src/main/java/com/thealgorithms/others/SJF.java new file mode 100644 index 000000000000..0ced44166814 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/SJF.java @@ -0,0 +1,188 @@ +package com.thealgorithms.others; + +/** + * + * + *

Shortest job first.

+ * + *

+ * Shortest job first (SJF) or shortest job next, is a scheduling policy that + * selects the waiting process with the smallest execution time to execute next + * Shortest Job first has the advantage of having minimum average waiting time + * among all scheduling algorithms. It is a Greedy Algorithm. It may cause + * starvation if shorter processes keep coming. This problem has been solved + * using the concept of aging. + * + * @author shivg7706 + * @since 2018/10/27 + */ +import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Scanner; + +class Process { + + public int pid; + public int arrivalTime; + public int burstTime; + public int priority; + public int turnAroundTime; + public int waitTime; + public int remainingTime; +} + +class Schedule { + + private int noOfProcess; + private int timer = 0; + private ArrayList processes; + private ArrayList remainingProcess; + private ArrayList gantChart; + private float burstAll; + private Map> arrivals; + + Schedule() { + Scanner in = new Scanner(System.in); + + processes = new ArrayList(); + remainingProcess = new ArrayList(); + + gantChart = new ArrayList<>(); + arrivals = new HashMap<>(); + + System.out.print("Enter the no. of processes: "); + noOfProcess = in.nextInt(); + System.out.println("Enter the arrival, burst and priority of processes"); + for (int i = 0; i < noOfProcess; i++) { + Process p = new Process(); + p.pid = i; + p.arrivalTime = in.nextInt(); + p.burstTime = in.nextInt(); + p.priority = in.nextInt(); + p.turnAroundTime = 0; + p.waitTime = 0; + p.remainingTime = p.burstTime; + + if (arrivals.get(p.arrivalTime) == null) { + arrivals.put(p.arrivalTime, new ArrayList()); + } + arrivals.get(p.arrivalTime).add(p); + processes.add(p); + burstAll += p.burstTime; + } + in.close(); + } + + void startScheduling() { + + processes.sort( + new Comparator() { + @Override + public int compare(Process a, Process b) { + return a.arrivalTime - b.arrivalTime; + } + }); + + while (!(arrivals.size() == 0 && remainingProcess.size() == 0)) { + removeFinishedProcess(); + if (arrivals.get(timer) != null) { + remainingProcess.addAll(arrivals.get(timer)); + arrivals.remove(timer); + } + + remainingProcess.sort( + new Comparator() { + private int alpha = 6; + private int beta = 1; + + @Override + public int compare(Process a, Process b) { + int aRem = a.remainingTime; + int bRem = b.remainingTime; + int aprior = a.priority; + int bprior = b.priority; + return (alpha * aRem + beta * aprior) - (alpha * bRem + beta * bprior); + } + }); + + int k = timeElapsed(timer); + ageing(k); + timer++; + } + + System.out.println("Total time required: " + (timer - 1)); + } + + void removeFinishedProcess() { + ArrayList completed = new ArrayList(); + for (int i = 0; i < remainingProcess.size(); i++) { + if (remainingProcess.get(i).remainingTime == 0) { + completed.add(i); + } + } + + for (int i = 0; i < completed.size(); i++) { + int pid = remainingProcess.get(completed.get(i)).pid; + processes.get(pid).waitTime = remainingProcess.get(completed.get(i)).waitTime; + remainingProcess.remove(remainingProcess.get(completed.get(i))); + } + } + + public int timeElapsed(int i) { + if (!remainingProcess.isEmpty()) { + gantChart.add(i, remainingProcess.get(0).pid); + remainingProcess.get(0).remainingTime--; + return 1; + } + return 0; + } + + public void ageing(int k) { + for (int i = k; i < remainingProcess.size(); i++) { + remainingProcess.get(i).waitTime++; + if (remainingProcess.get(i).waitTime % 7 == 0) { + remainingProcess.get(i).priority--; + } + } + } + + public void solve() { + System.out.println("Gant chart "); + for (int i = 0; i < gantChart.size(); i++) { + System.out.print(gantChart.get(i) + " "); + } + System.out.println(); + + float waitTimeTot = 0; + float tatTime = 0; + + for (int i = 0; i < noOfProcess; i++) { + processes.get(i).turnAroundTime = processes.get(i).waitTime + processes.get(i).burstTime; + + waitTimeTot += processes.get(i).waitTime; + tatTime += processes.get(i).turnAroundTime; + + System.out.println( + "Process no.: " + + i + + " Wait time: " + + processes.get(i).waitTime + + " Turn Around Time: " + + processes.get(i).turnAroundTime); + } + + System.out.println("Average Waiting Time: " + waitTimeTot / noOfProcess); + System.out.println("Average TAT Time: " + tatTime / noOfProcess); + System.out.println("Throughput: " + (float) noOfProcess / (timer - 1)); + } +} + +public class SJF { + + public static void main(String[] args) { + Schedule s = new Schedule(); + s.startScheduling(); + s.solve(); + } +} diff --git a/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java b/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java new file mode 100644 index 000000000000..7ba6d76b4612 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java @@ -0,0 +1,80 @@ +package com.thealgorithms.others; + +import java.util.Arrays; + +/** + * Sieve of Eratosthenes is an ancient algorithm for finding all prime numbers + * up to any given limit. It does so by iteratively marking as composite (i.e., + * not prime) the multiples of each prime, starting with the first prime number, + * 2. The multiples of a given prime are generated as a sequence of numbers + * starting from that prime, with constant difference between them that is equal + * to that prime. This is the sieve's key distinction from using trial division + * to sequentially test each candidate number for divisibility by each prime. + * Once all the multiples of each discovered prime have been marked as + * composites, the remaining unmarked numbers are primes. + *

+ * Poetry about Sieve of Eratosthenes: + *

+ * Sift the Two's and Sift the Three's:

+ *

+ * The Sieve of Eratosthenes.

+ *

+ * When the multiples sublime,

+ *

+ * The numbers that remain are Prime.

+ * + * @see Wiki + */ +public class SieveOfEratosthenes { + + /** + * @param n The number till which we have to check for prime Prints all the + * prime numbers till n. Should be more than 1. + * @return array of all prime numbers between 0 to n + */ + public static int[] findPrimesTill(int n) { + // Create array where index is number and value is flag - is that number a prime or not. + // size of array is n + 1 cause in Java array indexes starts with 0 + Type[] numbers = new Type[n + 1]; + + // Start with assumption that all numbers except 0 and 1 are primes. + Arrays.fill(numbers, Type.PRIME); + numbers[0] = numbers[1] = Type.NOT_PRIME; + + double cap = Math.sqrt(n); + // Main algorithm: mark all numbers which are multiples of some other values as not prime + for (int i = 2; i <= cap; i++) { + if (numbers[i] == Type.PRIME) { + for (int j = 2; i * j <= n; j++) { + numbers[i * j] = Type.NOT_PRIME; + } + } + } + + //Write all primes to result array + int primesCount = (int) Arrays.stream(numbers) + .filter(element -> element == Type.PRIME) + .count(); + int[] primes = new int[primesCount]; + + int primeIndex = 0; + for (int i = 0; i < n + 1; i++) { + if (numbers[i] == Type.PRIME) { + primes[primeIndex++] = i; + } + } + + return primes; + } + + private enum Type { + PRIME, NOT_PRIME + } + + public static void main(String[] args) { + int n = 100; + System.out.println("Searching for all primes from zero to " + n); + int[] primes = findPrimesTill(n); + System.out.println("Found: " + Arrays.toString(primes)); + } +} diff --git a/src/main/java/com/thealgorithms/others/SkylineProblem.java b/src/main/java/com/thealgorithms/others/SkylineProblem.java new file mode 100644 index 000000000000..149adf4349cf --- /dev/null +++ b/src/main/java/com/thealgorithms/others/SkylineProblem.java @@ -0,0 +1,139 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Scanner; + +public class SkylineProblem { + + Building[] building; + int count; + + public void run() { + Scanner sc = new Scanner(System.in); + + int num = sc.nextInt(); + this.building = new Building[num]; + + for (int i = 0; i < num; i++) { + String input = sc.next(); + String[] data = input.split(","); + this.add(Integer.parseInt(data[0]), Integer.parseInt(data[1]), Integer.parseInt(data[2])); + } + this.print(this.findSkyline(0, num - 1)); + + sc.close(); + } + + public void add(int left, int height, int right) { + building[count++] = new Building(left, height, right); + } + + public void print(ArrayList skyline) { + Iterator it = skyline.iterator(); + + while (it.hasNext()) { + Skyline temp = it.next(); + System.out.print(temp.coordinates + "," + temp.height); + if (it.hasNext()) { + System.out.print(","); + } + } + } + + public ArrayList findSkyline(int start, int end) { + if (start == end) { + ArrayList list = new ArrayList<>(); + list.add(new Skyline(building[start].left, building[start].height)); + list.add(new Skyline(building[end].right, 0)); + + return list; + } + + int mid = (start + end) / 2; + + ArrayList sky1 = this.findSkyline(start, mid); + ArrayList sky2 = this.findSkyline(mid + 1, end); + + return this.mergeSkyline(sky1, sky2); + } + + public ArrayList mergeSkyline(ArrayList sky1, ArrayList sky2) { + int currentH1 = 0, currentH2 = 0; + ArrayList skyline = new ArrayList<>(); + int maxH = 0; + + while (!sky1.isEmpty() && !sky2.isEmpty()) { + if (sky1.get(0).coordinates < sky2.get(0).coordinates) { + int currentX = sky1.get(0).coordinates; + currentH1 = sky1.get(0).height; + + if (currentH1 < currentH2) { + sky1.remove(0); + if (maxH != currentH2) { + skyline.add(new Skyline(currentX, currentH2)); + } + } else { + maxH = currentH1; + sky1.remove(0); + skyline.add(new Skyline(currentX, currentH1)); + } + } else { + int currentX = sky2.get(0).coordinates; + currentH2 = sky2.get(0).height; + + if (currentH2 < currentH1) { + sky2.remove(0); + if (maxH != currentH1) { + skyline.add(new Skyline(currentX, currentH1)); + } + } else { + maxH = currentH2; + sky2.remove(0); + skyline.add(new Skyline(currentX, currentH2)); + } + } + } + + while (!sky1.isEmpty()) { + skyline.add(sky1.get(0)); + sky1.remove(0); + } + + while (!sky2.isEmpty()) { + skyline.add(sky2.get(0)); + sky2.remove(0); + } + + return skyline; + } + + public class Skyline { + + public int coordinates; + public int height; + + public Skyline(int coordinates, int height) { + this.coordinates = coordinates; + this.height = height; + } + } + + public class Building { + + public int left; + public int height; + public int right; + + public Building(int left, int height, int right) { + this.left = left; + this.height = height; + this.right = right; + } + } + + public static void main(String[] args) { + SkylineProblem skylineProblem = new SkylineProblem(); + skylineProblem.run(); + } +} diff --git a/src/main/java/com/thealgorithms/others/StackPostfixNotation.java b/src/main/java/com/thealgorithms/others/StackPostfixNotation.java new file mode 100644 index 000000000000..0a949fe874ac --- /dev/null +++ b/src/main/java/com/thealgorithms/others/StackPostfixNotation.java @@ -0,0 +1,43 @@ +package com.thealgorithms.others; + +import java.util.*; + +public class StackPostfixNotation { + + public static void main(String[] args) { + Scanner scanner = new Scanner(System.in); + String post = scanner.nextLine(); // Takes input with spaces in between eg. "1 21 +" + System.out.println(postfixEvaluate(post)); + scanner.close(); + } + + // Evaluates the given postfix expression string and returns the result. + public static int postfixEvaluate(String exp) { + Stack s = new Stack(); + Scanner tokens = new Scanner(exp); + + while (tokens.hasNext()) { + if (tokens.hasNextInt()) { + s.push(tokens.nextInt()); // If int then push to stack + } else { // else pop top two values and perform the operation + int num2 = s.pop(); + int num1 = s.pop(); + String op = tokens.next(); + + if (op.equals("+")) { + s.push(num1 + num2); + } else if (op.equals("-")) { + s.push(num1 - num2); + } else if (op.equals("*")) { + s.push(num1 * num2); + } else { + s.push(num1 / num2); + } + + // "+", "-", "*", "/" + } + } + tokens.close(); + return s.pop(); + } +} diff --git a/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java b/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java new file mode 100644 index 000000000000..b2be51c10234 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java @@ -0,0 +1,85 @@ +package com.thealgorithms.others; + +/** + * @author Prateek Kumar Oraon (https://github.com/prateekKrOraon) + */ +import java.util.Scanner; + +// An implementaion of string matching using finite automata +public class StringMatchFiniteAutomata { + + public static final int CHARS = 256; + public static int[][] FA; + public static Scanner scanner = null; + + public static void main(String[] args) { + + scanner = new Scanner(System.in); + System.out.println("Enter String"); + String text = scanner.nextLine(); + System.out.println("Enter pattern"); + String pat = scanner.nextLine(); + + searchPat(text, pat); + + scanner.close(); + } + + public static void searchPat(String text, String pat) { + + int m = pat.length(); + int n = text.length(); + + FA = new int[m + 1][CHARS]; + + computeFA(pat, m, FA); + + int state = 0; + for (int i = 0; i < n; i++) { + state = FA[state][text.charAt(i)]; + + if (state == m) { + System.out.println("Pattern found at index " + (i - m + 1)); + } + } + } + + // Computes finite automata for the partern + public static void computeFA(String pat, int m, int[][] FA) { + + for (int state = 0; state <= m; ++state) { + for (int x = 0; x < CHARS; ++x) { + FA[state][x] = getNextState(pat, m, state, x); + } + } + } + + public static int getNextState(String pat, int m, int state, int x) { + + // if current state is less than length of pattern + // and input character of pattern matches the character in the alphabet + // then automata goes to next state + if (state < m && x == pat.charAt(state)) { + return state + 1; + } + + for (int ns = state; ns > 0; ns--) { + + if (pat.charAt(ns - 1) == x) { + + for (int i = 0; i < ns - 1; i++) { + + if (pat.charAt(i) != pat.charAt(state - ns + i + 1)) { + break; + } + + if (i == ns - 1) { + return ns; + } + } + } + } + + return 0; + } +} diff --git a/Others/Sudoku.java b/src/main/java/com/thealgorithms/others/Sudoku.java similarity index 55% rename from Others/Sudoku.java rename to src/main/java/com/thealgorithms/others/Sudoku.java index 375fe9f712f1..6c69663405d9 100644 --- a/Others/Sudoku.java +++ b/src/main/java/com/thealgorithms/others/Sudoku.java @@ -1,16 +1,13 @@ -package Others; +package com.thealgorithms.others; +class Sudoku { -class Sudoku -{ public static boolean isSafe(int[][] board, - int row, int col, - int num) - { + int row, int col, + int num) { // Row has the unique (row-clash) - for (int d = 0; d < board.length; d++) - { - + for (int d = 0; d < board.length; d++) { + // Check if the number we are trying to // place is already present in // that row, return false; @@ -18,59 +15,50 @@ public static boolean isSafe(int[][] board, return false; } } - + // Column has the unique numbers (column-clash) - for (int r = 0; r < board.length; r++) - { - + for (int r = 0; r < board.length; r++) { + // Check if the number // we are trying to // place is already present in // that column, return false; - if (board[r][col] == num) - { + if (board[r][col] == num) { return false; } } - + // Corresponding square has // unique number (box-clash) - int sqrt = (int)Math.sqrt(board.length); + int sqrt = (int) Math.sqrt(board.length); int boxRowStart = row - row % sqrt; int boxColStart = col - col % sqrt; - + for (int r = boxRowStart; - r < boxRowStart + sqrt; r++) - { + r < boxRowStart + sqrt; r++) { for (int d = boxColStart; - d < boxColStart + sqrt; d++) - { - if (board[r][d] == num) - { + d < boxColStart + sqrt; d++) { + if (board[r][d] == num) { return false; } } } - + // if there is no clash, it's safe return true; } - + public static boolean solveSudoku( - int[][] board, int n) - { + int[][] board, int n) { int row = -1; int col = -1; boolean isEmpty = true; - for (int i = 0; i < n; i++) - { - for (int j = 0; j < n; j++) - { - if (board[i][j] == 0) - { + for (int i = 0; i < n; i++) { + for (int j = 0; j < n; j++) { + if (board[i][j] == 0) { row = i; col = j; - + // We still have some remaining // missing values in Sudoku isEmpty = false; @@ -81,26 +69,20 @@ public static boolean solveSudoku( break; } } - + // No empty space left - if (isEmpty) - { + if (isEmpty) { return true; } - + // Else for each-row backtrack - for (int num = 1; num <= n; num++) - { - if (isSafe(board, row, col, num)) - { + for (int num = 1; num <= n; num++) { + if (isSafe(board, row, col, num)) { board[row][col] = num; - if (solveSudoku(board, n)) - { + if (solveSudoku(board, n)) { // print(board, n); return true; - } - else - { + } else { // replace it board[row][col] = 0; } @@ -108,52 +90,45 @@ public static boolean solveSudoku( } return false; } - + public static void print( - int[][] board, int N) - { - + int[][] board, int N) { + // We got the answer, just print it - for (int r = 0; r < N; r++) - { - for (int d = 0; d < N; d++) - { + for (int r = 0; r < N; r++) { + for (int d = 0; d < N; d++) { System.out.print(board[r][d]); System.out.print(" "); } System.out.print("\n"); - - if ((r + 1) % (int)Math.sqrt(N) == 0) - { + + if ((r + 1) % (int) Math.sqrt(N) == 0) { System.out.print(""); } } } - + // Driver Code - public static void main(String args[]) - { - - int[][] board = new int[][] { - { 3, 0, 6, 5, 0, 8, 4, 0, 0 }, - { 5, 2, 0, 0, 0, 0, 0, 0, 0 }, - { 0, 8, 7, 0, 0, 0, 0, 3, 1 }, - { 0, 0, 3, 0, 1, 0, 0, 8, 0 }, - { 9, 0, 0, 8, 6, 3, 0, 0, 5 }, - { 0, 5, 0, 0, 9, 0, 6, 0, 0 }, - { 1, 3, 0, 0, 0, 0, 2, 5, 0 }, - { 0, 0, 0, 0, 0, 0, 0, 7, 4 }, - { 0, 0, 5, 2, 0, 6, 3, 0, 0 } + public static void main(String args[]) { + + int[][] board = new int[][]{ + {3, 0, 6, 5, 0, 8, 4, 0, 0}, + {5, 2, 0, 0, 0, 0, 0, 0, 0}, + {0, 8, 7, 0, 0, 0, 0, 3, 1}, + {0, 0, 3, 0, 1, 0, 0, 8, 0}, + {9, 0, 0, 8, 6, 3, 0, 0, 5}, + {0, 5, 0, 0, 9, 0, 6, 0, 0}, + {1, 3, 0, 0, 0, 0, 2, 5, 0}, + {0, 0, 0, 0, 0, 0, 0, 7, 4}, + {0, 0, 5, 2, 0, 6, 3, 0, 0} }; int N = board.length; - - if (solveSudoku(board, N)) - { + + if (solveSudoku(board, N)) { // print solution print(board, N); - } - else { + } else { System.out.println("No solution"); } } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/others/ThreeSum.java b/src/main/java/com/thealgorithms/others/ThreeSum.java new file mode 100644 index 000000000000..a9a6c6728862 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/ThreeSum.java @@ -0,0 +1,54 @@ +package com.thealgorithms.others; + +import java.util.Arrays; +import java.util.Scanner; + +/** + * To find triplet equals to given sum in complexity O(n*log(n)) + * + *

+ * Array must be sorted + * + * @author Ujjawal Joshi + * @date 2020.05.18 + *

+ * Test Cases: Input: 6 //Length of array 12 3 4 1 6 9 target=24 Output:3 9 12 + * Explanation: There is a triplet (12, 3 and 9) present in the array whose sum + * is 24. + */ +class ThreeSum { + + public static void main(String args[]) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); // Length of an array + + int a[] = new int[n]; + + for (int i = 0; i < n; i++) { + a[i] = sc.nextInt(); + } + System.out.println("Target"); + int n_find = sc.nextInt(); + + Arrays.sort(a); // Sort the array if array is not sorted + + for (int i = 0; i < n; i++) { + + int l = i + 1, r = n - 1; + + while (l < r) { + if (a[i] + a[l] + a[r] == n_find) { + System.out.println(a[i] + " " + a[l] + " " + a[r]); + break; + } // if you want all the triplets write l++;r--; insted of break; + else if (a[i] + a[l] + a[r] < n_find) { + l++; + } else { + r--; + } + } + } + + sc.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/TopKWords.java b/src/main/java/com/thealgorithms/others/TopKWords.java new file mode 100644 index 000000000000..fe19ca82f2ad --- /dev/null +++ b/src/main/java/com/thealgorithms/others/TopKWords.java @@ -0,0 +1,89 @@ +package com.thealgorithms.others; + +import java.io.*; +import java.util.*; + +/* display the most frequent K words in the file and the times it appear +in the file – shown in order (ignore case and periods) */ +public class TopKWords { + + static class CountWords { + + private String fileName; + + public CountWords(String fileName) { + this.fileName = fileName; + } + + public Map getDictionary() { + Map dictionary = new HashMap<>(); + FileInputStream fis = null; + + try { + + fis = new FileInputStream(fileName); // open the file + int in = 0; + String s = ""; // init a empty word + in = fis.read(); // read one character + + while (-1 != in) { + if (Character.isLetter((char) in)) { + s += (char) in; // if get a letter, append to s + } else { + // this branch means an entire word has just been read + if (s.length() > 0) { + // see whether word exists or not + if (dictionary.containsKey(s)) { + // if exist, count++ + dictionary.put(s, dictionary.get(s) + 1); + } else { + // if not exist, initiate count of this word with 1 + dictionary.put(s, 1); + } + } + s = ""; // reInit a empty word + } + in = fis.read(); + } + return dictionary; + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + // you always have to close the I/O streams + if (fis != null) { + fis.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + } + + public static void main(String[] args) { + // you can replace the filePath with yours + CountWords cw = new CountWords("/Users/lisanaaa/Desktop/words.txt"); + Map dictionary + = cw.getDictionary(); // get the words dictionary: {word: frequency} + + // we change the map to list for convenient sort + List> list = new ArrayList<>(dictionary.entrySet()); + + // sort by lambda valueComparator + list.sort(Comparator.comparing(m -> m.getValue())); + + Scanner input = new Scanner(System.in); + int k = input.nextInt(); + while (k > list.size()) { + System.out.println("Retype a number, your number is too large"); + input = new Scanner(System.in); + k = input.nextInt(); + } + for (int i = 0; i < k; i++) { + System.out.println(list.get(list.size() - i - 1)); + } + input.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/TowerOfHanoi.java b/src/main/java/com/thealgorithms/others/TowerOfHanoi.java new file mode 100644 index 000000000000..17100b2ab611 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/TowerOfHanoi.java @@ -0,0 +1,27 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +class TowerOfHanoi { + + public static void shift(int n, String startPole, String intermediatePole, String endPole) { + // if n becomes zero the program returns thus ending the loop. + if (n != 0) { + // Shift function is called in recursion for swapping the n-1 disc from the startPole to the + // intermediatePole + shift(n - 1, startPole, endPole, intermediatePole); + System.out.format("Move %d from %s to %s\n", n, startPole, endPole); // Result Printing + // Shift function is called in recursion for swapping the n-1 disc from the intermediatePole + // to the endPole + shift(n - 1, intermediatePole, startPole, endPole); + } + } + + public static void main(String[] args) { + System.out.print("Enter number of discs on Pole 1: "); + Scanner scanner = new Scanner(System.in); + int numberOfDiscs = scanner.nextInt(); // input of number of discs on pole 1 + shift(numberOfDiscs, "Pole1", "Pole2", "Pole3"); // Shift function called + scanner.close(); + } +} diff --git a/src/main/java/com/thealgorithms/others/TwoPointers.java b/src/main/java/com/thealgorithms/others/TwoPointers.java new file mode 100644 index 000000000000..814ac1bfb1a4 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/TwoPointers.java @@ -0,0 +1,57 @@ +package com.thealgorithms.others; + +import java.util.Arrays; + +/** + * The two pointer technique is a useful tool to utilize when searching for + * pairs in a sorted array. + * + *

+ * link: https://www.geeksforgeeks.org/two-pointers-technique/ + */ +class TwoPointers { + + public static void main(String[] args) { + int[] arr = {10, 20, 35, 50, 75, 80}; + int key = 70; + assert isPairedSum(arr, key); + /* 20 + 60 == 70 */ + + arr = new int[]{1, 2, 3, 4, 5, 6, 7}; + key = 13; + assert isPairedSum(arr, key); + /* 6 + 7 == 13 */ + + key = 14; + assert !isPairedSum(arr, key); + } + + /** + * Given a sorted array arr (sorted in ascending order). Find if there + * exists any pair of elements such that their sum is equal to key. + * + * @param arr the array contains elements + * @param key the number to search + * @return {@code true} if there exists a pair of elements, {@code false} + * otherwise. + */ + private static boolean isPairedSum(int[] arr, int key) { + /* array sorting is necessary for this algorithm to function correctly */ + Arrays.sort(arr); + int i = 0; + /* index of first element */ + int j = arr.length - 1; + /* index of last element */ + + while (i < j) { + if (arr[i] + arr[j] == key) { + return true; + } else if (arr[i] + arr[j] < key) { + i++; + } else { + j--; + } + } + return false; + } +} diff --git a/Others/Verhoeff.java b/src/main/java/com/thealgorithms/others/Verhoeff.java similarity index 71% rename from Others/Verhoeff.java rename to src/main/java/com/thealgorithms/others/Verhoeff.java index 5dc29898e9cc..760ef0e16b68 100644 --- a/Others/Verhoeff.java +++ b/src/main/java/com/thealgorithms/others/Verhoeff.java @@ -1,36 +1,38 @@ -package Others; +package com.thealgorithms.others; import java.util.Objects; /** - * The Verhoeff algorithm is a checksum formula for error detection developed - * by the Dutch mathematician Jacobus Verhoeff and was first published in 1969. - * It was the first decimal check digit algorithm which detects all single-digit + * The Verhoeff algorithm is a checksum formula for error detection developed by + * the Dutch mathematician Jacobus Verhoeff and was first published in 1969. It + * was the first decimal check digit algorithm which detects all single-digit * errors, and all transposition errors involving two adjacent digits. * - *

The strengths of the algorithm are that it detects all transliteration and - * transposition errors, and additionally most twin, twin jump, jump transposition - * and phonetic errors. - * The main weakness of the Verhoeff algorithm is its complexity. - * The calculations required cannot easily be expressed as a formula. - * For easy calculation three tables are required:

+ *

+ * The strengths of the algorithm are that it detects all transliteration and + * transposition errors, and additionally most twin, twin jump, jump + * transposition and phonetic errors. The main weakness of the Verhoeff + * algorithm is its complexity. The calculations required cannot easily be + * expressed as a formula. For easy calculation three tables are required:

*
    - *
  1. multiplication table
  2. - *
  3. inverse table
  4. - *
  5. permutation table
  6. + *
  7. multiplication table
  8. + *
  9. inverse table
  10. + *
  11. permutation table
  12. *
* - * @see Wiki. Verhoeff algorithm + * @see Wiki. + * Verhoeff algorithm */ public class Verhoeff { /** - * Table {@code d}. - * Based on multiplication in the dihedral group D5 and is simply the Cayley table of the group. - * Note that this group is not commutative, that is, for some values of {@code j} and {@code k}, + * Table {@code d}. Based on multiplication in the dihedral group D5 and is + * simply the Cayley table of the group. Note that this group is not + * commutative, that is, for some values of {@code j} and {@code k}, * {@code d(j,k) ≠ d(k, j)}. * - * @see Wiki. Dihedral group + * @see Wiki. + * Dihedral group */ private static final byte[][] MULTIPLICATION_TABLE = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, @@ -46,17 +48,16 @@ public class Verhoeff { }; /** - * The inverse table {@code inv}. - * Represents the multiplicative inverse of a digit, that is, the value that satisfies - * {@code d(j, inv(j)) = 0}. + * The inverse table {@code inv}. Represents the multiplicative inverse of a + * digit, that is, the value that satisfies {@code d(j, inv(j)) = 0}. */ private static final byte[] MULTIPLICATIVE_INVERSE = {0, 4, 3, 2, 1, 5, 6, 7, 8, 9}; /** - * The permutation table {@code p}. - * Applies a permutation to each digit based on its position in the number. - * This is actually a single permutation {@code (1 5 8 9 4 2 7 0)(3 6)} applied iteratively; - * i.e. {@code p(i+j,n) = p(i, p(j,n))}. + * The permutation table {@code p}. Applies a permutation to each digit + * based on its position in the number. This is actually a single + * permutation {@code (1 5 8 9 4 2 7 0)(3 6)} applied iteratively; i.e. + * {@code p(i+j,n) = p(i, p(j,n))}. */ private static final byte[][] PERMUTATION_TABLE = { {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, @@ -74,8 +75,9 @@ public class Verhoeff { * * @param digits input to check * @return true if check was successful, false otherwise - * @throws IllegalArgumentException if input parameter contains not only digits - * @throws NullPointerException if input is null + * @throws IllegalArgumentException if input parameter contains not only + * digits + * @throws NullPointerException if input is null */ public static boolean verhoeffCheck(String digits) { checkInput(digits); @@ -93,12 +95,14 @@ public static boolean verhoeffCheck(String digits) { } /** - * Calculate check digit for initial digits and add it tho the last position. + * Calculate check digit for initial digits and add it tho the last + * position. * * @param initialDigits initial value * @return digits with the checksum in the last position - * @throws IllegalArgumentException if input parameter contains not only digits - * @throws NullPointerException if input is null + * @throws IllegalArgumentException if input parameter contains not only + * digits + * @throws NullPointerException if input is null */ public static String addVerhoeffChecksum(String initialDigits) { checkInput(initialDigits); @@ -133,8 +137,8 @@ public static void main(String[] args) { private static void checkAndPrint(String input) { String validationResult = Verhoeff.verhoeffCheck(input) - ? "valid" - : "not valid"; + ? "valid" + : "not valid"; System.out.println("Input '" + input + "' is " + validationResult); } @@ -152,7 +156,7 @@ private static void checkInput(String input) { private static int[] toIntArray(String string) { return string.chars() - .map(i -> Character.digit(i, 10)) - .toArray(); + .map(i -> Character.digit(i, 10)) + .toArray(); } } diff --git a/src/main/java/com/thealgorithms/others/WorstFit.java b/src/main/java/com/thealgorithms/others/WorstFit.java new file mode 100644 index 000000000000..69aedc1e9fc4 --- /dev/null +++ b/src/main/java/com/thealgorithms/others/WorstFit.java @@ -0,0 +1,89 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; + +/** + * @author Dekas Dimitrios + */ +public class WorstFit { + + private static final int NO_ALLOCATION + = -255; // if a process has been allocated in position -255, + // it means that it has not been actually allocated. + + /** + * Method to find the index of the memory block that is going to fit the + * given process based on the worst fit algorithm. + * + * @param blocks: the array with the available memory blocks. + * @param process: the size of the process. + * @return the index of the block that fits, or -255 if no such block + * exists. + */ + private static int findWorstFit(int[] blockSizes, int processSize) { + int max = -1; + int index = -1; + for (int i = 0; + i < blockSizes.length; + i++) { // Find the index of the biggest memory block available. + if (blockSizes[i] > max) { + max = blockSizes[i]; + index = i; + } + } + // If the biggest memory block cannot fit the process, return -255 as the result + if (processSize > blockSizes[index]) { + return NO_ALLOCATION; + } + return index; + } + + /** + * Method to allocate memory to blocks according to the worst fit algorithm. + * It should return an ArrayList of Integers, where the index is the process + * ID (zero-indexed) and the value is the block number (also zero-indexed). + * + * @param sizeOfBlocks: an int array that contains the sizes of the memory + * blocks available. + * @param sizeOfProcesses: an int array that contains the sizes of the + * processes we need memory blocks for. + * @return the ArrayList filled with Integers repressenting the memory + * allocation that took place. + */ + static ArrayList worstFit(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the worst-fit algorithm + ArrayList memAlloc = new ArrayList<>(); + // Do this for every process + for (int processSize : sizeOfProcesses) { + int chosenBlockIdx + = findWorstFit( + sizeOfBlocks, processSize); // Find the index of the memory block going to be used + memAlloc.add(chosenBlockIdx); // Store the chosen block index in the memAlloc array list + if (chosenBlockIdx + != NO_ALLOCATION) { // Only if a block was chosen to store the process in it, + sizeOfBlocks[chosenBlockIdx] -= processSize; // resize the block based on the process size + } + } + return memAlloc; + } + + /** + * Method to print the memory allocated. + * + * @param memAllocation: an ArrayList of Integer representing the memory + * allocation done by the worstFit method. + */ + public static void printMemoryAllocation(ArrayList memAllocation) { + System.out.println("Process No.\tBlock No."); + System.out.println("===========\t========="); + for (int i = 0; i < memAllocation.size(); i++) { + System.out.print(" " + i + "\t\t"); + if (memAllocation.get(i) != NO_ALLOCATION) { + System.out.print(memAllocation.get(i)); + } else { + System.out.print("Not Allocated"); + } + System.out.println(); + } + } +} diff --git a/src/main/java/com/thealgorithms/searches/BinarySearch.java b/src/main/java/com/thealgorithms/searches/BinarySearch.java new file mode 100644 index 000000000000..22c124597f3d --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/BinarySearch.java @@ -0,0 +1,94 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * Binary search is one of the most popular algorithms The algorithm finds the + * position of a target value within a sorted array + * + *

+ * Worst-case performance O(log n) Best-case performance O(1) Average + * performance O(log n) Worst-case space complexity O(1) + * + * @author Varun Upadhyay (https://github.com/varunu28) + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SearchAlgorithm + * @see IterativeBinarySearch + */ +class BinarySearch implements SearchAlgorithm { + + /** + * @param array is an array where the element should be found + * @param key is an element which should be found + * @param is any comparable type + * @return index of the element + */ + @Override + public > int find(T[] array, T key) { + return search(array, key, 0, array.length); + } + + /** + * This method implements the Generic Binary Search + * + * @param array The array to make the binary search + * @param key The number you are looking for + * @param left The lower bound + * @param right The upper bound + * @return the location of the key + */ + private > int search(T array[], T key, int left, int right) { + if (right < left) { + return -1; // this means that the key not found + } + // find median + int median = (left + right) >>> 1; + int comp = key.compareTo(array[median]); + + if (comp == 0) { + return median; + } else if (comp < 0) { + return search(array, key, left, median - 1); + } else { + return search(array, key, median + 1, right); + } + } + + // Driver Program + public static void main(String[] args) { + // Just generate data + Random r = ThreadLocalRandom.current(); + + int size = 100; + int maxElement = 100000; + + Integer[] integers + = IntStream.generate(() -> r.nextInt(maxElement)) + .limit(size) + .sorted() + .boxed() + .toArray(Integer[]::new); + + // The element that should be found + int shouldBeFound = integers[r.nextInt(size - 1)]; + + BinarySearch search = new BinarySearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.println( + format( + "Should be found: %d. Found %d at index %d. An array length %d", + shouldBeFound, integers[atIndex], atIndex, size)); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.println( + format( + "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); + } +} diff --git a/Searches/BreadthFirstSearch.java b/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java similarity index 89% rename from Searches/BreadthFirstSearch.java rename to src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java index c0abf82ba4fa..93a41871d077 100644 --- a/Searches/BreadthFirstSearch.java +++ b/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java @@ -1,6 +1,6 @@ -package Searches; +package com.thealgorithms.searches; -import Searches.DepthFirstSearch.Node; +import com.thealgorithms.searches.DepthFirstSearch.Node; import java.util.ArrayList; import java.util.List; @@ -8,8 +8,8 @@ import java.util.Optional; /** - * @author: caos321 - * @date: 31 October 2021 (Sunday) + * @author: caos321 + * @date: 31 October 2021 (Sunday) */ public class BreadthFirstSearch { @@ -20,10 +20,10 @@ public static Optional search(final Node node, final String name) { List queue = new ArrayList<>(node.getSubNodes()); - while(!queue.isEmpty()) { + while (!queue.isEmpty()) { final Node current = queue.get(0); - if(current.getName().equals(name)) { + if (current.getName().equals(name)) { return Optional.of(current); } diff --git a/Searches/DepthFirstSearch.java b/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java similarity index 96% rename from Searches/DepthFirstSearch.java rename to src/main/java/com/thealgorithms/searches/DepthFirstSearch.java index bca2685cf625..f355ee30392c 100644 --- a/Searches/DepthFirstSearch.java +++ b/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java @@ -1,4 +1,4 @@ -package Searches; +package com.thealgorithms.searches; import java.util.ArrayList; import java.util.List; @@ -6,11 +6,13 @@ import java.util.Optional; /** - * @author: caos321 - * @date: 31 October 2021 (Sunday) + * @author: caos321 + * @date: 31 October 2021 (Sunday) */ public class DepthFirstSearch { + static class Node { + private final String name; private final List subNodes; diff --git a/Searches/ExponentalSearch.java b/src/main/java/com/thealgorithms/searches/ExponentalSearch.java similarity index 82% rename from Searches/ExponentalSearch.java rename to src/main/java/com/thealgorithms/searches/ExponentalSearch.java index 8095031f43fc..3592f50cbe28 100644 --- a/Searches/ExponentalSearch.java +++ b/src/main/java/com/thealgorithms/searches/ExponentalSearch.java @@ -1,23 +1,23 @@ -package Searches; +package com.thealgorithms.searches; import java.util.Arrays; import java.util.Random; import java.util.concurrent.ThreadLocalRandom; import java.util.stream.IntStream; -import DevUtils.Searches.SearchAlgorithm; +import com.thealgorithms.devutils.searches.SearchAlgorithm; import static java.lang.String.format; class ExponentialSearch implements SearchAlgorithm { - public static void main(String [] args) { + public static void main(String[] args) { Random r = ThreadLocalRandom.current(); int size = 100; int maxElement = 100000; - Integer[] integers = - IntStream.generate(() -> r.nextInt(maxElement)) + Integer[] integers + = IntStream.generate(() -> r.nextInt(maxElement)) .limit(size) .sorted() .boxed() @@ -43,14 +43,15 @@ public static void main(String [] args) { @Override public > int find(T[] array, T key) { - if (array[0] == key) + if (array[0] == key) { return 0; - if (array[array.length - 1] == key) + } + if (array[array.length - 1] == key) { return array.length; + } int range = 1; - while (range < array.length && array[range].compareTo(key) <= -1) { range = range * 2; } diff --git a/Searches/FibonacciSearch.java b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java similarity index 78% rename from Searches/FibonacciSearch.java rename to src/main/java/com/thealgorithms/searches/FibonacciSearch.java index 1cb0a54df98c..fdd45cb628a2 100644 --- a/Searches/FibonacciSearch.java +++ b/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -1,6 +1,6 @@ -package Searches; +package com.thealgorithms.searches; -import DevUtils.Searches.SearchAlgorithm; +import com.thealgorithms.devutils.searches.SearchAlgorithm; /* * Fibonacci Search is a popular algorithm which finds the position of a target value in @@ -9,14 +9,15 @@ * The time complexity for this search algorithm is O(log3(n)) * The space complexity for this search algorithm is O(1) * @author Kanakalatha Vemuru (https://github.com/KanakalathaVemuru) -*/ + */ public class FibonacciSearch implements SearchAlgorithm { - /** - * @param array is a sorted array where the element has to be searched - * @param key is an element whose position has to be found - * @param is any comparable type - * @return index of the element - */ + + /** + * @param array is a sorted array where the element has to be searched + * @param key is an element whose position has to be found + * @param is any comparable type + * @return index of the element + */ @Override public > int find(T[] array, T key) { int fibMinus1 = 1; @@ -40,15 +41,13 @@ public > int find(T[] array, T key) { fibMinus1 = fibMinus2; fibMinus2 = fibNumber - fibMinus1; offset = i; - } - else if (array[i].compareTo(key) > 0) { + } else if (array[i].compareTo(key) > 0) { fibNumber = fibMinus2; fibMinus1 = fibMinus1 - fibMinus2; fibMinus2 = fibNumber - fibMinus1; - } - else { + } else { return i; - } + } } if (fibMinus1 == 1 && array[offset + 1] == key) { @@ -68,7 +67,7 @@ public static void main(String[] args) { int atIndex = fsearch.find(integers, shouldBeFound); System.out.println( - "Should be found: " + shouldBeFound + ". Found "+ integers[atIndex] + " at index "+ atIndex +". An array length " + size); + "Should be found: " + shouldBeFound + ". Found " + integers[atIndex] + " at index " + atIndex + ". An array length " + size); } -} \ No newline at end of file +} diff --git a/Searches/HowManyTimesRotated.java b/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java similarity index 63% rename from Searches/HowManyTimesRotated.java rename to src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java index 2efe50174338..ccdb1439e4d4 100644 --- a/Searches/HowManyTimesRotated.java +++ b/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java @@ -1,4 +1,4 @@ -package Searches; +package com.thealgorithms.searches; import java.util.*; @@ -22,46 +22,39 @@ If we look at the rotated array, to identify the minimum element (say a[i]), we Some other test cases: 1. [1,2,3,4] Number of rotations: 0 or 4(Both valid) 2. [15,17,2,3,5] Number of rotations: 3 -*/ -class HowManyTimesRotated -{ - public static void main(String[] args) - { + */ +class HowManyTimesRotated { + + public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] a = new int[n]; - for(int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); + } - System.out.println("The array has been rotated "+rotated(a)+" times"); + System.out.println("The array has been rotated " + rotated(a) + " times"); sc.close(); } - public static int rotated(int[] a) - { + public static int rotated(int[] a) { int low = 0; - int high = a.length-1; - int mid=0; // low + (high-low)/2 = (low + high)/2 - - while(low<=high) - { - mid = low + (high-low)/2; - - if(a[mid]a[mid-1] && a[mid]a[mid-1] && a[mid]>a[mid+1]) - { - low = mid-1; + } else if (a[mid] > a[mid - 1] && a[mid] < a[mid + 1]) { + high = mid + 1; + } else if (a[mid] > a[mid - 1] && a[mid] > a[mid + 1]) { + low = mid - 1; } } - + return mid; } } diff --git a/src/main/java/com/thealgorithms/searches/InterpolationSearch.java b/src/main/java/com/thealgorithms/searches/InterpolationSearch.java new file mode 100644 index 000000000000..0ac16685d72b --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/InterpolationSearch.java @@ -0,0 +1,76 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Arrays; +import java.util.Random; +import java.util.stream.IntStream; + +/** + * Interpolation search algorithm implementation + * + *

+ * Worst-case performance O(n) Best-case performance O(1) Average performance + * O(log(log(n))) if the elements are uniformly distributed if not O(n) + * Worst-case space complexity O(1) + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +class InterpolationSearch { + + /** + * @param array is a sorted array + * @param key is a value what shoulb be found in the array + * @return an index if the array contains the key unless -1 + */ + public int find(int array[], int key) { + // Find indexes of two corners + int start = 0, end = (array.length - 1); + + // Since array is sorted, an element present + // in array must be in range defined by corner + while (start <= end && key >= array[start] && key <= array[end]) { + // Probing the position with keeping + // uniform distribution in mind. + int pos = start + (((end - start) / (array[end] - array[start])) * (key - array[start])); + + // Condition of target found + if (array[pos] == key) { + return pos; + } + + // If key is larger, key is in upper part + if (array[pos] < key) { + start = pos + 1; + } // If key is smaller, x is in lower part + else { + end = pos - 1; + } + } + return -1; + } + + // Driver method + public static void main(String[] args) { + Random r = new Random(); + int size = 100; + int maxElement = 100000; + int[] integers = IntStream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(); + + // the element that should be found + Integer shouldBeFound = integers[r.nextInt(size - 1)]; + + InterpolationSearch search = new InterpolationSearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.println( + String.format( + "Should be found: %d. Found %d at index %d. An array length %d", + shouldBeFound, integers[atIndex], atIndex, size)); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.println( + format( + "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); + } +} diff --git a/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java b/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java new file mode 100644 index 000000000000..ce375df24a94 --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java @@ -0,0 +1,82 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Stream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * Binary search is one of the most popular algorithms This class represents + * iterative version {@link BinarySearch} Iterative binary search is likely to + * have lower constant factors because it doesn't involve the overhead of + * manipulating the call stack. But in java the recursive version can be + * optimized by the compiler to this version. + * + *

+ * Worst-case performance O(log n) Best-case performance O(1) Average + * performance O(log n) Worst-case space complexity O(1) + * + * @author Gabriele La Greca : https://github.com/thegabriele97 + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SearchAlgorithm + * @see BinarySearch + */ +public final class IterativeBinarySearch implements SearchAlgorithm { + + /** + * This method implements an iterative version of binary search algorithm + * + * @param array a sorted array + * @param key the key to search in array + * @return the index of key in the array or -1 if not found + */ + @Override + public > int find(T[] array, T key) { + int l, r, k, cmp; + + l = 0; + r = array.length - 1; + + while (l <= r) { + k = (l + r) >>> 1; + cmp = key.compareTo(array[k]); + + if (cmp == 0) { + return k; + } else if (cmp < 0) { + r = --k; + } else { + l = ++k; + } + } + + return -1; + } + + // Only a main method for test purpose + public static void main(String[] args) { + Random r = new Random(); + int size = 100; + int maxElement = 100000; + Integer[] integers + = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new); + + // the element that should be found + Integer shouldBeFound = integers[r.nextInt(size - 1)]; + + IterativeBinarySearch search = new IterativeBinarySearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.println( + String.format( + "Should be found: %d. Found %d at index %d. An array length %d", + shouldBeFound, integers[atIndex], atIndex, size)); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.println( + format( + "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); + } +} diff --git a/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java b/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java new file mode 100644 index 000000000000..09139578e2bb --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java @@ -0,0 +1,81 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Stream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * A iterative version of a ternary search algorithm This is better way to + * implement the ternary search, because a recursive version adds some overhead + * to a stack. But in java the compile can transform the recursive version to + * iterative implicitly, so there are no much differences between these two + * algorithms + * + *

+ * Worst-case performance Θ(log3(N)) Best-case performance O(1) Average + * performance Θ(log3(N)) Worst-case space complexity O(1) + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SearchAlgorithm + * @see TernarySearch + * @since 2018-04-13 + */ +public class IterativeTernarySearch implements SearchAlgorithm { + + @Override + public > int find(T[] array, T key) { + int left = 0; + int right = array.length - 1; + + while (right > left) { + + int leftCmp = array[left].compareTo(key); + int rightCmp = array[right].compareTo(key); + if (leftCmp == 0) { + return left; + } + if (rightCmp == 0) { + return right; + } + + int leftThird = left + (right - left) / 3 + 1; + int rightThird = right - (right - left) / 3 - 1; + + if (array[leftThird].compareTo(key) <= 0) { + left = leftThird; + } else { + right = rightThird; + } + } + + return -1; + } + + public static void main(String[] args) { + // just generate data + Random r = new Random(); + int size = 100; + int maxElement = 100000; + Integer[] integers + = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new); + + // the element that should be found + Integer shouldBeFound = integers[r.nextInt(size - 1)]; + + IterativeTernarySearch search = new IterativeTernarySearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.println( + format( + "Should be found: %d. Found %d at index %d. An array length %d", + shouldBeFound, integers[atIndex], atIndex, size)); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.println( + format( + "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); + } +} diff --git a/src/main/java/com/thealgorithms/searches/JumpSearch.java b/src/main/java/com/thealgorithms/searches/JumpSearch.java new file mode 100644 index 000000000000..f499cf8079cc --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/JumpSearch.java @@ -0,0 +1,45 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +public class JumpSearch implements SearchAlgorithm { + + public static void main(String[] args) { + JumpSearch jumpSearch = new JumpSearch(); + Integer[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (int i = 0; i < array.length; i++) { + assert jumpSearch.find(array, i) == i; + } + assert jumpSearch.find(array, -1) == -1; + assert jumpSearch.find(array, 11) == -1; + } + + /** + * Jump Search algorithm implements + * + * @param array the array contains elements + * @param key to be searched + * @return index of {@code key} if found, otherwise -1 + */ + @Override + public > int find(T[] array, T key) { + int length = array.length; + /* length of array */ + int blockSize = (int) Math.sqrt(length); + /* block size to be jumped */ + + int limit = blockSize; + while (key.compareTo(array[limit]) > 0 && limit < array.length - 1) { + limit = Math.min(limit + blockSize, array.length - 1); + } + + for (int i = limit - blockSize; i <= limit; i++) { + if (array[i] == key) { + /* execute linear search */ + return i; + } + } + return -1; + /* not found */ + } +} diff --git a/src/main/java/com/thealgorithms/searches/LinearSearch.java b/src/main/java/com/thealgorithms/searches/LinearSearch.java new file mode 100644 index 000000000000..330b68fdac34 --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/LinearSearch.java @@ -0,0 +1,59 @@ +package com.thealgorithms.searches; + +import java.util.Random; +import java.util.stream.Stream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * Linear search is the easiest search algorithm It works with sorted and + * unsorted arrays (an binary search works only with sorted array) This + * algorithm just compares all elements of an array to find a value + * + *

+ * Worst-case performance O(n) Best-case performance O(1) Average performance + * O(n) Worst-case space complexity + * + * @author Varun Upadhyay (https://github.com/varunu28) + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see BinarySearch + * @see SearchAlgorithm + */ +public class LinearSearch implements SearchAlgorithm { + + /** + * Generic Linear search method + * + * @param array List to be searched + * @param value Key being searched for + * @return Location of the key + */ + @Override + public > int find(T[] array, T value) { + for (int i = 0; i < array.length; i++) { + if (array[i].compareTo(value) == 0) { + return i; + } + } + return -1; + } + + public static void main(String[] args) { + // just generate data + Random r = new Random(); + int size = 200; + int maxElement = 100; + Integer[] integers + = Stream.generate(() -> r.nextInt(maxElement)).limit(size).toArray(Integer[]::new); + + // the element that should be found + Integer shouldBeFound = integers[r.nextInt(size - 1)]; + + LinearSearch search = new LinearSearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.println( + String.format( + "Should be found: %d. Found %d at index %d. An array length %d", + shouldBeFound, integers[atIndex], atIndex, size)); + } +} diff --git a/src/main/java/com/thealgorithms/searches/LowerBound.java b/src/main/java/com/thealgorithms/searches/LowerBound.java new file mode 100644 index 000000000000..1fc9b24b0777 --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/LowerBound.java @@ -0,0 +1,101 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * The LowerBound method is used to return an index pointing to the first + * element in the range [first, last) which has a value not less than val, i.e. + * the index of the next smallest number just greater than or equal to that + * number. If there are multiple values that are equal to val it returns the + * index of the first such value. + * + *

+ * This is an extension of BinarySearch. + * + *

+ * Worst-case performance O(log n) Best-case performance O(1) Average + * performance O(log n) Worst-case space complexity O(1) + * + * @author Pratik Padalia (https://github.com/15pratik) + * @see SearchAlgorithm + * @see BinarySearch + */ +class LowerBound implements SearchAlgorithm { + + // Driver Program + public static void main(String[] args) { + // Just generate data + Random r = ThreadLocalRandom.current(); + + int size = 100; + int maxElement = 100000; + + Integer[] integers + = IntStream.generate(() -> r.nextInt(maxElement)) + .limit(size) + .sorted() + .boxed() + .toArray(Integer[]::new); + + // The element for which the lower bound is to be found + int val = integers[r.nextInt(size - 1)] + 1; + + LowerBound search = new LowerBound(); + int atIndex = search.find(integers, val); + + System.out.println( + format( + "Val: %d. Lower Bound Found %d at index %d. An array length %d", + val, integers[atIndex], atIndex, size)); + + boolean toCheck = integers[atIndex] >= val || integers[size - 1] < val; + System.out.println( + format( + "Lower Bound found at an index: %d. Is greater or max element: %b", atIndex, toCheck)); + } + + /** + * @param array is an array where the LowerBound value is to be found + * @param key is an element for which the LowerBound is to be found + * @param is any comparable type + * @return index of the LowerBound element + */ + @Override + public > int find(T[] array, T key) { + return search(array, key, 0, array.length - 1); + } + + /** + * This method implements the Generic Binary Search + * + * @param array The array to make the binary search + * @param key The number you are looking for + * @param left The lower bound + * @param right The upper bound + * @return the location of the key + */ + private > int search(T[] array, T key, int left, int right) { + if (right <= left) { + return left; + } + + // find median + int median = (left + right) >>> 1; + int comp = key.compareTo(array[median]); + + if (comp == 0) { + return median; + } else if (comp < 0) { + // median position can be a possible solution + return search(array, key, left, median); + } else { + // key we are looking is greater, so we must look on the right of median position + return search(array, key, median + 1, right); + } + } +} diff --git a/Searches/MonteCarloTreeSearch.java b/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java similarity index 88% rename from Searches/MonteCarloTreeSearch.java rename to src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java index f6909b63a5e7..d6f6c756bc8b 100644 --- a/Searches/MonteCarloTreeSearch.java +++ b/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java @@ -1,4 +1,4 @@ -package Searches; +package com.thealgorithms.searches; import java.util.Collections; import java.util.ArrayList; @@ -6,22 +6,25 @@ import java.util.Random; /** - * Monte Carlo Tree Search (MCTS) is a heuristic search algorithm - * used in decition taking problems especially games. - * + * Monte Carlo Tree Search (MCTS) is a heuristic search algorithm used in + * decition taking problems especially games. + * * See more: https://en.wikipedia.org/wiki/Monte_Carlo_tree_search, * https://www.baeldung.com/java-monte-carlo-tree-search */ public class MonteCarloTreeSearch { + public class Node { + Node parent; - ArrayList childNodes; + ArrayList childNodes; boolean isPlayersTurn; // True if it is the player's turn. boolean playerWon; // True if the player won; false if the opponent won. int score; int visitCount; - public Node() {} + public Node() { + } public Node(Node parent, boolean isPlayersTurn) { this.parent = parent; @@ -43,9 +46,9 @@ public static void main(String[] args) { } /** - * Explores a game tree using Monte Carlo Tree Search (MCTS) - * and returns the most promising node. - * + * Explores a game tree using Monte Carlo Tree Search (MCTS) and returns the + * most promising node. + * * @param rootNode Root node of the game tree. * @return The most promising child of the root node. */ @@ -88,9 +91,9 @@ public void addChildNodes(Node node, int childCount) { /** * Uses UCT to find a promising child node to be explored. - * + * * UCT: Upper Confidence bounds applied to Trees. - * + * * @param rootNode Root node of the tree. * @return The most promising node according to UCT. */ @@ -116,7 +119,7 @@ public Node getPromisingNode(Node rootNode) { } uctTemp = ((double) childNode.score / childNode.visitCount) - + 1.41 * Math.sqrt(Math.log(promisingNode.visitCount) / (double) childNode.visitCount); + + 1.41 * Math.sqrt(Math.log(promisingNode.visitCount) / (double) childNode.visitCount); if (uctTemp > uctIndex) { uctIndex = uctTemp; @@ -131,9 +134,9 @@ public Node getPromisingNode(Node rootNode) { } /** - * Simulates a random play from a nodes current state - * and back propagates the result. - * + * Simulates a random play from a nodes current state and back propagates + * the result. + * * @param promisingNode Node that will be simulated. */ public void simulateRandomPlay(Node promisingNode) { @@ -155,8 +158,8 @@ public void simulateRandomPlay(Node promisingNode) { tempNode.visitCount++; // Add wining scores to bouth player and opponent depending on the turn. - if ((tempNode.isPlayersTurn && isPlayerWinner) || - (!tempNode.isPlayersTurn && !isPlayerWinner)) { + if ((tempNode.isPlayersTurn && isPlayerWinner) + || (!tempNode.isPlayersTurn && !isPlayerWinner)) { tempNode.score += WIN_SCORE; } @@ -170,10 +173,10 @@ public Node getWinnerNode(Node rootNode) { public void printScores(Node rootNode) { System.out.println("N.\tScore\t\tVisits"); - + for (int i = 0; i < rootNode.childNodes.size(); i++) { System.out.println(String.format("%02d\t%d\t\t%d", i + 1, - rootNode.childNodes.get(i).score, rootNode.childNodes.get(i).visitCount)); + rootNode.childNodes.get(i).score, rootNode.childNodes.get(i).visitCount)); } } } diff --git a/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java b/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java new file mode 100644 index 000000000000..8ce01575b67d --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java @@ -0,0 +1,29 @@ +package com.thealgorithms.searches; + +class PerfectBinarySearch { + + static int binarySearch(int[] arr, int target) { + int low = 0; + int high = arr.length - 1; + + while (low <= high) { + int mid = (low + high) / 2; + + if (arr[mid] == target) { + return mid; + } else if (arr[mid] > target) { + high = mid - 1; + } else { + low = mid + 1; + } + } + return -1; + } + + public static void main(String[] args) { + PerfectBinarySearch BinarySearch = new PerfectBinarySearch(); + int[] array = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + assert BinarySearch.binarySearch(array, -1) == -1; + assert BinarySearch.binarySearch(array, 11) == -1; + } +} diff --git a/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java b/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java new file mode 100644 index 000000000000..719a60d31f8a --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java @@ -0,0 +1,72 @@ +package com.thealgorithms.searches; + +import java.util.Scanner; + +/** + * Program to perform Saddleback Search Given a sorted 2D array(elements are + * sorted across every row and column, assuming ascending order) of size n*m we + * can search a given element in O(n+m) + * + *

+ * we start from bottom left corner if the current element is greater than the + * given element then we move up else we move right Sample Input: 5 5 + * ->Dimensions -10 -5 -3 4 9 -6 -2 0 5 10 -4 -1 1 6 12 2 3 7 8 13 100 120 130 + * 140 150 140 ->element to be searched output: 4 3 // first value is row, + * second one is column + * + * @author Nishita Aggarwal + */ +public class SaddlebackSearch { + + /** + * This method performs Saddleback Search + * + * @param arr The **Sorted** array in which we will search the element. + * @param row the current row. + * @param col the current column. + * @param key the element that we want to search for. + * @return The index(row and column) of the element if found. Else returns + * -1 -1. + */ + private static int[] find(int arr[][], int row, int col, int key) { + + // array to store the answer row and column + int ans[] = {-1, -1}; + if (row < 0 || col >= arr[row].length) { + return ans; + } + if (arr[row][col] == key) { + ans[0] = row; + ans[1] = col; + return ans; + } // if the current element is greater than the given element then we move up + else if (arr[row][col] > key) { + return find(arr, row - 1, col, key); + } + // else we move right + return find(arr, row, col + 1, key); + } + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + Scanner sc = new Scanner(System.in); + int arr[][]; + int i, j, rows = sc.nextInt(), col = sc.nextInt(); + arr = new int[rows][col]; + for (i = 0; i < rows; i++) { + for (j = 0; j < col; j++) { + arr[i][j] = sc.nextInt(); + } + } + int ele = sc.nextInt(); + // we start from bottom left corner + int ans[] = find(arr, rows - 1, 0, ele); + System.out.println(ans[0] + " " + ans[1]); + sc.close(); + } +} diff --git a/Searches/SquareRootBinarySearch.java b/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java similarity index 70% rename from Searches/SquareRootBinarySearch.java rename to src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java index 1790f8abc710..399499f57ed9 100644 --- a/Searches/SquareRootBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java @@ -1,15 +1,16 @@ -package Searches; +package com.thealgorithms.searches; import java.util.Scanner; /** - * Given an integer x, find the square root of x. If x is not a perfect square, then return floor(√x). + * Given an integer x, find the square root of x. If x is not a perfect square, + * then return floor(√x). *

- * For example, - * if x = 5, The answer should be 2 which is the floor value of √5. + * For example, if x = 5, The answer should be 2 which is the floor value of √5. *

- * The approach that will be used for solving the above problem is not going to be a straight forward Math.sqrt(). - * Instead we will be using Binary Search to find the square root of a number in the most optimised way. + * The approach that will be used for solving the above problem is not going to + * be a straight forward Math.sqrt(). Instead we will be using Binary Search to + * find the square root of a number in the most optimised way. * * @author sahil */ @@ -29,9 +30,9 @@ public static void main(String args[]) { } /** - * This function calculates the floor of square root of a number. - * We use Binary Search algorithm to calculate the square root - * in a more optimised way. + * This function calculates the floor of square root of a number. We use + * Binary Search algorithm to calculate the square root in a more optimised + * way. * * @param num Number * @return answer @@ -45,9 +46,9 @@ private static long squareRoot(long num) { long ans = 0; while (l <= r) { long mid = l + (r - l) / 2; - if (mid == num / mid) + if (mid == num / mid) { return mid; - else if (mid < num / mid) { + } else if (mid < num / mid) { ans = mid; l = mid + 1; } else { diff --git a/src/main/java/com/thealgorithms/searches/TernarySearch.java b/src/main/java/com/thealgorithms/searches/TernarySearch.java new file mode 100644 index 000000000000..47bb690b191a --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/TernarySearch.java @@ -0,0 +1,90 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Stream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * A ternary search algorithm is a technique in computer science for finding the + * minimum or maximum of a unimodal function The algorithm determines either + * that the minimum or maximum cannot be in the first third of the domain or + * that it cannot be in the last third of the domain, then repeats on the + * remaining third. + * + *

+ * Worst-case performance Θ(log3(N)) Best-case performance O(1) Average + * performance Θ(log3(N)) Worst-case space complexity O(1) + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SearchAlgorithm + * @see IterativeBinarySearch + */ +public class TernarySearch implements SearchAlgorithm { + + /** + * @param arr The **Sorted** array in which we will search the element. + * @param value The value that we want to search for. + * @return The index of the element if found. Else returns -1. + */ + @Override + public > int find(T[] arr, T value) { + return ternarySearch(arr, value, 0, arr.length - 1); + } + + /** + * @param arr The **Sorted** array in which we will search the element. + * @param key The value that we want to search for. + * @param start The starting index from which we will start Searching. + * @param end The ending index till which we will Search. + * @return Returns the index of the Element if found. Else returns -1. + */ + private > int ternarySearch(T[] arr, T key, int start, int end) { + if (start > end) { + return -1; + } + /* First boundary: add 1/3 of length to start */ + int mid1 = start + (end - start) / 3; + /* Second boundary: add 2/3 of length to start */ + int mid2 = start + 2 * (end - start) / 3; + + if (key.compareTo(arr[mid1]) == 0) { + return mid1; + } else if (key.compareTo(arr[mid2]) == 0) { + return mid2; + } /* Search the first (1/3) rd part of the array.*/ else if (key.compareTo(arr[mid1]) < 0) { + return ternarySearch(arr, key, start, --mid1); + } /* Search 3rd (1/3)rd part of the array */ else if (key.compareTo(arr[mid2]) > 0) { + return ternarySearch(arr, key, ++mid2, end); + } /* Search middle (1/3)rd part of the array */ else { + return ternarySearch(arr, key, mid1, mid2); + } + } + + public static void main(String[] args) { + // just generate data + Random r = new Random(); + int size = 100; + int maxElement = 100000; + Integer[] integers + = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new); + + // the element that should be found + Integer shouldBeFound = integers[r.nextInt(size - 1)]; + + TernarySearch search = new TernarySearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.println( + format( + "Should be found: %d. Found %d at index %d. An array length %d", + shouldBeFound, integers[atIndex], atIndex, size)); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.println( + format( + "Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex)); + } +} diff --git a/Searches/UnionFind.java b/src/main/java/com/thealgorithms/searches/UnionFind.java similarity index 84% rename from Searches/UnionFind.java rename to src/main/java/com/thealgorithms/searches/UnionFind.java index 0aba6f876a23..d32e4fd3ec1f 100644 --- a/Searches/UnionFind.java +++ b/src/main/java/com/thealgorithms/searches/UnionFind.java @@ -1,24 +1,27 @@ -package Searches; +package com.thealgorithms.searches; import java.util.*; public class UnionFind { + private int[] p; private int[] r; public UnionFind(int n) { p = new int[n]; r = new int[n]; - + for (int i = 0; i < n; i++) { p[i] = i; } } - + public int find(int i) { int parent = p[i]; - - if (i == parent) return i; + + if (i == parent) { + return i; + } return p[i] = find(parent); } @@ -26,9 +29,11 @@ public int find(int i) { public void union(int x, int y) { int r0 = find(x); int r1 = find(y); - - if (r1 == r0) return; - + + if (r1 == r0) { + return; + } + if (r[r0] > r[r1]) { p[r1] = r0; } else if (r[r1] > r[r0]) { @@ -41,8 +46,8 @@ public void union(int x, int y) { public int count() { List parents = new ArrayList(); - for(int i = 0; i < p.length; i++) { - if(!parents.contains(find(i))) { + for (int i = 0; i < p.length; i++) { + if (!parents.contains(find(i))) { parents.add(find(i)); } } @@ -52,18 +57,18 @@ public int count() { public String toString() { return "p " + Arrays.toString(p) + " r " + Arrays.toString(r) + "\n"; } - + // Tests public static void main(String[] args) { UnionFind uf = new UnionFind(5); System.out.println("init /w 5 (should print 'p [0, 1, 2, 3, 4] r [0, 0, 0, 0, 0]'):"); System.out.println(uf); - - uf.union(1,2); + + uf.union(1, 2); System.out.println("union 1 2 (should print 'p [0, 1, 1, 3, 4] r [0, 1, 0, 0, 0]'):"); System.out.println(uf); - uf.union(3,4); + uf.union(3, 4); System.out.println("union 3 4 (should print 'p [0, 1, 1, 3, 3] r [0, 1, 0, 1, 0]'):"); System.out.println(uf); diff --git a/src/main/java/com/thealgorithms/searches/UpperBound.java b/src/main/java/com/thealgorithms/searches/UpperBound.java new file mode 100644 index 000000000000..cae38363eb0d --- /dev/null +++ b/src/main/java/com/thealgorithms/searches/UpperBound.java @@ -0,0 +1,99 @@ +package com.thealgorithms.searches; + +import static java.lang.String.format; + +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/** + * The UpperBound method is used to return an index pointing to the first + * element in the range [first, last) which has a value greater than val, or the + * last index if no such element exists i.e. the index of the next smallest + * number just greater than that number. If there are multiple values that are + * equal to val it returns the index of the first such value. + * + *

+ * This is an extension of BinarySearch. + * + *

+ * Worst-case performance O(log n) Best-case performance O(1) Average + * performance O(log n) Worst-case space complexity O(1) + * + * @author Pratik Padalia (https://github.com/15pratik) + * @see SearchAlgorithm + * @see BinarySearch + */ +class UpperBound implements SearchAlgorithm { + + // Driver Program + public static void main(String[] args) { + // Just generate data + Random r = ThreadLocalRandom.current(); + + int size = 100; + int maxElement = 100000; + + Integer[] integers + = IntStream.generate(() -> r.nextInt(maxElement)) + .limit(size) + .sorted() + .boxed() + .toArray(Integer[]::new); + + // The element for which the upper bound is to be found + int val = integers[r.nextInt(size - 1)] + 1; + + UpperBound search = new UpperBound(); + int atIndex = search.find(integers, val); + + System.out.println( + format( + "Val: %d. Upper Bound Found %d at index %d. An array length %d", + val, integers[atIndex], atIndex, size)); + + boolean toCheck = integers[atIndex] > val || integers[size - 1] < val; + System.out.println( + format( + "Upper Bound found at an index: %d. Is greater or max element: %b", atIndex, toCheck)); + } + + /** + * @param array is an array where the UpperBound value is to be found + * @param key is an element for which the UpperBound is to be found + * @param is any comparable type + * @return index of the UpperBound element + */ + @Override + public > int find(T[] array, T key) { + return search(array, key, 0, array.length - 1); + } + + /** + * This method implements the Generic Binary Search + * + * @param array The array to make the binary search + * @param key The number you are looking for + * @param left The lower bound + * @param right The upper bound + * @return the location of the key + */ + private > int search(T[] array, T key, int left, int right) { + if (right <= left) { + return left; + } + + // find median + int median = (left + right) >>> 1; + int comp = key.compareTo(array[median]); + + if (comp < 0) { + // key is smaller, median position can be a possible solution + return search(array, key, left, median); + } else { + // key we are looking is greater, so we must look on the right of median position + return search(array, key, median + 1, right); + } + } +} diff --git a/src/main/java/com/thealgorithms/sorts/BitonicSort.java b/src/main/java/com/thealgorithms/sorts/BitonicSort.java new file mode 100644 index 000000000000..4f780ebdfe04 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/BitonicSort.java @@ -0,0 +1,79 @@ +package com.thealgorithms.sorts; + +/* Java program for Bitonic Sort. Note that this program +works only when size of input is a power of 2. */ +public class BitonicSort { + + /* The parameter dir indicates the sorting direction, + ASCENDING or DESCENDING; if (a[i] > a[j]) agrees + with the direction, then a[i] and a[j] are + interchanged. */ + void compAndSwap(int a[], int i, int j, int dir) { + if ((a[i] > a[j] && dir == 1) || (a[i] < a[j] && dir == 0)) { + // Swapping elements + int temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } + } + + /* It recursively sorts a bitonic sequence in ascending + order, if dir = 1, and in descending order otherwise + (means dir=0). The sequence to be sorted starts at + index position low, the parameter cnt is the number + of elements to be sorted.*/ + void bitonicMerge(int a[], int low, int cnt, int dir) { + if (cnt > 1) { + int k = cnt / 2; + for (int i = low; i < low + k; i++) { + compAndSwap(a, i, i + k, dir); + } + bitonicMerge(a, low, k, dir); + bitonicMerge(a, low + k, k, dir); + } + } + + /* This funcion first produces a bitonic sequence by + recursively sorting its two halves in opposite sorting + orders, and then calls bitonicMerge to make them in + the same order */ + void bitonicSort(int a[], int low, int cnt, int dir) { + if (cnt > 1) { + int k = cnt / 2; + + // sort in ascending order since dir here is 1 + bitonicSort(a, low, k, 1); + + // sort in descending order since dir here is 0 + bitonicSort(a, low + k, k, 0); + + // Will merge whole sequence in ascending order + // since dir=1. + bitonicMerge(a, low, cnt, dir); + } + } + + /*Caller of bitonicSort for sorting the entire array + of length N in ASCENDING order */ + void sort(int a[], int N, int up) { + bitonicSort(a, 0, N, up); + } + + /* A utility function to print array of size n */ + static void printArray(int arr[]) { + int n = arr.length; + for (int i = 0; i < n; ++i) { + System.out.print(arr[i] + " "); + } + System.out.println(); + } + + public static void main(String args[]) { + int a[] = {3, 7, 4, 8, 6, 2, 1, 5}; + int up = 1; + BitonicSort ob = new BitonicSort(); + ob.sort(a, a.length, up); + System.out.println("\nSorted array"); + printArray(a); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/BogoSort.java b/src/main/java/com/thealgorithms/sorts/BogoSort.java new file mode 100644 index 000000000000..75f1e84367c3 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/BogoSort.java @@ -0,0 +1,54 @@ +package com.thealgorithms.sorts; + +import java.util.Random; + +/** + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SortAlgorithm + */ +public class BogoSort implements SortAlgorithm { + + private static final Random random = new Random(); + + private static > boolean isSorted(T[] array) { + for (int i = 0; i < array.length - 1; i++) { + if (SortUtils.less(array[i + 1], array[i])) { + return false; + } + } + return true; + } + + // Randomly shuffles the array + private static void nextPermutation(T[] array) { + int length = array.length; + + for (int i = 0; i < array.length; i++) { + int randomIndex = i + random.nextInt(length - i); + SortUtils.swap(array, randomIndex, i); + } + } + + public > T[] sort(T[] array) { + while (!isSorted(array)) { + nextPermutation(array); + } + return array; + } + + // Driver Program + public static void main(String[] args) { + // Integer Input + Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + + BogoSort bogoSort = new BogoSort(); + + // print a sorted array + SortUtils.print(bogoSort.sort(integers)); + + // String Input + String[] strings = {"c", "a", "e", "b", "d"}; + + SortUtils.print(bogoSort.sort(strings)); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/BubbleSort.java b/src/main/java/com/thealgorithms/sorts/BubbleSort.java new file mode 100644 index 000000000000..3e5aae21d6b0 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/BubbleSort.java @@ -0,0 +1,59 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SortAlgorithm + */ +class BubbleSort implements SortAlgorithm { + + /** + * Implements generic bubble sort algorithm. + * + * @param array the array to be sorted. + * @param the type of elements in the array. + * @return the sorted array. + */ + @Override + public > T[] sort(T[] array) { + for (int i = 1, size = array.length; i < size; ++i) { + boolean swapped = false; + for (int j = 0; j < size - i; ++j) { + if (greater(array[j], array[j + 1])) { + swap(array, j, j + 1); + swapped = true; + } + } + if (!swapped) { + break; + } + } + return array; + } + + /** + * Driver Code + */ + public static void main(String[] args) { + + Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + BubbleSort bubbleSort = new BubbleSort(); + bubbleSort.sort(integers); + + for (int i = 0; i < integers.length - 1; ++i) { + assert integers[i] <= integers[i + 1]; + } + print(integers); + /* output: [1, 4, 6, 9, 12, 23, 54, 78, 231] */ + + String[] strings = {"c", "a", "e", "b", "d"}; + bubbleSort.sort(strings); + for (int i = 0; i < strings.length - 1; i++) { + assert strings[i].compareTo(strings[i + 1]) <= 0; + } + print(bubbleSort.sort(strings)); + /* output: [a, b, c, d, e] */ + } +} diff --git a/src/main/java/com/thealgorithms/sorts/BubbleSortRecursion.java b/src/main/java/com/thealgorithms/sorts/BubbleSortRecursion.java new file mode 100644 index 000000000000..10197969e853 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/BubbleSortRecursion.java @@ -0,0 +1,57 @@ +package com.thealgorithms.sorts; + +import java.util.Random; + +/** + * BubbleSort algorithm implements using recursion + */ +public class BubbleSortRecursion implements SortAlgorithm { + + public static void main(String[] args) { + Integer[] array = new Integer[10]; + + Random random = new Random(); + /* generate 10 random numbers from -50 to 49 */ + for (int i = 0; i < array.length; ++i) { + array[i] = random.nextInt(100) - 50; + } + + BubbleSortRecursion bubbleSortRecursion = new BubbleSortRecursion(); + bubbleSortRecursion.sort(array); + + /* check array is sorted or not */ + for (int i = 0; i < array.length - 1; ++i) { + assert (array[i].compareTo(array[i + 1]) <= 0); + } + } + + /** + * @param unsorted - an array should be sorted + * @return sorted array + */ + @Override + public > T[] sort(T[] unsorted) { + bubbleSort(unsorted, unsorted.length); + return unsorted; + } + + /** + * BubbleSort algorithm implements using recursion + * + * @param unsorted array contains elements + * @param len length of given array + */ + private static > void bubbleSort(T[] unsorted, int len) { + boolean swapped = false; + /* flag to check if array is sorted or not */ + for (int i = 0; i < len - 1; ++i) { + if (SortUtils.greater(unsorted[i], unsorted[i + 1])) { + SortUtils.swap(unsorted, i, i + 1); + swapped = true; + } + } + if (swapped) { + bubbleSort(unsorted, len - 1); + } + } +} diff --git a/src/main/java/com/thealgorithms/sorts/BucketSort.java b/src/main/java/com/thealgorithms/sorts/BucketSort.java new file mode 100644 index 000000000000..e4239b5f2be8 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/BucketSort.java @@ -0,0 +1,115 @@ +package com.thealgorithms.sorts; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Random; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Bucket_sort + */ +public class BucketSort { + + public static void main(String[] args) { + int[] arr = new int[10]; + + /* generate 10 random numbers from -50 to 49 */ + Random random = new Random(); + for (int i = 0; i < arr.length; ++i) { + arr[i] = random.nextInt(100) - 50; + } + + bucketSort(arr); + + /* check array is sorted or not */ + for (int i = 0, limit = arr.length - 1; i < limit; ++i) { + assert arr[i] <= arr[i + 1]; + } + } + + /** + * BucketSort algorithms implements + * + * @param arr the array contains elements + */ + private static void bucketSort(int[] arr) { + /* get max value of arr */ + int max = max(arr); + + /* get min value of arr */ + int min = min(arr); + + /* number of buckets */ + int numberOfBuckets = max - min + 1; + + List> buckets = new ArrayList<>(numberOfBuckets); + + /* init buckets */ + for (int i = 0; i < numberOfBuckets; ++i) { + buckets.add(new ArrayList<>()); + } + + /* store elements to buckets */ + for (int value : arr) { + int hash = hash(value, min, numberOfBuckets); + buckets.get(hash).add(value); + } + + /* sort individual bucket */ + for (List bucket : buckets) { + Collections.sort(bucket); + } + + /* concatenate buckets to origin array */ + int index = 0; + for (List bucket : buckets) { + for (int value : bucket) { + arr[index++] = value; + } + } + } + + /** + * Get index of bucket which of our elements gets placed into it. + * + * @param elem the element of array to be sorted + * @param min min value of array + * @param numberOfBucket the number of bucket + * @return index of bucket + */ + private static int hash(int elem, int min, int numberOfBucket) { + return (elem - min) / numberOfBucket; + } + + /** + * Calculate max value of array + * + * @param arr the array contains elements + * @return max value of given array + */ + public static int max(int[] arr) { + int max = arr[0]; + for (int value : arr) { + if (value > max) { + max = value; + } + } + return max; + } + + /** + * Calculate min value of array + * + * @param arr the array contains elements + * @return min value of given array + */ + public static int min(int[] arr) { + int min = arr[0]; + for (int value : arr) { + if (value < min) { + min = value; + } + } + return min; + } +} diff --git a/Sorts/CircleSort.java b/src/main/java/com/thealgorithms/sorts/CircleSort.java similarity index 85% rename from Sorts/CircleSort.java rename to src/main/java/com/thealgorithms/sorts/CircleSort.java index 6df72db05e7a..7dcd63f46cb1 100644 --- a/Sorts/CircleSort.java +++ b/src/main/java/com/thealgorithms/sorts/CircleSort.java @@ -1,33 +1,34 @@ -package Sorts; +package com.thealgorithms.sorts; -import static Sorts.SortUtils.*; +import static com.thealgorithms.sorts.SortUtils.*; public class CircleSort implements SortAlgorithm { + /* This method implements the circle sort * @param array The array to be sorted - */ + */ @Override public > T[] sort(T[] array) { int n = array.length; - while(doSort(array, 0, n - 1)); + while (doSort(array, 0, n - 1)); return array; } - + /* This method implements the cyclic sort recursive version * @param array The array to be sorted * @param the left boundary of the part currently being sorted * @param the right boundary of the part currently being sorted - */ + */ private > Boolean doSort(T[] array, int left, int right) { Boolean swapped = false; - + if (left == right) { return false; } - + int low = left; int high = right; - + while (low < high) { if (array[low].compareTo(array[high]) > 0) { swap(array, low, high); @@ -36,19 +37,19 @@ private > Boolean doSort(T[] array, int left, int right) low++; high--; } - + if (low == high && array[low].compareTo(array[high + 1]) > 0) { swap(array, low, high + 1); swapped = true; } - - int mid = left + (right - left)/2; + + int mid = left + (right - left) / 2; Boolean leftHalf = doSort(array, left, mid); Boolean rightHalf = doSort(array, mid + 1, right); - + return swapped || leftHalf || rightHalf; } - + /* Driver code*/ public static void main(String[] args) { CircleSort CSort = new CircleSort(); @@ -56,13 +57,13 @@ public static void main(String[] args) { Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; CSort.sort(arr); for (int i = 0; i < arr.length - 1; ++i) { - assert arr[i] <= arr[i + 1]; + assert arr[i] <= arr[i + 1]; } String[] stringArray = {"c", "a", "e", "b", "d"}; CSort.sort(stringArray); for (int i = 0; i < stringArray.length - 1; ++i) { - assert arr[i].compareTo(arr[i + 1]) <= 0; + assert arr[i].compareTo(arr[i + 1]) <= 0; } } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java b/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java new file mode 100644 index 000000000000..6bf98dbc8bc3 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java @@ -0,0 +1,57 @@ +package com.thealgorithms.sorts; + +/** + * @author Mateus Bizzo (https://github.com/MattBizzo) + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +class CocktailShakerSort implements SortAlgorithm { + + /** + * This method implements the Generic Cocktail Shaker Sort + * + * @param array The array to be sorted Sorts the array in increasing order + */ + @Override + public > T[] sort(T[] array) { + + int length = array.length; + int left = 0; + int right = length - 1; + int swappedLeft, swappedRight; + while (left < right) { + // front + swappedRight = 0; + for (int i = left; i < right; i++) { + if (SortUtils.less(array[i + 1], array[i])) { + SortUtils.swap(array, i, i + 1); + swappedRight = i; + } + } + // back + right = swappedRight; + swappedLeft = length - 1; + for (int j = right; j > left; j--) { + if (SortUtils.less(array[j], array[j - 1])) { + SortUtils.swap(array, j - 1, j); + swappedLeft = j; + } + } + left = swappedLeft; + } + return array; + } + + // Driver Program + public static void main(String[] args) { + // Integer Input + Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + CocktailShakerSort shakerSort = new CocktailShakerSort(); + + // Output => 1 4 6 9 12 23 54 78 231 + SortUtils.print(shakerSort.sort(integers)); + + // String Input + String[] strings = {"c", "a", "e", "b", "d"}; + SortUtils.print(shakerSort.sort(strings)); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/CombSort.java b/src/main/java/com/thealgorithms/sorts/CombSort.java new file mode 100644 index 000000000000..9bd3fb181c33 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/CombSort.java @@ -0,0 +1,73 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +/** + * Comb Sort algorithm implementation + * + *

+ * Best-case performance O(n * log(n)) Worst-case performance O(n ^ 2) + * Worst-case space complexity O(1) + * + *

+ * Comb sort improves on bubble sort. + * + * @author Sandeep Roy (https://github.com/sandeeproy99) + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see BubbleSort + * @see SortAlgorithm + */ +class CombSort implements SortAlgorithm { + + // To find gap between elements + private int nextGap(int gap) { + // Shrink gap by Shrink factor + gap = (gap * 10) / 13; + return (gap < 1) ? 1 : gap; + } + + /** + * Function to sort arr[] using Comb + * + * @param arr - an array should be sorted + * @return sorted array + */ + @Override + public > T[] sort(T[] arr) { + int size = arr.length; + + // initialize gap + int gap = size; + + // Initialize swapped as true to make sure that loop runs + boolean swapped = true; + + // Keep running while gap is more than 1 and last iteration caused a swap + while (gap != 1 || swapped) { + // Find next gap + gap = nextGap(gap); + + // Initialize swapped as false so that we can check if swap happened or not + swapped = false; + + // Compare all elements with current gap + for (int i = 0; i < size - gap; i++) { + if (less(arr[i + gap], arr[i])) { + // Swap arr[i] and arr[i+gap] + swapped = swap(arr, i, i + gap); + } + } + } + return arr; + } + + // Driver method + public static void main(String[] args) { + CombSort ob = new CombSort(); + Integer[] arr = {8, 4, 1, 56, 3, -44, -1, 0, 36, 34, 8, 12, -66, -78, 23, -6, 28, 0}; + ob.sort(arr); + + System.out.println("sorted array"); + print(arr); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java new file mode 100644 index 000000000000..47e91d880a21 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -0,0 +1,97 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.print; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; + +import java.util.*; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +/** + * @author Youssef Ali (https://github.com/youssefAli11997) + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +class CountingSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] unsorted) { + return sort(Arrays.asList(unsorted)).toArray(unsorted); + } + + /** + * This method implements the Generic Counting Sort + * + * @param list The list to be sorted + *

+ * Sorts the list in increasing order The method uses list elements as keys + * in the frequency map + */ + @Override + public > List sort(List list) { + + Map frequency = new TreeMap<>(); + // The final output array + List sortedArray = new ArrayList<>(list.size()); + + // Counting the frequency of @param array elements + list.forEach(v -> frequency.put(v, frequency.getOrDefault(v, 0) + 1)); + + // Filling the sortedArray + for (Map.Entry element : frequency.entrySet()) { + for (int j = 0; j < element.getValue(); j++) { + sortedArray.add(element.getKey()); + } + } + + return sortedArray; + } + + /** + * Stream Counting Sort The same as method {@link CountingSort#sort(List)} } + * but this method uses stream API + * + * @param list The list to be sorted + */ + private static > List streamSort(List list) { + return list.stream() + .collect(toMap(k -> k, v -> 1, (v1, v2) -> v1 + v2, TreeMap::new)) + .entrySet() + .stream() + .flatMap(entry -> IntStream.rangeClosed(1, entry.getValue()).mapToObj(t -> entry.getKey())) + .collect(toList()); + } + + // Driver Program + public static void main(String[] args) { + // Integer Input + List unsortedInts + = Stream.of(4, 23, 6, 78, 1, 54, 23, 1, 9, 231, 9, 12).collect(toList()); + CountingSort countingSort = new CountingSort(); + + System.out.println("Before Sorting:"); + print(unsortedInts); + + // Output => 1 1 4 6 9 9 12 23 23 54 78 231 + System.out.println("After Sorting:"); + print(countingSort.sort(unsortedInts)); + System.out.println("After Sorting By Streams:"); + print(streamSort(unsortedInts)); + + System.out.println("\n------------------------------\n"); + + // String Input + List unsortedStrings + = Stream.of("c", "a", "e", "b", "d", "a", "f", "g", "c").collect(toList()); + + System.out.println("Before Sorting:"); + print(unsortedStrings); + + // Output => a a b c c d e f g + System.out.println("After Sorting:"); + print(countingSort.sort(unsortedStrings)); + + System.out.println("After Sorting By Streams:"); + print(streamSort(unsortedStrings)); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/CycleSort.java b/src/main/java/com/thealgorithms/sorts/CycleSort.java new file mode 100644 index 000000000000..8e463c811ce7 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/CycleSort.java @@ -0,0 +1,84 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.less; +import static com.thealgorithms.sorts.SortUtils.print; + +/** + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +class CycleSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] arr) { + int n = arr.length; + + // traverse array elements + for (int j = 0; j <= n - 2; j++) { + // initialize item as starting point + T item = arr[j]; + + // Find position where we put the item. + int pos = j; + for (int i = j + 1; i < n; i++) { + if (less(arr[i], item)) { + pos++; + } + } + + // If item is already in correct position + if (pos == j) { + continue; + } + + // ignore all duplicate elements + while (item.compareTo(arr[pos]) == 0) { + pos += 1; + } + + // put the item to it's right position + if (pos != j) { + item = replace(arr, pos, item); + } + + // Rotate rest of the cycle + while (pos != j) { + pos = j; + + // Find position where we put the element + for (int i = j + 1; i < n; i++) { + if (less(arr[i], item)) { + pos += 1; + } + } + + // ignore all duplicate elements + while (item.compareTo(arr[pos]) == 0) { + pos += 1; + } + + // put the item to it's right position + if (item != arr[pos]) { + item = replace(arr, pos, item); + } + } + } + + return arr; + } + + private > T replace(T[] arr, int pos, T item) { + T temp = item; + item = arr[pos]; + arr[pos] = temp; + return item; + } + + public static void main(String[] args) { + Integer arr[] = {4, 23, 6, 78, 1, 26, 11, 23, 0, -6, 3, 54, 231, 9, 12}; + CycleSort cycleSort = new CycleSort(); + cycleSort.sort(arr); + + System.out.println("After sort : "); + print(arr); + } +} diff --git a/Sorts/DNFSort.java b/src/main/java/com/thealgorithms/sorts/DNFSort.java similarity index 89% rename from Sorts/DNFSort.java rename to src/main/java/com/thealgorithms/sorts/DNFSort.java index 551c88ac1ef5..b02bfc54ef67 100644 --- a/Sorts/DNFSort.java +++ b/src/main/java/com/thealgorithms/sorts/DNFSort.java @@ -1,6 +1,7 @@ -package Sorts; +package com.thealgorithms.sorts; public class DNFSort { + // Sort the input array, the array is assumed to // have values in {0, 1, 2} static void sort012(int a[], int arr_size) { @@ -33,14 +34,15 @@ static void sort012(int a[], int arr_size) { /* Utility function to print array arr[] */ static void printArray(int arr[], int arr_size) { - for (int i = 0; i < arr_size; i++) + for (int i = 0; i < arr_size; i++) { System.out.print(arr[i] + " "); + } System.out.println(""); } /*Driver function to check for above functions*/ public static void main(String[] args) { - int arr[] = { 0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1 }; + int arr[] = {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}; int arr_size = arr.length; sort012(arr, arr_size); System.out.println("Array after seggregation "); diff --git a/src/main/java/com/thealgorithms/sorts/GnomeSort.java b/src/main/java/com/thealgorithms/sorts/GnomeSort.java new file mode 100644 index 000000000000..fcdd4a917667 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/GnomeSort.java @@ -0,0 +1,43 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +/** + * Implementation of gnome sort + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @since 2018-04-10 + */ +public class GnomeSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] arr) { + int i = 1; + int j = 2; + while (i < arr.length) { + if (less(arr[i - 1], arr[i])) { + i = j++; + } else { + swap(arr, i - 1, i); + if (--i == 0) { + i = j++; + } + } + } + + return null; + } + + public static void main(String[] args) { + Integer[] integers = {4, 23, 6, 78, 1, 26, 11, 23, 0, -6, 3, 54, 231, 9, 12}; + String[] strings = {"c", "a", "e", "b", "d", "dd", "da", "zz", "AA", "aa", "aB", "Hb", "Z"}; + GnomeSort gnomeSort = new GnomeSort(); + + gnomeSort.sort(integers); + gnomeSort.sort(strings); + + System.out.println("After sort : "); + print(integers); + print(strings); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/HeapSort.java b/src/main/java/com/thealgorithms/sorts/HeapSort.java new file mode 100644 index 000000000000..92669a7be9ec --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/HeapSort.java @@ -0,0 +1,124 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Heap Sort Algorithm Implements MinHeap + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +public class HeapSort implements SortAlgorithm { + + private static class Heap> { + + /** + * Array to store heap + */ + private T[] heap; + + /** + * Constructor + * + * @param heap array of unordered integers + */ + public Heap(T[] heap) { + this.heap = heap; + } + + /** + * Heapifies subtree from top as root to last as last child + * + * @param rootIndex index of root + * @param lastChild index of last child + */ + private void heapSubtree(int rootIndex, int lastChild) { + int leftIndex = rootIndex * 2 + 1; + int rightIndex = rootIndex * 2 + 2; + T root = heap[rootIndex]; + if (rightIndex <= lastChild) { // if has right and left children + T left = heap[leftIndex]; + T right = heap[rightIndex]; + if (less(left, right) && less(left, root)) { + swap(heap, leftIndex, rootIndex); + heapSubtree(leftIndex, lastChild); + } else if (less(right, root)) { + swap(heap, rightIndex, rootIndex); + heapSubtree(rightIndex, lastChild); + } + } else if (leftIndex <= lastChild) { // if no right child, but has left child + T left = heap[leftIndex]; + if (less(left, root)) { + swap(heap, leftIndex, rootIndex); + heapSubtree(leftIndex, lastChild); + } + } + } + + /** + * Makes heap with root as root + * + * @param root index of root of heap + */ + private void makeMinHeap(int root) { + int leftIndex = root * 2 + 1; + int rightIndex = root * 2 + 2; + boolean hasLeftChild = leftIndex < heap.length; + boolean hasRightChild = rightIndex < heap.length; + if (hasRightChild) { // if has left and right + makeMinHeap(leftIndex); + makeMinHeap(rightIndex); + heapSubtree(root, heap.length - 1); + } else if (hasLeftChild) { + heapSubtree(root, heap.length - 1); + } + } + + /** + * Gets the root of heap + * + * @return root of heap + */ + private T getRoot(int size) { + swap(heap, 0, size); + heapSubtree(0, size - 1); + return heap[size]; // return old root + } + } + + @Override + public > T[] sort(T[] unsorted) { + return sort(Arrays.asList(unsorted)).toArray(unsorted); + } + + @Override + public > List sort(List unsorted) { + int size = unsorted.size(); + + @SuppressWarnings("unchecked") + Heap heap = new Heap<>(unsorted.toArray((T[]) new Comparable[unsorted.size()])); + + heap.makeMinHeap(0); // make min heap using index 0 as root. + List sorted = new ArrayList<>(size); + while (size > 0) { + T min = heap.getRoot(--size); + sorted.add(min); + } + + return sorted; + } + + /** + * Main method + * + * @param args the command line arguments + */ + public static void main(String[] args) { + Integer[] heap = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + HeapSort heapSort = new HeapSort(); + print(heapSort.sort(heap)); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/InsertionSort.java b/src/main/java/com/thealgorithms/sorts/InsertionSort.java new file mode 100644 index 000000000000..cde6d7bee57a --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/InsertionSort.java @@ -0,0 +1,45 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.less; +import static com.thealgorithms.sorts.SortUtils.print; + +class InsertionSort implements SortAlgorithm { + + /** + * Generic insertion sort algorithm in increasing order. + * + * @param array the array to be sorted. + * @param the class of array. + * @return sorted array. + */ + @Override + public > T[] sort(T[] array) { + for (int i = 1; i < array.length; i++) { + T insertValue = array[i]; + int j; + for (j = i - 1; j >= 0 && less(insertValue, array[j]); j--) { + array[j + 1] = array[j]; + } + if (j != i - 1) { + array[j + 1] = insertValue; + } + } + return array; + } + + /** + * Driver Code + */ + public static void main(String[] args) { + Integer[] integers = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + InsertionSort sort = new InsertionSort(); + sort.sort(integers); + print(integers); + /* [1, 4, 6, 9, 12, 23, 54, 78, 231] */ + + String[] strings = {"c", "a", "e", "b", "d"}; + sort.sort(strings); + print(strings); + /* [a, b, c, d, e] */ + } +} diff --git a/src/main/java/com/thealgorithms/sorts/MergeSort.java b/src/main/java/com/thealgorithms/sorts/MergeSort.java new file mode 100644 index 000000000000..ce50a4344006 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/MergeSort.java @@ -0,0 +1,91 @@ +package com.thealgorithms.sorts; + +/** + * Generic merge sort algorithm. + * + * @see SortAlgorithm + */ +class MergeSort implements SortAlgorithm { + + /** + * Generic merge sort algorithm implements. + * + * @param unsorted the array which should be sorted. + * @param Comparable class. + * @return sorted array. + */ + @Override + public > T[] sort(T[] unsorted) { + doSort(unsorted, 0, unsorted.length - 1); + return unsorted; + } + + /** + * @param arr the array to be sorted. + * @param left the first index of the array. + * @param right the last index of the array. + */ + private static > void doSort(T[] arr, int left, int right) { + if (left < right) { + int mid = (left + right) >>> 1; + doSort(arr, left, mid); + doSort(arr, mid + 1, right); + merge(arr, left, mid, right); + } + } + + /** + * Merges two parts of an array. + * + * @param arr the array to be merged. + * @param left the first index of the array. + * @param mid the middle index of the array. + * @param right the last index of the array merges two parts of an array in + * increasing order. + */ + private static > void merge(T[] arr, int left, int mid, int right) { + int length = right - left + 1; + @SuppressWarnings("unchecked") + T[] temp = (T[]) new Comparable[length]; + int i = left; + int j = mid + 1; + int k = 0; + + while (i <= mid && j <= right) { + if (arr[i].compareTo(arr[j]) <= 0) { + temp[k++] = arr[i++]; + } else { + temp[k++] = arr[j++]; + } + } + + while (i <= mid) { + temp[k++] = arr[i++]; + } + + while (j <= right) { + temp[k++] = arr[j++]; + } + + System.arraycopy(temp, 0, arr, left, length); + } + + /** + * Driver code + */ + public static void main(String[] args) { + MergeSort mergeSort = new MergeSort(); + + Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + mergeSort.sort(arr); + for (int i = 0; i < arr.length - 1; ++i) { + assert arr[i] <= arr[i + 1]; + } + + String[] stringArray = {"c", "a", "e", "b", "d"}; + mergeSort.sort(stringArray); + for (int i = 0; i < stringArray.length - 1; ++i) { + assert arr[i].compareTo(arr[i + 1]) <= 0; + } + } +} diff --git a/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java b/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java new file mode 100644 index 000000000000..f4df83726577 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java @@ -0,0 +1,76 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; +import java.util.*; + +/*This code implements the mergeSort algorithm without extra space +For understanding about mergesort visit :https://www.geeksforgeeks.org/merge-sort/ + */ +public class MergeSortNoExtraSpace { + + public static void call_merge_sort(int a[], int n) { + int maxele = Arrays.stream(a).max().getAsInt() + 1; + merge_sort(a, 0, n - 1, maxele); + } + + public static void merge_sort(int a[], int start, int end, int maxele) { //this function divides the array into 2 halves + + if (start < end) { + int mid = (start + end) / 2; + merge_sort(a, start, mid, maxele); + merge_sort(a, mid + 1, end, maxele); + implement_merge_sort(a, start, mid, end, maxele); + + } + } + + public static void implement_merge_sort(int a[], int start, int mid, int end, int maxele) { //implementation of mergesort + int i = start; + int j = mid + 1; + int k = start; + while (i <= mid && j <= end) { + if (a[i] % maxele <= a[j] % maxele) { + a[k] = a[k] + (a[i] + % maxele) * maxele; + k++; + i++; + } else { + a[k] = a[k] + (a[j] + % maxele) * maxele; + k++; + j++; + } + } + while (i <= mid) { + a[k] = a[k] + (a[i] + % maxele) * maxele; + k++; + i++; + } + while (j <= end) { + a[k] = a[k] + (a[j] + % maxele) * maxele; + k++; + j++; + } + for (i = start; i <= end; i++) { + a[i] = a[i] / maxele; + } + + } + + public static void main(String args[]) { + Scanner inp = new Scanner(System.in); + System.out.println("Enter array size"); + int n = inp.nextInt(); + int a[] = new int[n]; + System.out.println("Enter array elements"); + for (int i = 0; i < n; i++) { + a[i] = inp.nextInt(); + } + call_merge_sort(a, n); + for (int i = 0; i < a.length; i++) { + System.out.print(a[i] + " "); + } + } +} diff --git a/Sorts/MergeSortRecursive.java b/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java similarity index 93% rename from Sorts/MergeSortRecursive.java rename to src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java index f05bf2e6b00f..7e81a8303ef2 100644 --- a/Sorts/MergeSortRecursive.java +++ b/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java @@ -1,4 +1,4 @@ -package Sorts; +package com.thealgorithms.sorts; import java.util.Arrays; import java.util.ArrayList; @@ -59,16 +59,18 @@ private static List sort(List unsortedA, List unsorte { add(unsortedB.get(0)); } - };newAl.addAll(sort(unsortedA, unsortedB.subList(1, unsortedB.size()))); + }; + newAl.addAll(sort(unsortedA, unsortedB.subList(1, unsortedB.size()))); return newAl; } -} + } } class App { + public static void main(String[] args) { MergeSortRecursive sort = new MergeSortRecursive(new ArrayList<>(Arrays.asList(4, 3, 1, 8, 5, 10, 0, 1, 4, 11, 8, 9))); sort.mergeSort(); } -} \ No newline at end of file +} diff --git a/Sorts/OddEvenSort.java b/src/main/java/com/thealgorithms/sorts/OddEvenSort.java similarity index 80% rename from Sorts/OddEvenSort.java rename to src/main/java/com/thealgorithms/sorts/OddEvenSort.java index 160746c15c6b..e6fe5e6cade5 100644 --- a/Sorts/OddEvenSort.java +++ b/src/main/java/com/thealgorithms/sorts/OddEvenSort.java @@ -1,4 +1,4 @@ -package Sorts; +package com.thealgorithms.sorts; import java.util.Random; @@ -33,19 +33,19 @@ public static void main(String[] args) { */ public static void oddEvenSort(int[] arr) { boolean sorted = false; - while(!sorted) { + while (!sorted) { sorted = true; - for(int i = 1; i < arr.length-1; i += 2){ - if (arr[i] > arr [i + 1]){ - swap(arr, i, i+1); + for (int i = 1; i < arr.length - 1; i += 2) { + if (arr[i] > arr[i + 1]) { + swap(arr, i, i + 1); sorted = false; } } - for (int i = 0; i < arr.length - 1; i+= 2){ - if( arr[i] > arr[i + 1] ){ - swap(arr, i, i+1); + for (int i = 0; i < arr.length - 1; i += 2) { + if (arr[i] > arr[i + 1]) { + swap(arr, i, i + 1); sorted = false; } } @@ -64,4 +64,4 @@ private static void swap(int[] arr, int i, int j) { arr[i] = arr[j]; arr[j] = temp; } -} \ No newline at end of file +} diff --git a/src/main/java/com/thealgorithms/sorts/PancakeSort.java b/src/main/java/com/thealgorithms/sorts/PancakeSort.java new file mode 100644 index 000000000000..1d0b76fc04c7 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/PancakeSort.java @@ -0,0 +1,41 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +/** + * Implementation of pancake sort + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @since 2018-04-10 + */ +public class PancakeSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] array) { + int size = array.length; + + for (int i = 0; i < size; i++) { + T max = array[0]; + int index = 0; + for (int j = 0; j < size - i; j++) { + if (less(max, array[j])) { + max = array[j]; + index = j; + } + } + flip(array, index, array.length - 1 - i); + } + return array; + } + + public static void main(String[] args) { + + Integer[] arr = { + 10, 9, 8, 7, 6, 15, 14, 7, 4, 3, 8, 6, 3, 1, 2, -2, -5, -8, -3, -1, 13, 12, 11, 5, 4, 3, 2, 1 + }; + PancakeSort pancakeSort = new PancakeSort(); + System.out.println("After sorting:"); + pancakeSort.sort(arr); + print(arr); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/QuickSort.java b/src/main/java/com/thealgorithms/sorts/QuickSort.java new file mode 100644 index 000000000000..6eab72f847f1 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/QuickSort.java @@ -0,0 +1,98 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @see SortAlgorithm + */ +class QuickSort implements SortAlgorithm { + + /** + * This method implements the Generic Quick Sort + * + * @param array The array to be sorted Sorts the array in increasing order + */ + @Override + public > T[] sort(T[] array) { + doSort(array, 0, array.length - 1); + return array; + } + + /** + * The sorting process + * + * @param left The first index of an array + * @param right The last index of an array + * @param array The array to be sorted + */ + private static > void doSort(T[] array, int left, int right) { + if (left < right) { + int pivot = randomPartition(array, left, right); + doSort(array, left, pivot - 1); + doSort(array, pivot, right); + } + } + + /** + * Ramdomize the array to avoid the basically ordered sequences + * + * @param array The array to be sorted + * @param left The first index of an array + * @param right The last index of an array + * @return the partition index of the array + */ + private static > int randomPartition(T[] array, int left, int right) { + int randomIndex = left + (int) (Math.random() * (right - left + 1)); + swap(array, randomIndex, right); + return partition(array, left, right); + } + + /** + * This method finds the partition index for an array + * + * @param array The array to be sorted + * @param left The first index of an array + * @param right The last index of an array Finds the partition index of an + * array + */ + private static > int partition(T[] array, int left, int right) { + int mid = (left + right) >>> 1; + T pivot = array[mid]; + + while (left <= right) { + while (less(array[left], pivot)) { + ++left; + } + while (less(pivot, array[right])) { + --right; + } + if (left <= right) { + swap(array, left, right); + ++left; + --right; + } + } + return left; + } + + // Driver Program + public static void main(String[] args) { + + // For integer input + Integer[] array = {3, 4, 1, 32, 0, 1, 5, 12, 2, 5, 7, 8, 9, 2, 44, 111, 5}; + + QuickSort quickSort = new QuickSort(); + quickSort.sort(array); + + // Output => 0 1 1 2 2 3 4 5 5 5 7 8 9 12 32 44 111 + print(array); + + String[] stringArray = {"c", "a", "e", "b", "d"}; + quickSort.sort(stringArray); + + // Output => a b c d e + print(stringArray); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/RadixSort.java b/src/main/java/com/thealgorithms/sorts/RadixSort.java new file mode 100644 index 000000000000..080e386a46c2 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/RadixSort.java @@ -0,0 +1,63 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; + +class RadixSort { + + private static int getMax(int[] arr, int n) { + int mx = arr[0]; + for (int i = 1; i < n; i++) { + if (arr[i] > mx) { + mx = arr[i]; + } + } + return mx; + } + + private static void countSort(int[] arr, int n, int exp) { + int[] output = new int[n]; + int i; + int[] count = new int[10]; + Arrays.fill(count, 0); + + for (i = 0; i < n; i++) { + count[(arr[i] / exp) % 10]++; + } + + for (i = 1; i < 10; i++) { + count[i] += count[i - 1]; + } + + for (i = n - 1; i >= 0; i--) { + output[count[(arr[i] / exp) % 10] - 1] = arr[i]; + count[(arr[i] / exp) % 10]--; + } + + for (i = 0; i < n; i++) { + arr[i] = output[i]; + } + } + + private static void radixsort(int[] arr, int n) { + + int m = getMax(arr, n); + + for (int exp = 1; m / exp > 0; exp *= 10) { + countSort(arr, n, exp); + } + } + + static void print(int[] arr, int n) { + for (int i = 0; i < n; i++) { + System.out.print(arr[i] + " "); + } + } + + public static void main(String[] args) { + int[] arr = {170, 45, 75, 90, 802, 24, 2, 66}; + int n = arr.length; + radixsort(arr, n); + print(arr, n); + } +} +// Written by James Mc Dermott(theycallmemac) diff --git a/src/main/java/com/thealgorithms/sorts/SelectionSort.java b/src/main/java/com/thealgorithms/sorts/SelectionSort.java new file mode 100644 index 000000000000..e2248987259f --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/SelectionSort.java @@ -0,0 +1,49 @@ +package com.thealgorithms.sorts; + +public class SelectionSort implements SortAlgorithm { + + /** + * Generic selection sort algorithm in increasing order. + * + * @param arr the array to be sorted. + * @param the class of array. + * @return sorted array. + */ + @Override + public > T[] sort(T[] arr) { + int n = arr.length; + for (int i = 0; i < n - 1; i++) { + int minIndex = i; + for (int j = i + 1; j < n; j++) { + if (arr[minIndex].compareTo(arr[j]) > 0) { + minIndex = j; + } + } + if (minIndex != i) { + T temp = arr[i]; + arr[i] = arr[minIndex]; + arr[minIndex] = temp; + } + } + return arr; + } + + /** + * Driver Code + */ + public static void main(String[] args) { + + Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + SelectionSort selectionSort = new SelectionSort(); + Integer[] sorted = selectionSort.sort(arr); + for (int i = 0; i < sorted.length - 1; ++i) { + assert sorted[i] <= sorted[i + 1]; + } + + String[] strings = {"c", "a", "e", "b", "d"}; + String[] sortedStrings = selectionSort.sort(strings); + for (int i = 0; i < sortedStrings.length - 1; ++i) { + assert strings[i].compareTo(strings[i + 1]) <= 0; + } + } +} diff --git a/src/main/java/com/thealgorithms/sorts/ShellSort.java b/src/main/java/com/thealgorithms/sorts/ShellSort.java new file mode 100644 index 000000000000..5f41a5440388 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/ShellSort.java @@ -0,0 +1,48 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.*; + +public class ShellSort implements SortAlgorithm { + + /** + * Implements generic shell sort. + * + * @param array the array to be sorted. + * @param the type of elements in the array. + * @return the sorted array. + */ + @Override + public > T[] sort(T[] array) { + int length = array.length; + int gap = 1; + + /* Calculate gap for optimization purpose */ + while (gap < length / 3) { + gap = 3 * gap + 1; + } + + for (; gap > 0; gap /= 3) { + for (int i = gap; i < length; i++) { + int j; + T temp = array[i]; + for (j = i; j >= gap && less(temp, array[j - gap]); j -= gap) { + array[j] = array[j - gap]; + } + array[j] = temp; + } + } + return array; + } + + /* Driver Code */ + public static void main(String[] args) { + Integer[] toSort = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + + ShellSort sort = new ShellSort(); + sort.sort(toSort); + for (int i = 0; i < toSort.length - 1; ++i) { + assert toSort[i] <= toSort[i + 1]; + } + print(toSort); + } +} diff --git a/Sorts/SimpleSort.java b/src/main/java/com/thealgorithms/sorts/SimpleSort.java similarity index 81% rename from Sorts/SimpleSort.java rename to src/main/java/com/thealgorithms/sorts/SimpleSort.java index b9088ceea43d..4ae7082df779 100644 --- a/Sorts/SimpleSort.java +++ b/src/main/java/com/thealgorithms/sorts/SimpleSort.java @@ -1,6 +1,6 @@ -package Sorts; +package com.thealgorithms.sorts; -import static Sorts.SortUtils.*; +import static com.thealgorithms.sorts.SortUtils.*; public class SimpleSort implements SortAlgorithm { @@ -23,7 +23,7 @@ public > T[] sort(T[] array) { public static void main(String[] args) { // ==== Int ======= - Integer[] a = { 3, 7, 45, 1, 33, 5, 2, 9 }; + Integer[] a = {3, 7, 45, 1, 33, 5, 2, 9}; System.out.print("unsorted: "); print(a); System.out.println(); @@ -34,7 +34,7 @@ public static void main(String[] args) { System.out.println(); // ==== String ======= - String[] b = { "banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple" }; + String[] b = {"banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"}; System.out.print("unsorted: "); print(b); System.out.println(); diff --git a/Sorts/SlowSort.java b/src/main/java/com/thealgorithms/sorts/SlowSort.java similarity index 97% rename from Sorts/SlowSort.java rename to src/main/java/com/thealgorithms/sorts/SlowSort.java index 29f3ae0eda5f..bce97683d496 100644 --- a/Sorts/SlowSort.java +++ b/src/main/java/com/thealgorithms/sorts/SlowSort.java @@ -1,4 +1,4 @@ -package Sorts; +package com.thealgorithms.sorts; /** * @author Amir Hassan (https://github.com/ahsNT) diff --git a/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java b/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java new file mode 100644 index 000000000000..4df4e47e4702 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java @@ -0,0 +1,31 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; +import java.util.List; + +/** + * The common interface of most sorting algorithms + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +public interface SortAlgorithm { + + /** + * Main method arrays sorting algorithms + * + * @param unsorted - an array should be sorted + * @return a sorted array + */ + > T[] sort(T[] unsorted); + + /** + * Auxiliary method for algorithms what wanted to work with lists from JCF + * + * @param unsorted - a list should be sorted + * @return a sorted list + */ + @SuppressWarnings("unchecked") + default > List sort(List unsorted) { + return Arrays.asList(sort(unsorted.toArray((T[]) new Comparable[unsorted.size()]))); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/SortUtils.java b/src/main/java/com/thealgorithms/sorts/SortUtils.java new file mode 100644 index 000000000000..c3df99513e17 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/SortUtils.java @@ -0,0 +1,98 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; +import java.util.List; + +/** + * The class contains util methods + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + */ +final class SortUtils { + + /** + * Helper method for swapping places in array + * + * @param array The array which elements we want to swap + * @param idx index of the first element + * @param idy index of the second element + */ + static boolean swap(T[] array, int idx, int idy) { + T swap = array[idx]; + array[idx] = array[idy]; + array[idy] = swap; + return true; + } + + /** + * This method checks if first element is less than the other element + * + * @param v first element + * @param w second element + * @return true if the first element is less than the second element + */ + static > boolean less(T v, T w) { + return v.compareTo(w) < 0; + } + + /** + * This method checks if first element is greater than the other element + * + * @param v first element + * @param w second element + * @return true if the first element is greater than the second element + */ + static > boolean greater(T v, T w) { + return v.compareTo(w) > 0; + } + + /** + * This method checks if first element is greater than or equal the other + * element + * + * @param v first element + * @param w second element + * @return true if the first element is greater than or equal the second + * element + */ + static > boolean greaterOrEqual(T v, T w) { + return v.compareTo(w) >= 0; + } + + /** + * Prints a list + * + * @param toPrint - a list which should be printed + */ + static void print(List toPrint) { + toPrint.stream().map(Object::toString).map(str -> str + " ").forEach(System.out::print); + + System.out.println(); + } + + /** + * Prints an array + * + * @param toPrint - an array which should be printed + */ + static void print(Object[] toPrint) { + System.out.println(Arrays.toString(toPrint)); + } + + /** + * Swaps all position from { + * + * @param left} to @{ + * @param right} for { + * @param array} + * + * @param array is an array + * @param left is a left flip border of the array + * @param right is a right flip border of the array + */ + static > void flip(T[] array, int left, int right) { + while (left <= right) { + swap(array, left++, right--); + } + } +} diff --git a/Sorts/StoogeSort.java b/src/main/java/com/thealgorithms/sorts/StoogeSort.java similarity index 97% rename from Sorts/StoogeSort.java rename to src/main/java/com/thealgorithms/sorts/StoogeSort.java index 6669d7f126ef..330f9752d1e4 100644 --- a/Sorts/StoogeSort.java +++ b/src/main/java/com/thealgorithms/sorts/StoogeSort.java @@ -1,4 +1,4 @@ -package Sorts; +package com.thealgorithms.sorts; /** * @author Amir Hassan (https://github.com/ahsNT) diff --git a/Sorts/SwapSort.java b/src/main/java/com/thealgorithms/sorts/SwapSort.java similarity index 88% rename from Sorts/SwapSort.java rename to src/main/java/com/thealgorithms/sorts/SwapSort.java index c6ab1a516981..5550f70d7bd3 100644 --- a/Sorts/SwapSort.java +++ b/src/main/java/com/thealgorithms/sorts/SwapSort.java @@ -1,6 +1,6 @@ -package Sorts; +package com.thealgorithms.sorts; -import static Sorts.SortUtils.*; +import static com.thealgorithms.sorts.SortUtils.*; /** * The idea of Swap-Sort is to count the number m of smaller values (that are in @@ -44,7 +44,7 @@ private > int getSmallerElementCount(T[] array, int inde public static void main(String[] args) { // ==== Int ======= - Integer[] a = { 3, 7, 45, 1, 33, 5, 2, 9 }; + Integer[] a = {3, 7, 45, 1, 33, 5, 2, 9}; System.out.print("unsorted: "); print(a); System.out.println(); @@ -55,7 +55,7 @@ public static void main(String[] args) { System.out.println(); // ==== String ======= - String[] b = { "banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple" }; + String[] b = {"banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"}; System.out.print("unsorted: "); print(b); System.out.println(); diff --git a/src/main/java/com/thealgorithms/sorts/TimSort.java b/src/main/java/com/thealgorithms/sorts/TimSort.java new file mode 100644 index 000000000000..6f9a3a10a785 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/TimSort.java @@ -0,0 +1,204 @@ +package com.thealgorithms.sorts; + +import java.util.Random; + +/** + * @author [Hemanth Kotagiri](https://github.com/hemanth-kotagiri) + * @see [Tim Sort](https://en.wikipedia.org/wiki/Tim_sort) + */ +class TimSort { + + int array[]; + int array_length; + int RUN = 32; + + /** + * @brief A constructor which takes in the array specified by the user. + * @param array : Array given by the user. + */ + public TimSort(int[] array) { + this.array = array; + this.array_length = array.length; + } + + /** + * @brief A constructor which takes in an array length and randomly + * initializes an array. + * @param array_length length given by the user. + */ + public TimSort(int array_length) { + Random rand = new Random(); + + this.array_length = array_length; + this.array = new int[this.array_length]; + + for (int i = 0; i < this.array_length; i++) { + int random_number = rand.nextInt(1000); + this.array[i] = random_number; + } + } + + /** + * @brief A method to change the size of the run. + * @param run : Value specified by the user to change the run. + */ + public void change_run(int run) { + this.RUN = run; + } + + /** + * @brief A default constructor when no parameters are given. Initializes + * the array length to be 100. Generates a random number array of size 100. + */ + public TimSort() { + this.array_length = 100; + this.array = new int[this.array_length]; + + Random rand = new Random(); + for (int i = 0; i < this.array_length; i++) { + int random_number = rand.nextInt(1000); + this.array[i] = random_number; + } + } + + /** + * @brief Performs Insertion Sort Algorithm on given array with bounded + * indices. + * @param array: The array on which the algorithm is to be performed. + * @param start_idx: The starting index from which the algorithm is to be + * performed. + * @param end_idx: The ending index at which the algorithm needs to stop + * sorting. + */ + public void insertion_sort(int[] array, int start_idx, int end_idx) { + for (int i = 0; i < array.length; i++) { + int current_element = array[i]; + int j = i - 1; + while (j >= 0 && array[j] > current_element) { + array[j + 1] = array[j]; + j--; + } + array[j + 1] = current_element; + } + } + + /** + * @brief A method to merge two runs(chunks of array). + * @param array: The origin array which is to be sorted. + * @param start: Starting index of the first run(chunk). + * @param mid: The ending index of the first run(chunk). + * @param end: Ending index of the second run(chunk). + */ + public void merge_runs(int array[], int start, int mid, int end) { + + int first_array_size = mid - start + 1, second_array_size = end - mid; + int array1[] = new int[first_array_size], array2[] = new int[second_array_size]; + int i = 0, j = 0, k = 0; + + // Building the two sub arrays from the array to merge later + for (i = 0; i < first_array_size; i++) { + array1[i] = array[start + i]; + } + for (i = 0; i < second_array_size; i++) { + array2[i] = array[mid + 1 + i]; + } + + i = 0; + j = 0; + k = start; + + while (i < first_array_size && j < second_array_size) { + if (array1[i] <= array2[j]) { + array[k] = array1[i]; + i++; + } else { + array[k] = array2[j]; + j++; + } + k++; + } + + while (i < first_array_size) { + array[k] = array1[i]; + k++; + i++; + } + + while (j < second_array_size) { + array[k] = array2[j]; + k++; + j++; + } + } + + /** + * @brief Tim Sort Algorithm method. + */ + public void algorithm() { + // Before Sorting + System.out.println("Before sorting the array: "); + this.showArrayElements(); + System.out.println(); + + // Applying insertion sort on RUNS. + for (int i = 0; i < this.array_length; i += this.RUN) { + this.insertion_sort(this.array, i, Math.min(i + this.RUN, (this.array_length - 1))); + } + + for (int split = this.RUN; split < this.array_length; split = 2 * split) { + for (int start_idx = 0; start_idx < this.array_length; start_idx += 2 * split) { + int mid = start_idx + split - 1; + int end_idx = Math.min((start_idx + 2 * split - 1), (this.array_length - 1)); + + this.merge_runs(this.array, start_idx, mid, end_idx); + } + } + // After sorting + System.out.println("After sorting the array: "); + this.showArrayElements(); + System.out.println(); + } + + /** + * @brief A method to show the elements inside the array. + */ + public void showArrayElements() { + for (int i = 0; i < this.array.length; i++) { + System.out.print(this.array[i] + " "); + } + System.out.println(); + } + + /** + * @brief A method to test the sorting algorithm + */ + static void test() { + int[] array = {4, 1, 3, 17, 12, 11, 8}; + TimSort sorterObj1 = new TimSort(); + TimSort sorterObj2 = new TimSort(50); + TimSort sorterObj3 = new TimSort(array); + + sorterObj1.algorithm(); + sorterObj2.algorithm(); + sorterObj3.algorithm(); + + // Testing the first array + for (int i = 0; i < sorterObj1.array_length - 1; i++) { + assert ((sorterObj1.array[i] <= sorterObj1.array[i + 1])) : "Array is not sorted"; + } + + // Testing the second array. + for (int i = 0; i < sorterObj2.array_length - 1; i++) { + assert ((sorterObj2.array[i] <= sorterObj2.array[i + 1])) : "Array is not sorted"; + } + + // Testing the third array. + for (int i = 0; i < sorterObj3.array_length - 1; i++) { + assert ((sorterObj3.array[i] <= sorterObj3.array[i + 1])) : "Array is not sorted"; + } + } + + public static void main(String[] args) { + test(); + } +} diff --git a/src/main/java/com/thealgorithms/sorts/TreeSort.java b/src/main/java/com/thealgorithms/sorts/TreeSort.java new file mode 100644 index 000000000000..664585833a01 --- /dev/null +++ b/src/main/java/com/thealgorithms/sorts/TreeSort.java @@ -0,0 +1,111 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.print; +import com.thealgorithms.datastructures.trees.BSTRecursiveGeneric; + +import java.util.List; + +/** + *

Implementation of the Tree Sort algorithm

+ * + *

+ * Tree Sort: A sorting algorithm which constructs a Binary Search Tree using + * the unsorted data and then outputs the data by inorder traversal of the tree. + * + * Reference: https://en.wikipedia.org/wiki/Tree_sort + *

+ * + * @author Madhur Panwar (https://github.com/mdrpanwar) + */ +public class TreeSort implements SortAlgorithm { + + @Override + public > T[] sort(T[] unsortedArray) { + return doTreeSortArray(unsortedArray); + } + + @Override + public > List sort(List unsortedList) { + return doTreeSortList(unsortedList); + } + + private > T[] doTreeSortArray(T[] unsortedArray) { + // create a generic BST tree + BSTRecursiveGeneric tree = new BSTRecursiveGeneric(); + + // add all elements to the tree + for (T element : unsortedArray) { + tree.add(element); + } + + // get the sorted list by inorder traversal of the tree + List sortedList = tree.inorderSort(); + + // add the elements back to the initial array + int i = 0; + for (T element : sortedList) { + unsortedArray[i++] = element; + } + + // return the array + return unsortedArray; + } + + private > List doTreeSortList(List unsortedList) { + // create a generic BST tree + BSTRecursiveGeneric tree = new BSTRecursiveGeneric(); + + // add all elements to the tree + for (T element : unsortedList) { + tree.add(element); + } + + // get the sorted list by inorder traversal of the tree and return it + return tree.inorderSort(); + } + + public static void main(String[] args) { + TreeSort treeSort = new TreeSort(); + + // ==== Integer Array ======= + System.out.println("Testing for Integer Array...."); + Integer[] a = {3, -7, 45, 1, 343, -5, 2, 9}; + System.out.print(String.format("%-10s", "unsorted: ")); + print(a); + a = treeSort.sort(a); + System.out.print(String.format("%-10s", "sorted: ")); + print(a); + System.out.println(); + + // ==== Integer List ======= + System.out.println("Testing for Integer List...."); + List intList = List.of(3, -7, 45, 1, 343, -5, 2, 9); + System.out.print(String.format("%-10s", "unsorted: ")); + print(intList); + intList = treeSort.sort(intList); + System.out.print(String.format("%-10s", "sorted: ")); + print(intList); + System.out.println(); + + // ==== String Array ======= + System.out.println("Testing for String Array...."); + String[] b = {"banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"}; + System.out.print(String.format("%-10s", "unsorted: ")); + print(b); + b = treeSort.sort(b); + System.out.print(String.format("%-10s", "sorted: ")); + print(b); + System.out.println(); + + // ==== String List ======= + System.out.println("Testing for String List...."); + List stringList = List.of("banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"); + System.out.print(String.format("%-10s", "unsorted: ")); + print(stringList); + stringList = treeSort.sort(stringList); + System.out.print(String.format("%-10s", "sorted: ")); + print(stringList); + + } + +} diff --git a/src/main/java/com/thealgorithms/strings/Alphabetical.java b/src/main/java/com/thealgorithms/strings/Alphabetical.java new file mode 100644 index 000000000000..fde17c883917 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/Alphabetical.java @@ -0,0 +1,34 @@ +package com.thealgorithms.strings; + +/** + * Alphabetical order is a system whereby character strings are placed in order + * based on the position of the characters in the conventional ordering of an + * alphabet. Wikipedia: https://en.wikipedia.org/wiki/Alphabetical_order + */ +class Alphabetical { + + public static void main(String[] args) { + assert !isAlphabetical("123abc"); + assert isAlphabetical("aBC"); + assert isAlphabetical("abc"); + assert !isAlphabetical("xyzabc"); + assert isAlphabetical("abcxyz"); + } + + /** + * Check if a string is alphabetical order or not + * + * @param s a string + * @return {@code true} if given string is alphabetical order, otherwise + * {@code false} + */ + public static boolean isAlphabetical(String s) { + s = s.toLowerCase(); + for (int i = 0; i < s.length() - 1; ++i) { + if (!Character.isLetter(s.charAt(i)) || !(s.charAt(i) <= s.charAt(i + 1))) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/thealgorithms/strings/CharactersSame.java b/src/main/java/com/thealgorithms/strings/CharactersSame.java new file mode 100644 index 000000000000..e0243fa8edef --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/CharactersSame.java @@ -0,0 +1,30 @@ +package com.thealgorithms.strings; + +public class CharactersSame { + + /** + * Driver Code + */ + public static void main(String[] args) { + assert isAllCharactersSame(""); + assert !isAllCharactersSame("aab"); + assert isAllCharactersSame("aaa"); + assert isAllCharactersSame("11111"); + } + + /** + * check if all the characters of a string are same + * + * @param s the string to check + * @return {@code true} if all characters of a string are same, otherwise + * {@code false} + */ + public static boolean isAllCharactersSame(String s) { + for (int i = 1, length = s.length(); i < length; ++i) { + if (s.charAt(i) != s.charAt(0)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java b/src/main/java/com/thealgorithms/strings/CheckAnagrams.java new file mode 100644 index 000000000000..87ec3faeb9a5 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/CheckAnagrams.java @@ -0,0 +1,53 @@ +package com.thealgorithms.strings; + +import java.util.HashMap; +import java.util.Map; + +/** + * Two strings are anagrams if they are made of the same letters arranged + * differently (ignoring the case). + */ +public class CheckAnagrams { + + public static void main(String[] args) { + assert isAnagrams("Silent", "Listen"); + assert isAnagrams("This is a string", "Is this a string"); + assert !isAnagrams("There", "Their"); + } + + /** + * Check if two strings are anagrams or not + * + * @param s1 the first string + * @param s2 the second string + * @return {@code true} if two string are anagrams, otherwise {@code false} + */ + public static boolean isAnagrams(String s1, String s2) { + int l1 = s1.length(); + int l2 = s2.length(); + s1 = s1.toLowerCase(); + s2 = s2.toLowerCase(); + Map charAppearances = new HashMap<>(); + + for (int i = 0; i < l1; i++) { + char c = s1.charAt(i); + int numOfAppearances = charAppearances.getOrDefault(c, 0); + charAppearances.put(c, numOfAppearances + 1); + } + + for (int i = 0; i < l2; i++) { + char c = s2.charAt(i); + if (!charAppearances.containsKey(c)) { + return false; + } + charAppearances.put(c, charAppearances.get(c) - 1); + } + + for (int cnt : charAppearances.values()) { + if (cnt != 0) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/thealgorithms/strings/CheckVowels.java b/src/main/java/com/thealgorithms/strings/CheckVowels.java new file mode 100644 index 000000000000..6121812a11a1 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/CheckVowels.java @@ -0,0 +1,53 @@ +package com.thealgorithms.strings; + +/** + * Vowel Count is a system whereby character strings are placed in order based + * on the position of the characters in the conventional ordering of an + * alphabet. Wikipedia: https://en.wikipedia.org/wiki/Alphabetical_order + */ +class CheckVowels { + + public static void main(String[] args) { + assert !hasVowels("This is a strings"); + assert hasVowels("Hello World"); + assert hasVowels("Java is fun"); + assert !hasVowels("123hi"); + assert hasVowels("Coding vs Programming"); + } + + /** + * Check if a string is has vowels or not + * + * @param input a string + * @return {@code true} if given string has vowels, otherwise {@code false} + */ + public static boolean hasVowels(String input) { + if (input.matches("[AEIOUaeiou]")) { + countVowels(input); + return true; + } + return false; + } + + /** + * count the number of vowels + * + * @param input a string prints the count of vowels + */ + public static void countVowels(String input) { + input = input.toLowerCase(); + int count = 0; + int i = 0; + while (i < input.length()) { + if (input.charAt(i) == 'a' + || input.charAt(i) == 'e' + || input.charAt(i) == 'i' + || input.charAt(i) == 'o' + || input.charAt(i) == 'u') { + count++; + } + i++; + } + System.out.println(count); + } +} diff --git a/src/main/java/com/thealgorithms/strings/HorspoolSearch.java b/src/main/java/com/thealgorithms/strings/HorspoolSearch.java new file mode 100644 index 000000000000..d886c9f47ae5 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/HorspoolSearch.java @@ -0,0 +1,183 @@ +package com.thealgorithms.strings; + +import java.util.HashMap; + +/** + * This class is not thread safe
+ *
+ * (From wikipedia) In computer science, the Boyer–Moore–Horspool algorithm or + * Horspool's algorithm is an algorithm for finding substrings in strings. It + * was published by Nigel Horspool in 1980. + *
+ * Wikipedia + * page
+ *
+ * + *

+ * An explanation:
+ * + *

+ * The Horspool algorithm is a simplification of the Boyer-Moore algorithm in + * that it uses only one of the two heuristic methods for increasing the number + * of characters shifted when finding a bad match in the text. This method is + * usually called the "bad symbol" or "bad character" shift. The bad symbol + * shift method is classified as an input enhancement method in the theory of + * algorithms. Input enhancement is (from wikipedia) the principle that + * processing a given input to a problem and altering it in a specific way will + * increase runtime efficiency or space efficiency, or both. Both algorithms try + * to match the pattern and text comparing the pattern symbols to the text's + * from right to left.
+ *
+ * + *

+ * In the bad symbol shift method, a table is created prior to the search, + * called the "bad symbol table". The bad symbol table contains the shift values + * for any symbol in the text and pattern. For these symbols, the value is the + * length of the pattern, if the symbol is not in the first (length - 1) of the + * pattern. Else it is the distance from its rightmost occurrence in the pattern + * to the last symbol of the pattern. In practice, we only calculate the values + * for the ones that exist in the first (length - 1) of the pattern.
+ *
+ * + *

+ * For more details on the algorithm and the more advanced Boyer-Moore I + * recommend checking out the wikipedia page and professor Anany Levitin's book: + * Introduction To The Design And Analysis Of Algorithms. + */ +public class HorspoolSearch { + + private static HashMap shiftValues; // bad symbol table + private static Integer patternLength; + private static int comparisons = 0; // total comparisons in the current/last search + + /** + * Case sensitive version version of the algorithm + * + * @param pattern the pattern to be searched for (needle) + * @param text the text being searched in (haystack) + * @return -1 if not found or first index of the pattern in the text + */ + public static int findFirst(String pattern, String text) { + return firstOccurrence(pattern, text, true); + } + + /** + * Case insensitive version version of the algorithm + * + * @param pattern the pattern to be searched for (needle) + * @param text the text being searched in (haystack) + * @return -1 if not found or first index of the pattern in the text + */ + public static int findFirstInsensitive(String pattern, String text) { + return firstOccurrence(pattern, text, false); + } + + /** + * Utility method that returns comparisons made by last run (mainly for + * tests) + * + * @return number of character comparisons of the last search + */ + public static Integer getLastComparisons() { + return HorspoolSearch.comparisons; + } + + /** + * Fairly standard implementation of the Horspool algorithm. Only the index + * of the last character of the pattern on the text is saved and shifted by + * the appropriate amount when a mismatch is found. The algorithm stops at + * the first match or when the entire text has been exhausted. + * + * @param pattern String to be matched in the text + * @param text text String + * @return index of first occurrence of the pattern in the text + */ + private static int firstOccurrence(String pattern, String text, boolean caseSensitive) { + shiftValues = calcShiftValues(pattern); // build the bad symbol table + comparisons = 0; // reset comparisons + + int textIndex + = pattern.length() - 1; // align pattern with text start and get index of the last character + + // while pattern is not out of text bounds + while (textIndex < text.length()) { + + // try to match pattern with current part of the text starting from last character + int i = pattern.length() - 1; + while (i >= 0) { + comparisons++; + char patternChar = pattern.charAt(i); + char textChar = text.charAt((textIndex + i) - (pattern.length() - 1)); + if (!charEquals(patternChar, textChar, caseSensitive)) { // bad character, shift pattern + textIndex += getShiftValue(text.charAt(textIndex)); + break; + } + i--; + } + + // check for full match + if (i == -1) { + return textIndex - pattern.length() + 1; + } + } + + // text exhausted, return failure + return -1; + } + + /** + * Compares the argument characters + * + * @param c1 first character + * @param c2 second character + * @param caseSensitive boolean determining case sensitivity of comparison + * @return truth value of the equality comparison + */ + private static boolean charEquals(char c1, char c2, boolean caseSensitive) { + if (caseSensitive) { + return c1 == c2; + } + return Character.toLowerCase(c1) == Character.toLowerCase(c2); + } + + /** + * Builds the bad symbol table required to run the algorithm. The method + * starts from the second to last character of the pattern and moves to the + * left. When it meets a new character, it is by definition its rightmost + * occurrence and therefore puts the distance from the current index to the + * index of the last character into the table. If the character is already + * in the table, then it is not a rightmost occurrence, so it continues. + * + * @param pattern basis for the bad symbol table + * @return the bad symbol table + */ + private static HashMap calcShiftValues(String pattern) { + patternLength = pattern.length(); + HashMap table = new HashMap<>(); + + for (int i = pattern.length() - 2; + i >= 0; + i--) { // length - 2 is the index of the second to last character + char c = pattern.charAt(i); + int finalI = i; + table.computeIfAbsent(c, k -> pattern.length() - 1 - finalI); + } + + return table; + } + + /** + * Helper function that uses the bad symbol shift table to return the + * appropriate shift value for a given character + * + * @param c character + * @return shift value that corresponds to the character argument + */ + private static Integer getShiftValue(char c) { + if (shiftValues.get(c) != null) { + return shiftValues.get(c); + } else { + return patternLength; + } + } +} diff --git a/src/main/java/com/thealgorithms/strings/List_all_Possible_Words_From_Phone_Digits.java b/src/main/java/com/thealgorithms/strings/List_all_Possible_Words_From_Phone_Digits.java new file mode 100644 index 000000000000..4677fd84885e --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/List_all_Possible_Words_From_Phone_Digits.java @@ -0,0 +1,58 @@ +package com.thealgorithms.strings; + +import java.util.*; + +public class List_all_Possible_Words_From_Phone_Digits { + + static Character[][] numberToCharMap; + + private static List printWords(int[] numbers, + int len, + int numIndex, + String s) { + if (len == numIndex) { + return new ArrayList<>(Collections.singleton(s)); + } + + List stringList = new ArrayList<>(); + + for (int i = 0; + i < numberToCharMap[numbers[numIndex]].length; i++) { + String sCopy + = String.copyValueOf(s.toCharArray()); + sCopy = sCopy.concat( + numberToCharMap[numbers[numIndex]][i].toString()); + stringList.addAll(printWords(numbers, len, + numIndex + 1, + sCopy)); + } + return stringList; + } + + private static void printWords(int[] numbers) { + generateNumberToCharMap(); + List stringList + = printWords(numbers, numbers.length, 0, ""); + stringList.stream().forEach(System.out::println); + } + + private static void generateNumberToCharMap() { + numberToCharMap = new Character[10][5]; + numberToCharMap[0] = new Character[]{'\0'}; + numberToCharMap[1] = new Character[]{'\0'}; + numberToCharMap[2] = new Character[]{'a', 'b', 'c'}; + numberToCharMap[3] = new Character[]{'d', 'e', 'f'}; + numberToCharMap[4] = new Character[]{'g', 'h', 'i'}; + numberToCharMap[5] = new Character[]{'j', 'k', 'l'}; + numberToCharMap[6] = new Character[]{'m', 'n', 'o'}; + numberToCharMap[7] = new Character[]{'p', 'q', 'r', 's'}; + numberToCharMap[8] = new Character[]{'t', 'u', 'v'}; + numberToCharMap[9] = new Character[]{'w', 'x', 'y', 'z'}; + } + +// Driver code + public static void main(String[] args) { + int number[] = {2, 3, 4}; + printWords(number); + } +} diff --git a/Strings/LongestPalindromicSubstring.java b/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java similarity index 88% rename from Strings/LongestPalindromicSubstring.java rename to src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java index 0016afb2bf25..3014745559e8 100644 --- a/Strings/LongestPalindromicSubstring.java +++ b/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java @@ -1,20 +1,24 @@ -package Strings; +package com.thealgorithms.strings; // Longest Palindromic Substring -import java.util.Scanner;; +import java.util.Scanner; + +; class LongestPalindromicSubstring { + public static void main(String[] args) { Solution s = new Solution(); String str = ""; Scanner sc = new Scanner(System.in); System.out.print("Enter the string: "); str = sc.nextLine(); - System.out.println("Longest substring is : "+s.longestPalindrome(str)); + System.out.println("Longest substring is : " + s.longestPalindrome(str)); } } class Solution { + public String longestPalindrome(String s) { if (s == null || s.length() == 0) { return ""; diff --git a/src/main/java/com/thealgorithms/strings/Lower.java b/src/main/java/com/thealgorithms/strings/Lower.java new file mode 100644 index 000000000000..ef3902b15df3 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/Lower.java @@ -0,0 +1,30 @@ +package com.thealgorithms.strings; + +public class Lower { + + /** + * Driver Code + */ + public static void main(String[] args) { + String[] strings = {"ABC", "ABC123", "abcABC", "abc123ABC"}; + for (String s : strings) { + assert toLowerCase(s).equals(s.toLowerCase()); + } + } + + /** + * Converts all of the characters in this {@code String} to lower case + * + * @param s the string to convert + * @return the {@code String}, converted to lowercase. + */ + public static String toLowerCase(String s) { + char[] values = s.toCharArray(); + for (int i = 0; i < values.length; ++i) { + if (Character.isLetter(values[i]) && Character.isUpperCase(values[i])) { + values[i] = Character.toLowerCase(values[i]); + } + } + return new String(values); + } +} diff --git a/src/main/java/com/thealgorithms/strings/Palindrome.java b/src/main/java/com/thealgorithms/strings/Palindrome.java new file mode 100644 index 000000000000..839a1a2aafca --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/Palindrome.java @@ -0,0 +1,71 @@ +package com.thealgorithms.strings; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Palindrome + */ +class Palindrome { + + /** + * Driver Code + */ + public static void main(String[] args) { + String[] palindromes = {null, "", "aba", "123321"}; + for (String s : palindromes) { + assert isPalindrome(s) && isPalindromeRecursion(s) && isPalindrome1(s); + } + + String[] notPalindromes = {"abb", "abc", "abc123"}; + for (String s : notPalindromes) { + assert !isPalindrome(s) && !isPalindromeRecursion(s) && !isPalindrome1(s); + } + } + + /** + * Check if a string is palindrome string or not + * + * @param s a string to check + * @return {@code true} if given string is palindrome, otherwise + * {@code false} + */ + public static boolean isPalindrome(String s) { + return (s == null || s.length() <= 1) || s.equals(new StringBuilder(s).reverse().toString()); + } + + /** + * Check if a string is palindrome string or not using recursion + * + * @param s a string to check + * @return {@code true} if given string is palindrome, otherwise + * {@code false} + */ + public static boolean isPalindromeRecursion(String s) { + if (s == null || s.length() <= 1) { + return true; + } + + if (s.charAt(0) != s.charAt(s.length() - 1)) { + return false; + } + + return isPalindrome(s.substring(1, s.length() - 1)); + } + + /** + * Check if a string is palindrome string or not another way + * + * @param s a string to check + * @return {@code true} if given string is palindrome, otherwise + * {@code false} + */ + public static boolean isPalindrome1(String s) { + if (s == null || s.length() <= 1) { + return true; + } + for (int i = 0, j = s.length() - 1; i < j; ++i, --j) { + if (s.charAt(i) != s.charAt(j)) { + return false; + } + } + return true; + } +} diff --git a/src/main/java/com/thealgorithms/strings/Pangram.java b/src/main/java/com/thealgorithms/strings/Pangram.java new file mode 100644 index 000000000000..cc9b2dd77790 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/Pangram.java @@ -0,0 +1,42 @@ +package com.thealgorithms.strings; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Pangram + */ +public class Pangram { + + /** + * Driver Code + */ + public static void main(String[] args) { + assert isPangram("The quick brown fox jumps over the lazy dog"); + assert !isPangram("The quick brown fox jumps over the azy dog"); + /* not exists l character */ + } + + /** + * Check if a string is a pangram string or not + * + * @param s string to check + * @return {@code true} if given string is pangram, otherwise {@code false} + */ + public static boolean isPangram(String s) { + boolean[] marked = new boolean[26]; + /* by default all letters don't exists */ + char[] values = s.toCharArray(); + for (char value : values) { + if (Character.isLetter(value)) { + int index = Character.isUpperCase(value) ? value - 'A' : value - 'a'; + marked[index] = true; + /* mark current character exists */ + } + } + + for (boolean b : marked) { + if (!b) { + return false; + } + } + return true; + } +} diff --git a/Strings/PermuteString.java b/src/main/java/com/thealgorithms/strings/PermuteString.java similarity index 57% rename from Strings/PermuteString.java rename to src/main/java/com/thealgorithms/strings/PermuteString.java index 29023447155e..1239ab3dbf28 100644 --- a/Strings/PermuteString.java +++ b/src/main/java/com/thealgorithms/strings/PermuteString.java @@ -1,3 +1,5 @@ +package com.thealgorithms.strings; + /* Backtracking algorithm used in the program:- @@ -8,43 +10,40 @@ >>Now swap again to go back to the previous position. E.g., from ABC, we formed ABC by fixing B again, and we backtrack to the previous position and swap B with C. So, now we got ABC and ACB. >>Repeat these steps for BAC and CBA, to get all the permutations. -*/ -public class PermuteString { + */ +public class PermuteString { + //Function for swapping the characters at position I with character at position j - public static String swapString(String a, int i, int j) { - char[] b =a.toCharArray(); - char ch; - ch = b[i]; - b[i] = b[j]; - b[j] = ch; - return String.valueOf(b); - } - - public static void main(String[] args) - { - String str = "ABC"; - int len = str.length(); - System.out.println("All the permutations of the string are: "); - generatePermutation(str, 0, len); - } - + public static String swapString(String a, int i, int j) { + char[] b = a.toCharArray(); + char ch; + ch = b[i]; + b[i] = b[j]; + b[j] = ch; + return String.valueOf(b); + } + + public static void main(String[] args) { + String str = "ABC"; + int len = str.length(); + System.out.println("All the permutations of the string are: "); + generatePermutation(str, 0, len); + } + //Function for generating different permutations of the string - public static void generatePermutation(String str, int start, int end) - { + public static void generatePermutation(String str, int start, int end) { //Prints the permutations - if (start == end-1) - System.out.println(str); - else - { - for (int i = start; i < end; i++) - { + if (start == end - 1) { + System.out.println(str); + } else { + for (int i = start; i < end; i++) { //Swapping the string by fixing a character - str = swapString(str,start,i); + str = swapString(str, start, i); //Recursively calling function generatePermutation() for rest of the characters - generatePermutation(str,start+1,end); + generatePermutation(str, start + 1, end); //Backtracking and swapping the characters again. - str = swapString(str,start,i); - } - } - } -} \ No newline at end of file + str = swapString(str, start, i); + } + } + } +} diff --git a/src/main/java/com/thealgorithms/strings/ReverseString.java b/src/main/java/com/thealgorithms/strings/ReverseString.java new file mode 100644 index 000000000000..155316f62ae5 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/ReverseString.java @@ -0,0 +1,43 @@ +package com.thealgorithms.strings; + +/** + * Reverse String using different version + */ +public class ReverseString { + + public static void main(String[] args) { + assert reverse("abc123").equals("321cba"); + assert reverse2("abc123").equals("321cba"); + } + + /** + * easiest way to reverses the string str and returns it + * + * @param str string to be reversed + * @return reversed string + */ + public static String reverse(String str) { + return new StringBuilder(str).reverse().toString(); + } + + /** + * second way to reverses the string str and returns it + * + * @param str string to be reversed + * @return reversed string + */ + public static String reverse2(String str) { + + if (str == null || str.isEmpty()) { + return str; + } + + char[] value = str.toCharArray(); + for (int i = 0, j = str.length() - 1; i < j; i++, j--) { + char temp = value[i]; + value[i] = value[j]; + value[j] = temp; + } + return new String(value); + } +} diff --git a/src/main/java/com/thealgorithms/strings/Rotation.java b/src/main/java/com/thealgorithms/strings/Rotation.java new file mode 100644 index 000000000000..c82ae5c32758 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/Rotation.java @@ -0,0 +1,60 @@ +package com.thealgorithms.strings; + +/** + * Given a string, moving several characters in front of the string to the end + * of the string. For example, move the two characters'a' and 'b' in front of + * the string "abcdef" to the end of the string, so that the original string + * becomes the string "cdefab" + */ +public class Rotation { + + public static void main(String[] args) { + assert rotation("abcdef", 2).equals("cdefab"); + + char[] values = "abcdef".toCharArray(); + rotation(values, 2); + assert new String(values).equals("cdefab"); + } + + /** + * Move {@code n} characters in front of given string to the end of string + * time complexity: O(n) space complexity: O(n) + * + * @param s given string + * @param n the total characters to be moved + * @return string after rotation + */ + public static String rotation(String s, int n) { + return s.substring(n) + s.substring(0, n); + } + + /** + * Move {@code n} characters in front of given character array to the end of + * array time complexity: O(n) space complexity: O(1) + * + * @param values given character array + * @param n the total characters to be moved + */ + public static void rotation(char[] values, int n) { + reverse(values, 0, n - 1); + reverse(values, n, values.length - 1); + reverse(values, 0, values.length - 1); + } + + /** + * Reverse character array + * + * @param values character array + * @param from begin index of given array + * @param to end index of given array + */ + public static void reverse(char[] values, int from, int to) { + while (from < to) { + char temp = values[from]; + values[from] = values[to]; + values[to] = temp; + from++; + to--; + } + } +} diff --git a/src/main/java/com/thealgorithms/strings/Upper.java b/src/main/java/com/thealgorithms/strings/Upper.java new file mode 100644 index 000000000000..102d3a190a72 --- /dev/null +++ b/src/main/java/com/thealgorithms/strings/Upper.java @@ -0,0 +1,30 @@ +package com.thealgorithms.strings; + +public class Upper { + + /** + * Driver Code + */ + public static void main(String[] args) { + String[] strings = {"ABC", "ABC123", "abcABC", "abc123ABC"}; + for (String s : strings) { + assert toUpperCase(s).equals(s.toUpperCase()); + } + } + + /** + * Converts all of the characters in this {@code String} to upper case + * + * @param s the string to convert + * @return the {@code String}, converted to uppercase. + */ + public static String toUpperCase(String s) { + char[] values = s.toCharArray(); + for (int i = 0; i < values.length; ++i) { + if (Character.isLetter(values[i]) && Character.isLowerCase(values[i])) { + values[i] = Character.toUpperCase(values[i]); + } + } + return new String(values); + } +} diff --git a/Strings/WordLadder.java b/src/main/java/com/thealgorithms/strings/WordLadder.java similarity index 73% rename from Strings/WordLadder.java rename to src/main/java/com/thealgorithms/strings/WordLadder.java index 5ce9280b45df..c98f26efd7df 100644 --- a/Strings/WordLadder.java +++ b/src/main/java/com/thealgorithms/strings/WordLadder.java @@ -1,4 +1,4 @@ -package Strings; +package com.thealgorithms.strings; import java.util.List; import java.util.Arrays; @@ -33,55 +33,63 @@ beginWord, endWord, and wordList[i] consist of lowercase English letters. beginWord != endWord All the words in wordList are unique. -*/ - + */ class WordLadder { - /** Driver Code */ - public static void main(String []args){ + /** + * Driver Code + */ + public static void main(String[] args) { String beginWord = "hit"; String endWord = "cog"; - String words[] = {"hot","dot","dog","lot","log","cog"}; + String words[] = {"hot", "dot", "dog", "lot", "log", "cog"}; List wordList = Arrays.asList(words); - System.out.println("Ladder Length: " + ladderLength(beginWord,endWord,wordList)); + System.out.println("Ladder Length: " + ladderLength(beginWord, endWord, wordList)); } /** * This function finds the ladderLength - * @param beginWord: Starting word of the ladder + * + * @param beginWord: Starting word of the ladder * @param endWord: Ending word of the ladder - * @param wordList: This list contains the words which needs to be included in ladder. - * @return ladderLength: This function will return the ladderLength(level) if the endword is there. - * Otherwise, will return the length as 0. + * @param wordList: This list contains the words which needs to be included + * in ladder. + * @return ladderLength: This function will return the ladderLength(level) + * if the endword is there. Otherwise, will return the length as 0. */ - public static int ladderLength(String beginWord, String endWord, List wordList) { HashSet set = new HashSet(); - for(String word : wordList){ + for (String word : wordList) { set.add(word); } - - if(!set.contains(endWord)) return 0; - + + if (!set.contains(endWord)) { + return 0; + } + Queue queue = new LinkedList(); queue.offer(beginWord); int level = 1; - - while(!queue.isEmpty()){ + + while (!queue.isEmpty()) { int size = queue.size(); - for(int i = 0; i < size; i++){ + for (int i = 0; i < size; i++) { String curr = queue.poll(); char[] words_chars = curr.toCharArray(); - for(int j = 0; j < words_chars.length; j++){ + for (int j = 0; j < words_chars.length; j++) { char original_chars = words_chars[j]; - for(char c = 'a'; c <= 'z'; c++){ - if(words_chars[j] == c) continue; + for (char c = 'a'; c <= 'z'; c++) { + if (words_chars[j] == c) { + continue; + } words_chars[j] = c; String new_word = String.valueOf(words_chars); - if(new_word.equals(endWord)) return level+1; - if(set.contains(new_word)){ + if (new_word.equals(endWord)) { + return level + 1; + } + if (set.contains(new_word)) { set.remove(new_word); queue.offer(new_word); } @@ -93,4 +101,4 @@ public static int ladderLength(String beginWord, String endWord, List wo } return 0; } -} \ No newline at end of file +}