diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 7b319b78d4d7..bcea8e797ffb 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,8 +1,8 @@ # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java/.devcontainer/base.Dockerfile # [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster -ARG VARIANT="17-bullseye" -FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT} +ARG VARIANT="21-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/java:1.1.0-${VARIANT} # [Option] Install Maven ARG INSTALL_MAVEN="false" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 3994bec79ef8..fdc7cdbd25f9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,7 @@ // Update the VARIANT arg to pick a Java version: 11, 17 // Append -bullseye or -buster to pin to an OS version. // Use the -bullseye variants on local arm64/Apple Silicon. - "VARIANT": "17-bullseye", + "VARIANT": "21-bullseye", // Options "INSTALL_MAVEN": "true", "INSTALL_GRADLE": "true", diff --git a/.github/dependabot.yml b/.github/dependabot.yml index e568006bd634..2e5622f7b51d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,4 +10,9 @@ updates: directory: "/.github/workflows/" schedule: interval: "daily" + + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "daily" ... diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e725dfa74904..14a4ce5fe0f5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,14 +1,37 @@ name: Build on: [push, pull_request] + jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: 'adopt' - name: Build with Maven run: mvn --batch-mode --update-snapshots verify + - name: Upload coverage to codecov (tokenless) + if: >- + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name != github.repository + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: true + - name: Upload coverage to codecov (with token) + if: > + github.repository == 'TheAlgorithms/Java' && + (github.event_name != 'pull_request' || + github.event.pull_request.head.repo.full_name == github.repository) + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + - name: Checkstyle + run: mvn checkstyle:check + - name: SpotBugs + run: mvn spotbugs:check + - name: PMD + run: mvn pmd:check diff --git a/.github/workflows/clang-format-lint.yml b/.github/workflows/clang-format-lint.yml index 90c0550dc31b..7f3cb3d5162f 100644 --- a/.github/workflows/clang-format-lint.yml +++ b/.github/workflows/clang-format-lint.yml @@ -9,7 +9,7 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: DoozyX/clang-format-lint-action@v0.16.2 + - uses: DoozyX/clang-format-lint-action@v0.17 with: source: './src' extensions: 'java' diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f447eb954550..ff76b1af452a 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -26,10 +26,10 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK uses: actions/setup-java@v4 with: - java-version: 17 + java-version: 21 distribution: 'adopt' - name: Initialize CodeQL diff --git a/.gitpod.dockerfile b/.gitpod.dockerfile index e10a44af6132..82696623f953 100644 --- a/.gitpod.dockerfile +++ b/.gitpod.dockerfile @@ -1,4 +1,4 @@ -FROM gitpod/workspace-java-17:2023-08-30-14-07-38 +FROM gitpod/workspace-java-21:2024-06-03-17-43-12 ENV LLVM_SCRIPT="tmp_llvm.sh" @@ -11,7 +11,7 @@ USER root RUN ./"$LLVM_SCRIPT" 16 \ && apt-get update \ && apt-get install -y --no-install-recommends \ - clang-format-16=1:16.0.6~++20230710042027+7cbf1a259152-1~exp1~20230710162048.105 \ + clang-format-16=1:16.0.6~++20231112100510+7cbf1a259152-1~exp1~20231112100554.106 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/DIRECTORY.md b/DIRECTORY.md index a75b521341fc..c8b38bb20343 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -15,6 +15,7 @@ * [MazeRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java) * [MColoring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MColoring.java) * [NQueens](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/NQueens.java) + * [ParenthesesGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java) * [Permutation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Permutation.java) * [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java) * [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java) @@ -388,7 +389,7 @@ * [PalindromeSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java) * [RangeInSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java) * [Sort012D](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sort012D.java) - * [Sparcity](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sparcity.java) + * [Sparsity](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sparsity.java) * [ThreeSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java) * [TwoSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/TwoSumProblem.java) * [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/WordBoggle.java) @@ -438,12 +439,11 @@ * [ReturnSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReturnSubsequence.java) * [ReverseStackUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) * [RootPrecision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RootPrecision.java) - * [RotateMatriceBy90Degree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java) + * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java) * [SieveOfEratosthenes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java) * [SkylineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SkylineProblem.java) * [StringMatchFiniteAutomata](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java) * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Sudoku.java) - * [TopKWords](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TopKWords.java) * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TowerOfHanoi.java) * [TwoPointers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TwoPointers.java) * [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java) @@ -577,6 +577,7 @@ * [FloodFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/FloodFillTest.java) * [MazeRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java) * [MColoringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/MColoringTest.java) + * [ParenthesesGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java) * [PermutationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PermutationTest.java) * [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java) * [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java) @@ -688,6 +689,7 @@ * [KnapsackMemoizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java) * [KnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java) * [LevenshteinDistanceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java) + * [LongestIncreasingSubsequenceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java) * [MinimumPathSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java) * [MinimumSumPartitionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java) * [OptimalJobSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java) @@ -728,6 +730,7 @@ * [DigitalRootTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DigitalRootTest.java) * [DistanceFormulaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java) * [DudeneyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java) + * [FactorialRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java) * [FactorialTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialTest.java) * [FastInverseSqrtTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java) * [FFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FFTTest.java) @@ -760,7 +763,9 @@ * [MillerRabinPrimalityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java) * [MinValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MinValueTest.java) * [MobiusFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java) + * [ModeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ModeTest.java) * [NthUglyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java) + * [NumberOfDigitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java) * [PalindromeNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java) * [ParseIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java) * [PascalTriangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java) @@ -851,6 +856,7 @@ * [BogoSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BogoSortTest.java) * [BubbleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java) * [BucketSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BucketSortTest.java) + * [CircleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CircleSortTest.java) * [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java) * [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java) * [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java) diff --git a/Java/.clang-format b/Java/.clang-format new file mode 100644 index 000000000000..3d685994a1aa --- /dev/null +++ b/Java/.clang-format @@ -0,0 +1,136 @@ +--- +Language: Java +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: false +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: MultiLine +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 300 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +InsertNewlineAtEOF: true +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: Inner +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... diff --git a/Java/.devcontainer/Dockerfile b/Java/.devcontainer/Dockerfile new file mode 100644 index 000000000000..bcea8e797ffb --- /dev/null +++ b/Java/.devcontainer/Dockerfile @@ -0,0 +1,25 @@ +# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java/.devcontainer/base.Dockerfile + +# [Choice] Java version (use -bullseye variants on local arm64/Apple Silicon): 11, 17, 11-bullseye, 17-bullseye, 11-buster, 17-buster +ARG VARIANT="21-bullseye" +FROM mcr.microsoft.com/vscode/devcontainers/java:1.1.0-${VARIANT} + +# [Option] Install Maven +ARG INSTALL_MAVEN="false" +ARG MAVEN_VERSION="" +# [Option] Install Gradle +ARG INSTALL_GRADLE="false" +ARG GRADLE_VERSION="" +RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \ + && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi + +# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10 +ARG NODE_VERSION="none" +RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi + +# [Optional] Uncomment this section to install additional OS packages. +# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ +# && apt-get -y install --no-install-recommends + +# [Optional] Uncomment this line to install global node packages. +# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g " 2>&1 \ No newline at end of file diff --git a/Java/.devcontainer/devcontainer.json b/Java/.devcontainer/devcontainer.json new file mode 100644 index 000000000000..fdc7cdbd25f9 --- /dev/null +++ b/Java/.devcontainer/devcontainer.json @@ -0,0 +1,47 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.238.0/containers/java +{ + "name": "Java", + "build": { + "dockerfile": "Dockerfile", + "args": { + // Update the VARIANT arg to pick a Java version: 11, 17 + // Append -bullseye or -buster to pin to an OS version. + // Use the -bullseye variants on local arm64/Apple Silicon. + "VARIANT": "21-bullseye", + // Options + "INSTALL_MAVEN": "true", + "INSTALL_GRADLE": "true", + "NODE_VERSION": "lts/*" + } + }, + + // Configure tool-specific properties. + "customizations": { + // Configure properties specific to VS Code. + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + }, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "vscjava.vscode-java-pack", + "GitHub.copilot", + ] + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "java -version", + + // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. + "remoteUser": "vscode", + "features": { + "git": "os-provided", + "github-cli": "latest" + } +} diff --git a/Java/.github/CODEOWNERS b/Java/.github/CODEOWNERS new file mode 100644 index 000000000000..a84f13be1047 --- /dev/null +++ b/Java/.github/CODEOWNERS @@ -0,0 +1 @@ +* @yanglbme @vil02 @BamaCharanChhandogi diff --git a/Java/.github/ISSUE_TEMPLATE/bug_report.yml b/Java/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000000..9c906c381608 --- /dev/null +++ b/Java/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,45 @@ +name: "Bug report" +description: "Create a report to help us improve" +title: "[BUG] " +labels: ["bug"] +body: + - type: textarea + id: description + attributes: + label: "Description" + description: "A clear and concise description of what the bug is." + validations: + required: true + - type: textarea + id: steps + attributes: + label: "Steps to reproduce" + description: "Steps to reproduce the behavior (if applicable)" + placeholder: | + 1. Go to '...' + 2. Click on '....' + 3. Scroll down to '....' + 4. See error + validations: + required: false + - type: textarea + id: exceptedbhv + attributes: + label: "Excepted behavior" + description: "A clear and concise description of what you expected to happen." + validations: + required: true + - type: textarea + id: screenshots + attributes: + label: "Screenshots" + description: "If applicable, add screenshots to help explain your problem." + validations: + required: false + - type: textarea + id: context + attributes: + label: "Additional context" + description: "Is there anything else we should know about this bug report?" + validations: + required: false diff --git a/Java/.github/ISSUE_TEMPLATE/config.yml b/Java/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000000..875cc4efab00 --- /dev/null +++ b/Java/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Discord community + url: https://the-algorithms.com/discord/ + about: Have any questions or found any bugs? Please contact us via Discord diff --git a/Java/.github/ISSUE_TEMPLATE/feature_request.yml b/Java/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000000..98ff394158be --- /dev/null +++ b/Java/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,34 @@ +name: "Feature Request" +description: "Suggest an idea for this project" +title: "[FEATURE REQUEST] <title>" +labels: ["enhancement"] +body: + - type: textarea + id: description + attributes: + label: What would you like to Propose? + description: Provide a clear and concise explanation of your Proposal. + validations: + required: true + - type: markdown + attributes: + value: | + For new implementations, please specify the name and problem statement for the algorithm. + For algorithm enhancements, specify what needs to be changed and why. For example: + - Adding tests. + - Optimizing logic. + - Refactoring the file and folders for better structure. + - type: textarea + id: needdetails + attributes: + label: "Issue details" + description: "Write down all the issue/algorithm details description mentioned above." + validations: + required: true + - type: textarea + id: extrainfo + attributes: + label: "Additional Information" + description: "Add any other information or screenshots about the request here." + validations: + required: false diff --git a/Java/.github/ISSUE_TEMPLATE/other.yml b/Java/.github/ISSUE_TEMPLATE/other.yml new file mode 100644 index 000000000000..bf8b29f481c8 --- /dev/null +++ b/Java/.github/ISSUE_TEMPLATE/other.yml @@ -0,0 +1,19 @@ +name: Other +description: Use this for any other issues. Do NOT create blank issues +title: "[OTHER]" +labels: ["awaiting triage"] +body: + - type: textarea + id: issuedescription + attributes: + label: What would you like to share? + description: Provide a clear and concise explanation of your issue. + validations: + required: true + - type: textarea + id: extrainfo + attributes: + label: Additional information + description: Is there anything else we should know about this issue? + validations: + required: false diff --git a/Java/.github/dependabot.yml b/Java/.github/dependabot.yml new file mode 100644 index 000000000000..2e5622f7b51d --- /dev/null +++ b/Java/.github/dependabot.yml @@ -0,0 +1,18 @@ +--- +version: 2 +updates: + - package-ecosystem: "docker" + directory: "/" + schedule: + interval: "weekly" + + - package-ecosystem: "github-actions" + directory: "/.github/workflows/" + schedule: + interval: "daily" + + - package-ecosystem: "maven" + directory: "/" + schedule: + interval: "daily" +... diff --git a/Java/.github/pull_request_template.md b/Java/.github/pull_request_template.md new file mode 100644 index 000000000000..d9cc4c3c35c5 --- /dev/null +++ b/Java/.github/pull_request_template.md @@ -0,0 +1,16 @@ +<!-- +Thank you for your contribution! +In order to reduce the number of notifications sent to the maintainers, please: +- create your PR as draft, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests#draft-pull-requests, +- make sure that all of the CI checks pass, +- mark your PR as ready for review, cf. https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review +--> + +<!-- For completed items, change [ ] to [x] --> + +- [ ] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md). +- [ ] This pull request is all my own work -- I have not plagiarized it. +- [ ] All filenames are in PascalCase. +- [ ] All functions and variable names follow Java naming conventions. +- [ ] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations. +- [ ] All new code is formatted with `clang-format -i --style=file path/to/your/file.java` \ No newline at end of file diff --git a/Java/.github/workflows/build.yml b/Java/.github/workflows/build.yml new file mode 100644 index 000000000000..14a4ce5fe0f5 --- /dev/null +++ b/Java/.github/workflows/build.yml @@ -0,0 +1,37 @@ +name: Build +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: 'adopt' + - name: Build with Maven + run: mvn --batch-mode --update-snapshots verify + - name: Upload coverage to codecov (tokenless) + if: >- + github.event_name == 'pull_request' && + github.event.pull_request.head.repo.full_name != github.repository + uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: true + - name: Upload coverage to codecov (with token) + if: > + github.repository == 'TheAlgorithms/Java' && + (github.event_name != 'pull_request' || + github.event.pull_request.head.repo.full_name == github.repository) + uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + - name: Checkstyle + run: mvn checkstyle:check + - name: SpotBugs + run: mvn spotbugs:check + - name: PMD + run: mvn pmd:check diff --git a/Java/.github/workflows/clang-format-lint.yml b/Java/.github/workflows/clang-format-lint.yml new file mode 100644 index 000000000000..7f3cb3d5162f --- /dev/null +++ b/Java/.github/workflows/clang-format-lint.yml @@ -0,0 +1,16 @@ +name: Clang format linter +on: + push: {} + pull_request: {} + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: DoozyX/clang-format-lint-action@v0.17 + with: + source: './src' + extensions: 'java' + clangFormatVersion: 16 diff --git a/Java/.github/workflows/codeql.yml b/Java/.github/workflows/codeql.yml new file mode 100644 index 000000000000..ff76b1af452a --- /dev/null +++ b/Java/.github/workflows/codeql.yml @@ -0,0 +1,47 @@ +--- +name: "CodeQL" + +on: + workflow_dispatch: + push: + branches: + - master + pull_request: + schedule: + - cron: '53 3 * * 0' + +env: + LANGUAGE: 'java-kotlin' + +jobs: + analyze: + name: Analyze + runs-on: 'ubuntu-latest' + permissions: + actions: read + contents: read + security-events: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: 21 + distribution: 'adopt' + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ env.LANGUAGE }} + + - name: Build + run: mvn --batch-mode --update-snapshots verify + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{env.LANGUAGE}}" +... diff --git a/Java/.github/workflows/stale.yml b/Java/.github/workflows/stale.yml new file mode 100644 index 000000000000..6fb47c5d2dc9 --- /dev/null +++ b/Java/.github/workflows/stale.yml @@ -0,0 +1,18 @@ +name: 'Close stale issues and PRs' +on: + schedule: + - cron: '0 0 * * *' +jobs: + stale: + runs-on: ubuntu-latest + steps: + - uses: actions/stale@v9 + with: + stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!' + close-issue-message: 'Please reopen this issue once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!' + stale-pr-message: 'This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution!' + close-pr-message: 'Please reopen this pull request once you have made the required changes. If you need help, feel free to ask in our [Discord](https://the-algorithms.com/discord) server or ping one of the maintainers here. Thank you for your contribution!' + exempt-issue-labels: 'dont-close' + exempt-pr-labels: 'dont-close' + days-before-stale: 30 + days-before-close: 7 diff --git a/Java/.github/workflows/update_directory.yml b/Java/.github/workflows/update_directory.yml new file mode 100644 index 000000000000..c811d244e54b --- /dev/null +++ b/Java/.github/workflows/update_directory.yml @@ -0,0 +1,92 @@ +# This GitHub Action updates the DIRECTORY.md file (if needed) when doing a git push or pull_request +name: Update Directory +permissions: + contents: write +on: + push: + paths: + - 'src/**' + pull_request: + paths: + - 'src/**' + workflow_dispatch: + inputs: + logLevel: + description: 'Log level' + required: true + default: 'info' + type: choice + options: + - info + - warning + - debug +jobs: + update_directory_md: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Update Directory + shell: python + run: | + import os + from typing import Iterator + + URL_BASE = "https://github.com/TheAlgorithms/Java/blob/master" + g_output = [] + + + def good_filepaths(top_dir: str = ".") -> Iterator[str]: + for dirpath, dirnames, filenames in os.walk(top_dir): + dirnames[:] = [d for d in dirnames if d[0] not in "._"] + for filename in filenames: + if os.path.splitext(filename)[1].lower() == ".java": + yield os.path.join(dirpath, filename).lstrip("./") + + + def md_prefix(i): + return f"{i * ' '}*" if i else "\n##" + + + def print_path(old_path: str, new_path: str) -> str: + global g_output + old_parts = old_path.split(os.sep) + mid_diff = False + new_parts = new_path.split(os.sep) + for i, new_part in enumerate(new_parts): + if i + 1 > len(old_parts) or old_parts[i] != new_part or mid_diff: + if i + 1 < len(new_parts): + mid_diff = True + if new_part: + g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ')}") + return new_path + + + def build_directory_md(top_dir: str = ".") -> str: + global g_output + old_path = "" + for filepath in sorted(good_filepaths(top_dir), key=str.lower): + filepath, filename = os.path.split(filepath) + if filepath != old_path: + old_path = print_path(old_path, filepath) + indent = (filepath.count(os.sep) + 1) if filepath else 0 + url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20") + filename = os.path.splitext(filename.replace("_", " "))[0] + g_output.append(f"{md_prefix(indent)} [{filename}]({url})") + return "\n".join(g_output) + + + with open("DIRECTORY.md", "w") as out_file: + out_file.write(build_directory_md(".") + "\n") + + - name: Update DIRECTORY.md + run: | + cat DIRECTORY.md + git config --global user.name "$GITHUB_ACTOR" + git config --global user.email "$GITHUB_ACTOR@users.noreply.github.com" + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git add DIRECTORY.md + git commit -am "Update directory" || true + git push --force origin HEAD:$GITHUB_REF || true diff --git a/Java/.gitignore b/Java/.gitignore new file mode 100644 index 000000000000..bd1d54c0900a --- /dev/null +++ b/Java/.gitignore @@ -0,0 +1,44 @@ +/gradle/wrapper/gradle-wrapper.properties + +##----------Android---------- +*.apk +*.ap_ +*.dex +*.class +bin/ +gen/ +build/ +out/ + +# Ignoring Gradle build artifacts and project files +##----------Gradle---------- +.gradle/ +gradle-app.setting +!gradle-wrapper.jar +build/ + +# Ignoring Maven build artifacts and project files +##----------Maven---------- +*.classpath +*.project +*.settings +/target/ +local.properties + +# Ignoring IntelliJ IDEA project files and configurations +##----------IDEA---------- +*.iml +.idea/ +*.ipr +*.iws + +# Ignoring Android Studio Navigation editor temporary files +.navigation/ + +# Ignoring common system and editor-generated files +##----------Other---------- +*~ +.DS_Store +gradle.properties +.vscode +*.log diff --git a/Java/.gitpod.dockerfile b/Java/.gitpod.dockerfile new file mode 100644 index 000000000000..82696623f953 --- /dev/null +++ b/Java/.gitpod.dockerfile @@ -0,0 +1,22 @@ +FROM gitpod/workspace-java-21:2024-06-03-17-43-12 + +ENV LLVM_SCRIPT="tmp_llvm.sh" + +RUN test ! -f "$LLVM_SCRIPT" \ + && wget https://apt.llvm.org/llvm.sh -O "$LLVM_SCRIPT" \ + && chmod +x "$LLVM_SCRIPT" + +USER root + +RUN ./"$LLVM_SCRIPT" 16 \ + && apt-get update \ + && apt-get install -y --no-install-recommends \ + clang-format-16=1:16.0.6~++20231112100510+7cbf1a259152-1~exp1~20231112100554.106 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +RUN ln -s "$(command -v clang-format-16)" "/usr/bin/clang-format" + +USER gitpod + +RUN rm "$LLVM_SCRIPT" diff --git a/Java/.gitpod.yml b/Java/.gitpod.yml new file mode 100644 index 000000000000..21d69f6e2122 --- /dev/null +++ b/Java/.gitpod.yml @@ -0,0 +1,13 @@ +--- +image: + file: .gitpod.dockerfile + +tasks: + - init: | + mvn dependency:resolve + mvn compile + +vscode: + extensions: + - xaver.clang-format + diff --git a/Java/CONTRIBUTING.md b/Java/CONTRIBUTING.md new file mode 100644 index 000000000000..f2f8dd9ffdea --- /dev/null +++ b/Java/CONTRIBUTING.md @@ -0,0 +1,31 @@ +## How to contribute? + +NOTE: *We DO NOT add leetcode problems. They are just applications of basic principles that can be found in other algorithms included in the repository.* + +### Did you find a bug? + +**Ensure the bug was not already reported** by searching on GitHub under [Project Issues](https://github.com/TheAlgorithms/Java/issues). + - If it is mentioned in the issues and you want to fix it, [fork](https://github.com/TheAlgorithms/Java/fork) the repository and submit your implementation in a pull request. The project maintainers will evaluate it. + - If the bug is **NOT** mentioned in the issues, [open a new issue](https://github.com/TheAlgorithms/Java/issues/new). Be sure to include a **title**, a clear **description** and a **test case** demonstrating the expected behavior that is not occurring. + +NOTE: *Please avoid opening issues asking to be "assigned" to a particular algorithm. This merely creates unnecessary noise for maintainers. Instead, please submit your implementation in a pull request and project maintainers will evaluate it.* + + + +### Do you want to contribute to the documentation? + - [Fork](https://github.com/TheAlgorithms/Java/fork) the repository and make necessary changes. + - Create a pull request. + - It will be put under review for approval. + - If approved, the requested changes will be merged to the repository. + +### Do you want to add a new feature? + +- [Open a new issue](https://github.com/TheAlgorithms/Java/issues/new). +- Be sure to include a **title**, a clear **description** and a **test case** demonstrating the new feature you want to add to the project. + + +### Do you have questions about the source code? + +- Ask any question about how to use the repository in the [TheAlgorithms room in GITTER](https://gitter.im/TheAlgorithms/community?source=orgpage#) or [open a new issue](https://github.com/TheAlgorithms/Java/issues/new) + +:+1::tada: That's all you need to know about the process now it's your turn to help us improve the repository, thank you again! :+1::tada: \ No newline at end of file diff --git a/Java/DIRECTORY.md b/Java/DIRECTORY.md new file mode 100644 index 000000000000..c8b38bb20343 --- /dev/null +++ b/Java/DIRECTORY.md @@ -0,0 +1,913 @@ + +## src + * main + * java + * com + * thealgorithms + * audiofilters + * [IIRFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java) + * backtracking + * [AllPathsFromSourceToTarget](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java) + * [ArrayCombination](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java) + * [Combination](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Combination.java) + * [FloodFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/FloodFill.java) + * [KnightsTour](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/KnightsTour.java) + * [MazeRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java) + * [MColoring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/MColoring.java) + * [NQueens](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/NQueens.java) + * [ParenthesesGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java) + * [Permutation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/Permutation.java) + * [PowerSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/PowerSum.java) + * [WordSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/backtracking/WordSearch.java) + * bitmanipulation + * [BitSwap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java) + * [HighestSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java) + * [IndexOfRightMostSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java) + * [IsEven](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java) + * [IsPowerTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java) + * [NonRepeatingNumberFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java) + * [NumbersDifferentSigns](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java) + * [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java) + * [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java) + * ciphers + * a5 + * [A5Cipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java) + * [A5KeyStreamGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java) + * [BaseLFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java) + * [CompositeLFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java) + * [LFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java) + * [Utils](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/Utils.java) + * [AES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AES.java) + * [AESEncryption](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AESEncryption.java) + * [AffineCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AffineCipher.java) + * [Blowfish](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Blowfish.java) + * [Caesar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Caesar.java) + * [ColumnarTranspositionCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java) + * [DES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/DES.java) + * [HillCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/HillCipher.java) + * [PlayfairCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java) + * [Polybius](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Polybius.java) + * [ProductCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ProductCipher.java) + * [RSA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/RSA.java) + * [SimpleSubCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java) + * [Vigenere](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/Vigenere.java) + * conversions + * [AnyBaseToAnyBase](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java) + * [AnyBaseToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java) + * [AnytoAny](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/AnytoAny.java) + * [BinaryToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java) + * [BinaryToHexadecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java) + * [BinaryToOctal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java) + * [DecimalToAnyBase](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java) + * [DecimalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java) + * [DecimalToHexaDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java) + * [DecimalToOctal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java) + * [HexaDecimalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java) + * [HexaDecimalToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java) + * [HexToOct](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/HexToOct.java) + * [IntegerToRoman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java) + * [OctalToBinary](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToBinary.java) + * [OctalToDecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java) + * [OctalToHexadecimal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java) + * [RgbHsvConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java) + * [RomanToInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/RomanToInteger.java) + * [TurkishToLatinConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java) + * datastructures + * bags + * [Bag](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/bags/Bag.java) + * bloomfilter + * [BloomFilter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java) + * buffers + * [CircularBuffer](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java) + * caches + * [LFUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java) + * [LRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java) + * [MRUCache](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java) + * crdt + * [GCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java) + * [GSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java) + * [LWWElementSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java) + * [ORSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java) + * [PNCounter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java) + * [TwoPSet](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java) + * disjointsetunion + * [DisjointSetUnion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java) + * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java) + * dynamicarray + * [DynamicArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java) + * graphs + * [A Star](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java) + * [BellmanFord](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java) + * [BipartiteGrapfDFS](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java) + * [BoruvkaAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java) + * [ConnectedComponent](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java) + * [Cycles](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java) + * [DIJSKSTRAS ALGORITHM](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java) + * [FloydWarshall](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java) + * [Graphs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java) + * [HamiltonianCycle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java) + * [KahnsAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java) + * [Kosaraju](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java) + * [Kruskal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java) + * [MatrixGraphs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java) + * [PrimMST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java) + * [TarjansAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java) + * [WelshPowell](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java) + * hashmap + * hashing + * [GenericHashMapUsingArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java) + * [GenericHashMapUsingArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java) + * [HashMap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java) + * [HashMapCuckooHashing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java) + * [Intersection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java) + * [LinearProbingHashMap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java) + * [Main](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java) + * [MainCuckooHashing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java) + * [MajorityElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java) + * [Map](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java) + * heaps + * [EmptyHeapException](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java) + * [FibonacciHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java) + * [GenericHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java) + * [Heap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java) + * [HeapElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java) + * [LeftistHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java) + * [MaxHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java) + * [MinHeap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java) + * [MinPriorityQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java) + * lists + * [CircleLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java) + * [CountSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java) + * [CreateAndDetectLoop](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java) + * [CursorLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java) + * [DoublyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java) + * [Merge K SortedLinkedlist](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java) + * [MergeSortedArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java) + * [MergeSortedSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java) + * [QuickSortLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java) + * [RandomNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java) + * [ReverseKGroup](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java) + * [RotateSinglyLinkedLists](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java) + * [SearchSinglyLinkedListRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java) + * [SinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java) + * [SkipList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java) + * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/Node.java) + * queues + * [CircularQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java) + * [Deques](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/Deques.java) + * [GenericArrayListQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java) + * [LinkedQueue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java) + * [PriorityQueues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java) + * [Queues](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/queues/Queues.java) + * stacks + * [NodeStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java) + * [ReverseStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java) + * [StackArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java) + * [StackArrayList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java) + * [StackOfLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java) + * trees + * [AVLSimple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java) + * [AVLTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java) + * [BinaryTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java) + * [BSTFromSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java) + * [BSTIterative](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java) + * [BSTRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java) + * [BSTRecursiveGeneric](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java) + * [CeilInBinarySearchTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java) + * [CheckBinaryTreeIsValidBST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java) + * [CheckIfBinaryTreeBalanced](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java) + * [CheckTreeIsSymmetric](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java) + * [CreateBinaryTreeFromInorderPreorder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java) + * [FenwickTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java) + * [GenericTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java) + * [InorderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java) + * [KDTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java) + * [LazySegmentTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java) + * [LCA](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/LCA.java) + * [LevelOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java) + * [nearestRightKey](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java) + * [PostOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java) + * [PreOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java) + * [PrintTopViewofTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java) + * [RedBlackBST](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java) + * [SameTreesCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java) + * [SegmentTree](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java) + * [TreeRandomNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java) + * [TrieImp](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java) + * [VerticalOrderTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java) + * [ZigzagTraversal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java) + * devutils + * entities + * [ProcessDetails](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java) + * nodes + * [LargeTreeNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java) + * [Node](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/Node.java) + * [SimpleNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java) + * [SimpleTreeNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java) + * [TreeNode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java) + * searches + * [MatrixSearchAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java) + * [SearchAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java) + * divideandconquer + * [BinaryExponentiation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java) + * [ClosestPair](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java) + * [SkylineAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java) + * [StrassenMatrixMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java) + * dynamicprogramming + * [BoardPath](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java) + * [BoundaryFill](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java) + * [BruteForceKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java) + * [CatalanNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java) + * [ClimbingStairs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java) + * [CoinChange](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java) + * [CountFriendsPairing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java) + * [DiceThrow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java) + * [EditDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java) + * [EggDropping](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java) + * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java) + * [FordFulkerson](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java) + * [KadaneAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java) + * [Knapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java) + * [KnapsackMemoization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java) + * [LevenshteinDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java) + * [LongestAlternatingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java) + * [LongestCommonSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java) + * [LongestIncreasingSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java) + * [LongestPalindromicSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java) + * [LongestPalindromicSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java) + * [LongestValidParentheses](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java) + * [MatrixChainMultiplication](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java) + * [MatrixChainRecursiveTopDownMemoisation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java) + * [MinimumPathSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java) + * [MinimumSumPartition](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java) + * [NewManShanksPrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java) + * [OptimalJobScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java) + * [PalindromicPartitioning](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java) + * [PartitionProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java) + * [RegexMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java) + * [RodCutting](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java) + * [ShortestCommonSupersequenceLength](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java) + * [SubsetCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java) + * [SubsetSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java) + * [SumOfSubset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java) + * [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java) + * [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java) + * [WildcardMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java) + * [WineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java) + * geometry + * [GrahamScan](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/geometry/GrahamScan.java) + * greedyalgorithms + * [ActivitySelection](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java) + * [CoinChange](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java) + * [FractionalKnapsack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java) + * [JobSequencing](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java) + * [MinimizingLateness](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java) + * io + * [BufferedReader](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/io/BufferedReader.java) + * maths + * [AbsoluteMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AbsoluteMax.java) + * [AbsoluteMin](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AbsoluteMin.java) + * [AbsoluteValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AbsoluteValue.java) + * [ADTFraction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ADTFraction.java) + * [AliquotSum](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AliquotSum.java) + * [AmicableNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AmicableNumber.java) + * [Area](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Area.java) + * [Armstrong](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Armstrong.java) + * [AutoCorrelation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AutoCorrelation.java) + * [AutomorphicNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java) + * [Average](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Average.java) + * [BinaryPow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/BinaryPow.java) + * [BinomialCoefficient](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java) + * [Ceil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Ceil.java) + * [CircularConvolutionFFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java) + * [CollatzConjecture](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CollatzConjecture.java) + * [Combinations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Combinations.java) + * [Convolution](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Convolution.java) + * [ConvolutionFFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java) + * [CrossCorrelation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/CrossCorrelation.java) + * [DeterminantOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java) + * [DigitalRoot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DigitalRoot.java) + * [DistanceFormula](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DistanceFormula.java) + * [DudeneyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/DudeneyNumber.java) + * [EulerMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/EulerMethod.java) + * [Factorial](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Factorial.java) + * [FactorialRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FactorialRecursion.java) + * [FastInverseSqrt](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java) + * [FFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFT.java) + * [FFTBluestein](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFTBluestein.java) + * [FibonacciJavaStreams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java) + * [FibonacciLoop](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciLoop.java) + * [FibonacciNumberCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java) + * [FibonacciNumberGoldenRation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java) + * [FindKthNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindKthNumber.java) + * [FindMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMax.java) + * [FindMaxRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java) + * [FindMin](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMin.java) + * [FindMinRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FindMinRecursion.java) + * [Floor](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Floor.java) + * [FrizzyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FrizzyNumber.java) + * [Gaussian](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Gaussian.java) + * [GCD](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GCD.java) + * [GCDRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GCDRecursion.java) + * [GenericRoot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/GenericRoot.java) + * [HarshadNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/HarshadNumber.java) + * [HeronsFormula](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/HeronsFormula.java) + * [JosephusProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/JosephusProblem.java) + * [JugglerSequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/JugglerSequence.java) + * [KaprekarNumbers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java) + * [KeithNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KeithNumber.java) + * [KrishnamurthyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java) + * [LeastCommonMultiple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java) + * [LeonardoNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LeonardoNumber.java) + * [LinearDiophantineEquationsSolver](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java) + * [LiouvilleLambdaFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java) + * [LongDivision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LongDivision.java) + * [LucasSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/LucasSeries.java) + * [MagicSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MagicSquare.java) + * [MatrixRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixRank.java) + * [MatrixUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MatrixUtil.java) + * [MaxValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MaxValue.java) + * [Means](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Means.java) + * [Median](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Median.java) + * [MillerRabinPrimalityCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java) + * [MinValue](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MinValue.java) + * [MobiusFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/MobiusFunction.java) + * [Mode](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Mode.java) + * [NonRepeatingElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java) + * [NthUglyNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NthUglyNumber.java) + * [NumberOfDigits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/NumberOfDigits.java) + * [PalindromeNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PalindromeNumber.java) + * [ParseInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ParseInteger.java) + * [PascalTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PascalTriangle.java) + * [PerfectCube](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PerfectCube.java) + * [PerfectNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PerfectNumber.java) + * [PerfectSquare](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PerfectSquare.java) + * [Perimeter](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Perimeter.java) + * [PiNilakantha](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PiNilakantha.java) + * [PollardRho](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PollardRho.java) + * [Pow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Pow.java) + * [PowerOfTwoOrNot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java) + * [PowerUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java) + * [PrimeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PrimeCheck.java) + * [PrimeFactorization](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PrimeFactorization.java) + * [PronicNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PronicNumber.java) + * [PythagoreanTriple](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java) + * [ReverseNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/ReverseNumber.java) + * [RomanNumeralUtil](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java) + * [SecondMinMax](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SecondMinMax.java) + * [SimpsonIntegration](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java) + * [SquareFreeInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java) + * [SquareRootWithBabylonianMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java) + * [SquareRootWithNewtonRaphsonMethod](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java) + * [StandardDeviation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StandardDeviation.java) + * [StandardScore](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StandardScore.java) + * [StrobogrammaticNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java) + * [SumOfArithmeticSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java) + * [SumOfDigits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumOfDigits.java) + * [SumWithoutArithmeticOperators](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java) + * [TrinomialTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java) + * [TwinPrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/TwinPrime.java) + * [VampireNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/VampireNumber.java) + * [VectorCrossProduct](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java) + * [Volume](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Volume.java) + * matrixexponentiation + * [Fibonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java) + * misc + * [ColorContrastRatio](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java) + * [InverseOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java) + * [MapReduce](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MapReduce.java) + * [matrixTranspose](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/matrixTranspose.java) + * [MedianOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java) + * [MedianOfRunningArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java) + * [MedianOfRunningArrayByte](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java) + * [MedianOfRunningArrayDouble](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java) + * [MedianOfRunningArrayFloat](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java) + * [MedianOfRunningArrayInteger](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java) + * [MedianOfRunningArrayLong](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java) + * [MirrorOfMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java) + * [PalindromePrime](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromePrime.java) + * [PalindromeSinglyLinkedList](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java) + * [RangeInSortedArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java) + * [Sort012D](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sort012D.java) + * [Sparsity](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/Sparsity.java) + * [ThreeSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java) + * [TwoSumProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/TwoSumProblem.java) + * [WordBoggle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/misc/WordBoggle.java) + * others + * [ArrayLeftRotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java) + * [BankersAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BankersAlgorithm.java) + * [BFPRT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BFPRT.java) + * [BoyerMoore](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BoyerMoore.java) + * [BrianKernighanAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java) + * cn + * [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/cn/HammingDistance.java) + * [Conway](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Conway.java) + * [CountChar](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CountChar.java) + * [countSetBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/countSetBits.java) + * [CountWords](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CountWords.java) + * [CRC16](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRC16.java) + * [CRC32](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRC32.java) + * [CRCAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/CRCAlgorithm.java) + * [Damm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Damm.java) + * [Dijkstra](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Dijkstra.java) + * [EulersFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/EulersFunction.java) + * [FibbonaciSeries](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/FibbonaciSeries.java) + * [FloydTriangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/FloydTriangle.java) + * [GuassLegendre](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/GuassLegendre.java) + * [HappyNumbersSeq](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java) + * [Huffman](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Huffman.java) + * [Implementing auto completing features using trie](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java) + * [InsertDeleteInArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java) + * [KMP](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/KMP.java) + * [KochSnowflake](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/KochSnowflake.java) + * [Krishnamurthy](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Krishnamurthy.java) + * [LinearCongruentialGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java) + * [LineSweep](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/LineSweep.java) + * [LowestBasePalindrome](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java) + * [Luhn](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Luhn.java) + * [Mandelbrot](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Mandelbrot.java) + * [MaximumSumOfDistinctSubarraysWithLengthK](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java) + * [MemoryManagementAlgorithms](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java) + * [MiniMaxAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java) + * [PageRank](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PageRank.java) + * [PasswordGen](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PasswordGen.java) + * [PerlinNoise](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PerlinNoise.java) + * [PrintAMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java) + * [QueueUsingTwoStacks](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java) + * [RabinKarp](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RabinKarp.java) + * [RemoveDuplicateFromString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java) + * [ReturnSubsequence](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReturnSubsequence.java) + * [ReverseStackUsingRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java) + * [RootPrecision](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RootPrecision.java) + * [RotateMatrixBy90Degrees](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java) + * [SieveOfEratosthenes](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java) + * [SkylineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/SkylineProblem.java) + * [StringMatchFiniteAutomata](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java) + * [Sudoku](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Sudoku.java) + * [TowerOfHanoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TowerOfHanoi.java) + * [TwoPointers](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/TwoPointers.java) + * [Verhoeff](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/others/Verhoeff.java) + * scheduling + * [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java) + * [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java) + * [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java) + * [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java) + * [SRTFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java) + * searches + * [BinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BinarySearch.java) + * [BinarySearch2dArray](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java) + * [BreadthFirstSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java) + * [DepthFirstSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java) + * [ExponentalSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/ExponentalSearch.java) + * [FibonacciSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/FibonacciSearch.java) + * [HowManyTimesRotated](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java) + * [InterpolationSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/InterpolationSearch.java) + * [IterativeBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java) + * [IterativeTernarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java) + * [JumpSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/JumpSearch.java) + * [KMPSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/KMPSearch.java) + * [LinearSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/LinearSearch.java) + * [LinearSearchThread](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/LinearSearchThread.java) + * [LowerBound](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/LowerBound.java) + * [MonteCarloTreeSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java) + * [OrderAgnosticBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java) + * [PerfectBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java) + * [QuickSelect](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/QuickSelect.java) + * [RabinKarpAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java) + * [RecursiveBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java) + * [RowColumnWiseSorted2dArrayBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java) + * [SaddlebackSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java) + * [SearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java) + * [sortOrderAgnosticBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java) + * [SquareRootBinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java) + * [TernarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/TernarySearch.java) + * [UnionFind](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UnionFind.java) + * [UpperBound](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/UpperBound.java) + * sorts + * [BeadSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BeadSort.java) + * [BinaryInsertionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java) + * [BitonicSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BitonicSort.java) + * [BogoSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BogoSort.java) + * [BubbleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BubbleSort.java) + * [BubbleSortRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BubbleSortRecursion.java) + * [BucketSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/BucketSort.java) + * [CircleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CircleSort.java) + * [CocktailShakerSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java) + * [CombSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CombSort.java) + * [CountingSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CountingSort.java) + * [CycleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/CycleSort.java) + * [DNFSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DNFSort.java) + * [DualPivotQuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java) + * [DutchNationalFlagSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java) + * [ExchangeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ExchangeSort.java) + * [GnomeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/GnomeSort.java) + * [HeapSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/HeapSort.java) + * [InsertionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/InsertionSort.java) + * [IntrospectiveSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java) + * [LinkListSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/LinkListSort.java) + * [MergeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSort.java) + * [MergeSortNoExtraSpace](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java) + * [MergeSortRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java) + * [OddEvenSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/OddEvenSort.java) + * [PancakeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PancakeSort.java) + * [PigeonholeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java) + * [QuickSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/QuickSort.java) + * [RadixSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/RadixSort.java) + * [SelectionSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SelectionSort.java) + * [ShellSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/ShellSort.java) + * [SimpleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SimpleSort.java) + * [SlowSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SlowSort.java) + * [SortAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java) + * [SortUtils](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortUtils.java) + * [SortUtilsRandomGenerator](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java) + * [StoogeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StoogeSort.java) + * [StrandSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/StrandSort.java) + * [SwapSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/SwapSort.java) + * [TimSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TimSort.java) + * [TopologicalSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TopologicalSort.java) + * [TreeSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/TreeSort.java) + * [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java) + * stacks + * [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java) + * [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java) + * [DuplicateBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java) + * [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java) + * [LargestRectangle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/LargestRectangle.java) + * [MaximumMinimumWindow](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java) + * [NextGreaterElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java) + * [NextSmallerElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java) + * [PostfixToInfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java) + * [StackPostfixNotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java) + * strings + * [AhoCorasick](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/AhoCorasick.java) + * [Alphabetical](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Alphabetical.java) + * [Anagrams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Anagrams.java) + * [CharactersSame](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CharactersSame.java) + * [CheckAnagrams](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CheckAnagrams.java) + * [CheckVowels](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/CheckVowels.java) + * [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/HammingDistance.java) + * [HorspoolSearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/HorspoolSearch.java) + * [Isomorphic](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Isomorphic.java) + * [LetterCombinationsOfPhoneNumber](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java) + * [longestNonRepeativeSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java) + * [LongestPalindromicSubstring](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java) + * [Lower](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Lower.java) + * [MyAtoi](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/MyAtoi.java) + * [Palindrome](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Palindrome.java) + * [Pangram](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Pangram.java) + * [PermuteString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/PermuteString.java) + * [ReverseString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseString.java) + * [ReverseStringRecursive](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java) + * [ReverseWordsInString](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java) + * [Rotation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Rotation.java) + * [StringCompression](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/StringCompression.java) + * [Upper](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/Upper.java) + * [ValidParentheses](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/ValidParentheses.java) + * [WordLadder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/WordLadder.java) + * zigZagPattern + * [zigZagPattern](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java) + * test + * java + * com + * thealgorithms + * backtracking + * [AllPathsFromSourceToTargetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java) + * [ArrayCombinationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java) + * [CombinationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/CombinationTest.java) + * [FloodFillTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/FloodFillTest.java) + * [MazeRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java) + * [MColoringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/MColoringTest.java) + * [ParenthesesGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java) + * [PermutationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PermutationTest.java) + * [PowerSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java) + * [WordSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java) + * bitmanipulation + * [BitSwapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java) + * [HighestSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java) + * [IndexOfRightMostSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java) + * [IsEvenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java) + * [IsPowerTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java) + * [NonRepeatingNumberFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java) + * [NumbersDifferentSignsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java) + * [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java) + * [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java) + * ciphers + * a5 + * [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java) + * [BlowfishTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java) + * [CaesarTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/CaesarTest.java) + * [DESTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/DESTest.java) + * [PlayfairTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java) + * [PolybiusTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java) + * [RSATest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/RSATest.java) + * [SimpleSubCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java) + * [VigenereTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/VigenereTest.java) + * conversions + * [BinaryToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java) + * [BinaryToHexadecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java) + * [BinaryToOctalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java) + * [DecimalToHexaDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java) + * [HexaDecimalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java) + * [HexaDecimalToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java) + * [HexToOctTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/HexToOctTest.java) + * [IntegerToRomanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java) + * [OctalToBinaryTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java) + * [OctalToDecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java) + * [OctalToHexadecimalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java) + * [RomanToIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java) + * datastructures + * bloomfilter + * [BloomFilterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java) + * buffers + * [CircularBufferTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java) + * caches + * [LFUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java) + * [LRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java) + * [MRUCacheTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java) + * crdt + * [GCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java) + * [GSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java) + * [LWWElementSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java) + * [ORSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java) + * [PNCounterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java) + * [TwoPSetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java) + * disjointsetunion + * [DisjointSetUnionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java) + * graphs + * [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java) + * [HamiltonianCycleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java) + * [KosarajuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java) + * [TarjansAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java) + * [WelshPowellTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java) + * hashmap + * hashing + * [GenericHashMapUsingArrayListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java) + * [GenericHashMapUsingArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java) + * [LinearProbingHashMapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java) + * [MajorityElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java) + * [MapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java) + * [HashMapCuckooHashingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java) + * heaps + * [FibonacciHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java) + * [LeftistHeapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java) + * lists + * [QuickSortLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java) + * [ReverseKGroupTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java) + * [RotateSinglyLinkedListsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java) + * [SinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java) + * [SkipListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java) + * queues + * [LinkedQueueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java) + * [PriorityQueuesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java) + * trees + * [BinaryTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java) + * [BSTFromSortedArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java) + * [BSTIterativeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java) + * [BSTRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java) + * [CeilInBinarySearchTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java) + * [CheckBinaryTreeIsValidBSTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java) + * [CheckIfBinaryTreeBalancedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java) + * [CheckTreeIsSymmetricTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java) + * [CreateBinaryTreeFromInorderPreorderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java) + * [InorderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java) + * [KDTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java) + * [LazySegmentTreeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java) + * [LevelOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java) + * [PostOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java) + * [PreOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java) + * [SameTreesCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java) + * [TreeTestUtils](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java) + * [VerticalOrderTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java) + * [ZigzagTraversalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java) + * divideandconquer + * [BinaryExponentiationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java) + * [StrassenMatrixMultiplicationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java) + * dynamicprogramming + * [CatalanNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java) + * [climbStairsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/climbStairsTest.java) + * [EggDroppingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java) + * [KnapsackMemoizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java) + * [KnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java) + * [LevenshteinDistanceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java) + * [LongestIncreasingSubsequenceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java) + * [MinimumPathSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java) + * [MinimumSumPartitionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java) + * [OptimalJobSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java) + * [PartitionProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java) + * [SubsetCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java) + * [SumOfSubsetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java) + * [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java) + * [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java) + * [WildcardMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java) + * geometry + * [GrahamScanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java) + * greedyalgorithms + * [ActivitySelectionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java) + * [CoinChangeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java) + * [FractionalKnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java) + * [JobSequencingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java) + * [MinimizingLatenessTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java) + * io + * [BufferedReaderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/io/BufferedReaderTest.java) + * maths + * [AbsoluteMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java) + * [AbsoluteMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java) + * [AbsoluteValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java) + * [ADTFractionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ADTFractionTest.java) + * [AliquotSumTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AliquotSumTest.java) + * [AmicableNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AmicableNumberTest.java) + * [AreaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AreaTest.java) + * [ArmstrongTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ArmstrongTest.java) + * [AutoCorrelationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java) + * [AutomorphicNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java) + * [AverageTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/AverageTest.java) + * [BinaryPowTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/BinaryPowTest.java) + * [BinomialCoefficientTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java) + * [CeilTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CeilTest.java) + * [CollatzConjectureTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java) + * [CombinationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CombinationsTest.java) + * [CrossCorrelationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java) + * [DigitalRootTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DigitalRootTest.java) + * [DistanceFormulaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java) + * [DudeneyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java) + * [FactorialRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java) + * [FactorialTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialTest.java) + * [FastInverseSqrtTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java) + * [FFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FFTTest.java) + * [FibonacciJavaStreamsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java) + * [FibonacciLoopTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java) + * [FibonacciNumberCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java) + * [FibonacciNumberGoldenRationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java) + * [FindMaxRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java) + * [FindMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMaxTest.java) + * [FindMinRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java) + * [FindMinTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FindMinTest.java) + * [FloorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FloorTest.java) + * [FrizzyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java) + * [GaussianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GaussianTest.java) + * [GCDTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GCDTest.java) + * [GenericRootTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/GenericRootTest.java) + * [HarshadNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java) + * [HeronsFormulaTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java) + * [JosephusProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/JosephusProblemTest.java) + * [KaprekarNumbersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java) + * [LeastCommonMultipleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java) + * [LeonardoNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java) + * [LiouvilleLambdaFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java) + * [LongDivisionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LongDivisionTest.java) + * [LucasSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java) + * [MatrixRankTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MatrixRankTest.java) + * [MaxValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MaxValueTest.java) + * [MeansTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MeansTest.java) + * [MedianTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MedianTest.java) + * [MillerRabinPrimalityCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java) + * [MinValueTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MinValueTest.java) + * [MobiusFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java) + * [ModeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ModeTest.java) + * [NthUglyNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java) + * [NumberOfDigitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java) + * [PalindromeNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java) + * [ParseIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java) + * [PascalTriangleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java) + * [PerfectCubeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerfectCubeTest.java) + * [PerfectNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java) + * [PerfectSquareTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java) + * [PerimeterTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PerimeterTest.java) + * [PollardRhoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PollardRhoTest.java) + * [PowerOfTwoOrNotTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java) + * [PowerUsingRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java) + * [PrimeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java) + * [PrimeFactorizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java) + * [PronicNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PronicNumberTest.java) + * [PythagoreanTripleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java) + * [ReverseNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java) + * [SecondMinMaxTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java) + * [SquareFreeIntegerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java) + * [SquareRootwithBabylonianMethodTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java) + * [SquareRootWithNewtonRaphsonTestMethod](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java) + * [StandardDeviationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/StandardDeviationTest.java) + * [StandardScoreTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/StandardScoreTest.java) + * [StrobogrammaticNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java) + * [SumOfArithmeticSeriesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java) + * [SumOfDigitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java) + * [SumWithoutArithmeticOperatorsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java) + * [TestArmstrong](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TestArmstrong.java) + * [TwinPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java) + * [VolumeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/VolumeTest.java) + * misc + * [MapReduceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MapReduceTest.java) + * [MedianOfMatrixtest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java) + * [MedianOfRunningArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java) + * [MirrorOfMatrixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java) + * [PalindromeSinglyLinkedListTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java) + * [TwoSumProblemTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java) + * others + * [ArrayLeftRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java) + * [ArrayRightRotation](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayRightRotation.java) + * [ArrayRightRotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java) + * [BestFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BestFitCPUTest.java) + * [BoyerMooreTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/BoyerMooreTest.java) + * cn + * [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java) + * [ConwayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/ConwayTest.java) + * [CountCharTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CountCharTest.java) + * [CountFriendsPairingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java) + * [countSetBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/countSetBitsTest.java) + * [CountWordsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CountWordsTest.java) + * [CRC16Test](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CRC16Test.java) + * [CRCAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java) + * [EulersFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/EulersFunctionTest.java) + * [FirstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java) + * [KadaneAlogrithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java) + * [LineSweepTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/LineSweepTest.java) + * [LinkListSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/LinkListSortTest.java) + * [LowestBasePalindromeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java) + * [MaximumSumOfDistinctSubarraysWithLengthKTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java) + * [NewManShanksPrimeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java) + * [NextFitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/NextFitTest.java) + * [PasswordGenTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/PasswordGenTest.java) + * [SieveOfEratosthenesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/SieveOfEratosthenesTest.java) + * [TestPrintMatrixInSpiralOrder](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java) + * [TwoPointersTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/TwoPointersTest.java) + * [WorstFitCPUTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java) + * scheduling + * [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java) + * [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java) + * [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java) + * [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java) + * [SRTFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java) + * searches + * [BinarySearch2dArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java) + * [BreadthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java) + * [DepthFirstSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java) + * [HowManyTimesRotatedTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java) + * [KMPSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/KMPSearchTest.java) + * [OrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java) + * [PerfectBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java) + * [QuickSelectTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/QuickSelectTest.java) + * [RabinKarpAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java) + * [RecursiveBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java) + * [RowColumnWiseSorted2dArrayBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java) + * [sortOrderAgnosticBinarySearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearchTest.java) + * [TestSearchInARowAndColWiseSortedMatrix](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java) + * sorts + * [BeadSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BeadSortTest.java) + * [BinaryInsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java) + * [BogoSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BogoSortTest.java) + * [BubbleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java) + * [BucketSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/BucketSortTest.java) + * [CircleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CircleSortTest.java) + * [CocktailShakerSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java) + * [CombSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/CombSortTest.java) + * [DualPivotQuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java) + * [DutchNationalFlagSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java) + * [ExchangeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java) + * [GnomeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java) + * [HeapSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/HeapSortTest.java) + * [InsertionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java) + * [IntrospectiveSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java) + * [MergeSortRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java) + * [MergeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/MergeSortTest.java) + * [OddEvenSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java) + * [PancakeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java) + * [QuickSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/QuickSortTest.java) + * [SelectionSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java) + * [ShellSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/ShellSortTest.java) + * [SimpleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SimpleSortTest.java) + * [SlowSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SlowSortTest.java) + * [SortingAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java) + * [SortUtilsRandomGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java) + * [SortUtilsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java) + * [StrandSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/StrandSortTest.java) + * [TimSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TimSortTest.java) + * [TopologicalSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java) + * [TreeSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/TreeSortTest.java) + * [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java) + * stacks + * [StackPostfixNotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java) + * strings + * [AhoCorasickTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java) + * [AlphabeticalTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java) + * [AnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/AnagramsTest.java) + * [CharacterSameTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CharacterSameTest.java) + * [CheckAnagramsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java) + * [CheckVowelsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java) + * [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/HammingDistanceTest.java) + * [HorspoolSearchTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java) + * [IsomorphicTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/IsomorphicTest.java) + * [LetterCombinationsOfPhoneNumberTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java) + * [longestNonRepeativeSubstringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/longestNonRepeativeSubstringTest.java) + * [LowerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/LowerTest.java) + * [MyAtoiTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/MyAtoiTest.java) + * [PalindromeTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/PalindromeTest.java) + * [PangramTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/PangramTest.java) + * [ReverseStringRecursiveTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java) + * [ReverseStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseStringTest.java) + * [ReverseWordsInStringTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java) + * [RotationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/RotationTest.java) + * [StringCompressionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/StringCompressionTest.java) + * [UpperTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/UpperTest.java) + * [ValidParenthesesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java) + * [WordLadderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/WordLadderTest.java) + * zigZagPattern + * [zigZagPatternTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/strings/zigZagPattern/zigZagPatternTest.java) diff --git a/Java/LICENSE b/Java/LICENSE new file mode 100644 index 000000000000..f6bcf04e7773 --- /dev/null +++ b/Java/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 The Algorithms + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Java/README-ko.md b/Java/README-ko.md new file mode 100644 index 000000000000..4f8cab92fc42 --- /dev/null +++ b/Java/README-ko.md @@ -0,0 +1,191 @@ +# 알고리즘 - 자바 + +## 이 [개발브런치](https://github.com/TheAlgorithms/Java/tree/Development)는 기존 프로젝트를 Java 프로젝트 구조로 재개발하기 위해 작성되었다. 기여도를 위해 개발 지사로 전환할 수 있다. 자세한 내용은 이 문제를 참조하십시오. 컨트리뷰션을 위해 [개발브런치](https://github.com/TheAlgorithms/Java/tree/Development)로 전환할 수 있다. 자세한 내용은 [이 이슈](https://github.com/TheAlgorithms/Java/issues/474)를 참고하십시오. + +### 자바로 구현된 모든 알고리즘들 (교육용) + +이것들은 단지 시범을 위한 것이다. 표준 자바 라이브러리에는 성능상의 이유로 더 나은 것들이 구현되어있다 + +## 정렬 알고리즘 + +### Bubble(버블 정렬) + +![alt text][bubble-image] + +From [Wikipedia][bubble-wiki]: 버블 소트(sinking sor라고도 불리움)는 리스트를 반복적인 단계로 접근하여 정렬한다. 각각의 짝을 비교하며, 순서가 잘못된 경우 그접한 아이템들을 스왑하는 알고리즘이다. 더 이상 스왑할 것이 없을 때까지 반복하며, 반복이 끝남음 리스트가 정렬되었음을 의미한다. + +**속성** + +- 최악의 성능 O(n^2) +- 최고의 성능 O(n) +- 평균 성능 O(n^2) + +###### View the algorithm in [action][bubble-toptal] + +### Insertion(삽입 정렬) + +![alt text][insertion-image] + +From [Wikipedia][insertion-wiki]: 삽입 정렬은 최종 정렬된 배열(또는 리스트)을 한번에 하나씩 구축하는 알고리즘이다. 이것은 큰 리스트에서 더 나은 알고리즘인 퀵 소트, 힙 소트, 또는 머지 소트보다 훨씬 안좋은 효율을 가진다. 그림에서 각 막대는 정렬해야 하는 배열의 요소를 나타낸다. 상단과 두 번째 상단 막대의 첫 번째 교차점에서 발생하는 것은 두 번째 요소가 첫 번째 요소보다 더 높은 우선 순위를 가지기 때문에 막대로 표시되는 이러한 요소를 교환한 것이다. 이 방법을 반복하면 삽입 정렬이 완료된다. + +**속성** + +- 최악의 성능 O(n^2) +- 최고의 성능 O(n) +- 평균 O(n^2) + +###### View the algorithm in [action][insertion-toptal] + +### Merge(합병 정렬) + +![alt text][merge-image] + +From [Wikipedia][merge-wiki]: 컴퓨터 과학에서, 합병 정렬은 효율적인, 범용적인, 비교 기반 정렬 알고리즘이다. 대부분의 구현은 안정적인 분류를 이루는데, 이것은 구현이 정렬된 출력에 동일한 요소의 입력 순서를 유지한다는 것을 의미한다. 합병 정렬은 1945년에 John von Neumann이 발명한 분할 정복 알고리즘이다. + +**속성** + +- 최악의 성능 O(n log n) (일반적) +- 최고의 성능 O(n log n) +- 평균 O(n log n) + +###### View the algorithm in [action][merge-toptal] + +### Quick(퀵 정렬) + +![alt text][quick-image] + +From [Wikipedia][quick-wiki]: 퀵 정렬sometimes called partition-exchange sort)은 효율적인 정렬 알고리즘으로, 배열의 요소를 순서대로 정렬하는 체계적인 방법 역활을 한다. + +**속성** + +- 최악의 성능 O(n^2) +- 최고의 성능 O(n log n) or O(n) with three-way partition +- 평균 O(n log n) + +###### View the algorithm in [action][quick-toptal] + +### Selection(선택 정렬) + +![alt text][selection-image] + +From [Wikipedia][selection-wiki]: 알고리즘 입력 리스트를 두 부분으로 나눈다 : 첫 부분은 아이템들이 이미 왼쪽에서 오른쪽으로 정렬되었다. 그리고 남은 부분의 아이템들은 나머지 항목을 차지하는 리스트이다. 처음에는 정렬된 리스트는 공백이고 나머지가 전부이다. 오르차순(또는 내림차순) 알고리즘은 가장 작은 요소를 정렬되지 않은 리스트에서 찾고 정렬이 안된 가장 왼쪽(정렬된 리스트) 리스트와 바꾼다. 이렇게 오른쪽으로 나아간다. + +**속성** + +- 최악의 성능 O(n^2) +- 최고의 성능 O(n^2) +- 평균 O(n^2) + +###### View the algorithm in [action][selection-toptal] + +### Shell(쉘 정렬) + +![alt text][shell-image] + +From [Wikipedia][shell-wiki]: 쉘 정렬은 멀리 떨어져 있는 항목의 교환을 허용하는 삽입 종류의 일반화이다. 그 아이디어는 모든 n번째 요소가 정렬된 목록을 제공한다는 것을 고려하여 어느 곳에서든지 시작하도록 요소의 목록을 배열하는 것이다. 이러한 목록은 h-sorted로 알려져 있다. 마찬가지로, 각각 개별적으로 정렬된 h 인터리브 목록으로 간주할 수 있다. + +**속성** + +- 최악의 성능 O(nlog2 2n) +- 최고의 성능 O(n log n) +- Average case performance depends on gap sequence + +###### View the algorithm in [action][shell-toptal] + +### 시간 복잡성 그래프 + +정렬 알고리즘의 복잡성 비교 (버블 정렬, 삽입 정렬, 선택 정렬) + +[복잡성 그래프](https://github.com/prateekiiest/Python/blob/master/sorts/sortinggraphs.png) + +--- + +## 검색 알고리즘 + +### Linear (선형 탐색) + +![alt text][linear-image] + +From [Wikipedia][linear-wiki]: 선형 탐색 또는 순차 탐색은 목록 내에서 목표값을 찾는 방법이다. 일치 항목이 발견되거나 모든 요소가 탐색될 때까지 목록의 각 요소에 대해 목표값을 순차적으로 검사한다. +선형 검색은 최악의 선형 시간으로 실행되며 최대 n개의 비교에서 이루어진다. 여기서 n은 목록의 길이다. + +**속성** + +- 최악의 성능 O(n) +- 최고의 성능 O(1) +- 평균 O(n) +- 최악의 경우 공간 복잡성 O(1) iterative + +### Binary (이진 탐색) + +![alt text][binary-image] + +From [Wikipedia][binary-wiki]: 이진 탐색, (also known as half-interval search or logarithmic search), 은 정렬된 배열 내에서 목표값의 위치를 찾는 검색 알고리즘이다. 목표값을 배열의 중간 요소와 비교한다; 만약 목표값이 동일하지 않으면, 목표물의 절반이 제거되고 검색이 성공할 때까지 나머지 절반에서 속된다. + +**속성** + +- 최악의 성능 O(log n) +- 최고의 성능 O(1) +- 평균 O(log n) +- 최악의 경우 공간 복잡성 O(1) + +[bubble-toptal]: https://www.toptal.com/developers/sorting-algorithms/bubble-sort +[bubble-wiki]: https://en.wikipedia.org/wiki/Bubble_sort +[bubble-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Bubblesort-edited-color.svg/220px-Bubblesort-edited-color.svg.png "Bubble Sort" +[insertion-toptal]: https://www.toptal.com/developers/sorting-algorithms/insertion-sort +[insertion-wiki]: https://en.wikipedia.org/wiki/Insertion_sort +[insertion-image]: https://upload.wikimedia.org/wikipedia/commons/7/7e/Insertionsort-edited.png "Insertion Sort" +[quick-toptal]: https://www.toptal.com/developers/sorting-algorithms/quick-sort +[quick-wiki]: https://en.wikipedia.org/wiki/Quicksort +[quick-image]: https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif "Quick Sort" +[merge-toptal]: https://www.toptal.com/developers/sorting-algorithms/merge-sort +[merge-wiki]: https://en.wikipedia.org/wiki/Merge_sort +[merge-image]: https://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif "Merge Sort" +[selection-toptal]: https://www.toptal.com/developers/sorting-algorithms/selection-sort +[selection-wiki]: https://en.wikipedia.org/wiki/Selection_sort +[selection-image]: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Selection_sort_animation.gif/250px-Selection_sort_animation.gif "Selection Sort Sort" +[shell-toptal]: https://www.toptal.com/developers/sorting-algorithms/shell-sort +[shell-wiki]: https://en.wikipedia.org/wiki/Shellsort +[shell-image]: https://upload.wikimedia.org/wikipedia/commons/d/d8/Sorting_shellsort_anim.gif "Shell Sort" +[linear-wiki]: https://en.wikipedia.org/wiki/Linear_search +[linear-image]: http://www.tutorialspoint.com/data_structures_algorithms/images/linear_search.gif +[binary-wiki]: https://en.wikipedia.org/wiki/Binary_search_algorithm +[binary-image]: https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_search_into_array.png + +--- + +## 나머지 알고리즘에 대한 링크 + +| 전환 | 다이나믹프로그래밍(DP) | 암호 | 그 외 것들 | +| --------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------ | +| [Any Base to Any Base](Conversions/AnyBaseToAnyBase.java) | [Coin Change](DynamicProgramming/CoinChange.java) | [Caesar](Ciphers/Caesar.java) | [Heap Sort](Sorts/HeapSort.java) | +| [Any Base to Decimal](Conversions/AnyBaseToDecimal.java) | [Egg Dropping](DynamicProgramming/EggDropping.java) | [Columnar Transposition Cipher](Ciphers/ColumnarTranspositionCipher.java) | [Palindromic Prime Checker](Misc/PalindromePrime.java) | +| [Binary to Decimal](Conversions/BinaryToDecimal.java) | [Fibonacci](DynamicProgramming/Fibonacci.java) | [RSA](Ciphers/RSA.java) | More soon... | +| [Binary to HexaDecimal](Conversions/BinaryToHexadecimal.java) | [Kadane Algorithm](DynamicProgramming/KadaneAlgorithm.java) | more coming soon... | +| [Binary to Octal](Conversions/BinaryToOctal.java) | [Knapsack](DynamicProgramming/Knapsack.java) | +| [Decimal To Any Base](Conversions/DecimalToAnyBase.java) | [Longest Common Subsequence](DynamicProgramming/LongestCommonSubsequence.java) | +| [Decimal To Binary](Conversions/DecimalToBinary.java) | [Longest Increasing Subsequence](DynamicProgramming/LongestIncreasingSubsequence.java) | +| [Decimal To Hexadecimal](Conversions/DecimalToHexaDecimal.java) | [Rod Cutting](DynamicProgramming/RodCutting.java) | +| and much more... | and more... | + +### 자료 구조 + +| 그래프 | 힙 | 리스트 | 큐 | +| ------------------------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------- | +| | [빈 힙 예외처리](DataStructures/Heaps/EmptyHeapException.java) | [원형 연결리스트](DataStructures/Lists/CircleLinkedList.java) | [제너릭 어레이 리스트 큐](DataStructures/Queues/GenericArrayListQueue.java) | +| | [힙](DataStructures/Heaps/Heap.java) | [이중 연결리스트](DataStructures/Lists/DoublyLinkedList.java) | [큐](DataStructures/Queues/Queues.java) | +| [그래프](DataStructures/Graphs/Graphs.java) | [힙 요소](DataStructures/Heaps/HeapElement.java) | [단순 연결리스트](DataStructures/Lists/SinglyLinkedList.java) | +| [크루스칼 알고리즘](DataStructures/Graphs/Kruskal.java) | [최대힙](DataStructures/Heaps/MaxHeap.java) | +| [행렬 그래프](DataStructures/Graphs/MatrixGraphs.java) | [최소힙](DataStructures/Heaps/MinHeap.java) | +| [프림 최소신장트리](DataStructures/Graphs/PrimMST.java) | + +| 스택 | 트리 | +| --------------------------------------------------------------- | ------------------------------------------------- | +| [노드 스택](DataStructures/Stacks/NodeStack.java) | [AVL 트리](DataStructures/Trees/AVLTree.java) | +| [연결리스트 스택](DataStructures/Stacks/StackOfLinkedList.java) | [이진 트리](DataStructures/Trees/BinaryTree.java) | +| [스택](DataStructures/Stacks) | And much more... | + +- [Bags](DataStructures/Bags/Bag.java) +- [Buffer](DataStructures/Buffers/CircularBuffer.java) +- [HashMap](DataStructures/HashMap/Hashing/HashMap.java) +- diff --git a/Java/README.md b/Java/README.md new file mode 100644 index 000000000000..d60d5104c385 --- /dev/null +++ b/Java/README.md @@ -0,0 +1,20 @@ +# The Algorithms - Java + +[![Build](https://github.com/TheAlgorithms/Java/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/TheAlgorithms/Java/actions/workflows/build.yml) +[![codecov](https://codecov.io/gh/TheAlgorithms/Java/graph/badge.svg?token=XAdPyqTIqR)](https://codecov.io/gh/TheAlgorithms/Java) +[![Discord chat](https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA&style=flat-square)](https://discord.gg/c7MnfGFGa6) +[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/Java) + + +You can run and edit the algorithms, or contribute to them using Gitpod.io (a free online development environment) with a single click. + +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/TheAlgorithms/Java) + +### All algorithms are implemented in Java (for educational purposes) +These implementations are intended for learning purposes. As such, they may be less efficient than the Java standard library. + +## Contribution Guidelines +Please read our [Contribution Guidelines](CONTRIBUTING.md) before you contribute to this project. + +## Algorithms +Our [directory](DIRECTORY.md) has the full list of applications. diff --git a/Java/checkstyle.xml b/Java/checkstyle.xml new file mode 100644 index 000000000000..5ada9361d03c --- /dev/null +++ b/Java/checkstyle.xml @@ -0,0 +1,198 @@ +<?xml version="1.0"?> +<!DOCTYPE module PUBLIC + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> + +<!-- + + Checkstyle configuration that checks the sun coding conventions from: + + - the Java Language Specification at + https://docs.oracle.com/javase/specs/jls/se11/html/index.html + + - the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html + + - the Javadoc guidelines at + https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html + + - the JDK Api documentation https://docs.oracle.com/en/java/javase/11/ + + - some best practices + + Checkstyle is very configurable. Be sure to read the documentation at + https://checkstyle.org (or in your downloaded distribution). + + Most Checks are configurable, be sure to consult the documentation. + + To completely disable a check, just comment it out or delete it from the file. + To suppress certain violations please review suppression filters. + + Finally, it is worth reading the documentation. + +--> + +<module name="Checker"> + <!-- + If you set the basedir property below, then all reported file + names will be relative to the specified directory. See + https://checkstyle.org/config.html#Checker + + <property name="basedir" value="${basedir}"/> + --> + <property name="severity" value="error"/> + + <property name="fileExtensions" value="java, properties, xml"/> + + <!-- Excludes all 'module-info.java' files --> + <!-- See https://checkstyle.org/filefilters/index.html --> + <module name="BeforeExecutionExclusionFileFilter"> + <property name="fileNamePattern" value="module\-info\.java$"/> + </module> + + <!-- https://checkstyle.org/filters/suppressionfilter.html --> + <module name="SuppressionFilter"> + <property name="file" value="${org.checkstyle.sun.suppressionfilter.config}" + default="checkstyle-suppressions.xml" /> + <property name="optional" value="true"/> + </module> + + <!-- Checks that a package-info.java file exists for each package. --> + <!-- See https://checkstyle.org/checks/javadoc/javadocpackage.html#JavadocPackage --> + <!-- TODO <module name="JavadocPackage"/> --> + + <!-- Checks whether files end with a new line. --> + <!-- See https://checkstyle.org/checks/misc/newlineatendoffile.html --> + <module name="NewlineAtEndOfFile"/> + + <!-- Checks that property files contain the same keys. --> + <!-- See https://checkstyle.org/checks/misc/translation.html --> + <module name="Translation"/> + + <!-- Checks for Size Violations. --> + <!-- See https://checkstyle.org/checks/sizes/index.html --> + <!-- TODO <module name="FileLength"/> --> + <!-- TODO <module name="LineLength"> + <property name="fileExtensions" value="java"/> + </module> --> + + <!-- Checks for whitespace --> + <!-- See https://checkstyle.org/checks/whitespace/index.html --> + <!-- TODO <module name="FileTabCharacter"/> --> + + <!-- Miscellaneous other checks. --> + <!-- See https://checkstyle.org/checks/misc/index.html --> + <module name="RegexpSingleline"> + <property name="format" value="\s+$"/> + <property name="minimum" value="0"/> + <property name="maximum" value="0"/> + <property name="message" value="Line has trailing spaces."/> + </module> + + <!-- Checks for Headers --> + <!-- See https://checkstyle.org/checks/header/index.html --> + <!-- <module name="Header"> --> + <!-- <property name="headerFile" value="${checkstyle.header.file}"/> --> + <!-- <property name="fileExtensions" value="java"/> --> + <!-- </module> --> + + <module name="TreeWalker"> + + <!-- Checks for Javadoc comments. --> + <!-- See https://checkstyle.org/checks/javadoc/index.html --> + <!-- TODO <module name="InvalidJavadocPosition"/> --> + <!-- TODO <module name="JavadocMethod"/> --> + <!-- TODO <module name="JavadocType"/> --> + <!-- TODO <module name="JavadocVariable"/> --> + <!-- TODO <module name="JavadocStyle"/> --> + <!-- TODO <module name="MissingJavadocMethod"/> --> + + <!-- Checks for Naming Conventions. --> + <!-- See https://checkstyle.org/checks/naming/index.html --> + <module name="ConstantName"/> + <module name="LocalFinalVariableName"/> + <module name="LocalVariableName"/> + <module name="MemberName"/> + <module name="MethodName"/> + <module name="PackageName"/> + <module name="ParameterName"/> + <module name="StaticVariableName"/> + <!-- TODO <module name="TypeName"/> --> + + <!-- Checks for imports --> + <!-- See https://checkstyle.org/checks/imports/index.html --> + <module name="AvoidStarImport"/> + <module name="IllegalImport"/> <!-- defaults to sun.* packages --> + <module name="RedundantImport"/> + <module name="UnusedImports"> + <property name="processJavadoc" value="false"/> + </module> + + <!-- Checks for Size Violations. --> + <!-- See https://checkstyle.org/checks/sizes/index.html --> + <module name="MethodLength"/> + <module name="ParameterNumber"/> + + <!-- Checks for whitespace --> + <!-- See https://checkstyle.org/checks/whitespace/index.html --> + <module name="EmptyForIteratorPad"/> + <!-- TODO <module name="GenericWhitespace"/> --> + <module name="MethodParamPad"/> + <!-- TODO <module name="NoWhitespaceAfter"/> --> + <module name="NoWhitespaceBefore"/> + <!-- TODO <module name="OperatorWrap"/> --> + <!-- TODO <module name="ParenPad"/> --> + <module name="TypecastParenPad"/> + <module name="WhitespaceAfter"/> + <!-- TODO <module name="WhitespaceAround"/> --> + + <!-- Modifier Checks --> + <!-- See https://checkstyle.org/checks/modifier/index.html --> + <module name="ModifierOrder"/> + <module name="RedundantModifier"/> + + <!-- Checks for blocks. You know, those {}'s --> + <!-- See https://checkstyle.org/checks/blocks/index.html --> + <!-- TODO <module name="AvoidNestedBlocks"/> --> + <!-- TODO <module name="EmptyBlock"/> --> + <!-- TODO <module name="LeftCurly"/> --> + <!-- TODO <module name="NeedBraces"/> --> + <!-- TODO <module name="RightCurly"/> --> + + <!-- Checks for common coding problems --> + <!-- See https://checkstyle.org/checks/coding/index.html --> + <module name="EmptyStatement"/> + <module name="EqualsHashCode"/> + <!-- TODO <module name="HiddenField"/> --> + <module name="IllegalInstantiation"/> + <module name="InnerAssignment"/> + <!-- TODO <module name="MagicNumber"/> --> + <module name="MissingSwitchDefault"/> + <module name="MultipleVariableDeclarations"/> + <module name="SimplifyBooleanExpression"/> + <module name="SimplifyBooleanReturn"/> + + <!-- Checks for class design --> + <!-- See https://checkstyle.org/checks/design/index.html --> + <!-- TODO <module name="DesignForExtension"/> --> + <module name="FinalClass"/> + <module name="HideUtilityClassConstructor"/> + <module name="InterfaceIsType"/> + <!-- TODO <module name="VisibilityModifier"/> --> + + <!-- Miscellaneous other checks. --> + <!-- See https://checkstyle.org/checks/misc/index.html --> + <module name="ArrayTypeStyle"/> + <!-- TODO <module name="FinalParameters"/> --> + <!-- TODO <module name="TodoComment"/> --> + <module name="UpperEll"/> + + <!-- https://checkstyle.org/filters/suppressionxpathfilter.html --> + <module name="SuppressionXpathFilter"> + <property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}" + default="checkstyle-xpath-suppressions.xml" /> + <property name="optional" value="true"/> + </module> + + </module> + +</module> diff --git a/Java/pmd-exclude.properties b/Java/pmd-exclude.properties new file mode 100644 index 000000000000..400863992ed0 --- /dev/null +++ b/Java/pmd-exclude.properties @@ -0,0 +1,92 @@ +com.thealgorithms.bitmanipulation.SingleBitOperations=UselessParentheses +com.thealgorithms.ciphers.AffineCipher=UselessParentheses +com.thealgorithms.ciphers.ColumnarTranspositionCipher=UnnecessaryFullyQualifiedName +com.thealgorithms.ciphers.DES=UselessParentheses +com.thealgorithms.ciphers.HillCipher=UselessParentheses +com.thealgorithms.ciphers.RSA=UselessParentheses +com.thealgorithms.conversions.AnyBaseToAnyBase=UselessParentheses +com.thealgorithms.conversions.AnytoAny=UselessParentheses +com.thealgorithms.conversions.HexToOct=UselessParentheses +com.thealgorithms.conversions.IntegerToRoman=UnnecessaryFullyQualifiedName +com.thealgorithms.datastructures.crdt.LWWElementSet=UselessParentheses +com.thealgorithms.datastructures.crdt.Pair=UnusedPrivateField +com.thealgorithms.datastructures.graphs.A_Star=UselessParentheses +com.thealgorithms.datastructures.graphs.AdjacencyMatrixGraph=CollapsibleIfStatements,UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.datastructures.graphs.BipartiteGrapfDFS=CollapsibleIfStatements +com.thealgorithms.datastructures.graphs.Kruskal=UselessParentheses +com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing=UselessParentheses +com.thealgorithms.datastructures.heaps.FibonacciHeap=UselessParentheses +com.thealgorithms.datastructures.heaps.HeapElement=UselessParentheses +com.thealgorithms.datastructures.heaps.HeapNode=UselessParentheses +com.thealgorithms.datastructures.lists.DoublyLinkedList=UselessParentheses +com.thealgorithms.datastructures.lists.SearchSinglyLinkedListRecursion=UselessParentheses +com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable +com.thealgorithms.datastructures.queues.PriorityQueue=UselessParentheses +com.thealgorithms.datastructures.stacks.NodeStack=UnnecessaryFullyQualifiedName,UnusedFormalParameter +com.thealgorithms.datastructures.stacks.StackArray=UselessParentheses +com.thealgorithms.datastructures.trees.CheckBinaryTreeIsValidBST=UselessParentheses +com.thealgorithms.datastructures.trees.SegmentTree=UselessParentheses +com.thealgorithms.devutils.nodes.LargeTreeNode=UselessParentheses +com.thealgorithms.devutils.nodes.SimpleNode=UselessParentheses +com.thealgorithms.devutils.nodes.SimpleTreeNode=UselessParentheses +com.thealgorithms.devutils.nodes.TreeNode=UselessParentheses +com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.divideandconquer.Point=UselessParentheses +com.thealgorithms.dynamicprogramming.MatrixChainMultiplication=UselessParentheses +com.thealgorithms.dynamicprogramming.ShortestSuperSequence=UselessParentheses +com.thealgorithms.dynamicprogramming.UniquePaths=UnnecessarySemicolon +com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses +com.thealgorithms.maths.BinomialCoefficient=UselessParentheses +com.thealgorithms.maths.Complex=UselessParentheses +com.thealgorithms.maths.DistanceFormulaTest=UnnecessaryFullyQualifiedName +com.thealgorithms.maths.FibonacciJavaStreamsTest=BigIntegerInstantiation +com.thealgorithms.maths.Gaussian=UselessParentheses +com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses +com.thealgorithms.maths.HeronsFormula=UselessParentheses +com.thealgorithms.maths.KaprekarNumbers=UselessParentheses +com.thealgorithms.maths.KeithNumber=UselessParentheses +com.thealgorithms.maths.LeonardoNumber=UselessParentheses +com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessParentheses +com.thealgorithms.maths.MatrixUtil=BigIntegerInstantiation,UselessParentheses +com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses +com.thealgorithms.maths.SecondMinMax=UselessParentheses +com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName +com.thealgorithms.maths.StandardDeviation=UselessParentheses +com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses +com.thealgorithms.maths.TrinomialTriangle=UselessParentheses +com.thealgorithms.maths.VampireNumber=CollapsibleIfStatements +com.thealgorithms.maths.Volume=UselessParentheses +com.thealgorithms.matrixexponentiation.Fibonacci=UnnecessaryFullyQualifiedName +com.thealgorithms.misc.Sparsity=UselessParentheses +com.thealgorithms.misc.ThreeSumProblem=UselessParentheses +com.thealgorithms.misc.WordBoggle=UselessParentheses +com.thealgorithms.others.CRC16=UselessParentheses +com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName +com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName +com.thealgorithms.others.Mandelbrot=UselessParentheses +com.thealgorithms.others.MaximumSumOfDistinctSubarraysWithLengthK=CollapsibleIfStatements +com.thealgorithms.others.MiniMaxAlgorithm=UselessParentheses +com.thealgorithms.others.PageRank=UselessParentheses +com.thealgorithms.others.PerlinNoise=UselessParentheses +com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses +com.thealgorithms.others.QueueWithStack=UselessParentheses +com.thealgorithms.others.Trieac=UselessParentheses +com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName +com.thealgorithms.searches.InterpolationSearch=UselessParentheses +com.thealgorithms.searches.KMPSearch=UselessParentheses +com.thealgorithms.searches.LinearSearchThread=EmptyCatchBlock +com.thealgorithms.searches.RabinKarpAlgorithm=UselessParentheses +com.thealgorithms.sorts.BubbleSortRecursion=UselessParentheses +com.thealgorithms.sorts.CircleSort=EmptyControlStatement +com.thealgorithms.sorts.CombSort=UselessParentheses +com.thealgorithms.sorts.DutchNationalFlagSort=UselessParentheses +com.thealgorithms.sorts.LinkListSort=EmptyControlStatement,UnusedLocalVariable +com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses +com.thealgorithms.sorts.PigeonholeSort=UselessParentheses +com.thealgorithms.sorts.RadixSort=UselessParentheses +com.thealgorithms.sorts.WiggleSort=UselessParentheses +com.thealgorithms.stacks.PostfixToInfix=UselessParentheses +com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.strings.MyAtoi=UselessParentheses +com.thealgorithms.strings.Palindrome=UselessParentheses +com.thealgorithms.strings.Solution=CollapsibleIfStatements diff --git a/Java/pom.xml b/Java/pom.xml new file mode 100644 index 000000000000..b8fb946eeb5a --- /dev/null +++ b/Java/pom.xml @@ -0,0 +1,159 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>com.thealgorithms</groupId> + <artifactId>Java</artifactId> + <version>1.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + <assertj.version>3.26.0</assertj.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.junit</groupId> + <artifactId>junit-bom</artifactId> + <version>5.10.2</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter</artifactId> + <version>5.10.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <version>${assertj.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-api</artifactId> + <version>5.10.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.14.0</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-collections4</artifactId> + <version>4.5.0-M1</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>3.2.5</version> + <configuration> + <forkNode implementation="org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory"/> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.13.0</version> + <configuration> + <source>21</source> + <target>21</target> + <compilerArgs> + <arg>-Xlint:all</arg> + <arg>-Xlint:-auxiliaryclass</arg> + <arg>-Xlint:-rawtypes</arg> + <arg>-Xlint:-unchecked</arg> + <arg>-Xlint:-lossy-conversions</arg> + <arg>-Werror</arg> + </compilerArgs> + </configuration> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>0.8.12</version> + <executions> + <execution> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>generate-code-coverage-report</id> + <phase>test</phase> + <goals> + <goal>report</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>3.3.1</version> + <configuration> + <configLocation>checkstyle.xml</configLocation> + <consoleOutput>true</consoleOutput> + <includeTestSourceDirectory>true</includeTestSourceDirectory> + <violationSeverity>warning</violationSeverity> + </configuration> + <dependencies> + <dependency> + <groupId>com.puppycrawl.tools</groupId> + <artifactId>checkstyle</artifactId> + <version>10.17.0</version> + </dependency> + </dependencies> + </plugin> + <plugin> + <groupId>com.github.spotbugs</groupId> + <artifactId>spotbugs-maven-plugin</artifactId> + <version>4.8.5.0</version> + <configuration> + <excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile> + <includeTests>true</includeTests> + <plugins> + <plugin> + <groupId>com.mebigfatguy.fb-contrib</groupId> + <artifactId>fb-contrib</artifactId> + <version>7.6.4</version> + </plugin> + <plugin> + <groupId>com.h3xstream.findsecbugs</groupId> + <artifactId>findsecbugs-plugin</artifactId> + <version>1.13.0</version> + </plugin> + </plugins> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + <version>3.22.0</version> + <configuration> + <printFailingErrors>true</printFailingErrors> + <includeTests>true</includeTests> + <linkXRef>false</linkXRef> + <excludeFromFailureFile>pmd-exclude.properties</excludeFromFailureFile> + </configuration> + </plugin> + </plugins> + </build> +</project> diff --git a/Java/spotbugs-exclude.xml b/Java/spotbugs-exclude.xml new file mode 100644 index 000000000000..f621c84dd4bf --- /dev/null +++ b/Java/spotbugs-exclude.xml @@ -0,0 +1,250 @@ +<FindBugsFilter> + <Match> + <Bug pattern="DM_DEFAULT_ENCODING" /> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP2" /> + </Match> + <Match> + <Bug pattern="DMI_RANDOM_USED_ONLY_ONCE" /> + </Match> + <Match> + <Bug pattern="SF_SWITCH_NO_DEFAULT" /> + </Match> + <Match> + <Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" /> + </Match> + <Match> + <Bug pattern="DM_NEXTINT_VIA_NEXTDOUBLE" /> + </Match> + <Match> + <Bug pattern="NM_CLASS_NAMING_CONVENTION" /> + </Match> + <Match> + <Bug pattern="SIC_INNER_SHOULD_BE_STATIC" /> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP" /> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP" /> + </Match> + <Match> + <Bug pattern="SBSC_USE_STRINGBUFFER_CONCATENATION" /> + </Match> + <Match> + <Bug pattern="PA_PUBLIC_PRIMITIVE_ATTRIBUTE" /> + </Match> + <Match> + <Bug pattern="MS_PKGPROTECT" /> + </Match> + <Match> + <Bug pattern="SE_COMPARATOR_SHOULD_BE_SERIALIZABLE" /> + </Match> + <Match> + <Bug pattern="INT_BAD_REM_BY_1" /> + </Match> + <Match> + <Bug pattern="NM_METHOD_NAMING_CONVENTION" /> + </Match> + <Match> + <Bug pattern="ICAST_IDIV_CAST_TO_DOUBLE" /> + </Match> + <Match> + <Bug pattern="FE_FLOATING_POINT_EQUALITY" /> + </Match> + <Match> + <Bug pattern="CT_CONSTRUCTOR_THROW" /> + </Match> + <Match> + <Bug pattern="URF_UNREAD_FIELD" /> + </Match> + <Match> + <Bug pattern="RC_REF_COMPARISON" /> + </Match> + <Match> + <Bug pattern="MS_EXPOSE_REP" /> + </Match> + <Match> + <Bug pattern="IM_BAD_CHECK_FOR_ODD" /> + </Match> + <Match> + <Bug pattern="WMI_WRONG_MAP_ITERATOR" /> + </Match> + <Match> + <Bug pattern="DM_BOXED_PRIMITIVE_FOR_PARSING" /> + </Match> + <Match> + <Bug pattern="UWF_UNWRITTEN_FIELD" /> + </Match> + <Match> + <Bug pattern="DLS_DEAD_LOCAL_STORE" /> + </Match> + <Match> + <Bug pattern="UWF_NULL_FIELD" /> + </Match> + <Match> + <Bug pattern="NP_UNWRITTEN_FIELD" /> + </Match> + <Match> + <Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" /> + </Match> + <Match> + <Bug pattern="NP_IMMEDIATE_DEREFERENCE_OF_READLINE" /> + </Match> + <Match> + <Bug pattern="EQ_COMPARETO_USE_OBJECT_EQUALS" /> + </Match> + <Match> + <Bug pattern="SA_FIELD_SELF_ASSIGNMENT" /> + </Match> + <Match> + <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" /> + </Match> + <Match> + <Bug pattern="RV_ABSOLUTE_VALUE_OF_HASHCODE" /> + </Match> + <!-- fb-contrib --> + <Match> + <Bug pattern="OCP_OVERLY_CONCRETE_PARAMETER" /> + </Match> + <Match> + <Bug pattern="LSC_LITERAL_STRING_COMPARISON" /> + </Match> + <Match> + <Bug pattern="CE_CLASS_ENVY" /> + </Match> + <Match> + <Bug pattern="PSC_PRESIZE_COLLECTIONS" /> + </Match> + <Match> + <Bug pattern="SACM_STATIC_ARRAY_CREATED_IN_METHOD" /> + </Match> + <Match> + <Bug pattern="LUI_USE_SINGLETON_LIST" /> + </Match> + <Match> + <Bug pattern="CLI_CONSTANT_LIST_INDEX" /> + </Match> + <Match> + <Bug pattern="BED_BOGUS_EXCEPTION_DECLARATION" /> + </Match> + <Match> + <Bug pattern="CNC_COLLECTION_NAMING_CONFUSION" /> + </Match> + <Match> + <Bug pattern="TR_TAIL_RECURSION" /> + </Match> + <Match> + <Bug pattern="USBR_UNNECESSARY_STORE_BEFORE_RETURN" /> + </Match> + <Match> + <Bug pattern="SPP_USE_ISEMPTY" /> + </Match> + <Match> + <Bug pattern="BL_BURYING_LOGIC" /> + </Match> + <Match> + <Bug pattern="OI_OPTIONAL_ISSUES_USES_IMMEDIATE_EXECUTION" /> + </Match> + <Match> + <Bug pattern="PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS" /> + </Match> + <Match> + <Bug pattern="UTWR_USE_TRY_WITH_RESOURCES" /> + </Match> + <Match> + <Bug pattern="MUI_CONTAINSKEY_BEFORE_GET" /> + </Match> + <Match> + <Bug pattern="IMC_IMMATURE_CLASS_PRINTSTACKTRACE" /> + </Match> + <Match> + <Bug pattern="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" /> + </Match> + <Match> + <Bug pattern="SUA_SUSPICIOUS_UNINITIALIZED_ARRAY" /> + </Match> + <Match> + <Bug pattern="SPP_USE_MATH_CONSTANT" /> + </Match> + <Match> + <Bug pattern="UJM_UNJITABLE_METHOD" /> + </Match> + <Match> + <Bug pattern="SEC_SIDE_EFFECT_CONSTRUCTOR" /> + </Match> + <Match> + <Bug pattern="MDM_STRING_BYTES_ENCODING" /> + </Match> + <Match> + <Bug pattern="PMB_POSSIBLE_MEMORY_BLOAT" /> + </Match> + <Match> + <Bug pattern="LSYC_LOCAL_SYNCHRONIZED_COLLECTION" /> + </Match> + <Match> + <Bug pattern="IOI_USE_OF_FILE_STREAM_CONSTRUCTORS" /> + </Match> + <Match> + <Bug pattern="UP_UNUSED_PARAMETER" /> + </Match> + <Match> + <Bug pattern="DSOC_DUBIOUS_SET_OF_COLLECTIONS" /> + </Match> + <Match> + <Bug pattern="NAB_NEEDLESS_BOX_TO_UNBOX" /> + </Match> + <Match> + <Bug pattern="FPL_FLOATING_POINT_LOOPS" /> + </Match> + <Match> + <Bug pattern="ITU_INAPPROPRIATE_TOSTRING_USE" /> + </Match> + <Match> + <Bug pattern="DMC_DUBIOUS_MAP_COLLECTION" /> + </Match> + <Match> + <Bug pattern="SPP_PASSING_THIS_AS_PARM" /> + </Match> + <Match> + <Bug pattern="FCBL_FIELD_COULD_BE_LOCAL" /> + </Match> + <Match> + <Bug pattern="CFS_CONFUSING_FUNCTION_SEMANTICS" /> + </Match> + <Match> + <Bug pattern="PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS" /> + </Match> + <Match> + <Bug pattern="FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY" /> + </Match> + <Match> + <Bug pattern="PL_PARALLEL_LISTS" /> + </Match> + <Match> + <Bug pattern="PCAIL_POSSIBLE_CONSTANT_ALLOCATION_IN_LOOP" /> + </Match> + <Match> + <Bug pattern="STT_STRING_PARSING_A_FIELD" /> + </Match> + <Match> + <Bug pattern="IMC_IMMATURE_CLASS_BAD_SERIALVERSIONUID" /> + </Match> + <Match> + <Bug pattern="SUI_CONTAINS_BEFORE_ADD" /> + </Match> + <Match> + <Bug pattern="DRE_DECLARED_RUNTIME_EXCEPTION" /> + </Match> + <Match> + <Bug pattern="SLS_SUSPICIOUS_LOOP_SEARCH" /> + </Match> + <!-- find-sec-bugs --> + <Match> + <Bug pattern="PREDICTABLE_RANDOM" /> + </Match> + <Match> + <Bug pattern="HARD_CODE_KEY" /> + </Match> +</FindBugsFilter> diff --git a/Java/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java b/Java/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java new file mode 100644 index 000000000000..c211cd08a501 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/audiofilters/IIRFilter.java @@ -0,0 +1,93 @@ +package com.thealgorithms.audiofilters; + +/** + * N-Order IIR Filter Assumes inputs are normalized to [-1, 1] + * + * Based on the difference equation from + * <a href="https://en.wikipedia.org/wiki/Infinite_impulse_response">Wikipedia link</a> + */ +public class IIRFilter { + + private final int order; + private final double[] coeffsA; + private final double[] coeffsB; + private final double[] historyX; + private final double[] historyY; + + /** + * Construct an IIR Filter + * + * @param order the filter's order + * @throws IllegalArgumentException if order is zero or less + */ + public IIRFilter(int order) throws IllegalArgumentException { + if (order < 1) { + throw new IllegalArgumentException("order must be greater than zero"); + } + + this.order = order; + coeffsA = new double[order + 1]; + coeffsB = new double[order + 1]; + + // Sane defaults + coeffsA[0] = 1.0; + coeffsB[0] = 1.0; + + historyX = new double[order]; + historyY = new double[order]; + } + + /** + * 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 + */ + public void setCoeffs(double[] aCoeffs, double[] bCoeffs) throws IllegalArgumentException { + if (aCoeffs.length != order) { + throw new IllegalArgumentException("aCoeffs must be of size " + order + ", got " + aCoeffs.length); + } + + if (aCoeffs[0] == 0.0) { + throw new IllegalArgumentException("aCoeffs.get(0) must not be zero"); + } + + if (bCoeffs.length != order) { + throw new IllegalArgumentException("bCoeffs must be of size " + order + ", got " + bCoeffs.length); + } + + for (int i = 0; i <= order; i++) { + coeffsA[i] = aCoeffs[i]; + coeffsB[i] = bCoeffs[i]; + } + } + + /** + * Process a single sample + * + * @param sample the sample to process + * @return the processed sample + */ + public double process(double sample) { + double result = 0.0; + + // Process + for (int i = 1; i <= order; i++) { + 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]; + } + + historyX[0] = sample; + historyY[0] = result; + + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/Java/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java new file mode 100644 index 000000000000..dd43ab780bed --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java @@ -0,0 +1,143 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ + +/** Program description - To find all possible paths from source to destination */ +/** Wikipedia link -> https://en.wikipedia.org/wiki/Shortest_path_problem */ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + + +public class AllPathsFromSourceToTarget { + + /** + * Common variables to "AllPathsFromSourceToTarget" class. + * + * 1) Number of vertices in graph. + * 2) List to store the paths from source to destiny. + * 3) Adjacency list. + */ + private final int v; + static List<List<Integer>> nm = new ArrayList<>(); + private ArrayList<Integer>[] adjList; + + /** + * Constructor. + * @param vertices Number of vertices. + */ + + public AllPathsFromSourceToTarget(int vertices) { + + // initialise vertex count + this.v = vertices; + + // initialise adjacency list + initAdjList(); + } + + /** + * Creates an ArrayList for each position in adjList. + */ + + private void initAdjList() { + adjList = new ArrayList[v]; + + for (int i = 0; i < v; i++) { + adjList[i] = new ArrayList<>(); + } + } + + /** + * Add edge from u to v + * + * @param u Value to select list. + * @param v Value to introduce. + */ + + public void addEdge(int u, int v) { + adjList[u].add(v); + } + + /** + * + * @param s Value of source + * @param d Value of destiny. + */ + + public void storeAllPaths(int s, int d) { + // Array composed by boolean´s objects with v like lenght + boolean[] isVisited = new boolean[v]; + // This ArrayList stores the track. + ArrayList<Integer> pathList = new ArrayList<>(); + // add source to path[] + pathList.add(s); + // Call recursive function utility. + storeAllPathsUtil(s, d, isVisited, pathList); + } + + /** + * + * Function to StoreAllPaths + * + * @param u Value of source + * @param d Value of destiny + * @param isVisited array to keeps track of vertices in current path. + * @param localPathList stores actual vertices in the current path + */ + + private void storeAllPathsUtil(Integer u, Integer d, boolean[] isVisited, List<Integer> localPathList) { + + //If node u is equals to d the path has benn completly found it. + if (u.equals(d)) { + nm.add(new ArrayList<>(localPathList)); + return; + } + + // Mark the current node as visited. + isVisited[u] = true; + + // Recursion for all the vertices adjacent to current vertex + for (Integer i : adjList[u]) { + if (!isVisited[i]) { + // store current node in path[] + localPathList.add(i); + storeAllPathsUtil(i, d, isVisited, localPathList); + + // remove current node in path[] + localPathList.remove(i); + } + } + + // Mark the current node as false to release it and be used by others. + isVisited[u] = false; + } + + /** + * + * Driver program + * + * @param vertices number of vertices of the graph + * @param a represents the aristas of the graph. + * @param source value of source. + * @param destination value of destiny. + * @return A List composed by diferent lists that stores all the possible paths to the destiny. + */ + + public static List<List<Integer>> allPathsFromSourceToTarget(int vertices, int[][] a, int source, int destination) { + // Create a sample graph + AllPathsFromSourceToTarget g = new AllPathsFromSourceToTarget(vertices); + + // edges are added + for (int[] i : a) { + g.addEdge(i[0], i[1]); + } + + // method call to store all possible paths + g.storeAllPaths(source, destination); + + return nm; + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/Java/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java new file mode 100644 index 000000000000..a0b886e6be8a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java @@ -0,0 +1,32 @@ +package com.thealgorithms.backtracking; + +import java.util.List; +import java.util.TreeSet; + +/** + * Finds all permutations of 1...n of length k + * @author TheClerici (<a href="https://github.com/TheClerici">git-TheClerici</a>) + */ +public final class ArrayCombination { + private ArrayCombination() { + } + private static int length; + + /** + * Find all combinations of 1..n by creating an array and using backtracking in Combination.java + * @param n max value of the array. + * @param k length of combination + * @return a list of all combinations of length k. If k == 0, return null. + */ + public static List<TreeSet<Integer>> combination(int n, int k) { + if (n <= 0) { + return null; + } + length = k; + Integer[] arr = new Integer[n]; + for (int i = 1; i <= n; i++) { + arr[i - 1] = i; + } + return Combination.combination(arr, length); + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/Combination.java b/Java/src/main/java/com/thealgorithms/backtracking/Combination.java new file mode 100644 index 000000000000..80c11ce737fa --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/Combination.java @@ -0,0 +1,60 @@ +package com.thealgorithms.backtracking; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.TreeSet; + +/** + * Finds all permutations of given array + * @author Alan Piao (<a href="https://github.com/cpiao3">git-Alan Piao</a>) + */ +public final class Combination { + private Combination() { + } + + private static int length; + + /** + * Find all combinations of given array using backtracking + * @param arr the array. + * @param n length of combination + * @param <T> the type of elements in the array. + * @return a list of all combinations of length n. If n == 0, return null. + */ + public static <T> List<TreeSet<T>> combination(T[] arr, int n) { + if (n == 0) { + return null; + } + length = n; + T[] array = arr.clone(); + Arrays.sort(array); + List<TreeSet<T>> result = new LinkedList<>(); + backtracking(array, 0, new TreeSet<T>(), result); + return result; + } + + /** + * Backtrack all possible combinations of a given array + * @param arr the array. + * @param index the starting index. + * @param currSet set that tracks current combination + * @param result the list contains all combination. + * @param <T> the type of elements in the array. + */ + private static <T> void backtracking(T[] arr, int index, TreeSet<T> currSet, List<TreeSet<T>> result) { + if (index + length - currSet.size() > arr.length) return; + if (length - 1 == currSet.size()) { + for (int i = index; i < arr.length; i++) { + currSet.add(arr[i]); + result.add((TreeSet<T>) currSet.clone()); + currSet.remove(arr[i]); + } + } + for (int i = index; i < arr.length; i++) { + currSet.add(arr[i]); + backtracking(arr, i + 1, currSet, result); + currSet.remove(arr[i]); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/FloodFill.java b/Java/src/main/java/com/thealgorithms/backtracking/FloodFill.java new file mode 100644 index 000000000000..c8219ca8ba7e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/FloodFill.java @@ -0,0 +1,62 @@ +package com.thealgorithms.backtracking; + +/** + * Java program for Flood fill algorithm. + * @author Akshay Dubey (<a href="https://github.com/itsAkshayDubey">Git-Akshay Dubey</a>) + */ +public final class FloodFill { + private FloodFill() { + } + + /** + * Get the color at the given coordinates of a 2D image + * + * @param image The image to be filled + * @param x The x co-ordinate of which color is to be obtained + * @param y The y co-ordinate of which color is to be obtained + */ + + public static int getPixel(final int[][] image, final int x, final int y) { + return image[x][y]; + } + + /** + * Put the color at the given coordinates of a 2D image + * + * @param image The image to be filled + * @param x The x co-ordinate at which color is to be filled + * @param y The y co-ordinate at which color is to be filled + */ + public static void putPixel(final int[][] image, final int x, final int y, final int newColor) { + image[x][y] = newColor; + } + + /** + * Fill the 2D image with new color + * + * @param image The image to be filled + * @param x The x co-ordinate at which color is to be filled + * @param y The y co-ordinate at which color is to be filled + * @param newColor The new color which to be filled in the image + * @param oldColor The old color which is to be replaced in the image + */ + public static void floodFill(final int[][] image, final int x, final int y, final int newColor, final int oldColor) { + if (newColor == oldColor || x < 0 || x >= image.length || y < 0 || y >= image[x].length || getPixel(image, x, y) != oldColor) { + return; + } + + putPixel(image, x, y, newColor); + + /* Recursively check for horizontally & vertically adjacent coordinates */ + floodFill(image, x + 1, y, newColor, oldColor); + floodFill(image, x - 1, y, newColor, oldColor); + floodFill(image, x, y + 1, newColor, oldColor); + floodFill(image, x, y - 1, newColor, oldColor); + + /* Recursively check for diagonally adjacent coordinates */ + floodFill(image, x + 1, y - 1, newColor, oldColor); + floodFill(image, x - 1, y + 1, newColor, oldColor); + floodFill(image, x + 1, y + 1, newColor, oldColor); + floodFill(image, x - 1, y - 1, newColor, oldColor); + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/KnightsTour.java b/Java/src/main/java/com/thealgorithms/backtracking/KnightsTour.java new file mode 100644 index 000000000000..2287b39da385 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/KnightsTour.java @@ -0,0 +1,149 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/* + * Problem Statement: - + + Given a N*N board with the Knight placed on the first block of an empty board. Moving according + to the rules of chess knight must visit each square exactly once. Print the order of each cell in + which they are visited. + + Example: - + + Input : N = 8 + + Output: + 0 59 38 33 30 17 8 63 + 37 34 31 60 9 62 29 16 + 58 1 36 39 32 27 18 7 + 35 48 41 26 61 10 15 28 + 42 57 2 49 40 23 6 19 + 47 50 45 54 25 20 11 14 + 56 43 52 3 22 13 24 5 + 51 46 55 44 53 4 21 12 + + */ +public final class KnightsTour { + private KnightsTour() { + } + + private static final int BASE = 12; + private static final int[][] MOVES = { + {1, -2}, + {2, -1}, + {2, 1}, + {1, 2}, + {-1, 2}, + {-2, 1}, + {-2, -1}, + {-1, -2}, + }; // Possible moves by knight on chess + private static int[][] grid; // chess grid + private static int total; // total squares in chess + + 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) { + 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)) { + printResult(); + } else { + System.out.println("no result"); + } + } + + // Return True when solvable + private static boolean solve(int row, int column, int count) { + if (count > total) { + return true; + } + + List<int[]> neighbor = neighbors(row, column); + + if (neighbor.isEmpty() && count != total) { + return false; + } + + neighbor.sort(Comparator.comparingInt(a -> a[2])); + + for (int[] nb : neighbor) { + row = nb[0]; + column = nb[1]; + grid[row][column] = count; + if (!orphanDetected(count, row, column) && solve(row, column, count + 1)) { + return true; + } + grid[row][column] = 0; + } + + return false; + } + + // Returns List of neighbours + private static List<int[]> neighbors(int row, int column) { + List<int[]> neighbour = new ArrayList<>(); + + for (int[] m : MOVES) { + int x = m[0]; + int y = m[1]; + if (grid[row + y][column + x] == 0) { + int num = countNeighbors(row + y, column + x); + neighbour.add(new int[] {row + y, column + x, num}); + } + } + return neighbour; + } + + // 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) { + num++; + } + } + return num; + } + + // Returns true if it is orphan + private static boolean orphanDetected(int count, int row, int column) { + if (count < total - 1) { + List<int[]> neighbor = neighbors(row, column); + for (int[] nb : neighbor) { + if (countNeighbors(nb[0], nb[1]) == 0) { + return true; + } + } + } + return false; + } + + // Prints the result grid + private static void printResult() { + for (int[] row : grid) { + for (int i : row) { + if (i == -1) { + continue; + } + System.out.printf("%2d ", i); + } + System.out.println(); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/MColoring.java b/Java/src/main/java/com/thealgorithms/backtracking/MColoring.java new file mode 100644 index 000000000000..20c42e59e8a1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/MColoring.java @@ -0,0 +1,75 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; + +/** + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ +class Node { + int color = 1; + Set<Integer> edges = new HashSet<Integer>(); +} + +public final class MColoring { + private MColoring() { + } + static int possiblePaint(ArrayList<Node> nodes, int n, int m) { + + // Create a visited array of n nodes + ArrayList<Integer> visited = new ArrayList<Integer>(); + for (int i = 0; i < n + 1; i++) { + visited.add(0); + } + + // maxColors used till now are 1 as + // all nodes are painted color 1 + int maxColors = 1; + + for (int sv = 1; sv <= n; sv++) { + if (visited.get(sv) > 0) { + continue; + } + + // If the starting point is unvisited, + // mark it visited and push it in queue + visited.set(sv, 1); + Queue<Integer> q = new LinkedList<>(); + q.add(sv); + + // BFS + while (q.size() != 0) { + int top = q.peek(); + q.remove(); + + // Checking all adjacent nodes + // to "top" edge in our queue + for (int it : nodes.get(top).edges) { + + // If the color of the + // adjacent node is same, increase it by + // 1 + if (nodes.get(top).color == nodes.get(it).color) { + nodes.get(it).color += 1; + } + + // If number of colors used exceeds m, + // return 0 + maxColors = Math.max(maxColors, Math.max(nodes.get(top).color, nodes.get(it).color)); + if (maxColors > m) return 0; + + // If the adjacent node is not visited, + // mark it visited and push it in queue + if (visited.get(it) == 0) { + visited.set(it, 1); + q.add(it); + } + } + } + } + return 1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java b/Java/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java new file mode 100644 index 000000000000..f7eae01e449a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java @@ -0,0 +1,152 @@ +package com.thealgorithms.backtracking; + +public final class MazeRecursion { + private MazeRecursion() { + } + + public static void mazeRecursion() { + // First create a 2 dimensions array to mimic a maze map + int[][] map = new int[8][7]; + int[][] map2 = new int[8][7]; + + // We use 1 to indicate wall + // Set the ceiling and floor to 1 + for (int i = 0; i < 7; i++) { + map[0][i] = 1; + map[7][i] = 1; + } + + // Then we set the left and right wall to 1 + for (int i = 0; i < 8; i++) { + map[i][0] = 1; + map[i][6] = 1; + } + + // Now we have created a maze with its wall initialized + + // Here we set the obstacle + map[3][1] = 1; + map[3][2] = 1; + + // Print the current map + System.out.println("The condition of the map: "); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 7; j++) { + System.out.print(map[i][j] + " "); + } + System.out.println(); + } + + // clone another map for setWay2 method + for (int i = 0; i < map.length; i++) { + System.arraycopy(map[i], 0, map2[i], 0, map[i].length); + } + + // By using recursive backtracking to let your ball(target) find its way in the + // maze + // The first parameter is the map + // Second parameter is x coordinate of your target + // Third parameter is the y coordinate of your target + setWay(map, 1, 1); + setWay2(map2, 1, 1); + + // Print out the new map1, with the ball footprint + System.out.println("After the ball goes through the map1,show the current map1 condition"); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 7; j++) { + System.out.print(map[i][j] + " "); + } + System.out.println(); + } + + // Print out the new map2, with the ball footprint + System.out.println("After the ball goes through the map2,show the current map2 condition"); + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 7; j++) { + System.out.print(map2[i][j] + " "); + } + System.out.println(); + } + } + + /** + * Using recursive path finding to help the ball find its way in the maze + * Description: + * 1. map (means the maze) + * 2. i, j (means the initial coordinate of the ball in the maze) + * 3. if the ball can reach the end of maze, that is position of map[6][5], + * means the we have found a path for the ball + * 4. Additional Information: 0 in the map[i][j] means the ball has not gone + * through this position, 1 means the wall, 2 means the path is feasible, 3 + * means the ball has gone through the path but this path is dead end + * 5. We will need strategy for the ball to pass through the maze for example: + * Down -> Right -> Up -> Left, if the path doesn't work, then backtrack + * + * @author OngLipWei + * @version Jun 23, 2021 11:36:14 AM + * @param map The maze + * @param i x coordinate of your ball(target) + * @param j y coordinate of your ball(target) + * @return If we did find a path for the ball,return true,else false + */ + public static boolean setWay(int[][] map, int i, int j) { + if (map[6][5] == 2) { // means the ball find its path, ending condition + return true; + } + if (map[i][j] == 0) { // if the ball haven't gone through this point + // then the ball follows the move strategy : down -> right -> up -> left + map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2 + // first。 + if (setWay(map, i + 1, j)) { // go down + return true; + } else if (setWay(map, i, j + 1)) { // go right + return true; + } else if (setWay(map, i - 1, j)) { // go up + return true; + } else if (setWay(map, i, j - 1)) { // go left + return true; + } else { + // means that the current point is the dead end, the ball cannot proceed, set + // the current point to 3 and return false, the backtracking will start, it will + // go to the previous step and check for feasible path again + map[i][j] = 3; + return false; + } + } else { // if the map[i][j] != 0 , it will probably be 1,2,3, return false because the + // ball cannot hit the wall, cannot go to the path that has gone though before, + // and cannot head to deadened. + return false; + } + } + + // Here is another move strategy for the ball: up->right->down->left + public static boolean setWay2(int[][] map, int i, int j) { + if (map[6][5] == 2) { // means the ball find its path, ending condition + return true; + } + if (map[i][j] == 0) { // if the ball haven't gone through this point + // then the ball follows the move strategy : up->right->down->left + map[i][j] = 2; // we assume that this path is feasible first, set the current point to 2 + // first。 + if (setWay2(map, i - 1, j)) { // go up + return true; + } else if (setWay2(map, i, j + 1)) { // go right + return true; + } else if (setWay2(map, i + 1, j)) { // go down + return true; + } else if (setWay2(map, i, j - 1)) { // go left + return true; + } else { + // means that the current point is the dead end, the ball cannot proceed, set + // the current point to 3 and return false, the backtracking will start, it will + // go to the previous step and check for feasible path again + map[i][j] = 3; + return false; + } + } else { // if the map[i][j] != 0 , it will probably be 1,2,3, return false because the + // ball cannot hit the wall, cannot go to the path that has gone through before, + // and cannot head to deadend. + return false; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/NQueens.java b/Java/src/main/java/com/thealgorithms/backtracking/NQueens.java new file mode 100644 index 000000000000..e21a8bb7174c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/NQueens.java @@ -0,0 +1,114 @@ +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." + * + * Arrangement: 2 "..Q...", ".....Q", ".Q....", "....Q.", "Q.....", "...Q.." + * + * Arrangement: 3 "...Q..", "Q.....", "....Q.", ".Q....", ".....Q", "..Q..." + * + * Arrangement: 4 "....Q.", "..Q...", "Q.....", ".....Q", "...Q..", ".Q...." + * + * 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 + * + * 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 + */ +public final class NQueens { + private NQueens() { + } + + public static void main(String[] args) { + placeQueens(1); + placeQueens(2); + placeQueens(3); + placeQueens(4); + placeQueens(5); + placeQueens(6); + } + + public static void placeQueens(final int queens) { + List<List<String>> arrangements = new ArrayList<List<String>>(); + getSolution(queens, arrangements, new int[queens], 0); + if (arrangements.isEmpty()) { + System.out.println("There is no way to place " + queens + " queens on board of size " + queens + "x" + queens); + } else { + System.out.println("Arrangement for placing " + queens + " queens"); + } + for (List<String> arrangement : arrangements) { + arrangement.forEach(System.out::println); + System.out.println(); + } + } + + /** + * 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. + * @param columnIndex: This is the column in which queen is being placed + */ + private static void getSolution(int boardSize, List<List<String>> solutions, int[] columns, int columnIndex) { + if (columnIndex == boardSize) { + // this means that all queens have been placed + List<String> sol = new ArrayList<String>(); + for (int i = 0; i < boardSize; i++) { + StringBuilder sb = new StringBuilder(); + for (int j = 0; j < boardSize; j++) { + sb.append(j == columns[i] ? "Q" : "."); + } + sol.add(sb.toString()); + } + solutions.add(sol); + return; + } + + // This loop tries to place queen in a row one by one + for (int rowIndex = 0; rowIndex < boardSize; rowIndex++) { + columns[columnIndex] = rowIndex; + if (isPlacedCorrectly(columns, rowIndex, columnIndex)) { + // If queen is placed successfully at rowIndex in column=columnIndex then try + // placing queen in next column + getSolution(boardSize, solutions, columns, columnIndex + 1); + } + } + } + + /** + * 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 + */ + private static boolean isPlacedCorrectly(int[] columns, int rowIndex, int columnIndex) { + for (int i = 0; i < columnIndex; i++) { + int diff = Math.abs(columns[i] - rowIndex); + if (diff == 0 || columnIndex - i == diff) { + return false; + } + } + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java b/Java/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java new file mode 100644 index 000000000000..8bbed4106251 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java @@ -0,0 +1,50 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class generates all valid combinations of parentheses for a given number of pairs using backtracking. + */ +public final class ParenthesesGenerator { + private ParenthesesGenerator() { + } + + /** + * Generates all valid combinations of parentheses for a given number of pairs. + * + * @param n The number of pairs of parentheses. + * @return A list of strings representing valid combinations of parentheses. + * @throws IllegalArgumentException if n is less than 0. + */ + public static List<String> generateParentheses(final int n) { + if (n < 0) { + throw new IllegalArgumentException("The number of pairs of parentheses cannot be nagative"); + } + List<String> result = new ArrayList<>(); + generateParenthesesHelper(result, "", 0, 0, n); + return result; + } + + /** + * Helper function for generating all valid combinations of parentheses recursively. + * + * @param result The list to store valid combinations. + * @param current The current combination being formed. + * @param open The number of open parentheses. + * @param close The number of closed parentheses. + * @param n The total number of pairs of parentheses. + */ + private static void generateParenthesesHelper(List<String> result, final String current, final int open, final int close, final int n) { + if (current.length() == n * 2) { + result.add(current); + return; + } + if (open < n) { + generateParenthesesHelper(result, current + "(", open + 1, close, n); + } + if (close < open) { + generateParenthesesHelper(result, current + ")", open, close + 1, n); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/Permutation.java b/Java/src/main/java/com/thealgorithms/backtracking/Permutation.java new file mode 100644 index 000000000000..21d26e53980f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/Permutation.java @@ -0,0 +1,57 @@ +package com.thealgorithms.backtracking; + +import java.util.LinkedList; +import java.util.List; + +/** + * Finds all permutations of given array + * @author Alan Piao (<a href="https://github.com/cpiao3">Git-Alan Piao</a>) + */ +public final class Permutation { + private Permutation() { + } + + /** + * Find all permutations of given array using backtracking + * @param arr the array. + * @param <T> the type of elements in the array. + * @return a list of all permutations. + */ + public static <T> List<T[]> permutation(T[] arr) { + T[] array = arr.clone(); + List<T[]> result = new LinkedList<>(); + backtracking(array, 0, result); + return result; + } + + /** + * Backtrack all possible orders of a given array + * @param arr the array. + * @param index the starting index. + * @param result the list contains all permutations. + * @param <T> the type of elements in the array. + */ + private static <T> void backtracking(T[] arr, int index, List<T[]> result) { + if (index == arr.length) { + result.add(arr.clone()); + } + for (int i = index; i < arr.length; i++) { + swap(index, i, arr); + backtracking(arr, index + 1, result); + swap(index, i, arr); + } + } + + /** + * Swap two element for a given array + * @param a first index + * @param b second index + * @param arr the array. + * @param <T> the type of elements in the array. + */ + private static <T> void swap(int a, int b, T[] arr) { + T temp = arr[a]; + arr[a] = arr[b]; + arr[b] = temp; + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/PowerSum.java b/Java/src/main/java/com/thealgorithms/backtracking/PowerSum.java new file mode 100644 index 000000000000..6617ea326a1c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/PowerSum.java @@ -0,0 +1,45 @@ +package com.thealgorithms.backtracking; + +/* + * Problem Statement : + * Find the number of ways that a given integer, N , can be expressed as the sum of the Xth powers + * of unique, natural numbers. For example, if N=100 and X=3, we have to find all combinations of + * unique cubes adding up to 100. The only solution is 1^3+2^3+3^3+4^3. Therefore output will be 1. + */ +public class PowerSum { + + private int count = 0; + private int 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/Java/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java b/Java/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java new file mode 100644 index 000000000000..4a159dbfe0b1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java @@ -0,0 +1,54 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class generates all subsequences for a given list of elements using backtracking + */ +public final class SubsequenceFinder { + private SubsequenceFinder() { + } + + /** + * Find all subsequences of given list using backtracking + * + * @param sequence a list of items on the basis of which we need to generate all subsequences + * @param <T> the type of elements in the array + * @return a list of all subsequences + */ + public static <T> List<List<T>> generateAll(List<T> sequence) { + List<List<T>> allSubSequences = new ArrayList<>(); + if (sequence.isEmpty()) { + allSubSequences.add(new ArrayList<>()); + return allSubSequences; + } + List<T> currentSubsequence = new ArrayList<>(); + backtrack(sequence, currentSubsequence, 0, allSubSequences); + return allSubSequences; + } + + /** + * Iterate through each branch of states + * We know that each state has exactly two branching + * It terminates when it reaches the end of the given sequence + * + * @param sequence all elements + * @param currentSubsequence current subsequence + * @param index current index + * @param allSubSequences contains all sequences + * @param <T> the type of elements which we generate + */ + private static <T> void backtrack(List<T> sequence, List<T> currentSubsequence, final int index, List<List<T>> allSubSequences) { + assert index <= sequence.size(); + if (index == sequence.size()) { + allSubSequences.add(new ArrayList<>(currentSubsequence)); + return; + } + + backtrack(sequence, currentSubsequence, index + 1, allSubSequences); + currentSubsequence.add(sequence.get(index)); + backtrack(sequence, currentSubsequence, index + 1, allSubSequences); + currentSubsequence.removeLast(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/backtracking/WordSearch.java b/Java/src/main/java/com/thealgorithms/backtracking/WordSearch.java new file mode 100644 index 000000000000..4ab81bfd7d67 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/backtracking/WordSearch.java @@ -0,0 +1,75 @@ +package com.thealgorithms.backtracking; + +/* +Word Search Problem (https://en.wikipedia.org/wiki/Word_search) + +Given an m x n grid of characters board and a string word, return true if word exists in the grid. + +The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are +those horizontally or vertically neighboring. The same letter cell may not be used more than once. + +For example, +Given board = + +[ + ['A','B','C','E'], + ['S','F','C','S'], + ['A','D','E','E'] +] +word = "ABCCED", -> returns true, +word = "SEE", -> returns true, +word = "ABCB", -> returns false. +*/ + +/* + Solution + Depth First Search in matrix (as multiple sources possible) with backtracking + like finding cycle in a directed graph. Maintain a record of path + + Tx = O(m * n * 3^L): for each cell, we look at 3 options (not 4 as that one will be visited), we + do it L times Sx = O(L) : stack size is max L +*/ + +public class WordSearch { + private final int[] dx = {0, 0, 1, -1}; + private final int[] dy = {1, -1, 0, 0}; + private boolean[][] visited; + private char[][] board; + private String word; + + private boolean isValid(int x, int y) { + return x >= 0 && x < board.length && y >= 0 && y < board[0].length; + } + + private boolean doDFS(int x, int y, int nextIdx) { + visited[x][y] = true; + if (nextIdx == word.length()) { + return true; + } + for (int i = 0; i < 4; ++i) { + int xi = x + dx[i]; + int yi = y + dy[i]; + if (isValid(xi, yi) && board[xi][yi] == word.charAt(nextIdx) && !visited[xi][yi]) { + boolean exists = doDFS(xi, yi, nextIdx + 1); + if (exists) return true; + } + } + visited[x][y] = false; + return false; + } + + public boolean exist(char[][] board, String word) { + this.board = board; + this.word = word; + for (int i = 0; i < board.length; ++i) { + for (int j = 0; j < board[0].length; ++j) { + if (board[i][j] == word.charAt(0)) { + visited = new boolean[board.length][board[0].length]; + boolean exists = doDFS(i, j, 1); + if (exists) return true; + } + } + } + return false; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java new file mode 100644 index 000000000000..40b3097b1276 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java @@ -0,0 +1,15 @@ +package com.thealgorithms.bitmanipulation; + +public final class BitSwap { + private BitSwap() { + } + /* + * @brief Swaps the bits at the position posA and posB from data + */ + public static int bitSwap(int data, final int posA, final int posB) { + if (SingleBitOperations.getBit(data, posA) != SingleBitOperations.getBit(data, posB)) { + data ^= (1 << posA) ^ (1 << posB); + } + return data; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java new file mode 100644 index 000000000000..6b53b1aa182b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java @@ -0,0 +1,32 @@ +package com.thealgorithms.bitmanipulation; +import java.util.Optional; + +/** + * Find Highest Set Bit + * This class provides a function calculating the position (or index) + * of the most significant bit being set to 1 in a given integer. + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class HighestSetBit { + private HighestSetBit() { + } + + public static Optional<Integer> findHighestSetBit(int num) { + if (num < 0) { + throw new IllegalArgumentException("Input cannot be negative"); + } + + if (num == 0) { + return Optional.empty(); + } + + int position = 0; + while (num > 0) { + num >>= 1; + position++; + } + + return Optional.of(position - 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java new file mode 100644 index 000000000000..b825916a8674 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java @@ -0,0 +1,30 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Find The Index Of Right Most SetBit + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class IndexOfRightMostSetBit { + private IndexOfRightMostSetBit() { + } + public static int indexOfRightMostSetBit(int n) { + if (n == 0) { + return -1; // No set bits + } + + // Handle negative numbers by finding the two's complement + if (n < 0) { + n = -n; + n = n & (~n + 1); // Get the rightmost set bit in positive form + } + + int index = 0; + while ((n & 1) == 0) { + n = n >> 1; + index++; + } + + return index; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java new file mode 100644 index 000000000000..09d5383322ff --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java @@ -0,0 +1,14 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Checks whether a number is even + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class IsEven { + private IsEven() { + } + public static boolean isEven(int number) { + return (number & 1) == 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java new file mode 100644 index 000000000000..54d28d4d22cc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java @@ -0,0 +1,18 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Is number power of 2 + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class IsPowerTwo { + private IsPowerTwo() { + } + public static boolean isPowerTwo(int number) { + if (number <= 0) { + return false; + } + int ans = number & (number - 1); + return ans == 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java new file mode 100644 index 000000000000..07476a8b9476 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java @@ -0,0 +1,19 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Find Non Repeating Number + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class NonRepeatingNumberFinder { + private NonRepeatingNumberFinder() { + } + + public static int findNonRepeatingNumber(int[] arr) { + int result = 0; + for (int num : arr) { + result ^= num; + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java new file mode 100644 index 000000000000..8e0946f0eb23 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java @@ -0,0 +1,15 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Numbers Different Signs + * @author Bama Charan Chhandogi + */ + +public final class NumbersDifferentSigns { + private NumbersDifferentSigns() { + } + + public static boolean differentSigns(int num1, int num2) { + return (num1 ^ num2) < 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java new file mode 100644 index 000000000000..e8f2930d3afe --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java @@ -0,0 +1,22 @@ +package com.thealgorithms.bitmanipulation; + +/** + * Converts any Octal Number to a Binary Number + * @author Bama Charan Chhandogi + */ + +public final class ReverseBits { + private ReverseBits() { + } + + public static int reverseBits(int n) { + int result = 0; + int bitCount = 32; + for (int i = 0; i < bitCount; i++) { + result <<= 1; // Left shift the result to make space for the next bit + result |= (n & 1); // OR operation to set the least significant bit of result with the current bit of n + n >>= 1; // Right shift n to move on to the next bit + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java b/Java/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java new file mode 100644 index 000000000000..a972125a958b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java @@ -0,0 +1,34 @@ +package com.thealgorithms.bitmanipulation; + +/* + * Author: lukasb1b (https://github.com/lukasb1b) + */ + +public final class SingleBitOperations { + private SingleBitOperations() { + } + /** + * Flip the bit at position 'bit' in 'num' + */ + public static int flipBit(final int num, final int bit) { + return num ^ (1 << bit); + } + /** + * Set the bit at position 'bit' to 1 in the 'num' variable + */ + public static int setBit(final int num, final int bit) { + return num | (1 << bit); + } + /** + * Clears the bit located at 'bit' from 'num' + */ + public static int clearBit(final int num, final int bit) { + return num & ~(1 << bit); + } + /** + * Get the bit located at 'bit' from 'num' + */ + public static int getBit(final int num, final int bit) { + return ((num >> bit) & 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/AES.java b/Java/src/main/java/com/thealgorithms/ciphers/AES.java new file mode 100644 index 000000000000..cd04395e1b72 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/AES.java @@ -0,0 +1,2783 @@ +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 final class AES { + private 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, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + BigInteger.ZERO, + }; + + // 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/Java/src/main/java/com/thealgorithms/ciphers/AESEncryption.java b/Java/src/main/java/com/thealgorithms/ciphers/AESEncryption.java new file mode 100644 index 000000000000..14582205442f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/AESEncryption.java @@ -0,0 +1,104 @@ +package com.thealgorithms.ciphers; + +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; + +/** + * 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 final class AESEncryption { + private AESEncryption() { + } + + private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); + private static Cipher aesCipher; + + /** + * 1. Generate a plain text for encryption 2. Get a secret key (printed in + * hexadecimal form). In actual use this must be encrypted and kept safe. + * The same key is required for decryption. + */ + public static void main(String[] args) throws Exception { + String plainText = "Hello World"; + SecretKey secKey = getSecretEncryptionKey(); + byte[] cipherText = encryptText(plainText, secKey); + String decryptedText = decryptText(cipherText, secKey); + + System.out.println("Original Text:" + plainText); + System.out.println("AES Key (Hex Form):" + bytesToHex(secKey.getEncoded())); + System.out.println("Encrypted Text (Hex Form):" + bytesToHex(cipherText)); + System.out.println("Descrypted Text:" + decryptedText); + } + + /** + * 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) + */ + public static SecretKey getSecretEncryptionKey() throws NoSuchAlgorithmException { + KeyGenerator aesKeyGenerator = KeyGenerator.getInstance("AES"); + aesKeyGenerator.init(128); // The AES key size in number of bits + return aesKeyGenerator.generateKey(); + } + + /** + * 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 IllegalBlockSizeException (from Cipher) + */ + public static byte[] encryptText(String plainText, SecretKey secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + // AES defaults to AES/ECB/PKCS5Padding in Java 7 + aesCipher = Cipher.getInstance("AES/GCM/NoPadding"); + aesCipher.init(Cipher.ENCRYPT_MODE, secKey); + return aesCipher.doFinal(plainText.getBytes()); + } + + /** + * Decrypts encrypted byte array using the key used for encryption. + * + * @return plainText + */ + public static String decryptText(byte[] byteCipherText, SecretKey secKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException { + // AES defaults to AES/ECB/PKCS5Padding in Java 7 + Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding"); + GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, aesCipher.getIV()); + decryptionCipher.init(Cipher.DECRYPT_MODE, secKey, gcmParameterSpec); + byte[] bytePlainText = decryptionCipher.doFinal(byteCipherText); + return new String(bytePlainText); + } + + /** + * 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 + */ + public static String bytesToHex(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = HEX_ARRAY[v >>> 4]; + hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F]; + } + return new String(hexChars); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/AffineCipher.java b/Java/src/main/java/com/thealgorithms/ciphers/AffineCipher.java new file mode 100644 index 000000000000..bcf3a5b0167b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/AffineCipher.java @@ -0,0 +1,69 @@ +package com.thealgorithms.ciphers; + +final class AffineCipher { + private AffineCipher() { + } + + // Key values of a and b + static int a = 17; + static int b = 20; + + static String encryptMessage(char[] msg) { + /// Cipher Text initially empty + String cipher = ""; + for (int i = 0; i < msg.length; i++) { + // Avoid space to be encrypted + /* applying encryption formula ( a x + b ) mod m + {here x is msg[i] and m is 26} and added 'A' to + bring it in range of ascii alphabet[ 65-90 | A-Z ] */ + if (msg[i] != ' ') { + cipher = cipher + (char) ((((a * (msg[i] - 'A')) + b) % 26) + 'A'); + } else { // else simply append space character + cipher += msg[i]; + } + } + return cipher; + } + + static String decryptCipher(String cipher) { + String msg = ""; + int aInv = 0; + int flag = 0; + + // Find a^-1 (the multiplicative inverse of a + // in the group of integers modulo m.) + for (int i = 0; i < 26; i++) { + flag = (a * i) % 26; + + // Check if (a*i)%26 == 1, + // then i will be the multiplicative inverse of a + if (flag == 1) { + aInv = i; + } + } + for (int i = 0; i < cipher.length(); i++) { + /*Applying decryption formula a^-1 ( x - b ) mod m + {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) (((aInv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A'); + } else { // else simply append space character + msg += cipher.charAt(i); + } + } + + return msg; + } + + // Driver code + public static void main(String[] args) { + String msg = "AFFINE CIPHER"; + + // Calling encryption function + String cipherText = encryptMessage(msg.toCharArray()); + System.out.println("Encrypted Message is : " + cipherText); + + // Calling Decryption function + System.out.println("Decrypted Message is: " + decryptCipher(cipherText)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/Blowfish.java b/Java/src/main/java/com/thealgorithms/ciphers/Blowfish.java new file mode 100644 index 000000000000..a8fa6fc56088 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/Blowfish.java @@ -0,0 +1,1236 @@ +package com.thealgorithms.ciphers; + +/* + * Java program for Blowfish Algorithm + * Wikipedia: https://en.wikipedia.org/wiki/Blowfish_(cipher) + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +public class Blowfish { + + // Initializing substitution boxes + String[][] sBox = { + { + "d1310ba6", + "98dfb5ac", + "2ffd72db", + "d01adfb7", + "b8e1afed", + "6a267e96", + "ba7c9045", + "f12c7f99", + "24a19947", + "b3916cf7", + "0801f2e2", + "858efc16", + "636920d8", + "71574e69", + "a458fea3", + "f4933d7e", + "0d95748f", + "728eb658", + "718bcd58", + "82154aee", + "7b54a41d", + "c25a59b5", + "9c30d539", + "2af26013", + "c5d1b023", + "286085f0", + "ca417918", + "b8db38ef", + "8e79dcb0", + "603a180e", + "6c9e0e8b", + "b01e8a3e", + "d71577c1", + "bd314b27", + "78af2fda", + "55605c60", + "e65525f3", + "aa55ab94", + "57489862", + "63e81440", + "55ca396a", + "2aab10b6", + "b4cc5c34", + "1141e8ce", + "a15486af", + "7c72e993", + "b3ee1411", + "636fbc2a", + "2ba9c55d", + "741831f6", + "ce5c3e16", + "9b87931e", + "afd6ba33", + "6c24cf5c", + "7a325381", + "28958677", + "3b8f4898", + "6b4bb9af", + "c4bfe81b", + "66282193", + "61d809cc", + "fb21a991", + "487cac60", + "5dec8032", + "ef845d5d", + "e98575b1", + "dc262302", + "eb651b88", + "23893e81", + "d396acc5", + "0f6d6ff3", + "83f44239", + "2e0b4482", + "a4842004", + "69c8f04a", + "9e1f9b5e", + "21c66842", + "f6e96c9a", + "670c9c61", + "abd388f0", + "6a51a0d2", + "d8542f68", + "960fa728", + "ab5133a3", + "6eef0b6c", + "137a3be4", + "ba3bf050", + "7efb2a98", + "a1f1651d", + "39af0176", + "66ca593e", + "82430e88", + "8cee8619", + "456f9fb4", + "7d84a5c3", + "3b8b5ebe", + "e06f75d8", + "85c12073", + "401a449f", + "56c16aa6", + "4ed3aa62", + "363f7706", + "1bfedf72", + "429b023d", + "37d0d724", + "d00a1248", + "db0fead3", + "49f1c09b", + "075372c9", + "80991b7b", + "25d479d8", + "f6e8def7", + "e3fe501a", + "b6794c3b", + "976ce0bd", + "04c006ba", + "c1a94fb6", + "409f60c4", + "5e5c9ec2", + "196a2463", + "68fb6faf", + "3e6c53b5", + "1339b2eb", + "3b52ec6f", + "6dfc511f", + "9b30952c", + "cc814544", + "af5ebd09", + "bee3d004", + "de334afd", + "660f2807", + "192e4bb3", + "c0cba857", + "45c8740f", + "d20b5f39", + "b9d3fbdb", + "5579c0bd", + "1a60320a", + "d6a100c6", + "402c7279", + "679f25fe", + "fb1fa3cc", + "8ea5e9f8", + "db3222f8", + "3c7516df", + "fd616b15", + "2f501ec8", + "ad0552ab", + "323db5fa", + "fd238760", + "53317b48", + "3e00df82", + "9e5c57bb", + "ca6f8ca0", + "1a87562e", + "df1769db", + "d542a8f6", + "287effc3", + "ac6732c6", + "8c4f5573", + "695b27b0", + "bbca58c8", + "e1ffa35d", + "b8f011a0", + "10fa3d98", + "fd2183b8", + "4afcb56c", + "2dd1d35b", + "9a53e479", + "b6f84565", + "d28e49bc", + "4bfb9790", + "e1ddf2da", + "a4cb7e33", + "62fb1341", + "cee4c6e8", + "ef20cada", + "36774c01", + "d07e9efe", + "2bf11fb4", + "95dbda4d", + "ae909198", + "eaad8e71", + "6b93d5a0", + "d08ed1d0", + "afc725e0", + "8e3c5b2f", + "8e7594b7", + "8ff6e2fb", + "f2122b64", + "8888b812", + "900df01c", + "4fad5ea0", + "688fc31c", + "d1cff191", + "b3a8c1ad", + "2f2f2218", + "be0e1777", + "ea752dfe", + "8b021fa1", + "e5a0cc0f", + "b56f74e8", + "18acf3d6", + "ce89e299", + "b4a84fe0", + "fd13e0b7", + "7cc43b81", + "d2ada8d9", + "165fa266", + "80957705", + "93cc7314", + "211a1477", + "e6ad2065", + "77b5fa86", + "c75442f5", + "fb9d35cf", + "ebcdaf0c", + "7b3e89a0", + "d6411bd3", + "ae1e7e49", + "00250e2d", + "2071b35e", + "226800bb", + "57b8e0af", + "2464369b", + "f009b91e", + "5563911d", + "59dfa6aa", + "78c14389", + "d95a537f", + "207d5ba2", + "02e5b9c5", + "83260376", + "6295cfa9", + "11c81968", + "4e734a41", + "b3472dca", + "7b14a94a", + "1b510052", + "9a532915", + "d60f573f", + "bc9bc6e4", + "2b60a476", + "81e67400", + "08ba6fb5", + "571be91f", + "f296ec6b", + "2a0dd915", + "b6636521", + "e7b9f9b6", + "ff34052e", + "c5855664", + "53b02d5d", + "a99f8fa1", + "08ba4799", + "6e85076a", + }, + { + "4b7a70e9", + "b5b32944", + "db75092e", + "c4192623", + "ad6ea6b0", + "49a7df7d", + "9cee60b8", + "8fedb266", + "ecaa8c71", + "699a17ff", + "5664526c", + "c2b19ee1", + "193602a5", + "75094c29", + "a0591340", + "e4183a3e", + "3f54989a", + "5b429d65", + "6b8fe4d6", + "99f73fd6", + "a1d29c07", + "efe830f5", + "4d2d38e6", + "f0255dc1", + "4cdd2086", + "8470eb26", + "6382e9c6", + "021ecc5e", + "09686b3f", + "3ebaefc9", + "3c971814", + "6b6a70a1", + "687f3584", + "52a0e286", + "b79c5305", + "aa500737", + "3e07841c", + "7fdeae5c", + "8e7d44ec", + "5716f2b8", + "b03ada37", + "f0500c0d", + "f01c1f04", + "0200b3ff", + "ae0cf51a", + "3cb574b2", + "25837a58", + "dc0921bd", + "d19113f9", + "7ca92ff6", + "94324773", + "22f54701", + "3ae5e581", + "37c2dadc", + "c8b57634", + "9af3dda7", + "a9446146", + "0fd0030e", + "ecc8c73e", + "a4751e41", + "e238cd99", + "3bea0e2f", + "3280bba1", + "183eb331", + "4e548b38", + "4f6db908", + "6f420d03", + "f60a04bf", + "2cb81290", + "24977c79", + "5679b072", + "bcaf89af", + "de9a771f", + "d9930810", + "b38bae12", + "dccf3f2e", + "5512721f", + "2e6b7124", + "501adde6", + "9f84cd87", + "7a584718", + "7408da17", + "bc9f9abc", + "e94b7d8c", + "ec7aec3a", + "db851dfa", + "63094366", + "c464c3d2", + "ef1c1847", + "3215d908", + "dd433b37", + "24c2ba16", + "12a14d43", + "2a65c451", + "50940002", + "133ae4dd", + "71dff89e", + "10314e55", + "81ac77d6", + "5f11199b", + "043556f1", + "d7a3c76b", + "3c11183b", + "5924a509", + "f28fe6ed", + "97f1fbfa", + "9ebabf2c", + "1e153c6e", + "86e34570", + "eae96fb1", + "860e5e0a", + "5a3e2ab3", + "771fe71c", + "4e3d06fa", + "2965dcb9", + "99e71d0f", + "803e89d6", + "5266c825", + "2e4cc978", + "9c10b36a", + "c6150eba", + "94e2ea78", + "a5fc3c53", + "1e0a2df4", + "f2f74ea7", + "361d2b3d", + "1939260f", + "19c27960", + "5223a708", + "f71312b6", + "ebadfe6e", + "eac31f66", + "e3bc4595", + "a67bc883", + "b17f37d1", + "018cff28", + "c332ddef", + "be6c5aa5", + "65582185", + "68ab9802", + "eecea50f", + "db2f953b", + "2aef7dad", + "5b6e2f84", + "1521b628", + "29076170", + "ecdd4775", + "619f1510", + "13cca830", + "eb61bd96", + "0334fe1e", + "aa0363cf", + "b5735c90", + "4c70a239", + "d59e9e0b", + "cbaade14", + "eecc86bc", + "60622ca7", + "9cab5cab", + "b2f3846e", + "648b1eaf", + "19bdf0ca", + "a02369b9", + "655abb50", + "40685a32", + "3c2ab4b3", + "319ee9d5", + "c021b8f7", + "9b540b19", + "875fa099", + "95f7997e", + "623d7da8", + "f837889a", + "97e32d77", + "11ed935f", + "16681281", + "0e358829", + "c7e61fd6", + "96dedfa1", + "7858ba99", + "57f584a5", + "1b227263", + "9b83c3ff", + "1ac24696", + "cdb30aeb", + "532e3054", + "8fd948e4", + "6dbc3128", + "58ebf2ef", + "34c6ffea", + "fe28ed61", + "ee7c3c73", + "5d4a14d9", + "e864b7e3", + "42105d14", + "203e13e0", + "45eee2b6", + "a3aaabea", + "db6c4f15", + "facb4fd0", + "c742f442", + "ef6abbb5", + "654f3b1d", + "41cd2105", + "d81e799e", + "86854dc7", + "e44b476a", + "3d816250", + "cf62a1f2", + "5b8d2646", + "fc8883a0", + "c1c7b6a3", + "7f1524c3", + "69cb7492", + "47848a0b", + "5692b285", + "095bbf00", + "ad19489d", + "1462b174", + "23820e00", + "58428d2a", + "0c55f5ea", + "1dadf43e", + "233f7061", + "3372f092", + "8d937e41", + "d65fecf1", + "6c223bdb", + "7cde3759", + "cbee7460", + "4085f2a7", + "ce77326e", + "a6078084", + "19f8509e", + "e8efd855", + "61d99735", + "a969a7aa", + "c50c06c2", + "5a04abfc", + "800bcadc", + "9e447a2e", + "c3453484", + "fdd56705", + "0e1e9ec9", + "db73dbd3", + "105588cd", + "675fda79", + "e3674340", + "c5c43465", + "713e38d8", + "3d28f89e", + "f16dff20", + "153e21e7", + "8fb03d4a", + "e6e39f2b", + "db83adf7", + }, + { + "e93d5a68", + "948140f7", + "f64c261c", + "94692934", + "411520f7", + "7602d4f7", + "bcf46b2e", + "d4a20068", + "d4082471", + "3320f46a", + "43b7d4b7", + "500061af", + "1e39f62e", + "97244546", + "14214f74", + "bf8b8840", + "4d95fc1d", + "96b591af", + "70f4ddd3", + "66a02f45", + "bfbc09ec", + "03bd9785", + "7fac6dd0", + "31cb8504", + "96eb27b3", + "55fd3941", + "da2547e6", + "abca0a9a", + "28507825", + "530429f4", + "0a2c86da", + "e9b66dfb", + "68dc1462", + "d7486900", + "680ec0a4", + "27a18dee", + "4f3ffea2", + "e887ad8c", + "b58ce006", + "7af4d6b6", + "aace1e7c", + "d3375fec", + "ce78a399", + "406b2a42", + "20fe9e35", + "d9f385b9", + "ee39d7ab", + "3b124e8b", + "1dc9faf7", + "4b6d1856", + "26a36631", + "eae397b2", + "3a6efa74", + "dd5b4332", + "6841e7f7", + "ca7820fb", + "fb0af54e", + "d8feb397", + "454056ac", + "ba489527", + "55533a3a", + "20838d87", + "fe6ba9b7", + "d096954b", + "55a867bc", + "a1159a58", + "cca92963", + "99e1db33", + "a62a4a56", + "3f3125f9", + "5ef47e1c", + "9029317c", + "fdf8e802", + "04272f70", + "80bb155c", + "05282ce3", + "95c11548", + "e4c66d22", + "48c1133f", + "c70f86dc", + "07f9c9ee", + "41041f0f", + "404779a4", + "5d886e17", + "325f51eb", + "d59bc0d1", + "f2bcc18f", + "41113564", + "257b7834", + "602a9c60", + "dff8e8a3", + "1f636c1b", + "0e12b4c2", + "02e1329e", + "af664fd1", + "cad18115", + "6b2395e0", + "333e92e1", + "3b240b62", + "eebeb922", + "85b2a20e", + "e6ba0d99", + "de720c8c", + "2da2f728", + "d0127845", + "95b794fd", + "647d0862", + "e7ccf5f0", + "5449a36f", + "877d48fa", + "c39dfd27", + "f33e8d1e", + "0a476341", + "992eff74", + "3a6f6eab", + "f4f8fd37", + "a812dc60", + "a1ebddf8", + "991be14c", + "db6e6b0d", + "c67b5510", + "6d672c37", + "2765d43b", + "dcd0e804", + "f1290dc7", + "cc00ffa3", + "b5390f92", + "690fed0b", + "667b9ffb", + "cedb7d9c", + "a091cf0b", + "d9155ea3", + "bb132f88", + "515bad24", + "7b9479bf", + "763bd6eb", + "37392eb3", + "cc115979", + "8026e297", + "f42e312d", + "6842ada7", + "c66a2b3b", + "12754ccc", + "782ef11c", + "6a124237", + "b79251e7", + "06a1bbe6", + "4bfb6350", + "1a6b1018", + "11caedfa", + "3d25bdd8", + "e2e1c3c9", + "44421659", + "0a121386", + "d90cec6e", + "d5abea2a", + "64af674e", + "da86a85f", + "bebfe988", + "64e4c3fe", + "9dbc8057", + "f0f7c086", + "60787bf8", + "6003604d", + "d1fd8346", + "f6381fb0", + "7745ae04", + "d736fccc", + "83426b33", + "f01eab71", + "b0804187", + "3c005e5f", + "77a057be", + "bde8ae24", + "55464299", + "bf582e61", + "4e58f48f", + "f2ddfda2", + "f474ef38", + "8789bdc2", + "5366f9c3", + "c8b38e74", + "b475f255", + "46fcd9b9", + "7aeb2661", + "8b1ddf84", + "846a0e79", + "915f95e2", + "466e598e", + "20b45770", + "8cd55591", + "c902de4c", + "b90bace1", + "bb8205d0", + "11a86248", + "7574a99e", + "b77f19b6", + "e0a9dc09", + "662d09a1", + "c4324633", + "e85a1f02", + "09f0be8c", + "4a99a025", + "1d6efe10", + "1ab93d1d", + "0ba5a4df", + "a186f20f", + "2868f169", + "dcb7da83", + "573906fe", + "a1e2ce9b", + "4fcd7f52", + "50115e01", + "a70683fa", + "a002b5c4", + "0de6d027", + "9af88c27", + "773f8641", + "c3604c06", + "61a806b5", + "f0177a28", + "c0f586e0", + "006058aa", + "30dc7d62", + "11e69ed7", + "2338ea63", + "53c2dd94", + "c2c21634", + "bbcbee56", + "90bcb6de", + "ebfc7da1", + "ce591d76", + "6f05e409", + "4b7c0188", + "39720a3d", + "7c927c24", + "86e3725f", + "724d9db9", + "1ac15bb4", + "d39eb8fc", + "ed545578", + "08fca5b5", + "d83d7cd3", + "4dad0fc4", + "1e50ef5e", + "b161e6f8", + "a28514d9", + "6c51133c", + "6fd5c7e7", + "56e14ec4", + "362abfce", + "ddc6c837", + "d79a3234", + "92638212", + "670efa8e", + "406000e0", + }, + { + "3a39ce37", + "d3faf5cf", + "abc27737", + "5ac52d1b", + "5cb0679e", + "4fa33742", + "d3822740", + "99bc9bbe", + "d5118e9d", + "bf0f7315", + "d62d1c7e", + "c700c47b", + "b78c1b6b", + "21a19045", + "b26eb1be", + "6a366eb4", + "5748ab2f", + "bc946e79", + "c6a376d2", + "6549c2c8", + "530ff8ee", + "468dde7d", + "d5730a1d", + "4cd04dc6", + "2939bbdb", + "a9ba4650", + "ac9526e8", + "be5ee304", + "a1fad5f0", + "6a2d519a", + "63ef8ce2", + "9a86ee22", + "c089c2b8", + "43242ef6", + "a51e03aa", + "9cf2d0a4", + "83c061ba", + "9be96a4d", + "8fe51550", + "ba645bd6", + "2826a2f9", + "a73a3ae1", + "4ba99586", + "ef5562e9", + "c72fefd3", + "f752f7da", + "3f046f69", + "77fa0a59", + "80e4a915", + "87b08601", + "9b09e6ad", + "3b3ee593", + "e990fd5a", + "9e34d797", + "2cf0b7d9", + "022b8b51", + "96d5ac3a", + "017da67d", + "d1cf3ed6", + "7c7d2d28", + "1f9f25cf", + "adf2b89b", + "5ad6b472", + "5a88f54c", + "e029ac71", + "e019a5e6", + "47b0acfd", + "ed93fa9b", + "e8d3c48d", + "283b57cc", + "f8d56629", + "79132e28", + "785f0191", + "ed756055", + "f7960e44", + "e3d35e8c", + "15056dd4", + "88f46dba", + "03a16125", + "0564f0bd", + "c3eb9e15", + "3c9057a2", + "97271aec", + "a93a072a", + "1b3f6d9b", + "1e6321f5", + "f59c66fb", + "26dcf319", + "7533d928", + "b155fdf5", + "03563482", + "8aba3cbb", + "28517711", + "c20ad9f8", + "abcc5167", + "ccad925f", + "4de81751", + "3830dc8e", + "379d5862", + "9320f991", + "ea7a90c2", + "fb3e7bce", + "5121ce64", + "774fbe32", + "a8b6e37e", + "c3293d46", + "48de5369", + "6413e680", + "a2ae0810", + "dd6db224", + "69852dfd", + "09072166", + "b39a460a", + "6445c0dd", + "586cdecf", + "1c20c8ae", + "5bbef7dd", + "1b588d40", + "ccd2017f", + "6bb4e3bb", + "dda26a7e", + "3a59ff45", + "3e350a44", + "bcb4cdd5", + "72eacea8", + "fa6484bb", + "8d6612ae", + "bf3c6f47", + "d29be463", + "542f5d9e", + "aec2771b", + "f64e6370", + "740e0d8d", + "e75b1357", + "f8721671", + "af537d5d", + "4040cb08", + "4eb4e2cc", + "34d2466a", + "0115af84", + "e1b00428", + "95983a1d", + "06b89fb4", + "ce6ea048", + "6f3f3b82", + "3520ab82", + "011a1d4b", + "277227f8", + "611560b1", + "e7933fdc", + "bb3a792b", + "344525bd", + "a08839e1", + "51ce794b", + "2f32c9b7", + "a01fbac9", + "e01cc87e", + "bcc7d1f6", + "cf0111c3", + "a1e8aac7", + "1a908749", + "d44fbd9a", + "d0dadecb", + "d50ada38", + "0339c32a", + "c6913667", + "8df9317c", + "e0b12b4f", + "f79e59b7", + "43f5bb3a", + "f2d519ff", + "27d9459c", + "bf97222c", + "15e6fc2a", + "0f91fc71", + "9b941525", + "fae59361", + "ceb69ceb", + "c2a86459", + "12baa8d1", + "b6c1075e", + "e3056a0c", + "10d25065", + "cb03a442", + "e0ec6e0e", + "1698db3b", + "4c98a0be", + "3278e964", + "9f1f9532", + "e0d392df", + "d3a0342b", + "8971f21e", + "1b0a7441", + "4ba3348c", + "c5be7120", + "c37632d8", + "df359f8d", + "9b992f2e", + "e60b6f47", + "0fe3f11d", + "e54cda54", + "1edad891", + "ce6279cf", + "cd3e7e6f", + "1618b166", + "fd2c1d05", + "848fd2c5", + "f6fb2299", + "f523f357", + "a6327623", + "93a83531", + "56cccd02", + "acf08162", + "5a75ebb5", + "6e163697", + "88d273cc", + "de966292", + "81b949d0", + "4c50901b", + "71c65614", + "e6c6c7bd", + "327a140a", + "45e1d006", + "c3f27b9a", + "c9aa53fd", + "62a80f00", + "bb25bfe2", + "35bdd2f6", + "71126905", + "b2040222", + "b6cbcf7c", + "cd769c2b", + "53113ec0", + "1640e3d3", + "38abbd60", + "2547adf0", + "ba38209c", + "f746ce76", + "77afa1c5", + "20756060", + "85cbfe4e", + "8ae88dd8", + "7aaaf9b0", + "4cf9aa7e", + "1948c25c", + "02fb8a8c", + "01c36ae4", + "d6ebe1f9", + "90d4f869", + "a65cdea0", + "3f09252d", + "c208e69f", + "b74e6132", + "ce77e25b", + "578fdfe3", + "3ac372e6", + }, + }; + + // Initializing subkeys with digits of pi + String[] subKeys = { + "243f6a88", + "85a308d3", + "13198a2e", + "03707344", + "a4093822", + "299f31d0", + "082efa98", + "ec4e6c89", + "452821e6", + "38d01377", + "be5466cf", + "34e90c6c", + "c0ac29b7", + "c97c50dd", + "3f84d5b5", + "b5470917", + "9216d5d9", + "8979fb1b", + }; + + // Initializing modVal to 2^32 + long modVal = 4294967296L; + + /** + * This method returns binary representation of the hexadecimal number passed as parameter + * + * @param hex Number for which binary representation is required + * @return String object which is a binary representation of the hex number passed as parameter + */ + private String hexToBin(String hex) { + String binary = ""; + long num; + String binary4B; + int n = hex.length(); + for (int i = 0; i < n; i++) { + num = Long.parseUnsignedLong(hex.charAt(i) + "", 16); + binary4B = Long.toBinaryString(num); + + binary4B = "0000" + binary4B; + + binary4B = binary4B.substring(binary4B.length() - 4); + binary += binary4B; + } + return binary; + } + + /** + * This method returns hexadecimal representation of the binary number passed as parameter + * + * @param binary Number for which hexadecimal representation is required + * @return String object which is a hexadecimal representation of the binary number passed as + * parameter + */ + private String binToHex(String binary) { + long num = Long.parseUnsignedLong(binary, 2); + String hex = Long.toHexString(num); + while (hex.length() < (binary.length() / 4)) hex = "0" + hex; + + return hex; + } + + /** + * This method returns a string obtained by XOR-ing two strings of same length passed a method + * parameters + * + * @param String a and b are string objects which will be XORed and are to be of same length + * @return String object obtained by XOR operation on String a and String b + * */ + private String xor(String a, String b) { + a = hexToBin(a); + b = hexToBin(b); + String ans = ""; + for (int i = 0; i < a.length(); i++) ans += (char) (((a.charAt(i) - '0') ^ (b.charAt(i) - '0')) + '0'); + ans = binToHex(ans); + return ans; + } + + /** + * This method returns addition of two hexadecimal numbers passed as parameters and moded with + * 2^32 + * + * @param String a and b are hexadecimal numbers + * @return String object which is a is addition that is then moded with 2^32 of hex numbers + * passed as parameters + */ + private String addBin(String a, String b) { + String ans = ""; + long n1 = Long.parseUnsignedLong(a, 16); + long n2 = Long.parseUnsignedLong(b, 16); + n1 = (n1 + n2) % modVal; + ans = Long.toHexString(n1); + ans = "00000000" + ans; + return ans.substring(ans.length() - 8); + } + + /*F-function splits the 32-bit input into four 8-bit quarters + and uses the quarters as input to the S-boxes. + The S-boxes accept 8-bit input and produce 32-bit output. + The outputs are added modulo 232 and XORed to produce the final 32-bit output + */ + private String f(String plainText) { + String[] a = new String[4]; + String ans = ""; + for (int i = 0; i < 8; i += 2) { + // column number for S-box is a 8-bit value + long col = Long.parseUnsignedLong(hexToBin(plainText.substring(i, i + 2)), 2); + a[i / 2] = sBox[i / 2][(int) col]; + } + ans = addBin(a[0], a[1]); + ans = xor(ans, a[2]); + ans = addBin(ans, a[3]); + return ans; + } + + // generate subkeys + private void keyGenerate(String key) { + int j = 0; + for (int i = 0; i < subKeys.length; i++) { + // XOR-ing 32-bit parts of the key with initial subkeys + subKeys[i] = xor(subKeys[i], key.substring(j, j + 8)); + + j = (j + 8) % key.length(); + } + } + + // round function + private String round(int time, String plainText) { + String left; + String right; + left = plainText.substring(0, 8); + right = plainText.substring(8, 16); + left = xor(left, subKeys[time]); + + // output from F function + String fOut = f(left); + + right = xor(fOut, right); + + // swap left and right + return right + left; + } + + /** + * This method returns cipher text for the plaintext passed as the first parameter generated + * using the key passed as the second parameter + * + * @param String plainText is the text which is to be encrypted + * @param String key is the key which is to be used for generating cipher text + * @return String cipherText is the encrypted value + */ + String encrypt(String plainText, String key) { + // generating key + keyGenerate(key); + + for (int i = 0; i < 16; i++) plainText = round(i, plainText); + + // postprocessing + String right = plainText.substring(0, 8); + String left = plainText.substring(8, 16); + right = xor(right, subKeys[16]); + left = xor(left, subKeys[17]); + return left + right; + } + + /** + * This method returns plaintext for the ciphertext passed as the first parameter decoded + * using the key passed as the second parameter + * + * @param String ciphertext is the text which is to be decrypted + * @param String key is the key which is to be used for generating cipher text + * @return String plainText is the decrypted text + */ + String decrypt(String cipherText, String key) { + // generating key + keyGenerate(key); + + for (int i = 17; i > 1; i--) cipherText = round(i, cipherText); + + // postprocessing + String right = cipherText.substring(0, 8); + String left = cipherText.substring(8, 16); + right = xor(right, subKeys[1]); + left = xor(left, subKeys[0]); + return left + right; + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/Caesar.java b/Java/src/main/java/com/thealgorithms/ciphers/Caesar.java new file mode 100644 index 000000000000..61c444cf6463 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/Caesar.java @@ -0,0 +1,96 @@ +package com.thealgorithms.ciphers; + +/** + * 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 + */ +public class Caesar { + + /** + * Encrypt text by shifting every Latin char by add number shift for ASCII + * Example : A + 1 -> B + * + * @return Encrypted message + */ + public String encode(String message, int shift) { + StringBuilder encoded = new StringBuilder(); + + shift %= 26; + + final int length = message.length(); + for (int i = 0; i < length; i++) { + // int current = message.charAt(i); //using char to shift characters because + // ascii + // is in-order latin alphabet + char current = message.charAt(i); // Java law : char + int = char + + if (isCapitalLatinLetter(current)) { + current += shift; + encoded.append((char) (current > 'Z' ? current - 26 : current)); // 26 = number of latin letters + } else if (isSmallLatinLetter(current)) { + current += shift; + encoded.append((char) (current > 'z' ? current - 26 : current)); // 26 = number of latin letters + } else { + encoded.append(current); + } + } + return encoded.toString(); + } + + /** + * Decrypt message by shifting back every Latin char to previous the ASCII + * Example : B - 1 -> A + * + * @return message + */ + public String decode(String encryptedMessage, int shift) { + StringBuilder decoded = new StringBuilder(); + + shift %= 26; + + final int length = encryptedMessage.length(); + for (int i = 0; i < length; i++) { + char current = encryptedMessage.charAt(i); + if (isCapitalLatinLetter(current)) { + current -= shift; + decoded.append((char) (current < 'A' ? current + 26 : current)); // 26 = number of latin letters + } else if (isSmallLatinLetter(current)) { + current -= shift; + decoded.append((char) (current < 'a' ? current + 26 : current)); // 26 = number of latin letters + } else { + decoded.append(current); + } + } + return decoded.toString(); + } + + /** + * @return true if character is capital Latin letter or false for others + */ + private static boolean isCapitalLatinLetter(char c) { + return c >= 'A' && c <= 'Z'; + } + + /** + * @return true if character is small Latin letter or false for others + */ + private static boolean isSmallLatinLetter(char c) { + return c >= 'a' && c <= 'z'; + } + + /** + * @return string array which contains all the possible decoded combination. + */ + public String[] bruteforce(String encryptedMessage) { + String[] listOfAllTheAnswers = new String[27]; + for (int i = 0; i <= 26; i++) { + listOfAllTheAnswers[i] = decode(encryptedMessage, i); + } + + return listOfAllTheAnswers; + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java b/Java/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java new file mode 100644 index 000000000000..e59cfb12d816 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java @@ -0,0 +1,207 @@ +package com.thealgorithms.ciphers; + +import java.util.Objects; + +/** + * Columnar Transposition Cipher Encryption and Decryption. + * + * @author <a href="https://github.com/freitzzz">freitzzz</a> + */ +public final class ColumnarTranspositionCipher { + private ColumnarTranspositionCipher() { + } + + private static String keyword; + private static Object[][] table; + private static String abecedarium; + 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 keyword String with keyword being used + * @return a String with the word encrypted by the Columnar Transposition + * Cipher Rule + */ + public static String encrpyter(String word, String keyword) { + ColumnarTranspositionCipher.keyword = keyword; + abecedariumBuilder(500); + table = tableBuilder(word); + Object[][] sortedTable = sortTable(table); + StringBuilder wordEncrypted = new StringBuilder(); + for (int i = 0; i < sortedTable[i].length; i++) { + for (int j = 1; j < sortedTable.length; j++) { + wordEncrypted.append(sortedTable[j][i]); + } + } + return wordEncrypted.toString(); + } + + /** + * 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 + */ + public static String encrpyter(String word, String keyword, String abecedarium) { + ColumnarTranspositionCipher.keyword = keyword; + ColumnarTranspositionCipher.abecedarium = Objects.requireNonNullElse(abecedarium, ABECEDARIUM); + table = tableBuilder(word); + Object[][] sortedTable = sortTable(table); + StringBuilder wordEncrypted = new StringBuilder(); + for (int i = 0; i < sortedTable[0].length; i++) { + for (int j = 1; j < sortedTable.length; j++) { + wordEncrypted.append(sortedTable[j][i]); + } + } + return wordEncrypted.toString(); + } + + /** + * 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 + */ + public static String decrypter() { + StringBuilder wordDecrypted = new StringBuilder(); + for (int i = 1; i < table.length; i++) { + for (Object item : table[i]) { + wordDecrypted.append(item); + } + } + return wordDecrypted.toString().replaceAll(ENCRYPTION_FIELD, ""); + } + + /** + * 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 + */ + private static Object[][] tableBuilder(String word) { + Object[][] table = new Object[numberOfRows(word) + 1][keyword.length()]; + char[] wordInChards = word.toCharArray(); + // Fils in the respective numbers + table[0] = findElements(); + int charElement = 0; + for (int i = 1; i < table.length; i++) { + for (int j = 0; j < table[i].length; j++) { + if (charElement < wordInChards.length) { + table[i][j] = wordInChards[charElement]; + charElement++; + } else { + table[i][j] = ENCRYPTION_FIELD_CHAR; + } + } + } + return table; + } + + /** + * 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. + */ + private static int numberOfRows(String word) { + if (word.length() / keyword.length() > word.length() / keyword.length()) { + return (word.length() / keyword.length()) + 1; + } else { + return word.length() / keyword.length(); + } + } + + /** + * @return charValues + */ + private static Object[] findElements() { + Object[] charValues = new Object[keyword.length()]; + for (int i = 0; i < charValues.length; i++) { + int charValueIndex = abecedarium.indexOf(keyword.charAt(i)); + charValues[i] = charValueIndex > -1 ? charValueIndex : null; + } + return charValues; + } + + /** + * @return tableSorted + */ + private static Object[][] sortTable(Object[][] table) { + Object[][] tableSorted = new Object[table.length][table[0].length]; + for (int i = 0; i < tableSorted.length; i++) { + System.arraycopy(table[i], 0, tableSorted[i], 0, tableSorted[i].length); + } + for (int i = 0; i < tableSorted[0].length; i++) { + for (int j = i + 1; j < tableSorted[0].length; j++) { + if ((int) tableSorted[0][i] > (int) table[0][j]) { + Object[] column = getColumn(tableSorted, tableSorted.length, i); + switchColumns(tableSorted, j, i, column); + } + } + } + return tableSorted; + } + + /** + * @return columnArray + */ + private static Object[] getColumn(Object[][] table, int rows, int column) { + Object[] columnArray = new Object[rows]; + for (int i = 0; i < rows; i++) { + columnArray[i] = table[i][column]; + } + return columnArray; + } + + private static void switchColumns(Object[][] table, int firstColumnIndex, int secondColumnIndex, Object[] columnToSwitch) { + for (int i = 0; i < table.length; i++) { + table[i][secondColumnIndex] = table[i][firstColumnIndex]; + table[i][firstColumnIndex] = columnToSwitch[i]; + } + } + + /** + * Creates an abecedarium with a specified ascii inded + * + * @param value Number of characters being used based on the ASCII Table + */ + private static void abecedariumBuilder(int value) { + StringBuilder t = new StringBuilder(); + for (int i = 0; i < value; i++) { + t.append((char) i); + } + abecedarium = t.toString(); + } + + private static void showTable() { + for (Object[] table1 : table) { + for (Object item : table1) { + System.out.print(item + " "); + } + System.out.println(); + } + } + + public static void main(String[] args) { + String keywordForExample = "asd215"; + String wordBeingEncrypted = "This is a test of the Columnar Transposition Cipher"; + System.out.println("### Example of Columnar Transposition Cipher ###\n"); + System.out.println("Word being encryped ->>> " + wordBeingEncrypted); + System.out.println("Word encrypted ->>> " + ColumnarTranspositionCipher.encrpyter(wordBeingEncrypted, keywordForExample)); + System.out.println("Word decryped ->>> " + ColumnarTranspositionCipher.decrypter()); + System.out.println("\n### Encrypted Table ###"); + showTable(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/DES.java b/Java/src/main/java/com/thealgorithms/ciphers/DES.java new file mode 100644 index 000000000000..7f3eed70f3c2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/DES.java @@ -0,0 +1,250 @@ +package com.thealgorithms.ciphers; + +/** + * This class is build to demonstrate the application of the DES-algorithm + * (https://en.wikipedia.org/wiki/Data_Encryption_Standard) on a plain English message. The supplied + * key must be in form of a 64 bit binary String. + */ +public class DES { + + private String key; + private final String[] subKeys; + + private void sanitize(String key) { + int length = key.length(); + if (length != 64) { + throw new IllegalArgumentException("DES key must be supplied as a 64 character binary string"); + } + } + + DES(String key) { + sanitize(key); + this.key = key; + subKeys = getSubkeys(key); + } + + public String getKey() { + return this.key; + } + + public void setKey(String key) { + sanitize(key); + this.key = key; + } + + // Permutation table to convert initial 64-bit key to 56 bit key + private static final int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; + + // Lookup table used to shift the initial key, in order to generate the subkeys + private static final int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + + // Table to convert the 56 bit subkeys to 48 bit subkeys + private static final int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; + + // Initial permutation of each 64 but message block + private static final int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; + + // Expansion table to convert right half of message blocks from 32 bits to 48 bits + private static final int[] EXPANSION = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; + + // The eight substitution boxes are defined below + private static final int[][] S1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}; + + private static final int[][] S2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}; + + private static final int[][] S3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}; + + private static final int[][] S4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}; + + private static final int[][] S5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}; + + private static final int[][] S6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}; + + private static final int[][] S7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}; + + private static final int[][] S8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}; + + private static final int[][][] S = {S1, S2, S3, S4, S5, S6, S7, S8}; + + // Permutation table, used in the Feistel function post s-box usage + static final int[] PERMUTATION = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; + + // Table used for final inversion of the message box after 16 rounds of Feistel Function + static final int[] IP_INVERSE = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; + + private String[] getSubkeys(String originalKey) { + StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via pc1 + int i; + int j; + for (i = 0; i < 56; i++) { + permutedKey.append(originalKey.charAt(PC1[i] - 1)); + } + String[] subKeys = new String[16]; + String initialPermutedKey = permutedKey.toString(); + String c0 = initialPermutedKey.substring(0, 28); + String d0 = initialPermutedKey.substring(28); + + // We will now operate on the left and right halves of the permutedKey + for (i = 0; i < 16; i++) { + String cN = c0.substring(KEY_SHIFTS[i]) + c0.substring(0, KEY_SHIFTS[i]); + String dN = d0.substring(KEY_SHIFTS[i]) + d0.substring(0, KEY_SHIFTS[i]); + subKeys[i] = cN + dN; + c0 = cN; // Re-assign the values to create running permutation + d0 = dN; + } + + // Let us shrink the keys to 48 bits (well, characters here) using pc2 + for (i = 0; i < 16; i++) { + String key = subKeys[i]; + permutedKey.setLength(0); + for (j = 0; j < 48; j++) { + permutedKey.append(key.charAt(PC2[j] - 1)); + } + subKeys[i] = permutedKey.toString(); + } + + return subKeys; + } + + private String xOR(String a, String b) { + int i; + int l = a.length(); + StringBuilder xor = new StringBuilder(); + for (i = 0; i < l; i++) { + int firstBit = a.charAt(i) - 48; // 48 is '0' in ascii + int secondBit = b.charAt(i) - 48; + xor.append((firstBit ^ secondBit)); + } + return xor.toString(); + } + + private String createPaddedString(String s, int desiredLength, char pad) { + int i; + int l = s.length(); + StringBuilder paddedString = new StringBuilder(); + int diff = desiredLength - l; + for (i = 0; i < diff; i++) { + paddedString.append(pad); + } + return paddedString.toString(); + } + + private String pad(String s, int desiredLength) { + return createPaddedString(s, desiredLength, '0') + s; + } + + private String padLast(String s, int desiredLength) { + return s + createPaddedString(s, desiredLength, '\u0000'); + } + + private String feistel(String messageBlock, String key) { + int i; + StringBuilder expandedKey = new StringBuilder(); + for (i = 0; i < 48; i++) { + expandedKey.append(messageBlock.charAt(EXPANSION[i] - 1)); + } + String mixedKey = xOR(expandedKey.toString(), key); + StringBuilder substitutedString = new StringBuilder(); + + // Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits + for (i = 0; i < 48; i += 6) { + String block = mixedKey.substring(i, i + 6); + int row = (block.charAt(0) - 48) * 2 + (block.charAt(5) - 48); + int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4 + (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48); + String substitutedBlock = pad(Integer.toBinaryString(S[i / 6][row][col]), 4); + substitutedString.append(substitutedBlock); + } + + StringBuilder permutedString = new StringBuilder(); + for (i = 0; i < 32; i++) { + permutedString.append(substitutedString.charAt(PERMUTATION[i] - 1)); + } + + return permutedString.toString(); + } + + private String encryptBlock(String message, String[] keys) { + StringBuilder permutedMessage = new StringBuilder(); + int i; + for (i = 0; i < 64; i++) { + permutedMessage.append(message.charAt(IP[i] - 1)); + } + String e0 = permutedMessage.substring(0, 32); + String f0 = permutedMessage.substring(32); + + // Iterate 16 times + for (i = 0; i < 16; i++) { + String eN = f0; // Previous Right block + String fN = xOR(e0, feistel(f0, keys[i])); + e0 = eN; + f0 = fN; + } + + String combinedBlock = f0 + e0; // Reverse the 16th block + permutedMessage.setLength(0); + for (i = 0; i < 64; i++) { + permutedMessage.append(combinedBlock.charAt(IP_INVERSE[i] - 1)); + } + return permutedMessage.toString(); + } + + // To decode, we follow the same process as encoding, but with reversed keys + private String decryptBlock(String message, String[] keys) { + String[] reversedKeys = new String[keys.length]; + for (int i = 0; i < keys.length; i++) { + reversedKeys[i] = keys[keys.length - i - 1]; + } + return encryptBlock(message, reversedKeys); + } + + /** + * @param message Message to be encrypted + * @return The encrypted message, as a binary string + */ + public String encrypt(String message) { + StringBuilder encryptedMessage = new StringBuilder(); + int l = message.length(); + int i; + int j; + if (l % 8 != 0) { + int desiredLength = (l / 8 + 1) * 8; + l = desiredLength; + message = padLast(message, desiredLength); + } + + for (i = 0; i < l; i += 8) { + String block = message.substring(i, i + 8); + StringBuilder bitBlock = new StringBuilder(); + byte[] bytes = block.getBytes(); + for (j = 0; j < 8; j++) { + bitBlock.append(pad(Integer.toBinaryString(bytes[j]), 8)); + } + encryptedMessage.append(encryptBlock(bitBlock.toString(), subKeys)); + } + return encryptedMessage.toString(); + } + + /** + * @param message The encrypted string. Expects it to be a multiple of 64 bits, in binary format + * @return The decrypted String, in plain English + */ + public String decrypt(String message) { + StringBuilder decryptedMessage = new StringBuilder(); + int l = message.length(); + int i; + int j; + if (l % 64 != 0) { + throw new IllegalArgumentException("Encrypted message should be a multiple of 64 characters in length"); + } + for (i = 0; i < l; i += 64) { + String block = message.substring(i, i + 64); + String result = decryptBlock(block, subKeys); + byte[] res = new byte[8]; + for (j = 0; j < 64; j += 8) { + res[j / 8] = (byte) Integer.parseInt(result.substring(j, j + 8), 2); + } + decryptedMessage.append(new String(res)); + } + return decryptedMessage.toString().replace("\0", ""); // Get rid of the null bytes used for padding + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/HillCipher.java b/Java/src/main/java/com/thealgorithms/ciphers/HillCipher.java new file mode 100644 index 000000000000..780009c2f1d6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/HillCipher.java @@ -0,0 +1,178 @@ +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 final class HillCipher { + private HillCipher() { + } + + static Scanner userInput = 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 matrixSize = userInput.nextInt(); + System.out.println("Enter Key/encryptionKey matrix "); + int[][] keyMatrix = new int[matrixSize][matrixSize]; + for (int i = 0; i < matrixSize; i++) { + for (int j = 0; j < matrixSize; j++) { + keyMatrix[i][j] = userInput.nextInt(); + } + } + // check if det = 0 + validateDeterminant(keyMatrix, matrixSize); + + int[][] messageVector = new int[matrixSize][1]; + String cipherText = ""; + int[][] cipherMatrix = new int[matrixSize][1]; + int j = 0; + while (j < message.length()) { + for (int i = 0; i < matrixSize; 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; + int i; + for (i = 0; i < matrixSize; i++) { + cipherMatrix[i][0] = 0; + + for (x = 0; x < matrixSize; 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 < matrixSize; 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 = userInput.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] = userInput.nextInt(); + } + } + // check if det = 0 + validateDeterminant(keyMatrix, n); + + // 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; + int 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; + int sign = 1; + int p = 0; + int 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) { + 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 = userInput.nextShort(); + if (sc == 1) { + encrypt(message); + } else if (sc == 2) { + decrypt(message); + } else { + System.out.println("Invalid input, program terminated."); + } + } + + static void validateDeterminant(int[][] keyMatrix, int n) { + if (determinant(keyMatrix, n) % 26 == 0) { + System.out.println("Invalid key, as determinant = 0. Program Terminated"); + } + } + + // Driver code + public static void main(String[] args) { + // Get the message to be encrypted + System.out.println("Enter message"); + String message = userInput.nextLine(); + hillCipher(message); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java b/Java/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java new file mode 100644 index 000000000000..76ceb6dbce31 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/PlayfairCipher.java @@ -0,0 +1,128 @@ +package com.thealgorithms.ciphers; + +public class PlayfairCipher { + + private char[][] matrix; + private String key; + + public PlayfairCipher(String key) { + this.key = key; + generateMatrix(); + } + + public String encrypt(String plaintext) { + plaintext = prepareText(plaintext.replace("J", "I")); + StringBuilder ciphertext = new StringBuilder(); + for (int i = 0; i < plaintext.length(); i += 2) { + char char1 = plaintext.charAt(i); + char char2 = plaintext.charAt(i + 1); + int[] pos1 = findPosition(char1); + int[] pos2 = findPosition(char2); + int row1 = pos1[0]; + int col1 = pos1[1]; + int row2 = pos2[0]; + int col2 = pos2[1]; + if (row1 == row2) { + ciphertext.append(matrix[row1][(col1 + 1) % 5]); + ciphertext.append(matrix[row2][(col2 + 1) % 5]); + } else if (col1 == col2) { + ciphertext.append(matrix[(row1 + 1) % 5][col1]); + ciphertext.append(matrix[(row2 + 1) % 5][col2]); + } else { + ciphertext.append(matrix[row1][col2]); + ciphertext.append(matrix[row2][col1]); + } + } + return ciphertext.toString(); + } + + public String decrypt(String ciphertext) { + StringBuilder plaintext = new StringBuilder(); + for (int i = 0; i < ciphertext.length(); i += 2) { + char char1 = ciphertext.charAt(i); + char char2 = ciphertext.charAt(i + 1); + int[] pos1 = findPosition(char1); + int[] pos2 = findPosition(char2); + int row1 = pos1[0]; + int col1 = pos1[1]; + int row2 = pos2[0]; + int col2 = pos2[1]; + if (row1 == row2) { + plaintext.append(matrix[row1][(col1 + 4) % 5]); + plaintext.append(matrix[row2][(col2 + 4) % 5]); + } else if (col1 == col2) { + plaintext.append(matrix[(row1 + 4) % 5][col1]); + plaintext.append(matrix[(row2 + 4) % 5][col2]); + } else { + plaintext.append(matrix[row1][col2]); + plaintext.append(matrix[row2][col1]); + } + } + return plaintext.toString(); + } + + private void generateMatrix() { + String keyWithoutDuplicates = removeDuplicateChars(key + "ABCDEFGHIKLMNOPQRSTUVWXYZ"); + matrix = new char[5][5]; + int index = 0; + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + matrix[i][j] = keyWithoutDuplicates.charAt(index); + index++; + } + } + } + + private String removeDuplicateChars(String str) { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + if (result.indexOf(String.valueOf(str.charAt(i))) == -1) { + result.append(str.charAt(i)); + } + } + return result.toString(); + } + + private String prepareText(String text) { + text = text.toUpperCase().replaceAll("[^A-Z]", ""); + StringBuilder preparedText = new StringBuilder(); + char prevChar = '\0'; + for (char c : text.toCharArray()) { + if (c != prevChar) { + preparedText.append(c); + prevChar = c; + } else { + preparedText.append('X').append(c); + prevChar = '\0'; + } + } + if (preparedText.length() % 2 != 0) { + preparedText.append('X'); + } + return preparedText.toString(); + } + + private int[] findPosition(char c) { + int[] pos = new int[2]; + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + if (matrix[i][j] == c) { + pos[0] = i; + pos[1] = j; + return pos; + } + } + } + return pos; + } + + public void printMatrix() { + System.out.println("\nPlayfair Cipher Matrix:"); + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + System.out.print(matrix[i][j] + " "); + } + System.out.println(); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/Polybius.java b/Java/src/main/java/com/thealgorithms/ciphers/Polybius.java new file mode 100644 index 000000000000..6b3cd6ccae81 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/Polybius.java @@ -0,0 +1,62 @@ +package com.thealgorithms.ciphers; + +/** + * A Java implementation of Polybius Cipher + * Polybius is a substitution cipher method + * It was invented by a greek philosopher that name is Polybius + * Letters in alphabet takes place to two dimension table. + * Encrypted text is created according to row and column in two dimension table + * Decrypted text is generated by looking at the row and column respectively + * Additionally, some letters in english alphabet deliberately throws such as U because U is very + * similar with V + * + * @author Hikmet ÇAKIR + * @since 08-07-2022+03:00 + */ +public final class Polybius { + private Polybius() { + } + + private static final char[][] KEY = { + // 0 1 2 3 4 + /* 0 */ {'A', 'B', 'C', 'D', 'E'}, + /* 1 */ {'F', 'G', 'H', 'I', 'J'}, + /* 2 */ {'K', 'L', 'M', 'N', 'O'}, + /* 3 */ {'P', 'Q', 'R', 'S', 'T'}, + /* 4 */ {'V', 'W', 'X', 'Y', 'Z'}, + }; + + private static String findLocationByCharacter(final char character) { + final StringBuilder location = new StringBuilder(); + for (int i = 0; i < KEY.length; i++) { + for (int j = 0; j < KEY[i].length; j++) { + if (character == KEY[i][j]) { + location.append(i).append(j); + break; + } + } + } + return location.toString(); + } + + public static String encrypt(final String plaintext) { + final char[] chars = plaintext.toUpperCase().toCharArray(); + final StringBuilder ciphertext = new StringBuilder(); + for (char aChar : chars) { + String location = findLocationByCharacter(aChar); + ciphertext.append(location); + } + return ciphertext.toString(); + } + + public static String decrypt(final String ciphertext) { + final char[] chars = ciphertext.toCharArray(); + final StringBuilder plaintext = new StringBuilder(); + for (int i = 0; i < chars.length; i += 2) { + int pozitionX = Character.getNumericValue(chars[i]); + int pozitionY = Character.getNumericValue(chars[i + 1]); + plaintext.append(KEY[pozitionX][pozitionY]); + } + return plaintext.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/ProductCipher.java b/Java/src/main/java/com/thealgorithms/ciphers/ProductCipher.java new file mode 100644 index 000000000000..d7eaea757001 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/ProductCipher.java @@ -0,0 +1,73 @@ +package com.thealgorithms.ciphers; + +import java.util.Scanner; + +final class ProductCipher { + private ProductCipher() { + } + + public static void main(String[] args) { + try (Scanner sc = new Scanner(System.in)) { + System.out.println("Enter the input to be encrypted: "); + String substitutionInput = sc.nextLine(); + System.out.println(" "); + System.out.println("Enter a number: "); + int n = sc.nextInt(); + + // Substitution encryption + StringBuffer substitutionOutput = new StringBuffer(); + for (int i = 0; i < substitutionInput.length(); i++) { + char c = substitutionInput.charAt(i); + substitutionOutput.append((char) (c + 5)); + } + System.out.println(" "); + System.out.println("Substituted text: "); + System.out.println(substitutionOutput); + + // Transposition encryption + String transpositionInput = substitutionOutput.toString(); + int modulus = transpositionInput.length() % n; + if (modulus != 0) { + modulus = n - modulus; + + for (; modulus != 0; modulus--) { + transpositionInput += "/"; + } + } + StringBuffer transpositionOutput = new StringBuffer(); + System.out.println(" "); + System.out.println("Transposition Matrix: "); + for (int i = 0; i < n; i++) { + for (int j = 0; j < transpositionInput.length() / n; j++) { + char c = transpositionInput.charAt(i + (j * n)); + System.out.print(c); + transpositionOutput.append(c); + } + System.out.println(); + } + System.out.println(" "); + System.out.println("Final encrypted text: "); + System.out.println(transpositionOutput); + + // Transposition decryption + n = transpositionOutput.length() / n; + StringBuffer transpositionPlaintext = new StringBuffer(); + for (int i = 0; i < n; i++) { + for (int j = 0; j < transpositionOutput.length() / n; j++) { + char c = transpositionOutput.charAt(i + (j * n)); + transpositionPlaintext.append(c); + } + } + + // Substitution decryption + StringBuffer plaintext = new StringBuffer(); + for (int i = 0; i < transpositionPlaintext.length(); i++) { + char c = transpositionPlaintext.charAt(i); + plaintext.append((char) (c - 5)); + } + + System.out.println("Plaintext: "); + System.out.println(plaintext); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/RSA.java b/Java/src/main/java/com/thealgorithms/ciphers/RSA.java new file mode 100644 index 000000000000..f50e501e68c8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/RSA.java @@ -0,0 +1,66 @@ +package com.thealgorithms.ciphers; + +import java.math.BigInteger; +import java.security.SecureRandom; + +/** + * @author Nguyen Duy Tiep on 23-Oct-17. + */ +public class RSA { + + private BigInteger modulus; + private BigInteger privateKey; + private BigInteger publicKey; + + public RSA(int bits) { + generateKeys(bits); + } + + /** + * @return encrypted message + */ + public synchronized String encrypt(String message) { + return (new BigInteger(message.getBytes())).modPow(publicKey, modulus).toString(); + } + + /** + * @return encrypted message as big integer + */ + public synchronized BigInteger encrypt(BigInteger message) { + return message.modPow(publicKey, modulus); + } + + /** + * @return plain message + */ + public synchronized String decrypt(String encryptedMessage) { + return new String((new BigInteger(encryptedMessage)).modPow(privateKey, modulus).toByteArray()); + } + + /** + * @return plain message as big integer + */ + public synchronized BigInteger decrypt(BigInteger encryptedMessage) { + return encryptedMessage.modPow(privateKey, modulus); + } + + /** + * Generate a new public and private key set. + */ + public final synchronized void generateKeys(int bits) { + SecureRandom r = new SecureRandom(); + BigInteger p = new BigInteger(bits / 2, 100, r); + BigInteger q = new BigInteger(bits / 2, 100, r); + modulus = p.multiply(q); + + BigInteger m = (p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE)); + + publicKey = BigInteger.valueOf(3L); + + while (m.gcd(publicKey).intValue() > 1) { + publicKey = publicKey.add(BigInteger.TWO); + } + + privateKey = publicKey.modInverse(m); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java b/Java/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java new file mode 100644 index 000000000000..f6c88ef730ec --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/SimpleSubCipher.java @@ -0,0 +1,85 @@ +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. + */ +public class SimpleSubCipher { + + /** + * Encrypt text by replacing each element with its opposite character. + * + * @param message + * @param cipherSmall + * @return Encrypted message + */ + public String encode(String message, String cipherSmall) { + StringBuilder encoded = new StringBuilder(); + + // This map is used to encode + Map<Character, Character> cipherMap = new HashMap<>(); + + char beginSmallLetter = 'a'; + char beginCapitalLetter = 'A'; + + cipherSmall = cipherSmall.toLowerCase(); + String cipherCapital = cipherSmall.toUpperCase(); + + // To handle Small and Capital letters + for (int i = 0; i < cipherSmall.length(); i++) { + cipherMap.put(beginSmallLetter++, cipherSmall.charAt(i)); + cipherMap.put(beginCapitalLetter++, cipherCapital.charAt(i)); + } + + 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)); + } + } + + return encoded.toString(); + } + + /** + * Decrypt message by replacing each element with its opposite character in + * cipher. + * + * @param encryptedMessage + * @param cipherSmall + * @return message + */ + public String decode(String encryptedMessage, String cipherSmall) { + StringBuilder decoded = new StringBuilder(); + + Map<Character, Character> cipherMap = new HashMap<>(); + + char beginSmallLetter = 'a'; + char beginCapitalLetter = 'A'; + + cipherSmall = cipherSmall.toLowerCase(); + String cipherCapital = cipherSmall.toUpperCase(); + + for (int i = 0; i < cipherSmall.length(); i++) { + cipherMap.put(cipherSmall.charAt(i), beginSmallLetter++); + cipherMap.put(cipherCapital.charAt(i), beginCapitalLetter++); + } + + for (int i = 0; i < encryptedMessage.length(); i++) { + if (Character.isAlphabetic(encryptedMessage.charAt(i))) { + decoded.append(cipherMap.get(encryptedMessage.charAt(i))); + } else { + decoded.append(encryptedMessage.charAt(i)); + } + } + + return decoded.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/Vigenere.java b/Java/src/main/java/com/thealgorithms/ciphers/Vigenere.java new file mode 100644 index 000000000000..1702f1abb94c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/Vigenere.java @@ -0,0 +1,51 @@ +package com.thealgorithms.ciphers; + +/** + * A Java implementation of Vigenere Cipher. + * + * @author straiffix + * @author beingmartinbmc + */ +public class Vigenere { + + public String encrypt(final String message, final String key) { + StringBuilder result = new StringBuilder(); + + int j = 0; + for (int i = 0; i < message.length(); i++) { + char c = message.charAt(i); + if (Character.isLetter(c)) { + if (Character.isUpperCase(c)) { + result.append((char) ((c + key.toUpperCase().charAt(j) - 2 * 'A') % 26 + 'A')); + } else { + result.append((char) ((c + key.toLowerCase().charAt(j) - 2 * 'a') % 26 + 'a')); + } + } else { + result.append(c); + } + j = ++j % key.length(); + } + return result.toString(); + } + + public String decrypt(final String message, final String key) { + StringBuilder result = new StringBuilder(); + + int j = 0; + for (int i = 0; i < message.length(); i++) { + char c = message.charAt(i); + if (Character.isLetter(c)) { + if (Character.isUpperCase(c)) { + result.append((char) ('Z' - (25 - (c - key.toUpperCase().charAt(j))) % 26)); + } else { + result.append((char) ('z' - (25 - (c - key.toLowerCase().charAt(j))) % 26)); + } + } else { + result.append(c); + } + + j = ++j % key.length(); + } + return result.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java b/Java/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java new file mode 100644 index 000000000000..b7d36db5c809 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/a5/A5Cipher.java @@ -0,0 +1,30 @@ +package com.thealgorithms.ciphers.a5; + +import java.util.BitSet; + +// https://en.wikipedia.org/wiki/A5/1 +public class A5Cipher { + + private final A5KeyStreamGenerator keyStreamGenerator; + private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something + + public A5Cipher(BitSet sessionKey, BitSet frameCounter) { + keyStreamGenerator = new A5KeyStreamGenerator(); + keyStreamGenerator.initialize(sessionKey, frameCounter); + } + + public BitSet encrypt(BitSet plainTextBits) { + // create a copy + var result = new BitSet(KEY_STREAM_LENGTH); + result.xor(plainTextBits); + + var key = keyStreamGenerator.getNextKeyStream(); + result.xor(key); + + return result; + } + + public void resetCounter() { + keyStreamGenerator.reInitialize(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java b/Java/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java new file mode 100644 index 000000000000..2e92498056ae --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/a5/A5KeyStreamGenerator.java @@ -0,0 +1,54 @@ +package com.thealgorithms.ciphers.a5; + +import java.util.BitSet; + +// TODO: raise exceptions for improper use +public class A5KeyStreamGenerator extends CompositeLFSR { + + private BitSet initialFrameCounter; + private BitSet frameCounter; + private BitSet sessionKey; + private static final int INITIAL_CLOCKING_CYCLES = 100; + private static final int KEY_STREAM_LENGTH = 228; // 28.5 bytes so we need to pad bytes or something + + @Override + public void initialize(BitSet sessionKey, BitSet frameCounter) { + this.sessionKey = sessionKey; + this.frameCounter = (BitSet) frameCounter.clone(); + this.initialFrameCounter = (BitSet) frameCounter.clone(); + registers.clear(); + LFSR lfsr1 = new LFSR(19, 8, new int[] {13, 16, 17, 18}); + LFSR lfsr2 = new LFSR(22, 10, new int[] {20, 21}); + LFSR lfsr3 = new LFSR(23, 10, new int[] {7, 20, 21, 22}); + registers.add(lfsr1); + registers.add(lfsr2); + registers.add(lfsr3); + registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter)); + } + + public void reInitialize() { + this.initialize(sessionKey, initialFrameCounter); + } + + public BitSet getNextKeyStream() { + for (int cycle = 1; cycle <= INITIAL_CLOCKING_CYCLES; ++cycle) this.clock(); + + BitSet result = new BitSet(KEY_STREAM_LENGTH); + for (int cycle = 1; cycle <= KEY_STREAM_LENGTH; ++cycle) { + boolean outputBit = this.clock(); + result.set(cycle - 1, outputBit); + } + + reInitializeRegisters(); + return result; + } + + private void reInitializeRegisters() { + incrementFrameCounter(); + registers.forEach(lfsr -> lfsr.initialize(sessionKey, frameCounter)); + } + + private void incrementFrameCounter() { + Utils.increment(frameCounter, FRAME_COUNTER_LENGTH); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java b/Java/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java new file mode 100644 index 000000000000..18ad913784dc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/a5/BaseLFSR.java @@ -0,0 +1,10 @@ +package com.thealgorithms.ciphers.a5; + +import java.util.BitSet; + +public interface BaseLFSR { + void initialize(BitSet sessionKey, BitSet frameCounter); + boolean clock(); + int SESSION_KEY_LENGTH = 64; + int FRAME_COUNTER_LENGTH = 22; +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java b/Java/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java new file mode 100644 index 000000000000..3cac558237c2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java @@ -0,0 +1,35 @@ +package com.thealgorithms.ciphers.a5; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +public abstract class CompositeLFSR implements BaseLFSR { + + protected final List<LFSR> registers = new ArrayList<>(); + + /** + * Implements irregular clocking using the clock bit for each register + * @return the registers discarded bit xored value + */ + @Override + public boolean clock() { + boolean majorityBit = getMajorityBit(); + boolean result = false; + for (var register : registers) { + result ^= register.getLastBit(); + if (register.getClockBit() == majorityBit) register.clock(); + } + return result; + } + + private boolean getMajorityBit() { + Map<Boolean, Integer> bitCount = new TreeMap<>(); + bitCount.put(Boolean.FALSE, 0); + bitCount.put(Boolean.TRUE, 0); + + registers.forEach(lfsr -> bitCount.put(lfsr.getClockBit(), bitCount.get(lfsr.getClockBit()) + 1)); + return bitCount.get(Boolean.FALSE) <= bitCount.get(Boolean.TRUE); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java b/Java/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java new file mode 100644 index 000000000000..dc42ae0a7a5e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java @@ -0,0 +1,79 @@ +package com.thealgorithms.ciphers.a5; + +import java.util.BitSet; + +public class LFSR implements BaseLFSR { + + private final BitSet register; + private final int length; + private final int clockBitIndex; + private final int[] tappingBitsIndices; + + public LFSR(int length, int clockBitIndex, int[] tappingBitsIndices) { + this.length = length; + this.clockBitIndex = clockBitIndex; + this.tappingBitsIndices = tappingBitsIndices; + register = new BitSet(length); + } + + @Override + public void initialize(BitSet sessionKey, BitSet frameCounter) { + register.clear(); + clock(sessionKey, SESSION_KEY_LENGTH); + clock(frameCounter, FRAME_COUNTER_LENGTH); + } + + private void clock(BitSet key, int keyLength) { + // We start from reverse because LFSR 0 index is the left most bit + // while key 0 index is right most bit, so we reverse it + for (int i = keyLength - 1; i >= 0; --i) { + var newBit = key.get(i) ^ xorTappingBits(); + pushBit(newBit); + } + } + + @Override + public boolean clock() { + return pushBit(xorTappingBits()); + } + + public boolean getClockBit() { + return register.get(clockBitIndex); + } + + public boolean get(int bitIndex) { + return register.get(bitIndex); + } + + public boolean getLastBit() { + return register.get(length - 1); + } + + private boolean xorTappingBits() { + boolean result = false; + for (int i : tappingBitsIndices) { + result ^= register.get(i); + } + return result; + } + + private boolean pushBit(boolean bit) { + boolean discardedBit = rightShift(); + register.set(0, bit); + return discardedBit; + } + + private boolean rightShift() { + boolean discardedBit = get(length - 1); + for (int i = length - 1; i > 0; --i) { + register.set(i, get(i - 1)); + } + register.set(0, false); + return discardedBit; + } + + @Override + public String toString() { + return register.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/ciphers/a5/Utils.java b/Java/src/main/java/com/thealgorithms/ciphers/a5/Utils.java new file mode 100644 index 000000000000..b4addf18dd9d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/ciphers/a5/Utils.java @@ -0,0 +1,25 @@ +package com.thealgorithms.ciphers.a5; + +// Source +// http://www.java2s.com/example/java-utility-method/bitset/increment-bitset-bits-int-size-9fd84.html +// package com.java2s; +// License from project: Open Source License + +import java.util.BitSet; + +public final class Utils { + private Utils() { + } + + public static boolean increment(BitSet bits, int size) { + int i = size - 1; + while (i >= 0 && bits.get(i)) { + bits.set(i--, false); /*from w w w . j a v a 2s .c o m*/ + } + if (i < 0) { + return false; + } + bits.set(i, true); + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java b/Java/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java new file mode 100644 index 000000000000..4bd9c74a1751 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java @@ -0,0 +1,181 @@ +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 final class AnyBaseToAnyBase { + private 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; + int 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<Character> 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; + int 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 = 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/Java/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java b/Java/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java new file mode 100644 index 000000000000..6b4b14adc955 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java @@ -0,0 +1,56 @@ +package com.thealgorithms.conversions; + +/** + * @author Varun Upadhyay (<a href="https://github.com/varunu28">...</a>) + */ +// Driver program +public final class AnyBaseToDecimal { + private 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/Java/src/main/java/com/thealgorithms/conversions/AnytoAny.java b/Java/src/main/java/com/thealgorithms/conversions/AnytoAny.java new file mode 100644 index 000000000000..801e493032e0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/AnytoAny.java @@ -0,0 +1,35 @@ +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 final class AnytoAny { + private 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; + int dec = 0; + int 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/Java/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java b/Java/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java new file mode 100644 index 000000000000..67b815ab6466 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java @@ -0,0 +1,37 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * This class converts a Binary number to a Decimal number + */ +final class BinaryToDecimal { + private BinaryToDecimal() { + } + + public static long binaryToDecimal(long binNum) { + long binCopy; + long d; + long s = 0; + long power = 0; + binCopy = binNum; + while (binCopy != 0) { + d = binCopy % 10; + s += d * (long) Math.pow(2, power++); + binCopy /= 10; + } + return s; + } + + /** + * Main Method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.print("Binary number: "); + System.out.println("Decimal equivalent:" + binaryToDecimal(sc.nextLong())); + sc.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java b/Java/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java new file mode 100644 index 000000000000..a19baba39715 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java @@ -0,0 +1,60 @@ +package com.thealgorithms.conversions; + +import java.util.HashMap; +import java.util.Scanner; + +/** + * Converts any Binary Number to a Hexadecimal Number + * + * @author Nishita Aggarwal + */ +public final class BinaryToHexadecimal { + private 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<Integer, String> 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 * (int) 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/Java/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java b/Java/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java new file mode 100644 index 000000000000..6fef090287ab --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java @@ -0,0 +1,50 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Binary number to an Octal Number + * + * @author Zachary Jones + */ +public final class BinaryToOctal { + private 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; + int 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/Java/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java b/Java/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java new file mode 100644 index 000000000000..019c4026bfb5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java @@ -0,0 +1,69 @@ +package com.thealgorithms.conversions; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +/** + * @author Varun Upadhyay (<a href="https://github.com/varunu28">...</a>) + */ +// Driver Program +public final class DecimalToAnyBase { + private 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<Character> 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/Java/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java b/Java/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java new file mode 100644 index 000000000000..471724ff9966 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java @@ -0,0 +1,63 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * This class converts a Decimal number to a Binary number + */ +final class DecimalToBinary { + private 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; + int b = 0; + int c = 0; + int 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; + int b = 0; + int c = 0; + int 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/Java/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java b/Java/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java new file mode 100644 index 000000000000..78838c6107b7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java @@ -0,0 +1,51 @@ +package com.thealgorithms.conversions; + +// hex = [0 - 9] -> [A - F] +final class DecimalToHexaDecimal { + private DecimalToHexaDecimal() { + } + + private static final int SIZE_OF_INT_IN_HALF_BYTES = 8; + private static final int NUMBER_OF_BITS_IN_HALF_BYTE = 4; + private static final int HALF_BYTE = 0x0F; + private static final char[] HEX_DIGITS = { + '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(SIZE_OF_INT_IN_HALF_BYTES); + hexBuilder.setLength(SIZE_OF_INT_IN_HALF_BYTES); + for (int i = SIZE_OF_INT_IN_HALF_BYTES - 1; i >= 0; --i) { + int j = dec & HALF_BYTE; + hexBuilder.setCharAt(i, HEX_DIGITS[j]); + dec >>= NUMBER_OF_BITS_IN_HALF_BYTE; + } + 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/Java/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java b/Java/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java new file mode 100644 index 000000000000..4bc3a6e7af8c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java @@ -0,0 +1,38 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * This class converts Decimal numbers to Octal Numbers + */ +public final class DecimalToOctal { + private 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; + int k; + int d; + int s = 0; + int 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/Java/src/main/java/com/thealgorithms/conversions/HexToOct.java b/Java/src/main/java/com/thealgorithms/conversions/HexToOct.java new file mode 100644 index 000000000000..97a8be16b2e0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/HexToOct.java @@ -0,0 +1,75 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Hexadecimal Number to Octal + * + * @author Tanmay Joshi + */ +public final class HexToOct { + private 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; + int 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/Java/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java b/Java/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java new file mode 100644 index 000000000000..b6228488dc76 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java @@ -0,0 +1,43 @@ +package com.thealgorithms.conversions; + +// Hex [0-9],[A-F] -> Binary [0,1] +public class HexaDecimalToBinary { + public String convert(String numHex) { + // String a HexaDecimal: + int conHex = Integer.parseInt(numHex, 16); + // Hex a Binary: + String binary = Integer.toBinaryString(conHex); + // Output: + return completeDigits(binary); + } + + public String completeDigits(String binNum) { + final int longBits = 8; + for (int i = binNum.length(); i < longBits; 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) { + System.out.println(num + " = " + objConvert.convert(num)); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java b/Java/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java new file mode 100644 index 000000000000..003781da9d5e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java @@ -0,0 +1,39 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +public final class HexaDecimalToDecimal { + private 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 hexaInput; + int decOutput; + Scanner scan = new Scanner(System.in); + + System.out.print("Enter Hexadecimal Number : "); + hexaInput = scan.nextLine(); + + // convert hexadecimal to decimal + decOutput = getHexaToDec(hexaInput); + /* + Pass the string to the getHexaToDec function + and it returns the decimal form in the variable decOutput. + */ + System.out.println("Number in Decimal: " + decOutput); + scan.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java b/Java/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java new file mode 100644 index 000000000000..9c031df9504d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java @@ -0,0 +1,68 @@ +package com.thealgorithms.conversions; + +/** + * Converting Integers into Roman Numerals + * + * <p> + * ('I', 1); ('IV',4); ('V', 5); ('IX',9); ('X', 10); ('XL',40); ('L', 50); + * ('XC',90); ('C', 100); ('D', 500); ('M', 1000); + */ +public final class IntegerToRoman { + private IntegerToRoman() { + } + + private static final int[] ALL_ROMAN_NUMBERS_IN_ARABIC = new int[] { + 1000, + 900, + 500, + 400, + 100, + 90, + 50, + 40, + 10, + 9, + 5, + 4, + 1, + }; + private static final String[] ALL_ROMAN_NUMBERS = 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 < ALL_ROMAN_NUMBERS_IN_ARABIC.length; a++) { + int times = num / ALL_ROMAN_NUMBERS_IN_ARABIC[a]; + for (int b = 0; b < times; b++) { + builder.append(ALL_ROMAN_NUMBERS[a]); + } + + num -= times * ALL_ROMAN_NUMBERS_IN_ARABIC[a]; + } + + return builder.toString(); + } + + public static void main(String[] args) { + System.out.println(IntegerToRoman.integerToRoman(2131)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/conversions/OctalToBinary.java b/Java/src/main/java/com/thealgorithms/conversions/OctalToBinary.java new file mode 100644 index 000000000000..6b01c2f65cfe --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/OctalToBinary.java @@ -0,0 +1,43 @@ +package com.thealgorithms.conversions; + +/** + * Converts any Octal Number to a Binary Number + * + * @author Bama Charan Chhandogi + */ + +public final class OctalToBinary { + private OctalToBinary() { + } + public static long convertOctalToBinary(int octalNumber) { + long binaryNumber = 0; + int digitPosition = 1; + + while (octalNumber != 0) { + int octalDigit = octalNumber % 10; + long binaryDigit = convertOctalDigitToBinary(octalDigit); + + binaryNumber += binaryDigit * digitPosition; + + octalNumber /= 10; + digitPosition *= 1000; // Move to the next group of 3 binary digits + } + + return binaryNumber; + } + + public static long convertOctalDigitToBinary(int octalDigit) { + long binaryDigit = 0; + int binaryMultiplier = 1; + + while (octalDigit != 0) { + int octalDigitRemainder = octalDigit % 2; + binaryDigit += octalDigitRemainder * binaryMultiplier; + + octalDigit /= 2; + binaryMultiplier *= 10; + } + + return binaryDigit; + } +} diff --git a/Java/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java b/Java/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java new file mode 100644 index 000000000000..187f0ed1e2ea --- /dev/null +++ b/Java/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 final class OctalToDecimal { + private 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: + return Integer.parseInt(inputOctal, 8); + } 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/Java/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java b/Java/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java new file mode 100644 index 000000000000..5cc97fde12aa --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java @@ -0,0 +1,65 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts any Octal Number to HexaDecimal + * + * @author Tanmay Joshi + */ +public final class OctalToHexadecimal { + private 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/Java/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java b/Java/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java new file mode 100644 index 000000000000..84cbff09db6b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java @@ -0,0 +1,168 @@ +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 <a href="https://en.wikipedia.org/wiki/RGB_color_model">[1]</a> and + * <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">[2]</a>). + */ +public final class RgbHsvConversion { + private 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/Java/src/main/java/com/thealgorithms/conversions/RomanToInteger.java b/Java/src/main/java/com/thealgorithms/conversions/RomanToInteger.java new file mode 100644 index 000000000000..cf2d4145858f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/RomanToInteger.java @@ -0,0 +1,65 @@ +package com.thealgorithms.conversions; + +import java.util.HashMap; +import java.util.Map; + +public final class RomanToInteger { + private RomanToInteger() { + } + + private static final Map<Character, Integer> ROMAN_TO_INT = new HashMap<>() { + { + 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 than previous or not + newPrev = ROMAN_TO_INT.get(prev) > newPrev ? ROMAN_TO_INT.get(prev) : newPrev; + } + + int currentNum = ROMAN_TO_INT.get(c); + + // if current number greater than prev max previous then add + if (currentNum >= newPrev) { + sum += currentNum; + } else { + // subtract upcoming number until upcoming number not greater than 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/Java/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java b/Java/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java new file mode 100644 index 000000000000..4d13b8b7fd55 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java @@ -0,0 +1,67 @@ +package com.thealgorithms.conversions; + +import java.util.Scanner; + +/** + * Converts turkish character to latin character + * + * @author Özgün Gökşenli + */ +public final class TurkishToLatinConversion { + private 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(String.valueOf(turkishChars[i]), String.valueOf(latinChars[i])); + } + return param; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/Node.java b/Java/src/main/java/com/thealgorithms/datastructures/Node.java new file mode 100644 index 000000000000..c8d0e6cb4f7d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/Node.java @@ -0,0 +1,32 @@ +package com.thealgorithms.datastructures; + +import java.util.ArrayList; +import java.util.List; + +public class Node<T> { + + private final T value; + private final List<Node<T>> children; + + public Node(final T value) { + this.value = value; + this.children = new ArrayList<>(); + } + + public Node(final T value, final List<Node<T>> children) { + this.value = value; + this.children = children; + } + + public T getValue() { + return value; + } + + public void addChild(Node<T> child) { + children.add(child); + } + + public List<Node<T>> getChildren() { + return children; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/bags/Bag.java b/Java/src/main/java/com/thealgorithms/datastructures/bags/Bag.java new file mode 100644 index 000000000000..ff5c832baeaf --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/bags/Bag.java @@ -0,0 +1,128 @@ +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 <Element> - the generic type of an element in this bag + */ +public class Bag<Element> implements Iterable<Element> { + + private Node<Element> firstElement; // first element of the bag + private int size; // size of bag + + private static final class Node<Element> { + + private Element content; + private Node<Element> 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<Element> 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) { + for (Element value : this) { + if (value.equals(element)) { + return true; + } + } + return false; + } + + /** + * @return an iterator that iterates over the elements in this bag in + * arbitrary order + */ + public Iterator<Element> iterator() { + return new ListIterator<>(firstElement); + } + + @SuppressWarnings("hiding") + private class ListIterator<Element> implements Iterator<Element> { + + private Node<Element> currentElement; + + ListIterator(Node<Element> 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<String> 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/Java/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/Java/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java new file mode 100644 index 000000000000..a327690d7896 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java @@ -0,0 +1,61 @@ +package com.thealgorithms.datastructures.bloomfilter; + +import java.util.BitSet; + +public class BloomFilter<T> { + + private int numberOfHashFunctions; + private BitSet bitArray; + private Hash<T>[] hashFunctions; + + public BloomFilter(int numberOfHashFunctions, int n) { + this.numberOfHashFunctions = numberOfHashFunctions; + hashFunctions = new Hash[numberOfHashFunctions]; + bitArray = new BitSet(n); + insertHash(); + } + + private void insertHash() { + for (int i = 0; i < numberOfHashFunctions; i++) { + hashFunctions[i] = new Hash(i); + } + } + + public void insert(T key) { + for (Hash<T> hash : hashFunctions) { + int position = hash.compute(key) % bitArray.size(); + bitArray.set(position); + } + } + + public boolean contains(T key) { + for (Hash<T> hash : hashFunctions) { + int position = hash.compute(key) % bitArray.size(); + if (!bitArray.get(position)) { + return false; + } + } + return true; + } + + private class Hash<T> { + + int index; + + Hash(int index) { + this.index = index; + } + + public int compute(T key) { + return index * asciiString(String.valueOf(key)); + } + + private int asciiString(String word) { + int number = 0; + for (int i = 0; i < word.length(); i++) { + number += word.charAt(i); + } + return number; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java b/Java/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java new file mode 100644 index 000000000000..63295b83abe6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java @@ -0,0 +1,58 @@ +package com.thealgorithms.datastructures.buffers; + +import java.util.concurrent.atomic.AtomicInteger; + +public class CircularBuffer<Item> { + private final Item[] buffer; + private final CircularPointer putPointer; + private final CircularPointer getPointer; + private final AtomicInteger size = new AtomicInteger(0); + + public CircularBuffer(int size) { + // noinspection unchecked + this.buffer = (Item[]) new Object[size]; + this.putPointer = new CircularPointer(0, size); + this.getPointer = new CircularPointer(0, size); + } + + public boolean isEmpty() { + return size.get() == 0; + } + + public boolean isFull() { + return size.get() == buffer.length; + } + + public Item get() { + if (isEmpty()) return null; + + Item item = buffer[getPointer.getAndIncrement()]; + size.decrementAndGet(); + return item; + } + + public boolean put(Item item) { + if (isFull()) return false; + + buffer[putPointer.getAndIncrement()] = item; + size.incrementAndGet(); + return true; + } + + private static class CircularPointer { + private int pointer; + private final int max; + + CircularPointer(int pointer, int max) { + this.pointer = pointer; + this.max = max; + } + + public int getAndIncrement() { + if (pointer == max) pointer = 0; + int tmp = pointer; + pointer++; + return tmp; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java b/Java/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java new file mode 100644 index 000000000000..6e37b4a7109d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java @@ -0,0 +1,143 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.HashMap; +import java.util.Map; + +/** + * Java program for LFU Cache (https://en.wikipedia.org/wiki/Least_frequently_used) + * @author Akshay Dubey (https://github.com/itsAkshayDubey) + */ +public class LFUCache<K, V> { + + private class Node { + + private K key; + private V value; + private int frequency; + private Node previous; + private Node next; + + Node(K key, V value, int frequency) { + this.key = key; + this.value = value; + this.frequency = frequency; + } + } + + private Node head; + private Node tail; + private Map<K, Node> map = null; + private Integer capacity; + private static final int DEFAULT_CAPACITY = 100; + + public LFUCache() { + this.capacity = DEFAULT_CAPACITY; + } + + public LFUCache(Integer capacity) { + this.capacity = capacity; + this.map = new HashMap<>(); + } + + /** + * This method returns value present in the cache corresponding to the key passed as parameter + * + * @param <K> key for which value is to be retrieved + * @returns <V> object corresponding to the key passed as parameter, returns null if <K> key is + * not present in the cache + */ + public V get(K key) { + if (this.map.get(key) == null) { + return null; + } + + Node node = map.get(key); + removeNode(node); + node.frequency += 1; + addNodeWithUpdatedFrequency(node); + + return node.value; + } + + /** + * This method stores <K> key and <V> value in the cache + * + * @param <K> key which is to be stored in the cache + * @param <V> value which is to be stored in the cache + */ + public void put(K key, V value) { + if (map.containsKey(key)) { + Node node = map.get(key); + node.value = value; + node.frequency += 1; + removeNode(node); + addNodeWithUpdatedFrequency(node); + } else { + if (map.size() >= capacity) { + map.remove(this.head.key); + removeNode(head); + } + Node node = new Node(key, value, 1); + addNodeWithUpdatedFrequency(node); + map.put(key, node); + } + } + + /** + * This method stores the node in the cache with updated frequency + * + * @param Node node which is to be updated in the cache + */ + private void addNodeWithUpdatedFrequency(Node node) { + if (tail != null && head != null) { + Node temp = this.head; + while (temp != null) { + if (temp.frequency > node.frequency) { + if (temp == head) { + node.next = temp; + temp.previous = node; + this.head = node; + break; + } else { + node.next = temp; + node.previous = temp.previous; + temp.previous.next = node; + temp.previous = node; + break; + } + } else { + temp = temp.next; + if (temp == null) { + tail.next = node; + node.previous = tail; + node.next = null; + tail = node; + break; + } + } + } + } else { + tail = node; + head = tail; + } + } + + /** + * This method removes node from the cache + * + * @param Node node which is to be removed in the cache + */ + private void removeNode(Node node) { + if (node.previous != null) { + node.previous.next = node.next; + } else { + this.head = node.next; + } + + if (node.next != null) { + node.next.previous = node.previous; + } else { + this.tail = node.previous; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java b/Java/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java new file mode 100644 index 000000000000..97818ff83351 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java @@ -0,0 +1,171 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.HashMap; +import java.util.Map; + +/** + * Least recently used (LRU) + * <p> + * 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 <K> key type + * @param <V> value type + */ +public class LRUCache<K, V> { + + private final Map<K, Entry<K, V>> data = new HashMap<>(); + private Entry<K, V> head; + private Entry<K, V> tail; + private int cap; + private static final int DEFAULT_CAP = 100; + + public LRUCache() { + setCapacity(DEFAULT_CAP); + } + + public LRUCache(int cap) { + setCapacity(cap); + } + + private void setCapacity(int newCapacity) { + checkCapacity(newCapacity); + for (int i = data.size(); i > newCapacity; i--) { + Entry<K, V> evicted = evict(); + data.remove(evicted.getKey()); + } + this.cap = newCapacity; + } + + private Entry<K, V> evict() { + if (head == null) { + throw new RuntimeException("cache cannot be empty!"); + } + Entry<K, V> evicted = head; + head = evicted.getNextEntry(); + head.setPreEntry(null); + evicted.setNextEntry(null); + return evicted; + } + + private void checkCapacity(int capacity) { + if (capacity <= 0) { + throw new RuntimeException("capacity must greater than 0!"); + } + } + + public V get(K key) { + if (!data.containsKey(key)) { + return null; + } + final Entry<K, V> entry = data.get(key); + moveNodeToLast(entry); + return entry.getValue(); + } + + private void moveNodeToLast(Entry<K, V> entry) { + if (tail == entry) { + return; + } + final Entry<K, V> preEntry = entry.getPreEntry(); + final Entry<K, V> nextEntry = entry.getNextEntry(); + if (preEntry != null) { + preEntry.setNextEntry(nextEntry); + } + if (nextEntry != null) { + nextEntry.setPreEntry(preEntry); + } + if (head == entry) { + head = nextEntry; + } + tail.setNextEntry(entry); + entry.setPreEntry(tail); + entry.setNextEntry(null); + tail = entry; + } + + public void put(K key, V value) { + if (data.containsKey(key)) { + final Entry<K, V> existingEntry = data.get(key); + existingEntry.setValue(value); + moveNodeToLast(existingEntry); + return; + } + Entry<K, V> newEntry; + if (data.size() == cap) { + newEntry = evict(); + data.remove(newEntry.getKey()); + } else { + newEntry = new Entry<>(); + } + + newEntry.setKey(key); + newEntry.setValue(value); + addNewEntry(newEntry); + data.put(key, newEntry); + } + + private void addNewEntry(Entry<K, V> newEntry) { + if (data.isEmpty()) { + head = newEntry; + tail = newEntry; + return; + } + tail.setNextEntry(newEntry); + newEntry.setPreEntry(tail); + newEntry.setNextEntry(null); + tail = newEntry; + } + + static final class Entry<I, J> { + + private Entry<I, J> preEntry; + private Entry<I, J> nextEntry; + private I key; + private J value; + + Entry() { + } + + Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) { + this.preEntry = preEntry; + this.nextEntry = nextEntry; + this.key = key; + this.value = value; + } + + public Entry<I, J> getPreEntry() { + return preEntry; + } + + public void setPreEntry(Entry<I, J> preEntry) { + this.preEntry = preEntry; + } + + public Entry<I, J> getNextEntry() { + return nextEntry; + } + + public void setNextEntry(Entry<I, J> nextEntry) { + this.nextEntry = nextEntry; + } + + public I getKey() { + return key; + } + + public void setKey(I key) { + this.key = key; + } + + public J getValue() { + return value; + } + + public void setValue(J value) { + this.value = value; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java b/Java/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java new file mode 100644 index 000000000000..9c155be8b195 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java @@ -0,0 +1,169 @@ +package com.thealgorithms.datastructures.caches; + +import java.util.HashMap; +import java.util.Map; + +/** + * Most recently used (MRU) + * <p> + * 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 <K> key type + * @param <V> value type + */ +public class MRUCache<K, V> { + + private final Map<K, Entry<K, V>> data = new HashMap<>(); + private Entry<K, V> head; + private Entry<K, V> tail; + private int cap; + private static final int DEFAULT_CAP = 100; + + public MRUCache() { + setCapacity(DEFAULT_CAP); + } + + private void setCapacity(int newCapacity) { + checkCapacity(newCapacity); + for (int i = data.size(); i > newCapacity; i--) { + Entry<K, V> evicted = evict(); + data.remove(evicted.getKey()); + } + this.cap = newCapacity; + } + + private void checkCapacity(int capacity) { + if (capacity <= 0) { + throw new RuntimeException("capacity must greater than 0!"); + } + } + + private Entry<K, V> evict() { + if (head == null) { + throw new RuntimeException("cache cannot be empty!"); + } + final Entry<K, V> evicted = this.tail; + tail = evicted.getPreEntry(); + tail.setNextEntry(null); + evicted.setNextEntry(null); + return evicted; + } + + public MRUCache(int cap) { + setCapacity(cap); + } + + public V get(K key) { + if (!data.containsKey(key)) { + return null; + } + final Entry<K, V> entry = data.get(key); + moveEntryToLast(entry); + return entry.getValue(); + } + + public void put(K key, V value) { + if (data.containsKey(key)) { + final Entry<K, V> exitingEntry = data.get(key); + exitingEntry.setValue(value); + moveEntryToLast(exitingEntry); + return; + } + Entry<K, V> newEntry; + if (data.size() == cap) { + newEntry = evict(); + data.remove(newEntry.getKey()); + } else { + newEntry = new Entry<>(); + } + newEntry.setKey(key); + newEntry.setValue(value); + addNewEntry(newEntry); + data.put(key, newEntry); + } + + private void addNewEntry(Entry<K, V> newEntry) { + if (data.isEmpty()) { + head = newEntry; + tail = newEntry; + return; + } + tail.setNextEntry(newEntry); + newEntry.setPreEntry(tail); + newEntry.setNextEntry(null); + tail = newEntry; + } + + private void moveEntryToLast(Entry<K, V> entry) { + if (tail == entry) { + return; + } + final Entry<K, V> preEntry = entry.getPreEntry(); + final Entry<K, V> nextEntry = entry.getNextEntry(); + if (preEntry != null) { + preEntry.setNextEntry(nextEntry); + } + if (nextEntry != null) { + nextEntry.setPreEntry(preEntry); + } + if (head == entry) { + head = nextEntry; + } + tail.setNextEntry(entry); + entry.setPreEntry(tail); + entry.setNextEntry(null); + tail = entry; + } + + static final class Entry<I, J> { + + private Entry<I, J> preEntry; + private Entry<I, J> nextEntry; + private I key; + private J value; + + Entry() { + } + + Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) { + this.preEntry = preEntry; + this.nextEntry = nextEntry; + this.key = key; + this.value = value; + } + + public Entry<I, J> getPreEntry() { + return preEntry; + } + + public void setPreEntry(Entry<I, J> preEntry) { + this.preEntry = preEntry; + } + + public Entry<I, J> getNextEntry() { + return nextEntry; + } + + public void setNextEntry(Entry<I, J> nextEntry) { + this.nextEntry = nextEntry; + } + + public I getKey() { + return key; + } + + public void setKey(I key) { + this.key = key; + } + + public J getValue() { + return value; + } + + public void setValue(J value) { + this.value = value; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java b/Java/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java new file mode 100644 index 000000000000..25b01bce19f3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java @@ -0,0 +1,84 @@ +package com.thealgorithms.datastructures.crdt; + +import java.util.HashMap; +import java.util.Map; + +/** + * G-Counter (Grow-only Counter) is a state-based CRDT (Conflict-free Replicated Data Type) + * designed for tracking counts in a distributed and concurrent environment. + * Each process maintains its own counter, allowing only increments. The total count + * is obtained by summing individual process counts. + * This implementation supports incrementing, querying the total count, + * comparing with other G-Counters, and merging with another G-Counter + * to compute the element-wise maximum. + * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) + * + * @author itakurah (https://github.com/itakurah) + */ + +class GCounter { + private final Map<Integer, Integer> counterMap; + private final int myId; + private final int n; + + /** + * Constructs a G-Counter for a cluster of n nodes. + * + * @param n The number of nodes in the cluster. + */ + GCounter(int myId, int n) { + this.myId = myId; + this.n = n; + this.counterMap = new HashMap<>(); + + for (int i = 0; i < n; i++) { + counterMap.put(i, 0); + } + } + + /** + * Increments the counter for the current node. + */ + public void increment() { + counterMap.put(myId, counterMap.get(myId) + 1); + } + + /** + * Gets the total value of the counter by summing up values from all nodes. + * + * @return The total value of the counter. + */ + public int value() { + int sum = 0; + for (int v : counterMap.values()) { + sum += v; + } + return sum; + } + + /** + * Compares the state of this G-Counter with another G-Counter. + * + * @param other The other G-Counter to compare with. + * @return True if the state of this G-Counter is less than or equal to the state of the other G-Counter. + */ + public boolean compare(GCounter other) { + for (int i = 0; i < n; i++) { + if (this.counterMap.get(i) > other.counterMap.get(i)) { + return false; + } + } + return true; + } + + /** + * Merges the state of this G-Counter with another G-Counter. + * + * @param other The other G-Counter to merge with. + */ + public void merge(GCounter other) { + for (int i = 0; i < n; i++) { + this.counterMap.put(i, Math.max(this.counterMap.get(i), other.counterMap.get(i))); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java b/Java/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java new file mode 100644 index 000000000000..2b8959ed0136 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java @@ -0,0 +1,65 @@ +package com.thealgorithms.datastructures.crdt; + +import java.util.HashSet; +import java.util.Set; + +/** + * GSet (Grow-only Set) is a state-based CRDT (Conflict-free Replicated Data Type) + * that allows only the addition of elements and ensures that once an element is added, + * it cannot be removed. The merge operation of two G-Sets is their union. + * This implementation supports adding elements, looking up elements, comparing with other G-Sets, + * and merging with another G-Set to create a new G-Set containing all unique elements from both sets. + * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) + * + * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah) + */ + +public class GSet<T> { + private final Set<T> elements; + + /** + * Constructs an empty G-Set. + */ + public GSet() { + this.elements = new HashSet<>(); + } + + /** + * Adds an element to the G-Set. + * + * @param e the element to be added + */ + public void addElement(T e) { + elements.add(e); + } + + /** + * Checks if the given element is present in the G-Set. + * + * @param e the element to be checked + * @return true if the element is present, false otherwise + */ + public boolean lookup(T e) { + return elements.contains(e); + } + + /** + * Compares the G-Set with another G-Set to check if it is a subset. + * + * @param other the other G-Set to compare with + * @return true if the current G-Set is a subset of the other, false otherwise + */ + public boolean compare(GSet<T> other) { + return other.elements.containsAll(elements); + } + + /** + * Merges the current G-Set with another G-Set, creating a new G-Set + * containing all unique elements from both sets. + * + * @param other the G-Set to merge with + */ + public void merge(GSet<T> other) { + elements.addAll(other.elements); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java b/Java/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java new file mode 100644 index 000000000000..2c6ce8a427d1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java @@ -0,0 +1,138 @@ +package com.thealgorithms.datastructures.crdt; + +import java.util.HashMap; +import java.util.Map; + +/** + * Last-Write-Wins Element Set (LWWElementSet) is a state-based CRDT (Conflict-free Replicated Data Type) + * designed for managing sets in a distributed and concurrent environment. It supports the addition and removal + * of elements, using timestamps to determine the order of operations. The set is split into two subsets: + * the add set for elements to be added and the remove set for elements to be removed. + * + * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah) + * @see <a href="https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type">Conflict-free_replicated_data_type</a> + * @see <a href="https://github.com/itakurah">itakurah (Niklas Hoefflin)</a> + */ + +class Element { + String key; + int timestamp; + Bias bias; + + /** + * Constructs a new Element with the specified key, timestamp and bias. + * + * @param key The key of the element. + * @param timestamp The timestamp associated with the element. + * @param bias The bias of the element (ADDS or REMOVALS). + */ + Element(String key, int timestamp, Bias bias) { + this.key = key; + this.timestamp = timestamp; + this.bias = bias; + } +} + +enum Bias { + /** + * ADDS bias for the add set. + * REMOVALS bias for the remove set. + */ + ADDS, + REMOVALS +} + +class LWWElementSet { + private final Map<String, Element> addSet; + private final Map<String, Element> removeSet; + + /** + * Constructs an empty LWWElementSet. + */ + LWWElementSet() { + this.addSet = new HashMap<>(); + this.removeSet = new HashMap<>(); + } + + /** + * Adds an element to the addSet. + * + * @param e The element to be added. + */ + public void add(Element e) { + addSet.put(e.key, e); + } + + /** + * Removes an element from the removeSet. + * + * @param e The element to be removed. + */ + public void remove(Element e) { + if (lookup(e)) { + removeSet.put(e.key, e); + } + } + + /** + * Checks if an element is in the LWWElementSet by comparing timestamps in the addSet and removeSet. + * + * @param e The element to be checked. + * @return True if the element is present, false otherwise. + */ + public boolean lookup(Element e) { + Element inAddSet = addSet.get(e.key); + Element inRemoveSet = removeSet.get(e.key); + + return (inAddSet != null && (inRemoveSet == null || inAddSet.timestamp > inRemoveSet.timestamp)); + } + + /** + * Compares the LWWElementSet with another LWWElementSet to check if addSet and removeSet are a subset. + * + * @param other The LWWElementSet to compare. + * @return True if the set is subset, false otherwise. + */ + public boolean compare(LWWElementSet other) { + return other.addSet.keySet().containsAll(addSet.keySet()) && other.removeSet.keySet().containsAll(removeSet.keySet()); + } + + /** + * Merges another LWWElementSet into this set by resolving conflicts based on timestamps. + * + * @param other The LWWElementSet to merge. + */ + public void merge(LWWElementSet other) { + for (Element e : other.addSet.values()) { + if (!addSet.containsKey(e.key) || compareTimestamps(addSet.get(e.key), e)) { + addSet.put(e.key, e); + } + } + + for (Element e : other.removeSet.values()) { + if (!removeSet.containsKey(e.key) || compareTimestamps(removeSet.get(e.key), e)) { + removeSet.put(e.key, e); + } + } + } + + /** + * Compares timestamps of two elements based on their bias (ADDS or REMOVALS). + * + * @param e The first element. + * @param other The second element. + * @return True if the first element's timestamp is greater or the bias is ADDS and timestamps are equal. + */ + public boolean compareTimestamps(Element e, Element other) { + if (e.bias != other.bias) { + throw new IllegalArgumentException("Invalid bias value"); + } + Bias bias = e.bias; + int timestampComparison = Integer.compare(e.timestamp, other.timestamp); + + if (timestampComparison == 0) { + return bias != Bias.ADDS; + } + return timestampComparison < 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java b/Java/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java new file mode 100644 index 000000000000..a4cc2ffdd4a6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java @@ -0,0 +1,191 @@ +package com.thealgorithms.datastructures.crdt; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * ORSet (Observed-Removed Set) is a state-based CRDT (Conflict-free Replicated Data Type) + * that supports both addition and removal of elements. This particular implementation follows + * the Add-Wins strategy, meaning that in case of conflicting add and remove operations, + * the add operation takes precedence. The merge operation of two OR-Sets ensures that + * elements added at any replica are eventually observed at all replicas. Removed elements, + * once observed, are never reintroduced. + * This OR-Set implementation provides methods for adding elements, removing elements, + * checking for element existence, retrieving the set of elements, comparing with other OR-Sets, + * and merging with another OR-Set to create a new OR-Set containing all unique elements + * from both sets. + * + * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah) + * @see <a href="https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type">Conflict-free_replicated_data_type</a> + * @see <a href="https://github.com/itakurah">itakurah (Niklas Hoefflin)</a> + */ + +public class ORSet<T> { + + private final Set<Pair<T>> elements; + private final Set<Pair<T>> tombstones; + + /** + * Constructs an empty OR-Set. + */ + public ORSet() { + this.elements = new HashSet<>(); + this.tombstones = new HashSet<>(); + } + + /** + * Checks if the set contains the specified element. + * + * @param element the element to check for + * @return true if the set contains the element, false otherwise + */ + public boolean contains(T element) { + return elements.stream().anyMatch(pair -> pair.getElement().equals(element)); + } + + /** + * Retrieves the elements in the set. + * + * @return a set containing the elements + */ + public Set<T> elements() { + Set<T> result = new HashSet<>(); + elements.forEach(pair -> result.add(pair.getElement())); + return result; + } + + /** + * Adds the specified element to the set. + * + * @param element the element to add + */ + public void add(T element) { + String n = prepare(); + effect(element, n); + } + + /** + * Removes the specified element from the set. + * + * @param element the element to remove + */ + public void remove(T element) { + Set<Pair<T>> pairsToRemove = prepare(element); + effect(pairsToRemove); + } + + /** + * Collect all pairs with the specified element. + * + * @param element the element to collect pairs for + * @return a set of pairs with the specified element to be removed + */ + private Set<Pair<T>> prepare(T element) { + Set<Pair<T>> pairsToRemove = new HashSet<>(); + for (Pair<T> pair : elements) { + if (pair.getElement().equals(element)) { + pairsToRemove.add(pair); + } + } + return pairsToRemove; + } + + /** + * Generates a unique tag for the element. + * + * @return the unique tag + */ + private String prepare() { + return generateUniqueTag(); + } + + /** + * Adds the element with the specified unique tag to the set. + * + * @param element the element to add + * @param n the unique tag associated with the element + */ + private void effect(T element, String n) { + Pair<T> pair = new Pair<>(element, n); + elements.add(pair); + elements.removeAll(tombstones); + } + + /** + * Removes the specified pairs from the set. + * + * @param pairsToRemove the pairs to remove + */ + private void effect(Set<Pair<T>> pairsToRemove) { + elements.removeAll(pairsToRemove); + tombstones.addAll(pairsToRemove); + } + + /** + * Generates a unique tag. + * + * @return the unique tag + */ + private String generateUniqueTag() { + return UUID.randomUUID().toString(); + } + + /** + * Compares this Add-Wins OR-Set with another OR-Set to check if elements and tombstones are a subset. + * + * @param other the other OR-Set to compare + * @return true if the sets are subset, false otherwise + */ + public boolean compare(ORSet<T> other) { + Set<Pair<T>> union = new HashSet<>(elements); + union.addAll(tombstones); + + Set<Pair<T>> otherUnion = new HashSet<>(other.elements); + otherUnion.addAll(other.tombstones); + + return otherUnion.containsAll(union) && other.tombstones.containsAll(tombstones); + } + + /** + * Merges this Add-Wins OR-Set with another OR-Set. + * + * @param other the other OR-Set to merge + */ + public void merge(ORSet<T> other) { + elements.removeAll(other.tombstones); + other.elements.removeAll(tombstones); + elements.addAll(other.elements); + tombstones.addAll(other.tombstones); + } + + /** + * Represents a pair containing an element and a unique tag. + * + * @param <T> the type of the element in the pair + */ + public static class Pair<T> { + private final T element; + private final String uniqueTag; + + /** + * Constructs a pair with the specified element and unique tag. + * + * @param element the element in the pair + * @param uniqueTag the unique tag associated with the element + */ + public Pair(T element, String uniqueTag) { + this.element = element; + this.uniqueTag = uniqueTag; + } + + /** + * Gets the element from the pair. + * + * @return the element + */ + public T getElement() { + return element; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java b/Java/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java new file mode 100644 index 000000000000..53c21dcbd108 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java @@ -0,0 +1,100 @@ +package com.thealgorithms.datastructures.crdt; + +import java.util.HashMap; +import java.util.Map; + +/** + * PN-Counter (Positive-Negative Counter) is a state-based CRDT (Conflict-free Replicated Data Type) + * designed for tracking counts with both increments and decrements in a distributed and concurrent environment. + * It combines two G-Counters, one for increments (P) and one for decrements (N). + * The total count is obtained by subtracting the value of the decrement counter from the increment counter. + * This implementation supports incrementing, decrementing, querying the total count, + * comparing with other PN-Counters, and merging with another PN-Counter + * to compute the element-wise maximum for both increment and decrement counters. + * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) + * + * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah) + */ + +class PNCounter { + private final Map<Integer, Integer> pCounter; + private final Map<Integer, Integer> nCounter; + private final int myId; + private final int n; + + /** + * Constructs a PN-Counter for a cluster of n nodes. + * + * @param myId The identifier of the current node. + * @param n The number of nodes in the cluster. + */ + PNCounter(int myId, int n) { + this.myId = myId; + this.n = n; + this.pCounter = new HashMap<>(); + this.nCounter = new HashMap<>(); + + for (int i = 0; i < n; i++) { + pCounter.put(i, 0); + nCounter.put(i, 0); + } + } + + /** + * Increments the increment counter for the current node. + */ + public void increment() { + pCounter.put(myId, pCounter.get(myId) + 1); + } + + /** + * Increments the decrement counter for the current node. + */ + public void decrement() { + nCounter.put(myId, nCounter.get(myId) + 1); + } + + /** + * Gets the total value of the counter by subtracting the decrement counter from the increment counter. + * + * @return The total value of the counter. + */ + public int value() { + int sumP = pCounter.values().stream().mapToInt(Integer::intValue).sum(); + int sumN = nCounter.values().stream().mapToInt(Integer::intValue).sum(); + return sumP - sumN; + } + + /** + * Compares the state of this PN-Counter with another PN-Counter. + * + * @param other The other PN-Counter to compare with. + * @return True if the state of this PN-Counter is less than or equal to the state of the other PN-Counter. + */ + public boolean compare(PNCounter other) { + if (this.n != other.n) { + throw new IllegalArgumentException("Cannot compare PN-Counters with different number of nodes"); + } + for (int i = 0; i < n; i++) { + if (this.pCounter.get(i) > other.pCounter.get(i) && this.nCounter.get(i) > other.nCounter.get(i)) { + return false; + } + } + return true; + } + + /** + * Merges the state of this PN-Counter with another PN-Counter. + * + * @param other The other PN-Counter to merge with. + */ + public void merge(PNCounter other) { + if (this.n != other.n) { + throw new IllegalArgumentException("Cannot merge PN-Counters with different number of nodes"); + } + for (int i = 0; i < n; i++) { + this.pCounter.put(i, Math.max(this.pCounter.get(i), other.pCounter.get(i))); + this.nCounter.put(i, Math.max(this.nCounter.get(i), other.nCounter.get(i))); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java b/Java/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java new file mode 100644 index 000000000000..c0ce17b2802b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java @@ -0,0 +1,84 @@ +package com.thealgorithms.datastructures.crdt; + +import java.util.HashSet; +import java.util.Set; + +/** + * TwoPhaseSet (2P-Set) is a state-based CRDT (Conflict-free Replicated Data Type) designed for managing sets + * with support for both addition and removal operations in a distributed and concurrent environment. + * It combines two G-Sets (grow-only sets) - one set for additions and another set (tombstone set) for removals. + * Once an element is removed and placed in the tombstone set, it cannot be re-added, adhering to "remove-wins" semantics. + * This implementation supports querying the presence of elements, adding elements, removing elements, + * comparing with other 2P-Sets, and merging two 2P-Sets while preserving the remove-wins semantics. + * (https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) + * + * @author itakurah (Niklas Hoefflin) (https://github.com/itakurah) + */ + +public class TwoPSet<T> { + private final Set<T> setA; + private final Set<T> setR; + + /** + * Constructs an empty Two-Phase Set. + */ + public TwoPSet() { + this.setA = new HashSet<>(); + this.setR = new HashSet<>(); + } + + /** + * Checks if an element is in the set and has not been removed. + * + * @param element The element to be checked. + * @return True if the element is in the set and has not been removed, otherwise false. + */ + public boolean lookup(T element) { + return setA.contains(element) && !setR.contains(element); + } + + /** + * Adds an element to the set. + * + * @param element The element to be added. + */ + public void add(T element) { + setA.add(element); + } + + /** + * Removes an element from the set. The element will be placed in the tombstone set. + * + * @param element The element to be removed. + */ + public void remove(T element) { + if (lookup(element)) { + setR.add(element); + } + } + + /** + * Compares the current 2P-Set with another 2P-Set. + * + * @param otherSet The other 2P-Set to compare with. + * @return True if both SetA and SetR are subset, otherwise false. + */ + public boolean compare(TwoPSet<T> otherSet) { + return otherSet.setA.containsAll(setA) && otherSet.setR.containsAll(setR); + } + + /** + * Merges the current 2P-Set with another 2P-Set. + * + * @param otherSet The other 2P-Set to merge with. + * @return A new 2P-Set containing the merged elements. + */ + public TwoPSet<T> merge(TwoPSet<T> otherSet) { + TwoPSet<T> mergedSet = new TwoPSet<>(); + mergedSet.setA.addAll(this.setA); + mergedSet.setA.addAll(otherSet.setA); + mergedSet.setR.addAll(this.setR); + mergedSet.setR.addAll(otherSet.setR); + return mergedSet; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java b/Java/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java new file mode 100644 index 000000000000..583800998c81 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnion.java @@ -0,0 +1,53 @@ +package com.thealgorithms.datastructures.disjointsetunion; + +/** + * Disjoint Set Union or DSU is useful for solving problems related to connected components, + * cycle detection in graphs, and maintaining relationships in disjoint sets of data. + * It is commonly employed in graph algorithms and problems. + * + * @see <a href="https://en.wikipedia.org/wiki/Disjoint-set_data_structure">Disjoint Set Union</a> + */ +public class DisjointSetUnion<T> { + + /** + * Creates a new node of DSU with parent initialised as same node + */ + public Node<T> makeSet(final T x) { + return new Node<T>(x); + } + + /** + * Finds and returns the representative (root) element of the set to which a given element belongs. + * This operation uses path compression to optimize future findSet operations. + */ + public Node<T> findSet(Node<T> node) { + while (node != node.parent) { + node = node.parent; + } + return node; + } + + /** + * Unions two sets by merging their representative elements. The merge is performed based on the rank of each set + * to ensure efficient merging and path compression to optimize future findSet operations. + */ + public void unionSets(final Node<T> x, final Node<T> y) { + Node<T> nx = findSet(x); + Node<T> ny = findSet(y); + + if (nx == ny) { + return; // Both elements already belong to the same set. + } + // Merging happens based on rank of node, this is done to avoid long chaining of nodes and reduce time + // to find root of the component. Idea is to attach small components in big, instead of other way around. + if (nx.rank > ny.rank) { + ny.parent = nx; + } else if (ny.rank > nx.rank) { + nx.parent = ny; + } else { + // Both sets have the same rank; choose one as the parent and increment the rank. + ny.parent = nx; + nx.rank++; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java b/Java/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java new file mode 100644 index 000000000000..260f297bd713 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/disjointsetunion/Node.java @@ -0,0 +1,25 @@ +package com.thealgorithms.datastructures.disjointsetunion; + +public class Node<T> { + + /** + * The rank of the node, used for optimizing union operations. + */ + public int rank; + + /** + * Reference to the parent node in the set. + * Initially, a node is its own parent (represents a singleton set). + */ + public Node<T> parent; + + /** + * The data element associated with the node. + */ + public T data; + + public Node(final T data) { + this.data = data; + parent = this; // Initially, a node is its own parent. + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java b/Java/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java new file mode 100644 index 000000000000..cfec2e3b2c37 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java @@ -0,0 +1,227 @@ +package com.thealgorithms.datastructures.dynamicarray; + +import java.util.Arrays; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +/** + * This class implements a dynamic array + * + * @param <E> the type that each index of the array will hold + */ +public class DynamicArray<E> implements Iterable<E> { + + 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 <E> 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 <E> 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 <E> 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 <E> 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<E> 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); + } + + this.size = newSize; + this.elements[this.size] = 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<E> iterator() { + return new DynamicArrayIterator(); + } + + private final class DynamicArrayIterator implements Iterator<E> { + + 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<? super E> 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<E> class it tests a variety + * of methods and prints the output + */ + public static void main(String[] args) { + DynamicArray<String> 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java new file mode 100644 index 000000000000..b1af21eb6ff2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java @@ -0,0 +1,198 @@ +/* + Time Complexity = O(E), where E is equal to the number of edges + */ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +public final class A_Star { + private A_Star() { + } + + private static class Graph { + + // Graph's structure can be changed only applying changes to this class. + + private ArrayList<ArrayList<Edge>> graph; + + // Initialise ArrayLists in Constructor + Graph(int size) { + this.graph = new ArrayList<>(); + for (int i = 0; i < size; i++) { + this.graph.add(new ArrayList<>()); + } + } + + private ArrayList<Edge> 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; + + 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<Integer> path; // list of visited nodes in this path. + private int estimated; // heuristic value associated to the last node od the path (current node). + + PathAndDistance(int distance, ArrayList<Integer> path, int estimated) { + this.distance = distance; + this.path = path; + this.estimated = estimated; + } + + public int getDistance() { + return distance; + } + + public ArrayList<Integer> 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<Integer> data) { + for (int i = 0; i < data.size(); i += 4) { + graph.addEdge(new Edge(data.get(i), data.get(i + 1), data.get(i + 2))); + } + /* + .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<Integer> graphData = new ArrayList<>(Arrays.asList(0, 19, 75, null, 0, 15, 140, null, 0, 16, 118, null, 19, 12, 71, null, 12, 15, 151, null, 16, 9, 111, null, 9, 10, 70, null, 10, 3, 75, null, 3, 2, 120, null, 2, 14, 146, null, 2, 13, 138, null, 2, 6, 115, null, 15, 14, 80, null, + 15, 5, 99, null, 14, 13, 97, null, 5, 1, 211, null, 13, 1, 101, null, 6, 1, 160, null, 1, 17, 85, null, 17, 7, 98, null, 7, 4, 86, null, 17, 18, 142, null, 18, 8, 92, null, 8, 11, 87)); + initializeGraph(graph, graphData); + + PathAndDistance solution = aStar(3, 1, graph, heuristic); + solution.printSolution(); + } + + public static PathAndDistance aStar(int from, int to, Graph graph, int[] heuristic) { + // nodes are prioritised by the less value of the current distance of their paths, and the + // estimated value + // given by the heuristic function to reach the destination point from the current point. + PriorityQueue<PathAndDistance> queue = new PriorityQueue<>(Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated()))); + + // 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<Integer> updatedPath = new ArrayList<>(currentData.getPath()); + updatedPath.add(edge.getTo()); // Add the new node to the path, update the distance, + // and the heuristic function value associated to that path. + queue.add(new PathAndDistance(currentData.getDistance() + edge.getWeight(), updatedPath, heuristic[edge.getTo()])); + } + } + } + } + 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java new file mode 100644 index 000000000000..522e19787e8c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java @@ -0,0 +1,182 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.Scanner; + +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; + int 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; + int v; + int w; + + /** + * @param u Source Vertex + * @param v End vertex + * @param c Weight + */ + 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() { // shows distance to all vertices // Interactive run for understanding the + try ( // class first time. Assumes source vertex is 0 and + Scanner sc = new Scanner(System.in)) { + int i; + int v; + int e; + int u; + int ve; + int w; + int j; + int 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 (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 (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(); + } + } + } + } + + /** + * @param source Starting vertex + * @param end Ending vertex + * @param Edge Array of edges + */ + public void show(int source, int end, + Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray() + // method // Just shows results of computation, if graph is passed to it. The + // graph should + int i; + int j; + int v = vertex; + int e = edge; + int 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java new file mode 100644 index 000000000000..4cc14bfd38de --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java @@ -0,0 +1,81 @@ +package com.thealgorithms.datastructures.graphs; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +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}} + * + * Output : YES + */ +public final class BipartiteGrapfDFS { + private BipartiteGrapfDFS() { + } + + private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> 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)) { + return false; + } + } else if (color[it] == color[node]) { + return false; + } + } + return true; + } + + public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) { + // Code here + 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)) { + 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) { + String[] str1 = read.readLine().trim().split(" "); + int numVertices = Integer.parseInt(str1[0]); + int numEdges = Integer.parseInt(str1[1]); + + ArrayList<ArrayList<Integer>> adj = new ArrayList<>(); + for (int i = 0; i < numVertices; i++) { + adj.add(new ArrayList<>()); + } + for (int i = 0; i < numEdges; i++) { + String[] str2 = read.readLine().trim().split(" "); + int vertexU = Integer.parseInt(str2[0]); + int vertexV = Integer.parseInt(str2[1]); + adj.get(vertexU).add(vertexV); + adj.get(vertexV).add(vertexU); + } + + boolean ans = isBipartite(numVertices, adj); + if (ans) { + System.out.println("YES"); + } else { + System.out.println("NO"); + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java new file mode 100644 index 000000000000..dcdb08ad133e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java @@ -0,0 +1,217 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.List; + +/** + * Boruvka's algorithm to find Minimum Spanning Tree + * (https://en.wikipedia.org/wiki/Bor%C5%AFvka%27s_algorithm) + * + * @author itakurah (https://github.com/itakurah) + */ + +final class BoruvkaAlgorithm { + private BoruvkaAlgorithm() { + } + + /** + * Represents an edge in the graph + */ + static class Edge { + final int src; + final int dest; + final int weight; + + Edge(final int src, final int dest, final int weight) { + this.src = src; + this.dest = dest; + this.weight = weight; + } + } + + /** + * Represents the graph + */ + static class Graph { + final int vertex; + final List<Edge> edges; + + /** + * Constructor for the graph + * + * @param vertex number of vertices + * @param edges list of edges + */ + Graph(final int vertex, final List<Edge> edges) { + if (vertex < 0) { + throw new IllegalArgumentException("Number of vertices must be positive"); + } + if (edges == null || edges.isEmpty()) { + throw new IllegalArgumentException("Edges list must not be null or empty"); + } + for (final var edge : edges) { + checkEdgeVertices(edge.src, vertex); + checkEdgeVertices(edge.dest, vertex); + } + + this.vertex = vertex; + this.edges = edges; + } + } + + /** + * Represents a subset for Union-Find operations + */ + private static class Component { + int parent; + int rank; + + Component(final int parent, final int rank) { + this.parent = parent; + this.rank = rank; + } + } + + /** + * Represents the state of Union-Find components and the result list + */ + private static class BoruvkaState { + List<Edge> result; + Component[] components; + final Graph graph; + + BoruvkaState(final Graph graph) { + this.result = new ArrayList<>(); + this.components = initializeComponents(graph); + this.graph = graph; + } + + /** + * Adds the cheapest edges to the result list and performs Union operation on the subsets. + * + * @param cheapest Array containing the cheapest edge for each subset. + */ + void merge(final Edge[] cheapest) { + for (int i = 0; i < graph.vertex; ++i) { + if (cheapest[i] != null) { + final var component1 = find(components, cheapest[i].src); + final var component2 = find(components, cheapest[i].dest); + + if (component1 != component2) { + result.add(cheapest[i]); + union(components, component1, component2); + } + } + } + } + + /** + * Checks if there are more edges to add to the result list + * + * @return true if there are more edges to add, false otherwise + */ + boolean hasMoreEdgesToAdd() { + return result.size() < graph.vertex - 1; + } + + /** + * Computes the cheapest edges for each subset in the Union-Find structure. + * + * @return an array containing the cheapest edge for each subset. + */ + private Edge[] computeCheapestEdges() { + Edge[] cheapest = new Edge[graph.vertex]; + for (final var edge : graph.edges) { + final var set1 = find(components, edge.src); + final var set2 = find(components, edge.dest); + + if (set1 != set2) { + if (cheapest[set1] == null || edge.weight < cheapest[set1].weight) { + cheapest[set1] = edge; + } + if (cheapest[set2] == null || edge.weight < cheapest[set2].weight) { + cheapest[set2] = edge; + } + } + } + return cheapest; + } + + /** + * Initializes subsets for Union-Find + * + * @param graph the graph + * @return the initialized subsets + */ + private static Component[] initializeComponents(final Graph graph) { + Component[] components = new Component[graph.vertex]; + for (int v = 0; v < graph.vertex; ++v) { + components[v] = new Component(v, 0); + } + return components; + } + } + + /** + * Finds the parent of the subset using path compression + * + * @param components array of subsets + * @param i index of the subset + * @return the parent of the subset + */ + static int find(final Component[] components, final int i) { + if (components[i].parent != i) { + components[i].parent = find(components, components[i].parent); + } + return components[i].parent; + } + + /** + * Performs the Union operation for Union-Find + * + * @param components array of subsets + * @param x index of the first subset + * @param y index of the second subset + */ + static void union(Component[] components, final int x, final int y) { + final int xroot = find(components, x); + final int yroot = find(components, y); + + if (components[xroot].rank < components[yroot].rank) { + components[xroot].parent = yroot; + } else if (components[xroot].rank > components[yroot].rank) { + components[yroot].parent = xroot; + } else { + components[yroot].parent = xroot; + components[xroot].rank++; + } + } + + /** + * Boruvka's algorithm to find the Minimum Spanning Tree + * + * @param graph the graph + * @return list of edges in the Minimum Spanning Tree + */ + static List<Edge> boruvkaMST(final Graph graph) { + var boruvkaState = new BoruvkaState(graph); + + while (boruvkaState.hasMoreEdgesToAdd()) { + final var cheapest = boruvkaState.computeCheapestEdges(); + boruvkaState.merge(cheapest); + } + return boruvkaState.result; + } + + /** + * Checks if the edge vertices are in a valid range + * + * @param vertex the vertex to check + * @param upperBound the upper bound for the vertex range + */ + private static void checkEdgeVertices(final int vertex, final int upperBound) { + if (vertex < 0 || vertex >= upperBound) { + throw new IllegalArgumentException("Edge vertex out of range"); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java new file mode 100644 index 000000000000..d2b76e8e06b1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java @@ -0,0 +1,147 @@ +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<E extends Comparable<E>> { + + class Node { + + E name; + + Node(E name) { + this.name = name; + } + } + + class Edge { + + Node startNode; + Node endNode; + + Edge(Node startNode, Node endNode) { + this.startNode = startNode; + this.endNode = endNode; + } + } + + ArrayList<Edge> edgeList; + ArrayList<Node> nodeList; + + Graph() { + edgeList = new ArrayList<Edge>(); + nodeList = new ArrayList<Node>(); + } + + /** + * 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; + Node 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<Node> markedNodes = new HashSet<Node>(); + + for (Node n : nodeList) { + if (!markedNodes.contains(n)) { + markedNodes.add(n); + markedNodes.addAll(depthFirstSearch(n, new ArrayList<Node>())); + 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<Node> depthFirstSearch(Node n, ArrayList<Node> visited) { + visited.add(n); + for (Edge e : edgeList) { + if (e.startNode.equals(n) && !visited.contains(e.endNode)) { + depthFirstSearch(e.endNode, visited); + } + } + return visited; + } +} + +public final class ConnectedComponent { + private ConnectedComponent() { + } + + public static void main(String[] args) { + Graph<Character> 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<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java new file mode 100644 index 000000000000..b67c5512e622 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java @@ -0,0 +1,92 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.Scanner; + +class Cycle { + + private final int nodes; + private final int edges; + private int[][] adjacencyMatrix; + private boolean[] visited; + ArrayList<ArrayList<Integer>> cycles = new ArrayList<ArrayList<Integer>>(); + + 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 <Start Node> <End Node>"); + + for (int i = 0; i < edges; i++) { + int start; + int end; + start = in.nextInt(); + end = in.nextInt(); + adjacencyMatrix[start][end] = 1; + } + in.close(); + } + + public void start() { + for (int i = 0; i < nodes; i++) { + ArrayList<Integer> 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<Integer> 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<Integer>(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 final class Cycles { + private Cycles() { + } + + public static void main(String[] args) { + Cycle c = new Cycle(); + c.start(); + c.printAll(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java new file mode 100644 index 000000000000..8503aa48ec37 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java @@ -0,0 +1,86 @@ +/* +Refer https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/ +for better understanding + */ +package com.thealgorithms.datastructures.graphs; + +class dijkstras { + + int k = 9; + + int minDist(int[] dist, Boolean[] set) { + int min = Integer.MAX_VALUE; + int minIndex = -1; + + for (int r = 0; r < k; r++) { + if (!set[r] && dist[r] <= min) { + min = dist[r]; + minIndex = r; + } + } + + return minIndex; + } + + void print(int[] dist) { + System.out.println("Vertex \t\t Distance"); + 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]; + Boolean[] set = new Boolean[k]; + + for (int i = 0; i < k; i++) { + dist[i] = Integer.MAX_VALUE; + set[i] = Boolean.FALSE; + } + + dist[src] = 0; + + for (int c = 0; c < k - 1; c++) { + int u = minDist(dist, set); + + set[u] = Boolean.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]) { + 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}, + }; + dijkstras t = new dijkstras(); + t.dijkstra(graph, 0); + } // main +} // djikstras +/* +OUTPUT : +Vertex Distance +0 0 +1 4 +2 12 +3 19 +4 21 +5 11 +6 9 +7 8 +8 14 + */ diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java new file mode 100644 index 000000000000..d47ffe3aa27d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java @@ -0,0 +1,72 @@ +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]) { // calculated distance it get replaced as + // new shortest distance // if the new + // distance calculated is less then the + // earlier shortest + distanceMatrix[source][destination] = distanceMatrix[source][intermediate] + distanceMatrix[intermediate][destination]; + } + } + } + } + for (int 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java new file mode 100644 index 000000000000..b0970f36ddc5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java @@ -0,0 +1,140 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; + +class AdjacencyListGraph<E extends Comparable<E>> { + + ArrayList<Vertex> vertices; + + AdjacencyListGraph() { + vertices = new ArrayList<>(); + } + + private class Vertex { + + E data; + ArrayList<Vertex> adjacentVertices; + + Vertex(E data) { + adjacentVertices = new ArrayList<>(); + this.data = data; + } + + public boolean addAdjacentVertex(Vertex to) { + for (Vertex v : adjacentVertices) { + if (v.data.compareTo(to.data) == 0) { + return false; // the edge already exists + } + } + return adjacentVertices.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 < adjacentVertices.size(); i++) { + if (adjacentVertices.get(i).data.compareTo(to) == 0) { + adjacentVertices.remove(i); + 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(E from, E to) { + Vertex fromV = null; + for (Vertex v : vertices) { + 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 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(E from, E to) { + Vertex fromV = null; + Vertex toV = null; + for (Vertex v : vertices) { + 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); + vertices.add(fromV); + } + if (toV == null) { + toV = new Vertex(to); + vertices.add(toV); + } + return fromV.addAdjacentVertex(toV); + } + + /** + * this gives a list of vertices in the graph and their adjacencies + * + * @return returns a string describing this graph + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (Vertex v : vertices) { + sb.append("Vertex: "); + sb.append(v.data); + sb.append("\n"); + sb.append("Adjacent vertices: "); + for (Vertex v2 : v.adjacentVertices) { + sb.append(v2.data); + sb.append(" "); + } + sb.append("\n"); + } + return sb.toString(); + } +} + +public final class Graphs { + private Graphs() { + } + + public static void main(String[] args) { + AdjacencyListGraph<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java new file mode 100644 index 000000000000..65483eeeb65c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java @@ -0,0 +1,107 @@ +package com.thealgorithms.datastructures.graphs; + +/** + * Java program for Hamiltonian Cycle + * (https://en.wikipedia.org/wiki/Hamiltonian_path) + * + * @author Akshay Dubey (https://github.com/itsAkshayDubey) + */ +public class HamiltonianCycle { + + private int vertex; + private int pathCount; + private int[] cycle; + private int[][] graph; + + /** + * Find hamiltonian cycle for given graph G(V,E) + * + * @param graph Adjacency matrix of a graph G(V, E) + * for which hamiltonian path is to be found + * @return Array containing hamiltonian cycle + * else returns 1D array with value -1. + */ + public int[] findHamiltonianCycle(int[][] graph) { + this.vertex = graph.length; + this.cycle = new int[this.vertex + 1]; + + // Initialize path array with -1 value + for (int i = 0; i < this.cycle.length; i++) { + this.cycle[i] = -1; + } + + this.graph = graph; + + this.cycle[0] = 0; + this.pathCount = 1; + if (!isPathFound(0)) { + for (int i = 0; i < this.cycle.length; i++) { + this.cycle[i] = -1; + } + } else { + this.cycle[this.cycle.length - 1] = this.cycle[0]; + } + + return cycle; + } + + /** + * function to find paths recursively + * Find paths recursively from given vertex + * + * @param vertex Vertex from which path is to be found + * @returns true if path is found false otherwise + */ + public boolean isPathFound(int vertex) { + boolean isLastVertexConnectedToStart = this.graph[vertex][0] == 1 && this.pathCount == this.vertex; + if (isLastVertexConnectedToStart) { + return true; + } + + /** all vertices selected but last vertex not linked to 0 **/ + if (this.pathCount == this.vertex) { + return false; + } + + for (int v = 0; v < this.vertex; v++) { + /** if connected **/ + if (this.graph[vertex][v] == 1) { + /** add to path **/ + this.cycle[this.pathCount++] = v; + + /** remove connection **/ + this.graph[vertex][v] = 0; + this.graph[v][vertex] = 0; + + /** if vertex not already selected solve recursively **/ + if (!isPresent(v)) { + return isPathFound(v); + } + + /** restore connection **/ + this.graph[vertex][v] = 1; + this.graph[v][vertex] = 1; + + /** remove path **/ + this.cycle[--this.pathCount] = -1; + } + } + return false; + } + + /** + * function to check if path is already selected + * Check if path is already selected + * + * @param vertex Starting vertex + */ + public boolean isPresent(int vertex) { + for (int i = 0; i < pathCount - 1; i++) { + if (cycle[i] == vertex) { + return true; + } + } + + return false; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java new file mode 100644 index 000000000000..145071890d76 --- /dev/null +++ b/Java/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.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; +import java.util.Set; + +/** + * An algorithm that sorts a graph in toplogical order. + */ +/** + * A class that represents the adjaceny list of a graph + */ +class AdjacencyList<E extends Comparable<E>> { + + Map<E, ArrayList<E>> adj; + + AdjacencyList() { + adj = new LinkedHashMap<E, ArrayList<E>>(); + } + + /** + * 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<E>()); + adj.get(from).add(to); + } + if (!adj.containsKey(to)) { + adj.put(to, new ArrayList<E>()); + } + } + + /** + * @param v, A vertex in a graph + * @return returns an ArrayList of all the adjacents of vertex v + */ + ArrayList<E> getAdjacents(E v) { + return adj.get(v); + } + + /** + * @return returns a set of all vertices in the graph + */ + Set<E> 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<E extends Comparable<E>> { + + AdjacencyList<E> graph; + Map<E, Integer> inDegree; + + TopologicalSort(AdjacencyList<E> 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<E> topSortOrder() { + calculateInDegree(); + Queue<E> q = new LinkedList<E>(); + + for (E vertex : inDegree.keySet()) { + if (inDegree.get(vertex) == 0) { + q.add(vertex); + } + } + + ArrayList<E> 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 final class KahnsAlgorithm { + private KahnsAlgorithm() { + } + + public static void main(String[] args) { + // Graph definition and initialization + AdjacencyList<String> 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<String> topSort = new TopologicalSort<>(graph); + + // Printing the order + for (String s : topSort.topSortOrder()) { + System.out.print(s + " "); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java new file mode 100644 index 000000000000..c24046f510af --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java @@ -0,0 +1,143 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Java program that implements Kosaraju Algorithm. + * @author Shivanagouda S A (https://github.com/shivu2002a) + * + */ + +/** + * Kosaraju algorithm is a linear time algorithm to find the strongly connected components of a + directed graph, which, from here onwards will be referred by SCC. It leverages the fact that the + transpose graph (same graph with all the edges reversed) has exactly the same SCCs as the original + graph. + + * A graph is said to be strongly connected if every vertex is reachable from every other vertex. + The SCCs of a directed graph form a partition into subgraphs that are themselves strongly + connected. Single node is always a SCC. + + * Example: + + 0 <--- 2 -------> 3 -------- > 4 ---- > 7 + | ^ | ^ ^ + | / | \ / + | / | \ / + v / v \ / + 1 5 --> 6 + + For the above graph, the SCC list goes as follows: + 0, 1, 2 + 3 + 4, 5, 6 + 7 + + We can also see that order of the nodes in an SCC doesn't matter since they are in cycle. + + {@summary} + * Kosaraju Algorithm: + 1. Perform DFS traversal of the graph. Push node to stack before returning. This gives edges + sorted by lowest finish time. + 2. Find the transpose graph by reversing the edges. + 3. Pop nodes one by one from the stack and again to DFS on the modified graph. + + The transpose graph of the above graph: + 0 ---> 2 <------- 3 <------- 4 <------ 7 + ^ / ^ \ / + | / | \ / + | / | \ / + | v | v v + 1 5 <--- 6 + + We can observe that this graph has the same SCC as that of original graph. + + */ + +public class Kosaraju { + + // Sort edges according to lowest finish time + Stack<Integer> stack = new Stack<Integer>(); + + // Store each component + private List<Integer> scc = new ArrayList<>(); + + // All the strongly connected components + private List<List<Integer>> sccsList = new ArrayList<>(); + + /** + * + * @param v Node count + * @param list Adjacency list of graph + * @return List of SCCs + */ + public List<List<Integer>> kosaraju(int v, List<List<Integer>> list) { + + sortEdgesByLowestFinishTime(v, list); + + List<List<Integer>> transposeGraph = createTransposeMatrix(v, list); + + findStronglyConnectedComponents(v, transposeGraph); + + return sccsList; + } + + private void sortEdgesByLowestFinishTime(int v, List<List<Integer>> list) { + int[] vis = new int[v]; + for (int i = 0; i < v; i++) { + if (vis[i] == 0) { + dfs(i, vis, list); + } + } + } + + private List<List<Integer>> createTransposeMatrix(int v, List<List<Integer>> list) { + var transposeGraph = new ArrayList<List<Integer>>(v); + for (int i = 0; i < v; i++) { + transposeGraph.add(new ArrayList<>()); + } + for (int i = 0; i < v; i++) { + for (Integer neigh : list.get(i)) { + transposeGraph.get(neigh).add(i); + } + } + return transposeGraph; + } + + /** + * + * @param v Node count + * @param transposeGraph Transpose of the given adjacency list + */ + public void findStronglyConnectedComponents(int v, List<List<Integer>> transposeGraph) { + int[] vis = new int[v]; + while (!stack.isEmpty()) { + var node = stack.pop(); + if (vis[node] == 0) { + dfs2(node, vis, transposeGraph); + sccsList.add(scc); + scc = new ArrayList<>(); + } + } + } + + // Dfs to store the nodes in order of lowest finish time + private void dfs(int node, int[] vis, List<List<Integer>> list) { + vis[node] = 1; + for (Integer neighbour : list.get(node)) { + if (vis[neighbour] == 0) dfs(neighbour, vis, list); + } + stack.push(node); + } + + // Dfs to find all the nodes of each strongly connected component + private void dfs2(int node, int[] vis, List<List<Integer>> list) { + vis[node] = 1; + for (Integer neighbour : list.get(node)) { + if (vis[neighbour] == 0) dfs2(neighbour, vis, list); + } + scc.add(node); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java new file mode 100644 index 000000000000..eb5b65d5c0d4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java @@ -0,0 +1,103 @@ +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; + + Edge(int from, int to, int weight) { + this.from = from; + this.to = to; + this.weight = weight; + } + } + + private static void addEdge(HashSet<Edge>[] graph, int from, int to, int weight) { + graph[from].add(new Edge(from, to, weight)); + } + + public static void main(String[] args) { + HashSet<Edge>[] 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<Edge>[] 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<Edge>[] kruskal(HashSet<Edge>[] graph) { + int nodes = graph.length; + int[] captain = new int[nodes]; + // captain of i, stores the set with all the connected nodes to i + HashSet<Integer>[] connectedGroups = new HashSet[nodes]; + HashSet<Edge>[] minGraph = new HashSet[nodes]; + PriorityQueue<Edge> edges = new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight))); + 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java new file mode 100644 index 000000000000..902553f9a54c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java @@ -0,0 +1,345 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * 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 final class MatrixGraphs { + private 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 vertexCount; + + /** + * The number of edges in the graph + */ + private int edgeCount; + + /** + * The adjacency matrix for the graph + */ + private int[][] adjMatrix; + + /** + * 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 + */ + 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.vertexCount = newNumberOfVertices; + } + + /** + * Getter for `this.vertexCount` + * + * @return the number of vertices in the graph + */ + public int numberOfVertices() { + return this.vertexCount; + } + + /** + * Updates the number of edges in the graph + * + * @param newNumberOfEdges + * + */ + private void setNumberOfEdges(int newNumberOfEdges) { + this.edgeCount = newNumberOfEdges; + } + + /** + * Getter for `this.edgeCount` + * + * @return the number of edges + */ + public int numberOfEdges() { + return this.edgeCount; + } + + /** + * Sets a new matrix as the adjacency matrix + * + * @param newAdjacency the new adjaceny matrix + */ + private void setAdjacency(int[][] newAdjacency) { + this.adjMatrix = newAdjacency; + } + + /** + * Getter for the adjacency matrix + * + * @return the adjacency matrix + */ + private int[][] adjacency() { + return this.adjMatrix; + } + + /** + * 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) { + return aVertex >= 0 && aVertex < this.numberOfVertices(); + } + + /** + * 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<Integer> depthFirstOrder(int startVertex) { + // If the startVertex is invalid, return an empty list + if (startVertex >= vertexCount || startVertex < 0) { + return new ArrayList<Integer>(); + } + + // Create an array to track the visited vertices + boolean[] visited = new boolean[vertexCount]; + + // Create a list to keep track of the order of our traversal + ArrayList<Integer> orderList = new ArrayList<Integer>(); + + // 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<Integer> 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 = adjMatrix[currentVertex]; + for (int i = 0; i < adjacent.length; i++) { // we are considering exploring, recurse on it // If an edge exists between the + // currentVertex and the vertex + 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<Integer> breadthFirstOrder(int startVertex) { + // If the specified startVertex is invalid, return an empty list + if (startVertex >= vertexCount || startVertex < 0) { + return new ArrayList<Integer>(); + } + + // Create an array to keep track of the visited vertices + boolean[] visited = new boolean[vertexCount]; + + // Create a list to keep track of the ordered vertices + ArrayList<Integer> orderList = new ArrayList<Integer>(); + + // Create a queue for our BFS algorithm and add the startVertex + // to the queue + Queue<Integer> queue = new LinkedList<Integer>(); + 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 = adjMatrix[currentVertex]; + for (int vertex = 0; vertex < adjacent.length; vertex++) { // vertex we are considering exploring, we add it to the queue // If an + // edge exists between the current vertex and the + 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 + i + " "; + } + s = s + " \n"; + + for (int i = 0; i < this.numberOfVertices(); i++) { + s = s + i + " : "; + for (int j = 0; j < this.numberOfVertices(); j++) { + s = s + this.adjMatrix[i][j] + " "; + } + s = s + "\n"; + } + return s; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java new file mode 100644 index 000000000000..7e11862786f6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java @@ -0,0 +1,110 @@ +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; + int minIndex = -1; + + for (int v = 0; v < V; v++) { + if (!mstSet[v] && key[v] < min) { + min = key[v]; + minIndex = v; + } + } + + return minIndex; + } + + // 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] = Boolean.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] = Boolean.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++) // Update the key only if graph[u][v] is smaller than key[v] // mstSet[v] is + // false for vertices not yet included in MST // graph[u][v] is non zero only + // for adjacent vertices of m + { + if (graph[u][v] != 0 && !mstSet[v] && graph[u][v] < key[v]) { + 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/Java/src/main/java/com/thealgorithms/datastructures/graphs/README.md b/Java/src/main/java/com/thealgorithms/datastructures/graphs/README.md new file mode 100644 index 000000000000..057adb46acf5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/README.md @@ -0,0 +1,91 @@ +## Graphs +Graph is a useful data structure for representing most of the real-world problems involving a set of users/candidates/nodes and their relations. A graph consists of two parameters: + +``` +V = a set of vertices +E = a set of edges +``` + +Each edge in `E` connects any two vertices from `V`. Based on the type of edge, graphs can be of two types: + +1. **Directed**: The edges are directed in nature, which means that when there is an edge from node `A` to `B`, it does not imply that there is an edge from `B` to `A`. An example of a directed edge graph is the **follow** feature of social media. If you follow a celebrity, it doesn't imply that they follow you. + +2. **Undirected**: The edges don't have any direction. So if `A` and `B` are connected, we can assume that there is an edge from both `A` to `B` and `B` to `A`. For example, in a social media graph, if two persons are friends, it implies that both are friends with each other. + +### Components of a Graph + +**Vertices:** Vertices are the fundamental units of the graph. Sometimes, vertices are also known as vertex or nodes. Every node/vertex can be labeled or unlabelled. + +**Edges:** Edges are used to connect two nodes of the graph. They can be an ordered pair of nodes in a directed graph. Edges can connect any two nodes in any possible way. There are no rules. Sometimes, edges are also known as arcs. Every edge can be labeled/unlabeled. + +Graphs are used to solve many real-life problems. Graphs are used to represent networks. The networks may include paths in a city, telephone network, or circuit network. Graphs are also used in social networks like LinkedIn, Facebook. For example, on Facebook, each person is represented with a vertex (or node). Each node is a structure and contains information like person id, name, gender, locale, etc. + +### Graph Representation + +Graph can be represented in the following ways: + +**Set Representation:** Set representation of a graph involves two sets: Set of vertices V = {V1, V2, V3, V4} and set of edges E = {{V1, V2}, {V2, V3}, {V3, V4}, {V4, V1}}. This representation is efficient for memory but does not allow parallel edges. + +**Sequential Representation:** This representation of a graph can be represented by means of matrices: Adjacency Matrix, Incidence matrix, and Path matrix. + +**Adjacency Matrix:** This matrix includes information about the adjacent nodes. Here, aij = 1 if there is an edge from Vi to Vj; otherwise, it's 0. It is a matrix of order V×V. + +**Incidence Matrix:** This matrix includes information about the incidence of edges on the nodes. Here, aij = 1 if the jth edge Ej is incident on the ith vertex Vi; otherwise, it's 0. It is a matrix of order V×E. + +**Path Matrix:** This matrix includes information about the simple path between two vertices. Here, Pij = 1 if there is a path from Vi to Vj; otherwise, it's 0. It is also called the reachability matrix of graph G. + +**Linked Representation:** This representation gives information about the nodes to which a specific node is connected, i.e., adjacency lists. This representation gives the adjacency lists of the vertices with the help of arrays and linked lists. In the adjacency lists, the vertices connected to the specific vertex are arranged in the form of lists that are connected to that vertex. + +### Real-Time Applications of Graph + +Graphs are used to represent the flow of control in computers. +Graphs are used in social networking sites where users act as nodes, and connections between them act as edges. +In an operating system, graphs are used as resource allocation graphs. +Graphs are used in Google Maps to find the shortest route. +Graphs are also used in the airline system for effective route optimization. +In state transition diagrams, the graph is used to represent states and their transitions. +In transportation, graphs are used to find the shortest path. +In circuits, graphs can be used to represent circuit points as nodes and wires as edges. +Graphs are used in solving puzzles with only one solution, such as mazes. +Graphs are used in computer networks for Peer to Peer (P2P) applications. +Graphs, basically in the form of DAG (Directed Acyclic Graph), are used as an alternative to blockchain for cryptocurrency. For example, cryptocurrencies like IOTA and Nano are mainly based on DAG. + +### Advantages of Graph + +Using graphs, we can easily find the shortest path, neighbors of the nodes, and many more. +Graphs are used to implement algorithms like DFS and BFS. +They are used to find minimum spanning trees, which have many practical applications. +Graphs help in organizing data. +Because of their non-linear structure, graphs help in understanding complex problems and their visualization. + +### Disadvantages of Graph + +Graphs use lots of pointers, which can be complex to handle. +They can have large memory complexity. +If the graph is represented with an adjacency matrix, then it does not allow parallel edges, and multiplication of the graph is also difficult. + +### Representation + +1. **Adjacency Lists**: Each node is represented as an entry, and all the edges are represented as a list emerging from the corresponding node. So, if vertex 1 has edges to 2, 3, and 6, the list corresponding to 1 will have 2, 3, and 6 as entries. Consider the following graph: + +``` +0: 1-->2-->3 +1: 0-->2 +2: 0-->1 +3: 0-->4 +4: 3 +``` + +It means there are edges from 0 to 1, 2, and 3; from 1 to 0 and 2, and so on. + +2. **Adjacency Matrix**: The graph is represented as a matrix of size |V| x |V|, and an entry 1 in cell (i, j) implies that there is an edge from i to j. 0 represents no edge. The matrix for the above graph: + +``` + 0 1 2 3 4 + +0 0 1 1 1 0 +1 1 0 1 0 0 +2 1 1 0 0 0 +3 1 0 0 0 1 +4 0 0 0 1 0 +``` diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java new file mode 100644 index 000000000000..987e73a2a5d5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java @@ -0,0 +1,129 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** + * Java program that implements Tarjan's Algorithm. + * @author Shivanagouda S A (https://github.com/shivu2002a) + * + */ + +/** + * Tarjan's algorithm is a linear time algorithm to find the strongly connected components of a + directed graph, which, from here onwards will be referred as SCC. + + * A graph is said to be strongly connected if every vertex is reachable from every other vertex. + The SCCs of a directed graph form a partition into subgraphs that are themselves strongly + connected. Single node is always a SCC. + + * Example: + 0 --------> 1 -------> 3 --------> 4 + ^ / + | / + | / + | / + | / + | / + | / + | / + | / + | / + |V + 2 + + For the above graph, the SCC list goes as follows: + 1, 2, 0 + 3 + 4 + + We can also see that order of the nodes in an SCC doesn't matter since they are in cycle. + + {@summary} + Tarjan's Algorithm: + * DFS search produces a DFS tree + * Strongly Connected Components form subtrees of the DFS tree. + * If we can find the head of these subtrees, we can get all the nodes in that subtree (including + the head) and that will be one SCC. + * There is no back edge from one SCC to another (here can be cross edges, but they will not be + used). + + * Kosaraju Algorithm aims at doing the same but uses two DFS traversalse whereas Tarjan’s + algorithm does the same in a single DFS, which leads to much lower constant factors in the latter. + + */ +public class TarjansAlgorithm { + + // Timer for tracking lowtime and insertion time + private int time; + + private List<List<Integer>> sccList = new ArrayList<List<Integer>>(); + + public List<List<Integer>> stronglyConnectedComponents(int v, List<List<Integer>> graph) { + + // Initially all vertices as unvisited, insertion and low time are undefined + + // insertionTime:Time when a node is visited 1st time while DFS traversal + + // lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time) + // that can be reached from a subtree rooted with a particular node. + int[] lowTime = new int[v]; + int[] insertionTime = new int[v]; + for (int i = 0; i < v; i++) { + insertionTime[i] = -1; + lowTime[i] = -1; + } + + // To check if element is present in stack + boolean[] isInStack = new boolean[v]; + + // Store nodes during DFS + Stack<Integer> st = new Stack<Integer>(); + + for (int i = 0; i < v; i++) { + if (insertionTime[i] == -1) stronglyConnCompsUtil(i, lowTime, insertionTime, isInStack, st, graph); + } + + return sccList; + } + + private void stronglyConnCompsUtil(int u, int[] lowTime, int[] insertionTime, boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) { + + // Initialize insertion time and lowTime value of current node + insertionTime[u] = time; + lowTime[u] = time; + time += 1; + + // Push current node into stack + isInStack[u] = true; + st.push(u); + + // Go through all vertices adjacent to this + for (Integer vertex : graph.get(u)) { + // If the adjacent node is unvisited, do DFS + if (insertionTime[vertex] == -1) { + stronglyConnCompsUtil(vertex, lowTime, insertionTime, isInStack, st, graph); + // update lowTime for the current node comparing lowtime of adj node + lowTime[u] = Math.min(lowTime[u], lowTime[vertex]); + } else if (isInStack[vertex]) { + // If adj node is in stack, update low + lowTime[u] = Math.min(lowTime[u], insertionTime[vertex]); + } + } + // If lowtime and insertion time are same, current node is the head of an SCC + // head node found, get all the nodes in this SCC + if (lowTime[u] == insertionTime[u]) { + int w = -1; + var scc = new ArrayList<Integer>(); + + // Stack has all the nodes of the current SCC + while (w != u) { + w = st.pop(); + scc.add(w); + isInStack[w] = false; + } + sccList.add(scc); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java b/Java/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java new file mode 100644 index 000000000000..0981638d4903 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java @@ -0,0 +1,113 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.HashSet; +import java.util.stream.IntStream; + +/* + * The Welsh-Powell algorithm is a graph coloring algorithm + * used for coloring a graph with the minimum number of colors. + * https://en.wikipedia.org/wiki/Graph_coloring + */ + +public final class WelshPowell { + private static final int BLANK_COLOR = -1; // Representing uncolored state + + private WelshPowell() { + } + + static final class Graph { + private HashSet<Integer>[] adjacencyLists; + + private Graph(int vertices) { + if (vertices < 0) { + throw new IllegalArgumentException("Number of vertices cannot be negative"); + } + + adjacencyLists = new HashSet[vertices]; + Arrays.setAll(adjacencyLists, i -> new HashSet<>()); + } + + private void addEdge(int nodeA, int nodeB) { + validateVertex(nodeA); + validateVertex(nodeB); + if (nodeA == nodeB) { + throw new IllegalArgumentException("Self-loops are not allowed"); + } + adjacencyLists[nodeA].add(nodeB); + adjacencyLists[nodeB].add(nodeA); + } + + private void validateVertex(int vertex) { + if (vertex < 0 || vertex >= getNumVertices()) { + throw new IllegalArgumentException("Vertex " + vertex + " is out of bounds"); + } + } + + HashSet<Integer> getAdjacencyList(int vertex) { + return adjacencyLists[vertex]; + } + + int getNumVertices() { + return adjacencyLists.length; + } + } + + public static Graph makeGraph(int numberOfVertices, int[][] listOfEdges) { + Graph graph = new Graph(numberOfVertices); + for (int[] edge : listOfEdges) { + if (edge.length != 2) { + throw new IllegalArgumentException("Edge array must have exactly two elements"); + } + graph.addEdge(edge[0], edge[1]); + } + return graph; + } + + public static int[] findColoring(Graph graph) { + int[] colors = initializeColors(graph.getNumVertices()); + Integer[] sortedVertices = getSortedNodes(graph); + for (int vertex : sortedVertices) { + if (isBlank(colors[vertex])) { + boolean[] usedColors = computeUsedColors(graph, vertex, colors); + final var newColor = firstUnusedColor(usedColors); + colors[vertex] = newColor; + Arrays.stream(sortedVertices).forEach(otherVertex -> { + if (isBlank(colors[otherVertex]) && !isAdjacentToColored(graph, otherVertex, colors)) { + colors[otherVertex] = newColor; + } + }); + } + } + return colors; + } + + private static boolean isBlank(int color) { + return color == BLANK_COLOR; + } + + private static boolean isAdjacentToColored(Graph graph, int vertex, int[] colors) { + return graph.getAdjacencyList(vertex).stream().anyMatch(otherVertex -> !isBlank(colors[otherVertex])); + } + + private static int[] initializeColors(int numberOfVertices) { + int[] colors = new int[numberOfVertices]; + Arrays.fill(colors, BLANK_COLOR); + return colors; + } + + private static Integer[] getSortedNodes(final Graph graph) { + return IntStream.range(0, graph.getNumVertices()).boxed().sorted(Comparator.comparingInt(v -> - graph.getAdjacencyList(v).size())).toArray(Integer[] ::new); + } + + private static boolean[] computeUsedColors(final Graph graph, final int vertex, final int[] colors) { + boolean[] usedColors = new boolean[graph.getNumVertices()]; + graph.getAdjacencyList(vertex).stream().map(neighbor -> colors[neighbor]).filter(color -> !isBlank(color)).forEach(color -> usedColors[color] = true); + return usedColors; + } + + private static int firstUnusedColor(boolean[] usedColors) { + return IntStream.range(0, usedColors.length).filter(color -> !usedColors[color]).findFirst().getAsInt(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md new file mode 100644 index 000000000000..252b06ea59b0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/Readme.md @@ -0,0 +1,65 @@ +# HASHMAP DATA STRUCTURE + +A hash map organizes data so you can quickly look up values for a given key. + +## Strengths: +- **Fast lookups**: Lookups take O(1) time on average. +- **Flexible keys**: Most data types can be used for keys, as long as they're hashable. + +## Weaknesses: +- **Slow worst-case**: Lookups take O(n) time in the worst case. +- **Unordered**: Keys aren't stored in a special order. If you're looking for the smallest key, the largest key, or all the keys in a range, you'll need to look through every key to find it. +- **Single-directional lookups**: While you can look up the value for a given key in O(1) time, looking up the keys for a given value requires looping through the whole dataset—O(n) time. +- **Not cache-friendly**: Many hash table implementations use linked lists, which don't put data next to each other in memory. + +## Time Complexity +| | AVERAGE | WORST | +|--------|---------|-------| +| Space | O(n) | O(n) | +| Insert | O(1) | O(n) | +| Lookup | O(1) | O(n) | +| Delete | O(1) | O(n) | + +## Internal Structure of HashMap +Internally HashMap contains an array of Node and a node is represented as a class that contains 4 fields: +- int hash +- K key +- V value +- Node next + +It can be seen that the node contains a reference to its object. So it’s a linked list. + +## Performance of HashMap +The performance of HashMap depends on 2 parameters which are named as follows: +- Initial Capacity +- Load Factor + + +**Initial Capacity**: It is the capacity of HashMap at the time of its creation (It is the number of buckets a HashMap can hold when the HashMap is instantiated). In Java, it is 2^4=16 initially, meaning it can hold 16 key-value pairs. + +**Load Factor**: It is the percent value of the capacity after which the capacity of Hashmap is to be increased (It is the percentage fill of buckets after which Rehashing takes place). In Java, it is 0.75f by default, meaning the rehashing takes place after filling 75% of the capacity. + +**Threshold**: It is the product of Load Factor and Initial Capacity. In Java, by default, it is (16 * 0.75 = 12). That is, Rehashing takes place after inserting 12 key-value pairs into the HashMap. + +**Rehashing** : It is the process of doubling the capacity of the HashMap after it reaches its Threshold. In Java, HashMap continues to rehash(by default) in the following sequence – 2^4, 2^5, 2^6, 2^7, …. so on. + +If the initial capacity is kept higher then rehashing will never be done. But keeping it higher increases the time complexity of iteration. So it should be chosen very cleverly to increase performance. The expected number of values should be taken into account to set the initial capacity. The most generally preferred load factor value is 0.75 which provides a good deal between time and space costs. The load factor’s value varies between 0 and 1. + +``` +Note: From Java 8 onward, Java has started using Self Balancing BST instead of a linked list for chaining. +The advantage of self-balancing bst is, that we get the worst case (when every key maps to the same slot) search time is O(Log n). +``` + +Java has two hash table classes: HashTable and HashMap. In general, you should use a HashMap. + +While both classes use keys to look up values, there are some important differences, including: + +- A HashTable doesn't allow null keys or values; a HashMap does. +- A HashTable is synchronized to prevent multiple threads from accessing it at once; a HashMap isn't. + +## When Hash Map operations cost O(n) time? + +**Hash collisions**: If all our keys caused hash collisions, we'd be at risk of having to walk through all of our values for a single lookup (in the example above, we'd have one big linked list). This is unlikely, but it could happen. That's the worst case. + +**Dynamic array resizing**: Suppose we keep adding more items to our hash map. As the number of keys and values in our hash map exceeds the number of indices in the underlying array, hash collisions become inevitable. To mitigate this, we could expand our underlying array whenever things start to get crowded. That requires allocating a larger array and rehashing all of our existing keys to figure out their new position—O(n) time. + diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java new file mode 100644 index 000000000000..9fbb2ff0ad62 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java @@ -0,0 +1,128 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.LinkedList; + +// implementation of generic hashmaps using array of Linked Lists + +public class GenericHashMapUsingArray<K, V> { + + private int size; // n (total number of key-value pairs) + private LinkedList<Node>[] buckets; // N = buckets.length + private float lf = 0.75f; + + public GenericHashMapUsingArray() { + initBuckets(16); + size = 0; + } + + // load factor = 0.75 means if we need to add 100 items and we have added + // 75, then adding 76th item it will double the size, copy all elements + // & then add 76th item. + + private void initBuckets(int n) { + buckets = new LinkedList[n]; + for (int i = 0; i < buckets.length; i++) { + buckets[i] = new LinkedList<>(); + } + } + + public void put(K key, V value) { + int bucketIndex = hashFunction(key); + LinkedList<Node> nodes = buckets[bucketIndex]; + for (Node node : nodes) { // if key present => update + if (node.key.equals(key)) { + node.value = value; + return; + } + } + + // key is not present => insert + nodes.add(new Node(key, value)); + size++; + + if ((float) size / buckets.length > lf) { + reHash(); + } + } + + // tells which bucket to go to + private int hashFunction(K key) { + int hc = key.hashCode(); + return Math.abs(hc) % buckets.length; + } + + private void reHash() { + System.out.println("Rehashing!"); + LinkedList<Node>[] old = buckets; + initBuckets(old.length * 2); + this.size = 0; + + for (LinkedList<Node> nodes : old) { + for (Node node : nodes) { + put(node.key, node.value); + } + } + } + + public void remove(K key) { + int bucketIndex = hashFunction(key); + LinkedList<Node> nodes = buckets[bucketIndex]; + + Node target = null; + for (Node node : nodes) { + if (node.key.equals(key)) { + target = node; + break; + } + } + nodes.remove(target); + size--; + } + + public int size() { + return this.size; + } + + public V get(K key) { + int bucketIndex = hashFunction(key); + LinkedList<Node> nodes = buckets[bucketIndex]; + for (Node node : nodes) { + if (node.key.equals(key)) { + return node.value; + } + } + return null; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + + builder.append("{"); + for (LinkedList<Node> nodes : buckets) { + for (Node node : nodes) { + builder.append(node.key); + builder.append(" : "); + builder.append(node.value); + builder.append(", "); + } + } + builder.append("}"); + return builder.toString(); + } + + public boolean containsKey(K key) { + return get(key) != null; + } + + public class Node { + + K key; + V value; + + public Node(K key, V value) { + this.key = key; + this.value = value; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java new file mode 100644 index 000000000000..a1ef457f3432 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java @@ -0,0 +1,113 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.ArrayList; +import java.util.LinkedList; + +public class GenericHashMapUsingArrayList<K, V> { + + ArrayList<LinkedList<Node>> buckets; + private float lf = 0.5f; + private int size; + + public GenericHashMapUsingArrayList() { + buckets = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + buckets.add(new LinkedList<>()); + } + size = 0; + } + + public void put(K key, V value) { + int hash = Math.abs(key.hashCode() % buckets.size()); + LinkedList<Node> nodes = buckets.get(hash); + + for (Node node : nodes) { + if (node.key.equals(key)) { + node.val = value; + return; + } + } + + nodes.add(new Node(key, value)); + size++; + + if ((float) size / buckets.size() > lf) { + reHash(); + } + } + + private void reHash() { + ArrayList<LinkedList<Node>> old = buckets; + buckets = new ArrayList<>(); + size = 0; + for (int i = 0; i < old.size() * 2; i++) { + buckets.add(new LinkedList<>()); + } + for (LinkedList<Node> nodes : buckets) { + for (Node node : nodes) { + put(node.key, node.val); + } + } + } + + public V get(K key) { + int hash = Math.abs(key.hashCode() % buckets.size()); + LinkedList<Node> nodes = buckets.get(hash); + for (Node node : nodes) { + if (node.key.equals(key)) { + return node.val; + } + } + return null; + } + + public void remove(K key) { + int hash = Math.abs(key.hashCode() % buckets.size()); + LinkedList<Node> nodes = buckets.get(hash); + + Node target = null; + for (Node node : nodes) { + if (node.key.equals(key)) { + target = node; + break; + } + } + nodes.remove(target); + size--; + } + + public boolean containsKey(K key) { + return get(key) != null; + } + + public int size() { + return this.size; + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("{"); + for (LinkedList<Node> nodes : buckets) { + for (Node node : nodes) { + builder.append(node.key); + builder.append(" : "); + builder.append(node.val); + builder.append(", "); + } + } + builder.append("}"); + return builder.toString(); + } + + private class Node { + + K key; + V val; + + Node(K key, V val) { + this.key = key; + this.val = val; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java new file mode 100644 index 000000000000..ad273deaf4f0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMap.java @@ -0,0 +1,143 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +public class HashMap { + + private final int hsize; + private final LinkedList[] buckets; + + public HashMap(int hsize) { + buckets = new LinkedList[hsize]; + for (int i = 0; i < hsize; i++) { + buckets[i] = new LinkedList(); + // Java requires explicit initialization 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) { + while (n.getNext() != null) { + n = n.getNext(); + } + return n; + } + + public Node findKey(int key) { + if (!isEmpty()) { + Node temp = first; + if (temp.getKey() == key) return temp; + + while ((temp = temp.getNext()) != null) { + if (temp.getKey() == key) return temp; + } + } + return null; + } + + public void delete(int key) { + if (!isEmpty()) { + if (first.getKey() == key) { + Node next = first.next; + first.next = null; // help GC + first = next; + } else { + delete(first, key); + } + } + } + + 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()); + } + } else { + delete(n.getNext(), key); + } + } + + 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 final 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/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java new file mode 100644 index 000000000000..b48502b51d08 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java @@ -0,0 +1,258 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.Objects; + +/** + * This class is an implementation of a hash table using Cuckoo Hashing It uses + * a dynamic array to lengthen the size of the hash table when load factor > .7 + * + * <a href="https://en.wikipedia.org/wiki/Cuckoo_hashing">...</a> + */ +public class HashMapCuckooHashing { + + private int tableSize; // size of the hash table + private Integer[] buckets; // array representing the table + private final Integer emptySlot; + private int size; // number of elements in the hash table + + private int thresh; // threshold for infinite loop checking + + /** + * Constructor initializes buckets array, hsize, and creates dummy object + * for emptySlot + * + * @param tableSize the desired size of the hash map + */ + public HashMapCuckooHashing(int tableSize) { + this.buckets = new Integer[tableSize]; + this.tableSize = tableSize; + this.emptySlot = Integer.MIN_VALUE; + this.size = 0; + this.thresh = (int) (Math.log(tableSize) / Math.log(2)) + 2; + } + + /** + * The 2 Hash Functions takes a given key and finds an index based on its data, 2 distinctive + * ways to minimize collisions + * + * @param key the desired key to be converted + * @return int an index corresponding to the key + */ + + public int hashFunction1(int key) { + int hash = key % tableSize; + if (hash < 0) { + hash += tableSize; + } + return hash; + } + + public int hashFunction2(int key) { + int hash = key / tableSize; + hash %= tableSize; + if (hash < 0) { + hash += tableSize; + } + return hash; + } + + /** + * inserts the key into the hash map by wrapping it as an Integer object, then uses while loop + * to insert new key if desired place is empty, return. if already occupied, continue while loop + * over the new key that has just been pushed out. if while loop continues more than Thresh, + * rehash table to new size, then push again. + * + * @param key the desired key to be inserted in the hash map + */ + + public void insertKey2HashTable(int key) { + Integer wrappedInt = key; + Integer temp; + int hash; + int loopCounter = 0; + + if (isFull()) { + System.out.println("Hash table is full, lengthening & rehashing table"); + reHashTableIncreasesTableSize(); + } + + if (checkTableContainsKey(key)) { + throw new IllegalArgumentException("Key already inside, no duplicates allowed"); + } + + while (loopCounter <= thresh) { + loopCounter++; + hash = hashFunction1(key); + + if ((buckets[hash] == null) || Objects.equals(buckets[hash], emptySlot)) { + buckets[hash] = wrappedInt; + size++; + checkLoadFactor(); + return; + } + + temp = buckets[hash]; + buckets[hash] = wrappedInt; + wrappedInt = temp; + hash = hashFunction2(temp); + if (Objects.equals(buckets[hash], emptySlot)) { + buckets[hash] = wrappedInt; + size++; + checkLoadFactor(); + return; + } else if (buckets[hash] == null) { + buckets[hash] = wrappedInt; + size++; + checkLoadFactor(); + return; + } + + temp = buckets[hash]; + buckets[hash] = wrappedInt; + wrappedInt = temp; + } + System.out.println("Infinite loop occurred, lengthening & rehashing table"); + reHashTableIncreasesTableSize(); + insertKey2HashTable(key); + } + + /** + * creates new HashMapCuckooHashing object, then inserts each of the elements in the previous + * table to it with its new hash functions. then refers current array to new table. + * + */ + public void reHashTableIncreasesTableSize() { + HashMapCuckooHashing newT = new HashMapCuckooHashing(tableSize * 2); + for (int i = 0; i < tableSize; i++) { + if (buckets[i] != null && !Objects.equals(buckets[i], emptySlot)) { + newT.insertKey2HashTable(this.buckets[i]); + } + } + this.tableSize *= 2; + this.buckets = newT.buckets; + this.thresh = (int) (Math.log(tableSize) / Math.log(2)) + 2; + } + + /** + * deletes a key from the hash map and adds an available placeholder + * + * @param key the desired key to be deleted + */ + public void deleteKeyFromHashTable(int key) { + Integer wrappedInt = key; + int hash = hashFunction1(key); + if (isEmpty()) { + throw new IllegalArgumentException("Table is empty"); + } + + if (Objects.equals(buckets[hash], wrappedInt)) { + buckets[hash] = emptySlot; + size--; + return; + } + + hash = hashFunction2(key); + if (Objects.equals(buckets[hash], wrappedInt)) { + buckets[hash] = emptySlot; + size--; + return; + } + throw new IllegalArgumentException("Key " + key + " already inside, no duplicates allowed"); + } + + /** + * Displays the hash table line by line + */ + public void displayHashtable() { + for (int i = 0; i < tableSize; i++) { + if ((buckets[i] == null) || Objects.equals(buckets[i], emptySlot)) { + System.out.println("Bucket " + i + ": Empty"); + } else { + System.out.println("Bucket " + i + ": " + buckets[i].toString()); + } + } + System.out.println(); + } + + /** + * Finds the index of location based on an inputted key + * + * @param key the desired key to be found + * @return int the index where the key is located + */ + public int findKeyInTable(int key) { + Integer wrappedInt = key; + int hash = hashFunction1(key); + + if (isEmpty()) { + throw new IllegalArgumentException("Table is empty"); + } + + if (Objects.equals(buckets[hash], wrappedInt)) return hash; + + hash = hashFunction2(key); + if (!Objects.equals(buckets[hash], wrappedInt)) + throw new IllegalArgumentException("Key " + key + " not found in table"); + else { + return hash; + } + } + + /** + * checks if key is inside without any output other than returned boolean. + * + * @param key the desired key to be found + * @return int the index where the key is located + */ + public boolean checkTableContainsKey(int key) { + return ((buckets[hashFunction1(key)] != null && buckets[hashFunction1(key)].equals(key)) || (buckets[hashFunction2(key)] != null && buckets[hashFunction2(key)] == key)); + } + + /** + * Checks the load factor of the hash table if greater than .7, + * automatically lengthens table to prevent further collisions + */ + public double checkLoadFactor() { + double factor = (double) size / tableSize; + if (factor > .7) { + System.out.printf("Load factor is %.2f , rehashing table%n", factor); + reHashTableIncreasesTableSize(); + } + return 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 < tableSize; i++) { + if (buckets[i] == null || Objects.equals(buckets[i], emptySlot)) { + return false; + } + } + 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 < tableSize; i++) { + if (buckets[i] != null) { + response = false; + break; + } + } + return response; + } + + public int getNumberOfKeysInTable() { + return size; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java new file mode 100644 index 000000000000..54bd10de50fa --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java @@ -0,0 +1,37 @@ +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 + * here metaphor of sets is HashMap + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public final class Intersection { + + public static List<Integer> intersection(int[] arr1, int[] arr2) { + if (arr1 == null || arr2 == null || arr1.length == 0 || arr2.length == 0) { + return Collections.emptyList(); + } + Map<Integer, Integer> cnt = new HashMap<>(16); + for (int v : arr1) { + cnt.put(v, cnt.getOrDefault(v, 0) + 1); + } + List<Integer> res = new ArrayList<>(); + for (int v : arr2) { + if (cnt.containsKey(v) && cnt.get(v) > 0) { + res.add(v); + cnt.put(v, cnt.get(v) - 1); + } + } + return res; + } + + private Intersection() { + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java new file mode 100644 index 000000000000..c96da27c0331 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMap.java @@ -0,0 +1,141 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.ArrayList; + +/*** + * This class is an implementation of a hash table using linear probing. + * @see <a href="https://en.wikipedia.org/wiki/Linear_probing">Linear Probing Hash Table</a> + * + * @param <Key> keys type. + * @param <Value> values type. + */ +public class LinearProbingHashMap<Key extends Comparable<Key>, Value> extends Map<Key, Value> { + private int hsize; // size of the hash table + private Key[] keys; + private Value[] values; + private int size; // amount of elements in the hash table + + public LinearProbingHashMap() { + this(16); + } + + @SuppressWarnings("unchecked") + public LinearProbingHashMap(int size) { + this.hsize = size; + keys = (Key[]) new Comparable[size]; + values = (Value[]) new Object[size]; + } + + @Override + public boolean put(Key key, Value value) { + if (key == null) { + return false; + } + + if (size > hsize / 2) { + resize(2 * hsize); + } + + int keyIndex = hash(key, hsize); + for (; keys[keyIndex] != null; keyIndex = increment(keyIndex)) { + if (key.equals(keys[keyIndex])) { + values[keyIndex] = value; + return true; + } + } + + keys[keyIndex] = key; + values[keyIndex] = value; + size++; + return true; + } + + @Override + public Value get(Key key) { + if (key == null) { + return null; + } + + for (int i = hash(key, hsize); keys[i] != null; i = increment(i)) { + if (key.equals(keys[i])) { + return values[i]; + } + } + + return null; + } + + @Override + public boolean delete(Key key) { + if (key == null || !contains(key)) { + return false; + } + + int i = hash(key, hsize); + while (!key.equals(keys[i])) { + i = increment(i); + } + + keys[i] = null; + values[i] = null; + + i = increment(i); + while (keys[i] != null) { + // delete keys[i] an vals[i] and reinsert + Key keyToRehash = keys[i]; + Value valToRehash = values[i]; + keys[i] = null; + values[i] = null; + size--; + put(keyToRehash, valToRehash); + i = increment(i); + } + + size--; + if (size > 0 && size <= hsize / 8) { + resize(hsize / 2); + } + + return true; + } + + @Override + public boolean contains(Key key) { + return get(key) != null; + } + + @Override + int size() { + return size; + } + + @Override + Iterable<Key> keys() { + ArrayList<Key> listOfKeys = new ArrayList<>(size); + for (int i = 0; i < hsize; i++) { + if (keys[i] != null) { + listOfKeys.add(keys[i]); + } + } + + listOfKeys.sort(Comparable::compareTo); + return listOfKeys; + } + + private int increment(int i) { + return (i + 1) % hsize; + } + + private void resize(int newSize) { + LinearProbingHashMap<Key, Value> tmp = new LinearProbingHashMap<>(newSize); + for (int i = 0; i < hsize; i++) { + if (keys[i] != null) { + tmp.put(keys[i], values[i]); + } + } + + this.keys = tmp.keys; + this.values = tmp.values; + this.hsize = newSize; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java new file mode 100644 index 000000000000..082fd4b5ab2a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java @@ -0,0 +1,53 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.Scanner; + +public final class Main { + private Main() { + } + + public static void main(String[] args) { + int choice; + int key; + + HashMap h = new HashMap(7); + Scanner scan = 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 = scan.nextInt(); + + switch (choice) { + case 1: { + System.out.println("Enter the Key: "); + key = scan.nextInt(); + h.insertHash(key); + break; + } + case 2: { + System.out.println("Enter the Key delete: "); + key = scan.nextInt(); + h.deleteHash(key); + break; + } + case 3: { + System.out.println("Print table"); + h.displayHashtable(); + break; + } + case 4: { + scan.close(); + return; + } + default: { + throw new IllegalArgumentException("Unexpected value: " + choice); + } + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java new file mode 100644 index 000000000000..5a4a56e9b37d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java @@ -0,0 +1,71 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.Scanner; + +public final class MainCuckooHashing { + private MainCuckooHashing() { + } + + public static void main(String[] args) { + int choice; + int key; + + HashMapCuckooHashing h = new HashMapCuckooHashing(7); + Scanner scan = new Scanner(System.in); + + while (true) { + System.out.println("_________________________"); + 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"); + System.out.println("7. Rehash Current Table"); + + choice = scan.nextInt(); + + switch (choice) { + case 1: { + System.out.println("Enter the Key: "); + key = scan.nextInt(); + h.insertKey2HashTable(key); + break; + } + case 2: { + System.out.println("Enter the Key delete: "); + key = scan.nextInt(); + h.deleteKeyFromHashTable(key); + break; + } + case 3: { + System.out.println("Print table:\n"); + h.displayHashtable(); + break; + } + case 4: { + scan.close(); + return; + } + case 5: { + System.out.println("Enter the Key to find and print: "); + key = scan.nextInt(); + System.out.println("Key: " + key + " is at index: " + h.findKeyInTable(key) + "\n"); + break; + } + case 6: { + System.out.printf("Load factor is: %.2f%n", h.checkLoadFactor()); + break; + } + case 7: { + h.reHashTableIncreasesTableSize(); + break; + } + default: { + throw new IllegalArgumentException("Unexpected value: " + choice); + } + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java new file mode 100644 index 000000000000..bfa5759a41b9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java @@ -0,0 +1,37 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +/* +This class finds the majority element(s) in an array of integers. +A majority element is an element that appears more than or equal to n/2 times, where n is the length +of the array. +*/ +public final class MajorityElement { + private MajorityElement() { + } + /* + This method returns the majority element(s) in the given array of integers. + @param nums: an array of integers + @return a list of majority elements + */ + public static List<Integer> majority(int[] nums) { + HashMap<Integer, Integer> numToCount = new HashMap<>(); + int n = nums.length; + for (int i = 0; i < n; i++) { + if (numToCount.containsKey(nums[i])) { + numToCount.put(nums[i], numToCount.get(nums[i]) + 1); + } else { + numToCount.put(nums[i], 1); + } + } + List<Integer> majorityElements = new ArrayList<>(); + for (int key : numToCount.keySet()) { + if (numToCount.get(key) >= n / 2) { + majorityElements.add(key); + } + } + return majorityElements; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java new file mode 100644 index 000000000000..4605883fbbb1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Map.java @@ -0,0 +1,22 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +public abstract class Map<Key, Value> { + + abstract boolean put(Key key, Value value); + + abstract Value get(Key key); + + abstract boolean delete(Key key); + + abstract Iterable<Key> keys(); + + abstract int size(); + + public boolean contains(Key key) { + return get(key) != null; + } + + protected int hash(Key key, int size) { + return (key.hashCode() & Integer.MAX_VALUE) % size; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java new file mode 100644 index 000000000000..11af3f39981c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java @@ -0,0 +1,17 @@ +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); + } + + public EmptyHeapException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java new file mode 100644 index 000000000000..4aa7db1956ea --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/FibonacciHeap.java @@ -0,0 +1,427 @@ +package com.thealgorithms.datastructures.heaps; + +public class FibonacciHeap { + + private static final double GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2; + private HeapNode min; + private static int totalLinks = 0; + private static int totalCuts = 0; + private int numOfTrees = 0; + private int numOfHeapNodes = 0; + private int markedHeapNoodesCounter = 0; + + /* + * a constructor for an empty Heap + * set the min to be null + */ + public FibonacciHeap() { + this.min = null; + } + + /* + * a constructor for a Heap with one element + * set the min to be the HeapNode with the given key + * @pre key>=0 + * @post empty == false + */ + public FibonacciHeap(int key) { + this.min = new HeapNode(key); + this.numOfTrees++; + this.numOfHeapNodes++; + } + + /* + * check if the heap is empty + * $ret == true - if the tree is empty + */ + public boolean empty() { + return (this.min == null); + } + + /** + * Creates a node (of type HeapNode) which contains the given key, and inserts it into the heap. + * + * @pre key>=0 + * @post (numOfnodes = = $prev numOfnodes + 1) + * @post empty == false + * $ret = the HeapNode we inserted + */ + public HeapNode insert(int key) { + HeapNode toInsert = new HeapNode(key); // creates the node + if (this.empty()) { + this.min = toInsert; + } else { // tree is not empty + min.setNext(toInsert); + this.updateMin(toInsert); + } + this.numOfHeapNodes++; + this.numOfTrees++; + return toInsert; + } + + /** + * Delete the node containing the minimum key in the heap + * updates new min + * + * @post (numOfnodes = = $prev numOfnodes - 1) + */ + public void deleteMin() { + if (this.empty()) { + return; + } + if (this.numOfHeapNodes == 1) { // if there is only one tree + this.min = null; + this.numOfTrees--; + this.numOfHeapNodes--; + return; + } + // change all children's parent to null// + if (this.min.child != null) { // min has a child + HeapNode child = this.min.child; + HeapNode tmpChild = child; + child.parent = null; + while (child.next != tmpChild) { + child = child.next; + child.parent = null; + } + } + // delete the node// + if (this.numOfTrees > 1) { + (this.min.prev).next = this.min.next; + (this.min.next).prev = this.min.prev; + if (this.min.child != null) { + (this.min.prev).setNext(this.min.child); + } + } else { // this.numOfTrees = 1 + this.min = this.min.child; + } + this.numOfHeapNodes--; + this.successiveLink(this.min.getNext()); + } + + /** + * Return the node of the heap whose key is minimal. + * $ret == null if (empty==true) + */ + public HeapNode findMin() { + return this.min; + } + + /** + * Meld the heap with heap2 + * + * @pre heap2 != null + * @post (numOfnodes = = $prev numOfnodes + heap2.numOfnodes) + */ + public void meld(FibonacciHeap heap2) { + if (heap2.empty()) { + return; + } + if (this.empty()) { + this.min = heap2.min; + } else { + this.min.setNext(heap2.min); + this.updateMin(heap2.min); + } + this.numOfTrees += heap2.numOfTrees; + this.numOfHeapNodes += heap2.numOfHeapNodes; + } + + /** + * Return the number of elements in the heap + * $ret == 0 if heap is empty + */ + public int size() { + return this.numOfHeapNodes; + } + + /** + * Return a counters array, where the value of the i-th index is the number of trees with rank i + * in the heap. returns an empty array for an empty heap + */ + public int[] countersRep() { + if (this.empty()) { + return new int[0]; /// return an empty array + } + int[] rankArray = new int[(int) Math.floor(Math.log(this.size()) / Math.log(GOLDEN_RATIO)) + 1]; // creates the array + rankArray[this.min.rank]++; + HeapNode curr = this.min.next; + while (curr != this.min) { + rankArray[curr.rank]++; + curr = curr.next; + } + return rankArray; + } + + /** + * Deletes the node x from the heap (using decreaseKey(x) to -1) + * + * @pre heap contains x + * @post (numOfnodes = = $prev numOfnodes - 1) + */ + public void delete(HeapNode x) { + this.decreaseKey(x, x.getKey() + 1); // change key to be the minimal (-1) + this.deleteMin(); // delete it + } + + /** + * The function decreases the key of the node x by delta. + * + * @pre x.key >= delta (we don't realize it when calling from delete()) + * @pre heap contains x + */ + private void decreaseKey(HeapNode x, int delta) { + int newKey = x.getKey() - delta; + x.key = newKey; + if (x.isRoot()) { // no parent to x + this.updateMin(x); + return; + } + if (x.getKey() >= x.parent.getKey()) { + return; + } // we don't need to cut + HeapNode prevParent = x.parent; + this.cut(x); + this.cascadingCuts(prevParent); + } + + /** + * returns the current potential of the heap, which is: + * Potential = #trees + 2*#markedNodes + */ + public int potential() { + return numOfTrees + (2 * markedHeapNoodesCounter); + } + + /** + * This static function returns the total number of link operations made during the run-time of + * the program. A link operation is the operation which gets as input two trees of the same + * rank, and generates a tree of rank bigger by one. + */ + public static int totalLinks() { + return totalLinks; + } + + /** + * This static function returns the total number of cut operations made during the run-time of + * the program. A cut operation is the operation which disconnects a subtree from its parent + * (during decreaseKey/delete methods). + */ + public static int totalCuts() { + return totalCuts; + } + + /* + * updates the min of the heap (if needed) + * @pre this.min == @param (posMin) if and only if (posMin.key < this.min.key) + */ + private void updateMin(HeapNode posMin) { + if (posMin.getKey() < this.min.getKey()) { + this.min = posMin; + } + } + + /* + * Recursively "runs" all the way up from @param (curr) and mark the nodes. + * stop the recursion if we had arrived to a marked node or to a root. + * if we arrived to a marked node, we cut it and continue recursively. + * called after a node was cut. + * @post (numOfnodes == $prev numOfnodes) + */ + private void cascadingCuts(HeapNode curr) { + if (!curr.isMarked()) { // stop the recursion + curr.mark(); + if (!curr.isRoot()) this.markedHeapNoodesCounter++; + } else { + if (curr.isRoot()) { + return; + } + HeapNode prevParent = curr.parent; + this.cut(curr); + this.cascadingCuts(prevParent); + } + } + + /* + * cut a node (and his "subtree") from his origin tree and connect it to the heap as a new tree. + * called after a node was cut. + * @post (numOfnodes == $prev numOfnodes) + */ + private void cut(HeapNode curr) { + curr.parent.rank--; + if (curr.marked) { + this.markedHeapNoodesCounter--; + curr.marked = false; + } + if (curr.parent.child == curr) { // we should change the parent's child + if (curr.next == curr) { // curr do not have brothers + curr.parent.child = null; + } else { // curr have brothers + curr.parent.child = curr.next; + } + } + curr.prev.next = curr.next; + curr.next.prev = curr.prev; + curr.next = curr; + curr.prev = curr; + curr.parent = null; + this.min.setNext(curr); + this.updateMin(curr); + this.numOfTrees++; + totalCuts++; + } + + /* + * + */ + private void successiveLink(HeapNode curr) { + HeapNode[] buckets = this.toBuckets(curr); + this.min = this.fromBuckets(buckets); + } + + /* + * + */ + private HeapNode[] toBuckets(HeapNode curr) { + HeapNode[] buckets = new HeapNode[(int) Math.floor(Math.log(this.size()) / Math.log(GOLDEN_RATIO)) + 1]; + curr.prev.next = null; + HeapNode tmpCurr; + while (curr != null) { + tmpCurr = curr; + curr = curr.next; + tmpCurr.next = tmpCurr; + tmpCurr.prev = tmpCurr; + while (buckets[tmpCurr.rank] != null) { + tmpCurr = this.link(tmpCurr, buckets[tmpCurr.rank]); + buckets[tmpCurr.rank - 1] = null; + } + buckets[tmpCurr.rank] = tmpCurr; + } + return buckets; + } + + /* + * + */ + private HeapNode fromBuckets(HeapNode[] buckets) { + HeapNode tmpMin = null; + this.numOfTrees = 0; + for (int i = 0; i < buckets.length; i++) { + if (buckets[i] != null) { + this.numOfTrees++; + if (tmpMin == null) { + tmpMin = buckets[i]; + tmpMin.next = tmpMin; + tmpMin.prev = tmpMin; + } else { + tmpMin.setNext(buckets[i]); + if (buckets[i].getKey() < tmpMin.getKey()) { + tmpMin = buckets[i]; + } + } + } + } + return tmpMin; + } + + /* + * link between two nodes (and their trees) + * defines the smaller node to be the parent + */ + private HeapNode link(HeapNode c1, HeapNode c2) { + if (c1.getKey() > c2.getKey()) { + HeapNode c3 = c1; + c1 = c2; + c2 = c3; + } + if (c1.child == null) { + c1.child = c2; + } else { + c1.child.setNext(c2); + } + c2.parent = c1; + c1.rank++; + totalLinks++; + return c1; + } + + /** + * public class HeapNode + * each HeapNode belongs to a heap (Inner class) + */ + public class HeapNode { + + public int key; + private int rank; + private boolean marked; + private HeapNode child; + private HeapNode next; + private HeapNode prev; + private HeapNode parent; + + /* + * a constructor for a heapNode withe key @param (key) + * prev == next == this + * parent == child == null + */ + public HeapNode(int key) { + this.key = key; + this.marked = false; + this.next = this; + this.prev = this; + } + + /* + * returns the key of the node. + */ + public int getKey() { + return this.key; + } + + /* + * checks whether the node is marked + * $ret = true if one child has been cut + */ + private boolean isMarked() { + return this.marked; + } + + /* + * mark a node (after a child was cut) + * @inv root.mark() == false. + */ + private void mark() { + if (this.isRoot()) { + return; + } // check if the node is a root + this.marked = true; + } + + /* + * add the node @param (newNext) to be between this and this.next + * works fine also if @param (newNext) does not "stands" alone + */ + private void setNext(HeapNode newNext) { + HeapNode tmpNext = this.next; + this.next = newNext; + this.next.prev.next = tmpNext; + tmpNext.prev = newNext.prev; + this.next.prev = this; + } + + /* + * returns the next node to this node + */ + private HeapNode getNext() { + return this.next; + } + + /* + * check if the node is a root + * root definition - this.parent == null (uppest in his tree) + */ + private boolean isRoot() { + return (this.parent == null); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java new file mode 100644 index 000000000000..d546b7cc88d4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java @@ -0,0 +1,84 @@ +package com.thealgorithms.datastructures.heaps; + +import java.util.ArrayList; +import java.util.HashMap; + +public class GenericHeap<T extends Comparable<T>> { + + ArrayList<T> data = new ArrayList<>(); + HashMap<T, Integer> map = new HashMap<>(); + + public void add(T item) { + this.data.add(item); + map.put(item, this.data.size() - 1); // + upHeapify(this.data.size() - 1); + } + + private void upHeapify(int ci) { + int pi = (ci - 1) / 2; + if (isLarger(this.data.get(ci), this.data.get(pi)) > 0) { + swap(pi, ci); + upHeapify(pi); + } + } + + public void display() { + System.out.println(this.data); + } + + public int size() { + return this.data.size(); + } + + public boolean isEmpty() { + return this.size() == 0; + } + + public T remove() { + this.swap(0, this.size() - 1); + T rv = this.data.remove(this.size() - 1); + downHeapify(0); + map.remove(rv); + return rv; + } + + private void downHeapify(int pi) { + int lci = 2 * pi + 1; + int rci = 2 * pi + 2; + int mini = pi; + if (lci < this.size() && isLarger(this.data.get(lci), this.data.get(mini)) > 0) { + mini = lci; + } + if (rci < this.size() && isLarger(this.data.get(rci), this.data.get(mini)) > 0) { + mini = rci; + } + if (mini != pi) { + this.swap(pi, mini); + downHeapify(mini); + } + } + + public T get() { + return this.data.get(0); + } + + // t has higher property then return +ve + private int isLarger(T t, T o) { + return t.compareTo(o); + } + + private void swap(int i, int j) { + T ith = this.data.get(i); + T jth = this.data.get(j); + this.data.set(i, jth); + this.data.set(j, ith); + map.put(ith, j); + map.put(jth, i); + } + + public void updatePriority(T item) { + int index = map.get(item); + // because we enter lesser value then old vale + upHeapify(index); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java new file mode 100644 index 000000000000..63e101d9b13d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/Heap.java @@ -0,0 +1,44 @@ +package com.thealgorithms.datastructures.heaps; + +/** + * Interface common to heap data structures.<br> + * + * <p> + * 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). + * + * <p> + * 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/Java/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java new file mode 100644 index 000000000000..7c457a340645 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/HeapElement.java @@ -0,0 +1,137 @@ +package com.thealgorithms.datastructures.heaps; + +/** + * Class for heap elements.<br> + * + * <p> + * 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/Java/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java new file mode 100644 index 000000000000..59cb9dfab700 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java @@ -0,0 +1,117 @@ +package com.thealgorithms.datastructures.heaps; + +import java.util.ArrayList; + +/* + * This is a leftist heap that follows the same operations as a + * binary min heap, but may be unbalanced at times and follows a + * leftist property, in which the left side is more heavy on the + * right based on the null-path length (npl) values. + * + * Source: https://iq.opengenus.org/leftist-heap/ + * + */ + +public class LeftistHeap { + private static final class Node { + private final int element; + private int npl; + private Node left; + private Node right; + + // Node constructor setting the data element and left/right pointers to null + private Node(int element) { + this.element = element; + left = null; + right = null; + npl = 0; + } + } + + private Node root; + + // Constructor + public LeftistHeap() { + root = null; + } + + // Checks if heap is empty + public boolean isEmpty() { + return root == null; + } + + // Resets structure to initial state + public void clear() { + // We will put head is null + root = null; + } + + // Merge function that merges the contents of another leftist heap with the + // current one + public void merge(LeftistHeap h1) { + // If the present function is rhs then we ignore the merge + root = merge(root, h1.root); + h1.root = null; + } + + // Function merge with two Nodes a and b + public Node merge(Node a, Node b) { + if (a == null) return b; + + if (b == null) return a; + + // Violates leftist property, so must do a swap + if (a.element > b.element) { + Node temp = a; + a = b; + b = temp; + } + + // Now we call the function merge to merge a and b + a.right = merge(a.right, b); + + // Violates leftist property so must swap here + if (a.left == null) { + a.left = a.right; + a.right = null; + } else { + if (a.left.npl < a.right.npl) { + Node temp = a.left; + a.left = a.right; + a.right = temp; + } + a.npl = a.right.npl + 1; + } + return a; + } + + // Function insert. Uses the merge function to add the data + public void insert(int a) { + root = merge(new Node(a), root); + } + + // Returns and removes the minimum element in the heap + public int extractMin() { + // If is empty return -1 + if (isEmpty()) return -1; + + int min = root.element; + root = merge(root.left, root.right); + return min; + } + + // Function returning a list of an in order traversal of the data structure + public ArrayList<Integer> inOrder() { + ArrayList<Integer> lst = new ArrayList<>(); + inOrderAux(root, lst); + return new ArrayList<>(lst); + } + + // Auxiliary function for in_order + private void inOrderAux(Node n, ArrayList<Integer> lst) { + if (n == null) return; + inOrderAux(n.left, lst); + lst.add(n.element); + inOrderAux(n.right, lst); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java new file mode 100644 index 000000000000..9a584da0411c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java @@ -0,0 +1,129 @@ +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<HeapElement> maxHeap; + + public MaxHeap(List<HeapElement> 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) { + if ((elementIndex <= 0) || (elementIndex > maxHeap.size())) { + throw new IndexOutOfBoundsException("Index out of heap range"); + } + + 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 final 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", e); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java new file mode 100644 index 000000000000..f7ff0ec5a73d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java @@ -0,0 +1,123 @@ +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<HeapElement> minHeap; + + public MinHeap(List<HeapElement> 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) { + if ((elementIndex <= 0) || (elementIndex > minHeap.size())) { + throw new IndexOutOfBoundsException("Index out of heap range"); + } + + 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) + 1) > 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 final 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", e); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java b/Java/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java new file mode 100644 index 000000000000..2ad4ed5320c9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/MinPriorityQueue.java @@ -0,0 +1,132 @@ +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. + * + * <p> + * + * <p> + * 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() { + return 0 == this.size; + } + + // returns boolean value whether the heap is full or not + public boolean isFull() { + return this.size == this.capacity; + } + + // 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/Java/src/main/java/com/thealgorithms/datastructures/heaps/Readme.md b/Java/src/main/java/com/thealgorithms/datastructures/heaps/Readme.md new file mode 100644 index 000000000000..5e77c68dee8c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/heaps/Readme.md @@ -0,0 +1,128 @@ +<b><h1 align=center> HEAP DATA STRUCTURE</h1></b> +<p>A Heap is a special Tree-based data structure in which the tree is a complete binary tree. + +## <h2>Complete Binary Tree</h2> +<p>A complete binary tree is a binary tree +in which all the levels except the last level, i.e., leaf node should be completely filled, and all the nodes should be left-justified.</p> + + +``` + 10 + / \ + 20 30 + / \ + 40 50 + + COMPLETE BINARY TREE +``` + + +## <h2>Types of Heap</h2> +<p>Generally, Heaps can be of two types: +<br> +<strong>Max-Heap:</strong> In a Max-Heap the key present at the root node must be greatest among the keys present at all of it’s children. The same property must be recursively true for all sub-trees in that Binary Tree. +<br> +<strong>Min-Heap:</strong> In a Min-Heap the key present at the root node must be minimum among the keys present at all of it’s children. The same property must be recursively true for all sub-trees in that Binary Tree. +</p> + + + +``` + 10 + / \ + 20 30 + / \ / \ + 40 50 60 70 + + MIN HEAP +``` + +``` + 70 + / \ + 50 60 + / \ / \ + 40 30 10 20 + + MAX HEAP +``` + +## <h2>Min Heap Construction Algorithm</h2> +``` +Step 1 − Create a new node at the end of heap. +Step 2 − Assign new value to the node. +Step 3 − Compare the value of this child node with its parent. +Step 4 − If value of parent is more than child, then swap them. +Step 5 − Repeat step 3 & 4 until Heap property holds. +``` + +``` +Add 15 + + 10 10 10 + / \ / \ / \ + 20 30 ------> 20 30 ------> 20 15 + / \ / \ / / \ / + 40 50 40 50 15 40 50 30 + + +``` + +## <h2>Min Heap Deletion Algorithm</h2> +``` +Step 1 − Remove root node. +Step 2 − Move the last element of last level to root. +Step 3 − Compare the value of this child node with its parent. +Step 4 − If value of parent is more than child, then swap them. +Step 5 − Repeat step 3 & 4 until Heap property holds. +``` + +``` +Delete 10 + + 10 50 20 20 + / \ / \ / \ / \ + 20 30 ------> 20 30 ------> 50 30 ------> 40 30 + / \ / / / + 40 50 40 40 50 + + +``` + +## <h2>Time Complexity (Min Heap)</h2> +<table border=1> + <tr> + <th>Operations</th> + <th>Sorted Array</th> + <th>UnSorted Array</th> + <th>Heap</th> + </tr> + <tr> + <td>Add</td> + <td>O(N)</td> + <td>O(1)</td> + <td>O(logN)</td> + </tr> + <tr> + <td>Delete Minimum</td> + <td>O(N)</td> + <td>O(N)</td> + <td>O(logN)</td> + </tr> + <tr> + <td>Get Minimum</td> + <td>O(1)</td> + <td>O(N)</td> + <td>O(1)</td> + </tr> +</table> + +## <h2>Applications of Heap Data Structure</h2> + +<p> +<strong>Heapsort:</strong> Heapsort algorithm has limited uses because Quicksort is better in practice. Nevertheless, the Heap data structure itself is enormously used. + +<strong>Priority Queues:</strong> Priority queues can be efficiently implemented using Binary Heap because it supports insert(), delete() and extractmax(), decreaseKey() operations in O(logn) time. Binomoial Heap and Fibonacci Heap are variations of Binary Heap. These variations perform union also in O(logn) time which is a O(n) operation in Binary Heap. Heap Implemented priority queues are used in Graph algorithms like Prim’s Algorithm and Dijkstra’s algorithm. + +<strong>Order statistics:</strong> The Heap data structure can be used to efficiently find the kth smallest (or largest) element in an array. +</p> diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java new file mode 100644 index 000000000000..6eb9d75fe58f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java @@ -0,0 +1,106 @@ +package com.thealgorithms.datastructures.lists; + +public class CircleLinkedList<E> { + + private static final class Node<E> { + + Node<E> next; + E value; + + private Node(E value, Node<E> 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<E> head = null; + private Node<E> tail = null; // keeping a tail pointer to keep track of the end of list + + // constructor 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<E>(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<E>(value, head); + head.next = tail; + } else { + tail.next = new Node<E>(value, head); + tail = tail.next; + } + size++; + } + + // utility function for traversing the list + public String toString() { + Node<E> p = head.next; + String s = "[ "; + while (p != head) { + s += p.value; + if (p != tail) { + s += " , "; + } + p = p.next; + } + return s + " ]"; + } + + 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<E> before = head; + for (int i = 1; i <= pos; i++) { + before = before.next; + } + Node<E> destroy = before.next; + E saved = destroy.value; + // assigning the next reference to 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; + } + + public static void main(String[] args) { + CircleLinkedList<Integer> 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); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/CountSinglyLinkedListRecursion.java new file mode 100644 index 000000000000..8d864bc8caae --- /dev/null +++ b/Java/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/Java/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java new file mode 100644 index 000000000000..441c95702050 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java @@ -0,0 +1,106 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.Scanner; + +public final class CreateAndDetectLoop { + private 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 + * <a href="https://www.geeksforgeeks.org/make-loop-k-th-position-linked-list/"> + * GeeksForGeeks: Make a loop at K-th position</a> + * @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 + * <a href="https://en.wikipedia.org/wiki/Cycle_detection#Floyd's_tortoise_and_hare"> + * Floyd's Cycle Detection Algorithm</a> + * + * @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/Java/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java new file mode 100644 index 000000000000..b4fa9c51d4dc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java @@ -0,0 +1,184 @@ +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<T> { + + private static class Node<T> { + + 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<T>[] 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<T> 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 tempElement = cursorSpace[head].element; + int tempNext = cursorSpace[head].next; + if (tempElement.equals(element)) { + free(head); + head = tempNext; + } else { // otherwise cases + int prevIndex = head; + int currentIndex = cursorSpace[prevIndex].next; + + while (currentIndex != -1) { + T currentElement = cursorSpace[currentIndex].element; + if (currentElement.equals(element)) { + cursorSpace[prevIndex].next = cursorSpace[currentIndex].next; + free(currentIndex); + break; + } + + prevIndex = currentIndex; + currentIndex = cursorSpace[prevIndex].next; + } + } + + count--; + } + + private void free(int index) { + Node<T> osNode = cursorSpace[os]; + int osNext = osNode.next; + cursorSpace[os].next = index; + cursorSpace[index].element = null; + cursorSpace[index].next = osNext; + } + + 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} + cursorSpace[os].next = cursorSpace[availableNodeIndex].next; + + // 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/Java/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java new file mode 100644 index 000000000000..58898ddc0fcf --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java @@ -0,0 +1,410 @@ +package com.thealgorithms.datastructures.lists; + +/** + * This class implements a DoublyLinkedList. This is done using the classes + * LinkedList and Link. + * + * <p> + * 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 final class DoublyLinkedList { + + /** + * Head refers to the front of the list + */ + protected Link head; + /** + * Tail refers to the back of the list + */ + private Link tail; + /** + * Link Operations to perform operations on nodes of the list + */ + private LinkOperations linkOperations; + + /** + * Default Constructor + */ + public DoublyLinkedList() { + head = null; + tail = null; + } + + /** + * 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) { + linkOperations.insertTail(i, this); + } + } + + /** + * 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 + */ + 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(); + LinkOperations linkOperations = new LinkOperations(); + linkOperations.insertHead(13, myList); + linkOperations.insertHead(7, myList); + linkOperations.insertHead(10, myList); + myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) --> + myList.displayBackwards(); + + linkOperations.insertTail(11, myList); + myList.display(); // <-- 10(head) <--> 7 <--> 13 <--> 11(tail) --> + myList.displayBackwards(); + + linkOperations.deleteTail(); + myList.display(); // <-- 10(head) <--> 7 <--> 13(tail) --> + myList.displayBackwards(); + + linkOperations.delete(7); + myList.display(); // <-- 10(head) <--> 13(tail) --> + myList.displayBackwards(); + + linkOperations.insertOrdered(23, myList); + linkOperations.insertOrdered(67, myList); + linkOperations.insertOrdered(3, myList); + myList.display(); // <-- 3(head) <--> 10 <--> 13 <--> 23 <--> 67(tail) --> + linkOperations.insertElementByIndex(5, 1, myList); + myList.display(); // <-- 3(head) <--> 5 <--> 10 <--> 13 <--> 23 <--> 67(tail) --> + myList.displayBackwards(); + linkOperations.reverse(); // <-- 67(head) <--> 23 <--> 13 <--> 10 <--> 5 <--> 3(tail) --> + myList.display(); + + linkOperations.clearList(); + myList.display(); + myList.displayBackwards(); + linkOperations.insertHead(20, myList); + myList.display(); + myList.displayBackwards(); + } +} + +/* + * This class implements the operations of the Link nodes. + */ +class LinkOperations { + + /** + * 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; + + /** + * Insert an element at the head + * + * @param x Element to be inserted + */ + public void insertHead(int x, DoublyLinkedList doublyLinkedList) { + Link newLink = new Link(x); // Create a new link with a value attached to it + if (doublyLinkedList.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, DoublyLinkedList doublyLinkedList) { + Link newLink = new Link(x); + newLink.next = null; // currentTail(tail) newlink --> + if (doublyLinkedList.isEmpty()) { // Check if there are no elements in list then it adds first element + 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, DoublyLinkedList doublyLinkedList) { + if (index > size) { + throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); + } + if (index == 0) { + insertHead(x, doublyLinkedList); + } else { + if (index == size) { + insertTail(x, doublyLinkedList); + } 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, DoublyLinkedList doublyLinkedList) { + 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, doublyLinkedList); + } else if (current == null) { + insertTail(x, doublyLinkedList); + } 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 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 + 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 + */ + 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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java new file mode 100644 index 000000000000..99ab09f81c1c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java @@ -0,0 +1,65 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author https://github.com/shellhub + */ +public final class MergeSortedArrayList { + private MergeSortedArrayList() { + } + + public static void main(String[] args) { + List<Integer> listA = new ArrayList<>(); + List<Integer> listB = new ArrayList<>(); + List<Integer> 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<Integer> listA, List<Integer> listB, List<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedSinglyLinkedList.java new file mode 100644 index 000000000000..2bee945c9db6 --- /dev/null +++ b/Java/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/Java/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java new file mode 100644 index 000000000000..a714eda18bcd --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java @@ -0,0 +1,51 @@ +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<Node> min = new PriorityQueue<>(Comparator.comparingInt(x -> x.data)); + + // adding head of all linkedList in min heap + min.addAll(Arrays.asList(a).subList(0, n)); + + // 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 final class Node { + + private int data; + private Node next; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java new file mode 100644 index 000000000000..36b6e9c62cbe --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/QuickSortLinkedList.java @@ -0,0 +1,170 @@ +package com.thealgorithms.datastructures.lists; +/* + * + * @aurthor - Prabhat-Kumar-42 + * @github - https://github.com/Prabhat-Kumar-42 + * + * Problem : + * QuickSort on Linked List + * + * Note: Taking head as pivot in current implementation. + * N represents NULL node + * Example: + * + * -> Given Linked List : + * 5 -> 3 -> 8 -> 1 -> 10 -> 2 -> 7 -> 4 -> 9 -> 6 + * + * -> How Sorting will work according to the QuickSort Algo written below + * + * current pivot : 5 + * List lessThanPivot : 3 -> 1 -> 2 -> 4 + * List greaterThanPivot : 5 -> 8 -> 10 -> 7 -> 9 -> 6 + * + * -> reccur for lessThanPivot and greaterThanPivot + * + * lessThanPivot : + * current pivot : 3 + * lessThanPivot : 1 -> 2 + * greaterThanPivot : 4 + * + * greaterThanPivot: + * current pivot : 5 + * lessThanPivot : null + * greaterThanPivot : 8 -> 10 -> 7 -> 9 -> 6 + * + * By following the above pattern, reccuring tree will form like below : + * + * List-> 5 -> 3 -> 8 -> 1 -> 10 -> 2 -> 7 -> 4 -> 9 -> 6 + * + * Pivot : 5 + * /\ + * / \ + * / \ + * / \ + * / \ + * List: (3 -> 1 -> 2 -> 4) (5 -> 8 -> 10 -> 7 -> 9 -> 6) + * Pivot : 3 5 + * /\ /\ + * / \ / \ + * / \ / \ + * / \ / \ + * List: (1 -> 2) (4) (N) (8 -> 10 -> 7 -> 9 -> 6) + * Pivot: 1 4 8 + * /\ /\ /\ + * / \ / \ / \ + * / \ / \ / \ + * List: (N) (2) (N) (N) (6 -> 7) (9 -> 10) + * Pivot: 2 6 9 + * /\ /\ /\ + * / \ / \ / \ + * / \ / \ / \ + * List: (N) (N) (N) (7) (N) (10) + * Pivot: 7 10 + * /\ /\ + * / \ / \ + * / \ / \ + * (N) (N) (N) (N) + * + * + * -> After this the tree will reccur back (or backtrack) + * and the returning list from left and right subtree will attach + * themselves around pivot. + * i.e. , + * (listFromLeftSubTree) -> (Pivot) -> (listFromRightSubtree) + * + * This will continue until whole list is merged back + * + * eg : + * Megring the above Tree back we get : + * + * List: (1 -> 2) (4) (6 -> 7) (9 -> 10) + * \ / \ / + * \ / \ / + * \ / \ / + * \ / \ / + * \ / \ / + * \ / \ / + * \ / \ / + * Pivot: 3 8 + * List: (1 -> 2 -> 3 -> 4) (6 -> 7 -> 8 -> 9 -> 10) + * \ / + * \ / + * \ / + * \ / + * \ / + * \ / + * \ / + * \/ + * Pivot: 5 + * List: (1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10) + * + * + * -> This will result in a sorted Linked List + */ + +public class QuickSortLinkedList { + + private SinglyLinkedList list = null; // Linked list + private Node head = null; // head of the list + // Counstructor + public QuickSortLinkedList(SinglyLinkedList list) { + this.list = list; + this.head = list.getHead(); + } + + // Function to sort a linked list using the Quick Sort algorithm + public void sortList() { + head = sortList(head); + list.setHead(head); + } + // helper function to apply QuickSort to the stored list + public Node sortList(Node head) { + if (head == null || head.next == null) { + return head; + } + + // Choose the first element as the pivot + Node pivot = head; + head = head.next; + pivot.next = null; + + Node lessHead = new Node(); // stores the nodes cantaining data less than pivot node + Node lessTail = lessHead; // tail of lessHead + Node greaterHead = new Node(); // stores the nodes cantaining data greater than pivot node + Node greaterTail = greaterHead; // tail of greaterHead + + // Partition the list around the pivot + while (head != null) { + if (head.value < pivot.value) { + lessTail.next = head; + lessTail = lessTail.next; + } else { + greaterTail.next = head; + greaterTail = greaterTail.next; + } + head = head.next; + } + + // Seperating lessHead and greaterHead to form two seperate linkedList + lessTail.next = null; + greaterTail.next = null; + + // Recursively sort the sublists + Node sortedLess = sortList(lessHead.next); + Node sortedGreater = sortList(greaterHead.next); + + // Combine the sorted sublists and pivot + if (sortedLess == null) { + pivot.next = sortedGreater; + return pivot; + } else { + Node current = sortedLess; + while (current.next != null) { + current = current.next; + } + current.next = pivot; + pivot.next = sortedGreater; + return sortedLess; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/README.md b/Java/src/main/java/com/thealgorithms/datastructures/lists/README.md new file mode 100644 index 000000000000..cfb8221abca6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/README.md @@ -0,0 +1,32 @@ +## Linked List +### Description + +LinkedList is a data structure in which data is stored in a linear manner. It usually contains a data field and a link to the memory location of the next mode. + +### Structure + +``` +class LinkedList<E>{ + E value; + LinkedList next; +} +``` + +The `next` variable points to the next node in the data structure and value stores the data. Any number of nodes can be linked in this manner. The structure will be: + + +### Properties +1. Linked list does not provide indexing like an array. For accessing a node at position `p` , θ(p) nodes need to be accessed. +2. Main advantage of linked list is addition and removal of nodes near the end and beginning of lists. It can be done just by updating the link (O(1) time) +3. Unlike an array, its size is not predefined. So any number of nodes can be appended. + +### File descriptions: + +1. `CircleLinkedList.java` : A circular linked list where next pointer of last node points to first node of linked list. +2. `SinglyLinkedList.java` : The classic case of single links. +3. `CountSinglyLinkedListRecursion.java`: Recursively counts the size of a list. +4. `CreateAndDetectLoop.java` : Create and detect a loop in a linked list. +5. `DoublyLinkedList.java` : A modification of singly linked list which has a `prev` pointer to point to the previous node. +6. `Merge_K_SortedLinkedlist.java` : Merges K sorted linked list with mergesort (mergesort is also the most efficient sorting algorithm for linked list). +7. `RandomNode.java` : Selects a random node from given linked list and diplays it. +8. `SkipList.java` : Data Structure used for storing a sorted list of elements with help of a Linked list hierarchy that connects to subsequences of elements. diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java new file mode 100644 index 000000000000..7318b8027f8c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/RandomNode.java @@ -0,0 +1,97 @@ +/** + * Author : Suraj Kumar + * Github : https://github.com/skmodi649 + */ + +/** + * PROBLEM DESCRIPTION : + * There is a single linked list and we are supposed to find a random node in the given linked list + */ + +/** + * ALGORITHM : + * Step 1 : START + * Step 2 : Create an arraylist of type integer + * Step 3 : Declare an integer type variable for size and linked list type for head + * Step 4 : We will use two methods, one for traversing through the linked list using while loop and + * also increase the size by 1 + * + * (a) RandomNode(head) + * (b) run a while loop till null; + * (c) add the value to arraylist; + * (d) increase the size; + * + * Step 5 : Now use another method for getting random values using Math.random() and return the + * value present in arraylist for the calculated index Step 6 : Now in main() method we will simply + * insert nodes in the linked list and then call the appropriate method and then print the random + * node generated Step 7 : STOP + */ + +package com.thealgorithms.datastructures.lists; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +public class RandomNode { + + private List<Integer> list; + private int size; + private static Random rand = new Random(); + + static class ListNode { + + int val; + ListNode next; + + ListNode(int val) { + this.val = val; + } + } + + public RandomNode(ListNode head) { + list = new ArrayList<>(); + ListNode temp = head; + + // Now using while loop to traverse through the linked list and + // go on adding values and increasing the size value by 1 + while (temp != null) { + list.add(temp.val); + temp = temp.next; + size++; + } + } + + public int getRandom() { + int index = rand.nextInt(size); + return list.get(index); + } + + // Driver program to test above functions + public static void main(String[] args) { + ListNode head = new ListNode(15); + head.next = new ListNode(25); + head.next.next = new ListNode(4); + head.next.next.next = new ListNode(1); + head.next.next.next.next = new ListNode(78); + head.next.next.next.next.next = new ListNode(63); + RandomNode list = new RandomNode(head); + int randomNum = list.getRandom(); + System.out.println("Random Node : " + randomNum); + } +} +/** + * OUTPUT : + * First output : + * Random Node : 25 + * Second output : + * Random Node : 78 + * Time Complexity : O(n) + * Auxiliary Space Complexity : O(1) + * Time Complexity : O(n) + * Auxiliary Space Complexity : O(1) + */ +/** + * Time Complexity : O(n) + * Auxiliary Space Complexity : O(1) + */ diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java new file mode 100644 index 000000000000..3c4b9331266c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java @@ -0,0 +1,45 @@ +package com.thealgorithms.datastructures.lists; + +/** + * Reverse K Group LinkedList (https://www.topcoder.com/thrive/articles/reverse-node-in-k-group) + * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public class ReverseKGroup { + public int length(Node head) { + Node curr = head; + int count = 0; + while (curr != null) { + curr = curr.next; + count++; + } + return count; + } + // reverse function + public Node reverse(Node head, int count, int k) { + if (count < k) { + return head; + } + Node prev = null; + int count1 = 0; + Node curr = head; + Node next = null; + while (curr != null && count1 < k) { + next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + count1++; + } + + if (next != null) { + head.next = reverse(next, count - k, k); + } + return prev; + } + public Node reverseKGroup(Node head, int k) { + int count = length(head); + Node ans = reverse(head, count, k); + return ans; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java new file mode 100644 index 000000000000..e7ea95d3f037 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedLists.java @@ -0,0 +1,33 @@ +package com.thealgorithms.datastructures.lists; + +/** + * Rotate a list + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public class RotateSinglyLinkedLists { + public Node rotateRight(Node head, int k) { + if (head == null || head.next == null || k == 0) { + return head; + } + + Node curr = head; + int len = 1; + while (curr.next != null) { + curr = curr.next; + len++; + } + + curr.next = head; + k = k % len; + k = len - k; + while (k > 0) { + curr = curr.next; + k--; + } + + head = curr.next; + curr.next = null; + return head; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/SearchSinglyLinkedListRecursion.java new file mode 100644 index 000000000000..35f8c9a95b56 --- /dev/null +++ b/Java/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/Java/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java new file mode 100644 index 000000000000..bca3c77f2724 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java @@ -0,0 +1,521 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.StringJoiner; + +/** + * https://en.wikipedia.org/wiki/Linked_list + */ +public class SinglyLinkedList implements Iterable<Integer> { + + /** + * 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; + } + + /** + * 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; + while (currentNodeFast != null && currentNodeFast.next != null) { + currentNodeFast = currentNodeFast.next.next; + currentNodeSlow = currentNodeSlow.next; + if (currentNodeFast == currentNodeSlow) { + return true; + } + } + return false; + } + + /** + * Return the node in the middle of the list + * If the length of the list is even then return item number length/2 + * @return middle node of the list + */ + public Node middle() { + if (head == null) { + return null; + } + Node firstCounter = head; + Node secondCounter = firstCounter.next; + while (secondCounter != null && secondCounter.next != null) { + firstCounter = firstCounter.next; + secondCounter = secondCounter.next.next; + } + return firstCounter; + } + + /** + * Swaps nodes of two given values a and b. + * + */ + public void swapNodes(int valueFirst, int valueSecond) { + if (valueFirst == valueSecond) { + return; + } + Node previousA = null; + Node currentA = head; + while (currentA != null && currentA.value != valueFirst) { + previousA = currentA; + currentA = currentA.next; + } + + Node previousB = null; + Node currentB = head; + while (currentB != null && currentB.value != valueSecond) { + previousB = currentB; + currentB = currentB.next; + } + /** If either of 'a' or 'b' is not present, then return */ + if (currentA == null || currentB == null) { + return; + } + + // If 'a' is not head node of list + if (previousA != null) { + previousA.next = currentB; + } else { + // make 'b' as the new head + head = currentB; + } + + // If 'b' is not head node of list + if (previousB != null) { + previousB.next = currentA; + } else { + // Make 'a' as new head + head = currentA; + } + // Swap next pointer + + Node temp = currentA.next; + currentA.next = currentB.next; + currentB.next = temp; + } + + /** + * Reverse a singly linked list[Iterative] from a given node till the end + * + */ + public Node reverseListIter(Node node) { + Node prev = null; + Node curr = node; + + while (curr != null && curr.next != null) { + Node next = curr.next; + curr.next = prev; + prev = curr; + curr = next; + } + // when curr.next==null, the current element is left without pointing it to its prev,so + if (curr != null) { + curr.next = prev; + prev = curr; + } + // prev will be pointing to the last element in the Linkedlist, it will be the new head of + // the reversed linkedlist + return prev; + } + /** + * Reverse a singly linked list[Recursive] from a given node till the end + * + */ + public Node reverseListRec(Node head) { + if (head == null || head.next == null) { + return head; + } + + Node prev = null; + Node h2 = reverseListRec(head.next); + + head.next.next = head; + head.next = prev; + + return h2; + } + + /** + * Clear all nodes in the list + */ + public void clear() { + Node cur = head; + while (cur != null) { + cur = cur.next; + } + 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; + } + + /** + * Set head of the list. + * + */ + public void setHead(Node head) { + this.head = head; + } + + /** + * Calculate the count of the list manually + * + * @return count of the list + */ + public int count() { + int count = 0; + for (final var element : this) { + ++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(final int key) { + for (final var element : this) { + if (element == key) { + return true; + } + } + return false; + } + + @Override + public String toString() { + StringJoiner joiner = new StringJoiner("->"); + for (final var element : this) { + joiner.add(element + ""); + } + return joiner.toString(); + } + + public void deleteDuplicates() { + Node pred = head; + // predecessor = the node + // having sublist of its duplicates + Node newHead = head; + while (newHead != null) { + // if it's a beginning of duplicates sublist + // skip all duplicates + if (newHead.next != null && newHead.value == newHead.next.value) { + // move till the end of duplicates sublist + while (newHead.next != null && newHead.value == newHead.next.value) { + newHead = newHead.next; + } + // skip all duplicates + pred.next = newHead.next; + newHead = null; + // otherwise, move predecessor + } + // move forward + pred = pred.next; + newHead = pred; + } + } + + public void print() { + Node temp = head; + while (temp != null && temp.next != null) { + System.out.print(temp.value + "->"); + temp = temp.next; + } + if (temp != null) { + System.out.print(temp.value); + System.out.println(); + } + } + + /** + * 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; + } + 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++; + } + + /** + * Swaps nodes of two given values a and b. + * + */ + + /** + * 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) { + head = head.next; + /* clear to let GC do its work */ + size--; + return; + } + Node cur = head; + for (int i = 0; i < position - 1; ++i) { + cur = cur.next; + } + + cur.next = cur.next.next; + size--; + } + + /** + * 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; + } + + /** + * @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 + ""); + } + } + + /** + * 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"); + System.out.println(list); + /* 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"); + System.out.println(list); + 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 */ + } + + SinglyLinkedList instance = new SinglyLinkedList(); + Node head = new Node(0, new Node(2, new Node(3, new Node(3, new Node(4))))); + instance.setHead(head); + instance.deleteDuplicates(); + instance.print(); + } + + @Override + public Iterator<Integer> iterator() { + return new SinglyLinkedListIterator(); + } + + private class SinglyLinkedListIterator implements Iterator<Integer> { + private Node current; + + SinglyLinkedListIterator() { + current = head; + } + + @Override + public boolean hasNext() { + return current != null; + } + + @Override + public Integer next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + final var value = current.value; + current = current.next; + return value; + } + } +} + +/** + * 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/Java/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java b/Java/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java new file mode 100644 index 000000000000..3309ab24917d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java @@ -0,0 +1,329 @@ +package com.thealgorithms.datastructures.lists; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +/** + * Skip list is a data structure that allows {@code O(log n)} search complexity + * as well as {@code O(log n)} insertion complexity within an ordered sequence + * of {@code n} elements. Thus it can get the best features of a sorted array + * (for searching) while maintaining a linked list-like structure that allows + * insertion, which is not possible with a static array. + * <p> + * A skip list is built in layers. The bottom layer is an ordinary ordered + * linked list. Each higher layer acts as an "express lane" for the lists + * below. + * <pre> + * [ ] ------> [ ] --> [ ] + * [ ] --> [ ] [ ] --> [ ] + * [ ] [ ] [ ] [ ] [ ] [ ] + * H 0 1 2 3 4 + * </pre> + * + * @param <E> type of elements + * @see <a href="https://en.wikipedia.org/wiki/Skip_list">Wiki. Skip list</a> + */ +public class SkipList<E extends Comparable<E>> { + + /** + * Node before first node. + */ + private final Node<E> head; + + /** + * Maximum layers count. + * Calculated by {@link #heightStrategy}. + */ + private final int height; + + /** + * Function for determining height of new nodes. + * @see HeightStrategy + */ + private final HeightStrategy heightStrategy; + + /** + * Current count of elements in list. + */ + private int size; + + private static final int DEFAULT_CAPACITY = 100; + + public SkipList() { + this(DEFAULT_CAPACITY, new BernoulliHeightStrategy()); + } + + public SkipList(int expectedCapacity, HeightStrategy heightStrategy) { + this.heightStrategy = heightStrategy; + this.height = heightStrategy.height(expectedCapacity); + this.head = new Node<>(null, this.height); + this.size = 0; + } + + public void add(E e) { + Objects.requireNonNull(e); + Node<E> current = head; + int layer = height; + Node<E>[] toFix = new Node[height + 1]; + + while (layer >= 0) { + Node<E> next = current.next(layer); + if (next == null || next.getValue().compareTo(e) > 0) { + toFix[layer] = current; + layer--; + } else { + current = next; + } + } + int nodeHeight = heightStrategy.nodeHeight(height); + Node<E> node = new Node<>(e, nodeHeight); + for (int i = 0; i <= nodeHeight; i++) { + if (toFix[i].next(i) != null) { + node.setNext(i, toFix[i].next(i)); + toFix[i].next(i).setPrevious(i, node); + } + + toFix[i].setNext(i, node); + node.setPrevious(i, toFix[i]); + } + size++; + } + + public E get(int index) { + int counter = -1; // head index + Node<E> current = head; + while (counter != index) { + current = current.next(0); + counter++; + } + return current.value; + } + + public void remove(E e) { + Objects.requireNonNull(e); + Node<E> current = head; + int layer = height; + + while (layer >= 0) { + Node<E> next = current.next(layer); + if (e.equals(current.getValue())) { + break; + } else if (next == null || next.getValue().compareTo(e) > 0) { + layer--; + } else { + current = next; + } + } + for (int i = 0; i <= layer; i++) { + current.previous(i).setNext(i, current.next(i)); + if (current.next(i) != null) { + current.next(i).setPrevious(i, current.previous(i)); + } + } + size--; + } + + /** + * A search for a target element begins at the head element in the top + * list, and proceeds horizontally until the current element is greater + * than or equal to the target. If the current element is equal to the + * target, it has been found. If the current element is greater than the + * target, or the search reaches the end of the linked list, the procedure + * is repeated after returning to the previous element and dropping down + * vertically to the next lower list. + * + * @param e element whose presence in this list is to be tested + * @return true if this list contains the specified element + */ + public boolean contains(E e) { + Objects.requireNonNull(e); + Node<E> current = head; + int layer = height; + + while (layer >= 0) { + Node<E> next = current.next(layer); + if (e.equals(current.getValue())) { + return true; + } else if (next == null || next.getValue().compareTo(e) > 0) { + layer--; + } else { + current = next; + } + } + return false; + } + + public int size() { + return size; + } + + /** + * Print height distribution of the nodes in a manner: + * <pre> + * [ ] --- --- [ ] --- [ ] + * [ ] --- [ ] [ ] --- [ ] + * [ ] [ ] [ ] [ ] [ ] [ ] + * H 0 1 2 3 4 + * </pre> + * Values of nodes is not presented. + * + * @return string representation + */ + @Override + public String toString() { + List<boolean[]> layers = new ArrayList<>(); + int sizeWithHeader = size + 1; + for (int i = 0; i <= height; i++) { + layers.add(new boolean[sizeWithHeader]); + } + + Node<E> current = head; + int position = 0; + while (current != null) { + for (int i = 0; i <= current.height; i++) { + layers.get(i)[position] = true; + } + current = current.next(0); + position++; + } + + Collections.reverse(layers); + String result = layers.stream() + .map(layer -> { + StringBuilder acc = new StringBuilder(); + for (boolean b : layer) { + if (b) { + acc.append("[ ]"); + } else { + acc.append("---"); + } + acc.append(" "); + } + return acc.toString(); + }) + .collect(Collectors.joining("\n")); + String positions = IntStream.range(0, sizeWithHeader - 1).mapToObj(i -> String.format("%3d", i)).collect(Collectors.joining(" ")); + + return result + String.format("%n H %s%n", positions); + } + + /** + * Value container. + * Each node have pointers to the closest nodes left and right from current + * on each layer of nodes height. + * @param <E> type of elements + */ + private static class Node<E> { + + private final E value; + private final int height; + private final List<Node<E>> forward; + private final List<Node<E>> backward; + + @SuppressWarnings("unchecked") + Node(E value, int height) { + this.value = value; + this.height = height; + + // predefined size lists with null values in every cell + this.forward = Arrays.asList(new Node[height + 1]); + this.backward = Arrays.asList(new Node[height + 1]); + } + + public Node<E> next(int layer) { + checkLayer(layer); + return forward.get(layer); + } + + public void setNext(int layer, Node<E> node) { + forward.set(layer, node); + } + + public void setPrevious(int layer, Node<E> node) { + backward.set(layer, node); + } + + public Node<E> previous(int layer) { + checkLayer(layer); + return backward.get(layer); + } + + public E getValue() { + return value; + } + + private void checkLayer(int layer) { + if (layer < 0 || layer > height) { + throw new IllegalArgumentException(); + } + } + } + + /** + * Height strategy is a way of calculating maximum height for skip list + * and height for each node. + * @see BernoulliHeightStrategy + */ + public interface HeightStrategy { + int height(int expectedSize); + int nodeHeight(int heightCap); + } + + /** + * In most common skip list realisation element in layer {@code i} appears + * in layer {@code i+1} with some fixed probability {@code p}. + * Two commonly used values for {@code p} are 1/2 and 1/4. + * Probability of appearing element in layer {@code i} could be calculated + * with <code>P = p<sup>i</sup>(1 - p)</code> + * <p> + * Maximum height that would give the best search complexity + * calculated by <code>log<sub>1/p</sub>n</code> + * where {@code n} is an expected count of elements in list. + */ + public static class BernoulliHeightStrategy implements HeightStrategy { + + private final double probability; + + private static final double DEFAULT_PROBABILITY = 0.5; + private static final Random RANDOM = new Random(); + + public BernoulliHeightStrategy() { + this.probability = DEFAULT_PROBABILITY; + } + + public BernoulliHeightStrategy(double probability) { + if (probability <= 0 || probability >= 1) { + throw new IllegalArgumentException("Probability should be from 0 to 1. But was: " + probability); + } + this.probability = probability; + } + + @Override + public int height(int expectedSize) { + long height = Math.round(Math.log10(expectedSize) / Math.log10(1 / probability)); + if (height > Integer.MAX_VALUE) { + throw new IllegalArgumentException(); + } + return (int) height; + } + + @Override + public int nodeHeight(int heightCap) { + int level = 0; + double border = 100 * (1 - probability); + while (((RANDOM.nextInt(Integer.MAX_VALUE) % 100) + 1) > border) { + if (level + 1 >= heightCap) { + return level; + } + level++; + } + return level; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java b/Java/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java new file mode 100644 index 000000000000..cd3761bdcf75 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java @@ -0,0 +1,106 @@ +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 { + + int[] arr; + int topOfQueue; + int beginningOfQueue; + int size; + + public CircularQueue(int size) { + arr = new int[size]; + topOfQueue = -1; + beginningOfQueue = -1; + this.size = size; + } + + public boolean isEmpty() { + return beginningOfQueue == -1; + } + + public boolean isFull() { + if (topOfQueue + 1 == beginningOfQueue) { + return true; + } else + return topOfQueue == size - 1 && beginningOfQueue == 0; + } + + public void enQueue(int value) { + if (isFull()) { + System.out.println("The Queue is full!"); + } 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 { + topOfQueue++; + } + arr[topOfQueue] = value; + System.out.println(value + " has been successfully inserted!"); + } + } + + 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 = -1; + topOfQueue = -1; + } else if (beginningOfQueue + 1 == size) { + beginningOfQueue = 0; + } else { + beginningOfQueue++; + } + return res; + } + } + + public int peek() { + if (isEmpty()) { + System.out.println("The Queue is Empty!"); + return -1; + } else { + return arr[beginningOfQueue]; + } + } + + public void deleteQueue() { + arr = null; + System.out.println("The Queue is deleted!"); + } + + public static void main(String[] args) { + CircularQueue cq = new CircularQueue(5); + System.out.println(cq.isEmpty()); + System.out.println(cq.isFull()); + cq.enQueue(1); + cq.enQueue(2); + cq.enQueue(3); + cq.enQueue(4); + cq.enQueue(5); + + System.out.println(cq.deQueue()); + System.out.println(cq.deQueue()); + System.out.println(cq.deQueue()); + System.out.println(cq.deQueue()); + System.out.println(cq.deQueue()); + System.out.println(cq.isFull()); + System.out.println(cq.isEmpty()); + cq.enQueue(6); + cq.enQueue(7); + cq.enQueue(8); + System.out.println(cq.peek()); + System.out.println(cq.peek()); + cq.deleteQueue(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/queues/Deques.java b/Java/src/main/java/com/thealgorithms/datastructures/queues/Deques.java new file mode 100644 index 000000000000..5c4e9b641445 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/queues/Deques.java @@ -0,0 +1,272 @@ +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<T> { + + /** + * Node for the deque + */ + class DequeNode<S> { + + /** + * Value of the node + */ + S val; + + /** + * Next node in the deque from this node + */ + DequeNode<S> next = null; + + /** + * Previous node in the deque from this node + */ + DequeNode<S> prev = null; + + /** + * Constructor + */ + DequeNode(S val) { + this.val = val; + } + } + + /** + * Head of the deque + */ + DequeNode<T> head = null; + + /** + * Tail of the deque + */ + DequeNode<T> 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<T> newNode = new DequeNode<T>(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<T> newNode = new DequeNode<T>(val); + + // Add the node + if (tail == null) { + // If the deque is empty, add the node as the head and tail + head = 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<T> 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<T> 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: + * + * <p> + * Head -> 1 <-> 2 <-> 3 <- Tail + * + * @return the stringified deque + */ + @Override + public String toString() { + String dequeString = "Head -> "; + DequeNode<T> 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<Integer> myDeque = new Deques<Integer>(); + 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/Java/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java b/Java/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java new file mode 100644 index 000000000000..ec1e15e415b8 --- /dev/null +++ b/Java/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<T> { + + /** + * The generic ArrayList for the queue T is the generic element + */ + ArrayList<T> elementList = new ArrayList<>(); + + /** + * Checks if the queue has elements (not empty). + * + * @return True if the queue has elements. False otherwise. + */ + private boolean hasElements() { + return !elementList.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 = elementList.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 elementList.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 = elementList.remove(0); + } + return result; + } + + /** + * Main method + * + * @param args Command line arguments + */ + public static void main(String[] args) { + GenericArrayListQueue<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java b/Java/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java new file mode 100644 index 000000000000..171f24e09396 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java @@ -0,0 +1,209 @@ +package com.thealgorithms.datastructures.queues; + +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.StringJoiner; + +public class LinkedQueue<T> implements Iterable<T> { + + static class Node<T> { + + T data; + Node<T> next; + + Node() { + this(null); + } + + Node(T data) { + this(data, null); + } + + Node(T data, Node<T> next) { + this.data = data; + this.next = next; + } + } + + /** + * Front of Queue + */ + private Node<T> front; + + /** + * Rear of Queue + */ + private Node<T> rear; + + /** + * Size of Queue + */ + private int size; + + /** + * Init LinkedQueue + */ + public LinkedQueue() { + + front = new Node<>(); + rear = front; + } + + /** + * 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 + */ + public void enqueue(T data) { + Node<T> newNode = new Node<>(data); + + rear.next = newNode; + rear = newNode; + /* make rear point at last node */ + size++; + } + + /** + * Remove element at the front of queue + * + * @return element at the front of queue + */ + public T dequeue() { + if (isEmpty()) { + throw new NoSuchElementException("queue is empty"); + } + Node<T> destroy = front.next; + T retValue = destroy.data; + front.next = front.next.next; + /* 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 T 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 T peekRear() { + if (isEmpty()) { + throw new NoSuchElementException("queue is empty"); + } + return rear.data; + } + + /** + * Peeks the element at the index and + * returns the value + * @param pos at which to peek + */ + + public T peek(int pos) { + if (pos > size) throw new IndexOutOfBoundsException("Position %s out of range!".formatted(pos)); + Node<T> node = front; + while (pos-- > 0) node = node.next; + return node.data; + } + + /** + * Node iterator, allows to travel through + * the nodes using for() loop or forEach(Consumer) + */ + + @Override + public Iterator<T> iterator() { + return new Iterator<>() { + Node<T> node = front; + + @Override + public boolean hasNext() { + return node.next != null; + } + + @Override + public T next() { + if (hasNext()) { + node = node.next; + return node.data; + } + throw new NoSuchElementException(); + } + }; + } + + /** + * Return size of queue + * + * @return size of queue + */ + public int size() { + return size; + } + + /** + * Clear all nodes in queue + */ + public void clear() { + while (size > 0) dequeue(); + } + + @Override + public String toString() { + StringJoiner join = new StringJoiner(", "); // separator of ', ' + Node<T> travel = front; + while ((travel = travel.next) != null) join.add(String.valueOf(travel.data)); + return '[' + join.toString() + ']'; + } + + /* Driver Code */ + public static void main(String[] args) { + LinkedQueue<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java b/Java/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java new file mode 100644 index 000000000000..16a0c1673886 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java @@ -0,0 +1,175 @@ +package com.thealgorithms.datastructures.queues; + +/** + * This class implements a PriorityQueue. + * + * <p> + * 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. + * <p> + * Additional contibutions made by: PuneetTri(https://github.com/PuneetTri) + */ +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; + + /** + * Default Constructor + */ + + PriorityQueue() { + /* If capacity is not defined, default size of 11 would be used + * capacity=max+1 because we cant access 0th element of PQ, and to + * accomodate (max)th elements we need capacity to be max+1. + * Parent is at position k, child at position (k*2,k*2+1), if we + * use position 0 in our queue, its child would be at: + * (0*2, 0*2+1) -> (0,0). This is why we start at position 1 + */ + int size = 11; // Default value of 11 + maxSize = size + 1; + queueArray = new int[maxSize]; + nItems = 0; + } + + /** + * Parameterized Constructor + * + * @param size Size of the queue + */ + + PriorityQueue(int size) { + maxSize = size + 1; + queueArray = new int[maxSize]; + nItems = 0; + } + + /** + * Helper function for the max-heap implementation of PQ + * Function would help demote parent node to their correct + * position + * + * @param pos Position of newly added element at bottom + */ + private void swim(int pos) { + // Check if parent is smaller than child node + while (pos > 1 && (queueArray[pos / 2] < queueArray[pos])) { + // In such case swap value of child with parent + int temp = queueArray[pos]; + queueArray[pos] = queueArray[pos / 2]; + queueArray[pos / 2] = temp; + pos = pos / 2; // Jump to position of parent node + } + // Promotion of child node will go on until it becomes smaller than the parent + } + + /** + * Helper function for the max-heap implementation of PQ + * Function would help demote parent node to their correct + * position + * + * @param pos Position of element at top + */ + private void sink(int pos) { + // Check if node's position is that of parent node + while (2 * pos <= nItems) { + int current = 2 * pos; // Jump to the positon of child node + // Compare both the children for the greater one + if (current < nItems && queueArray[current] < queueArray[current + 1]) current++; + // If the parent node is greater, sink operation is complete. Break the loop + if (queueArray[pos] >= queueArray[current]) break; + + // If not exchange the value of parent with child + int temp = queueArray[pos]; + queueArray[pos] = queueArray[current]; + queueArray[current] = temp; + pos = current; // Exchange parent position to child position in the array + } + } + + /** + * Inserts an element in it's appropriate place + * + * @param value Value to be inserted + */ + public void insert(int value) { + // Print overflow message if the capacity is full + if (isFull()) { + throw new RuntimeException("Queue is full"); + } else { + queueArray[++nItems] = value; + swim(nItems); // Swim up the element to its correct position + } + } + + /** + * Dequeue the element with the max priority from PQ + * + * @return The element removed + */ + public int remove() { + if (isEmpty()) { + throw new RuntimeException("Queue is Empty"); + } else { + int max = queueArray[1]; // By defintion of our max-heap, value at queueArray[1] pos is + // the greatest + + // Swap max and last element + int temp = queueArray[1]; + queueArray[1] = queueArray[nItems]; + queueArray[nItems] = temp; + queueArray[nItems--] = 0; // Nullify the last element from the priority queue + sink(1); // Sink the element in order + + return max; + } + } + + /** + * Checks what's at the front of the queue + * + * @return element at the front of the queue + */ + public int peek() { + return queueArray[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 - 1); + } + + /** + * Returns the number of elements in the queue + * + * @return number of elements in the queue + */ + public int getSize() { + return nItems; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/queues/Queues.java b/Java/src/main/java/com/thealgorithms/datastructures/queues/Queues.java new file mode 100644 index 000000000000..2f364b7cbb6b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/queues/Queues.java @@ -0,0 +1,184 @@ +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 + */ + Queue() { + this(DEFAULT_CAPACITY); + } + + /** + * Constructor + * + * @param size Size of the new queue + */ + 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 final class Queues { + private 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); // Will print [2, 5, 3, 7] + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/queues/README.md b/Java/src/main/java/com/thealgorithms/datastructures/queues/README.md new file mode 100644 index 000000000000..ef1b89b5c9a4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/queues/README.md @@ -0,0 +1,89 @@ +# Queue +- The Queue interface is present in the `java.util` package. +- It is an ordered list of objects that follows the **FIFO** (First-In-First-Out) principle. + +## Characteristics of a Queue +- The Queue is used to insert elements at the end of the queue and removes elements from the beginning of the queue. +- It supports all methods of Collection interface including insertion, deletion etc. +- LinkedList, ArrayBlockingQueue and PriorityQueue are the most commonly used implementations. + + +## Types Of Queue:- + +- **FIFO Queue (First-In-First-Out):** This is the most common type of queue where the first item added is the first one to be removed. It follows a strict order of insertion and removal. + + +- **Priority Queue:** Elements in this queue are assigned priorities, and the item with the highest priority is dequeued first. It doesn't strictly follow the FIFO order. + + +- **Double-ended Queue (Deque):** A queue that allows elements to be added and removed from both ends. It can function as both a FIFO queue and a LIFO stack. + + +- **Circular Queue:** In this type, the last element is connected to the first element, forming a circular structure. It's often used for tasks like managing memory buffers. + + +- **Blocking Queue:** Designed for multithreaded applications, it provides thread-safety and blocking operations. Threads can wait until an element is available or space is free. + + +- **Priority Blocking Queue:** Similar to a priority queue but thread-safe, it allows multiple threads to access and modify the queue concurrently while maintaining priority. + + +- **Delay Queue:** Used for scheduling tasks to run after a specific delay or at a certain time. Elements are removed from the queue when their delay expires. + +## Declaration +`Queue<Obj> queue = new PriorityQueue<Obj>();` + +## Important operations + +| Operations | Description |Time Complexity +| ----------- | ----------- |----------- +|Enqueue|Adds an item to the queue|O(1) +|Dequeue|Removes an item from the queue|O(1) +|Front|Gets the front item from the queue|O(1) +|Rear|Gets the last item from the queue|O(n) + +## Enqueue + It adds an item to the rear of the queue. + + For example: If we have `1, 2, 3, 4, 5` in queue, and if we call Enqueue(8), + +`8` will be added to last index of queue -> `1, 2, 3, 4, 5, 8`. +## Dequeue + + It removes an item to the front of the queue. + + For example: If we have `1, 2, 3, 4, 5` in queue, and we call Dequeue(), + +`1` will be removed from front of queue and returned -> `2, 3, 4, 5`. + +## Front + It returns an item to the front of the queue. + +For example: If we have `1, 2, 3, 5` in queue, and we call Front(), + +`1` will be returned (without removing it from the queue). + +## Rear + It returns an item to the rear of the queue. + + For example: If we have `1, 2, 3, 5` in queue, and we call Rear(), + +`5` will be returned (without removing it from the queue). + +# Real Life Applications +`Task Scheduling in Operating Systems:` + +Processes in a multitasking system are often scheduled using queues. For example, the ready queue contains processes ready to be executed. + +`Multi-threaded Programming:` + +Queues are often used to facilitate communication and synchronization between different threads. + +`Breadth-First Search (BFS) in Graphs:` + +Queues are used in algorithms like BFS to explore a graph level by level. + + + + + diff --git a/Java/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java b/Java/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java new file mode 100644 index 000000000000..7c4f334cd617 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java @@ -0,0 +1,161 @@ +package com.thealgorithms.datastructures.stacks; + +/** + * Implementation of a stack using nodes. Unlimited size, no arraylist. + * + * @author Kyler Smith, 2017 + */ +public class NodeStack<Item> { + + /** + * Entry point for the program. + */ + public static void main(String[] args) { + NodeStack<Integer> stack = new NodeStack<Integer>(); + + 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<?> 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<Item> newNs = new NodeStack<Item>(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.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.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. + * + * <p> + * 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()); + } + } + + private static void setHead(NodeStack<?> ns) { + NodeStack.head = ns; + } + + private void setNext(NodeStack<?> 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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/stacks/README.md b/Java/src/main/java/com/thealgorithms/datastructures/stacks/README.md new file mode 100644 index 000000000000..55c3ffd7de64 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/stacks/README.md @@ -0,0 +1,45 @@ +# STACK + +- Stack is an ADT (abstract data type) that is a collection of elements where items are added and removed from the end, known as the "top" of the stack. + +- Stack works on the principle of _LIFO_ (Last In First Out), it means that the last item added to the stack will be the first item to be removed. + +## Declaration + `Stack<Obj> stack=new Stack<Obj>();` + +# Functionalities +Stack is based on two functions (methods)- + +## push(element) + +It adds "element" to the top of the stack. + +For example: If we have `1, 3, 5` in stack, and we call push(9), + +`9` will be added to last index of stack -> `1, 3, 5 , 9`. + +## peek() or top() + +It returns element at the top of the stack. + +For example: If we have `1, 3, 5` in stack, and we call peek(), + +`5` will be returned (without removing it from the stack). + +## pop() + +It removes the last element (i.e. top of stack) from stack. + +For example: If we have `1, 3, 5 , 9` in stack, and we call pop(), + +the function will return `9` and the stack will change to `1, 3, 5`. + +# Real Life Applications + - `Undo mechanisms:` + Many software applications use stacks to implement an "undo" feature. + + - `Browser history:` + The "back" button in a web browser is implemented using a stack, allowing users to navigate through previously visited pages. + + - `Function calls and recursion:` + The computer's call stack keeps track of function calls, allowing programs to remember where to return after a function finishes execution. diff --git a/Java/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java b/Java/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java new file mode 100644 index 000000000000..84e9df96e0d9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java @@ -0,0 +1,67 @@ +package com.thealgorithms.datastructures.stacks; + +import java.util.Scanner; +import java.util.Stack; + +/** + * Reversal of a stack using recursion. + * + * @author Ishika Agarwal, 2021 + */ +public final class ReverseStack { + private ReverseStack() { + } + + public static void main(String[] args) { + try (Scanner sc = new Scanner(System.in)) { + System.out.println("Enter the number of elements you wish to insert in the stack"); + int n = sc.nextInt(); + int i; + Stack<Integer> stack = new Stack<Integer>(); + System.out.println("Enter the stack elements"); + for (i = 0; i < n; i++) { + stack.push(sc.nextInt()); + } + reverseStack(stack); + System.out.println("The reversed stack is:"); + while (!stack.isEmpty()) { + System.out.print(stack.peek() + ","); + stack.pop(); + } + } + } + + private static void reverseStack(Stack<Integer> stack) { + if (stack.isEmpty()) { + return; + } + + // Store the topmost element + int element = stack.peek(); + // Remove the topmost element + stack.pop(); + + // Reverse the stack for the leftover elements + reverseStack(stack); + + // Insert the topmost element to the bottom of the stack + insertAtBottom(stack, element); + } + + private static void insertAtBottom(Stack<Integer> stack, int element) { + if (stack.isEmpty()) { + // When stack is empty, insert the element so it will be present at + // the bottom of the stack + stack.push(element); + return; + } + + int ele = stack.peek(); + // Keep popping elements till stack becomes empty. Push the elements + // once the topmost element has moved to the bottom of the stack. + stack.pop(); + insertAtBottom(stack, element); + + stack.push(ele); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java b/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackArray.java new file mode 100644 index 000000000000..cb2cb25e9e0c --- /dev/null +++ b/Java/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. + * + * <p> + * 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 + * + * <p> + * 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/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java b/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackArrayList.java new file mode 100644 index 000000000000..9506ae385733 --- /dev/null +++ b/Java/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. + * + * <p> + * 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. + * + * <p> + * 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<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java b/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java new file mode 100644 index 000000000000..52b1c1d86c94 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java @@ -0,0 +1,143 @@ +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 +final class StackOfLinkedList { + private 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; + + Node(int data) { + this.data = data; + this.next = null; + } +} + +/** + * A class which implements a stack using a linked list + * + * <p> + * Contains all the stack methods : push, pop, printStack, isEmpty + */ +class LinkedListStack { + + /** + * Top of stack + */ + Node head; + + /** + * Size of stack + */ + private int size; + + /** + * Init properties + */ + LinkedListStack() { + head = null; + size = 0; + } + + /** + * Add element at top + * + * @param x to be added + * @return <tt>true</tt> 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 <tt>true</tt> if stack is empty, otherwise <tt>false</tt> + */ + public boolean isEmpty() { + return size == 0; + } + + /** + * Return size of stack + * + * @return size of stack + */ + public int getSize() { + return size; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java new file mode 100644 index 000000000000..052da616fe8e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java @@ -0,0 +1,134 @@ +package com.thealgorithms.datastructures.trees; + +/* +* Avl is algo that balance itself while adding new alues to tree +* by rotating branches of binary tree and make itself Binary seaarch tree +* there are four cases which has to tackle +* rotating - left right ,left left,right right,right left + +Test Case: + +AVLTree tree=new AVLTree(); + tree.insert(20); + tree.insert(25); + tree.insert(30); + tree.insert(10); + tree.insert(5); + tree.insert(15); + tree.insert(27); + tree.insert(19); + tree.insert(16); + + tree.display(); + + + + +*/ + +public class AVLSimple { + + private class Node { + + int data; + int height; + Node left; + Node right; + + Node(int data) { + this.data = data; + this.height = 1; + } + } + + private Node root; + + public void insert(int data) { + this.root = insert(this.root, data); + } + + private Node insert(Node node, int item) { + if (node == null) { + return new Node(item); + } + if (node.data > item) { + node.left = insert(node.left, item); + } + if (node.data < item) { + node.right = insert(node.right, item); + } + node.height = Math.max(height(node.left), height(node.right)) + 1; + int bf = bf(node); + // LL case + if (bf > 1 && item < node.left.data) return rightRotate(node); + // RR case + if (bf < -1 && item > node.right.data) return leftRotate(node); + // RL case + if (bf < -1 && item < node.right.data) { + node.right = rightRotate(node.right); + return leftRotate(node); + } + // LR case + if (bf > 1 && item > node.left.data) { + node.left = leftRotate(node.left); + return rightRotate(node); + } + + return node; + } + + public void display() { + this.display(this.root); + System.out.println(this.root.height); + } + + private void display(Node node) { + String str = ""; + if (node.left != null) + str += node.left.data + "=>"; + else + str += "END=>"; + str += node.data + ""; + if (node.right != null) + str += "<=" + node.right.data; + else + str += "<=END"; + System.out.println(str); + if (node.left != null) display(node.left); + if (node.right != null) display(node.right); + } + + private int height(Node node) { + if (node == null) { + return 0; + } + return node.height; + } + + private int bf(Node node) { + if (node == null) return 0; + return height(node.left) - height(node.right); + } + + private Node rightRotate(Node c) { + Node b = c.left; + Node t3 = b.right; + + b.right = c; + c.left = t3; + c.height = Math.max(height(c.left), height(c.right)) + 1; + b.height = Math.max(height(b.left), height(b.right)) + 1; + return b; + } + + private Node leftRotate(Node c) { + Node b = c.right; + Node t3 = b.left; + + b.left = c; + c.right = t3; + c.height = Math.max(height(c.left), height(c.right)) + 1; + b.height = Math.max(height(b.left), height(b.right)) + 1; + return b; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java new file mode 100644 index 000000000000..7b959b085353 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java @@ -0,0 +1,249 @@ +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; + private Node right; + private Node 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; + } + Node child; + if (node.left != null) { + child = node.left; + while (child.right != null) { + child = child.right; + } + } else { + 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); + return result != null; + } + + 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/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java new file mode 100644 index 000000000000..1962eaa0a106 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java @@ -0,0 +1,35 @@ +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 final class BSTFromSortedArray { + private BSTFromSortedArray() { + } + public static Node createBST(int[] array) { + if (array == null || array.length == 0) { + return null; + } + return createBST(array, 0, array.length - 1); + } + + private static Node createBST(int[] array, int startIdx, int endIdx) { + // No element left. + if (startIdx > endIdx) { + return null; + } + int mid = startIdx + (endIdx - startIdx) / 2; + + // middle element will be the root + Node root = new Node(array[mid]); + root.left = createBST(array, startIdx, mid - 1); + root.right = createBST(array, mid + 1, endIdx); + return root; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java new file mode 100644 index 000000000000..97c2667002b6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTIterative.java @@ -0,0 +1,191 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; + +/** + * + * + * <h1>Binary Search Tree (Iterative)</h1> + * + * <p> + * 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 child must themselves be + * a BST. + * + * @author [Lakhan Nad](<a href="https://github.com/Lakhan-Nad">git-Lakhan Nad</a>) + */ + +public class BSTIterative { + + /** + * Reference for the node of BST. + */ + private Node root; + + /** + * Default Constructor Initializes the root of BST with null. + */ + BSTIterative() { + root = null; + } + + public Node getRoot() { + return root; + } + + /** + * 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 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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java new file mode 100644 index 000000000000..4e24f4bfb32a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursive.java @@ -0,0 +1,148 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; + +/** + * + * + * <h1>Binary Search Tree (Recursive)</h1> + * + * An implementation of BST recursively. In recursive implementation the checks + * are down the tree First root is checked if not found then its children 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 children must themselves be a BST. + * + * <p> + * I have made public functions as methods and to actually implement recursive + * approach I have used private methods + * + * @author [Lakhan Nad](<a href="https://github.com/Lakhan-Nad">git-Lakhan Nad</a>) + */ +public class BSTRecursive { + + /** + * only data member is root of BST + */ + private Node root; + + /** + * Constructor use to initialize node as null + */ + BSTRecursive() { + root = null; + } + + public Node getRoot() { + return root; + } + + /** + * 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 children 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; + } + + /** + * 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 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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java new file mode 100644 index 000000000000..5c1334ffa0e8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/BSTRecursiveGeneric.java @@ -0,0 +1,328 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.List; + +/** + * <h1>Binary Search Tree (Recursive) Generic Type Implementation</h1> + * + * <p> + * A recursive implementation of generic type BST. + * + * Reference: <a href="https://en.wikipedia.org/wiki/Binary_search_tree">Wiki links for BST</a> + * </p> + * + * @author [Madhur Panwar](<a href="https://github.com/mdrpanwar">git-Madhur Panwar</a>) + */ +public class BSTRecursiveGeneric<T extends Comparable<T>> { + + /** + * only data member is root of BST + */ + private Node<T> 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<Integer> integerTree = new BSTRecursiveGeneric<Integer>(); + + 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<String> stringTree = new BSTRecursiveGeneric<String>(); + + 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<T> delete(Node<T> 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<T> temp = node.right; + node.right = null; + node = temp; + } else if (node.right == null) { // Only left node is present + Node<T> temp = node.left; + node.left = null; + node = temp; + } else { // both child are present + Node<T> 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<T> insert(Node<T> 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<T> 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<T> 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<T> 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<T> node, List<T> 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); + } + } + + /** + * Search 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<T> 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<T> inorderSort() { + List<T> 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> { + + T data; + Node<T> left; + Node<T> right; + + /** + * Constructor with data as parameter + */ + Node(T d) { + data = d; + left = null; + right = null; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java new file mode 100644 index 000000000000..d4d677a4cda0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java @@ -0,0 +1,330 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.LinkedList; +import java.util.Queue; + +/* + * 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 + */ + 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; + } else { + parent.right = newNode; + parent.right.parent = parent; + } + } + } + + /** + * 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; + } else { + successor.parent.left = null; + } + successor.right = temp.right; + successor.right.parent = successor; + } + + if (temp == root) { + successor.parent = null; + root = successor; + } // 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; + } + } // 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<Node> 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/Java/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java new file mode 100644 index 000000000000..f238b5e9fe8d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java @@ -0,0 +1,72 @@ +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. + * <p> + * <p> + * 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. + * <p> + * <p> + * 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 final class CeilInBinarySearchTree { + private 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/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java new file mode 100644 index 000000000000..0c2b44d78d74 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java @@ -0,0 +1,30 @@ +package com.thealgorithms.datastructures.trees; + +/** + * This code recursively validates whether given Binary Search Tree (BST) is balanced or not. + * Trees with only distinct values are supported. + * Key points: + * 1. According to the definition of a BST, each node in a tree must be in range [min, max], + * where 'min' and 'max' values represent the child nodes (left, right). + * 2. The smallest possible node value is Integer.MIN_VALUE, the biggest - Integer.MAX_VALUE. + */ +public final class CheckBinaryTreeIsValidBST { + private CheckBinaryTreeIsValidBST() { + } + public static boolean isBST(BinaryTree.Node root) { + return isBSTUtil(root, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + private static boolean isBSTUtil(BinaryTree.Node node, int min, int max) { + // empty tree is a BST + if (node == null) { + return true; + } + + if (node.data < min || node.data > max) { + return false; + } + + return (isBSTUtil(node.left, min, node.data - 1) && isBSTUtil(node.right, node.data + 1, max)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java new file mode 100644 index 000000000000..9aa4d5a1fef2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java @@ -0,0 +1,157 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.HashMap; +import java.util.Stack; + +/** + * This class will check if a BinaryTree is balanced. A balanced binary tree is + * defined as a binary tree where the difference in height between the left and + * right subtree of each node differs by at most one. + * <p> + * 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](<a href="https://github.com/iccowan">Git-Ian Cowan</a>) + */ +public final class CheckIfBinaryTreeBalanced { + private CheckIfBinaryTreeBalanced() { + } + /** + * Recursive is BT balanced implementation + * + * @param root The binary tree to check if balanced + */ + public static boolean isBalancedRecursive(BinaryTree.Node root) { + if (root == null) { + return true; + } + // Create an array of length 1 to keep track of our balance + // Default to true. We use an array, so we have an efficient mutable object + boolean[] isBalanced = new boolean[1]; + isBalanced[0] = true; + + // Check for balance and return whether we are balanced + isBalancedRecursive(root, 0, isBalanced); + return isBalanced[0]; + } + + /** + * 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 + */ + private static int isBalancedRecursive(BinaryTree.Node 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]) { + return 0; + } + + // Visit the left and right children, incrementing their depths by 1 + int leftHeight = isBalancedRecursive(node.left, depth + 1, isBalanced); + int rightHeight = isBalancedRecursive(node.right, depth + 1, isBalanced); + + // 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) { + isBalanced[0] = false; + } + + // The height of our tree is the maximum of the heights of the left + // and right subtrees plus one + return Math.max(leftHeight, rightHeight) + 1; + } + + /** + * Iterative is BT balanced implementation + */ + public static boolean isBalancedIterative(BinaryTree.Node root) { + if (root == null) { + return true; + } + + // Default that we are balanced and our algo will prove it wrong + boolean isBalanced = true; + + // Create a stack for our post order traversal + Stack<BinaryTree.Node> nodeStack = new Stack<>(); + + // For post order traversal, we'll have to keep track of where we + // visited last + BinaryTree.Node lastVisited = null; + + // Create a HashMap to keep track of the subtree heights for each node + HashMap<BinaryTree.Node, Integer> subtreeHeights = new HashMap<>(); + + // We begin at the root of the tree + BinaryTree.Node node = root; + + // We loop while: + // - the node stack is empty and the node we explore is null + // AND + // - the tree is still balanced + 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 + } else { + // Find the last node we put on the stack + node = nodeStack.peek(); + + // If the right child of the node has either been visited or + // is null, we visit this node + if (node.right == null || node.right == lastVisited) { + // We assume the left and right heights are 0 + int leftHeight = 0; + int rightHeight = 0; + + // 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) { + leftHeight = subtreeHeights.get(node.left); + } + + 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) { + isBalanced = false; + } + + // The height of the subtree containing this node is the + // max of the left and right subtree heights plus 1 + subtreeHeights.put(node, Math.max(rightHeight, leftHeight) + 1); + + // We've now visited this node, so we pop it from the stack + nodeStack.pop(); + lastVisited = node; + + // 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 + } else { + node = node.right; + } + } + } + + // Return whether the tree is balanced + return isBalanced; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java new file mode 100644 index 000000000000..17d84bf11d54 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java @@ -0,0 +1,59 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; + +/** + * Check if a binary tree is symmetric or not. + * A binary tree is a symmetric tree if the left and right subtree of root are mirror image. + * Below is a symmetric tree + * 1 + * / \ + * 2 2 + * / \ / \ + * 3 4 4 3 + * + * Below is not symmetric because values is different in last level + * 1 + * / \ + * 2 2 + * / \ / \ + * 3 5 4 3 + * <p> + * Approach: + * Recursively check for left and right subtree of root + * 1. left subtrees root's values should be equal right subtree's root value + * 2. recursively check with left subtrees' left child VS right subtree's right child AND + * left subtree's right child VS right subtree left child + * Complexity + * 1. Time: O(n) + * 2. Space: O(lg(n)) for height of tree + * + * @author kumanoit on 10/10/22 IST 12:52 AM + */ +public final class CheckTreeIsSymmetric { + private CheckTreeIsSymmetric() { + } + + public static boolean isSymmetric(Node root) { + if (root == null) { + return true; + } + return isSymmetric(root.left, root.right); + } + + private static boolean isSymmetric(Node leftSubtreeRoot, Node rightSubtreeRoot) { + if (leftSubtreeRoot == null && rightSubtreeRoot == null) { + return true; + } + + if (isInvalidSubtree(leftSubtreeRoot, rightSubtreeRoot)) { + return false; + } + + return isSymmetric(leftSubtreeRoot.right, rightSubtreeRoot.left) && isSymmetric(leftSubtreeRoot.left, rightSubtreeRoot.right); + } + + private static boolean isInvalidSubtree(Node leftSubtreeRoot, Node rightSubtreeRoot) { + return leftSubtreeRoot == null || rightSubtreeRoot == null || leftSubtreeRoot.data != rightSubtreeRoot.data; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java new file mode 100644 index 000000000000..04caa0b9e9d2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java @@ -0,0 +1,71 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; +import java.util.HashMap; +import java.util.Map; + +/** + * 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)) + * <p> + * 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 final class CreateBinaryTreeFromInorderPreorder { + private CreateBinaryTreeFromInorderPreorder() { + } + public static Node createTree(final Integer[] preorder, final Integer[] inorder) { + if (preorder == null || inorder == null) { + return null; + } + return createTree(preorder, inorder, 0, 0, inorder.length); + } + + public static Node createTreeOptimized(final Integer[] preorder, final Integer[] inorder) { + if (preorder == null || inorder == null) { + return null; + } + Map<Integer, Integer> inorderMap = new HashMap<>(); + for (int i = 0; i < inorder.length; i++) { + inorderMap.put(inorder[i], i); + } + return createTreeOptimized(preorder, inorderMap, 0, 0, inorder.length); + } + + private static Node createTree(final Integer[] preorder, final Integer[] inorder, final int preStart, final int inStart, final int size) { + if (size == 0) { + return null; + } + + Node root = new Node(preorder[preStart]); + int i = inStart; + while (!preorder[preStart].equals(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 Map<Integer, Integer> inorderMap, final int preStart, final int inStart, final int size) { + 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, inorderMap, preStart + 1, inStart, leftNodesCount); + root.right = createTreeOptimized(preorder, inorderMap, preStart + leftNodesCount + 1, i + 1, rightNodesCount); + return root; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java new file mode 100644 index 000000000000..5378a01f6642 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java @@ -0,0 +1,35 @@ +package com.thealgorithms.datastructures.trees; + +public class FenwickTree { + + private int n; + private int[] fenTree; + + /* Constructor which takes the size of the array as a parameter */ + public FenwickTree(int n) { + this.n = n; + this.fenTree = 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 + i += 1; + while (i <= n) { + fenTree[i] += 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 + i += 1; + int cumSum = 0; + while (i > 0) { + cumSum += fenTree[i]; + i -= i & (-i); + } + return cumSum; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java new file mode 100644 index 000000000000..a2e36f33dd4b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java @@ -0,0 +1,238 @@ +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. + * + * <p> + * 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 static final class Node { + + int data; + ArrayList<Node> child = new ArrayList<>(); + } + + private final Node root; + public GenericTree() { // Constructor + Scanner scn = new Scanner(System.in); + root = createTreeG(null, 0, scn); + } + + private Node createTreeG(Node node, int childIndex, Scanner scanner) { + // display + if (node == null) { + System.out.println("Enter root's data"); + } else { + System.out.println("Enter data of parent of index " + node.data + " " + childIndex); + } + // input + node = new Node(); + node.data = scanner.nextInt(); + System.out.println("number of children"); + int number = scanner.nextInt(); + for (int i = 0; i < number; i++) { + Node child = createTreeG(node, i, scanner); + node.child.add(child); + } + return node; + } + + /** + * Function to display the generic tree + */ + public void display() { // Helper function + display1(root); + } + + private void display1(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++) { + display1(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); + } + } + + /** + * 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<Node> 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<Integer> 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/Java/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java new file mode 100644 index 000000000000..3bae17ed1bb8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java @@ -0,0 +1,62 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; + +/** + * Given tree is traversed in an 'inorder' way: LEFT -> ROOT -> RIGHT. + * Below are given the recursive and iterative implementations. + * + * Complexities: + * Recursive: O(n) - time, O(n) - space, where 'n' is the number of nodes in a tree. + * + * Iterative: O(n) - time, O(h) - space, where 'n' is the number of nodes in a tree + * and 'h' is the height of a binary tree. + * In the worst case 'h' can be O(n) if tree is completely unbalanced, for instance: + * 5 + * \ + * 6 + * \ + * 7 + * \ + * 8 + * + * @author Albina Gimaletdinova on 21/02/2023 + */ +public final class InorderTraversal { + private InorderTraversal() { + } + public static List<Integer> recursiveInorder(BinaryTree.Node root) { + List<Integer> result = new ArrayList<>(); + recursiveInorder(root, result); + return result; + } + + public static List<Integer> iterativeInorder(BinaryTree.Node root) { + List<Integer> result = new ArrayList<>(); + if (root == null) return result; + + Deque<BinaryTree.Node> stack = new ArrayDeque<>(); + while (!stack.isEmpty() || root != null) { + while (root != null) { + stack.push(root); + root = root.left; + } + root = stack.pop(); + result.add(root.data); + root = root.right; + } + return result; + } + + private static void recursiveInorder(BinaryTree.Node root, List<Integer> result) { + if (root == null) { + return; + } + recursiveInorder(root.left, result); + result.add(root.data); + recursiveInorder(root.right, result); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java new file mode 100644 index 000000000000..e5528c392bb8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java @@ -0,0 +1,407 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.Objects; +import java.util.Optional; + +/* + * K-D Tree Implementation + * Wikipedia: https://en.wikipedia.org/wiki/K-d_tree + * + * Author: Amir Hosseini (https://github.com/itsamirhn) + * + * */ + +public class KDTree { + + private Node root; + + private final int k; // Dimensions of the points + + /** + * Constructor for empty KDTree + * + * @param k Number of dimensions + */ + KDTree(int k) { + this.k = k; + } + + /** + * Builds the KDTree from the specified points + * + * @param points Array of initial points + */ + KDTree(Point[] points) { + if (points.length == 0) throw new IllegalArgumentException("Points array cannot be empty"); + this.k = points[0].getDimension(); + for (Point point : points) + if (point.getDimension() != k) throw new IllegalArgumentException("Points must have the same dimension"); + this.root = build(points, 0); + } + + /** + * Builds the KDTree from the specified coordinates of the points + * + * @param pointsCoordinates Array of initial points coordinates + * + */ + KDTree(int[][] pointsCoordinates) { + if (pointsCoordinates.length == 0) throw new IllegalArgumentException("Points array cannot be empty"); + this.k = pointsCoordinates[0].length; + Point[] points = Arrays.stream(pointsCoordinates).map(Point::new).toArray(Point[] ::new); + for (Point point : points) + if (point.getDimension() != k) throw new IllegalArgumentException("Points must have the same dimension"); + this.root = build(points, 0); + } + + static class Point { + + int[] coordinates; + + public int getCoordinate(int i) { + return coordinates[i]; + } + + public int getDimension() { + return coordinates.length; + } + + Point(int[] coordinates) { + this.coordinates = coordinates; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Point other) { + return Arrays.equals(other.coordinates, this.coordinates); + } + return false; + } + + @Override + public int hashCode() { + return Arrays.hashCode(coordinates); + } + + @Override + public String toString() { + return Arrays.toString(coordinates); + } + + /** + * Find the comparable distance between two points (without SQRT) + * + * @param p1 First point + * @param p2 Second point + * + * @return The comparable distance between the two points + */ + public static int comparableDistance(Point p1, Point p2) { + int distance = 0; + for (int i = 0; i < p1.getDimension(); i++) { + int t = p1.getCoordinate(i) - p2.getCoordinate(i); + distance += t * t; + } + return distance; + } + + /** + * Find the comparable distance between two points with ignoring specified axis + * + * @param p1 First point + * @param p2 Second point + * @param axis The axis to ignore + * + * @return The distance between the two points + */ + public static int comparableDistanceExceptAxis(Point p1, Point p2, int axis) { + int distance = 0; + for (int i = 0; i < p1.getDimension(); i++) { + if (i == axis) continue; + int t = p1.getCoordinate(i) - p2.getCoordinate(i); + distance += t * t; + } + return distance; + } + } + + static class Node { + + private Point point; + private int axis; // 0 for x, 1 for y, 2 for z, etc. + + private Node left = null; // Left child + private Node right = null; // Right child + + Node(Point point, int axis) { + this.point = point; + this.axis = axis; + } + + public Point getPoint() { + return point; + } + + public Node getLeft() { + return left; + } + + public Node getRight() { + return right; + } + + public int getAxis() { + return axis; + } + + /** + * Get the nearest child according to the specified point + * + * @param point The point to find the nearest child to + * + * @return The nearest child Node + */ + public Node getNearChild(Point point) { + if (point.getCoordinate(axis) < this.point.getCoordinate(axis)) + return left; + else + return right; + } + + /** + * Get the farthest child according to the specified point + * + * @param point The point to find the farthest child to + * + * @return The farthest child Node + */ + public Node getFarChild(Point point) { + if (point.getCoordinate(axis) < this.point.getCoordinate(axis)) + return right; + else + return left; + } + + /** + * Get the node axis coordinate of point + * + * @return The axis coordinate of the point + */ + public int getAxisCoordinate() { + return point.getCoordinate(axis); + } + } + + public Node getRoot() { + return root; + } + + /** + * Builds the KDTree from the specified points + * + * @param points Array of initial points + * @param depth The current depth of the tree + * + * @return The root of the KDTree + */ + private Node build(Point[] points, int depth) { + if (points.length == 0) return null; + int axis = depth % k; + if (points.length == 1) return new Node(points[0], axis); + Arrays.sort(points, Comparator.comparingInt(o -> o.getCoordinate(axis))); + int median = points.length >> 1; + Node node = new Node(points[median], axis); + node.left = build(Arrays.copyOfRange(points, 0, median), depth + 1); + node.right = build(Arrays.copyOfRange(points, median + 1, points.length), depth + 1); + return node; + } + + /** + * Insert a point into the KDTree + * + * @param point The point to insert + * + */ + public void insert(Point point) { + if (point.getDimension() != k) throw new IllegalArgumentException("Point has wrong dimension"); + root = insert(root, point, 0); + } + + /** + * Insert a point into a subtree + * + * @param root The root of the subtree + * @param point The point to insert + * @param depth The current depth of the tree + * + * @return The root of the KDTree + */ + private Node insert(Node root, Point point, int depth) { + int axis = depth % k; + if (root == null) return new Node(point, axis); + if (point.getCoordinate(axis) < root.getAxisCoordinate()) + root.left = insert(root.left, point, depth + 1); + else + root.right = insert(root.right, point, depth + 1); + + return root; + } + + /** + * Search for Node corresponding to the specified point in the KDTree + * + * @param point The point to search for + * + * @return The Node corresponding to the specified point + */ + public Optional<Node> search(Point point) { + if (point.getDimension() != k) throw new IllegalArgumentException("Point has wrong dimension"); + return search(root, point); + } + + /** + * Search for Node corresponding to the specified point in a subtree + * + * @param root The root of the subtree to search in + * @param point The point to search for + * + * @return The Node corresponding to the specified point + */ + public Optional<Node> search(Node root, Point point) { + if (root == null) return Optional.empty(); + if (root.point.equals(point)) return Optional.of(root); + return search(root.getNearChild(point), point); + } + + /** + * Find a point with minimum value in specified axis in the KDTree + * + * @param axis The axis to find the minimum value in + * + * @return The point with minimum value in the specified axis + */ + public Point findMin(int axis) { + return findMin(root, axis).point; + } + + /** + * Find a point with minimum value in specified axis in a subtree + * + * @param root The root of the subtree to search in + * @param axis The axis to find the minimum value in + * + * @return The Node with minimum value in the specified axis of the point + */ + public Node findMin(Node root, int axis) { + if (root == null) return null; + if (root.getAxis() == axis) { + if (root.left == null) return root; + return findMin(root.left, axis); + } else { + Node left = findMin(root.left, axis); + Node right = findMin(root.right, axis); + Node[] candidates = {left, root, right}; + return Arrays.stream(candidates).filter(Objects::nonNull).min(Comparator.comparingInt(a -> a.point.getCoordinate(axis))).orElse(null); + } + } + + /** + * Find a point with maximum value in specified axis in the KDTree + * + * @param axis The axis to find the maximum value in + * + * @return The point with maximum value in the specified axis + */ + public Point findMax(int axis) { + return findMax(root, axis).point; + } + + /** + * Find a point with maximum value in specified axis in a subtree + * + * @param root The root of the subtree to search in + * @param axis The axis to find the maximum value in + * + * @return The Node with maximum value in the specified axis of the point + */ + public Node findMax(Node root, int axis) { + if (root == null) return null; + if (root.getAxis() == axis) { + if (root.right == null) return root; + return findMax(root.right, axis); + } else { + Node left = findMax(root.left, axis); + Node right = findMax(root.right, axis); + Node[] candidates = {left, root, right}; + return Arrays.stream(candidates).filter(Objects::nonNull).max(Comparator.comparingInt(a -> a.point.getCoordinate(axis))).orElse(null); + } + } + + /** + * Delete the node with the given point. + * + * @param point the point to delete + * */ + public void delete(Point point) { + Node node = search(point).orElseThrow(() -> new IllegalArgumentException("Point not found")); + root = delete(root, node); + } + + /** + * Delete the specified node from a subtree. + * + * @param root The root of the subtree to delete from + * @param node The node to delete + * + * @return The new root of the subtree + */ + private Node delete(Node root, Node node) { + if (root == null) return null; + if (root.equals(node)) { + if (root.right != null) { + Node min = findMin(root.right, root.getAxis()); + root.point = min.point; + root.right = delete(root.right, min); + } else if (root.left != null) { + Node min = findMin(root.left, root.getAxis()); + root.point = min.point; + root.left = delete(root.left, min); + } else + return null; + } + if (root.getAxisCoordinate() < node.point.getCoordinate(root.getAxis())) + root.left = delete(root.left, node); + else + root.right = delete(root.right, node); + return root; + } + + /** + * Finds the nearest point in the tree to the given point. + * + * @param point The point to find the nearest neighbor to. + * */ + public Point findNearest(Point point) { + return findNearest(root, point, root).point; + } + + /** + * Finds the nearest point in a subtree to the given point. + * + * @param root The root of the subtree to search in. + * @param point The point to find the nearest neighbor to. + * @param nearest The nearest neighbor found so far. + * */ + private Node findNearest(Node root, Point point, Node nearest) { + if (root == null) return nearest; + if (root.point.equals(point)) return root; + int distance = Point.comparableDistance(root.point, point); + int distanceExceptAxis = Point.comparableDistanceExceptAxis(root.point, point, root.getAxis()); + if (distance < Point.comparableDistance(nearest.point, point)) nearest = root; + nearest = findNearest(root.getNearChild(point), point, nearest); + if (distanceExceptAxis < Point.comparableDistance(nearest.point, point)) nearest = findNearest(root.getFarChild(point), point, nearest); + return nearest; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/LCA.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/LCA.java new file mode 100644 index 000000000000..95a289493007 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/LCA.java @@ -0,0 +1,114 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.Scanner; + +public final class LCA { + private LCA() { + } + + private static final Scanner SCANNER = new Scanner(System.in); + + public static void main(String[] args) { + // The adjacency list representation of a tree: + ArrayList<ArrayList<Integer>> adj = new ArrayList<>(); + + // v is the number of vertices and e is the number of edges + int v = SCANNER.nextInt(); + int e = v - 1; + + for (int i = 0; i < v; i++) { + adj.add(new ArrayList<Integer>()); + } + + // Storing the given tree as an adjacency list + int to; + int from; + for (int i = 0; i < e; i++) { + to = SCANNER.nextInt(); + from = SCANNER.nextInt(); + + adj.get(to).add(from); + adj.get(from).add(to); + } + + // parent[v1] gives parent of a vertex v1 + int[] parent = new int[v]; + + // depth[v1] gives depth of vertex v1 with respect to the root + int[] depth = new int[v]; + + // Assuming the tree to be rooted at 0, hence calculating parent and depth of every vertex + dfs(adj, 0, -1, parent, depth); + + // Inputting the two vertices whose LCA is to be calculated + int v1 = SCANNER.nextInt(); + int v2 = SCANNER.nextInt(); + + // Outputting the LCA + System.out.println(getLCA(v1, v2, depth, parent)); + } + + /** + * Depth first search to calculate parent and depth of every vertex + * + * @param adj The adjacency list representation of the tree + * @param s The source vertex + * @param p Parent of source + * @param parent An array to store parents of all vertices + * @param depth An array to store depth of all vertices + */ + private static void dfs(ArrayList<ArrayList<Integer>> adj, int s, int p, int[] parent, int[] depth) { + for (int adjacent : adj.get(s)) { + if (adjacent != p) { + parent[adjacent] = s; + depth[adjacent] = 1 + depth[s]; + 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]) { + int temp = v1; + v1 = v2; + v2 = temp; + } + while (depth[v1] != depth[v2]) { + v1 = parent[v1]; + } + if (v1 == v2) { + return v1; + } + while (v1 != v2) { + v1 = parent[v1]; + v2 = parent[v2]; + } + return v1; + } +} +/* + * Input: + * 10 + * 0 1 + * 0 2 + * 1 5 + * 5 6 + * 2 4 + * 2 3 + * 3 7 + * 7 9 + * 7 8 + * 9 4 + * Output: + * 2 + */ diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java new file mode 100644 index 000000000000..1d8febff4b5f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java @@ -0,0 +1,154 @@ +package com.thealgorithms.datastructures.trees; + +public class LazySegmentTree { + + /** + * Lazy Segment Tree + * + * @see + * <a href="https://www.geeksforgeeks.org/lazy-propagation-in-segment-tree/"> + */ + static class Node { + + private final int start; + private final int end; // start and end of the segment represented by this node + private int value; // value is the sum of all elements in the range [start, end) + private int lazy; // lazied value that should be added to children nodes + Node left; + Node right; // left and right children + + Node(int start, int end, int value) { + this.start = start; + this.end = end; + this.value = value; + this.lazy = 0; + this.left = null; + this.right = null; + } + + /** + * Update the value of this node with the given value diff. + * + * @param diff The value to add to every index of this node range. + */ + public void applyUpdate(int diff) { + this.lazy += diff; + this.value += (this.end - this.start) * diff; + } + + /** + * Shift the lazy value of this node to its children. + */ + public void shift() { + if (lazy == 0) return; + if (this.left == null && this.right == null) return; + this.value += this.lazy; + if (this.left != null) this.left.applyUpdate(this.lazy); + if (this.right != null) this.right.applyUpdate(this.lazy); + this.lazy = 0; + } + + /** + * Create a new node that is the sum of this node and the given node. + * + * @param left The left Node of merging + * @param right The right Node of merging + * @return The new Node. + */ + static Node merge(Node left, Node right) { + if (left == null) return right; + if (right == null) return left; + Node result = new Node(left.start, right.end, left.value + right.value); + result.left = left; + result.right = right; + return result; + } + + public int getValue() { + return value; + } + + public Node getLeft() { + return left; + } + + public Node getRight() { + return right; + } + } + + private final Node root; + + /** + * Create a new LazySegmentTree with the given array. + * + * @param array The array to create the LazySegmentTree from. + */ + public LazySegmentTree(int[] array) { + this.root = buildTree(array, 0, array.length); + } + + /** + * Build a new LazySegmentTree from the given array in O(n) time. + * + * @param array The array to build the LazySegmentTree from. + * @param start The start index of the current node. + * @param end The end index of the current node. + * @return The root of the new LazySegmentTree. + */ + private Node buildTree(int[] array, int start, int end) { + if (end - start < 2) return new Node(start, end, array[start]); + int mid = (start + end) >> 1; + Node left = buildTree(array, start, mid); + Node right = buildTree(array, mid, end); + return Node.merge(left, right); + } + + /** + * Update the value of given range with the given value diff in O(log n) time. + * + * @param left The left index of the range to update. + * @param right The right index of the range to update. + * @param diff The value to add to every index of the range. + * @param curr The current node. + */ + private void updateRange(int left, int right, int diff, Node curr) { + if (left <= curr.start && curr.end <= right) { + curr.applyUpdate(diff); + return; + } + if (left >= curr.end || right <= curr.start) return; + curr.shift(); + updateRange(left, right, diff, curr.left); + updateRange(left, right, diff, curr.right); + Node merge = Node.merge(curr.left, curr.right); + curr.value = merge.value; + } + + /** + * Get Node of given range in O(log n) time. + * + * @param left The left index of the range to update. + * @param right The right index of the range to update. + * @return The Node representing the sum of the given range. + */ + private Node getRange(int left, int right, Node curr) { + if (left <= curr.start && curr.end <= right) return curr; + if (left >= curr.end || right <= curr.start) return null; + curr.shift(); + return Node.merge(getRange(left, right, curr.left), getRange(left, right, curr.right)); + } + + public int getRange(int left, int right) { + Node result = getRange(left, right, root); + return result == null ? 0 : result.getValue(); + } + + public void updateRange(int left, int right, int diff) { + updateRange(left, right, diff, root); + } + + public Node getRoot() { + return root; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java new file mode 100644 index 000000000000..f91aa303f66c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java @@ -0,0 +1,54 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public final class LevelOrderTraversal { + private LevelOrderTraversal() { + } + + public static List<List<Integer>> traverse(BinaryTree.Node root) { + if (root == null) { + return List.of(); + } + + List<List<Integer>> result = new ArrayList<>(); + + Queue<BinaryTree.Node> q = new LinkedList<>(); + q.add(root); + while (!q.isEmpty()) { + int nodesOnLevel = q.size(); + List<Integer> level = new LinkedList<>(); + for (int i = 0; i < nodesOnLevel; i++) { + BinaryTree.Node tempNode = q.poll(); + level.add(tempNode.data); + + if (tempNode.left != null) { + q.add(tempNode.left); + } + + if (tempNode.right != null) { + q.add(tempNode.right); + } + } + result.add(level); + } + return result; + } + + /* Print nodes at the given level */ + public static void printGivenLevel(BinaryTree.Node root, int level) { + if (root == null) { + System.out.println("Root node must not be null! Exiting."); + 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/Java/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java new file mode 100644 index 000000000000..50dc88381a24 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java @@ -0,0 +1,68 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +/** + * Given tree is traversed in a 'post-order' way: LEFT -> RIGHT -> ROOT. + * Below are given the recursive and iterative implementations. + * <p> + * Complexities: + * Recursive: O(n) - time, O(n) - space, where 'n' is the number of nodes in a tree. + * <p> + * Iterative: O(n) - time, O(h) - space, where 'n' is the number of nodes in a tree + * and 'h' is the height of a binary tree. + * In the worst case 'h' can be O(n) if tree is completely unbalanced, for instance: + * 5 + * \ + * 6 + * \ + * 7 + * \ + * 8 + * + * @author Albina Gimaletdinova on 21/02/2023 + */ +public final class PostOrderTraversal { + private PostOrderTraversal() { + } + public static List<Integer> recursivePostOrder(BinaryTree.Node root) { + List<Integer> result = new ArrayList<>(); + recursivePostOrder(root, result); + return result; + } + + public static List<Integer> iterativePostOrder(BinaryTree.Node root) { + LinkedList<Integer> result = new LinkedList<>(); + if (root == null) { + return result; + } + + Deque<BinaryTree.Node> stack = new ArrayDeque<>(); + stack.push(root); + while (!stack.isEmpty()) { + BinaryTree.Node node = stack.pop(); + result.addFirst(node.data); + if (node.left != null) { + stack.push(node.left); + } + if (node.right != null) { + stack.push(node.right); + } + } + + return result; + } + + private static void recursivePostOrder(BinaryTree.Node root, List<Integer> result) { + if (root == null) { + return; + } + recursivePostOrder(root.left, result); + recursivePostOrder(root.right, result); + result.add(root.data); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java new file mode 100644 index 000000000000..6a0eef369407 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java @@ -0,0 +1,61 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +/** + * Given tree is traversed in a 'pre-order' way: ROOT -> LEFT -> RIGHT. + * Below are given the recursive and iterative implementations. + * + * Complexities: + * Recursive: O(n) - time, O(n) - space, where 'n' is the number of nodes in a tree. + * + * Iterative: O(n) - time, O(h) - space, where 'n' is the number of nodes in a tree + * and 'h' is the height of a binary tree. + * In the worst case 'h' can be O(n) if tree is completely unbalanced, for instance: + * 5 + * \ + * 6 + * \ + * 7 + * \ + * 8 + * + * @author Albina Gimaletdinova on 17/02/2023 + */ +public final class PreOrderTraversal { + private PreOrderTraversal() { + } + public static List<Integer> recursivePreOrder(BinaryTree.Node root) { + List<Integer> result = new ArrayList<>(); + recursivePreOrder(root, result); + return result; + } + + public static List<Integer> iterativePreOrder(BinaryTree.Node root) { + List<Integer> result = new ArrayList<>(); + if (root == null) return result; + + Deque<BinaryTree.Node> stack = new LinkedList<>(); + stack.push(root); + while (!stack.isEmpty()) { + BinaryTree.Node node = stack.pop(); + result.add(node.data); + if (node.right != null) stack.push(node.right); + if (node.left != null) stack.push(node.left); + } + + return result; + } + + private static void recursivePreOrder(BinaryTree.Node root, List<Integer> result) { + if (root == null) { + return; + } + result.add(root.data); + recursivePreOrder(root.left, result); + recursivePreOrder(root.right, result); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java new file mode 100644 index 000000000000..3ef664f3fa7d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java @@ -0,0 +1,117 @@ +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; + TreeNode right; + + // Constructor + TreeNode(int key) { + this.key = key; + left = null; + 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; + + QItem(TreeNode n, int h) { + node = n; + hd = h; + } +} + +// Class for a Binary Tree +class Tree { + + TreeNode root; + + // Constructors + Tree() { + root = null; + } + + 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<Integer> set = new HashSet<>(); + + // Create a queue and add root to it + Queue<QItem> queue = new LinkedList<QItem>(); + queue.add(new QItem(root, 0)); // Horizontal distance of root is 0 + + // Standard BFS or level order traversal loop + while (!queue.isEmpty()) { + // Remove the front item and get its details + QItem qi = queue.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) { + queue.add(new QItem(n.left, hd - 1)); + } + if (n.right != null) { + queue.add(new QItem(n.right, hd + 1)); + } + } + } +} + +// Driver class to test above methods +public final class PrintTopViewofTree { + private 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/Java/src/main/java/com/thealgorithms/datastructures/trees/README.md b/Java/src/main/java/com/thealgorithms/datastructures/trees/README.md new file mode 100644 index 000000000000..89eeb35c5917 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/README.md @@ -0,0 +1,30 @@ +## Tree +### Description + +Tree is a data structure where the data is organized in a hierarchial structure. There should be one root node (which does not have any parent) and all subsequent nodes are represented as children of the root node and its children. If a node has at least one child, it is called `internal` node and nodes with no children are called `leaf` nodes. + +### Basic Structure + +``` +class Tree<E>{ + E value; + Tree left; + Tree right; +} +``` + +This basic structure is for a binary tree where each internal tree has at least one and at most two children. `left` and `right` represent the two children and `value` is the placeholder for data. + + +### Properties +1. Tree data structure gives the facility to organize data in a hierarchial structure +2. Tree nodes can be inserted in a sorted order which can be used for searching and inserting data in O(logN) time where N is the number of nodes. + +### Types of Trees +1. **Binary Search Tree:** A binary tree where the elements are inserted in asorted order. Here the searching can be done in O(logN) time in (depending on the structure) +2. **AVL Tree and Red-Black Tree:** Binary search trees where the height is balanced. Here, searching is guaranteed to be in O(logN) time. +3. **Traversal algorithms:** <br> +a. **BFS:** Breadth-first-search where all the children at each level are traversed at once. <br> +b. **DFS:** Depth-first-search where the first discovered child is traversed first. +4. **MultiWay Search Tree:** Tree in sorted order, but more than two children in each internal node. +5. **Trie:** A character based multiway search tree where words can be retrieved based on their prefix. Useful for implementing prefix based search algorithm. \ No newline at end of file diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java new file mode 100644 index 000000000000..01222b739ff0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java @@ -0,0 +1,339 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Scanner; + +/** + * @author jack870131 + */ +public class RedBlackBST { + + private static final int RED = 0; + private static final int BLACK = 1; + + private class Node { + + int key = -1; + int color = BLACK; + Node left = nil; + Node right = nil; + Node 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 == RED) ? " 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 == RED) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); + printTreepre(node.left); + printTreepre(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 = BLACK; + node.p = nil; + } else { + node.color = RED; + 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 == RED) { + Node y = nil; + if (node.p == node.p.p.left) { + y = node.p.p.right; + + if (y != nil && y.color == RED) { + node.p.color = BLACK; + y.color = BLACK; + node.p.p.color = RED; + node = node.p.p; + continue; + } + if (node == node.p.right) { + node = node.p; + rotateLeft(node); + } + node.p.color = BLACK; + node.p.p.color = RED; + rotateRight(node.p.p); + } else { + y = node.p.p.left; + if (y != nil && y.color == RED) { + node.p.color = BLACK; + y.color = BLACK; + node.p.p.color = RED; + node = node.p.p; + continue; + } + if (node == node.p.left) { + node = node.p; + rotateRight(node); + } + node.p.color = BLACK; + node.p.p.color = RED; + rotateLeft(node.p.p); + } + } + root.color = BLACK; + } + + 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) { + Node result = findNode(z, root); + if (result == 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 == BLACK) { + deleteFixup(x); + } + return true; + } + + void deleteFixup(Node x) { + while (x != root && x.color == BLACK) { + if (x == x.p.left) { + Node w = x.p.right; + if (w.color == RED) { + w.color = BLACK; + x.p.color = RED; + rotateLeft(x.p); + w = x.p.right; + } + if (w.left.color == BLACK && w.right.color == BLACK) { + w.color = RED; + x = x.p; + continue; + } else if (w.right.color == BLACK) { + w.left.color = BLACK; + w.color = RED; + rotateRight(w); + w = x.p.right; + } + if (w.right.color == RED) { + w.color = x.p.color; + x.p.color = BLACK; + w.right.color = BLACK; + rotateLeft(x.p); + x = root; + } + } else { + Node w = x.p.left; + if (w.color == RED) { + w.color = BLACK; + x.p.color = RED; + rotateRight(x.p); + w = x.p.left; + } + if (w.right.color == BLACK && w.left.color == BLACK) { + w.color = RED; + x = x.p; + continue; + } else if (w.left.color == BLACK) { + w.right.color = BLACK; + w.color = RED; + rotateLeft(w); + w = x.p.left; + } + if (w.left.color == RED) { + w.color = x.p.color; + x.p.color = BLACK; + w.left.color = BLACK; + rotateRight(x.p); + x = root; + } + } + } + x.color = BLACK; + } + + public void insertDemo() { + Scanner scan = new Scanner(System.in); + 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); + 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/Java/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java new file mode 100644 index 000000000000..883eadd1840a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java @@ -0,0 +1,83 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayDeque; +import java.util.Deque; + +/** + * Given 2 binary trees. + * This code checks whether they are the same (structurally identical and have the same values) or + * not. <p> Example: + * 1. Binary trees: + * 1 1 + * / \ / \ + * 2 3 2 3 + * /\ /\ /\ /\ + * 4 5 6 7 4 5 6 7 + * These trees are the same, so the code returns 'true'. + * <p> + * 2. Binary trees: + * 1 1 + * / \ + * 2 2 + * These trees are NOT the same (the structure differs), so the code returns 'false'. + * <p> + * This solution implements the breadth-first search (BFS) algorithm. + * For each tree we create a queue and iterate the trees using these queues. + * On each step we check the nodes for equality, and if the nodes are not the same, return false. + * Otherwise, add children nodes to the queues and continue traversing the trees. + * <p> + * Complexities: + * O(N) - time, where N is the number of nodes in a binary tree, + * O(N) - space, where N is the number of nodes in a binary tree. + * + * @author Albina Gimaletdinova on 13/01/2023 + */ +public final class SameTreesCheck { + private SameTreesCheck() { + } + public static boolean check(BinaryTree.Node p, BinaryTree.Node q) { + if (p == null && q == null) { + return true; + } + if (p == null || q == null) { + return false; + } + + Deque<BinaryTree.Node> q1 = new ArrayDeque<>(); + Deque<BinaryTree.Node> q2 = new ArrayDeque<>(); + q1.add(p); + q2.add(q); + while (!q1.isEmpty() && !q2.isEmpty()) { + BinaryTree.Node first = q1.poll(); + BinaryTree.Node second = q2.poll(); + // check that some node can be null + // if the check is true: both nodes are null or both nodes are not null + if (!equalNodes(first, second)) return false; + + if (first != null) { + if (!equalNodes(first.left, second.left)) return false; + if (first.left != null) { + q1.add(first.left); + q2.add(second.left); + } + + if (!equalNodes(first.right, second.right)) return false; + if (first.right != null) { + q1.add(first.right); + q2.add(second.right); + } + } + } + return true; + } + + private static boolean equalNodes(BinaryTree.Node p, BinaryTree.Node q) { + if (p == null && q == null) { + return true; + } + if (p == null || q == null) { + return false; + } + return p.data == q.data; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java new file mode 100644 index 000000000000..57b3edc163ca --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java @@ -0,0 +1,81 @@ +package com.thealgorithms.datastructures.trees; + +public class SegmentTree { + + private int[] segTree; + 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; + int x = (int) (Math.ceil(Math.log(n) / Math.log(2))); + int segSize = 2 * (int) Math.pow(2, x) - 1; + + this.segTree = new int[segSize]; + this.arr = arr; + this.n = n; + constructTree(arr, 0, n - 1, 0); + } + + /* A function which will create the segment tree*/ + public final int constructTree(int[] arr, int start, int end, int index) { + if (start == end) { + this.segTree[index] = arr[start]; + return arr[start]; + } + + int mid = start + (end - start) / 2; + this.segTree[index] = constructTree(arr, start, mid, index * 2 + 1) + constructTree(arr, mid + 1, end, index * 2 + 2); + return this.segTree[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 segIndex) { + if (index < start || index > end) { + return; + } + + this.segTree[segIndex] += diff; + if (start != end) { + int mid = start + (end - start) / 2; + updateTree(start, mid, index, diff, segIndex * 2 + 1); + updateTree(mid + 1, end, index, diff, segIndex * 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 qStart, int qEnd, int segIndex) { + if (qStart <= start && qEnd >= end) { + return this.segTree[segIndex]; + } + + if (qStart > end || qEnd < start) { + return 0; + } + + int mid = start + (end - start) / 2; + return (getSumTree(start, mid, qStart, qEnd, segIndex * 2 + 1) + getSumTree(mid + 1, end, qStart, qEnd, segIndex * 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); + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java new file mode 100644 index 000000000000..cf56731fb079 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java @@ -0,0 +1,87 @@ +package com.thealgorithms.datastructures.trees; + +/* Author : Suraj Kumar + Github : https://github.com/skmodi649 + */ + +/* PROBLEM DESCRIPTION : + There is a Binary Search Tree given, and we are supposed to find a random node in the given binary + tree. + */ + +/* ALGORITHM : + Step 1: START + Step 2: First create a binary tree using the steps mentioned in the first approach + Step 3: Now use a method inOrder() that takes a node as input parameter to traverse through the + binary tree in inorder fashion as also store the values in a ArrayList simultaneously. + Step 4: Now define a method getRandom() that takes a node as input parameter, in this first call + the inOrder() method to store the values in the arraylist, then find the size of the + binary tree and now just generate a random number between 0 to n-1. Step 5: After generating the + number display the value of the ArrayList at the generated index Step 6: STOP + */ + +import java.util.ArrayList; + +// Using auxiliary array to find the random node in a given binary tree + +public class TreeRandomNode { + + private final class Node { + + int item; + Node left; + Node right; + } + + // Using an arraylist to store the inorder traversal of the given binary tree + static ArrayList<Integer> list = new ArrayList<>(); + // root of Tree + Node root; + + TreeRandomNode() { + root = null; + } + + // Now lets find the inorder traversal of the given binary tree + static void inOrder(Node node) { + if (node == null) { + return; + } + + // traverse the left child + inOrder(node.left); + + list.add(node.item); + // traverse the right child + inOrder(node.right); + } + + public void getRandom(Node val) { + inOrder(val); + // getting the count of node of the binary tree + int n = list.size(); + int min = 0; + int max = n - 1; + // Generate random int value from 0 to n-1 + int b = (int) (Math.random() * (max - min + 1) + min); + // displaying the value at the generated index + int random = list.get(b); + System.out.println("Random Node : " + random); + } +} +/* Explanation of the Approach : + (a) Form the required binary tree + (b) Now use the inOrder() method to get the nodes in inOrder fashion and also store them in the + given arraylist 'list' (c) Using the getRandom() method generate a random number between 0 to n-1, + then get the value at the generated random number from the arraylist using get() method and + finally display the result. + */ +/* OUTPUT : + First output : + Random Node : 15 + Second output : + Random Node : 99 + */ +/* Time Complexity : O(n) + Auxiliary Space Complexity : O(1) + */ diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java new file mode 100644 index 000000000000..79c66cb90f01 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/TrieImp.java @@ -0,0 +1,143 @@ +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) { + 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/Java/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java new file mode 100644 index 000000000000..c1d15390d4b9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java @@ -0,0 +1,96 @@ +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 final class VerticalOrderTraversal { + private VerticalOrderTraversal() { + } + + /*Function that receives a root Node and prints the tree + in Vertical Order.*/ + public static ArrayList<Integer> verticalTraversal(BinaryTree.Node root) { + if (root == null) { + return new ArrayList<>(); + } + + /*Queue to store the Nodes.*/ + Queue<BinaryTree.Node> 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<Integer> 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<Integer, ArrayList<Integer>> map = new HashMap<>(); + + /* min and max stores leftmost and right most index to + later print the tree in vertical fashion.*/ + int max = 0; + int 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<Integer> 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 = Math.max(max, index.peek()); + min = 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<Integer> ans = new ArrayList<>(); + for (int i = min; i <= max; i++) { + ans.addAll(map.get(i)); + } + return ans; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java new file mode 100644 index 000000000000..84fe0eb2c42a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java @@ -0,0 +1,77 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; + +/** + * Given a binary tree. + * This code returns the zigzag level order traversal of its nodes' values. + * Binary tree: + * 7 + * / \ + * 6 3 + * / \ / \ + * 2 4 10 19 + * Zigzag traversal: + * [[7], [3, 6], [2, 4, 10, 19]] + * <p> + * This solution implements the breadth-first search (BFS) algorithm using a queue. + * 1. The algorithm starts with a root node. This node is added to a queue. + * 2. While the queue is not empty: + * - each time we enter the while-loop we get queue size. Queue size refers to the number of nodes + * at the current level. + * - we traverse all the level nodes in 2 ways: from left to right OR from right to left + * (this state is stored on `prevLevelFromLeftToRight` variable) + * - if the current node has children we add them to a queue + * - add level with nodes to a result. + * <p> + * Complexities: + * O(N) - time, where N is the number of nodes in a binary tree + * O(N) - space, where N is the number of nodes in a binary tree + * + * @author Albina Gimaletdinova on 11/01/2023 + */ +public final class ZigzagTraversal { + private ZigzagTraversal() { + } + public static List<List<Integer>> traverse(BinaryTree.Node root) { + if (root == null) { + return List.of(); + } + + List<List<Integer>> result = new ArrayList<>(); + + // create a queue + Deque<BinaryTree.Node> q = new ArrayDeque<>(); + q.offer(root); + // start with writing nodes from left to right + boolean prevLevelFromLeftToRight = false; + + while (!q.isEmpty()) { + int nodesOnLevel = q.size(); + List<Integer> level = new LinkedList<>(); + // traverse all the level nodes + for (int i = 0; i < nodesOnLevel; i++) { + BinaryTree.Node node = q.poll(); + if (prevLevelFromLeftToRight) { + level.add(0, node.data); + } else { + level.add(node.data); + } + if (node.left != null) { + q.offer(node.left); + } + if (node.right != null) { + q.offer(node.right); + } + } + // the next level node traversal will be from the other side + prevLevelFromLeftToRight = !prevLevelFromLeftToRight; + result.add(level); + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java b/Java/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java new file mode 100644 index 000000000000..6c53666e5856 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java @@ -0,0 +1,83 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Scanner; +import java.util.concurrent.ThreadLocalRandom; + +final class NearestRightKey { + private NearestRightKey() { + } + + public static void main(String[] args) { + NRKTree root = buildTree(); + Scanner sc = new Scanner(System.in); + System.out.print("Enter first number: "); + int inputX0 = sc.nextInt(); + int toPrint = nearestRightKey(root, inputX0); + System.out.println("Key: " + toPrint); + sc.close(); + } + + public static NRKTree buildTree() { + int randomX = ThreadLocalRandom.current().nextInt(0, 100 + 1); + NRKTree root = new NRKTree(null, null, randomX); + + for (int i = 0; i < 1000; i++) { + randomX = ThreadLocalRandom.current().nextInt(0, 100 + 1); + root = root.insertKey(root, randomX); + } + + return root; + } + + public static int nearestRightKey(NRKTree root, int x0) { + // Check whether tree is empty + if (root == null) { + return 0; + } else { + if (root.data - x0 > 0) { + // Go left + int temp = nearestRightKey(root.left, x0); + if (temp == 0) { + return root.data; + } + return temp; + } else { + // Go right + return nearestRightKey(root.right, x0); + } + } + } +} + +class NRKTree { + + public NRKTree left; + public NRKTree right; + public int data; + + NRKTree(int x) { + this.left = null; + this.right = null; + this.data = x; + } + + NRKTree(NRKTree right, NRKTree left, int x) { + this.left = left; + this.right = right; + this.data = x; + } + + public NRKTree insertKey(NRKTree current, int value) { + if (current == null) { + return new NRKTree(value); + } + + if (value < current.data) { + current.left = insertKey(current.left, value); + } else if (value > current.data) { + current.right = insertKey(current.right, value); + } + + return current; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java b/Java/src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java new file mode 100644 index 000000000000..388fb3fd9056 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/entities/ProcessDetails.java @@ -0,0 +1,55 @@ +package com.thealgorithms.devutils.entities; + +public class ProcessDetails { + private String processId; + private int arrivalTime; + private int burstTime; + private int waitingTime; + private int turnAroundTime; + + public ProcessDetails(final String processId, final int arrivalTime, final int burstTime) { + this.processId = processId; + this.arrivalTime = arrivalTime; + this.burstTime = burstTime; + } + + public String getProcessId() { + return processId; + } + + public int getArrivalTime() { + return arrivalTime; + } + + public int getBurstTime() { + return burstTime; + } + + public int getWaitingTime() { + return waitingTime; + } + + public int getTurnAroundTimeTime() { + return turnAroundTime; + } + + public void setProcessId(final String processId) { + this.processId = processId; + } + + public void setArrivalTime(final int arrivalTime) { + this.arrivalTime = arrivalTime; + } + + public void setBurstTime(final int burstTime) { + this.burstTime = burstTime; + } + + public void setWaitingTime(final int waitingTime) { + this.waitingTime = waitingTime; + } + + public void setTurnAroundTimeTime(final int turnAroundTime) { + this.turnAroundTime = turnAroundTime; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java b/Java/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java new file mode 100644 index 000000000000..1575e3649bc3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/nodes/LargeTreeNode.java @@ -0,0 +1,77 @@ +package com.thealgorithms.devutils.nodes; + +import java.util.Collection; + +/** + * {@link TreeNode} extension that holds a {@link Collection} of refrences to + * child Nodes. + * + * @param <E> The type of the data held in the Node. + * + * @author <a href="https://github.com/aitorfi">aitorfi</a> + */ +public class LargeTreeNode<E> extends TreeNode<E> { + + /** + * {@link Collection} that holds the Nodes' child nodes. + */ + private Collection<LargeTreeNode<E>> childNodes; + + /** + * Empty contructor. + */ + public LargeTreeNode() { + super(); + } + + /** + * Initializes the Nodes' data. + * + * @param data Value to which data will be initialized. + * @see TreeNode#TreeNode(Object) + */ + public LargeTreeNode(E data) { + super(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) + */ + public LargeTreeNode(E data, LargeTreeNode<E> parentNode) { + super(data, 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. + * @see TreeNode#TreeNode(Object, Node) + */ + public LargeTreeNode(E data, LargeTreeNode<E> parentNode, Collection<LargeTreeNode<E>> childNodes) { + super(data, parentNode); + this.childNodes = childNodes; + } + + /** + * @return True if the node is a leaf node, otherwise false. + * @see TreeNode#isLeafNode() + */ + @Override + public boolean isLeafNode() { + return (childNodes == null || childNodes.size() == 0); + } + + public Collection<LargeTreeNode<E>> getChildNodes() { + return childNodes; + } + + public void setChildNodes(Collection<LargeTreeNode<E>> childNodes) { + this.childNodes = childNodes; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/nodes/Node.java b/Java/src/main/java/com/thealgorithms/devutils/nodes/Node.java new file mode 100644 index 000000000000..a10817830962 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/nodes/Node.java @@ -0,0 +1,42 @@ +package com.thealgorithms.devutils.nodes; + +/** + * Base class for any node implementation which contains a generic type + * variable. + * + * All known subclasses: {@link TreeNode}, {@link SimpleNode}. + * + * @param <E> The type of the data held in the Node. + * + * @author <a href="https://github.com/aitorfi">aitorfi</a> + */ +public abstract class Node<E> { + + /** + * Generic type data stored in the Node. + */ + private E data; + + /** + * Empty constructor. + */ + public Node() { + } + + /** + * Initializes the Nodes' data. + * + * @param data Value to which data will be initialized. + */ + public Node(E data) { + this.data = data; + } + + public E getData() { + return data; + } + + public void setData(E data) { + this.data = data; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java b/Java/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java new file mode 100644 index 000000000000..769ffc2a9a96 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/nodes/SimpleNode.java @@ -0,0 +1,59 @@ +package com.thealgorithms.devutils.nodes; + +/** + * Simple Node implementation that holds a reference to the next Node. + * + * @param <E> The type of the data held in the Node. + * + * @author <a href="https://github.com/aitorfi">aitorfi</a> + */ +public class SimpleNode<E> extends Node<E> { + + /** + * Reference to the next Node. + */ + private SimpleNode<E> nextNode; + + /** + * Empty contructor. + */ + public SimpleNode() { + super(); + } + + /** + * Initializes the Nodes' data. + * + * @param data Value to which data will be initialized. + * @see Node#Node(Object) + */ + public SimpleNode(E data) { + super(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. + */ + public SimpleNode(E data, SimpleNode<E> nextNode) { + super(data); + this.nextNode = nextNode; + } + + /** + * @return True if there is a next node, otherwise false. + */ + public boolean hasNext() { + return (nextNode != null); + } + + public SimpleNode<E> getNextNode() { + return nextNode; + } + + public void setNextNode(SimpleNode<E> nextNode) { + this.nextNode = nextNode; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java b/Java/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java new file mode 100644 index 000000000000..215f01a6ef59 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/nodes/SimpleTreeNode.java @@ -0,0 +1,90 @@ +package com.thealgorithms.devutils.nodes; + +/** + * Simple TreeNode extension that holds references to two child Nodes (left and + * right). + * + * @param <E> The type of the data held in the Node. + * + * @author <a href="https://github.com/aitorfi">aitorfi</a> + */ +public class SimpleTreeNode<E> extends TreeNode<E> { + + /** + * Refrence to the child Node on the left. + */ + private SimpleTreeNode<E> leftNode; + /** + * Refrence to the child Node on the right. + */ + private SimpleTreeNode<E> rightNode; + + /** + * Empty contructor. + */ + public SimpleTreeNode() { + super(); + } + + /** + * Initializes the Nodes' data. + * + * @param data Value to which data will be initialized. + * @see TreeNode#TreeNode(Object) + */ + public SimpleTreeNode(E data) { + super(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) + */ + public SimpleTreeNode(E data, SimpleTreeNode<E> parentNode) { + super(data, 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. + */ + public SimpleTreeNode(E data, SimpleTreeNode<E> parentNode, SimpleTreeNode<E> leftNode, SimpleTreeNode<E> rightNode) { + super(data, parentNode); + this.leftNode = leftNode; + this.rightNode = rightNode; + } + + /** + * @return True if the node is a leaf node, otherwise false. + * @see TreeNode#isLeafNode() + */ + @Override + public boolean isLeafNode() { + return (leftNode == null && rightNode == null); + } + + public SimpleTreeNode<E> getLeftNode() { + return leftNode; + } + + public void setLeftNode(SimpleTreeNode<E> leftNode) { + this.leftNode = leftNode; + } + + public SimpleTreeNode<E> getRightNode() { + return rightNode; + } + + public void setRightNode(SimpleTreeNode<E> rightNode) { + this.rightNode = rightNode; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java b/Java/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java new file mode 100644 index 000000000000..13c9212306c1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/nodes/TreeNode.java @@ -0,0 +1,78 @@ +package com.thealgorithms.devutils.nodes; + +/** + * Base class for any tree node which holds a reference to the parent node. + * + * All known subclasses: {@link SimpleTreeNode}, {@link LargeTreeNode}. + * + * @param <E> The type of the data held in the Node. + * + * @author <a href="https://github.com/aitorfi">aitorfi</a> + */ +public abstract class TreeNode<E> extends Node<E> { + + /** + * Refernce to the parent Node. + */ + private TreeNode<E> parentNode; + /** + * Indicates the depth at which this node is in the tree. + */ + private int depth; + + /** + * Empty contructor. + */ + public TreeNode() { + super(); + depth = 0; + } + + /** + * Initializes the Nodes' data. + * + * @param data Value to which data will be initialized. + * @see Node#Node(Object) + */ + public TreeNode(E data) { + super(data); + depth = 0; + } + + /** + * 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. + */ + public TreeNode(E data, TreeNode<E> parentNode) { + super(data); + this.parentNode = parentNode; + depth = this.parentNode.getDepth() + 1; + } + + /** + * @return True if the node is a leaf node, otherwise false. + */ + public abstract boolean isLeafNode(); + + /** + * @return True if the node is the root node, otherwise false. + */ + public boolean isRootNode() { + return (parentNode == null); + } + + public TreeNode<E> getParent() { + return parentNode; + } + + public void setParent(TreeNode<E> parentNode) { + this.parentNode = parentNode; + depth = this.parentNode.getDepth() + 1; + } + + public int getDepth() { + return depth; + } +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java b/Java/src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java new file mode 100644 index 000000000000..36587a21c863 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/searches/MatrixSearchAlgorithm.java @@ -0,0 +1,16 @@ +package com.thealgorithms.devutils.searches; + +/** + * The common interface of most searching algorithms that search in matrixes. + * + * @author Aitor Fidalgo (https://github.com/aitorfi) + */ +public interface MatrixSearchAlgorithm { + /** + * @param key is an element which should be found + * @param matrix is a matrix where the element should be found + * @param <T> Comparable type + * @return array containing the first found coordinates of the element + */ + <T extends Comparable<T>> int[] find(T[][] matrix, T key); +} diff --git a/Java/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java b/Java/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java new file mode 100644 index 000000000000..eb5b42756958 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/devutils/searches/SearchAlgorithm.java @@ -0,0 +1,16 @@ +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 <T> Comparable type + * @return first found index of the element + */ + <T extends Comparable<T>> int find(T[] array, T key); +} diff --git a/Java/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java b/Java/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java new file mode 100644 index 000000000000..de829585891a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java @@ -0,0 +1,42 @@ +package com.thealgorithms.divideandconquer; + +// Java Program to Implement Binary Exponentiation (power in log n) + +// Reference Link: https://en.wikipedia.org/wiki/Exponentiation_by_squaring + +/* + * Binary Exponentiation is a method to calculate a to the power of b. + * It is used to calculate a^n in O(log n) time. + * + * Reference: + * https://iq.opengenus.org/binary-exponentiation/ + */ + +public class BinaryExponentiation { + + // recursive function to calculate a to the power of b + public static long calculatePower(long x, long y) { + // Base Case + if (y == 0) { + return 1; + } + if (y % 2 == 1) { // odd power + return x * calculatePower(x, y - 1); + } + return calculatePower(x * x, y / 2); // even power + } + + // iterative function to calculate a to the power of b + long power(long n, long m) { + long power = n; + long sum = 1; + while (m > 0) { + if ((m & 1) == 1) { + sum *= power; + } + power = power * power; + m = m >> 1; + } + return sum; + } +} diff --git a/Java/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java b/Java/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java new file mode 100644 index 000000000000..aa453539ac94 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/divideandconquer/ClosestPair.java @@ -0,0 +1,342 @@ +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 <br> + * @param ypar (IN Parameter) y coordinate <br> + */ + 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 <br> + * @param first (IN Parameter) first point <br> + * @param last (IN Parameter) last point <br> + * @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 <br> + * @param first (IN Parameter) first point <br> + * @param last (IN Parameter) last point <br> + * @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 <br> + * @param first (IN Parameter) first point <br> + * @param last (IN Parameter) last point <br> + */ + 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 <br> + * @param first (IN Parameter) first point <br> + * @param last (IN Parameter) last point <br> + */ + 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 <br> + * @param indexNum (IN Parameter) number coordinates divideArray <br> + * @return minimum distance <br> + */ + 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 <br> + * @return <br> + */ + 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) <br> + */ + 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/Java/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java b/Java/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java new file mode 100644 index 000000000000..610b1b78a36a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/divideandconquer/SkylineAlgorithm.java @@ -0,0 +1,184 @@ +package com.thealgorithms.divideandconquer; + +import java.util.ArrayList; +import java.util.Comparator; + +/** + * @author dimgrichr + * <p> + * Space complexity: O(n) Time complexity: O(nlogn), because it is a divide and + * conquer algorithm + */ +public class SkylineAlgorithm { + + private ArrayList<Point> 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<Point> 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<Point> produceSubSkyLines(ArrayList<Point> 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<Point> leftHalf = new ArrayList<>(); + ArrayList<Point> 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<Point> leftSubSkyLine = produceSubSkyLines(leftHalf); + ArrayList<Point> 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<Point> produceFinalSkyLine(ArrayList<Point> left, ArrayList<Point> 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<Point> { + + @Override + public int compare(Point a, Point b) { + return Integer.compare(a.x, b.x); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java b/Java/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java new file mode 100644 index 000000000000..86a6f3e11483 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java @@ -0,0 +1,142 @@ +package com.thealgorithms.divideandconquer; + +// Java Program to Implement Strassen Algorithm for Matrix Multiplication + +/* + * Uses the divide and conquer approach to multiply two matrices. + * Time Complexity: O(n^2.8074) better than the O(n^3) of the standard matrix multiplication + * algorithm. Space Complexity: O(n^2) + * + * This Matrix multiplication can be performed only on square matrices + * where n is a power of 2. Order of both of the matrices are n × n. + * + * Reference: + * https://www.tutorialspoint.com/design_and_analysis_of_algorithms/design_and_analysis_of_algorithms_strassens_matrix_multiplication.htm#:~:text=Strassen's%20Matrix%20multiplication%20can%20be,matrices%20are%20n%20%C3%97%20n. + * https://www.geeksforgeeks.org/strassens-matrix-multiplication/ + */ + +public class StrassenMatrixMultiplication { + + // Function to multiply matrices + public int[][] multiply(int[][] a, int[][] b) { + int n = a.length; + + int[][] mat = new int[n][n]; + + if (n == 1) { + mat[0][0] = a[0][0] * b[0][0]; + } else { + // Dividing Matrix into parts + // by storing sub-parts to variables + int[][] a11 = new int[n / 2][n / 2]; + int[][] a12 = new int[n / 2][n / 2]; + int[][] a21 = new int[n / 2][n / 2]; + int[][] a22 = new int[n / 2][n / 2]; + int[][] b11 = new int[n / 2][n / 2]; + 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)); + + // 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)); + + // m7:=A4×(B3−B1) + int[][] m7 = 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); + + // mat:=m5+m7 + int[][] c21 = add(m2, m4); + + // S:=m1−m3−m4−m5 + int[][] c22 = add(sub(add(m1, m3), m2), m6); + + join(c11, mat, 0, 0); + join(c12, mat, 0, n / 2); + join(c21, mat, n / 2, 0); + join(c22, mat, n / 2, n / 2); + } + + return mat; + } + + // Function to subtract two matrices + 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++) { + c[i][j] = a[i][j] - b[i][j]; + } + } + + return c; + } + + // Function to add two matrices + 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++) { + c[i][j] = a[i][j] + b[i][j]; + } + } + + return c; + } + + // 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++) { + c[i1][j1] = p[i2][j2]; + } + } + } + + // 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++) { + p[i2][j2] = c[i1][j1]; + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java new file mode 100644 index 000000000000..b041cfc478d6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java @@ -0,0 +1,85 @@ +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 final class BoardPath { + private 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java new file mode 100644 index 000000000000..3fa8728930cb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java @@ -0,0 +1,99 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Java program for Boundary fill algorithm. + * @author Akshay Dubey (https://github.com/itsAkshayDubey) + */ +public final class BoundaryFill { + private BoundaryFill() { + } + + /** + * Get the color at the given co-odrinates of a 2D image + * + * @param image The image to be filled + * @param xCoordinate The x co-ordinate of which color is to be obtained + * @param yCoordinate The y co-ordinate of which color is to be obtained + */ + public static int getPixel(int[][] image, int xCoordinate, int yCoordinate) { + return image[xCoordinate][yCoordinate]; + } + + /** + * Put the color at the given co-odrinates of a 2D image + * + * @param image The image to be filed + * @param xCoordinate The x co-ordinate at which color is to be filled + * @param yCoordinate The y co-ordinate at which color is to be filled + */ + public static void putPixel(int[][] image, int xCoordinate, int yCoordinate, int newColor) { + image[xCoordinate][yCoordinate] = newColor; + } + + /** + * Fill the 2D image with new color + * + * @param image The image to be filed + * @param xCoordinate The x co-ordinate at which color is to be filled + * @param yCoordinate The y co-ordinate at which color is to be filled + * @param newColor The new color which to be filled in the image + * @param boundaryColor The old color which is to be replaced in the image + */ + public static void boundaryFill(int[][] image, int xCoordinate, int yCoordinate, int newColor, int boundaryColor) { + if (xCoordinate >= 0 && yCoordinate >= 0 && getPixel(image, xCoordinate, yCoordinate) != newColor && getPixel(image, xCoordinate, yCoordinate) != boundaryColor) { + putPixel(image, xCoordinate, yCoordinate, newColor); + boundaryFill(image, xCoordinate + 1, yCoordinate, newColor, boundaryColor); + boundaryFill(image, xCoordinate - 1, yCoordinate, newColor, boundaryColor); + boundaryFill(image, xCoordinate, yCoordinate + 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate, yCoordinate - 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate + 1, yCoordinate - 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate - 1, yCoordinate + 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate + 1, yCoordinate + 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate - 1, yCoordinate - 1, newColor, boundaryColor); + } + } + + /** + * This method will print the 2D image matrix + * + * @param image The image to be printed on the console + */ + public static void printImageArray(int[][] image) { + for (int i = 0; i < image.length; i++) { + for (int j = 0; j < image[0].length; j++) { + System.out.print(image[i][j] + " "); + } + + System.out.println(); + } + } + + // Driver Program + public static void main(String[] args) { + // Input 2D image matrix + int[][] image = { + {0, 0, 0, 0, 0, 0, 0}, + {0, 3, 3, 3, 3, 0, 0}, + {0, 3, 0, 0, 3, 0, 0}, + {0, 3, 0, 0, 3, 3, 3}, + {0, 3, 3, 3, 0, 0, 3}, + {0, 0, 0, 3, 0, 0, 3}, + {0, 0, 0, 3, 3, 3, 3}, + }; + + boundaryFill(image, 2, 2, 5, 3); + + /* Output ==> + * 0 0 0 0 0 0 0 + 0 3 3 3 3 0 0 + 0 3 5 5 3 0 0 + 0 3 5 5 3 3 3 + 0 3 3 3 5 5 3 + 0 0 0 3 5 5 3 + 0 0 0 3 3 3 3 + * */ + + // print 2D image matrix + printImageArray(image); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java new file mode 100644 index 000000000000..b433c44b9077 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java @@ -0,0 +1,39 @@ +package com.thealgorithms.dynamicprogramming; + +/* A Naive recursive implementation +of 0-1 Knapsack problem */ +public final class BruteForceKnapsack { + private BruteForceKnapsack() { + } + // 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 Math.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/Java/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java new file mode 100644 index 000000000000..8658bca3df52 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java @@ -0,0 +1,58 @@ +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) + */ +import java.util.Scanner; + +public final class CatalanNumber { + private 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) { + // Array to store the results of subproblems i.e Catalan numbers from [1...n-1] + long[] catalanArray = new long[n + 1]; + + // Initialising C₀ = 1 and C₁ = 1 + catalanArray[0] = 1; + 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++) { + catalanArray[i] = 0; + for (int j = 0; j < i; j++) { + catalanArray[i] += catalanArray[j] * catalanArray[i - j - 1]; + } + } + + return catalanArray[n]; + } + + // Main method + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + + 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java new file mode 100644 index 000000000000..d79ed3c23e13 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java @@ -0,0 +1,31 @@ +package com.thealgorithms.dynamicprogramming; + +/* A DynamicProgramming solution for Climbing Stairs' problem Returns the + distinct ways can you climb to the staircase by either climbing 1 or 2 steps. + + Link : https://medium.com/analytics-vidhya/leetcode-q70-climbing-stairs-easy-444a4aae54e8 +*/ +public final class ClimbingStairs { + private ClimbingStairs() { + } + + public static int numberOfWays(int n) { + + if (n == 1 || n == 0) { + return n; + } + int prev = 1; + int curr = 1; + + int next; + + for (int i = 2; i <= n; i++) { + next = curr + prev; + prev = curr; + + curr = next; + } + + return curr; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java new file mode 100644 index 000000000000..12cc29faa923 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java @@ -0,0 +1,80 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +public final class CoinChange { + private 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 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 subRes = minimumCoins[i - coin]; + if (subRes != Integer.MAX_VALUE && subRes + 1 < minimumCoins[i]) { + minimumCoins[i] = subRes + 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java new file mode 100644 index 000000000000..8c70c9c3fada --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java @@ -0,0 +1,40 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ +/** + * In mathematics, the Golomb sequence is a non-decreasing integer sequence where n-th term is equal + * to number of times n appears in the sequence. + */ + +/** + * Wikipedia Link - https://en.wikipedia.org/wiki/Golomb_sequence + */ + +/** Program description - To find the Golomb sequence upto n */ + +package com.thealgorithms.dynamicprogramming; + +public final class CountFriendsPairing { + private CountFriendsPairing() { + } + + public static boolean countFriendsPairing(int n, int[] a) { + int[] dp = new int[n + 1]; + // array of n+1 size is created + dp[0] = 1; + // since 1st index position value is fixed so it's marked as 1 + for (int i = 1; i < n; i++) { + dp[i] = 1 + dp[i - dp[dp[i - 1]]]; + // formula for ith golomb sequence is dp(i) = 1 + dp(i – dp(dp(i - 1))) + } + for (int i = 1; i < n; i++) { + if (a[i - 1] != dp[i]) { + return false; + // checks whether the calculated answer matches with the expected answer + } + } + return true; + // returns true if calculated answer matches with the expected answer + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java new file mode 100644 index 000000000000..e1be3ead5895 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java @@ -0,0 +1,63 @@ +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 +final class DP { + private 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. + 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 + 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]; + } + } + } + + 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)); + } +} +/* +OUTPUT: +0 +2 +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/Java/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java new file mode 100644 index 000000000000..6db30514db68 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java @@ -0,0 +1,116 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * A DynamicProgramming based solution for Edit Distance problem In Java + * Description of Edit Distance with an Example: + * + * <p> + * 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. + * + * <p> + * + * <p> + * The Distance between "kitten" and "sitting" is 3. A minimal edit script that + * transforms the former into the latter is: + * + * <p> + * 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 final class EditDistance { + private 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 = Math.min(replace, insert); + min = Math.min(delete, min); + 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; + String 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); + } 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java new file mode 100644 index 000000000000..be52ab166f18 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java @@ -0,0 +1,51 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * DynamicProgramming solution for the Egg Dropping Puzzle + */ +public final class EggDropping { + private EggDropping() { + } + + // min trials with n eggs and m floors + public static int minTrials(int n, int m) { + int[][] eggFloor = new int[n + 1][m + 1]; + int result; + int 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; + int 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java new file mode 100644 index 000000000000..5855030fc65c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java @@ -0,0 +1,115 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +public final class Fibonacci { + private Fibonacci() { + } + + private static final Map<Integer, Integer> CACHE = 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)); + System.out.println(fibBinet(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 (CACHE.containsKey(n)) { + return CACHE.get(n); + } + + int f; + + if (n <= 1) { + f = n; + } else { + f = fibMemo(n - 1) + fibMemo(n - 2); + CACHE.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<Integer, Integer> 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 + * <p> + * 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) + * <p> + * 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; + int res = 1; + int next; + for (int i = 2; i <= n; i++) { + next = prev + res; + prev = res; + res = next; + } + return res; + } + + /** + * We have only defined the nth Fibonacci number in terms of the two before it. Now, we will + * look at Binet's formula to calculate the nth Fibonacci number in constant time. The Fibonacci + * terms maintain a ratio called golden ratio denoted by Φ, the Greek character pronounced + * ‘phi'. First, let's look at how the golden ratio is calculated: Φ = ( 1 + √5 )/2 + * = 1.6180339887... Now, let's look at Binet's formula: Sn = Φⁿ–(– Φ⁻ⁿ)/√5 We first calculate + * the squareRootof5 and phi and store them in variables. Later, we apply Binet's formula to get + * the required term. Time Complexity will be O(1) + */ + + public static int fibBinet(int n) { + double squareRootOf5 = Math.sqrt(5); + double phi = (1 + squareRootOf5) / 2; + return (int) ((Math.pow(phi, n) - Math.pow(-phi, -n)) / squareRootOf5); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java new file mode 100644 index 000000000000..6168ec6ec09f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java @@ -0,0 +1,79 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.LinkedList; +import java.util.Queue; +import java.util.Vector; + +public final class FordFulkerson { + private FordFulkerson() { + } + + static final int INF = 987654321; + // edges + static int vertexCount; + static int[][] capacity; + static int[][] flow; + + public static void main(String[] args) { + System.out.println("Vertex Count : 6"); + vertexCount = 6; + capacity = new int[vertexCount][vertexCount]; + + 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[vertexCount][vertexCount]; + int totalFlow = 0; + while (true) { + Vector<Integer> parent = new Vector<>(vertexCount); + for (int i = 0; i < vertexCount; i++) { + parent.add(-1); + } + Queue<Integer> 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 < vertexCount; ++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/Java/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java new file mode 100644 index 000000000000..de75126044ae --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java @@ -0,0 +1,36 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ + +/** Program description - To find the maximum subarray sum */ +package com.thealgorithms.dynamicprogramming; + +public final class KadaneAlgorithm { + private KadaneAlgorithm() { + } + + public static boolean maxSum(int[] a, int predictedAnswer) { + int sum = a[0]; + int runningSum = 0; + for (int k : a) { + runningSum = runningSum + k; + // running sum of all the indexs are stored + sum = Math.max(sum, runningSum); + // the max is stored inorder to the get the maximum sum + if (runningSum < 0) runningSum = 0; + // if running sum is negative then it is initialized to zero + } + // for-each loop is used to iterate over the array and find the maximum subarray sum + return sum == predictedAnswer; + // It returns true if sum and predicted answer matches + // The predicted answer is the answer itself. So it always return true + } + /** + * OUTPUT : + * Input - {89,56,98,123,26,75,12,40,39,68,91} + * Output: it returns either true or false + * 1st approach Time Complexity : O(n) + * Auxiliary Space Complexity : O(1) + */ +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java new file mode 100644 index 000000000000..134561766830 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/Knapsack.java @@ -0,0 +1,55 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + +/** + * A Dynamic Programming based solution for the 0-1 Knapsack problem. + * This class provides a method, `knapSack`, that calculates the maximum value that can be + * obtained from a given set of items with weights and values, while not exceeding a + * given weight capacity. + * + * @see <a href="https://en.wikipedia.org/?title=0-1_Knapsack_problem">0-1 Knapsack Problem </a> + */ +public final class Knapsack { + + private Knapsack() { + } + + private static void throwIfInvalidInput(final int weightCapacity, final int[] weights, final int[] values) { + if (weightCapacity < 0) { + throw new IllegalArgumentException("Weight capacity should not be negative."); + } + if (weights == null || values == null || weights.length != values.length) { + throw new IllegalArgumentException("Input arrays must not be null and must have the same length."); + } + if (Arrays.stream(weights).anyMatch(w -> w <= 0)) { + throw new IllegalArgumentException("Input array should not contain non-positive weight(s)."); + } + } + + /** + * Solves the 0-1 Knapsack problem using Dynamic Programming. + * + * @param weightCapacity The maximum weight capacity of the knapsack. + * @param weights An array of item weights. + * @param values An array of item values. + * @return The maximum value that can be obtained without exceeding the weight capacity. + * @throws IllegalArgumentException If the input arrays are null or have different lengths. + */ + public static int knapSack(final int weightCapacity, final int[] weights, final int[] values) throws IllegalArgumentException { + throwIfInvalidInput(weightCapacity, weights, values); + + // DP table to store the state of the maximum possible return for a given weight capacity. + int[] dp = new int[weightCapacity + 1]; + + for (int i = 0; i < values.length; i++) { + for (int w = weightCapacity; w > 0; w--) { + if (weights[i] <= w) { + dp[w] = Math.max(dp[w], dp[w - weights[i]] + values[i]); + } + } + } + + return dp[weightCapacity]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java new file mode 100644 index 000000000000..396efb1a7893 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java @@ -0,0 +1,54 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Recursive Solution for 0-1 knapsack with memoization + * This method is basically an extension to the recursive approach so that we + * can overcome the problem of calculating redundant cases and thus increased + * complexity. We can solve this problem by simply creating a 2-D array that can + * store a particular state (n, w) if we get it the first time. + */ +public class KnapsackMemoization { + + int knapSack(int capacity, int[] weights, int[] profits, int numOfItems) { + + // Declare the table dynamically + int[][] dpTable = new int[numOfItems + 1][capacity + 1]; + + // Loop to initially fill the table with -1 + for (int i = 0; i < numOfItems + 1; i++) { + for (int j = 0; j < capacity + 1; j++) { + dpTable[i][j] = -1; + } + } + + return solveKnapsackRecursive(capacity, weights, profits, numOfItems, dpTable); + } + + // Returns the value of maximum profit using recursive approach + int solveKnapsackRecursive(int capacity, int[] weights, int[] profits, int numOfItems, int[][] dpTable) { + // Base condition + if (numOfItems == 0 || capacity == 0) { + return 0; + } + + if (dpTable[numOfItems][capacity] != -1) { + return dpTable[numOfItems][capacity]; + } + + if (weights[numOfItems - 1] > capacity) { + // Store the value of function call stack in table + dpTable[numOfItems][capacity] = solveKnapsackRecursive(capacity, weights, profits, numOfItems - 1, dpTable); + return dpTable[numOfItems][capacity]; + } else { + // case 1. include the item, if it is less than the capacity + final int includeCurrentItem = profits[numOfItems - 1] + solveKnapsackRecursive(capacity - weights[numOfItems - 1], weights, profits, numOfItems - 1, dpTable); + + // case 2. exclude the item if it is more than the capacity + final int excludeCurrentItem = solveKnapsackRecursive(capacity, weights, profits, numOfItems - 1, dpTable); + + // Store the value of function call stack in table and return + dpTable[numOfItems][capacity] = Math.max(includeCurrentItem, excludeCurrentItem); + return dpTable[numOfItems][capacity]; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java new file mode 100644 index 000000000000..119d65dfe365 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java @@ -0,0 +1,84 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.stream.IntStream; + +/** + * Provides functions to calculate the Levenshtein distance between two strings. + * + * The Levenshtein distance is a measure of the similarity between two strings by calculating the minimum number of single-character + * edits (insertions, deletions, or substitutions) required to change one string into the other. + */ +public final class LevenshteinDistance { + private LevenshteinDistance() { + } + + /** + * Calculates the Levenshtein distance between two strings using a naive dynamic programming approach. + * + * This function computes the Levenshtein distance by constructing a dynamic programming matrix and iteratively filling it in. + * It follows the standard top-to-bottom, left-to-right approach for filling in the matrix. + * + * @param string1 The first string. + * @param string2 The second string. + * @return The Levenshtein distance between the two input strings. + * + * Time complexity: O(nm), + * Space complexity: O(nm), + * + * where n and m are lengths of `string1` and `string2`. + * + * Note that this implementation uses a straightforward dynamic programming approach without any space optimization. + * It may consume more memory for larger input strings compared to the optimized version. + */ + public static int naiveLevenshteinDistance(final String string1, final String string2) { + int[][] distanceMatrix = IntStream.rangeClosed(0, string1.length()).mapToObj(i -> IntStream.rangeClosed(0, string2.length()).map(j -> (i == 0) ? j : (j == 0) ? i : 0).toArray()).toArray(int[][] ::new); + + IntStream.range(1, string1.length() + 1).forEach(i -> IntStream.range(1, string2.length() + 1).forEach(j -> { + final int cost = (string1.charAt(i - 1) == string2.charAt(j - 1)) ? 0 : 1; + distanceMatrix[i][j] = Math.min(distanceMatrix[i - 1][j - 1] + cost, Math.min(distanceMatrix[i][j - 1] + 1, distanceMatrix[i - 1][j] + 1)); + })); + + return distanceMatrix[string1.length()][string2.length()]; + } + + /** + * Calculates the Levenshtein distance between two strings using an optimized dynamic programming approach. + * + * This edit distance is defined as 1 point per insertion, substitution, or deletion required to make the strings equal. + * + * @param string1 The first string. + * @param string2 The second string. + * @return The Levenshtein distance between the two input strings. + * + * Time complexity: O(nm), + * Space complexity: O(n), + * + * where n and m are lengths of `string1` and `string2`. + * + * Note that this implementation utilizes an optimized dynamic programming approach, significantly reducing the space complexity from O(nm) to O(n), where n and m are the lengths of `string1` and `string2`. + * + * Additionally, it minimizes space usage by leveraging the shortest string horizontally and the longest string vertically in the computation matrix. + */ + public static int optimizedLevenshteinDistance(final String string1, final String string2) { + if (string1.isEmpty()) { + return string2.length(); + } + + int[] previousDistance = IntStream.rangeClosed(0, string1.length()).toArray(); + + for (int j = 1; j <= string2.length(); j++) { + int prevSubstitutionCost = previousDistance[0]; + previousDistance[0] = j; + + for (int i = 1; i <= string1.length(); i++) { + final int deletionCost = previousDistance[i] + 1; + final int insertionCost = previousDistance[i - 1] + 1; + final int substitutionCost = (string1.charAt(i - 1) == string2.charAt(j - 1)) ? prevSubstitutionCost : prevSubstitutionCost + 1; + prevSubstitutionCost = previousDistance[i]; + previousDistance[i] = Math.min(deletionCost, Math.min(insertionCost, substitutionCost)); + } + } + + return previousDistance[string1.length()]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java new file mode 100644 index 000000000000..d6f9b2acf768 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java @@ -0,0 +1,73 @@ +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 final class LongestAlternatingSubsequence { + private 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] = 1; + 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java new file mode 100644 index 000000000000..2d1fa1d1153f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java @@ -0,0 +1,73 @@ +package com.thealgorithms.dynamicprogramming; + +final class LongestCommonSubsequence { + private 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] = Math.max(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(); + int 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java new file mode 100644 index 000000000000..470833ce9c97 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java @@ -0,0 +1,98 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * @author Afrizal Fikri (https://github.com/icalF) + */ +public final class LongestIncreasingSubsequence { + private LongestIncreasingSubsequence() { + } + + 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; + } + + public static int lis(int[] array) { + int len = array.length; + if (len == 0) { + return 0; + } + + int[] tail = new int[len]; + + // always points empty slot in tail + int length = 1; + + tail[0] = array[0]; + for (int i = 1; i < len; 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) { + final int size = a.length; + if (size == 0) { + return 0; + } + int[] arr = new int[size]; + arr[0] = a[0]; + int lis = 1; + for (int i = 1; i < size; i++) { + int index = binarySearchBetween(arr, lis - 1, 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) { + final int middle = (left + right) >>> 1; + if (t[middle] < key) { + left = middle; + } else { + right = middle; + } + } + return right; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java new file mode 100644 index 000000000000..0b40d4559341 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java @@ -0,0 +1,58 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Algorithm explanation + * https://www.educative.io/edpresso/longest-palindromic-subsequence-algorithm + */ +public final class LongestPalindromicSubsequence { + private 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java new file mode 100644 index 000000000000..c6ae55919b82 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java @@ -0,0 +1,46 @@ +package com.thealgorithms.dynamicprogramming; + +/* + * Algorithm explanation https://leetcode.com/problems/longest-palindromic-substring/ + */ +public final class LongestPalindromicSubstring { + private 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; + int 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) { + arr[i][j] = input.charAt(i) == input.charAt(j); + } else { + arr[i][j] = input.charAt(i) == input.charAt(j) && arr[i + 1][j - 1]; + } + + if (arr[i][j]) { + start = i; + end = j; + } + } + } + return input.substring(start, end + 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java new file mode 100644 index 000000000000..02696bfca9c2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java @@ -0,0 +1,43 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * 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 final class LongestValidParentheses { + private 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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java new file mode 100644 index 000000000000..45568d21f295 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java @@ -0,0 +1,141 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Scanner; + +public final class MatrixChainMultiplication { + private MatrixChainMultiplication() { + } + + private static final Scanner SCANNER = new Scanner(System.in); + private static final ArrayList<Matrix> MATRICES = 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); + MATRICES.add(matrix); + count++; + } + for (Matrix m : MATRICES) { + System.out.format("A(%d) = %2d x %2d%n", m.count(), m.col(), m.row()); + } + + size = MATRICES.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 ? MATRICES.get(i).col() : MATRICES.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.printf("%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 (SCANNER.nextLine().split(" ")); + } +} + +class Matrix { + + private final int count; + private final int col; + private final 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java new file mode 100644 index 000000000000..6c1c4cf54ffc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java @@ -0,0 +1,48 @@ +package com.thealgorithms.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 final class MatrixChainRecursiveTopDownMemoisation { + private MatrixChainRecursiveTopDownMemoisation() { + } + + static int memoizedMatrixChain(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 lookupChain(m, p, 1, n - 1); + } + + static int lookupChain(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 < j; k++) { + int q = lookupChain(m, p, i, k) + lookupChain(m, p, k + 1, j) + (p[i - 1] * p[k] * p[j]); + if (q < m[i][j]) { + m[i][j] = q; + } + } + } + return m[i][j]; + } + + // in this code we are taking the example of 4 matrixes whose orders are 1x2,2x3,3x4,4x5 + // respectively output should be Minimum number of multiplications is 38 + public static void main(String[] args) { + int[] arr = {1, 2, 3, 4, 5}; + System.out.println("Minimum number of multiplications is " + memoizedMatrixChain(arr)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java new file mode 100644 index 000000000000..98773de92f6b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MinimumPathSum.java @@ -0,0 +1,64 @@ +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. + +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(n). +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 final class MinimumPathSum { + + private MinimumPathSum() { + } + + public static int minimumPathSum(final int[][] grid) { + int numRows = grid.length; + int numCols = grid[0].length; + + if (numCols == 0) { + return 0; + } + + int[] dp = new int[numCols]; + + // Initialize the first element of the dp array + dp[0] = grid[0][0]; + + // Calculate the minimum path sums for the first row + for (int col = 1; col < numCols; col++) { + dp[col] = dp[col - 1] + grid[0][col]; + } + + // Calculate the minimum path sums for the remaining rows + for (int row = 1; row < numRows; row++) { + // Update the minimum path sum for the first column + dp[0] += grid[row][0]; + + for (int col = 1; col < numCols; col++) { + // Choose the minimum path sum from the left or above + dp[col] = Math.min(dp[col - 1], dp[col]) + grid[row][col]; + } + } + + // Return the minimum path sum for the last cell in the grid + return dp[numCols - 1]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java new file mode 100644 index 000000000000..52308c23cf1c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java @@ -0,0 +1,57 @@ +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + +/* +Given an array of non-negative integers , partition the array in two subset that +difference in sum of elements for both subset minimum. +Return the minimum difference in sum of these subsets you can achieve. + +Input: array[] = {1, 6, 11, 4} +Output: 0 +Explanation: +Subset1 = {1, 4, 6}, sum of Subset1 = 11 +Subset2 = {11}, sum of Subset2 = 11 + +Input: array[] = {36, 7, 46, 40} +Output: 23 +Explanation: +Subset1 = {7, 46} ; sum of Subset1 = 53 +Subset2 = {36, 40} ; sum of Subset2 = 76 + */ +public final class MinimumSumPartition { + private MinimumSumPartition() { + } + + private static void throwIfInvalidInput(final int[] array) { + if (Arrays.stream(array).anyMatch(a -> a < 0)) { + throw new IllegalArgumentException("Input array should not contain negative number(s)."); + } + } + + public static int minimumSumPartition(final int[] array) { + throwIfInvalidInput(array); + int sum = Arrays.stream(array).sum(); + boolean[] dp = new boolean[sum / 2 + 1]; + dp[0] = true; // Base case , don't select any element from array + + // Find the closest sum of subset array that we can achieve which is closest to half of sum of full array + int closestPartitionSum = 0; + + for (int i = 0; i < array.length; i++) { + for (int j = sum / 2; j > 0; j--) { + if (array[i] <= j) { + dp[j] = dp[j] || dp[j - array[i]]; + } + if (dp[j]) { + closestPartitionSum = Math.max(closestPartitionSum, j); + } + } + } + /* + Difference in sum = Big partition sum - Small partition sum + = ( Total sum - Small partition sum) - Small partition sum + */ + return sum - (2 * closestPartitionSum); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java new file mode 100644 index 000000000000..5d31d40dacdc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java @@ -0,0 +1,28 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ + +/** Program description - To find the New Man Shanks Prime. */ +/** Wikipedia Link - https://en.wikipedia.org/wiki/Newman%E2%80%93Shanks%E2%80%93Williams_prime */ + +package com.thealgorithms.dynamicprogramming; + +public final class NewManShanksPrime { + private NewManShanksPrime() { + } + + public static boolean nthManShanksPrime(int n, int expectedAnswer) { + int[] a = new int[n + 1]; + // array of n+1 size is initialized + a[0] = 1; + a[1] = 1; + // The 0th and 1st index position values are fixed. They are initialized as 1 + for (int i = 2; i <= n; i++) { + a[i] = 2 * a[i - 1] + a[i - 2]; + } + // The loop is continued till n + return a[n] == expectedAnswer; + // returns true if calculated answer matches with expected answer + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java new file mode 100644 index 000000000000..0840e08c531c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java @@ -0,0 +1,129 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * This class refers to the Optimal Job Scheduling problem with the following constrains: + * - precedence relation between the processes + * - machine pair dependent transportation delays + * + * https://en.wikipedia.org/wiki/Optimal_job_scheduling + * + * @author georgioct@csd.auth.gr + */ +public class OptimalJobScheduling { + + private final int numberProcesses; + private final int numberMachines; + private final int[][] run; + private final int[][] transfer; + private final int[][] cost; + + /** + * Constructor of the class. + * @param numberProcesses ,refers to the number of precedent processes(N) + * @param numberMachines ,refers to the number of different machines in our disposal(M) + * @param run , N*M matrix refers to the cost of running each process to each machine + * @param transfer ,M*M symmetric matrix refers to the transportation delay for each pair of + * machines + */ + public OptimalJobScheduling(int numberProcesses, int numberMachines, int[][] run, int[][] transfer) { + this.numberProcesses = numberProcesses; + this.numberMachines = numberMachines; + this.run = run; + this.transfer = transfer; + this.cost = new int[numberProcesses][numberMachines]; + } + + /** + * Function which computes the cost of process scheduling to a number of VMs. + */ + public void execute() { + this.calculateCost(); + this.showResults(); + } + + /** + * Function which computes the cost of running each Process to each and every Machine + */ + private void calculateCost() { + + for (int i = 0; i < numberProcesses; i++) { // for each Process + + for (int j = 0; j < numberMachines; j++) { // for each Machine + + cost[i][j] = runningCost(i, j); + } + } + } + + /** + * Function which returns the minimum cost of running a certain Process to a certain Machine.In + * order for the Machine to execute the Process ,he requires the output of the previously + * executed Process, which may have been executed to the same Machine or some other.If the + * previous Process has been executed to another Machine,we have to transfer her result, which + * means extra cost for transferring the data from one Machine to another(if the previous + * Process has been executed to the same Machine, there is no transport cost). + * + * @param process ,refers to the Process + * @param machine ,refers to the Machine + * @return the minimum cost of executing the process to the certain machine. + */ + private int runningCost(int process, int machine) { + + if (process == 0) // refers to the first process,which does not require for a previous one + // to have been executed + return run[process][machine]; + else { + + int[] runningCosts = new int[numberMachines]; // stores the costs of executing our Process depending on + // the Machine the previous one was executed + + for (int k = 0; k < numberMachines; k++) // computes the cost of executing the previous + // process to each and every Machine + runningCosts[k] = cost[process - 1][k] + transfer[k][machine] + run[process][machine]; // transferring the result to our Machine and executing + // the Process to our Machine + + return findMin(runningCosts); // returns the minimum running cost + } + } + + /** + * Function used in order to return the minimum Cost. + * @param costArr ,an Array of size M which refers to the costs of executing a Process to each + * Machine + * @return the minimum cost + */ + private int findMin(int[] costArr) { + + int min = 0; + + for (int i = 1; i < costArr.length; i++) { + + if (costArr[i] < costArr[min]) min = i; + } + return costArr[min]; + } + + /** + * Method used in order to present the overall costs. + */ + private void showResults() { + + for (int i = 0; i < numberProcesses; i++) { + + for (int j = 0; j < numberMachines; j++) { + System.out.print(cost[i][j]); + System.out.print(" "); + } + + System.out.println(); + } + System.out.println(); + } + + /** + * Getter for the running Cost of i process on j machine. + */ + public int getCost(int process, int machine) { + return cost[process][machine]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java new file mode 100644 index 000000000000..01fa1d19609a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java @@ -0,0 +1,90 @@ +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 final class PalindromicPartitioning { + private 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; + int j; + int subLen; // different looping variables + + // Every substring of length 1 is a palindrome + for (i = 0; i < len; i++) { + isPalindrome[i][i] = true; + } + + /* subLen is substring length. Build the solution in bottom up manner by considering all + * substrings of length starting from 2 to n. */ + for (subLen = 2; subLen <= len; subLen++) { + // For substring of length subLen, set different possible starting indexes + for (i = 0; i < len - subLen + 1; i++) { + j = i + subLen - 1; // Ending index + // If subLen 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 (subLen == 2) { + isPalindrome[i][j] = (word.charAt(i) == word.charAt(j)); + } else { + isPalindrome[i][j] = (word.charAt(i) == word.charAt(j)) && isPalindrome[i + 1][j - 1]; + } + } + } + + // We find the minimum for each index + for (i = 0; i < len; i++) { + if (isPalindrome[0][i]) { + minCuts[i] = 0; + } else { + minCuts[i] = Integer.MAX_VALUE; + for (j = 0; j < i; j++) { + if (isPalindrome[j + 1][i] && 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java new file mode 100644 index 000000000000..49c4a0a3a008 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java @@ -0,0 +1,42 @@ +/** + * @author Md Asif Joardar + * + * Description: The partition problem is a classic problem in computer science + * that asks whether a given set can be partitioned into two subsets such that + * the sum of elements in each subset is the same. + * + * Example: + * Consider nums = {1, 2, 3} + * We can split the array "nums" into two partitions, where each having a sum of 3. + * nums1 = {1, 2} + * nums2 = {3} + * + * The time complexity of the solution is O(n × sum) and requires O(n × sum) space + */ + +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + +public final class PartitionProblem { + private PartitionProblem() { + } + + /** + * Test if a set of integers can be partitioned into two subsets such that the sum of elements + * in each subset is the same. + * + * @param nums the array contains integers. + * @return {@code true} if two subset exists, otherwise {@code false}. + */ + public static boolean partition(int[] nums) { + // calculate the sum of all the elements in the array + int sum = Arrays.stream(nums).sum(); + + // it will return true if the sum is even and the array can be divided into two + // subarrays/subset with equal sum. and here i reuse the SubsetSum class from dynamic + // programming section to check if there is exists a subsetsum into nums[] array same as the + // given sum + return (sum & 1) == 0 && SubsetSum.subsetSum(nums, sum / 2); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java new file mode 100644 index 000000000000..43427457e307 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java @@ -0,0 +1,169 @@ +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 final class RegexMatching { + private 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; + } + 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 ? 2 : 1; + 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java new file mode 100644 index 000000000000..f56fc4ff5641 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java @@ -0,0 +1,39 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * A Dynamic Programming solution for the Rod cutting problem. + * Returns the best obtainable price for a rod of length n and price[] as prices of different pieces. + */ +public final class RodCutting { + private RodCutting() { + } + + /** + * This method calculates the maximum obtainable value for cutting a rod of length n + * into different pieces, given the prices for each possible piece length. + * + * @param price An array representing the prices of different pieces, where price[i-1] + * represents the price of a piece of length i. + * @param n The length of the rod to be cut. + * @return The maximum obtainable value. + */ + public static int cutRod(int[] price, int n) { + // Create an array to store the maximum obtainable values for each rod length. + int[] val = new int[n + 1]; + val[0] = 0; + + // Calculate the maximum value for each rod length from 1 to n. + for (int i = 1; i <= n; i++) { + int maxVal = Integer.MIN_VALUE; + // Try all possible ways to cut the rod and find the maximum value. + for (int j = 1; j <= i; j++) { + maxVal = Math.max(maxVal, price[j - 1] + val[i - j]); + } + // Store the maximum value for the current rod length. + val[i] = maxVal; + } + + // The final element of 'val' contains the maximum obtainable value for a rod of length 'n'. + return val[n]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java new file mode 100644 index 000000000000..362ed5e252d2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java @@ -0,0 +1,58 @@ +package com.thealgorithms.dynamicprogramming; + +// Java program to find length of the shortest supersequence +final class ShortestSuperSequence { + private ShortestSuperSequence() { + } + + // Function to find length of the + // shortest supersequence of x and 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) { + int[][] lN = new int[m + 1][n + 1]; + int i; + int j; + + // Following steps build lN[m + 1][n + 1] + // in bottom up fashion. Note that + // lN[i][j] contains length of lNCS + // 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) { + lN[i][j] = 0; + } else if (x.charAt(i - 1) == y.charAt(j - 1)) { + lN[i][j] = lN[i - 1][j - 1] + 1; + } else { + lN[i][j] = Math.max(lN[i - 1][j], lN[i][j - 1]); + } + } + } + + // lN[m][n] contains length of LCS + // for x[0..n - 1] and y[0..m - 1] + return lN[m][n]; + } + + // Driver code + public static void main(String[] args) { + String x = "AGGTAB"; + String y = "GXTXAYB"; + + System.out.println("Length of the shortest " + + "supersequence is " + shortestSuperSequence(x, y)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java new file mode 100644 index 000000000000..af31294f7e0e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java @@ -0,0 +1,69 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * Find the number of subsets present in the given array with a sum equal to target. + * Based on Solution discussed on + * StackOverflow(https://stackoverflow.com/questions/22891076/count-number-of-subsets-with-sum-equal-to-k) + * @author Samrat Podder(https://github.com/samratpodder) + */ +public final class SubsetCount { + private SubsetCount() { + } + + /** + * Dynamic Programming Implementation. + * Method to find out the number of subsets present in the given array with a sum equal to + * target. Time Complexity is O(n*target) and Space Complexity is O(n*target) + * @param arr is the input array on which subsets are to searched + * @param target is the sum of each element of the subset taken together + * + */ + public static int getCount(int[] arr, int target) { + /** + * Base Cases - If target becomes zero, we have reached the required sum for the subset + * If we reach the end of the array arr then, either if target==arr[end], then we add one to + * the final count Otherwise we add 0 to the final count + */ + int n = arr.length; + int[][] dp = new int[n][target + 1]; + for (int i = 0; i < n; i++) { + dp[i][0] = 1; + } + if (arr[0] <= target) dp[0][arr[0]] = 1; + for (int t = 1; t <= target; t++) { + for (int idx = 1; idx < n; idx++) { + int notpick = dp[idx - 1][t]; + int pick = 0; + if (arr[idx] <= t) pick += dp[idx - 1][target - t]; + dp[idx][target] = pick + notpick; + } + } + return dp[n - 1][target]; + } + + /** + * This Method is a Space Optimized version of the getCount(int[], int) method and solves the + * same problem This approach is a bit better in terms of Space Used Time Complexity is + * O(n*target) and Space Complexity is O(target) + * @param arr is the input array on which subsets are to searched + * @param target is the sum of each element of the subset taken together + */ + public static int getCountSO(int[] arr, int target) { + int n = arr.length; + int[] prev = new int[target + 1]; + prev[0] = 1; + if (arr[0] <= target) prev[arr[0]] = 1; + for (int ind = 1; ind < n; ind++) { + int[] cur = new int[target + 1]; + cur[0] = 1; + for (int t = 1; t <= target; t++) { + int notTaken = prev[t]; + int taken = 0; + if (arr[ind] <= t) taken = prev[t - arr[ind]]; + cur[t] = notTaken + taken; + } + prev = cur; + } + return prev[target]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java new file mode 100644 index 000000000000..087d9ac2c7e7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java @@ -0,0 +1,50 @@ +package com.thealgorithms.dynamicprogramming; + +public final class SubsetSum { + private 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}. + */ + public 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/Java/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java new file mode 100644 index 000000000000..dd48008bd21e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java @@ -0,0 +1,20 @@ +package com.thealgorithms.dynamicprogramming; + +public final class SumOfSubset { + private SumOfSubset() { + } + + public static boolean subsetSum(int[] arr, int num, int key) { + if (key == 0) { + return true; + } + if (num < 0 || key < 0) { + return false; + } + + boolean include = subsetSum(arr, num - 1, key - arr[num]); + boolean exclude = subsetSum(arr, num - 1, key); + + return include || exclude; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java new file mode 100644 index 000000000000..407566f481a0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java @@ -0,0 +1,34 @@ +package com.thealgorithms.dynamicprogramming; + +/** + * The {@code Tribonacci} class provides a method to compute the n-th number in the Tribonacci sequence. + * N-th Tribonacci Number - https://leetcode.com/problems/n-th-tribonacci-number/description/ + */ +public final class Tribonacci { + private Tribonacci() { + } + + /** + * Computes the n-th Tribonacci number. + * + * @param n the index of the Tribonacci number to compute + * @return the n-th Tribonacci number + */ + public static int compute(int n) { + if (n == 0) return 0; + if (n == 1 || n == 2) return 1; + + int first = 0; + int second = 1; + int third = 1; + + for (int i = 3; i <= n; i++) { + int next = first + second + third; + first = second; + second = third; + third = next; + } + + return third; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java new file mode 100644 index 000000000000..c48bdea2dc8d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java @@ -0,0 +1,71 @@ +/** + * Author: Siddhant Swarup Mallick + * Github: https://github.com/siddhant2002 + * <p> + * Problem Description: + * A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). + * The robot can only move either down or right at any point in time. + * The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). + * How many possible unique paths are there? + * <p> + * Program Description: + * This program calculates the number of unique paths possible for a robot to reach the bottom-right corner + * of an m x n grid using dynamic programming. + */ + +package com.thealgorithms.dynamicprogramming; + +import java.util.Arrays; + +public final class UniquePaths { + + private UniquePaths(){}; + + /** + * Calculates the number of unique paths using a 1D dynamic programming array. + * Time complexity O(n*m) + * Space complexity O(min(n,m)) + * + * @param m The number of rows in the grid. + * @param n The number of columns in the grid. + * @return The number of unique paths. + */ + public static int uniquePaths(final int m, final int n) { + if (m > n) { + return uniquePaths(n, m); // Recursive call to handle n > m cases + } + int[] dp = new int[n]; // Create a 1D array to store unique paths for each column + Arrays.fill(dp, 1); // Initialize all values to 1 (one way to reach each cell) + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[j] = Math.addExact(dp[j], dp[j - 1]); // Update the number of unique paths for each cell + } + } + return dp[n - 1]; // The result is stored in the last column of the array + } + + /** + * Calculates the number of unique paths using a 2D dynamic programming array. + * Time complexity O(n*m) + * Space complexity O(n*m) + * + * @param m The number of rows in the grid. + * @param n The number of columns in the grid. + * @return The number of unique paths. + */ + public static int uniquePaths2(final int m, final int n) { + int[][] dp = new int[m][n]; // Create a 2D array to store unique paths for each cell + for (int i = 0; i < m; i++) { + dp[i][0] = 1; // Initialize the first column to 1 (one way to reach each cell) + } + for (int j = 0; j < n; j++) { + dp[0][j] = 1; // Initialize the first row to 1 (one way to reach each cell) + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = Math.addExact(dp[i - 1][j], dp[i][j - 1]); // Update the number of unique paths for each cell + } + } + return dp[m - 1][n - 1]; // The result is stored in the bottom-right cell of the array + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java new file mode 100644 index 000000000000..8e8bf3cc6606 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java @@ -0,0 +1,57 @@ +/** + * + * Author: Janmesh Singh + * Github: https://github.com/janmeshjs + + * Problem Statement: To determine if the pattern matches the text. + * The pattern can include two special wildcard characters: + * ' ? ': Matches any single character. + * ' * ': Matches zero or more of any character sequence. + * + * Use DP to return True if the pattern matches the entire text and False otherwise + * + */ + +package com.thealgorithms.dynamicprogramming; + +public final class WildcardMatching { + private WildcardMatching() { + } + + public static boolean isMatch(String text, String pattern) { + int m = text.length(); + int n = pattern.length(); + + // Create a DP table to store intermediate results + boolean[][] dp = new boolean[m + 1][n + 1]; + + // Base case: an empty pattern matches an empty text + dp[0][0] = true; + + // Handle patterns starting with '*' + for (int j = 1; j <= n; j++) { + if (pattern.charAt(j - 1) == '*') { + dp[0][j] = dp[0][j - 1]; + } + } + + // Fill the DP table + for (int i = 1; i <= m; i++) { + for (int j = 1; j <= n; j++) { + char textChar = text.charAt(i - 1); + char patternChar = pattern.charAt(j - 1); + + if (patternChar == textChar || patternChar == '?') { + dp[i][j] = dp[i - 1][j - 1]; + } else if (patternChar == '*') { + // '*' can match zero or more characters + dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; + } else { + dp[i][j] = false; + } + } + } + // The result is in the bottom-right cell of the DP table + return dp[m][n]; + } +} diff --git a/Java/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java b/Java/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java new file mode 100644 index 000000000000..0f5359f4d95e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java @@ -0,0 +1,85 @@ +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 final class WineProblem { + private 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; + + return Math.max(start, end); + } + + // 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/Java/src/main/java/com/thealgorithms/geometry/GrahamScan.java b/Java/src/main/java/com/thealgorithms/geometry/GrahamScan.java new file mode 100644 index 000000000000..4f4aebaed971 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/geometry/GrahamScan.java @@ -0,0 +1,163 @@ +package com.thealgorithms.geometry; + +import java.util.Arrays; +import java.util.Comparator; +import java.util.Stack; + +/* + * A Java program that computes the convex hull using the Graham Scan algorithm + * In the best case, time complexity is O(n), while in the worst case, it is O(nlog(n)). + * O(n) space complexity + * + * This algorithm is only applicable to integral coordinates. + * + * Reference: + * https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/graham_scan_algorithm.cpp + * https://github.com/TheAlgorithms/C-Plus-Plus/blob/master/geometry/graham_scan_functions.hpp + * https://algs4.cs.princeton.edu/99hull/GrahamScan.java.html + */ +public class GrahamScan { + private final Stack<Point> hull = new Stack<>(); + + public GrahamScan(Point[] points) { + + /* + * pre-process the points by sorting them with respect to the bottom-most point, then we'll + * push the first point in the array to be our first extreme point. + */ + Arrays.sort(points); + Arrays.sort(points, 1, points.length, points[0].polarOrder()); + hull.push(points[0]); + + // find index of first point not equal to a[0] (indexPoint1) and the first point that's not + // collinear with either (indexPoint2). + int indexPoint1; + for (indexPoint1 = 1; indexPoint1 < points.length; indexPoint1++) + if (!points[0].equals(points[indexPoint1])) break; + if (indexPoint1 == points.length) return; + + int indexPoint2; + for (indexPoint2 = indexPoint1 + 1; indexPoint2 < points.length; indexPoint2++) + if (Point.orientation(points[0], points[indexPoint1], points[indexPoint2]) != 0) break; + hull.push(points[indexPoint2 - 1]); + + // Now we simply add the point to the stack based on the orientation. + for (int i = indexPoint2; i < points.length; i++) { + Point top = hull.pop(); + while (Point.orientation(hull.peek(), top, points[i]) <= 0) { + top = hull.pop(); + } + hull.push(top); + hull.push(points[i]); + } + } + + /** + * @return A stack of points representing the convex hull. + */ + public Iterable<Point> hull() { + Stack<Point> s = new Stack<>(); + for (Point p : hull) s.push(p); + return s; + } + + public record Point(int x, int y) implements Comparable<Point> { + + /** + * Default constructor + * @param x x-coordinate + * @param y y-coordinate + */ + public Point { + } + + /** + * @return the x-coordinate + */ + @Override + public int x() { + return x; + } + + /** + * @return the y-coordinate + */ + @Override + public int y() { + return y; + } + + /** + * Finds the orientation of ordered triplet. + * + * @param a Co-ordinates of point a <int, int> + * @param b Co-ordinates of point a <int, int> + * @param c Co-ordinates of point a <int, int> + * @return { -1, 0, +1 } if a -→ b -→ c is a { clockwise, collinear; counterclockwise } + * turn. + */ + public static int orientation(Point a, Point b, Point c) { + int val = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x); + if (val == 0) { + return 0; + } + return (val > 0) ? +1 : -1; + } + + /** + * @param p2 Co-ordinate of point to compare to. + * This function will compare the points and will return a positive integer if the + * point is greater than the argument point and a negative integer if the point is + * less than the argument point. + */ + public int compareTo(Point p2) { + int res = Integer.compare(this.y, p2.y); + if (res == 0) res = Integer.compare(this.x, p2.x); + return res; + } + + /** + * A helper function that will let us sort points by their polar order + * This function will compare the angle between 2 polar Co-ordinates + * + * @return the comparator + */ + public Comparator<Point> polarOrder() { + return new PolarOrder(); + } + + private final class PolarOrder implements Comparator<Point> { + public int compare(Point p1, Point p2) { + int dx1 = p1.x - x; + int dy1 = p1.y - y; + int dx2 = p2.x - x; + int dy2 = p2.y - y; + + if (dy1 >= 0 && dy2 < 0) + return -1; // q1 above; q2 below + else if (dy2 >= 0 && dy1 < 0) + return +1; // q1 below; q2 above + else if (dy1 == 0 && dy2 == 0) { // 3-collinear and horizontal + if (dx1 >= 0 && dx2 < 0) + return -1; + else if (dx2 >= 0 && dx1 < 0) + return +1; + else + return 0; + } else + return -orientation(Point.this, p1, p2); // both above or below + } + } + + /** + * Override of the toString method, necessary to compute the difference + * between the expected result and the derived result + * + * @return a string representation of any given 2D point in the format (x, y) + */ + @Override + public String toString() { + return "(" + x + ", " + y + ")"; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java b/Java/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java new file mode 100644 index 000000000000..88fbc50129ca --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java @@ -0,0 +1,42 @@ +package com.thealgorithms.greedyalgorithms; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +// Problem Link: https://en.wikipedia.org/wiki/Activity_selection_problem + +public final class ActivitySelection { + private ActivitySelection() { + } + // Function to perform activity selection + public static ArrayList<Integer> activitySelection(int[] startTimes, int[] endTimes) { + int n = startTimes.length; + int[][] activities = new int[n][3]; + + // Create a 2D array to store activities and their start/end times. + // Each row: [activity index, start time, end time] + + for (int i = 0; i < n; i++) { + activities[i][0] = i; // Assign activity index + activities[i][1] = startTimes[i]; // Assign start time + activities[i][2] = endTimes[i]; // Assign end time + } + + // Sort activities by their end times in ascending order. + Arrays.sort(activities, Comparator.comparingDouble(activity -> activity[2])); + int lastEndTime; + ArrayList<Integer> selectedActivities = new ArrayList<>(); + selectedActivities.add(activities[0][0]); + lastEndTime = activities[0][2]; + + // Iterate through sorted activities to select compatible ones. + for (int i = 1; i < n; i++) { + if (activities[i][1] >= lastEndTime) { + selectedActivities.add(activities[i][0]); + lastEndTime = activities[i][2]; + } + } + return selectedActivities; + } +} diff --git a/Java/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java b/Java/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java new file mode 100644 index 000000000000..8054581d21d7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java @@ -0,0 +1,35 @@ +package com.thealgorithms.greedyalgorithms; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; + +// Problem Link : https://en.wikipedia.org/wiki/Change-making_problem + +public final class CoinChange { + private CoinChange() { + } + // Function to solve the coin change problem + public static ArrayList<Integer> coinChangeProblem(int amount) { + // Define an array of coin denominations in descending order + Integer[] coins = {1, 2, 5, 10, 20, 50, 100, 500, 2000}; + + // Sort the coin denominations in descending order + Arrays.sort(coins, Comparator.reverseOrder()); + + ArrayList<Integer> ans = new ArrayList<>(); // List to store selected coins + + // Iterate through the coin denominations + for (int i = 0; i < coins.length; i++) { + // Check if the current coin denomination can be used to reduce the remaining amount + if (coins[i] <= amount) { + // Repeatedly subtract the coin denomination from the remaining amount + while (coins[i] <= amount) { + ans.add(coins[i]); // Add the coin to the list of selected coins + amount -= coins[i]; // Update the remaining amount + } + } + } + return ans; + } +} diff --git a/Java/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java b/Java/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java new file mode 100644 index 000000000000..082bd9c68b32 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java @@ -0,0 +1,43 @@ +package com.thealgorithms.greedyalgorithms; + +import java.util.Arrays; +import java.util.Comparator; + +// Problem Link: https://en.wikipedia.org/wiki/Continuous_knapsack_problem + +public final class FractionalKnapsack { + private FractionalKnapsack() { + } + // Function to perform fractional knapsack + public static int fractionalKnapsack(int[] weight, int[] value, int capacity) { + // Create a 2D array to store item indices and their value-to-weight ratios. + double[][] ratio = new double[weight.length][2]; + + // Populate the ratio array with item indices and their value-to-weight ratios. + for (int i = 0; i < weight.length; i++) { + ratio[i][0] = i; // Assign item index. + ratio[i][1] = value[i] / (double) weight[i]; // Calculate and assign value-to-weight ratio. + } + + // Sort items by their value-to-weight ratios in descending order. + Arrays.sort(ratio, Comparator.comparingDouble(o -> o[1])); + + int finalValue = 0; // Variable to store the final knapsack value. + double current = capacity; // Variable to track the remaining capacity of the knapsack. + + // Iterate through the sorted items to select items for the knapsack. + for (int i = ratio.length - 1; i >= 0; i--) { + int index = (int) ratio[i][0]; // Get the item index. + if (current >= weight[index]) { + // If the entire item can fit in the knapsack, add its value. + finalValue += value[index]; + current -= weight[index]; + } else { + // If only a fraction of the item can fit, add a proportionate value. + finalValue += (int) (ratio[i][1] * current); + break; // Stop adding items to the knapsack since it's full. + } + } + return finalValue; + } +} diff --git a/Java/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java b/Java/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java new file mode 100644 index 000000000000..ceb664a31e8a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java @@ -0,0 +1,66 @@ +package com.thealgorithms.greedyalgorithms; + +import java.util.ArrayList; +import java.util.Arrays; + +// Problem Link: https://en.wikipedia.org/wiki/Job-shop_scheduling + +public final class JobSequencing { + private JobSequencing() { + } + + // Define a Job class that implements Comparable for sorting by profit in descending order + static class Job implements Comparable<Job> { + char id; + int deadline; + int profit; + + // Compare jobs by profit in descending order + @Override + public int compareTo(Job otherJob) { + return otherJob.profit - this.profit; + } + + Job(char id, int deadline, int profit) { + this.id = id; + this.deadline = deadline; + this.profit = profit; + } + } + + // Function to print the job sequence + public static String findJobSequence(ArrayList<Job> jobs, int size) { + Boolean[] slots = new Boolean[size]; + Arrays.fill(slots, Boolean.FALSE); + + int[] result = new int[size]; + + // Iterate through jobs to find the optimal job sequence + for (int i = 0; i < size; i++) { + for (int j = jobs.get(i).deadline - 1; j >= 0; j--) { + if (!slots[j]) { + result[j] = i; + slots[j] = Boolean.TRUE; + break; + } + } + } + + // Create a StringBuilder to build the job sequence string + StringBuilder jobSequenceBuilder = new StringBuilder(); + jobSequenceBuilder.append("Job Sequence: "); + for (int i = 0; i < jobs.size(); i++) { + if (slots[i]) { + jobSequenceBuilder.append(jobs.get(result[i]).id).append(" -> "); + } + } + + // Remove the trailing " -> " from the job sequence + if (jobSequenceBuilder.length() >= 4) { + jobSequenceBuilder.setLength(jobSequenceBuilder.length() - 4); + } + + // Return the job sequence as a string + return jobSequenceBuilder.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java b/Java/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java new file mode 100644 index 000000000000..c7f219ef3eab --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java @@ -0,0 +1,45 @@ +package com.thealgorithms.greedyalgorithms; + +import java.util.Arrays; + +public final class MinimizingLateness { + private MinimizingLateness() { + } + + public static class Job { + String jobName; + int startTime = 0; + int lateness = 0; + int processingTime; + int deadline; + + public Job(String jobName, int processingTime, int deadline) { + this.jobName = jobName; + this.processingTime = processingTime; + this.deadline = deadline; + } + + public static Job of(String jobName, int processingTime, int deadline) { + return new Job(jobName, processingTime, deadline); + } + + @Override + public String toString() { + return String.format("%s, startTime: %d, endTime: %d, lateness: %d", jobName, startTime, processingTime + startTime, lateness); + } + } + + static void calculateLateness(Job... jobs) { + + // sort the jobs based on their deadline + Arrays.sort(jobs, (a, b) -> a.deadline - b.deadline); + + int startTime = 0; + + for (Job job : jobs) { + job.startTime = startTime; + startTime += job.processingTime; + job.lateness = Math.max(0, startTime - job.deadline); // if the job finishes before deadline the lateness is 0 + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/io/BufferedReader.java b/Java/src/main/java/com/thealgorithms/io/BufferedReader.java new file mode 100644 index 000000000000..fa0237a48049 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/io/BufferedReader.java @@ -0,0 +1,183 @@ +package com.thealgorithms.io; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +/** + * Mimics the actions of the Original buffered reader + * implements other actions, such as peek(n) to lookahead, + * block() to read a chunk of size {BUFFER SIZE} + * <p> + * Author: Kumaraswamy B.G (Xoma Dev) + */ +public class BufferedReader { + + private static final int DEFAULT_BUFFER_SIZE = 5; + + /** + * The maximum number of bytes the buffer can hold. + * Value is changed when encountered Eof to not + * cause overflow read of 0 bytes + */ + + private int bufferSize; + private final byte[] buffer; + + /** + * posRead -> indicates the next byte to read + */ + private int posRead = 0; + private int bufferPos = 0; + + private boolean foundEof = false; + + private InputStream input; + + public BufferedReader(byte[] input) throws IOException { + this(new ByteArrayInputStream(input)); + } + + public BufferedReader(InputStream input) throws IOException { + this(input, DEFAULT_BUFFER_SIZE); + } + + public BufferedReader(InputStream input, int bufferSize) throws IOException { + this.input = input; + if (input.available() == -1) throw new IOException("Empty or already closed stream provided"); + + this.bufferSize = bufferSize; + buffer = new byte[bufferSize]; + } + + /** + * Reads a single byte from the stream + */ + public int read() throws IOException { + if (needsRefill()) { + if (foundEof) return -1; + // the buffer is empty, or the buffer has + // been completely read and needs to be refilled + refill(); + } + return buffer[posRead++] & 0xff; // read and un-sign it + } + + /** + * Number of bytes not yet been read + */ + + public int available() throws IOException { + int available = input.available(); + if (needsRefill()) + // since the block is already empty, + // we have no responsibility yet + return available; + return bufferPos - posRead + available; + } + + /** + * Returns the next character + */ + + public int peek() throws IOException { + return peek(1); + } + + /** + * Peeks and returns a value located at next {n} + */ + + public int peek(int n) throws IOException { + int available = available(); + if (n >= available) throw new IOException("Out of range, available %d, but trying with %d".formatted(available, n)); + pushRefreshData(); + + if (n >= bufferSize) throw new IllegalAccessError("Cannot peek %s, maximum upto %s (Buffer Limit)".formatted(n, bufferSize)); + return buffer[n]; + } + + /** + * Removes the already read bytes from the buffer + * in-order to make space for new bytes to be filled up. + * <p> + * This may also do the job to read first time data (the whole buffer is empty) + */ + + private void pushRefreshData() throws IOException { + for (int i = posRead, j = 0; i < bufferSize; i++, j++) buffer[j] = buffer[i]; + + bufferPos -= posRead; + posRead = 0; + + // fill out the spaces that we've + // emptied + justRefill(); + } + + /** + * Reads one complete block of size {bufferSize} + * if found eof, the total length of an array will + * be that of what's available + * + * @return a completed block + */ + public byte[] readBlock() throws IOException { + pushRefreshData(); + + byte[] cloned = new byte[bufferSize]; + // arraycopy() function is better than clone() + if (bufferPos >= 0) + System.arraycopy(buffer, 0, cloned, 0, + // important to note that, bufferSize does not stay constant + // once the class is defined. See justRefill() function + bufferSize); + // we assume that already a chunk + // has been read + refill(); + return cloned; + } + + private boolean needsRefill() { + return bufferPos == 0 || posRead == bufferSize; + } + + private void refill() throws IOException { + posRead = 0; + bufferPos = 0; + justRefill(); + } + + private void justRefill() throws IOException { + assertStreamOpen(); + + // try to fill in the maximum we can until + // we reach EOF + while (bufferPos < bufferSize) { + int read = input.read(); + if (read == -1) { + // reached end-of-file, no more data left + // to be read + foundEof = true; + // rewrite the BUFFER_SIZE, to know that we've reached + // EOF when requested refill + bufferSize = bufferPos; + } + buffer[bufferPos++] = (byte) read; + } + } + + private void assertStreamOpen() { + if (input == null) throw new IllegalStateException("Input Stream already closed!"); + } + + public void close() throws IOException { + if (input != null) { + try { + input.close(); + } finally { + input = null; + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/ADTFraction.java b/Java/src/main/java/com/thealgorithms/maths/ADTFraction.java new file mode 100644 index 000000000000..a85ef09079c9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/ADTFraction.java @@ -0,0 +1,80 @@ +package com.thealgorithms.maths; + +public record ADTFraction(int numerator, int denominator) { + /** + * Initializes a newly created {@code ADTFraction} object so that it represents + * a fraction with the {@code numerator} and {@code denominator} provided as arguments. + * + * @param numerator The fraction numerator + * @param denominator The fraction denominator + */ + public ADTFraction { + if (denominator == 0) { + throw new IllegalArgumentException("Denominator cannot be 0"); + } + } + + /** + * Add two fractions. + * + * @param fraction the {@code ADTFraction} to add + * @return A new {@code ADTFraction} containing the result of the operation + */ + public ADTFraction plus(ADTFraction fraction) { + var numerator = this.denominator * fraction.numerator + this.numerator * fraction.denominator; + var denominator = this.denominator * fraction.denominator; + return new ADTFraction(numerator, denominator); + } + + /** + * Multiply fraction by a number. + * + * @param number the number to multiply + * @return A new {@code ADTFraction} containing the result of the operation + */ + public ADTFraction times(int number) { + return times(new ADTFraction(number, 1)); + } + + /** + * Multiply two fractions. + * + * @param fraction the {@code ADTFraction} to multiply + * @return A new {@code ADTFraction} containing the result of the operation + */ + public ADTFraction times(ADTFraction fraction) { + var numerator = this.numerator * fraction.numerator; + var denominator = this.denominator * fraction.denominator; + return new ADTFraction(numerator, denominator); + } + + /** + * Generates the reciprocal of the fraction. + * + * @return A new {@code ADTFraction} with the {@code numerator} and {@code denominator} switched + */ + public ADTFraction reciprocal() { + return new ADTFraction(this.denominator, this.numerator); + } + + /** + * Calculates the result of the fraction. + * + * @return The numerical result of the division between {@code numerator} and {@code + * denominator} + */ + public float value() { + return (float) this.numerator / this.denominator; + } + + /** + * Returns a string representation of this {@code ADTFraction} in the format + * {@code numerator}/{@code denominator}. + * + * @return A string representation of this {@code ADTFraction} + */ + @Override + public String toString() { + return String.format("%d/%d", this.numerator, this.denominator); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AbsoluteMax.java b/Java/src/main/java/com/thealgorithms/maths/AbsoluteMax.java new file mode 100644 index 000000000000..d0c3db3790a3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AbsoluteMax.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +public final class AbsoluteMax { + private AbsoluteMax() { + } + + /** + * Finds the absolute maximum value among the given numbers. + * + * @param numbers The numbers to compare. + * @return The absolute maximum value. + * @throws IllegalArgumentException If the input array is empty or null. + */ + public static int getMaxValue(int... numbers) { + if (numbers == null || numbers.length == 0) { + throw new IllegalArgumentException("Numbers array cannot be empty or null"); + } + int absMax = numbers[0]; + for (int i = 1; i < numbers.length; i++) { + if (Math.abs(numbers[i]) > Math.abs(absMax)) { + absMax = numbers[i]; + } + } + return absMax; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AbsoluteMin.java b/Java/src/main/java/com/thealgorithms/maths/AbsoluteMin.java new file mode 100644 index 000000000000..1ffe6d2e81bc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AbsoluteMin.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; + +public final class AbsoluteMin { + private AbsoluteMin() { + } + + /** + * Compares the numbers given as arguments to get the absolute min value. + * + * @param numbers The numbers to compare + * @return The absolute min value + */ + public static int getMinValue(int... numbers) { + if (numbers.length == 0) { + throw new IllegalArgumentException("Numbers array cannot be empty"); + } + + var absMinWrapper = new Object() { int value = numbers[0]; }; + + Arrays.stream(numbers).skip(1).filter(number -> Math.abs(number) < Math.abs(absMinWrapper.value)).forEach(number -> absMinWrapper.value = number); + + return absMinWrapper.value; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AbsoluteValue.java b/Java/src/main/java/com/thealgorithms/maths/AbsoluteValue.java new file mode 100644 index 000000000000..b9279d5a244a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AbsoluteValue.java @@ -0,0 +1,16 @@ +package com.thealgorithms.maths; + +public final class AbsoluteValue { + private AbsoluteValue() { + } + + /** + * Returns the absolute value of a number. + * + * @param number The number to be transformed + * @return The absolute value of the {@code number} + */ + public static int getAbsValue(int number) { + return number < 0 ? -number : number; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AliquotSum.java b/Java/src/main/java/com/thealgorithms/maths/AliquotSum.java new file mode 100644 index 000000000000..5a5555777425 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AliquotSum.java @@ -0,0 +1,59 @@ +package com.thealgorithms.maths; + +import java.util.stream.IntStream; + +/** + * 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 final class AliquotSum { + private AliquotSum() { + } + + /** + * Finds the aliquot sum of an integer number. + * + * @param number a positive integer + * @return aliquot sum of given {@code number} + */ + public static int getAliquotValue(int number) { + var sumWrapper = new Object() { int value = 0; }; + + IntStream.iterate(1, i -> ++i).limit(number / 2).filter(i -> number % i == 0).forEach(i -> sumWrapper.value += i); + + return sumWrapper.value; + } + + /** + * Function to calculate the aliquot sum of an integer number + * + * @param n a positive integer + * @return aliquot sum of given {@code number} + */ + public static int getAliquotSum(int n) { + if (n <= 0) return -1; + int sum = 1; + double root = Math.sqrt(n); + /* + * We can get the factors after the root by dividing number by its factors + * before the root. + * Ex- Factors of 100 are 1, 2, 4, 5, 10, 20, 25, 50 and 100. + * Root of 100 is 10. So factors before 10 are 1, 2, 4 and 5. + * Now by dividing 100 by each factor before 10 we get: + * 100/1 = 100, 100/2 = 50, 100/4 = 25 and 100/5 = 20 + * So we get 100, 50, 25 and 20 which are factors of 100 after 10 + */ + for (int i = 2; i <= root; i++) { + if (n % i == 0) { + sum += i + n / i; + } + } + // if n is a perfect square then its root was added twice in above loop, so subtracting root + // from sum + if (root == (int) root) sum -= root; + return sum; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AmicableNumber.java b/Java/src/main/java/com/thealgorithms/maths/AmicableNumber.java new file mode 100644 index 000000000000..b30831bfdc58 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AmicableNumber.java @@ -0,0 +1,71 @@ +package com.thealgorithms.maths; + +import java.util.LinkedHashSet; +import java.util.Set; +import org.apache.commons.lang3.tuple.Pair; + +/** + * Amicable numbers are two different natural numbers 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. + * + * <p> + * link: https://en.wikipedia.org/wiki/Amicable_numbers + * <p> + * 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} <-SUM = 220. + */ +public final class AmicableNumber { + private AmicableNumber() { + } + /** + * Finds all the amicable numbers in a given range. + * + * @param from range start value + * @param to range end value (inclusive) + * @return list with amicable numbers found in given range. + */ + public static Set<Pair<Integer, Integer>> findAllInRange(int from, int to) { + if (from <= 0 || to <= 0 || to < from) { + throw new IllegalArgumentException("Given range of values is invalid!"); + } + + Set<Pair<Integer, Integer>> result = new LinkedHashSet<>(); + + for (int i = from; i < to; i++) { + for (int j = i + 1; j <= to; j++) { + if (isAmicableNumber(i, j)) { + result.add(Pair.of(i, j)); + } + } + } + return result; + } + + /** + * Checks whether 2 numbers are AmicableNumbers or not. + */ + public static boolean isAmicableNumber(int a, int b) { + if (a <= 0 || b <= 0) { + throw new IllegalArgumentException("Input numbers must be natural!"); + } + return sumOfDividers(a, a) == b && sumOfDividers(b, b) == a; + } + + /** + * Recursively calculates the sum of all dividers for a given number excluding the divider itself. + */ + private static int sumOfDividers(int number, int divisor) { + if (divisor == 1) { + return 0; + } else if (number % --divisor == 0) { + return sumOfDividers(number, divisor) + divisor; + } else { + return sumOfDividers(number, divisor); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Area.java b/Java/src/main/java/com/thealgorithms/maths/Area.java new file mode 100644 index 000000000000..7a06fd5e5fa0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Area.java @@ -0,0 +1,195 @@ +package com.thealgorithms.maths; + +/** + * Find the area of various geometric shapes + */ +public final class Area { + private Area() { + } + + /** + * String of IllegalArgumentException for radius + */ + private static final String POSITIVE_RADIUS = "Must be a positive radius"; + + /** + * String of IllegalArgumentException for height + */ + private static final String POSITIVE_HEIGHT = "Must be a positive height"; + + /** + * String of IllegalArgumentException for base + */ + private static final String POSITIVE_BASE = "Must be a positive base"; + + /** + * Calculate the surface area of a cube. + * + * @param sideLength side length of cube + * @return surface area of given cube + */ + public static double surfaceAreaCube(final double sideLength) { + if (sideLength <= 0) { + throw new IllegalArgumentException("Must be a positive sideLength"); + } + return 6 * sideLength * sideLength; + } + + /** + * Calculate the surface area of a sphere. + * + * @param radius radius of sphere + * @return surface area of given sphere + */ + public static double surfaceAreaSphere(final double radius) { + if (radius <= 0) { + throw new IllegalArgumentException(POSITIVE_RADIUS); + } + return 4 * Math.PI * radius * radius; + } + + /** + * Calculate the area of a rectangle. + * + * @param length length of a rectangle + * @param width width of a rectangle + * @return area of given rectangle + */ + public static double surfaceAreaRectangle(final double length, final double width) { + if (length <= 0) { + throw new IllegalArgumentException("Must be a positive length"); + } + if (width <= 0) { + throw new IllegalArgumentException("Must be a positive 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 + */ + public static double surfaceAreaCylinder(final double radius, final double height) { + if (radius <= 0) { + throw new IllegalArgumentException(POSITIVE_RADIUS); + } + if (height <= 0) { + throw new IllegalArgumentException(POSITIVE_RADIUS); + } + 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 + */ + public static double surfaceAreaSquare(final double sideLength) { + if (sideLength <= 0) { + throw new IllegalArgumentException("Must be a positive 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 + */ + public static double surfaceAreaTriangle(final double base, final double height) { + if (base <= 0) { + throw new IllegalArgumentException(POSITIVE_BASE); + } + if (height <= 0) { + throw new IllegalArgumentException(POSITIVE_HEIGHT); + } + return base * height / 2; + } + + /** + * Calculate the area of a parallelogram. + * + * @param base base of a parallelogram + * @param height height of a parallelogram + * @return area of given parallelogram + */ + public static double surfaceAreaParallelogram(final double base, final double height) { + if (base <= 0) { + throw new IllegalArgumentException(POSITIVE_BASE); + } + if (height <= 0) { + throw new IllegalArgumentException(POSITIVE_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 + */ + public static double surfaceAreaTrapezium(final double base1, final double base2, final double height) { + if (base1 <= 0) { + throw new IllegalArgumentException(POSITIVE_BASE + 1); + } + if (base2 <= 0) { + throw new IllegalArgumentException(POSITIVE_BASE + 2); + } + if (height <= 0) { + throw new IllegalArgumentException(POSITIVE_HEIGHT); + } + return (base1 + base2) * height / 2; + } + + /** + * Calculate the area of a circle. + * + * @param radius radius of circle + * @return area of given circle + */ + public static double surfaceAreaCircle(final double radius) { + if (radius <= 0) { + throw new IllegalArgumentException(POSITIVE_RADIUS); + } + return Math.PI * radius * radius; + } + + /** + * Calculate the surface area of a hemisphere. + * + * @param radius radius of hemisphere + * @return surface area of given hemisphere + */ + public static double surfaceAreaHemisphere(final double radius) { + if (radius <= 0) { + throw new IllegalArgumentException(POSITIVE_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. + */ + public static double surfaceAreaCone(final double radius, final double height) { + if (radius <= 0) { + throw new IllegalArgumentException(POSITIVE_RADIUS); + } + if (height <= 0) { + throw new IllegalArgumentException(POSITIVE_HEIGHT); + } + return Math.PI * radius * (radius + Math.pow(height * height + radius * radius, 0.5)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Armstrong.java b/Java/src/main/java/com/thealgorithms/maths/Armstrong.java new file mode 100644 index 000000000000..ff4ae027a0b7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Armstrong.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +/** + * This class checks whether a given number is an Armstrong number or not. + * An Armstrong number is a number that is equal to the sum of its own digits, + * each raised to the power of the number of digits. + * + * For example, 370 is an Armstrong number because 3^3 + 7^3 + 0^3 = 370. + * 1634 is an Armstrong number because 1^4 + 6^4 + 3^4 + 4^4 = 1634. + * An Armstrong number is often called a Narcissistic number. + * + * @author satyabarghav + */ +public class Armstrong { + + /** + * Checks whether a given number is an Armstrong number or not. + * + * @param number the number to check + * @return {@code true} if the given number is an Armstrong number, {@code false} otherwise + */ + public boolean isArmstrong(int number) { + long sum = 0; + String temp = Integer.toString(number); // Convert the given number to a string + int power = temp.length(); // Extract the length of the number (number of digits) + long originalNumber = number; + + while (originalNumber > 0) { + long digit = originalNumber % 10; + sum += (long) Math.pow(digit, power); // The digit raised to the power of the number of digits and added to the sum. + originalNumber /= 10; + } + + return sum == number; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AutoCorrelation.java b/Java/src/main/java/com/thealgorithms/maths/AutoCorrelation.java new file mode 100644 index 000000000000..344a1271e11c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AutoCorrelation.java @@ -0,0 +1,57 @@ +package com.thealgorithms.maths; + +/** + * Class for linear auto-correlation of a discrete signal + * + * @author Athina-Frederiki Swinkels + * @version 2.0 + */ + +public final class AutoCorrelation { + private AutoCorrelation() { + } + + /** + * Discrete linear auto-correlation function. + * Input and output signals have starting index 0. + * + * @param x The discrete signal + * @return The result of the auto-correlation of signals x. The result is also a signal. + */ + public static double[] autoCorrelation(double[] x) { + + /* + To find the auto-correlation of a discrete signal x, we perform cross-correlation between x signal and itself. + Here's an example: + x=[1,2,1,1] + y=[1,2,1,1] + + i=0: [1,2,1,1] + [1,2,1,1] result[0]=1*1=1 + + i=1: [1,2,1,1] + [1,2,1,1] result[1]=1*1+2*1=3 + + i=2: [1,2,1,1] + [1,2,1,1] result[2]=1*2+2*1+1*1=5 + + i=3: [1,2,1,1] + [1,2,1,1] result[3]=1*1+2*2+1*1+1*1=7 + + i=4: [1,2,1,1] + [1,2,1,1] result[4]=2*1+1*2+1*1=5 + + i=5: [1,2,1,1] + [1,2,1,1] result[5]=1*1+1*2=3 + + i=1: [1,2,1,1] + [1,2,1,1] result[6]=1*1=1 + + result=[1,3,5,7,5,3,1] + + + */ + + return CrossCorrelation.crossCorrelation(x, x); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java b/Java/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java new file mode 100644 index 000000000000..560ce3aabd1a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java @@ -0,0 +1,63 @@ +package com.thealgorithms.maths; + +/** + * Wikipedia link for Automorphic Number : https://en.wikipedia.org/wiki/Automorphic_number + * 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.math.BigInteger; + +public final class AutomorphicNumber { + private AutomorphicNumber() { + } + + /** + * A function to check if a number is Automorphic number or not + * + * @param n The number to be checked + * @return {@code true} if {@code a} is Automorphic number, otherwise + * {@code false} + */ + public static boolean isAutomorphic(long n) { + if (n < 0) return false; + long square = n * n; // Calculating square of the number + long t = n; + long numberOfdigits = 0; + while (t > 0) { + numberOfdigits++; // Calculating number of digits in n + t /= 10; + } + long lastDigits = square % (long) Math.pow(10, numberOfdigits); // Extracting last Digits of square + return n == lastDigits; + } + + /** + * A function to check if a number is Automorphic number or not by using String functions + * + * @param n The number to be checked + * @return {@code true} if {@code a} is Automorphic number, otherwise + * {@code false} + */ + public static boolean isAutomorphic2(long n) { + if (n < 0) return false; + long square = n * n; // Calculating square of the number + return String.valueOf(square).endsWith(String.valueOf(n)); + } + + /** + * A function to check if a number is Automorphic number or not by using BigInteger + * + * @param s The number in String to be checked + * @return {@code true} if {@code a} is Automorphic number, otherwise + * {@code false} + */ + public static boolean isAutomorphic3(String s) { + BigInteger n = new BigInteger(s); + if (n.signum() == -1) return false; // if number is negative, return false + BigInteger square = n.multiply(n); // Calculating square of the number + return String.valueOf(square).endsWith(String.valueOf(n)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Average.java b/Java/src/main/java/com/thealgorithms/maths/Average.java new file mode 100644 index 000000000000..1c632cf0a65e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Average.java @@ -0,0 +1,44 @@ +package com.thealgorithms.maths; + +/** + * Calculate average of a list of numbers + */ +public final class Average { + private Average() { + } + + /** + * Calculate average of a list of numbers + * + * @param numbers array to store numbers + * @return mean of given numbers + */ + public static double average(double[] numbers) { + if (numbers == null || numbers.length == 0) { + throw new IllegalArgumentException("Numbers array cannot be empty or null"); + } + double sum = 0; + for (double number : numbers) { + sum += number; + } + return sum / numbers.length; + } + + /** + * find average value of an int array + * + * @param numbers the array contains element and the sum does not excess long + * value limit + * @return average value + */ + public static int average(int[] numbers) { + if (numbers == null || numbers.length == 0) { + throw new IllegalArgumentException("Numbers array cannot be empty or null"); + } + long sum = 0; + for (int number : numbers) { + sum += number; + } + return (int) (sum / numbers.length); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/BinaryPow.java b/Java/src/main/java/com/thealgorithms/maths/BinaryPow.java new file mode 100644 index 000000000000..1550376782b1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/BinaryPow.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +public final class BinaryPow { + private 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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java b/Java/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java new file mode 100644 index 000000000000..faec049b08a7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +/* + * Java program for Binomial Cofficients + * Binomial Cofficients: A binomial cofficient C(n,k) gives number ways + * in which k objects can be chosen from n objects. + * Wikipedia: https://en.wikipedia.org/wiki/Binomial_coefficient + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +public final class BinomialCoefficient { + private BinomialCoefficient() { + } + + /** + * This method returns the number of ways in which k objects can be chosen from n objects + * + * @param totalObjects Total number of objects + * @param numberOfObjects Number of objects to be chosen from total_objects + * @return number of ways in which no_of_objects objects can be chosen from total_objects + * objects + */ + + public static int binomialCoefficient(int totalObjects, int numberOfObjects) { + // Base Case + if (numberOfObjects > totalObjects) { + return 0; + } + + // Base Case + if (numberOfObjects == 0 || numberOfObjects == totalObjects) { + return 1; + } + + // Recursive Call + return (binomialCoefficient(totalObjects - 1, numberOfObjects - 1) + binomialCoefficient(totalObjects - 1, numberOfObjects)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Ceil.java b/Java/src/main/java/com/thealgorithms/maths/Ceil.java new file mode 100644 index 000000000000..aacb9d969950 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Ceil.java @@ -0,0 +1,23 @@ +package com.thealgorithms.maths; + +public final class Ceil { + private Ceil() { + } + + /** + * 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/Java/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java b/Java/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java new file mode 100644 index 000000000000..f7010acf452d --- /dev/null +++ b/Java/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 final class CircularConvolutionFFT { + private 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<FFT.Complex> 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. + * + * <p> + * 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<FFT.Complex> fftCircularConvolution(ArrayList<FFT.Complex> a, ArrayList<FFT.Complex> 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<FFT.Complex> 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/Java/src/main/java/com/thealgorithms/maths/CollatzConjecture.java b/Java/src/main/java/com/thealgorithms/maths/CollatzConjecture.java new file mode 100644 index 000000000000..980dc89b716e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/CollatzConjecture.java @@ -0,0 +1,42 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.List; + +/** + * <a href="https://en.wikipedia.org/wiki/Collatz_conjecture">...</a> + */ +public class CollatzConjecture { + + /** + * Calculate the next number of the sequence. + * + * @param n current number of the sequence + * @return next number of the sequence + */ + public int nextNumber(final int n) { + if (n % 2 == 0) { + return n / 2; + } + return 3 * n + 1; + } + + /** + * Calculate the Collatz sequence of any natural number. + * + * @param firstNumber starting number of the sequence + * @return sequence of the Collatz Conjecture + */ + public List<Integer> collatzConjecture(int firstNumber) { + if (firstNumber < 1) { + throw new IllegalArgumentException("Must be a natural number"); + } + ArrayList<Integer> result = new ArrayList<>(); + result.add(firstNumber); + while (firstNumber != 1) { + result.add(nextNumber(firstNumber)); + firstNumber = nextNumber(firstNumber); + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Combinations.java b/Java/src/main/java/com/thealgorithms/maths/Combinations.java new file mode 100644 index 000000000000..2b4a78613190 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Combinations.java @@ -0,0 +1,61 @@ +package com.thealgorithms.maths; + +/** + * @see <a href="https://en.wikipedia.org/wiki/Combination">Combination</a> + */ +public final class Combinations { + private Combinations() { + } + + /** + * 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++) { + solution = (n - i) * solution / (i + 1); + } + return solution; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Convolution.java b/Java/src/main/java/com/thealgorithms/maths/Convolution.java new file mode 100644 index 000000000000..93e103f8c7cf --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Convolution.java @@ -0,0 +1,48 @@ +package com.thealgorithms.maths; + +/** + * Class for linear convolution of two discrete signals + * + * @author Ioannis Karavitsis + * @version 1.0 + */ +public final class Convolution { + private 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/Java/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java b/Java/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java new file mode 100644 index 000000000000..ce35b02ca13b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java @@ -0,0 +1,68 @@ +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 final class ConvolutionFFT { + private 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<FFT.Complex> 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. + * + * <p> + * 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<FFT.Complex> convolutionFFT(ArrayList<FFT.Complex> a, ArrayList<FFT.Complex> 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<FFT.Complex> 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/Java/src/main/java/com/thealgorithms/maths/CrossCorrelation.java b/Java/src/main/java/com/thealgorithms/maths/CrossCorrelation.java new file mode 100644 index 000000000000..eeb4d6d1717a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/CrossCorrelation.java @@ -0,0 +1,89 @@ +package com.thealgorithms.maths; + +/** + * Class for linear cross-correlation of two discrete signals + * + * @author Athina-Frederiki Swinkels + * @version 1.0 + */ + +public final class CrossCorrelation { + private CrossCorrelation() { + } + + /** + * Discrete linear cross-correlation function. + * Input and output signals have starting index 0. + * + * @param x The first discrete signal + * @param y The second discrete signal + * @return The result of the cross-correlation of signals x,y. The result is also a signal. + */ + public static double[] crossCorrelation(double[] x, double[] y) { + // The result signal's length is the sum of the input signals' lengths minus 1 + double[] result = new double[x.length + y.length - 1]; + int n = result.length; + + /* + To find the cross-correlation between 2 discrete signals x & y, we start by "placing" the second signal + y under the first signal x, shifted to the left so that the last value of y meets the first value of x + and for every new position (i++) of the result signal, we shift y signal one position to the right, until + the first y-value meets the last x-value. The result-value for each position is the sum of all x*y meeting + values. + Here's an example: + x=[1,2,1,1] + y=[1,1,2,1] + + i=0: [1,2,1,1] + [1,1,2,1] result[0]=1*1=1 + + i=1: [1,2,1,1] + [1,1,2,1] result[1]=1*2+2*1=4 + + i=2: [1,2,1,1] + [1,1,2,1] result[2]=1*1+2*2+1*1=6 + + i=3: [1,2,1,1] + [1,1,2,1] result[3]=1*1+2*1+1*2+1*1=6 + + i=4: [1,2,1,1] + [1,1,2,1] result[4]=2*1+1*1+1*2=5 + + i=5: [1,2,1,1] + [1,1,2,1] result[5]=1*1+1*1=2 + + i=1: [1,2,1,1] + [1,1,2,1] result[6]=1*1=1 + + result=[1,4,6,6,5,2,1] + + + + + To find the result[i] value for each i:0->n-1, the positions of x-signal in which the 2 signals meet + are calculated: kMin<=k<=kMax. + The variable 'yStart' indicates the starting index of y in each sum calculation. + The variable 'count' increases the index of y-signal by 1, to move to the next value. + */ + int yStart = y.length; + for (int i = 0; i < n; i++) { + result[i] = 0; + + int kMin = Math.max(i - (y.length - 1), 0); + int kMax = Math.min(i, x.length - 1); + + if (i < y.length) { + yStart--; + } + + int count = 0; + for (int k = kMin; k <= kMax; k++) { + result[i] += x[k] * y[yStart + count]; + count++; + } + } + + // The calculated cross-correlation of x & y signals is returned here. + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java b/Java/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java new file mode 100644 index 000000000000..a2a327117700 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java @@ -0,0 +1,61 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +/* + * @author Ojasva Jain + * Determinant of a Matrix Wikipedia link: https://en.wikipedia.org/wiki/Determinant + */ +public final class DeterminantOfMatrix { + private DeterminantOfMatrix() { + } + + // Determinant calculator + //@return determinant of the input matrix + static int determinant(int[][] a, int n) { + int det = 0; + int sign = 1; + int p = 0; + int 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 < n; i++) { + for (int j = 0; j < n; j++) { + a[i][j] = in.nextInt(); + } + } + System.out.println(determinant(a, n)); + in.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/DigitalRoot.java b/Java/src/main/java/com/thealgorithms/maths/DigitalRoot.java new file mode 100644 index 000000000000..84b33f34c393 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/DigitalRoot.java @@ -0,0 +1,69 @@ +/** + * Author : Suraj Kumar Modi + * https://github.com/skmodi649 + */ +/** + * You are given a number n. You need to find the digital root of n. + * DigitalRoot of a number is the recursive sum of its digits until we get a single digit number. + * + * Test Case 1: + * Input: + * n = 1 + * Output: 1 + * Explanation: Digital root of 1 is 1 + * + * Test Case 2: + * Input: + * n = 99999 + * Output: 9 + * Explanation: Sum of digits of 99999 is 45 + * which is not a single digit number, hence + * sum of digit of 45 is 9 which is a single + * digit number. + */ +/** + * Algorithm : + * Step 1 : Define a method digitalRoot(int n) + * Step 2 : Define another method single(int n) + * Step 3 : digitalRoot(int n) method takes output of single(int n) as input + * if(single(int n) <= 9) + * return single(n) + * else + * return digitalRoot(single(n)) + * Step 4 : single(int n) calculates the sum of digits of number n recursively + * if(n<=9) + * return n; + * else + * return (n%10) + (n/10) + * Step 5 : In main method simply take n as input and then call digitalRoot(int n) function and + * print the result + */ +package com.thealgorithms.maths; + +final class DigitalRoot { + private DigitalRoot() { + } + + public static int digitalRoot(int n) { + if (single(n) <= 9) { // If n is already single digit than simply call single method and + // return the value + return single(n); + } else { + return digitalRoot(single(n)); + } + } + + // This function is used for finding the sum of the digits of number + public static int single(int n) { + if (n <= 9) { // if n becomes less than 10 than return n + return n; + } else { + return (n % 10) + single(n / 10); // n % 10 for extracting digits one by one + } + } // n / 10 is the number obtained after removing the digit one by one + // The Sum of digits is stored in the Stack memory and then finally returned +} +/** + * Time Complexity: O((Number of Digits)^2) Auxiliary Space Complexity: + * O(Number of Digits) Constraints: 1 <= n <= 10^7 + */ diff --git a/Java/src/main/java/com/thealgorithms/maths/DistanceFormula.java b/Java/src/main/java/com/thealgorithms/maths/DistanceFormula.java new file mode 100644 index 000000000000..f7e2c7629551 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/DistanceFormula.java @@ -0,0 +1,47 @@ +package com.thealgorithms.maths; + +public final class DistanceFormula { + private DistanceFormula() { + } + + public static double euclideanDistance(double x1, double y1, double x2, double y2) { + double dX = Math.pow(x2 - x1, 2); + double dY = Math.pow(y2 - x1, 2); + return Math.sqrt(dX + dY); + } + + public static double manhattanDistance(double x1, double y1, double x2, double y2) { + return Math.abs(x1 - x2) + Math.abs(y1 - y2); + } + + public static int hammingDistance(int[] b1, int[] b2) { + int d = 0; + + if (b1.length != b2.length) { + return -1; // error, both arrays must have the same length + } + + for (int i = 0; i < b1.length; i++) { + d += Math.abs(b1[i] - b2[i]); + } + + return d; + } + + public static double minkowskiDistance(double[] p1, double[] p2, int p) { + double d = 0; + double distance = 0.0; + + if (p1.length != p2.length) { + return -1; // error, both arrays must have the same length + } + + for (int i = 0; i < p1.length; i++) { + distance += Math.abs(Math.pow(p1[i] - p2[i], p)); + } + + distance = Math.pow(distance, (double) 1 / p); + d = distance; + return d; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/DudeneyNumber.java b/Java/src/main/java/com/thealgorithms/maths/DudeneyNumber.java new file mode 100644 index 000000000000..acf1e55d49c8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/DudeneyNumber.java @@ -0,0 +1,28 @@ +/** + * 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; + +public final class DudeneyNumber { + private DudeneyNumber() { + } + + // returns True if the number is a Dudeney number and False if it is not a Dudeney number. + public static boolean isDudeney(final int n) { + if (n <= 0) { + throw new IllegalArgumentException("Input must me positive."); + } + // Calculating Cube Root + final int cubeRoot = (int) Math.round(Math.pow(n, 1.0 / 3.0)); + // If the number is not a perfect cube the method returns false. + if (cubeRoot * cubeRoot * cubeRoot != n) { + return false; + } + + // If the cube root of the number is not equal to the sum of its digits, we return false. + return cubeRoot == SumOfDigits.sumOfDigits(n); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/EulerMethod.java b/Java/src/main/java/com/thealgorithms/maths/EulerMethod.java new file mode 100644 index 000000000000..3663b6c534aa --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/EulerMethod.java @@ -0,0 +1,101 @@ +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 final class EulerMethod { + private 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<Double, Double, Double> exampleEquation1 = (x, y) -> x; + ArrayList<double[]> points1 = eulerFull(0, 4, 0.1, 0, exampleEquation1); + assert points1.get(points1.size() - 1)[1] == 7.800000000000003; + points1.forEach(point -> System.out.printf("x: %1$f; y: %2$f%n", point[0], point[1])); + + // example from https://en.wikipedia.org/wiki/Euler_method + System.out.println("\n\nexample 2:"); + BiFunction<Double, Double, Double> exampleEquation2 = (x, y) -> y; + ArrayList<double[]> points2 = eulerFull(0, 4, 0.1, 1, exampleEquation2); + assert points2.get(points2.size() - 1)[1] == 45.25925556817596; + points2.forEach(point -> System.out.printf("x: %1$f; y: %2$f%n", point[0], point[1])); + + // example from https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ + System.out.println("\n\nexample 3:"); + BiFunction<Double, Double, Double> exampleEquation3 = (x, y) -> x + y + x * y; + ArrayList<double[]> points3 = eulerFull(0, 0.1, 0.025, 1, exampleEquation3); + assert points3.get(points3.size() - 1)[1] == 1.1116729841674804; + points3.forEach(point -> System.out.printf("x: %1$f; y: %2$f%n", 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<Double, Double, Double> differentialEquation) { + if (stepSize <= 0) { + throw new IllegalArgumentException("stepSize should be greater than zero"); + } + return yCurrent + stepSize * differentialEquation.apply(xCurrent, yCurrent); + } + + /** + * 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<double[]> eulerFull(double xStart, double xEnd, double stepSize, double yStart, BiFunction<Double, Double, Double> 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<double[]> points = new ArrayList<double[]>(); + double[] firstPoint = {xStart, yStart}; + points.add(firstPoint); + double yCurrent = yStart; + double xCurrent = xStart; + + while (xCurrent < xEnd) { + // Euler's method for next step + yCurrent = eulerStep(xCurrent, stepSize, yCurrent, differentialEquation); + xCurrent += stepSize; + double[] point = {xCurrent, yCurrent}; + points.add(point); + } + + return points; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FFT.java b/Java/src/main/java/com/thealgorithms/maths/FFT.java new file mode 100644 index 000000000000..7ca7543d7985 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FFT.java @@ -0,0 +1,287 @@ +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 final class FFT { + private FFT() { + } + + /** + * This class represents a complex number and has methods for basic + * operations. + * + * <p> + * More info: + * https://introcs.cs.princeton.edu/java/32class/Complex.java.html + */ + static class Complex { + + private double real; + private double img; + + /** + * Default Constructor. Creates the complex number 0. + */ + 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. + */ + 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(); + double d = z.abs() * z.abs(); + d = (double) Math.round(d * 1000000000d) / 1000000000d; + temp.real = (this.real * z.real + this.img * z.img) / (d); + temp.img = (this.img * z.real - this.real * z.img) / (d); + 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. + * + * <p> + * 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. + * @return + */ + public static ArrayList<Complex> fft(ArrayList<Complex> x, boolean inverse) { + /* Pad the signal with zeros if necessary */ + paddingPowerOfTwo(x); + int n = x.size(); + int log2n = findLog2(n); + x = fftBitReversal(n, log2n, x); + 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); + } + } + } + x = inverseFFT(n, inverse, x); + return x; + } + + /* Find the log2(n) */ + public static int findLog2(int n) { + int log2n = 0; + while ((1 << log2n) < n) { + log2n++; + } + return log2n; + } + + /* Swap the values of the signal with bit-reversal method */ + public static ArrayList<Complex> fftBitReversal(int n, int log2n, ArrayList<Complex> x) { + int reverse; + for (int i = 0; i < n; i++) { + reverse = reverseBits(i, log2n); + if (i < reverse) { + Collections.swap(x, i, reverse); + } + } + return x; + } + + /* Divide by n if we want the inverse FFT */ + public static ArrayList<Complex> inverseFFT(int n, boolean inverse, ArrayList<Complex> x) { + if (inverse) { + for (int i = 0; i < x.size(); i++) { + Complex z = x.get(i); + x.set(i, z.divide(n)); + } + } + return x; + } + + /** + * This function reverses the bits of a number. It is used in Cooley-Tukey + * FFT algorithm. + * + * <p> + * E.g. num = 13 = 00001101 in binary log2n = 8 Then reversed = 176 = + * 10110000 in binary + * + * <p> + * 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<Complex> 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/Java/src/main/java/com/thealgorithms/maths/FFTBluestein.java b/Java/src/main/java/com/thealgorithms/maths/FFTBluestein.java new file mode 100644 index 000000000000..388de6fed3eb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FFTBluestein.java @@ -0,0 +1,70 @@ +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 final class FFTBluestein { + private FFTBluestein() { + } + + /** + * Bluestein's FFT Algorithm. + * + * <p> + * 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<FFT.Complex> x, boolean inverse) { + int n = x.size(); + int bnSize = 2 * n - 1; + int direction = inverse ? -1 : 1; + ArrayList<FFT.Complex> an = new ArrayList<>(); + ArrayList<FFT.Complex> 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<FFT.Complex> 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/Java/src/main/java/com/thealgorithms/maths/Factorial.java b/Java/src/main/java/com/thealgorithms/maths/Factorial.java new file mode 100644 index 000000000000..511cc1f84f05 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Factorial.java @@ -0,0 +1,23 @@ +package com.thealgorithms.maths; + +public final class Factorial { + private Factorial() { + } + + /** + * 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("Input number cannot be negative"); + } + long factorial = 1; + for (int i = 1; i <= n; ++i) { + factorial *= i; + } + return factorial; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FactorialRecursion.java b/Java/src/main/java/com/thealgorithms/maths/FactorialRecursion.java new file mode 100644 index 000000000000..d9bafd1e39e9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FactorialRecursion.java @@ -0,0 +1,18 @@ +package com.thealgorithms.maths; + +public final class FactorialRecursion { + private FactorialRecursion() { + } + /** + * 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/Java/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java b/Java/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java new file mode 100644 index 000000000000..a0dbfb1f70a4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java @@ -0,0 +1,58 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ + +/** Program description - To find out the inverse square root of the given number*/ + +/** Wikipedia Link - https://en.wikipedia.org/wiki/Fast_inverse_square_root */ + +package com.thealgorithms.maths; + +public final class FastInverseSqrt { + private FastInverseSqrt() { + } + + public static boolean inverseSqrt(float number) { + float x = number; + float xhalf = 0.5f * x; + int i = Float.floatToIntBits(x); + i = 0x5f3759df - (i >> 1); + x = Float.intBitsToFloat(i); + x = x * (1.5f - xhalf * x * x); + return x == ((float) 1 / (float) Math.sqrt(number)); + } + + /** + * Returns the inverse square root of the given number upto 6 - 8 decimal places. + * calculates the inverse square root of the given number and returns true if calculated answer + * matches with given answer else returns false + */ + + public static boolean inverseSqrt(double number) { + double x = number; + double xhalf = 0.5d * x; + long i = Double.doubleToLongBits(x); + i = 0x5fe6ec85e7de30daL - (i >> 1); + x = Double.longBitsToDouble(i); + for (int it = 0; it < 4; it++) { + x = x * (1.5d - xhalf * x * x); + } + x *= number; + return x == 1 / Math.sqrt(number); + } + /** + * Returns the inverse square root of the given number upto 14 - 16 decimal places. + * calculates the inverse square root of the given number and returns true if calculated answer + * matches with given answer else returns false + */ +} +/** + * OUTPUT : + * Input - number = 4522 + * Output: it calculates the inverse squareroot of a number and returns true with it matches the + * given answer else returns false. 1st approach Time Complexity : O(1) Auxiliary Space Complexity : + * O(1) Input - number = 4522 Output: it calculates the inverse squareroot of a number and returns + * true with it matches the given answer else returns false. 2nd approach Time Complexity : O(1) + * Auxiliary Space Complexity : O(1) + */ diff --git a/Java/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java b/Java/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java new file mode 100644 index 000000000000..72bae57c27b0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java @@ -0,0 +1,34 @@ +package com.thealgorithms.maths; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +/** + * @author: caos321 + * @date: 14 October 2021 (Thursday) + */ +public final class FibonacciJavaStreams { + private FibonacciJavaStreams() { + } + + public static Optional<BigDecimal> calculate(final BigDecimal index) { + if (index == null || index.compareTo(BigDecimal.ZERO) < 0) { + throw new IllegalArgumentException("Input index cannot be null or negative!"); + } + + if (index.compareTo(BigDecimal.ONE) < 0) { + return Optional.of(BigDecimal.ZERO); + } + + if (index.compareTo(new BigDecimal(2)) < 0) { + return Optional.of(BigDecimal.ONE); + } + + final List<BigDecimal> results = Stream.iterate(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))), (list1, list2) -> list1); + + return results.isEmpty() ? Optional.empty() : Optional.of(results.get(results.size() - 1)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FibonacciLoop.java b/Java/src/main/java/com/thealgorithms/maths/FibonacciLoop.java new file mode 100644 index 000000000000..de23a4305c3f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FibonacciLoop.java @@ -0,0 +1,41 @@ +package com.thealgorithms.maths; + +import java.math.BigInteger; + +/** + * This class provides methods for calculating Fibonacci numbers using BigInteger for large values of 'n'. + */ +public final class FibonacciLoop { + + private FibonacciLoop() { + // Private constructor to prevent instantiation of this utility class. + } + + /** + * Calculates the nth Fibonacci number. + * + * @param n The index of the Fibonacci number to calculate. + * @return The nth Fibonacci number as a BigInteger. + * @throws IllegalArgumentException if the input 'n' is a negative integer. + */ + public static BigInteger compute(final int n) { + if (n < 0) { + throw new IllegalArgumentException("Input 'n' must be a non-negative integer."); + } + + if (n <= 1) { + return BigInteger.valueOf(n); + } + + BigInteger prev = BigInteger.ZERO; + BigInteger current = BigInteger.ONE; + + for (int i = 2; i <= n; i++) { + BigInteger next = prev.add(current); + prev = current; + current = next; + } + + return current; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java b/Java/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java new file mode 100644 index 000000000000..781275d3130d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java @@ -0,0 +1,37 @@ +package com.thealgorithms.maths; + +/** + * Fibonacci: 0 1 1 2 3 5 8 13 21 ... + * This code checks Fibonacci Numbers up to 45th number. + * Other checks fail because of 'long'-type overflow. + */ +public final class FibonacciNumberCheck { + private FibonacciNumberCheck() { + } + /** + * Check if a number is perfect square number + * + * @param number the number to be checked + * @return <tt>true</tt> if {@code number} is a perfect square, otherwise + * <tt>false</tt> + */ + public static boolean isPerfectSquare(long number) { + long sqrt = (long) Math.sqrt(number); + return sqrt * sqrt == number; + } + + /** + * Check if a number is a 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 <tt>true</tt> if {@code number} is a Fibonacci number, otherwise + * <tt>false</tt> + * @link https://en.wikipedia.org/wiki/Fibonacci_number#Identification + */ + public static boolean isFibonacciNumber(long number) { + long value1 = 5 * number * number + 4; + long value2 = 5 * number * number - 4; + return isPerfectSquare(value1) || isPerfectSquare(value2); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java b/Java/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java new file mode 100644 index 000000000000..4df37a40f541 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FibonacciNumberGoldenRation.java @@ -0,0 +1,50 @@ +package com.thealgorithms.maths; + +/** + * This class provides methods for calculating Fibonacci numbers using Binet's formula. + * Binet's formula is based on the golden ratio and allows computing Fibonacci numbers efficiently. + * + * @see <a href="https://en.wikipedia.org/wiki/Fibonacci_sequence#Binet's_formula">Binet's formula on Wikipedia</a> + */ +public final class FibonacciNumberGoldenRation { + private FibonacciNumberGoldenRation() { + // Private constructor to prevent instantiation of this utility class. + } + + /** + * Compute the limit for 'n' that fits in a long data type. + * Reducing the limit to 70 due to potential floating-point arithmetic errors + * that may result in incorrect results for larger inputs. + */ + public static final int MAX_ARG = 70; + + /** + * Calculates the nth Fibonacci number using Binet's formula. + * + * @param n The index of the Fibonacci number to calculate. + * @return The nth Fibonacci number as a long. + * @throws IllegalArgumentException if the input 'n' is negative or exceeds the range of a long data type. + */ + public static long compute(int n) { + if (n < 0) { + throw new IllegalArgumentException("Input 'n' must be a non-negative integer."); + } + + if (n > MAX_ARG) { + throw new IllegalArgumentException("Input 'n' is too big to give accurate result."); + } + + if (n <= 1) { + return n; + } + + // Calculate the nth Fibonacci number using the golden ratio formula + final double sqrt5 = Math.sqrt(5); + final double phi = (1 + sqrt5) / 2; + final double psi = (1 - sqrt5) / 2; + final double result = (Math.pow(phi, n) - Math.pow(psi, n)) / sqrt5; + + // Round to the nearest integer and return as a long + return Math.round(result); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FindKthNumber.java b/Java/src/main/java/com/thealgorithms/maths/FindKthNumber.java new file mode 100644 index 000000000000..daea3f96332b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FindKthNumber.java @@ -0,0 +1,77 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; +import java.util.Random; + +/** + * use quick sort algorithm to get kth largest or kth smallest element in given array + */ +public final class FindKthNumber { + private FindKthNumber() { + } + + private static final Random RANDOM = new Random(); + + public static void main(String[] args) { + /* generate an array with random size and random elements */ + int[] nums = generateArray(100); + + /* get 3th largest element */ + int kth = 3; + int kthMaxIndex = nums.length - kth; + int targetMax = findKthMax(nums, kthMaxIndex); + + /* get 3th smallest element */ + int kthMinIndex = kth - 1; + int targetMin = findKthMax(nums, kthMinIndex); + + Arrays.sort(nums); + assert nums[kthMaxIndex] == targetMax; + assert nums[kthMinIndex] == targetMin; + } + + private static int[] generateArray(int capacity) { + int size = RANDOM.nextInt(capacity) + 1; + int[] array = new int[size]; + + for (int i = 0; i < size; i++) { + array[i] = RANDOM.nextInt() % 100; + } + return array; + } + + private static int findKthMax(int[] nums, int k) { + int start = 0; + int end = nums.length; + while (start < end) { + int pivot = partition(nums, start, end); + if (k == pivot) { + return nums[pivot]; + } else if (k > pivot) { + start = pivot + 1; + } else { + end = pivot; + } + } + return -1; + } + + private static int partition(int[] nums, int start, int end) { + int pivot = nums[start]; + int j = start; + for (int i = start + 1; i < end; i++) { + if (nums[i] < pivot) { + j++; + swap(nums, i, j); + } + } + swap(nums, start, j); + return j; + } + + private static void swap(int[] nums, int a, int b) { + int tmp = nums[a]; + nums[a] = nums[b]; + nums[b] = tmp; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FindMax.java b/Java/src/main/java/com/thealgorithms/maths/FindMax.java new file mode 100644 index 000000000000..0ff2bdd191ac --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FindMax.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +public final class FindMax { + private FindMax() { + } + + /** + * @brief finds the maximum value stored in the input array + * + * @param array the input array + * @exception IllegalArgumentException input array is empty + * @return the maximum value stored in the input array + */ + public static int findMax(final int[] array) { + int n = array.length; + if (n == 0) { + throw new IllegalArgumentException("Array must be non-empty."); + } + int max = array[0]; + for (int i = 1; i < n; i++) { + if (array[i] > max) { + max = array[i]; + } + } + return max; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java b/Java/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java new file mode 100644 index 000000000000..950a0ebe0085 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FindMaxRecursion.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +public final class FindMaxRecursion { + + private FindMaxRecursion() { + } + /** + * Get max of an 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(final int[] array, final int low, final int high) { + if (array.length == 0) { + throw new IllegalArgumentException("Array must be non-empty."); + } + 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 an array using recursion algorithm + * + * @param array contains elements + * @return max value of {@code array} + */ + public static int max(final int[] array) { + return max(array, 0, array.length - 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FindMin.java b/Java/src/main/java/com/thealgorithms/maths/FindMin.java new file mode 100644 index 000000000000..76fa2e815ee0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FindMin.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +public final class FindMin { + private FindMin() { + } + + /** + * @brief finds the minimum value stored in the input array + * + * @param array the input array + * @exception IllegalArgumentException input array is empty + * @return the mimum value stored in the input array + */ + public static int findMin(final int[] array) { + if (array.length == 0) { + throw new IllegalArgumentException("Array must be non-empty."); + } + int min = array[0]; + for (int i = 1; i < array.length; i++) { + if (array[i] < min) { + min = array[i]; + } + } + return min; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/FindMinRecursion.java b/Java/src/main/java/com/thealgorithms/maths/FindMinRecursion.java new file mode 100644 index 000000000000..a2cf1b36d6cb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FindMinRecursion.java @@ -0,0 +1,42 @@ +package com.thealgorithms.maths; + +public final class FindMinRecursion { + + private FindMinRecursion() { + } + + /** + * Get min of an 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(final int[] array, final int low, final int high) { + if (array.length == 0) { + throw new IllegalArgumentException("array must be non-empty."); + } + 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 an array using recursion algorithm + * + * @param array contains elements + * @return min value of {@code array} + */ + public static int min(final int[] array) { + return min(array, 0, array.length - 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Floor.java b/Java/src/main/java/com/thealgorithms/maths/Floor.java new file mode 100644 index 000000000000..271fc42d0d17 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Floor.java @@ -0,0 +1,24 @@ +package com.thealgorithms.maths; + +public final class Floor { + + private Floor() { + } + + /** + * 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/Java/src/main/java/com/thealgorithms/maths/FrizzyNumber.java b/Java/src/main/java/com/thealgorithms/maths/FrizzyNumber.java new file mode 100644 index 000000000000..3ae5e021df1b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/FrizzyNumber.java @@ -0,0 +1,34 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ + +/** Program description - To find the FrizzyNumber*/ + +package com.thealgorithms.maths; + +public final class FrizzyNumber { + private FrizzyNumber() { + } + + /** + * Returns the n-th number that is a sum of powers + * of the given base. + * Example: base = 3 and n = 4 + * Ascending order of sums of powers of 3 = + * 3^0 = 1, 3^1 = 3, 3^1 + 3^0 = 4, 3^2 + 3^0 = 9 + * Ans = 9 + * + * @param base The base whose n-th sum of powers is required + * @param n Index from ascending order of sum of powers of base + * @return n-th sum of powers of base + */ + public static double getNthFrizzy(int base, int n) { + double final1 = 0.0; + int i = 0; + do { + final1 += Math.pow(base, i++) * (n % 2); + } while ((n /= 2) > 0); + return final1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/GCD.java b/Java/src/main/java/com/thealgorithms/maths/GCD.java new file mode 100644 index 000000000000..5156e4ac881d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/GCD.java @@ -0,0 +1,59 @@ +package com.thealgorithms.maths; + +/** + * This is Euclid's algorithm, used to find the greatest common + * denominator Override function name gcd + * + * @author Oskar Enmalm 3/10/17 + */ +public final class GCD { + private GCD() { + } + + /** + * get the 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; + } + + /** + * @brief computes gcd of an array of numbers + * + * @param numbers the input array + * @return gcd of all of the numbers in the input array + */ + public static int gcd(int[] numbers) { + int result = 0; + for (final var number : numbers) { + result = gcd(result, number); + } + + 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/Java/src/main/java/com/thealgorithms/maths/GCDRecursion.java b/Java/src/main/java/com/thealgorithms/maths/GCDRecursion.java new file mode 100644 index 000000000000..e95ce97c8a04 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/GCDRecursion.java @@ -0,0 +1,41 @@ +package com.thealgorithms.maths; + +/** + * @author https://github.com/shellhub/ + */ +public final class GCDRecursion { + private 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/Java/src/main/java/com/thealgorithms/maths/Gaussian.java b/Java/src/main/java/com/thealgorithms/maths/Gaussian.java new file mode 100644 index 000000000000..cefbaea5b9b4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Gaussian.java @@ -0,0 +1,71 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; + +public final class Gaussian { + private Gaussian() { + } + + public static ArrayList<Double> gaussian(int matSize, ArrayList<Double> matrix) { + ArrayList<Double> answerArray = new ArrayList<Double>(); + int i; + int j = 0; + + double[][] mat = new double[matSize + 1][matSize + 1]; + double[][] x = new double[matSize][matSize + 1]; + + // Values from arraylist to matrix + for (i = 0; i < matSize; i++) { + for (j = 0; j <= matSize; j++) { + mat[i][j] = matrix.get(i); + } + } + + mat = gaussianElimination(matSize, i, mat); + answerArray = valueOfGaussian(matSize, x, mat); + return answerArray; + } + + // Perform Gaussian elimination + public static double[][] gaussianElimination(int matSize, int i, double[][] mat) { + int step = 0; + for (step = 0; step < matSize - 1; step++) { + for (i = step; i < matSize - 1; i++) { + double a = (mat[i + 1][step] / mat[step][step]); + + for (int j = step; j <= matSize; j++) { + mat[i + 1][j] = mat[i + 1][j] - (a * mat[step][j]); + } + } + } + return mat; + } + + // calculate the x_1, x_2, ... values of the gaussian and save it in an arraylist. + public static ArrayList<Double> valueOfGaussian(int matSize, double[][] x, double[][] mat) { + ArrayList<Double> answerArray = new ArrayList<Double>(); + int i; + int j; + + for (i = 0; i < matSize; i++) { + for (j = 0; j <= matSize; j++) { + x[i][j] = mat[i][j]; + } + } + + for (i = matSize - 1; i >= 0; i--) { + double sum = 0; + for (j = matSize - 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][matSize] - sum) / (x[i][i]); + } + answerArray.add(x[i][j]); + } + return answerArray; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/GenericRoot.java b/Java/src/main/java/com/thealgorithms/maths/GenericRoot.java new file mode 100644 index 000000000000..07f4756f93f8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/GenericRoot.java @@ -0,0 +1,30 @@ +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 final class GenericRoot { + private GenericRoot() { + } + + private static int base = 10; + + private static int sumOfDigits(final int n) { + assert n >= 0; + if (n < base) { + return n; + } + return n % base + sumOfDigits(n / base); + } + + public static int genericRoot(final int n) { + if (n < 0) { + return genericRoot(-n); + } + if (n > base) { + return genericRoot(sumOfDigits(n)); + } + return n; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/HarshadNumber.java b/Java/src/main/java/com/thealgorithms/maths/HarshadNumber.java new file mode 100644 index 000000000000..0b1ba1285c4d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/HarshadNumber.java @@ -0,0 +1,47 @@ +package com.thealgorithms.maths; + +// Wikipedia for Harshad Number : https://en.wikipedia.org/wiki/Harshad_number + +public final class HarshadNumber { + private HarshadNumber() { + } + + /** + * A function to check if a number is Harshad number or not + * + * @param n The number to be checked + * @return {@code true} if {@code a} is Harshad number, otherwise + * {@code false} + */ + public static boolean isHarshad(long n) { + if (n <= 0) return false; + + long t = n; + long sumOfDigits = 0; + while (t > 0) { + sumOfDigits += t % 10; + t /= 10; + } + + return n % sumOfDigits == 0; + } + + /** + * A function to check if a number is Harshad number or not + * + * @param s The number in String to be checked + * @return {@code true} if {@code a} is Harshad number, otherwise + * {@code false} + */ + public static boolean isHarshad(String s) { + final Long n = Long.valueOf(s); + if (n <= 0) return false; + + int sumOfDigits = 0; + for (char ch : s.toCharArray()) { + sumOfDigits += ch - '0'; + } + + return n % sumOfDigits == 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/HeronsFormula.java b/Java/src/main/java/com/thealgorithms/maths/HeronsFormula.java new file mode 100644 index 000000000000..5baee715d1ec --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/HeronsFormula.java @@ -0,0 +1,35 @@ +package com.thealgorithms.maths; + +/** + * Wikipedia for HeronsFormula => https://en.wikipedia.org/wiki/Heron%27s_formula + * Find the area of a triangle using only side lengths + */ + +public final class HeronsFormula { + + /* + * A function to get the Area of a Triangle using Heron's Formula + * @param s1,s2,s3 => the three sides of the Triangle + * @return area using the formula (√(s(s – s1)(s – s2)(s – s3))) + * here s is called semi-perimeter and it is the half of the perimeter (i.e; s = (s1+s2+s3)/2) + * @author satyabarghav + */ + private HeronsFormula() { + } + + private static boolean areAllSidesPositive(final double a, final double b, final double c) { + return a > 0 && b > 0 && c > 0; + } + + private static boolean canFormTriangle(final double a, final double b, final double c) { + return a + b > c && b + c > a && c + a > b; + } + + public static double herons(final double a, final double b, final double c) { + if (!areAllSidesPositive(a, b, c) || !canFormTriangle(a, b, c)) { + throw new IllegalArgumentException("Triangle can't be formed with the given side lengths"); + } + final double s = (a + b + c) / 2.0; + return Math.sqrt((s) * (s - a) * (s - b) * (s - c)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/JosephusProblem.java b/Java/src/main/java/com/thealgorithms/maths/JosephusProblem.java new file mode 100644 index 000000000000..7d19623b3ed0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/JosephusProblem.java @@ -0,0 +1,44 @@ +package com.thealgorithms.maths; + +/** + * There are n friends that are playing a game. The friends are sitting in a circle and are + * numbered from 1 to n in clockwise order. More formally, moving clockwise from the ith friend + * brings you to the (i+1)th friend for 1 <= i < n, and moving clockwise from the nth friend brings + * you to the 1st friend. + */ + +/** + The rules of the game are as follows: + + 1.Start at the 1st friend. + 2.Count the next k friends in the clockwise direction including the friend you started at. + The counting wraps around the circle and may count some friends more than once. 3.The last friend + you counted leaves the circle and loses the game. 4.If there is still more than one friend in the + circle, go back to step 2 starting from the friend immediately clockwise of the friend who just + lost and repeat. 5.Else, the last friend in the circle wins the game. + + @author Kunal + */ + +public final class JosephusProblem { + private JosephusProblem() { + } + + /** + * Find the Winner of the Circular Game. + * + * @param number of friends, n, and an integer k + * @return return the winner of the game + */ + + public static int findTheWinner(int n, int k) { + return winner(n, k) + 1; + } + + public static int winner(int n, int k) { + if (n == 1) { + return 0; + } + return (winner(n - 1, k) + k) % n; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/JugglerSequence.java b/Java/src/main/java/com/thealgorithms/maths/JugglerSequence.java new file mode 100644 index 000000000000..702310a1f295 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/JugglerSequence.java @@ -0,0 +1,54 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.List; + +/* + * Java program for printing juggler sequence + * Wikipedia: https://en.wikipedia.org/wiki/Juggler_sequence + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +public final class JugglerSequence { + private JugglerSequence() { + } + + /** + * This method prints juggler sequence starting with the number in the parameter + * + * @param inputNumber Number from which juggler sequence is to be started + */ + public static void jugglerSequence(int inputNumber) { + // Copy method argument to a local variable + int n = inputNumber; + List<String> seq = new ArrayList<>(); + seq.add(n + ""); + // Looping till n reaches 1 + while (n != 1) { + int temp; + // if previous term is even then + // next term in the sequence is square root of previous term + // if previous term is odd then + // next term is floor value of 3 time the square root of previous term + + // Check if previous term is even or odd + if (n % 2 == 0) { + temp = (int) Math.floor(Math.sqrt(n)); + } else { + temp = (int) Math.floor(Math.sqrt(n) * Math.sqrt(n) * Math.sqrt(n)); + } + n = temp; + seq.add(n + ""); + } + String res = String.join(",", seq); + System.out.println(res); + } + + // Driver code + public static void main(String[] args) { + jugglerSequence(3); + // Output: 3,5,11,36,6,2,1 + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java b/Java/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java new file mode 100644 index 000000000000..f025f86682a2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java @@ -0,0 +1,49 @@ +package com.thealgorithms.maths; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; + +public final class KaprekarNumbers { + private KaprekarNumbers() { + } + + /* This program demonstrates if a given number is Kaprekar Number or not. + Kaprekar Number: A Kaprekar number is an n-digit number which its square can be split into + two parts where the right part has n digits and sum of these parts is equal to the original + number. */ + + // Provides a list of kaprekarNumber in a range + public static List<Long> kaprekarNumberInRange(long start, long end) throws Exception { + long n = end - start; + if (n < 0) throw new Exception("Invalid range"); + ArrayList<Long> list = new ArrayList<>(); + + for (long i = start; i <= end; i++) { + if (isKaprekarNumber(i)) list.add(i); + } + + return list; + } + + // Checks whether a given number is Kaprekar Number or not + public static boolean isKaprekarNumber(long num) { + String number = Long.toString(num); + BigInteger originalNumber = BigInteger.valueOf(num); + BigInteger numberSquared = originalNumber.multiply(originalNumber); + if (number.length() == numberSquared.toString().length()) { + return number.equals(numberSquared.toString()); + } else { + BigInteger leftDigits1 = BigInteger.ZERO; + BigInteger leftDigits2; + if (numberSquared.toString().contains("0")) { + leftDigits1 = new BigInteger(numberSquared.toString().substring(0, numberSquared.toString().indexOf("0"))); + } + leftDigits2 = new BigInteger(numberSquared.toString().substring(0, (numberSquared.toString().length() - number.length()))); + BigInteger rightDigits = new BigInteger(numberSquared.toString().substring(numberSquared.toString().length() - number.length())); + String x = leftDigits1.add(rightDigits).toString(); + String y = leftDigits2.add(rightDigits).toString(); + return (number.equals(x)) || (number.equals(y)); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/KeithNumber.java b/Java/src/main/java/com/thealgorithms/maths/KeithNumber.java new file mode 100644 index 000000000000..1756cfbae91b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/KeithNumber.java @@ -0,0 +1,60 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Scanner; + +final class KeithNumber { + private KeithNumber() { + } + + // user-defined function that checks if the given number is Keith or not + static boolean isKeith(int x) { + // List stores all the digits of the X + ArrayList<Integer> terms = new ArrayList<>(); + // n denotes the number of digits + int temp = x; + int n = 0; + // executes until the condition becomes false + while (temp > 0) { + // determines the last digit of the number and add it to the List + terms.add(temp % 10); + // removes the last digit + temp = temp / 10; + // increments the number of digits (n) by 1 + n++; + } + // reverse the List + Collections.reverse(terms); + int nextTerm = 0; + int i = n; + // finds next term for the series + // loop executes until the condition returns true + while (nextTerm < x) { + nextTerm = 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++) { + nextTerm = nextTerm + terms.get(i - j); + } + terms.add(nextTerm); + i++; + } + // when the control comes out of the while loop, there will be two conditions: + // either nextTerm will be equal to x or greater than x + // if equal, the given number is Keith, else not + return (nextTerm == x); + } + + // driver code + 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."); + } + in.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java b/Java/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java new file mode 100644 index 000000000000..f5ff50337bc7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java @@ -0,0 +1,57 @@ +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.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public final class KrishnamurthyNumber { + private 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 + return tmp == s; + } + } + + 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/Java/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java b/Java/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java new file mode 100644 index 000000000000..db79340f0a99 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java @@ -0,0 +1,56 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +/** + * Is a common mathematics concept to find the smallest value number + * that can be divide using either number without having the remainder. + * https://maticschool.blogspot.com/2013/11/find-least-common-multiple-lcm.html + * @author LauKinHoong + */ + +public final class LeastCommonMultiple { + private LeastCommonMultiple() { + } + + /** + * Driver Code + */ + public static void main(String[] args) { + Scanner input = new Scanner(System.in); + System.out.println("Please enter first number >> "); + int num1 = input.nextInt(); + System.out.println("Please enter second number >> "); + int num2 = input.nextInt(); + System.out.println("The least common multiple of two numbers is >> " + lcm(num1, num2)); + input.close(); + } + + /* + * get least common multiple from two number + */ + public static int lcm(int num1, int num2) { + int high; + int num3; + int cmv = 0; + /* + * value selection for the numerator + */ + if (num1 > num2) { + high = num1; + num3 = num1; + } else { + high = num2; + num3 = num2; + } + + while (num1 != 0) { + if (high % num1 == 0 && high % num2 == 0) { + cmv = high; + break; + } + high += num3; + } + return cmv; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/LeonardoNumber.java b/Java/src/main/java/com/thealgorithms/maths/LeonardoNumber.java new file mode 100644 index 000000000000..bbeec052777f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/LeonardoNumber.java @@ -0,0 +1,25 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Leonardo_number + */ +public final class LeonardoNumber { + private LeonardoNumber() { + } + + /** + * Calculate nth Leonardo Number (1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, ...) + * + * @param n the index of Leonardo Number to calculate + * @return nth number of Leonardo sequences + */ + public static int leonardoNumber(int n) { + if (n < 0) { + throw new ArithmeticException(); + } + if (n == 0 || n == 1) { + return 1; + } + return (leonardoNumber(n - 1) + leonardoNumber(n - 2) + 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java b/Java/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java new file mode 100644 index 000000000000..a50cfb218283 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java @@ -0,0 +1,151 @@ +package com.thealgorithms.maths; + +import java.util.Objects; + +public final class LinearDiophantineEquationsSolver { + private LinearDiophantineEquationsSolver() { + } + + public static void main(String[] args) { + // 3x + 4y = 7 + final var toSolve = new Equation(3, 4, 7); + System.out.println(findAnySolution(toSolve)); + } + + public static Solution findAnySolution(final Equation equation) { + if (equation.a() == 0 && equation.b() == 0 && equation.c() == 0) { + return Solution.INFINITE_SOLUTIONS; + } + final var stub = new GcdSolutionWrapper(0, new Solution(0, 0)); + final var gcdSolution = gcd(equation.a(), equation.b(), stub); + if (equation.c() % gcdSolution.getGcd() != 0) { + return Solution.NO_SOLUTION; + } + final var toReturn = new Solution(0, 0); + var xToSet = stub.getSolution().getX() * (equation.c() / stub.getGcd()); + var yToSet = stub.getSolution().getY() * (equation.c() / stub.getGcd()); + toReturn.setX(xToSet); + toReturn.setY(yToSet); + return toReturn; + } + + private static GcdSolutionWrapper gcd(final int a, final int b, final GcdSolutionWrapper previous) { + if (b == 0) { + return new GcdSolutionWrapper(a, new Solution(1, 0)); + } + // stub wrapper becomes the `previous` of the next recursive call + final var stubWrapper = new GcdSolutionWrapper(0, new Solution(0, 0)); + final var next = /* recursive call */ gcd(b, a % b, stubWrapper); + previous.getSolution().setX(next.getSolution().getY()); + previous.getSolution().setY(next.getSolution().getX() - (a / b) * (next.getSolution().getY())); + previous.setGcd(next.getGcd()); + return new GcdSolutionWrapper(next.getGcd(), previous.getSolution()); + } + + 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; + private int y; + + public Solution(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public void setX(int x) { + this.x = x; + } + + public void setY(int y) { + this.y = y; + } + + @Override + public boolean equals(Object obj) { + 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; + } + + @Override + public int hashCode() { + return Objects.hash(x, y); + } + + @Override + public String toString() { + 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; + + public GcdSolutionWrapper(int gcd, Solution solution) { + this.gcd = gcd; + this.solution = solution; + } + + @Override + public boolean equals(Object obj) { + 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)); + } + + public int getGcd() { + return gcd; + } + + public void setGcd(int gcd) { + this.gcd = gcd; + } + + public Solution getSolution() { + return solution; + } + + public void setSolution(Solution solution) { + this.solution = solution; + } + + @Override + public int hashCode() { + return Objects.hash(gcd, solution); + } + + @Override + public String toString() { + return ("GcdSolutionWrapper[" + + "gcd=" + gcd + ", " + + "solution=" + solution + ']'); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java b/Java/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java new file mode 100644 index 000000000000..c0f55f5e3485 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +/* + * Java program for liouville lambda function + * For any positive integer n, define λ(n) as the sum of the primitive nth roots of unity. + * It has values in {−1, 1} depending on the factorization of n into prime factors: + * λ(n) = +1 if n is a positive integer with an even number of prime factors. + * λ(n) = −1 if n is a positive integer with an odd number of prime factors. + * Wikipedia: https://en.wikipedia.org/wiki/Liouville_function + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +public final class LiouvilleLambdaFunction { + private LiouvilleLambdaFunction() { + } + + /** + * This method returns λ(n) of given number n + * + * @param number Integer value which λ(n) is to be calculated + * @return 1 when number has even number of prime factors + * -1 when number has odd number of prime factors + * @throws IllegalArgumentException when number is negative + */ + static int liouvilleLambda(int number) { + if (number <= 0) { + // throw exception when number is less than or is zero + throw new IllegalArgumentException("Number must be greater than zero."); + } + + // return 1 if size of prime factor list is even, -1 otherwise + return PrimeFactorization.pfactors(number).size() % 2 == 0 ? 1 : -1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/LongDivision.java b/Java/src/main/java/com/thealgorithms/maths/LongDivision.java new file mode 100644 index 000000000000..45e97b1c14c3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/LongDivision.java @@ -0,0 +1,83 @@ +// Given two integers dividend and divisor, divide two integers without using multiplication, +// division, and mod operator. +// +// The integer division should truncate toward zero, which means losing its fractional part. +// For example, 8.345 would be truncated to 8, and -2.7335 would be truncated to -2. My +// method used Long Division, here is the source +// "https://en.wikipedia.org/wiki/Long_division" + +package com.thealgorithms.maths; + +public final class LongDivision { + private LongDivision() { + } + public static int divide(int dividend, int divisor) { + long newDividend1 = dividend; + long newDivisor1 = divisor; + + if (divisor == 0) { + return 0; + } + if (dividend < 0) { + newDividend1 = newDividend1 * -1; + } + if (divisor < 0) { + newDivisor1 = newDivisor1 * -1; + } + + if (dividend == 0 || newDividend1 < newDivisor1) { + return 0; + } + + StringBuilder answer = new StringBuilder(); + + String dividendString = "" + newDividend1; + int lastIndex = 0; + + String remainder = ""; + + for (int i = 0; i < dividendString.length(); i++) { + String partV1 = remainder + "" + dividendString.substring(lastIndex, i + 1); + long part1 = Long.parseLong(partV1); + if (part1 > newDivisor1) { + int quotient = 0; + while (part1 >= newDivisor1) { + part1 = part1 - newDivisor1; + quotient++; + } + answer.append(quotient); + } else if (part1 == newDivisor1) { + int quotient = 0; + while (part1 >= newDivisor1) { + part1 = part1 - newDivisor1; + quotient++; + } + answer.append(quotient); + } else if (part1 == 0) { + answer.append(0); + } else if (part1 < newDivisor1) { + answer.append(0); + } + if (!(part1 == 0)) { + remainder = String.valueOf(part1); + } else { + remainder = ""; + } + + lastIndex++; + } + + if ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)) { + try { + return Integer.parseInt(answer.toString()) * (-1); + } catch (NumberFormatException e) { + return -2147483648; + } + } + try { + return Integer.parseInt(answer.toString()); + } catch (NumberFormatException e) { + return 2147483647; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/LucasSeries.java b/Java/src/main/java/com/thealgorithms/maths/LucasSeries.java new file mode 100644 index 000000000000..e277c511f317 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/LucasSeries.java @@ -0,0 +1,38 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Lucas_number + */ +public final class LucasSeries { + private LucasSeries() { + } + + /** + * 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/Java/src/main/java/com/thealgorithms/maths/MagicSquare.java b/Java/src/main/java/com/thealgorithms/maths/MagicSquare.java new file mode 100644 index 000000000000..de0afc148982 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MagicSquare.java @@ -0,0 +1,52 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +/*A magic square of order n is an arrangement of distinct n^2 integers,in a square, such that the n +numbers in all rows, all columns, and both diagonals sum to the same constant. A magic square +contains the integers from 1 to n^2.*/ +public final class MagicSquare { + private MagicSquare() { + } + + 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)) { + System.out.print("Input number must be odd and >0"); + System.exit(0); + } + + int[][] magicSquare = new int[num][num]; + + int rowNum = num / 2; + int colNum = num - 1; + magicSquare[rowNum][colNum] = 1; + + for (int i = 2; i <= num * num; i++) { + if (magicSquare[(rowNum - 1 + num) % num][(colNum + 1) % num] == 0) { + rowNum = (rowNum - 1 + num) % num; + colNum = (colNum + 1) % num; + } else { + colNum = (colNum - 1 + num) % num; + } + magicSquare[rowNum][colNum] = i; + } + + // print the square + for (int i = 0; i < num; i++) { + for (int j = 0; j < num; j++) { + if (magicSquare[i][j] < 10) { + System.out.print(" "); + } + if (magicSquare[i][j] < 100) { + System.out.print(" "); + } + System.out.print(magicSquare[i][j] + " "); + } + System.out.println(); + } + sc.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/MatrixRank.java b/Java/src/main/java/com/thealgorithms/maths/MatrixRank.java new file mode 100644 index 000000000000..7a628b92dccb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MatrixRank.java @@ -0,0 +1,164 @@ +package com.thealgorithms.maths; + +/** + * This class provides a method to compute the rank of a matrix. + * In linear algebra, the rank of a matrix is the maximum number of linearly independent rows or columns in the matrix. + * For example, consider the following 3x3 matrix: + * 1 2 3 + * 2 4 6 + * 3 6 9 + * Despite having 3 rows and 3 columns, this matrix only has a rank of 1 because all rows (and columns) are multiples of each other. + * It's a fundamental concept that gives key insights into the structure of the matrix. + * It's important to note that the rank is not only defined for square matrices but for any m x n matrix. + * + * @author Anup Omkar + */ +public final class MatrixRank { + + private MatrixRank() { + } + + private static final double EPSILON = 1e-10; + + /** + * @brief Computes the rank of the input matrix + * + * @param matrix The input matrix + * @return The rank of the input matrix + */ + public static int computeRank(double[][] matrix) { + validateInputMatrix(matrix); + + int numRows = matrix.length; + int numColumns = matrix[0].length; + int rank = 0; + + boolean[] rowMarked = new boolean[numRows]; + + double[][] matrixCopy = deepCopy(matrix); + + for (int colIndex = 0; colIndex < numColumns; ++colIndex) { + int pivotRow = findPivotRow(matrixCopy, rowMarked, colIndex); + if (pivotRow != numRows) { + ++rank; + rowMarked[pivotRow] = true; + normalizePivotRow(matrixCopy, pivotRow, colIndex); + eliminateRows(matrixCopy, pivotRow, colIndex); + } + } + return rank; + } + + private static boolean isZero(double value) { + return Math.abs(value) < EPSILON; + } + + private static double[][] deepCopy(double[][] matrix) { + int numRows = matrix.length; + int numColumns = matrix[0].length; + double[][] matrixCopy = new double[numRows][numColumns]; + for (int rowIndex = 0; rowIndex < numRows; ++rowIndex) { + System.arraycopy(matrix[rowIndex], 0, matrixCopy[rowIndex], 0, numColumns); + } + return matrixCopy; + } + + private static void validateInputMatrix(double[][] matrix) { + if (matrix == null) { + throw new IllegalArgumentException("The input matrix cannot be null"); + } + if (matrix.length == 0) { + throw new IllegalArgumentException("The input matrix cannot be empty"); + } + if (!hasValidRows(matrix)) { + throw new IllegalArgumentException("The input matrix cannot have null or empty rows"); + } + if (isJaggedMatrix(matrix)) { + throw new IllegalArgumentException("The input matrix cannot be jagged"); + } + } + + private static boolean hasValidRows(double[][] matrix) { + for (double[] row : matrix) { + if (row == null || row.length == 0) { + return false; + } + } + return true; + } + + /** + * @brief Checks if the input matrix is a jagged matrix. + * Jagged matrix is a matrix where the number of columns in each row is not the same. + * + * @param matrix The input matrix + * @return True if the input matrix is a jagged matrix, false otherwise + */ + private static boolean isJaggedMatrix(double[][] matrix) { + int numColumns = matrix[0].length; + for (double[] row : matrix) { + if (row.length != numColumns) { + return true; + } + } + return false; + } + + /** + * @brief The pivot row is the row in the matrix that is used to eliminate other rows and reduce the matrix to its row echelon form. + * The pivot row is selected as the first row (from top to bottom) where the value in the current column (the pivot column) is not zero. + * This row is then used to "eliminate" other rows, by subtracting multiples of the pivot row from them, so that all other entries in the pivot column become zero. + * This process is repeated for each column, each time selecting a new pivot row, until the matrix is in row echelon form. + * The number of pivot rows (rows with a leading entry, or pivot) then gives the rank of the matrix. + * + * @param matrix The input matrix + * @param rowMarked An array indicating which rows have been marked + * @param colIndex The column index + * @return The pivot row index, or the number of rows if no suitable pivot row was found + */ + private static int findPivotRow(double[][] matrix, boolean[] rowMarked, int colIndex) { + int numRows = matrix.length; + for (int pivotRow = 0; pivotRow < numRows; ++pivotRow) { + if (!rowMarked[pivotRow] && !isZero(matrix[pivotRow][colIndex])) { + return pivotRow; + } + } + return numRows; + } + + /** + * @brief This method divides all values in the pivot row by the value in the given column. + * This ensures that the pivot value itself will be 1, which simplifies further calculations. + * + * @param matrix The input matrix + * @param pivotRow The pivot row index + * @param colIndex The column index + */ + private static void normalizePivotRow(double[][] matrix, int pivotRow, int colIndex) { + int numColumns = matrix[0].length; + for (int nextCol = colIndex + 1; nextCol < numColumns; ++nextCol) { + matrix[pivotRow][nextCol] /= matrix[pivotRow][colIndex]; + } + } + + /** + * @brief This method subtracts multiples of the pivot row from all other rows, + * so that all values in the given column of other rows will be zero. + * This is a key step in reducing the matrix to row echelon form. + * + * @param matrix The input matrix + * @param pivotRow The pivot row index + * @param colIndex The column index + */ + private static void eliminateRows(double[][] matrix, int pivotRow, int colIndex) { + int numRows = matrix.length; + int numColumns = matrix[0].length; + for (int otherRow = 0; otherRow < numRows; ++otherRow) { + if (otherRow != pivotRow && !isZero(matrix[otherRow][colIndex])) { + for (int col2 = colIndex + 1; col2 < numColumns; ++col2) { + matrix[otherRow][col2] -= matrix[pivotRow][col2] * matrix[otherRow][colIndex]; + } + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/MatrixUtil.java b/Java/src/main/java/com/thealgorithms/maths/MatrixUtil.java new file mode 100644 index 000000000000..0759853d61a9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MatrixUtil.java @@ -0,0 +1,159 @@ +package com.thealgorithms.maths; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Objects; +import java.util.Optional; +import java.util.function.BiFunction; +import java.util.stream.IntStream; + +/** + * @author: caos321 + * @date: 31 October 2021 (Sunday) + */ +public final class MatrixUtil { + private MatrixUtil() { + } + + public static boolean isValid(final BigDecimal[][] matrix) { + return matrix != null && matrix.length > 0 && matrix[0].length > 0; + } + + public static boolean hasEqualSizes(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { + return (isValid(matrix1) && isValid(matrix2) && matrix1.length == matrix2.length && matrix1[0].length == matrix2[0].length); + } + + public static boolean canMultiply(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { + return (isValid(matrix1) && isValid(matrix2) && matrix1[0].length == matrix2.length); + } + + public static Optional<BigDecimal[][]> operate(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2, final BiFunction<BigDecimal, BigDecimal, BigDecimal> operation) { + if (!hasEqualSizes(matrix1, matrix2)) { + return Optional.empty(); + } + + final int rowSize = matrix1.length; + final int columnSize = matrix1[0].length; + + final BigDecimal[][] result = new BigDecimal[rowSize][columnSize]; + + IntStream.range(0, rowSize).forEach(rowIndex -> IntStream.range(0, columnSize).forEach(columnIndex -> { + final BigDecimal value1 = matrix1[rowIndex][columnIndex]; + final BigDecimal value2 = matrix2[rowIndex][columnIndex]; + + result[rowIndex][columnIndex] = operation.apply(value1, value2); + })); + + return Optional.of(result); + } + + public static Optional<BigDecimal[][]> add(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { + return operate(matrix1, matrix2, BigDecimal::add); + } + + public static Optional<BigDecimal[][]> subtract(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { + return operate(matrix1, matrix2, BigDecimal::subtract); + } + + public static Optional<BigDecimal[][]> multiply(final BigDecimal[][] matrix1, final BigDecimal[][] matrix2) { + if (!canMultiply(matrix1, matrix2)) { + return Optional.empty(); + } + + final int size = matrix1[0].length; + + final int matrix1RowSize = matrix1.length; + final int matrix2ColumnSize = matrix2[0].length; + + 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]; + + return value1.multiply(value2); + }) + .reduce(BigDecimal.ZERO, BigDecimal::add))); + + return Optional.of(result); + } + + public static void assertThat(final BigDecimal[][] actual, final BigDecimal[][] expected) { + if (!Objects.deepEquals(actual, expected)) { + throw new AssertionError(String.format("expected=%s but was actual=%s", Arrays.deepToString(expected), Arrays.deepToString(actual))); + } + } + + public static void main(final String[] args) { + { + final BigDecimal[][] matrix1 = { + {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)}, + }; + + 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)}, + }; + + assertThat(actual, expected); + } + + { + final BigDecimal[][] matrix1 = { + {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)}, + }; + + 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)}, + }; + + assertThat(actual, expected); + } + + { + 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)}, + }; + + final BigDecimal[][] matrix2 = { + {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)}, + }; + + assertThat(actual, expected); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/MaxValue.java b/Java/src/main/java/com/thealgorithms/maths/MaxValue.java new file mode 100644 index 000000000000..d88291060f51 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MaxValue.java @@ -0,0 +1,18 @@ +package com.thealgorithms.maths; + +public final class MaxValue { + private MaxValue() { + } + /** + * 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/Java/src/main/java/com/thealgorithms/maths/Means.java b/Java/src/main/java/com/thealgorithms/maths/Means.java new file mode 100644 index 000000000000..dccc820b172e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Means.java @@ -0,0 +1,54 @@ +package com.thealgorithms.maths; + +import java.util.stream.StreamSupport; +import org.apache.commons.collections4.IterableUtils; + +/** + * https://en.wikipedia.org/wiki/Mean + * <p> + * by: Punit Patel + */ +public final class Means { + + private Means() { + } + + /** + * @brief computes the [Arithmetic Mean](https://en.wikipedia.org/wiki/Arithmetic_mean) of the input + * @param numbers the input numbers + * @throws IllegalArgumentException empty input + * @return the arithmetic mean of the input numbers + */ + public static Double arithmetic(final Iterable<Double> numbers) { + checkIfNotEmpty(numbers); + return StreamSupport.stream(numbers.spliterator(), false).reduce((x, y) -> x + y).get() / IterableUtils.size(numbers); + } + + /** + * @brief computes the [Geometric Mean](https://en.wikipedia.org/wiki/Geometric_mean) of the input + * @param numbers the input numbers + * @throws IllegalArgumentException empty input + * @return the geometric mean of the input numbers + */ + public static Double geometric(final Iterable<Double> numbers) { + checkIfNotEmpty(numbers); + return Math.pow(StreamSupport.stream(numbers.spliterator(), false).reduce((x, y) -> x * y).get(), 1d / IterableUtils.size(numbers)); + } + + /** + * @brief computes the [Harmonic Mean](https://en.wikipedia.org/wiki/Harmonic_mean) of the input + * @param numbers the input numbers + * @throws IllegalArgumentException empty input + * @return the harmonic mean of the input numbers + */ + public static Double harmonic(final Iterable<Double> numbers) { + checkIfNotEmpty(numbers); + return IterableUtils.size(numbers) / StreamSupport.stream(numbers.spliterator(), false).reduce(0d, (x, y) -> x + 1d / y); + } + + private static void checkIfNotEmpty(final Iterable<Double> numbers) { + if (!numbers.iterator().hasNext()) { + throw new IllegalArgumentException("Emtpy list given for Mean computation."); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Median.java b/Java/src/main/java/com/thealgorithms/maths/Median.java new file mode 100644 index 000000000000..e4daec8fc11a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Median.java @@ -0,0 +1,22 @@ +package com.thealgorithms.maths; + +import java.util.Arrays; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Median + */ +public final class Median { + private Median() { + } + + /** + * Calculate average median + * @param values sorted numbers to find median of + * @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/Java/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java b/Java/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java new file mode 100644 index 000000000000..e25836f713a9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java @@ -0,0 +1,104 @@ +package com.thealgorithms.maths; + +import java.util.Random; + +public final class MillerRabinPrimalityCheck { + private MillerRabinPrimalityCheck() { + } + + /** + * Check whether the given number is prime or not + * MillerRabin algorithm is probabilistic. There is also an altered version which is deterministic. + * https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test + * https://cp-algorithms.com/algebra/primality_tests.html + * + * @param n Whole number which is tested on primality + * @param k Number of iterations + * If n is composite then running k iterations of the Miller–Rabin + * test will declare n probably prime with a probability at most 4^(−k) + * @return true or false whether the given number is probably prime or not + */ + + public static boolean millerRabin(long n, int k) { // returns true if n is probably prime, else returns false. + if (n < 4) return n == 2 || n == 3; + + int s = 0; + long d = n - 1; + while ((d & 1) == 0) { + d >>= 1; + s++; + } + Random rnd = new Random(); + for (int i = 0; i < k; i++) { + long a = 2 + rnd.nextLong(n) % (n - 3); + if (checkComposite(n, a, d, s)) return false; + } + return true; + } + + public static boolean deterministicMillerRabin(long n) { // returns true if n is prime, else returns false. + if (n < 2) return false; + + int r = 0; + long d = n - 1; + while ((d & 1) == 0) { + d >>= 1; + r++; + } + + for (int a : new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { + if (n == a) return true; + if (checkComposite(n, a, d, r)) return false; + } + return true; + } + + /** + * Check if number n is composite (probabilistic) + * + * @param n Whole number which is tested for compositeness + * @param a Random number (prime base) to check if it holds certain equality + * @param d Number which holds this equation: 'n - 1 = 2^s * d' + * @param s Number of twos in (n - 1) factorization + * + * @return true or false whether the numbers hold the equation or not + * the equations are described on the websites mentioned at the beginning of the class + */ + private static boolean checkComposite(long n, long a, long d, int s) { + long x = powerModP(a, d, n); + if (x == 1 || x == n - 1) return false; + for (int r = 1; r < s; r++) { + x = powerModP(x, 2, n); + if (x == n - 1) return false; + } + return true; + } + + private static long powerModP(long x, long y, long p) { + long res = 1; // Initialize result + + x = x % p; // Update x if it is more than or equal to p + + if (x == 0) return 0; // In case x is divisible by p; + + while (y > 0) { + // If y is odd, multiply x with result + if ((y & 1) == 1) res = multiplyModP(res, x, p); + + // y must be even now + y = y >> 1; // y = y/2 + x = multiplyModP(x, x, p); + } + return res; + } + + private static long multiplyModP(long a, long b, long p) { + long aHi = a >> 24; + long aLo = a & ((1 << 24) - 1); + long bHi = b >> 24; + long bLo = b & ((1 << 24) - 1); + long result = ((((aHi * bHi << 16) % p) << 16) % p) << 16; + result += ((aLo * bHi + aHi * bLo) << 24) + aLo * bLo; + return result % p; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/MinValue.java b/Java/src/main/java/com/thealgorithms/maths/MinValue.java new file mode 100644 index 000000000000..88e28e8816c6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MinValue.java @@ -0,0 +1,18 @@ +package com.thealgorithms.maths; + +public final class MinValue { + private MinValue() { + } + /** + * 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/Java/src/main/java/com/thealgorithms/maths/MobiusFunction.java b/Java/src/main/java/com/thealgorithms/maths/MobiusFunction.java new file mode 100644 index 000000000000..915d0d9a6dae --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/MobiusFunction.java @@ -0,0 +1,57 @@ +package com.thealgorithms.maths; + +/* + * Java program for mobius function + * For any positive integer n, define μ(n) as the sum of the primitive nth roots of unity. + * It has values in {−1, 0, 1} depending on the factorization of n into prime factors: + * μ(n) = +1 if n is a square-free positive integer with an even number of prime factors. + * μ(n) = −1 if n is a square-free positive integer with an odd number of prime factors. + * μ(n) = 0 if n has a squared prime factor. + * Wikipedia: https://en.wikipedia.org/wiki/M%C3%B6bius_function + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ +public final class MobiusFunction { + private MobiusFunction() { + } + + /** + * This method returns μ(n) of given number n + * + * @param number Integer value which μ(n) is to be calculated + * @return 1 when number is less than or equals 1 + * or number has even number of prime factors + * 0 when number has repeated prime factor + * -1 when number has odd number of prime factors + */ + static int mobius(int number) { + if (number <= 0) { + // throw exception when number is less than or is zero + throw new IllegalArgumentException("Number must be greater than zero."); + } + + if (number == 1) { + // return 1 if number passed is less or is 1 + return 1; + } + + int primeFactorCount = 0; + + for (int i = 1; i <= number; i++) { + // find prime factors of number + if (number % i == 0 && PrimeCheck.isPrime(i)) { + // check if number is divisible by square of prime factor + if (number % (i * i) == 0) { + // if number is divisible by square of prime factor + return 0; + } + /*increment primeFactorCount by 1 + if number is not divisible by square of found prime factor*/ + primeFactorCount++; + } + } + + return (primeFactorCount % 2 == 0) ? 1 : -1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Mode.java b/Java/src/main/java/com/thealgorithms/maths/Mode.java new file mode 100644 index 000000000000..a92f404c653a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Mode.java @@ -0,0 +1,48 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +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 final class Mode { + private Mode() { + } + + /* + * Find the mode of an array of integers + * + * @param numbers array of integers + * @return mode of the array + */ + public static int[] mode(final int[] numbers) { + if (numbers.length == 0) { + return null; + } + + HashMap<Integer, Integer> 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<Integer> 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/Java/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java b/Java/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java new file mode 100644 index 000000000000..5f1190d67de0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java @@ -0,0 +1,76 @@ +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 final class NonRepeatingElement { + private NonRepeatingElement() { + } + + public static void main(String[] args) { + try (Scanner sc = new Scanner(System.in)) { + int i; + int 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(); + } + + // 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; + int 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/Java/src/main/java/com/thealgorithms/maths/NthUglyNumber.java b/Java/src/main/java/com/thealgorithms/maths/NthUglyNumber.java new file mode 100644 index 000000000000..103ff504ad14 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/NthUglyNumber.java @@ -0,0 +1,80 @@ +package com.thealgorithms.maths; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +/** + * @brief class computing the n-th ugly number (when they are sorted) + * @details the ugly numbers with base [2, 3, 5] are all numbers of the form 2^a*3^b^5^c, + * where the exponents a, b, c are non-negative integers. + * Some properties of ugly numbers: + * - base [2, 3, 5] ugly numbers are the 5-smooth numbers, cf. https://oeis.org/A051037 + * - base [2, 3, 5, 7] ugly numbers are 7-smooth numbers, cf. https://oeis.org/A002473 + * - base [2] ugly numbers are the non-negative powers of 2, + * - the base [2, 3, 5] ugly numbers are the same as base [5, 6, 2, 3, 5] ugly numbers + */ +public class NthUglyNumber { + private ArrayList<Long> uglyNumbers = new ArrayList<>(Arrays.asList(1L)); + private final int[] baseNumbers; + private HashMap<Integer, Integer> positions = new HashMap<>(); + + /** + * @brief initialized the object allowing to compute ugly numbers with given base + * @param baseNumbers the given base of ugly numbers + * @exception IllegalArgumentException baseNumber is empty + */ + NthUglyNumber(final int[] baseNumbers) { + if (baseNumbers.length == 0) { + throw new IllegalArgumentException("baseNumbers must be non-empty."); + } + + this.baseNumbers = baseNumbers; + for (final var baseNumber : baseNumbers) { + this.positions.put(baseNumber, 0); + } + } + + /** + * @param n the zero-based-index of the queried ugly number + * @exception IllegalArgumentException n is negative + * @return the n-th ugly number (starting from index 0) + */ + public Long get(final int n) { + if (n < 0) { + throw new IllegalArgumentException("n must be non-negative."); + } + + while (uglyNumbers.size() <= n) { + addUglyNumber(); + } + + return uglyNumbers.get(n); + } + + private void addUglyNumber() { + uglyNumbers.add(computeMinimalCandidate()); + updatePositions(); + } + + private void updatePositions() { + final var lastUglyNumber = uglyNumbers.get(uglyNumbers.size() - 1); + for (final var baseNumber : baseNumbers) { + if (computeCandidate(baseNumber) == lastUglyNumber) { + positions.put(baseNumber, positions.get(baseNumber) + 1); + } + } + } + + private long computeCandidate(final int candidateBase) { + return candidateBase * uglyNumbers.get(positions.get(candidateBase)); + } + + private long computeMinimalCandidate() { + long res = Long.MAX_VALUE; + for (final var baseNumber : baseNumbers) { + res = Math.min(res, computeCandidate(baseNumber)); + } + return res; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/NumberOfDigits.java b/Java/src/main/java/com/thealgorithms/maths/NumberOfDigits.java new file mode 100644 index 000000000000..fc538196c7da --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/NumberOfDigits.java @@ -0,0 +1,53 @@ +package com.thealgorithms.maths; + +/** + * Find the number of digits in a number. + */ +public final class NumberOfDigits { + private NumberOfDigits() { + } + /** + * Find the number of digits in a number. + * + * @param number number to find + * @return number of digits of given number + */ + public 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 + */ + public 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 + */ + public 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 + */ + public static int numberOfDigitsRecursion(int number) { + return number / 10 == 0 ? 1 : 1 + numberOfDigitsRecursion(number / 10); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PalindromeNumber.java b/Java/src/main/java/com/thealgorithms/maths/PalindromeNumber.java new file mode 100644 index 000000000000..a22d63897b37 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PalindromeNumber.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +public final class PalindromeNumber { + private PalindromeNumber() { + } + /** + * 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("Input parameter must not be negative!"); + } + 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/Java/src/main/java/com/thealgorithms/maths/ParseInteger.java b/Java/src/main/java/com/thealgorithms/maths/ParseInteger.java new file mode 100644 index 000000000000..cdca9f815c4d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/ParseInteger.java @@ -0,0 +1,46 @@ +package com.thealgorithms.maths; + +public final class ParseInteger { + private ParseInteger() { + } + + private static void checkInput(final String s) { + if (s == null) { + throw new NumberFormatException("Input parameter must not be null!"); + } + if (s.isEmpty()) { + throw new NumberFormatException("Input parameter must not be empty!"); + } + } + + private static void checkDigitAt(final String s, final int pos) { + if (!Character.isDigit(s.charAt(pos))) { + throw new NumberFormatException("Input parameter of incorrect format: " + s); + } + } + + private static int digitToInt(final char digit) { + return digit - '0'; + } + + /** + * 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(final String s) { + checkInput(s); + + final boolean isNegative = s.charAt(0) == '-'; + final boolean isPositive = s.charAt(0) == '+'; + int number = 0; + for (int i = isNegative || isPositive ? 1 : 0, length = s.length(); i < length; ++i) { + checkDigitAt(s, i); + number = number * 10 + digitToInt(s.charAt(i)); + } + return isNegative ? -number : number; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PascalTriangle.java b/Java/src/main/java/com/thealgorithms/maths/PascalTriangle.java new file mode 100644 index 000000000000..ef6aa41d6e53 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PascalTriangle.java @@ -0,0 +1,64 @@ +package com.thealgorithms.maths; + +public final class PascalTriangle { + private PascalTriangle() { + } + + /** + *In mathematics, Pascal's triangle is a triangular array of the binomial coefficients that + *arises in probability theory, combinatorics, and algebra. In much of the Western world, it is + *named after the French mathematician Blaise Pascal, although other mathematicians studied it + *centuries before him in India, Persia, China, Germany, and Italy. + * + * The rows of Pascal's triangle are conventionally enumerated starting with row n=0 at the top + *(the 0th row). The entries in each row are numbered from the left beginning with k=0 and are + *usually staggered relative to the numbers in the adjacent rows. The triangle may be + *constructed in the following manner: In row 0 (the topmost row), there is a unique nonzero + *entry 1. Each entry of each subsequent row is constructed by adding the number above and to + *the left with the number above and to the right, treating blank entries as 0. For example, the + *initial number in the first (or any other) row is 1 (the sum of 0 and 1), whereas the numbers + *1 and 3 in the third row are added to produce the number 4 in the fourth row. * + * + *<p> + * link:-https://en.wikipedia.org/wiki/Pascal%27s_triangle + * + * <p> + * Example:- + * 1 + * 1 1 + * 1 2 1 + * 1 3 3 1 + * 1 4 6 4 1 + * 1 5 10 10 5 1 + * 1 6 15 20 15 6 1 + * 1 7 21 35 35 21 7 1 + * 1 8 28 56 70 56 28 8 1 + * + */ + + public static int[][] pascal(int n) { + /** + * @param arr An auxiliary array to store generated pascal triangle values + * @return + */ + int[][] arr = new int[n][n]; + /** + * @param line Iterate through every line and print integer(s) in it + * @param i Represents the column number of the element we are currently on + */ + for (int line = 0; line < n; line++) { + /** + * @Every line has number of integers equal to line number + */ + for (int i = 0; i <= line; i++) { + // First and last values in every row are 1 + if (line == i || i == 0) arr[line][i] = 1; + // The rest elements are sum of values just above and left of above + else + arr[line][i] = arr[line - 1][i - 1] + arr[line - 1][i]; + } + } + + return arr; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PerfectCube.java b/Java/src/main/java/com/thealgorithms/maths/PerfectCube.java new file mode 100644 index 000000000000..4104c6238580 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PerfectCube.java @@ -0,0 +1,34 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Cube_(algebra) + */ +public final class PerfectCube { + private PerfectCube() { + } + + /** + * 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) { + number = Math.abs(number); // converting negative number to positive number + int a = (int) Math.pow(number, 1.0 / 3); + return a * a * a == number; + } + + /** + * Check if a number is perfect cube or not by using Math.cbrt function + * + * @param number number to check + * @return {@code true} if {@code number} is perfect cube, otherwise + * {@code false} + */ + public static boolean isPerfectCubeMathCbrt(int number) { + double cubeRoot = Math.cbrt(number); + return cubeRoot == (int) cubeRoot; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PerfectNumber.java b/Java/src/main/java/com/thealgorithms/maths/PerfectNumber.java new file mode 100644 index 000000000000..49afd23f91bf --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PerfectNumber.java @@ -0,0 +1,65 @@ +package com.thealgorithms.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 final class PerfectNumber { + private PerfectNumber() { + } + + /** + * 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) { + if (number <= 0) return false; + int sum = 0; + /* sum of its positive divisors */ + for (int i = 1; i < number; ++i) { + if (number % i == 0) { + sum += i; + } + } + return sum == number; + } + + /** + * Check if {@code n} is perfect number or not + * + * @param n the number + * @return {@code true} if {@code number} is perfect number, otherwise false + */ + public static boolean isPerfectNumber2(int n) { + if (n <= 0) return false; + int sum = 1; + double root = Math.sqrt(n); + + /* + * We can get the factors after the root by dividing number by its factors + * before the root. + * Ex- Factors of 100 are 1, 2, 4, 5, 10, 20, 25, 50 and 100. + * Root of 100 is 10. So factors before 10 are 1, 2, 4 and 5. + * Now by dividing 100 by each factor before 10 we get: + * 100/1 = 100, 100/2 = 50, 100/4 = 25 and 100/5 = 20 + * So we get 100, 50, 25 and 20 which are factors of 100 after 10 + */ + for (int i = 2; i <= root; i++) { + if (n % i == 0) { + sum += i + n / i; + } + } + + // if n is a perfect square then its root was added twice in above loop, so subtracting root + // from sum + if (root == (int) root) sum -= root; + + return sum == n; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PerfectSquare.java b/Java/src/main/java/com/thealgorithms/maths/PerfectSquare.java new file mode 100644 index 000000000000..fbc7a6f19bd0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PerfectSquare.java @@ -0,0 +1,21 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Perfect_square + */ +public final class PerfectSquare { + private PerfectSquare() { + } + + /** + * Check if a number is perfect square number + * + * @param number the number to be checked + * @return <tt>true</tt> if {@code number} is perfect square, otherwise + * <tt>false</tt> + */ + public static boolean isPerfectSquare(final int number) { + final int sqrt = (int) Math.sqrt(number); + return sqrt * sqrt == number; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Perimeter.java b/Java/src/main/java/com/thealgorithms/maths/Perimeter.java new file mode 100644 index 000000000000..f8aa1876d388 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Perimeter.java @@ -0,0 +1,60 @@ +package com.thealgorithms.maths; + +// Perimeter of different 2D geometrical shapes +public final class Perimeter { + private Perimeter() { + } + + /** + * Calculate the Perimeter of regular polygon (equals sides) + * Examples of regular polygon are Equilateral Triangle, Square, Regular Pentagon, Regular + * Hexagon. + * + * @param n for number of sides. + * @param side for length of each side. + * @return Perimeter of given polygon + */ + public static float perimeterRegularPolygon(int n, float side) { + return n * side; + } + + /** + * Calculate the Perimeter of irregular polygon (unequals sides) + * Examples of irregular polygon are scalent triangle, irregular quadrilateral, irregular + * Pentagon, irregular Hexagon. + * + * @param side1 for length of side 1 + * @param side2 for length of side 2 + * @param side3 for length of side 3 + * @param sides for length of remaining sides + * @return Perimeter of given trapezoid. + */ + public static float perimeterIrregularPolygon(float side1, float side2, float side3, float... sides) { + float perimeter = side1 + side2 + side3; + for (float side : sides) { + perimeter += side; + } + return perimeter; + } + + /** + * Calculate the Perimeter of rectangle + * + * @param length for length of rectangle + * @param breadth for breadth of rectangle + * @return Perimeter of given rectangle + */ + public static float perimeterRectangle(float length, float breadth) { + return 2 * (length + breadth); + } + + /** + * Calculate the Perimeter or Circumference of circle. + * + * @param r for radius of circle. + * @return circumference of given circle. + */ + public static double perimeterCircle(float r) { + return 2 * Math.PI * r; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PiNilakantha.java b/Java/src/main/java/com/thealgorithms/maths/PiNilakantha.java new file mode 100644 index 000000000000..6d43f134c94c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PiNilakantha.java @@ -0,0 +1,44 @@ +package com.thealgorithms.maths; + +public final class PiNilakantha { + private 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/Java/src/main/java/com/thealgorithms/maths/PollardRho.java b/Java/src/main/java/com/thealgorithms/maths/PollardRho.java new file mode 100644 index 000000000000..7fa913b21b7e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PollardRho.java @@ -0,0 +1,80 @@ +package com.thealgorithms.maths; + +/* + * Java program for pollard rho algorithm + * The algorithm is used to factorize a number n = pq, + * where p is a non-trivial factor. + * Pollard's rho algorithm is an algorithm for integer factorization + * and it takes as its inputs n, the integer to be factored; + * and g(x), a polynomial in x computed modulo n. + * In the original algorithm, g(x) = ((x ^ 2) − 1) mod n, + * but nowadays it is more common to use g(x) = ((x ^ 2) + 1 ) mod n. + * The output is either a non-trivial factor of n, or failure. + * It performs the following steps: + * x ← 2 + * y ← 2 + * d ← 1 + + * while d = 1: + * x ← g(x) + * y ← g(g(y)) + * d ← gcd(|x - y|, n) + + * if d = n: + * return failure + * else: + * return d + + * Here x and y corresponds to xi and xj in the previous section. + * Note that this algorithm may fail to find a nontrivial factor even when n is composite. + * In that case, the method can be tried again, using a starting value other than 2 or a different + g(x) + * + * Wikipedia: https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ +public final class PollardRho { + private PollardRho() { + } + + /** + * This method returns a polynomial in x computed modulo n + * + * @param base Integer base of the polynomial + * @param modulus Integer is value which is to be used to perform modulo operation over the + * polynomial + * @return Integer (((base * base) - 1) % modulus) + */ + static int g(int base, int modulus) { + return ((base * base) - 1) % modulus; + } + + /** + * This method returns a non-trivial factor of given integer number + * + * @param number Integer is a integer value whose non-trivial factor is to be found + * @return Integer non-trivial factor of number + * @throws RuntimeException object if GCD of given number cannot be found + */ + static int pollardRho(int number) { + int x = 2; + int y = 2; + int d = 1; + while (d == 1) { + // tortoise move + x = g(x, number); + + // hare move + y = g(g(y, number), number); + + // check GCD of |x-y| and number + d = GCD.gcd(Math.abs(x - y), number); + } + if (d == number) { + throw new RuntimeException("GCD cannot be found."); + } + return d; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/Pow.java b/Java/src/main/java/com/thealgorithms/maths/Pow.java new file mode 100644 index 000000000000..3f362fe88d30 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Pow.java @@ -0,0 +1,30 @@ +package com.thealgorithms.maths; + +// POWER (exponentials) Examples (a^b) +public final class Pow { + private 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}<sup>{@code b}</sup>. + */ + 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/Java/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java b/Java/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java new file mode 100644 index 000000000000..c1f8beffdb2e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PowerOfTwoOrNot.java @@ -0,0 +1,21 @@ +package com.thealgorithms.maths; + +/** + * A utility to check if a given number is power of two or not. For example 8,16 + * etc. + */ +public final class PowerOfTwoOrNot { + private PowerOfTwoOrNot() { + } + + /** + * 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(final int number) { + return number != 0 && ((number & (number - 1)) == 0); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java b/Java/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java new file mode 100644 index 000000000000..93c8252ab929 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java @@ -0,0 +1,22 @@ +package com.thealgorithms.maths; + +/** + * calculate Power using Recursion + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class PowerUsingRecursion { + private PowerUsingRecursion() { + } + + public static double power(double base, int exponent) { + // Base case: anything raised to the power of 0 is 1 + if (exponent == 0) { + return 1; + } + + // Recursive case: base ^ exponent = base * base ^ (exponent - 1) + // Recurse with a smaller exponent and multiply with base + return base * power(base, exponent - 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PrimeCheck.java b/Java/src/main/java/com/thealgorithms/maths/PrimeCheck.java new file mode 100644 index 000000000000..628a819aeba4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PrimeCheck.java @@ -0,0 +1,85 @@ +package com.thealgorithms.maths; + +import java.util.Scanner; + +public final class PrimeCheck { + private 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("algo1 verify that " + n + " is a prime number"); + } else { + System.out.println("algo1 verify that " + n + " is not a prime number"); + } + + if (fermatPrimeChecking(n, 20)) { + System.out.println("algo2 verify that " + n + " is a prime number"); + } else { + System.out.println("algo2 verify that " + 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; + } + + /** + * * + * Checks if a number is prime or not + * + * @param n the number + * @return {@code true} if {@code n} is prime + */ + public static boolean fermatPrimeChecking(int n, int iteration) { + long a; + int up = n - 2; + int down = 2; + for (int i = 0; i < iteration; i++) { + a = (long) Math.floor(Math.random() * (up - down + 1) + down); + if (modPow(a, n - 1, n) != 1) { + return false; + } + } + return true; + } + + /** + * * + * @param a basis + * @param b exponent + * @param c modulo + * @return (a^b) mod c + */ + private static long modPow(long a, long b, long c) { + long res = 1; + for (int i = 0; i < b; i++) { + res *= a; + res %= c; + } + return res % c; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PrimeFactorization.java b/Java/src/main/java/com/thealgorithms/maths/PrimeFactorization.java new file mode 100644 index 000000000000..9ac50fd9043b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PrimeFactorization.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +/* + * Authors: + * (1) Aitor Fidalgo Sánchez (https://github.com/aitorfi) + * (2) Akshay Dubey (https://github.com/itsAkshayDubey) + */ + +import java.util.ArrayList; +import java.util.List; + +public final class PrimeFactorization { + private PrimeFactorization() { + } + + public static List<Integer> pfactors(int n) { + List<Integer> primeFactors = new ArrayList<>(); + + if (n == 0) { + return primeFactors; + } + + while (n % 2 == 0) { + primeFactors.add(2); + n /= 2; + } + + for (int i = 3; i <= Math.sqrt(n); i += 2) { + while (n % i == 0) { + primeFactors.add(i); + n /= i; + } + } + + if (n > 2) { + primeFactors.add(n); + } + return primeFactors; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PronicNumber.java b/Java/src/main/java/com/thealgorithms/maths/PronicNumber.java new file mode 100644 index 000000000000..4891cf3c63b3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PronicNumber.java @@ -0,0 +1,37 @@ +package com.thealgorithms.maths; + +/* + * Java program for Pronic Number + * Pronic Number: A number n is a pronic number if + * it is equal to product of two consecutive numbers m and m+1. + * Wikipedia: https://en.wikipedia.org/wiki/Pronic_number + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +public final class PronicNumber { + private PronicNumber() { + } + + /** + * This method checks if the given number is pronic number or non-pronic number + * + * @param inputNumber Integer value which is to be checked if is a pronic number or not + * @return true if input number is a pronic number, false otherwise + */ + static boolean isPronic(int inputNumber) { + // Iterating from 0 to input_number + for (int i = 0; i <= inputNumber; i++) { + // Checking if product of i and (i+1) is equals input_number + if (i * (i + 1) == inputNumber && i != inputNumber) { + // return true if product of i and (i+1) is equals input_number + return true; + } + } + + // return false if product of i and (i+1) for all values from 0 to input_number is not + // equals input_number + return false; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java b/Java/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java new file mode 100644 index 000000000000..f535e9e6929b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +/** + * https://en.wikipedia.org/wiki/Pythagorean_triple + */ +public final class PythagoreanTriple { + private 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 <tt>true</tt> if a, b, c satisfy the Pythagorean theorem, + * otherwise + * <tt>false</tt> + */ + 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/Java/src/main/java/com/thealgorithms/maths/ReverseNumber.java b/Java/src/main/java/com/thealgorithms/maths/ReverseNumber.java new file mode 100644 index 000000000000..667a0a43fc2c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/ReverseNumber.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +/** + * @brief utility class reversing numbers + */ +public final class ReverseNumber { + private ReverseNumber() { + } + + /** + * @brief reverses the input number + * @param number the input number + * @exception IllegalArgumentException number is negative + * @return the number created by reversing the order of digits of the input number + */ + public static int reverseNumber(int number) { + if (number < 0) { + throw new IllegalArgumentException("number must be nonnegative."); + } + + int result = 0; + while (number > 0) { + result *= 10; + result += number % 10; + number /= 10; + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java b/Java/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java new file mode 100644 index 000000000000..8f5d44dbe146 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java @@ -0,0 +1,73 @@ +package com.thealgorithms.maths; + +/** + * Translates numbers into the Roman Numeral System. + * + * @see <a href="https://en.wikipedia.org/wiki/Roman_numerals">Roman + * numerals</a> + * @author Sokratis Fotkatzikis + * @version 1.0 + */ +public final class RomanNumeralUtil { + private RomanNumeralUtil() { + } + + private static final int MIN_VALUE = 1; + private static final int MAX_VALUE = 5999; + // 1000-5999 + private static final String[] RN_M = { + "", + "M", + "MM", + "MMM", + "MMMM", + "MMMMM", + }; + // 100-900 + private static final String[] RN_C = { + "", + "C", + "CC", + "CCC", + "CD", + "D", + "DC", + "DCC", + "DCCC", + "CM", + }; + // 10-90 + private static final String[] RN_X = { + "", + "X", + "XX", + "XXX", + "XL", + "L", + "LX", + "LXX", + "LXXX", + "XC", + }; + // 1-9 + private static final String[] RN_I = { + "", + "I", + "II", + "III", + "IV", + "V", + "VI", + "VII", + "VIII", + "IX", + }; + + public static String generate(int number) { + if (number < MIN_VALUE || number > MAX_VALUE) { + throw new IllegalArgumentException(String.format("The number must be in the range [%d, %d]", MIN_VALUE, MAX_VALUE)); + } + + return (RN_M[number / 1000] + RN_C[number % 1000 / 100] + RN_X[number % 100 / 10] + RN_I[number % 10]); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SecondMinMax.java b/Java/src/main/java/com/thealgorithms/maths/SecondMinMax.java new file mode 100644 index 000000000000..e5a2d3b89085 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SecondMinMax.java @@ -0,0 +1,60 @@ +package com.thealgorithms.maths; + +import java.util.function.BiPredicate; + +public final class SecondMinMax { + + /** + * Utility class for finding second maximum or minimum based on BiPredicate + * @exception IllegalArgumentException => if input array is of length less than 2 also if all elements are same + * @return the second minimum / maximum value from the input array + * @author Bharath Sanjeevi ( https://github.com/BharathSanjeeviT ) + */ + + private SecondMinMax() { + } + + private static int secondBest(final int[] arr, final int initialVal, final BiPredicate<Integer, Integer> isBetter) { + checkInput(arr); + int best = initialVal; + int secBest = initialVal; + for (final int num : arr) { + if (isBetter.test(num, best)) { + secBest = best; + best = num; + } else if ((isBetter.test(num, secBest)) && (num != best)) { + secBest = num; + } + } + checkOutput(secBest, initialVal); + return secBest; + } + + /** + * @brief Finds the Second minimum / maximum value from the array + * @param arr the input array + * @exception IllegalArgumentException => if input array is of length less than 2 also if all elements are same + * @return the second minimum / maximum value from the input array + * @author Bharath Sanjeevi ( https://github.com/BharathSanjeeviT ) + */ + + public static int findSecondMin(final int[] arr) { + return secondBest(arr, Integer.MAX_VALUE, (a, b) -> a < b); + } + + public static int findSecondMax(final int[] arr) { + return secondBest(arr, Integer.MIN_VALUE, (a, b) -> a > b); + } + + private static void checkInput(final int[] arr) { + if (arr.length < 2) { + throw new IllegalArgumentException("Input array must have length of at least two"); + } + } + + private static void checkOutput(final int secNum, final int initialVal) { + if (secNum == initialVal) { + throw new IllegalArgumentException("Input array should have at least 2 distinct elements"); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java b/Java/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java new file mode 100644 index 000000000000..79bc112902c4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java @@ -0,0 +1,88 @@ +package com.thealgorithms.maths; + +import java.util.TreeMap; + +public class SimpsonIntegration { + + /* + * Calculate definite integrals by using Composite Simpson's rule. + * Wiki: https://en.wikipedia.org/wiki/Simpson%27s_rule#Composite_Simpson's_rule + * Given f a function and an even number N of intervals that divide the integration interval + * e.g. [a, b], we calculate the step h = (b-a)/N and create a table that contains all the x + * points of the real axis xi = x0 + i*h and the value f(xi) that corresponds to these xi. + * + * To evaluate the integral i use the formula below: + * 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(); + + // Give random data for the example purposes + int n = 16; + double a = 1; + double b = 3; + + // Check so that n is even + 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 integralEvaluation = integration.simpsonsMethod(n, h, a); + System.out.println("The integral is equal to: " + integralEvaluation); + } + + /* + * @param N: Number of intervals (must be even number N=2*k) + * @param h: Step h = (b-a)/N + * @param a: Starting point of the interval + * @param b: Ending point of the interval + * + * The interpolation points xi = x0 + i*h are stored the treeMap data + * + * @return result of the integral evaluation + */ + public double simpsonsMethod(int n, double h, double a) { + TreeMap<Integer, Double> 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++) { + 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 + } + + // Apply the formula + double integralEvaluation = 0; + for (int i = 0; i < data.size(); i++) { + if (i == 0 || i == data.size() - 1) { + integralEvaluation += data.get(i); + System.out.println("Multiply f(x" + i + ") by 1"); + } else if (i % 2 == 1) { + integralEvaluation += (double) 4 * data.get(i); + System.out.println("Multiply f(x" + i + ") by 4"); + } else { + integralEvaluation += (double) 2 * data.get(i); + System.out.println("Multiply f(x" + i + ") by 2"); + } + } + + // Multiply by h/3 + integralEvaluation = h / 3 * integralEvaluation; + + // Return the result + return integralEvaluation; + } + + // Sample function f + // Function f(x) = e^(-x) * (4 - x^2) + public double f(double x) { + return Math.exp(-x) * (4 - Math.pow(x, 2)); + // return Math.sqrt(x); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java b/Java/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java new file mode 100644 index 000000000000..22e9fee00605 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java @@ -0,0 +1,45 @@ +package com.thealgorithms.maths; +/* + * Java program for Square free integer + * This class has a function which checks + * if an integer has repeated prime factors + * and will return false if the number has repeated prime factors. + * true otherwise + * Wikipedia: https://en.wikipedia.org/wiki/Square-free_integer + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +import java.util.HashSet; +import java.util.List; + +public final class SquareFreeInteger { + private SquareFreeInteger() { + } + /** + * This method returns whether an integer is square free + * + * @param number Integer value which is to be checked + * @return false when number has repeated prime factors + * true when number has non repeated prime factors + * @throws IllegalArgumentException when number is negative or zero + */ + public static boolean isSquareFreeInteger(int number) { + + if (number <= 0) { + // throw exception when number is less than or is zero + throw new IllegalArgumentException("Number must be greater than zero."); + } + + // Store prime factors of number which is passed as argument + // in a list + List<Integer> primeFactorsList = PrimeFactorization.pfactors(number); + + // Create set from list of prime factors of integer number + // if size of list and set is equal then the argument passed to this method is square free + // if size of list and set is not equal then the argument passed to this method is not + // square free + return primeFactorsList.size() == new HashSet<>(primeFactorsList).size(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java b/Java/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java new file mode 100644 index 000000000000..2b071307e2bc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java @@ -0,0 +1,23 @@ +package com.thealgorithms.maths; + +public final class SquareRootWithBabylonianMethod { + private SquareRootWithBabylonianMethod() { + } + + /** + * get the value, return the square root + * + * @param num contains elements + * @return the square root of num + */ + public static float squareRoot(float num) { + float a = num; + float b = 1; + double e = 0.000001; + while (a - b > e) { + a = (a + b) / 2; + b = num / a; + } + return a; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java b/Java/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java new file mode 100644 index 000000000000..80d185c93785 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java @@ -0,0 +1,33 @@ +package com.thealgorithms.maths; + +/* + *To learn about the method, visit the link below : + * https://en.wikipedia.org/wiki/Newton%27s_method + * + * To obtain the square root, no built-in functions should be used + * + * The formula to calculate the root is : root = 0.5(x + n/x), + * here, n is the no. whose square root has to be calculated and + * x has to be guessed such that, the calculation should result into + * the square root of n. + * And the root will be obtained when the error < 0.5 or the precision value can also + * be changed according to the user preference. + */ + +public final class SquareRootWithNewtonRaphsonMethod { + private SquareRootWithNewtonRaphsonMethod() { + } + + public static double squareRoot(int n) { + double x = n; // initially taking a guess that x = n. + double root = 0.5 * (x + n / x); // applying Newton-Raphson Method. + + while (Math.abs(root - x) > 0.0000001) { // root - x = error and error < 0.0000001, 0.0000001 + // is the precision value taken over here. + x = root; // decreasing the value of x to root, i.e. decreasing the guess. + root = 0.5 * (x + n / x); + } + + return root; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/StandardDeviation.java b/Java/src/main/java/com/thealgorithms/maths/StandardDeviation.java new file mode 100644 index 000000000000..a8e88d930a9c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/StandardDeviation.java @@ -0,0 +1,20 @@ +package com.thealgorithms.maths; + +public final class StandardDeviation { + private StandardDeviation() { + } + + public static double stdDev(double[] data) { + double variance = 0; + double avg = 0; + for (int i = 0; i < data.length; i++) { + avg += data[i]; + } + avg /= data.length; + for (int j = 0; j < data.length; j++) { + variance += Math.pow((data[j] - avg), 2); + } + variance /= data.length; + return Math.sqrt(variance); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/StandardScore.java b/Java/src/main/java/com/thealgorithms/maths/StandardScore.java new file mode 100644 index 000000000000..22a9f550e114 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/StandardScore.java @@ -0,0 +1,10 @@ +package com.thealgorithms.maths; + +public final class StandardScore { + private StandardScore() { + } + + public static double zScore(double num, double mean, double stdDev) { + return (num - mean) / stdDev; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java b/Java/src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java new file mode 100644 index 000000000000..bcd9a8467e50 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/StrobogrammaticNumber.java @@ -0,0 +1,43 @@ +package com.thealgorithms.maths; + +import java.util.HashMap; +import java.util.Map; + +/** + * A strobogrammatic number is a number that remains the same when rotated 180 degrees. + * In other words, the number looks the same when rotated upside down. + * Examples of strobogrammatic numbers are "69", "88", "818", and "101". + * Numbers like "609" or "120" are not strobogrammatic because they do not look the same when rotated. + */ +public class StrobogrammaticNumber { + /** + * Check if a number is strobogrammatic + * @param number the number to be checked + * @return true if the number is strobogrammatic, false otherwise + */ + public boolean isStrobogrammatic(String number) { + Map<Character, Character> strobogrammaticMap = new HashMap<>(); + strobogrammaticMap.put('0', '0'); + strobogrammaticMap.put('1', '1'); + strobogrammaticMap.put('6', '9'); + strobogrammaticMap.put('8', '8'); + strobogrammaticMap.put('9', '6'); + + int left = 0; + int right = number.length() - 1; + + while (left <= right) { + char leftChar = number.charAt(left); + char rightChar = number.charAt(right); + + if (!strobogrammaticMap.containsKey(leftChar) || strobogrammaticMap.get(leftChar) != rightChar) { + return false; + } + + left++; + right--; + } + + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java b/Java/src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java new file mode 100644 index 000000000000..315f0d3a7d28 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SumOfArithmeticSeries.java @@ -0,0 +1,31 @@ +package com.thealgorithms.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. + * + * <p> + * Wikipedia: https://en.wikipedia.org/wiki/Arithmetic_progression + */ +public final class SumOfArithmeticSeries { + private SumOfArithmeticSeries() { + } + + /** + * 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 + */ + public static double sumOfSeries(final double firstTerm, final double commonDiff, final int numOfTerms) { + if (numOfTerms < 0) { + throw new IllegalArgumentException("numOfTerms nonnegative."); + } + return (numOfTerms / 2.0 * (2 * firstTerm + (numOfTerms - 1) * commonDiff)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SumOfDigits.java b/Java/src/main/java/com/thealgorithms/maths/SumOfDigits.java new file mode 100644 index 000000000000..e5ec8a02025d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SumOfDigits.java @@ -0,0 +1,45 @@ +package com.thealgorithms.maths; + +public final class SumOfDigits { + private SumOfDigits() { + } + + /** + * 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) { + final int base = 10; + number = Math.abs(number); + int sum = 0; + while (number != 0) { + sum += number % base; + number /= base; + } + 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) { + final int base = 10; + number = Math.abs(number); + return number < base ? number : number % base + sumOfDigitsRecursion(number / base); + } + + /** + * 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(final int number) { + return String.valueOf(Math.abs(number)).chars().map(c -> c - '0').reduce(0, Integer::sum); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java b/Java/src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java new file mode 100644 index 000000000000..8bc1afbe8771 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/SumWithoutArithmeticOperators.java @@ -0,0 +1,20 @@ +package com.thealgorithms.maths; + +public class SumWithoutArithmeticOperators { + + /** + * Calculate the sum of two numbers a and b without using any arithmetic operators (+, -, *, /). + * All the integers associated are unsigned 32-bit integers + *https://stackoverflow.com/questions/365522/what-is-the-best-way-to-add-two-numbers-without-using-the-operator + *@param a - It is the first number + *@param b - It is the second number + *@return returns an integer which is the sum of the first and second number + */ + + public int getSum(int a, int b) { + if (b == 0) return a; + int sum = a ^ b; + int carry = (a & b) << 1; + return getSum(sum, carry); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java b/Java/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java new file mode 100644 index 000000000000..877ef4227afc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java @@ -0,0 +1,44 @@ +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 + */ +public final class TrinomialTriangle { + private TrinomialTriangle() { + } + + public static int trinomialValue(int n, int k) { + if (n == 0 && k == 0) { + return 1; + } + + if (k < -n || k > n) { + return 0; + } + + return (trinomialValue(n - 1, k - 1) + trinomialValue(n - 1, k) + trinomialValue(n - 1, k + 1)); + } + + public static void printTrinomial(int n) { + for (int i = 0; i < n; i++) { + for (int j = -i; j <= 0; j++) { + System.out.print(trinomialValue(i, j) + " "); + } + + for (int j = 1; j <= i; j++) { + System.out.print(trinomialValue(i, j) + " "); + } + + System.out.println(); + } + } + + public static void main(String[] argc) { + int n = 6; + printTrinomial(n); + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/TwinPrime.java b/Java/src/main/java/com/thealgorithms/maths/TwinPrime.java new file mode 100644 index 000000000000..81731376b37a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/TwinPrime.java @@ -0,0 +1,33 @@ +package com.thealgorithms.maths; +/* + * Java program to find 'twin prime' of a prime number + * Twin Prime: Twin prime of a number n is (n+2) + * if and only if n & (n+2) are prime. + * Wikipedia: https://en.wikipedia.org/wiki/Twin_prime + * + * Author: Akshay Dubey (https://github.com/itsAkshayDubey) + * + * */ + +public final class TwinPrime { + private TwinPrime() { + } + + /** + * This method returns twin prime of the integer value passed as argument + * + * @param input_number Integer value of which twin prime is to be found + * @return (number + 2) if number and (number + 2) are prime, -1 otherwise + */ + static int getTwinPrime(int inputNumber) { + + // if inputNumber and (inputNumber + 2) are both prime + // then return (inputNumber + 2) as a result + if (PrimeCheck.isPrime(inputNumber) && PrimeCheck.isPrime(inputNumber + 2)) { + return inputNumber + 2; + } + // if any one from inputNumber and (inputNumber + 2) or if both of them are not prime + // then return -1 as a result + return -1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/maths/VampireNumber.java b/Java/src/main/java/com/thealgorithms/maths/VampireNumber.java new file mode 100644 index 000000000000..d64c82c6e68e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/VampireNumber.java @@ -0,0 +1,79 @@ +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. * + * + * <p> + * link: https://en.wikipedia.org/wiki/Vampire_number * + * + * <p> + */ +public final class VampireNumber { + private 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<Integer> 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/Java/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java b/Java/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java new file mode 100644 index 000000000000..e2769744bcda --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java @@ -0,0 +1,125 @@ +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 separated 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 vectorX set to x + * @param vectorY set to y + * @param vectorZ set to z + */ + VectorCrossProduct(int vectorX, int vectorY, int vectorZ) { + x = vectorX; + y = vectorY; + z = vectorZ; + } + + /** + * 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/Java/src/main/java/com/thealgorithms/maths/Volume.java b/Java/src/main/java/com/thealgorithms/maths/Volume.java new file mode 100644 index 000000000000..4b73f849bb81 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/maths/Volume.java @@ -0,0 +1,93 @@ +package com.thealgorithms.maths; + +/* Calculate the volume of various shapes.*/ +public final class Volume { + private Volume() { + } + + /** + * Calculate the volume of a cube. + * + * @param sideLength length of the given cube's sides + * @return volume of the given cube + */ + public static double volumeCube(double sideLength) { + return sideLength * sideLength * sideLength; + } + + /** + * Calculate the volume of a cuboid. + * + * @param width width of given cuboid + * @param height height of given cuboid + * @param length length of given cuboid + * @return volume of given cuboid + */ + public static double volumeCuboid(double width, double height, double length) { + return width * height * length; + } + + /** + * Calculate the volume of a sphere. + * + * @param radius radius of given sphere + * @return volume of given sphere + */ + public static double volumeSphere(double radius) { + return (4 * Math.PI * radius * radius * radius) / 3; + } + + /** + * Calculate volume of a cylinder + * + * @param radius radius of the given cylinder's floor + * @param height height of the given cylinder + * @return volume of given cylinder + */ + public static double volumeCylinder(double radius, double height) { + return Math.PI * radius * radius * height; + } + + /** + * Calculate the volume of a hemisphere. + * + * @param radius radius of given hemisphere + * @return volume of given hemisphere + */ + public static double volumeHemisphere(double radius) { + return (2 * Math.PI * radius * radius * radius) / 3; + } + + /** + * Calculate the volume of a cone. + * + * @param radius radius of given cone + * @param height of given cone + * @return volume of given cone + */ + public static double volumeCone(double radius, double height) { + return (Math.PI * radius * radius * height) / 3; + } + + /** + * Calculate the volume of a prism. + * + * @param baseArea area of the given prism's base + * @param height of given prism + * @return volume of given prism + */ + public static double volumePrism(double baseArea, double height) { + return baseArea * height; + } + + /** + * Calculate the volume of a pyramid. + * + * @param baseArea of the given pyramid's base + * @param height of given pyramid + * @return volume of given pyramid + */ + public static double volumePyramid(double baseArea, double height) { + return (baseArea * height) / 3; + } +} diff --git a/Java/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java b/Java/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java new file mode 100644 index 000000000000..afd34933047a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java @@ -0,0 +1,78 @@ +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 final class Fibonacci { + private Fibonacci() { + } + + // Exponentiation matrix for Fibonacci sequence + private static final int[][] FIB_MATRIX = {{1, 1}, {1, 0}}; + private static final int[][] IDENTITY_MATRIX = {{1, 0}, {0, 1}}; + // First 2 fibonacci numbers + private static final int[][] BASE_FIB_NUMBERS = {{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.IDENTITY_MATRIX; + } else { + int[][] cachedResult = fib(n / 2); + int[][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult); + if (n % 2 == 0) { + return matrixExpResult; + } else { + return matrixMultiplication(Fibonacci.FIB_MATRIX, 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), BASE_FIB_NUMBERS); + System.out.println("Fib(" + n + ") = " + result[1][0]); + sc.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java b/Java/src/main/java/com/thealgorithms/misc/ColorContrastRatio.java new file mode 100644 index 000000000000..2d8371a9a53d --- /dev/null +++ b/Java/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 official 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/Java/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java b/Java/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java new file mode 100644 index 000000000000..5543463e9749 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java @@ -0,0 +1,129 @@ +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 final class InverseOfMatrix { + private 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/Java/src/main/java/com/thealgorithms/misc/MapReduce.java b/Java/src/main/java/com/thealgorithms/misc/MapReduce.java new file mode 100644 index 000000000000..c076957344f9 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MapReduce.java @@ -0,0 +1,41 @@ +package com.thealgorithms.misc; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +/* +* MapReduce is a programming model for processing and generating large data sets with a parallel, +distributed algorithm on a cluster. +* It has two main steps: the Map step, where the data is divided into smaller chunks and processed in parallel, +and the Reduce step, where the results from the Map step are combined to produce the final output. +* Wikipedia link : https://en.wikipedia.org/wiki/MapReduce +*/ + +public final class MapReduce { + private MapReduce() { + } + /* + *Counting all the words frequency within a sentence. + */ + public static String mapreduce(String sentence) { + List<String> wordList = Arrays.stream(sentence.split(" ")).toList(); + + // Map step + Map<String, Long> wordCounts = wordList.stream().collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting())); + + // Reduce step + StringBuilder result = new StringBuilder(); + wordCounts.forEach((word, count) -> result.append(word).append(": ").append(count).append(",")); + + // Removing the last ',' if it exists + if (!result.isEmpty()) { + result.setLength(result.length() - 1); + } + + return result.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java new file mode 100644 index 000000000000..d4ddffe8ddd7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java @@ -0,0 +1,32 @@ +package com.thealgorithms.misc; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Median of Matrix (https://medium.com/@vaibhav.yadav8101/median-in-a-row-wise-sorted-matrix-901737f3e116) + * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public final class MedianOfMatrix { + private MedianOfMatrix() { + } + + public static int median(List<List<Integer>> matrix) { + // Flatten the matrix into a 1D list + List<Integer> linear = new ArrayList<>(); + for (List<Integer> row : matrix) { + linear.addAll(row); + } + + // Sort the 1D list + Collections.sort(linear); + + // Calculate the middle index + int mid = (0 + linear.size() - 1) / 2; + + // Return the median + return linear.get(mid); + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArray.java new file mode 100644 index 000000000000..62013ee31183 --- /dev/null +++ b/Java/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 abstract class MedianOfRunningArray<T extends Number & Comparable<T>> { + + private PriorityQueue<T> maxHeap; + private PriorityQueue<T> minHeap; + + // Constructor + public MedianOfRunningArray() { + this.maxHeap = new PriorityQueue<>(Collections.reverseOrder()); // Max Heap + this.minHeap = new PriorityQueue<>(); // Min Heap + } + + /* + Inserting lower half of array to max Heap + and upper half to min heap + */ + public void insert(final T e) { + if (!minHeap.isEmpty() && e.compareTo(minHeap.peek()) < 0) { + maxHeap.offer(e); + if (maxHeap.size() > minHeap.size() + 1) { + minHeap.offer(maxHeap.poll()); + } + } else { + minHeap.offer(e); + if (minHeap.size() > maxHeap.size() + 1) { + maxHeap.offer(minHeap.poll()); + } + } + } + + /* + Returns median at any given point + */ + public T median() { + if (maxHeap.isEmpty() && minHeap.isEmpty()) { + throw new IllegalArgumentException("Enter at least 1 element, Median of empty list is not defined!"); + } else if (maxHeap.size() == minHeap.size()) { + T maxHeapTop = maxHeap.peek(); + T minHeapTop = minHeap.peek(); + return calculateAverage(maxHeapTop, minHeapTop); + } + return maxHeap.size() > minHeap.size() ? maxHeap.peek() : minHeap.peek(); + } + + public abstract T calculateAverage(T a, T b); +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java new file mode 100644 index 000000000000..668f651e7251 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayByte.java @@ -0,0 +1,8 @@ +package com.thealgorithms.misc; + +public final class MedianOfRunningArrayByte extends MedianOfRunningArray<Byte> { + @Override + public Byte calculateAverage(final Byte a, final Byte b) { + return (byte) ((a + b) / 2); + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java new file mode 100644 index 000000000000..9d743de51643 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayDouble.java @@ -0,0 +1,8 @@ +package com.thealgorithms.misc; + +public final class MedianOfRunningArrayDouble extends MedianOfRunningArray<Double> { + @Override + public Double calculateAverage(final Double a, final Double b) { + return (a + b) / 2.0d; + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java new file mode 100644 index 000000000000..a667abf6121b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayFloat.java @@ -0,0 +1,8 @@ +package com.thealgorithms.misc; + +public final class MedianOfRunningArrayFloat extends MedianOfRunningArray<Float> { + @Override + public Float calculateAverage(final Float a, final Float b) { + return (a + b) / 2.0f; + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java new file mode 100644 index 000000000000..7154ba073136 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayInteger.java @@ -0,0 +1,8 @@ +package com.thealgorithms.misc; + +public final class MedianOfRunningArrayInteger extends MedianOfRunningArray<Integer> { + @Override + public Integer calculateAverage(final Integer a, final Integer b) { + return (a + b) / 2; + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java new file mode 100644 index 000000000000..1f138c6313fb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MedianOfRunningArrayLong.java @@ -0,0 +1,8 @@ +package com.thealgorithms.misc; + +public final class MedianOfRunningArrayLong extends MedianOfRunningArray<Long> { + @Override + public Long calculateAverage(final Long a, final Long b) { + return (a + b) / 2L; + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java b/Java/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java new file mode 100644 index 000000000000..89dfce3fe049 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/MirrorOfMatrix.java @@ -0,0 +1,57 @@ +package com.thealgorithms.misc; + +// Problem Statement +/* +We have given an array of m x n (where m is the number of rows and n is the number of columns). +Print the new matrix in such a way that the new matrix is the mirror image of the original matrix. + +The Original matrix is: | The Mirror matrix is: +1 2 3 | 3 2 1 +4 5 6 | 6 5 4 +7 8 9 | 9 8 7 + +@author - Aman (https://github.com/Aman28801) +*/ + +public final class MirrorOfMatrix { + private MirrorOfMatrix() { + } + + public static int[][] mirrorMatrix(final int[][] originalMatrix) { + if (originalMatrix == null) { + // Handle invalid input + return null; + } + if (originalMatrix.length == 0) { + return new int[0][0]; + } + + checkInput(originalMatrix); + + int numRows = originalMatrix.length; + int numCols = originalMatrix[0].length; + + int[][] mirroredMatrix = new int[numRows][numCols]; + + for (int i = 0; i < numRows; i++) { + mirroredMatrix[i] = reverseRow(originalMatrix[i]); + } + return mirroredMatrix; + } + private static int[] reverseRow(final int[] inRow) { + int[] res = new int[inRow.length]; + for (int i = 0; i < inRow.length; ++i) { + res[i] = inRow[inRow.length - 1 - i]; + } + return res; + } + + private static void checkInput(final int[][] matrix) { + // Check if all rows have the same number of columns + for (int i = 1; i < matrix.length; i++) { + if (matrix[i].length != matrix[0].length) { + throw new IllegalArgumentException("The input is not a matrix."); + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/PalindromePrime.java b/Java/src/main/java/com/thealgorithms/misc/PalindromePrime.java new file mode 100644 index 000000000000..6b01cdced23c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/PalindromePrime.java @@ -0,0 +1,51 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +public final class PalindromePrime { + private 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/Java/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java b/Java/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java new file mode 100644 index 000000000000..07286b39f2e4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/PalindromeSinglyLinkedList.java @@ -0,0 +1,33 @@ +package com.thealgorithms.misc; + +import com.thealgorithms.datastructures.lists.SinglyLinkedList; +import java.util.Stack; + +/** + * 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 final class PalindromeSinglyLinkedList { + private PalindromeSinglyLinkedList() { + } + + public static boolean isPalindrome(final SinglyLinkedList linkedList) { + Stack<Integer> linkedListValues = new Stack<>(); + + for (final var x : linkedList) { + linkedListValues.push(x); + } + + for (final var x : linkedList) { + if (x != linkedListValues.pop()) { + return false; + } + } + + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java b/Java/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java new file mode 100644 index 000000000000..0dfc8ac32a6f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java @@ -0,0 +1,99 @@ +package com.thealgorithms.misc; + +import java.util.Arrays; + +public final class RangeInSortedArray { + private 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) >>> 1; + 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) { + final int mid = (left + right) >>> 1; + 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) { + final int mid = (left + right) >>> 1; + if (nums[mid] > key) { + right = mid - 1; + } else if (nums[mid] <= key) { + count = mid + 1; // At least mid+1 elements exist which are <= key + left = mid + 1; + } + } + return count; + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/Sort012D.java b/Java/src/main/java/com/thealgorithms/misc/Sort012D.java new file mode 100644 index 000000000000..febe13f4fec3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/Sort012D.java @@ -0,0 +1,64 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +/** + * 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 final class Sort012D { + private 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); + np.close(); + } + + 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; + } + default: { + throw new IllegalArgumentException("Unexpected value: " + a[mid]); + } + } + } + System.out.println("the Sorted array is "); + for (int i = 0; i < a.length; i++) { + System.out.print(+a[i] + " "); + } + } +} diff --git a/src/main/java/com/thealgorithms/misc/Sparcity.java b/Java/src/main/java/com/thealgorithms/misc/Sparsity.java similarity index 81% rename from src/main/java/com/thealgorithms/misc/Sparcity.java rename to Java/src/main/java/com/thealgorithms/misc/Sparsity.java index 7eb5e5896308..cae2fbdead94 100644 --- a/src/main/java/com/thealgorithms/misc/Sparcity.java +++ b/Java/src/main/java/com/thealgorithms/misc/Sparsity.java @@ -1,6 +1,6 @@ package com.thealgorithms.misc; -import java.util.*; +import java.util.Scanner; /* *A matrix is sparse if many of its coefficients are zero (In general if 2/3rd of matrix elements @@ -11,15 +11,17 @@ * @author Ojasva Jain */ -class Sparcity { +final class Sparsity { + private Sparsity() { + } /* - * @return Sparcity of matrix + * @return Sparsity of matrix * - * where sparcity = number of zeroes/total elements in matrix + * where sparsity = number of zeroes/total elements in matrix * */ - static double sparcity(double[][] mat) { + static double sparsity(double[][] mat) { int zero = 0; // Traversing the matrix to count number of zeroes for (int i = 0; i < mat.length; i++) { @@ -29,7 +31,7 @@ static double sparcity(double[][] mat) { } } } - // return sparcity + // return sparsity return ((double) zero / (mat.length * mat[1].length)); } @@ -48,7 +50,7 @@ public static void main(String[] args) { mat[i][j] = in.nextDouble(); } } - System.out.println("Sparcity of matrix is: " + sparcity(mat)); + System.out.println("Sparsity of matrix is: " + sparsity(mat)); in.close(); } } diff --git a/Java/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java b/Java/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java new file mode 100644 index 000000000000..1c5f4a440532 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java @@ -0,0 +1,107 @@ +package com.thealgorithms.misc; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Scanner; +import java.util.Set; + +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 < n; i++) { + arr[i] = scan.nextInt(); + } + ThreeSumProblem th = new ThreeSumProblem(); + System.out.println("Brute Force Approach\n" + (th.bruteForce(arr, ts)) + "\n"); + System.out.println("Two Pointer Approach\n" + (th.twoPointer(arr, ts)) + "\n"); + System.out.println("Hashmap Approach\n" + (th.hashMap(arr, ts))); + scan.close(); + } + + public List<List<Integer>> bruteForce(int[] nums, int target) { + List<List<Integer>> arr = new ArrayList<List<Integer>>(); + + 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<Integer> temp = new ArrayList<>(); + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(nums[k]); + Collections.sort(temp); + arr.add(temp); + } + } + } + } + arr = new ArrayList<List<Integer>>(new LinkedHashSet<List<Integer>>(arr)); + return arr; + } + + public List<List<Integer>> twoPointer(int[] nums, int target) { + Arrays.sort(nums); + List<List<Integer>> arr = new ArrayList<List<Integer>>(); + 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<Integer> 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<List<Integer>> set = new LinkedHashSet<List<Integer>>(arr); + return new ArrayList<List<Integer>>(set); + } + + public List<List<Integer>> hashMap(int[] nums, int target) { + Arrays.sort(nums); + Set<List<Integer>> ts = new HashSet<>(); + HashMap<Integer, Integer> 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<Integer> temp = new ArrayList<>(); + temp.add(nums[i]); + temp.add(nums[j]); + temp.add(t); + ts.add(temp); + } + } + } + return new ArrayList<>(ts); + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/TwoSumProblem.java b/Java/src/main/java/com/thealgorithms/misc/TwoSumProblem.java new file mode 100644 index 000000000000..ceeb3717fd4a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/TwoSumProblem.java @@ -0,0 +1,33 @@ +package com.thealgorithms.misc; + +import java.util.HashMap; +import java.util.Optional; +import org.apache.commons.lang3.tuple.Pair; + +public final class TwoSumProblem { + private TwoSumProblem() { + } + + /** + * The function "twoSum" takes an array of integers and a target integer as input, and returns an + * array of two indices where the corresponding elements in the input array add up to the target. + * @param values An array of integers. + * @param target The target is the sum that we are trying to find using two numbers from the given array. + * @return A pair or indexes such that sum of values at these indexes equals to the target + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + + public static Optional<Pair<Integer, Integer>> twoSum(final int[] values, final int target) { + HashMap<Integer, Integer> valueToIndex = new HashMap<>(); + for (int i = 0; i < values.length; i++) { + final var rem = target - values[i]; + if (valueToIndex.containsKey(rem)) { + return Optional.of(Pair.of(valueToIndex.get(rem), i)); + } + if (!valueToIndex.containsKey(values[i])) { + valueToIndex.put(values[i], i); + } + } + return Optional.empty(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/misc/WordBoggle.java b/Java/src/main/java/com/thealgorithms/misc/WordBoggle.java new file mode 100644 index 000000000000..3eb0dc95ffb5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/WordBoggle.java @@ -0,0 +1,156 @@ +package com.thealgorithms.misc; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public final class WordBoggle { + private 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<String> boggleBoard(char[][] board, String[] words) { + Trie trie = new Trie(); + for (String word : words) { + trie.add(word); + } + Set<String> 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<String> 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<String> 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<Integer[]> 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<Integer[]> getNeighbors(int i, int j, char[][] board) { + List<Integer[]> 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<Character, TrieNode> children = new HashMap<>(); + String word = ""; +} + +class Trie { + + TrieNode root; + char endSymbol; + + 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/Java/src/main/java/com/thealgorithms/misc/matrixTranspose.java b/Java/src/main/java/com/thealgorithms/misc/matrixTranspose.java new file mode 100644 index 000000000000..40634f18b5f6 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/misc/matrixTranspose.java @@ -0,0 +1,83 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +/** + * + * + * <h1>Find the Transpose of Matrix!</h1> + * + * Simply take input from the user and print the matrix before the transpose and + * after the transpose. + * + * <p> + * <b>Note:</b> 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 final class matrixTranspose { + private 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; + int j; + int row; + int 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/Java/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java b/Java/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java new file mode 100644 index 000000000000..f43841f1f184 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java @@ -0,0 +1,34 @@ +package com.thealgorithms.others; + +/* + * A left rotation operation on an array + * shifts each of the array's elements + * given integer n unit to the left. + * + * @author sangin-lee + */ + +public final class ArrayLeftRotation { + private ArrayLeftRotation() { + } + + /* + * Returns the result of left rotation of given array arr and integer n + * + * @param arr : int[] given array + * + * @param n : int given integer + * + * @return : int[] result of left rotation + */ + public static int[] rotateLeft(int[] arr, int n) { + int size = arr.length; + int[] dst = new int[size]; + n = n % size; + for (int i = 0; i < size; i++) { + dst[i] = arr[n]; + n = (n + 1) % size; + } + return dst; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/BFPRT.java b/Java/src/main/java/com/thealgorithms/others/BFPRT.java new file mode 100644 index 000000000000..1a5b44180651 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/BFPRT.java @@ -0,0 +1,146 @@ +package com.thealgorithms.others; + +import java.util.Arrays; + +/** + * BFPRT algorithm. + */ +public final class BFPRT { + private BFPRT() { + } + + public static int[] getMinKNumsByBFPRT(int[] arr, int k) { + if (k < 1 || k > arr.length) { + return null; + } + int minKth = getMinKthByBFPRT(arr, k); + int[] res = new int[k]; + int index = 0; + for (int i = 0; i < arr.length; i++) { + if (arr[i] < minKth) { + res[index++] = arr[i]; + } + } + for (; index != res.length; index++) { + res[index] = minKth; + } + return res; + } + + public static int getMinKthByBFPRT(int[] arr, int k) { + int[] copyArr = copyArray(arr); + return bfprt(copyArr, 0, copyArr.length - 1, k - 1); + } + + public static int[] copyArray(int[] arr) { + int[] copyArr = new int[arr.length]; + System.arraycopy(arr, 0, copyArr, 0, arr.length); + return copyArr; + } + + public static int bfprt(int[] arr, int begin, int end, int i) { + if (begin == end) { + return arr[begin]; + } + int pivot = medianOfMedians(arr, begin, end); + int[] pivotRange = partition(arr, begin, end, pivot); + if (i >= pivotRange[0] && i <= pivotRange[1]) { + return arr[i]; + } else if (i < pivotRange[0]) { + return bfprt(arr, begin, pivotRange[0] - 1, i); + } else { + return bfprt(arr, pivotRange[1] + 1, end, i); + } + } + + /** + * wikipedia: https://en.wikipedia.org/wiki/Median_of_medians . + * + * @param arr an array. + * @param begin begin num. + * @param end end num. + * @return median of medians. + */ + 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++) { + 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) { + 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, ++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; + return pivotRange; + } + + public static int getMedian(int[] arr, int begin, int end) { + insertionSort(arr, begin, end); + int sum = begin + end; + int mid = sum / 2 + (sum % 2); + return arr[mid]; + } + + 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--) { + if (arr[j - 1] > arr[j]) { + swap(arr, j - 1, j); + } else { + break; + } + } + } + } + + 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); + System.out.println(Arrays.toString(minK)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/BankersAlgorithm.java b/Java/src/main/java/com/thealgorithms/others/BankersAlgorithm.java new file mode 100644 index 000000000000..a22d7c737415 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/BankersAlgorithm.java @@ -0,0 +1,179 @@ +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 final class BankersAlgorithm { + private 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]; + System.arraycopy(availableArray, 0, workArray, 0, totalResources); + + 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]) { + 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) { + 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; + int 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/Java/src/main/java/com/thealgorithms/others/BoyerMoore.java b/Java/src/main/java/com/thealgorithms/others/BoyerMoore.java new file mode 100644 index 000000000000..e67427deda79 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/BoyerMoore.java @@ -0,0 +1,54 @@ +/* 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.Optional; + +public final class BoyerMoore { + private BoyerMoore() { + } + + public static Optional<Integer> findMajor(final int[] a) { + final var candidate = findCandidate(a); + final var count = countOccurrences(candidate, a); + if (isMajority(count, a.length)) { + return Optional.of(candidate); + } + return Optional.empty(); + } + + private static int findCandidate(final int[] a) { + int count = 0; + int candidate = -1; + for (final var k : a) { + if (count == 0) { + candidate = k; + count = 1; + } else { + if (k == candidate) { + count++; + } else { + count--; + } + } + } + return candidate; + } + + private static int countOccurrences(final int candidate, final int[] a) { + int count = 0; + for (final var j : a) { + if (j == candidate) { + count++; + } + } + return count; + } + + private static boolean isMajority(final int count, final int totalCount) { + return 2 * count > totalCount; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java b/Java/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java new file mode 100644 index 000000000000..b70fffe82c5b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java @@ -0,0 +1,50 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +/** + * @author Nishita Aggarwal + * <p> + * Brian Kernighan’s Algorithm + * <p> + * algorithm to count the number of set bits in a given number + * <p> + * 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. + * <p> + * If we do n & (n-1) in a loop and count the no of times loop executes we get + * the set bit count. + * <p> + * <p> + * Time Complexity: O(logn) + */ +public final class BrianKernighanAlgorithm { + private 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/Java/src/main/java/com/thealgorithms/others/CRC16.java b/Java/src/main/java/com/thealgorithms/others/CRC16.java new file mode 100644 index 000000000000..85e5cd2c13ae --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/CRC16.java @@ -0,0 +1,30 @@ +package com.thealgorithms.others; + +/** + * Generates a crc16 checksum for a given string + */ +public final class CRC16 { + private CRC16() { + } + + public static void main(String[] args) { + System.out.println(crc16("Hello World!")); + } + + public static String crc16(String message) { + int crc = 0xFFFF; // initial value + int polynomial = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) + byte[] bytes = message.getBytes(); + + for (byte b : bytes) { + for (int i = 0; i < 8; i++) { + boolean bit = ((b >> (7 - i) & 1) == 1); + boolean c15 = ((crc >> 15 & 1) == 1); + crc <<= 1; + if (c15 ^ bit) crc ^= polynomial; + } + } + crc &= 0xffff; + return Integer.toHexString(crc).toUpperCase(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/CRC32.java b/Java/src/main/java/com/thealgorithms/others/CRC32.java new file mode 100644 index 000000000000..180936ed46c1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/CRC32.java @@ -0,0 +1,33 @@ +package com.thealgorithms.others; + +import java.util.BitSet; + +/** + * Generates a crc32 checksum for a given string or byte array + */ +public final class CRC32 { + private 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/Java/src/main/java/com/thealgorithms/others/CRCAlgorithm.java b/Java/src/main/java/com/thealgorithms/others/CRCAlgorithm.java new file mode 100644 index 000000000000..bfa8828e250b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/CRCAlgorithm.java @@ -0,0 +1,201 @@ +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<Integer> message; + + private ArrayList<Integer> dividedMessage; + + private ArrayList<Integer> 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<Integer> 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<integer> + * 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<Integer> x = new ArrayList<>(); + ArrayList<Integer> k = (ArrayList<Integer>) 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<Integer>) x.clone(); + if (!check) { + message.addAll(dividedMessage); + } 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/Java/src/main/java/com/thealgorithms/others/Conway.java b/Java/src/main/java/com/thealgorithms/others/Conway.java new file mode 100644 index 000000000000..ab39890c9ece --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Conway.java @@ -0,0 +1,37 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public final class Conway { + private Conway() { + } + + /* + * This class will generate the conway sequence also known as the look and say sequence. + * To generate a member of the sequence from the previous member, read off the digits of the + *previous member, counting the number of digits in groups of the same digit. For example: 1 is + *read off as "one 1" or 11. 11 is read off as "two 1s" or 21. 21 is read off as "one 2, one 1" + *or 1211. 1211 is read off as "one 1, one 2, two 1s" or 111221. 111221 is read off as "three + *1s, two 2s, one 1" or 312211. https://en.wikipedia.org/wiki/Look-and-say_sequence + * */ + + private static final StringBuilder BUILDER = new StringBuilder(); + + protected static List<String> generateList(String originalString, int maxIteration) { + List<String> numbers = new ArrayList<>(); + for (int i = 0; i < maxIteration; i++) { + originalString = generateNextElement(originalString); + numbers.add(originalString); + } + return numbers; + } + + public static String generateNextElement(String originalString) { + BUILDER.setLength(0); + String[] stp = originalString.split("(?<=(.))(?!\\1)"); + Arrays.stream(stp).forEach(s -> BUILDER.append(s.length()).append(s.charAt(0))); + return BUILDER.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/CountChar.java b/Java/src/main/java/com/thealgorithms/others/CountChar.java new file mode 100644 index 000000000000..ad858137726b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/CountChar.java @@ -0,0 +1,17 @@ +package com.thealgorithms.others; + +public final class CountChar { + private CountChar() { + } + + /** + * Count non space character in string + * + * @param str String to count the characters + * @return number of character in the specified string + */ + + public static int countCharacters(String str) { + return str.replaceAll("\\s", "").length(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/CountWords.java b/Java/src/main/java/com/thealgorithms/others/CountWords.java new file mode 100644 index 000000000000..26b9c50d928c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/CountWords.java @@ -0,0 +1,46 @@ +package com.thealgorithms.others; + +/** + * @author Marcus + */ +public final class CountWords { + private CountWords() { + } + + /** + * @brief counts the number of words in the input string + * @param s the input string + * @return the number of words in the input string + */ + public static int wordCount(String s) { + if (s == null || s.isEmpty()) { + return 0; + } + return s.trim().split("[\\s]+").length; + } + + private static String removeSpecialCharacters(String s) { + StringBuilder sb = new StringBuilder(); + for (char c : s.toCharArray()) { + if (Character.isLetterOrDigit(c) || Character.isWhitespace(c)) { + sb.append(c); + } + } + return sb.toString(); + } + + /** + * 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 + */ + public static int secondaryWordCount(String s) { + if (s == null) { + return 0; + } + return wordCount(removeSpecialCharacters(s)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/Damm.java b/Java/src/main/java/com/thealgorithms/others/Damm.java new file mode 100644 index 000000000000..55a4c5b81a89 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Damm.java @@ -0,0 +1,116 @@ +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. + * + * @see <a href="https://en.wikipedia.org/wiki/Damm_algorithm">Wiki. Damm + * algorithm</a> + */ +public final class Damm { + private 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. + */ + private static final byte[][] DAMM_TABLE = { + {0, 3, 1, 7, 5, 9, 8, 6, 4, 2}, + {7, 0, 9, 2, 1, 5, 4, 8, 6, 3}, + {4, 2, 0, 6, 8, 7, 1, 3, 5, 9}, + {1, 7, 5, 0, 9, 8, 3, 4, 2, 6}, + {6, 1, 2, 3, 0, 4, 5, 9, 7, 8}, + {3, 6, 7, 4, 2, 0, 9, 5, 8, 1}, + {5, 8, 6, 9, 7, 2, 0, 1, 3, 4}, + {8, 9, 4, 5, 3, 6, 2, 0, 1, 7}, + {9, 4, 3, 8, 6, 1, 7, 2, 0, 5}, + {2, 5, 8, 1, 4, 3, 6, 7, 9, 0}, + }; + + /** + * Check input digits by Damm algorithm. + * + * @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 + */ + public static boolean dammCheck(String digits) { + checkInput(digits); + int[] numbers = toIntArray(digits); + + int checksum = 0; + for (int number : numbers) { + checksum = DAMM_TABLE[checksum][number]; + } + + return checksum == 0; + } + + /** + * 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 + */ + public static String addDammChecksum(String initialDigits) { + checkInput(initialDigits); + int[] numbers = toIntArray(initialDigits); + + int checksum = 0; + for (int number : numbers) { + checksum = DAMM_TABLE[checksum][number]; + } + + return initialDigits + checksum; + } + + public static void main(String[] args) { + System.out.println("Damm algorithm usage examples:"); + var validInput = "5724"; + var invalidInput = "5824"; + checkAndPrint(validInput); + checkAndPrint(invalidInput); + + System.out.println("\nCheck digit generation example:"); + var input = "572"; + generateAndPrint(input); + } + + private static void checkAndPrint(String input) { + String validationResult = Damm.dammCheck(input) ? "valid" : "not valid"; + System.out.println("Input '" + input + "' is " + validationResult); + } + + private static void generateAndPrint(String input) { + String result = addDammChecksum(input); + System.out.println("Generate and add checksum to initial value '" + input + "'. Result: '" + result + "'"); + } + + private static void checkInput(String input) { + Objects.requireNonNull(input); + if (!input.matches("\\d+")) { + throw new IllegalArgumentException("Input '" + input + "' contains not only digits"); + } + } + + private static int[] toIntArray(String string) { + return string.chars().map(i -> Character.digit(i, 10)).toArray(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/Dijkstra.java b/Java/src/main/java/com/thealgorithms/others/Dijkstra.java new file mode 100644 index 000000000000..e2a778f8d6c3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Dijkstra.java @@ -0,0 +1,249 @@ +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. + * + * <p> + * 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. + * + * <p> + * Original source of code: + * https://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java Also most of the + * comments are from RosettaCode. + */ +import java.util.HashMap; +import java.util.Map; +import java.util.NavigableSet; +import java.util.TreeSet; + +public final class Dijkstra { + private 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<String, Vertex> graph; + + /** + * One edge of the graph (only used by Graph constructor) + */ + public static class Edge { + + public final String v1; + public final String v2; + public final int dist; + + 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<Vertex> { + + public final String name; + // MAX_VALUE assumed to be infinity + public int dist = Integer.MAX_VALUE; + public Vertex previous = null; + public final Map<Vertex, Integer> neighbours = new HashMap<>(); + + 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; + } + return neighbours != null ? neighbours.equals(vertex.neighbours) : vertex.neighbours == null; + } + + @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 + */ + 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<Vertex> 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<Vertex> q) { + Vertex u; + Vertex 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<Vertex, Integer> 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/Java/src/main/java/com/thealgorithms/others/EulersFunction.java b/Java/src/main/java/com/thealgorithms/others/EulersFunction.java new file mode 100644 index 000000000000..f08e5e4fa395 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/EulersFunction.java @@ -0,0 +1,39 @@ +package com.thealgorithms.others; + +/** + * @brief utility class for <a href="https://en.wikipedia.org/wiki/Euler%27s_totient_function">Euler's totient function</a> + */ +public final class EulersFunction { + private EulersFunction() { + } + + private static void checkInput(int n) { + if (n <= 0) { + throw new IllegalArgumentException("n must be positive."); + } + } + + /** + * @brief computes the value of Euler's totient function for given input + * @details has time complexity of O(sqrt(n)) + * @param n the input + * @exception IllegalArgumentException n is non-positive + * @return the value of Euler's totient function for the input + */ + public static int getEuler(int n) { + checkInput(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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/FibbonaciSeries.java b/Java/src/main/java/com/thealgorithms/others/FibbonaciSeries.java new file mode 100644 index 000000000000..a4815296e547 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/FibbonaciSeries.java @@ -0,0 +1,37 @@ +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. + * + * <p> + * Fibonacci sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21,... + * + * <p> + * 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 final class FibbonaciSeries { + private 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; + int 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/Java/src/main/java/com/thealgorithms/others/FloydTriangle.java b/Java/src/main/java/com/thealgorithms/others/FloydTriangle.java new file mode 100644 index 000000000000..fbeaec339248 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/FloydTriangle.java @@ -0,0 +1,22 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +final class FloydTriangle { + private 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(); + int 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/Java/src/main/java/com/thealgorithms/others/GuassLegendre.java b/Java/src/main/java/com/thealgorithms/others/GuassLegendre.java new file mode 100644 index 000000000000..5ecfdf2b84cc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/GuassLegendre.java @@ -0,0 +1,48 @@ +package com.thealgorithms.others; + +/** + * Guass Legendre Algorithm ref + * https://en.wikipedia.org/wiki/Gauss–Legendre_algorithm + * + * @author AKS1996 + */ +public final class GuassLegendre { + private 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; + double b = Math.pow(2, -0.5); + double t = 0.25; + double 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/Java/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java b/Java/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java new file mode 100644 index 000000000000..0ae1e451bc6a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java @@ -0,0 +1,39 @@ +package com.thealgorithms.others; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +public final class HappyNumbersSeq { + private HappyNumbersSeq() { + } + + private static final Set<Integer> CYCLE_NUMS = new HashSet<>(Arrays.asList(4, 16, 20, 37, 58, 145)); + + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + System.out.print("Enter number: "); + int n = in.nextInt(); + while (n != 1 && !isSad(n)) { + System.out.print(n + " "); + n = sumSquares(n); + } + String res = n == 1 ? "1 Happy number" : "Sad number"; + System.out.println(res); + in.close(); + } + + private static int sumSquares(int n) { + int s = 0; + for (; n > 0; n /= 10) { + int r = n % 10; + s += r * r; + } + return s; + } + + private static boolean isSad(int n) { + return CYCLE_NUMS.contains(n); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/Huffman.java b/Java/src/main/java/com/thealgorithms/others/Huffman.java new file mode 100644 index 000000000000..4fdee5d5e70e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Huffman.java @@ -0,0 +1,125 @@ +package com.thealgorithms.others; + +import java.util.Comparator; +import java.util.PriorityQueue; +import java.util.Scanner; + +// 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<HuffmanNode> { + + public int compare(HuffmanNode x, HuffmanNode y) { + return x.data - y.data; + } +} + +public final class Huffman { + private 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<HuffmanNode> q = new PriorityQueue<HuffmanNode>(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, ""); + s.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java b/Java/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java new file mode 100644 index 000000000000..bb88c7e3ae2f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Implementing_auto_completing_features_using_trie.java @@ -0,0 +1,170 @@ +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); + + // 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 nodes below the 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/Java/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java b/Java/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java new file mode 100644 index 000000000000..15093549871b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java @@ -0,0 +1,52 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +public final class InsertDeleteInArray { + private InsertDeleteInArray() { + } + + public static void main(String[] args) { + try (Scanner s = new Scanner(System.in)) { + 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 insertPos = 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 <= insertPos) { + b[i] = a[i]; + } else { + b[i] = a[i - 1]; + } + } + b[insertPos] = 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 delPos = s.nextInt(); + for (i = delPos; i < size2 - 1; i++) { + b[i] = b[i + 1]; + } + for (i = 0; i < size2 - 1; i++) { + System.out.println(b[i]); + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/KMP.java b/Java/src/main/java/com/thealgorithms/others/KMP.java new file mode 100644 index 000000000000..73eaf2fc9beb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/KMP.java @@ -0,0 +1,60 @@ +package com.thealgorithms.others; + +/** + * Implementation of Knuth–Morris–Pratt algorithm Usage: see the main function + * for an example + */ +public final class KMP { + private 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/Java/src/main/java/com/thealgorithms/others/KochSnowflake.java b/Java/src/main/java/com/thealgorithms/others/KochSnowflake.java new file mode 100644 index 000000000000..0e2600a7d72f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/KochSnowflake.java @@ -0,0 +1,245 @@ +package com.thealgorithms.others; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +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 final class KochSnowflake { + private KochSnowflake() { + } + + public static void main(String[] args) { + // Test Iterate-method + ArrayList<Vector2> vectors = new ArrayList<Vector2>(); + vectors.add(new Vector2(0, 0)); + vectors.add(new Vector2(1, 0)); + ArrayList<Vector2> 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<Vector2> iterate(ArrayList<Vector2> initialVectors, int steps) { + ArrayList<Vector2> 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<Vector2> initialVectors = new ArrayList<Vector2>(); + initialVectors.add(vector1); + initialVectors.add(vector2); + initialVectors.add(vector3); + initialVectors.add(vector1); + ArrayList<Vector2> 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<Vector2> iterationStep(ArrayList<Vector2> vectors) { + ArrayList<Vector2> newVectors = new ArrayList<Vector2>(); + 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<Vector2> 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; + double y; + + 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/Java/src/main/java/com/thealgorithms/others/Krishnamurthy.java b/Java/src/main/java/com/thealgorithms/others/Krishnamurthy.java new file mode 100644 index 000000000000..8e5ba7c6f1c7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Krishnamurthy.java @@ -0,0 +1,38 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +final class Krishnamurthy { + private Krishnamurthy() { + } + + static int fact(int n) { + int i; + int 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; + int b; + int 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/Java/src/main/java/com/thealgorithms/others/LineSweep.java b/Java/src/main/java/com/thealgorithms/others/LineSweep.java new file mode 100644 index 000000000000..946ba6edb475 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/LineSweep.java @@ -0,0 +1,55 @@ +package com.thealgorithms.others; +import java.util.Arrays; +import java.util.Comparator; + +/* Line Sweep algorithm can be used to solve range problems by first sorting the list of ranges + * by the start value of the range in non-decreasing order and doing a "sweep" through the number + * line(x-axis) by incrementing the start point by 1 and decrementing the end point+1 by 1 on the + * number line. + * An overlapping range is defined as (StartA <= EndB) AND (EndA >= StartB) + * References + * https://en.wikipedia.org/wiki/Sweep_line_algorithm + * https://en.wikipedia.org/wiki/De_Morgan%27s_laws> + */ +public final class LineSweep { + private LineSweep() { + } + + /** + * Find Maximum end point + * param = ranges : Array of range[start,end] + * return Maximum Endpoint + */ + public static int findMaximumEndPoint(int[][] ranges) { + Arrays.sort(ranges, Comparator.comparingInt(a -> a[1])); + return ranges[ranges.length - 1][1]; + } + + /** + * Find if any ranges overlap + * param = ranges : Array of range[start,end] + * return true if overlap exists false otherwise. + */ + public static boolean isOverlap(int[][] ranges) { + + int maximumEndPoint = findMaximumEndPoint(ranges); + Arrays.sort(ranges, Comparator.comparingInt(a -> a[0])); + int[] numberLine = new int[maximumEndPoint + 2]; + for (int[] range : ranges) { + + int start = range[0]; + int end = range[1]; + + numberLine[start] += 1; + numberLine[end + 1] -= 1; + } + + int current = 0; + int overlaps = 0; + for (int num : numberLine) { + current += num; + overlaps = Math.max(overlaps, current); + } + return overlaps > 1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java b/Java/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java new file mode 100644 index 000000000000..36bcca3edc00 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java @@ -0,0 +1,68 @@ +package com.thealgorithms.others; + +/** + * * + * A pseudorandom number generator. + * + * @author Tobias Carryer + * @date October 10, 2017 + */ +public class LinearCongruentialGenerator { + + private final double a; + private final double c; + private final double m; + private double 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/Java/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java b/Java/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java new file mode 100644 index 000000000000..c8328a4ee552 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java @@ -0,0 +1,96 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; + +/** + * @brief Class for finding the lowest base in which a given integer is a palindrome. + cf. https://oeis.org/A016026 + */ +public final class LowestBasePalindrome { + private LowestBasePalindrome() { + } + + private static void checkBase(int base) { + if (base <= 1) { + throw new IllegalArgumentException("base must be greater than 1."); + } + } + + private static void checkNumber(int number) { + if (number < 0) { + throw new IllegalArgumentException("number must be nonnegative."); + } + } + + /** + * @brief computes the representation of the input number in given base + * @param number the input number + * @param base the given base + * @exception IllegalArgumentException number is negative or base is less than 2 + * @return the list containing the digits of the input number in the given base, the most + * significant digit is at the end of the array + */ + public static ArrayList<Integer> computeDigitsInBase(int number, int base) { + checkNumber(number); + checkBase(base); + var result = new ArrayList<Integer>(); + while (number > 0) { + result.add(number % base); + number /= base; + } + return result; + } + + /** + * @brief checks if the input array is a palindrome + * @brief list the input array + * @return true, if the input array is a palindrome, false otherwise + */ + public static boolean isPalindromic(ArrayList<Integer> list) { + for (int pos = 0; pos < list.size() / 2; ++pos) { + if (list.get(pos) != list.get(list.size() - 1 - pos)) { + return false; + } + } + return true; + } + + /** + * @brief checks if representation of the input number in given base is a palindrome + * @param number the input number + * @param base the given base + * @exception IllegalArgumentException number is negative or base is less than 2 + * @return true, if the input number represented in the given base is a palindrome, false + * otherwise + */ + public static boolean isPalindromicInBase(int number, int base) { + checkNumber(number); + checkBase(base); + + if (number <= 1) { + return true; + } + + if (number % base == 0) { + // the last digit of number written in base is 0 + return false; + } + + return isPalindromic(computeDigitsInBase(number, base)); + } + + /** + * @brief finds the smallest base for which the representation of the input number is a + * palindrome + * @param number the input number + * @exception IllegalArgumentException number is negative + * @return the smallest base for which the representation of the input number is a palindrome + */ + public static int lowestBasePalindrome(int number) { + int base = 2; + while (!isPalindromicInBase(number, base)) { + ++base; + } + return base; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/Luhn.java b/Java/src/main/java/com/thealgorithms/others/Luhn.java new file mode 100644 index 000000000000..600128a7725b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Luhn.java @@ -0,0 +1,160 @@ +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. + * + * <p> + * 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.</p> + * + * <p> + * 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).</p> + * + * <p> + * The check digit is computed as follows:</p> + * <ol> + * <li>Take the original number and starting from the rightmost digit moving + * left, double the value of every second digit (including the rightmost + * digit).</li> + * <li>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.</li> + * <li>Sum up the resulting values from all positions (s).</li> + * <li>The calculated check digit is equal to {@code 10 - s % 10}.</li> + * </ol> + * + * @see <a href="https://en.wikipedia.org/wiki/Luhn_algorithm">Wiki</a> + */ +public final class Luhn { + private Luhn() { + } + + /** + * 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 + */ + public static boolean luhnCheck(int[] digits) { + int[] numbers = Arrays.copyOf(digits, digits.length); + int sum = 0; + + for (int i = numbers.length - 1; i >= 0; i--) { + if (i % 2 == 0) { + int temp = numbers[i] * 2; + if (temp > 9) { + temp = temp - 9; + } + numbers[i] = temp; + } + sum += numbers[i]; + } + + return sum % 10 == 0; + } + + public static void main(String[] args) { + System.out.println("Luhn algorithm usage examples:"); + int[] validInput = {4, 5, 6, 1, 2, 6, 1, 2, 1, 2, 3, 4, 5, 4, 6, 7}; + int[] invalidInput = {4, 5, 6, 1, 2, 6, 1, 2, 1, 2, 3, 4, 5, 4, 6, 4}; // typo in last + // symbol + checkAndPrint(validInput); + checkAndPrint(invalidInput); + + System.out.println("\nBusiness examples:"); + String validCardNumber = "5265 9251 6151 1412"; + String invalidCardNumber = "4929 3231 3088 1896"; + String illegalCardNumber = "4F15 BC06 3A88 76D5"; + businessExample(validCardNumber); + businessExample(invalidCardNumber); + businessExample(illegalCardNumber); + } + + private static void checkAndPrint(int[] input) { + String validationResult = Luhn.luhnCheck(input) ? "valid" : "not valid"; + System.out.println("Input " + Arrays.toString(input) + " is " + validationResult); + } + + /* + ======================== + Business usage example + ======================== + */ + /** + * Object representation of credit card. + */ + 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 + * @return credit card object + * @throws IllegalArgumentException if input string is not 16 digits or + * if Luhn check was failed + */ + public static CreditCard fromString(String cardNumber) { + Objects.requireNonNull(cardNumber); + String trimmedCardNumber = cardNumber.replaceAll(" ", ""); + if (trimmedCardNumber.length() != DIGITS_COUNT || !trimmedCardNumber.matches("\\d+")) { + throw new IllegalArgumentException("{" + cardNumber + "} - is not a card number"); + } + + int[] cardNumbers = toIntArray(trimmedCardNumber); + boolean isValid = luhnCheck(cardNumbers); + if (!isValid) { + throw new IllegalArgumentException("Credit card number {" + cardNumber + "} - have a typo"); + } + + return new CreditCard(cardNumbers); + } + + /** + * @return string representation separated by space every 4 digits. + * Example: "5265 9251 6151 1412" + */ + public String number() { + StringBuilder result = new StringBuilder(); + for (int i = 0; i < DIGITS_COUNT; i++) { + if (i % 4 == 0 && i != 0) { + result.append(" "); + } + result.append(digits[i]); + } + return result.toString(); + } + + @Override + public String toString() { + return String.format("%s {%s}", CreditCard.class.getSimpleName(), number()); + } + + private static int[] toIntArray(String string) { + return string.chars().map(i -> Character.digit(i, 10)).toArray(); + } + } + + private static void businessExample(String cardNumber) { + try { + System.out.println("Trying to create CreditCard object from valid card number: " + cardNumber); + CreditCard creditCard = CreditCard.fromString(cardNumber); + System.out.println("And business object is successfully created: " + creditCard + "\n"); + } catch (IllegalArgumentException e) { + System.out.println("And fail with exception message: " + e.getMessage() + "\n"); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/Mandelbrot.java b/Java/src/main/java/com/thealgorithms/others/Mandelbrot.java new file mode 100644 index 000000000000..6d7588090ba8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Mandelbrot.java @@ -0,0 +1,188 @@ +package com.thealgorithms.others; + +import java.awt.Color; +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 final class Mandelbrot { + private 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/Java/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java b/Java/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java new file mode 100644 index 000000000000..0bafc435aa75 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java @@ -0,0 +1,72 @@ +package com.thealgorithms.others; + +import java.util.HashSet; + +/* +References: https://en.wikipedia.org/wiki/Streaming_algorithm +* In this model, the function of interest is computing over a fixed-size window in the stream. As the stream progresses, +* items from the end of the window are removed from consideration while new items from the stream take their place. +* @author Swarga-codes (https://github.com/Swarga-codes) +*/ +public final class MaximumSumOfDistinctSubarraysWithLengthK { + private MaximumSumOfDistinctSubarraysWithLengthK() { + } + /* + * Returns the maximum sum of subarray of size K consisting of distinct + * elements. + * + * @param k size of the subarray which should be considered from the given + * array. + * + * @param nums is the array from which we would be finding the required + * subarray. + * + * @return the maximum sum of distinct subarray of size K. + */ + public static long maximumSubarraySum(int k, int... nums) { + if (nums.length < k) return 0; + long max = 0; // this will store the max sum which will be our result + long s = 0; // this will store the sum of every k elements which can be used to compare with + // max + HashSet<Integer> set = new HashSet<>(); // this can be used to store unique elements in our subarray + // Looping through k elements to get the sum of first k elements + for (int i = 0; i < k; i++) { + s += nums[i]; + set.add(nums[i]); + } + // Checking if the first kth subarray contains unique elements or not if so then + // we assign that to max + if (set.size() == k) { + max = s; + } + // Looping through the rest of the array to find different subarrays and also + // utilising the sliding window algorithm to find the sum + // in O(n) time complexity + for (int i = 1; i < nums.length - k + 1; i++) { + s = s - nums[i - 1]; + s = s + nums[i + k - 1]; + int j = i; + boolean flag = false; // flag value which says that the subarray contains distinct elements + while (j < i + k && set.size() < k) { + if (nums[i - 1] == nums[j]) { + flag = true; + break; + } else { + j++; + } + } + if (!flag) { + set.remove(nums[i - 1]); + } + set.add(nums[i + k - 1]); + // if the subarray contains distinct elements then we compare and update the max + // value + if (set.size() == k) { + if (max < s) { + max = s; + } + } + } + return max; // the final maximum sum + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java b/Java/src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java new file mode 100644 index 000000000000..1f5f455f24e3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/MemoryManagementAlgorithms.java @@ -0,0 +1,284 @@ +package com.thealgorithms.others; + +/** + * @author Alexandros Lemonaris + */ + +import java.util.ArrayList; + +public abstract class MemoryManagementAlgorithms { + + /** + * Method to allocate memory to blocks according to CPU algorithms. + * Use of inheritance to avoid repeated code. + * Abstract method since it is implemented different for each 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. + */ + public abstract ArrayList<Integer> fitProcess(int[] sizeOfBlocks, int[] sizeOfProcesses); + + /** + * A constant value used to indicate that an allocation has not been made. + * This value is used as a sentinel value to represent that no allocation has been made + * when allocating space in an array or other data structure. + * The value is -255 and is marked as protected and final to ensure that it cannot be modified + * from outside the class and that its value remains consistent throughout the program + * execution. + * + * @author: Ishan Makadia (github.com/intrepid-ishan) + * @version: April 06, 2023 + */ + protected static final int NO_ALLOCATION = -255; +} + +/** + * @author Dekas Dimitrios + */ +class BestFitCPU extends MemoryManagementAlgorithms { + + /** + * 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. + */ + public ArrayList<Integer> fitProcess(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the best-fit + // algorithm + ArrayList<Integer> 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; + } +} + +/** + * @author Dekas Dimitrios + */ +class WorstFitCPU extends MemoryManagementAlgorithms { + + /** + * 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. + */ + public ArrayList<Integer> fitProcess(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the worst-fit + // algorithm + ArrayList<Integer> 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; + } +} + +/** + * @author Dekas Dimitrios + */ +class FirstFitCPU extends MemoryManagementAlgorithms { + + /** + * 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. + */ + public ArrayList<Integer> fitProcess(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the first-fit + // algorithm + ArrayList<Integer> 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; + } +} + +/** + * @author Alexandros Lemonaris + */ +class NextFit extends MemoryManagementAlgorithms { + + private int counter = 0; // variable that keeps the position of the last registration into the memory + + /** + * Method to find the index of the memory block that is going to fit the + * given process based on the next fit algorithm. In the case of next fit, + * if the search is interrupted in between, the new search is carried out from the last + * location. + * + * @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 int findNextFit(int[] blockSizes, int processSize) { + for (int i = 0; i < blockSizes.length; i++) { + if (counter + i >= blockSizes.length) { + counter = -i; // starts from the start of the array + } + if (blockSizes[i + counter] >= processSize) { + counter += i; + return counter; + } + } + // If there is not a block that can fit the process, return -255 as the result + counter += blockSizes.length; // counter keeps its last value + 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. + */ + public ArrayList<Integer> fitProcess(int[] sizeOfBlocks, int[] sizeOfProcesses) { + // The array list responsible for saving the memory allocations done by the first-fit + // algorithm + ArrayList<Integer> memAlloc = new ArrayList<>(); + // Do this for every process + for (int processSize : sizeOfProcesses) { + int chosenBlockIdx = findNextFit(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; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java b/Java/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java new file mode 100644 index 000000000000..cd2cd02ab908 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java @@ -0,0 +1,128 @@ +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 " + 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; + int score1; + int 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.printf("From %02d and %02d, %s chooses %02d%n", 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/Java/src/main/java/com/thealgorithms/others/PageRank.java b/Java/src/main/java/com/thealgorithms/others/PageRank.java new file mode 100644 index 000000000000..c7be7a9882bc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/PageRank.java @@ -0,0 +1,95 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +class PageRank { + + public static void main(String[] args) { + int nodes; + int i; + int 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 iterationStep = 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.print("\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 (iterationStep <= 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 " + iterationStep + "th Step \n"); + + for (k = 1; k <= totalNodes; k++) { + System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); + } + + iterationStep = iterationStep + 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.print("\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/Java/src/main/java/com/thealgorithms/others/PasswordGen.java b/Java/src/main/java/com/thealgorithms/others/PasswordGen.java new file mode 100644 index 000000000000..7d21f112d480 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/PasswordGen.java @@ -0,0 +1,44 @@ +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 + */ +final class PasswordGen { + private PasswordGen() { + } + + static String generatePassword(int minLength, int maxLength) { + Random random = new Random(); + + String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + String lower = "abcdefghijklmnopqrstuvwxyz"; + String numbers = "0123456789"; + String specialChars = "!@#$%^&*(){}?"; + + String allChars = upper + lower + numbers + specialChars; + + List<Character> letters = new ArrayList<Character>(); + 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(maxLength - minLength) + minLength; i > 0; --i) { + password.append(letters.get(random.nextInt(letters.size()))); + } + + return password.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/PerlinNoise.java b/Java/src/main/java/com/thealgorithms/others/PerlinNoise.java new file mode 100644 index 000000000000..e6551ed6b9ee --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/PerlinNoise.java @@ -0,0 +1,171 @@ +package com.thealgorithms.others; + +import java.util.Random; +import java.util.Scanner; + +/** + * For detailed info and implementation see: <a + * href="http://devmag.org.za/2009/04/25/perlin-noise/">Perlin-Noise</a> + */ +public final class PerlinNoise { + private 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/Java/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java b/Java/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java new file mode 100644 index 000000000000..437b59cb1070 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/PrintAMatrixInSpiralOrder.java @@ -0,0 +1,62 @@ +package com.thealgorithms.others; + +import java.util.ArrayList; +import java.util.List; + +public class PrintAMatrixInSpiralOrder { + /** + * Search a key in row and column wise sorted matrix + * + * @param matrix matrix to be searched + * @param row number of rows matrix has + * @param col number of columns matrix has + * @author Sadiul Hakim : https://github.com/sadiul-hakim + */ + + public List<Integer> print(int[][] matrix, int row, int col) { + + // r traverses matrix row wise from first + int r = 0; + // c traverses matrix column wise from first + int c = 0; + int i; + + List<Integer> result = new ArrayList<>(); + + while (r < row && c < col) { + // print first row of matrix + for (i = c; i < col; i++) { + result.add(matrix[r][i]); + } + + // increase r by one because first row printed + r++; + + // print last column + for (i = r; i < row; i++) { + result.add(matrix[i][col - 1]); + } + + // decrease col by one because last column has been printed + col--; + + // print rows from last except printed elements + if (r < row) { + for (i = col - 1; i >= c; i--) { + result.add(matrix[row - 1][i]); + } + + row--; + } + + // print columns from first except printed elements + if (c < col) { + for (i = row - 1; i >= r; i--) { + result.add(matrix[i][c]); + } + c++; + } + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java b/Java/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java new file mode 100644 index 000000000000..259e108a354d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java @@ -0,0 +1,175 @@ +package com.thealgorithms.others; + +import java.util.Stack; + +/** + * This implements Queue using two Stacks. + * + * <p> + * Big O Runtime: insert(): O(1) remove(): O(1) amortized isEmpty(): O(1) + * + * <p> + * 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<Object> inStack; + // Stack to keep track of elements to be removed next in queue + private Stack<Object> outStack; + + /** + * Constructor + */ + 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 final class QueueUsingTwoStacks { + private 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/Java/src/main/java/com/thealgorithms/others/RabinKarp.java b/Java/src/main/java/com/thealgorithms/others/RabinKarp.java new file mode 100644 index 000000000000..f8ca33becad3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/RabinKarp.java @@ -0,0 +1,81 @@ +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 final class RabinKarp { + private RabinKarp() { + } + + public static Scanner scanner = null; + public static final int ALPHABET_SIZE = 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(ALPHABET_SIZE, 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 = (ALPHABET_SIZE * p + pattern.charAt(i)) % q; + t = (ALPHABET_SIZE * 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<n-m then 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 to get + // the hash value of the next window of characters in the text + if (i < n - m) { + t = (ALPHABET_SIZE * (t - text.charAt(i) * h) + text.charAt(i + m)) % q; + + // if hash value becomes less than zero than q is added to make it positive + if (t < 0) { + t = (t + q); + } + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java b/Java/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java new file mode 100644 index 000000000000..695a10648b6c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java @@ -0,0 +1,47 @@ +package com.thealgorithms.others; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * @author Varun Upadhyay (https://github.com/varunu28) + */ +public final class RemoveDuplicateFromString { + private RemoveDuplicateFromString() { + } + + public static void main(String[] args) throws Exception { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + String inpStr = br.readLine(); + + System.out.println("Actual string is: " + inpStr); + System.out.println("String after removing duplicates: " + removeDuplicate(inpStr)); + + br.close(); + } + + /** + * This method produces a string after removing all the duplicate characters + * from input string and returns it Example: Input String - "aabbbccccddddd" + * Output String - "abcd" + * + * @param s String from which duplicate characters have to be removed + * @return string with only unique characters + */ + public static String removeDuplicate(String s) { + if (s == null || s.isEmpty()) { + return s; + } + + StringBuilder sb = new StringBuilder(); + int n = s.length(); + + for (int i = 0; i < n; i++) { + if (sb.toString().indexOf(s.charAt(i)) == -1) { + sb.append(s.charAt(i)); + } + } + + return sb.toString(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/ReturnSubsequence.java b/Java/src/main/java/com/thealgorithms/others/ReturnSubsequence.java new file mode 100644 index 000000000000..ef376c47a8f8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/ReturnSubsequence.java @@ -0,0 +1,46 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +public final class ReturnSubsequence { + private ReturnSubsequence() { + } + + public static void main(String[] args) { + System.out.println("Enter String: "); + Scanner s = new Scanner(System.in); + String givenString = s.next(); // given string + String[] subsequence = returnSubsequence(givenString); // calling returnSubsequence() function + System.out.println("Subsequences : "); + // print the given array of subsequences + for (int i = 0; i < subsequence.length; i++) { + System.out.println(subsequence[i]); + } + s.close(); + } + + /** + * @param givenString + * @return subsequence + */ + private static String[] returnSubsequence(String givenString) { + if (givenString.length() == 0) { // in it // If string is empty we will create an array of + // size=1 and insert "" (Empty string) + String[] ans = new String[1]; + ans[0] = ""; + return ans; + } + String[] smallAns = returnSubsequence(givenString.substring(1)); // recursive call to get subsequences of substring starting from index + // position=1 + + String[] ans = new String[2 * smallAns.length]; // Our answer will be an array off string of size=2*smallAns + System.arraycopy(smallAns, 0, ans, 0, smallAns.length); + + for (int k = 0; k < smallAns.length; k++) { + ans[k + smallAns.length] = givenString.charAt(0) + smallAns[k]; // Insert character at index=0 of the given + // substring in front of every string + // in smallAns + } + return ans; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java b/Java/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java new file mode 100644 index 000000000000..2c26f8eae4dc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java @@ -0,0 +1,63 @@ +package com.thealgorithms.others; + +/* Program to reverse a Stack using Recursion*/ +import java.util.Stack; + +public final class ReverseStackUsingRecursion { + private ReverseStackUsingRecursion() { + } + + // Stack + private static Stack<Integer> 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<Integer> 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/Java/src/main/java/com/thealgorithms/others/RootPrecision.java b/Java/src/main/java/com/thealgorithms/others/RootPrecision.java new file mode 100644 index 000000000000..bc195ffca5ae --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/RootPrecision.java @@ -0,0 +1,38 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +public final class RootPrecision { + private 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/Java/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java similarity index 88% rename from src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java rename to Java/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java index e2b47f8e627d..2ea3de814d0d 100644 --- a/src/main/java/com/thealgorithms/others/RotateMatriceBy90Degree.java +++ b/Java/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java @@ -4,9 +4,11 @@ * 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.*; +import java.util.Scanner; -class Rotate_by_90_degree { +final class Rotate_by_90_degrees { + private Rotate_by_90_degrees() { + } public static void main(String[] args) { Scanner sc = new Scanner(System.in); @@ -41,7 +43,9 @@ static void printMatrix(int[][] arr) { /** * Class containing the algo to roate matrix by 90 degree */ -class Rotate { +final class Rotate { + private Rotate() { + } static void rotate(int[][] a) { int n = a.length; @@ -54,7 +58,8 @@ static void rotate(int[][] a) { } } } - int i = 0, k = n - 1; + int i = 0; + int k = n - 1; while (i < k) { for (int j = 0; j < n; j++) { int temp = a[i][j]; diff --git a/Java/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java b/Java/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java new file mode 100644 index 000000000000..6a3412500d11 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java @@ -0,0 +1,66 @@ +package com.thealgorithms.others; + +import java.util.Arrays; + +/** + * @brief utility class implementing <a href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes">Sieve of Eratosthenes</a> + */ +public final class SieveOfEratosthenes { + private SieveOfEratosthenes() { + } + + private static void checkInput(int n) { + if (n <= 0) { + throw new IllegalArgumentException("n must be positive."); + } + } + + private static Type[] sievePrimesTill(int n) { + checkInput(n); + Type[] isPrimeArray = new Type[n + 1]; + Arrays.fill(isPrimeArray, Type.PRIME); + isPrimeArray[0] = Type.NOT_PRIME; + isPrimeArray[1] = Type.NOT_PRIME; + + double cap = Math.sqrt(n); + for (int i = 2; i <= cap; i++) { + if (isPrimeArray[i] == Type.PRIME) { + for (int j = 2; i * j <= n; j++) { + isPrimeArray[i * j] = Type.NOT_PRIME; + } + } + } + return isPrimeArray; + } + + private static int countPrimes(Type[] isPrimeArray) { + return (int) Arrays.stream(isPrimeArray).filter(element -> element == Type.PRIME).count(); + } + + private static int[] extractPrimes(Type[] isPrimeArray) { + int numberOfPrimes = countPrimes(isPrimeArray); + int[] primes = new int[numberOfPrimes]; + int primeIndex = 0; + for (int curNumber = 0; curNumber < isPrimeArray.length; ++curNumber) { + if (isPrimeArray[curNumber] == Type.PRIME) { + primes[primeIndex++] = curNumber; + } + } + return primes; + } + + /** + * @brief finds all of the prime numbers up to the given upper (inclusive) limit + * @param n upper (inclusive) limit + * @exception IllegalArgumentException n is non-positive + * @return the array of all primes up to the given number (inclusive) + */ + public static int[] findPrimesTill(int n) { + return extractPrimes(sievePrimesTill(n)); + } + + private enum Type { + PRIME, + NOT_PRIME, + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/SkylineProblem.java b/Java/src/main/java/com/thealgorithms/others/SkylineProblem.java new file mode 100644 index 000000000000..ece398e70405 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/SkylineProblem.java @@ -0,0 +1,140 @@ +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> skyline) { + Iterator<Skyline> 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<Skyline> findSkyline(int start, int end) { + if (start == end) { + ArrayList<Skyline> 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<Skyline> sky1 = this.findSkyline(start, mid); + ArrayList<Skyline> sky2 = this.findSkyline(mid + 1, end); + + return this.mergeSkyline(sky1, sky2); + } + + public ArrayList<Skyline> mergeSkyline(ArrayList<Skyline> sky1, ArrayList<Skyline> sky2) { + int currentH1 = 0; + int currentH2 = 0; + ArrayList<Skyline> 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/Java/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java b/Java/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java new file mode 100644 index 000000000000..22979e59b555 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java @@ -0,0 +1,80 @@ +package com.thealgorithms.others; + +/** + * @author Prateek Kumar Oraon (https://github.com/prateekKrOraon) + */ +import java.util.Scanner; + +// An implementation of string matching using finite automata +public final class StringMatchFiniteAutomata { + private 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 pattern + 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/Java/src/main/java/com/thealgorithms/others/Sudoku.java b/Java/src/main/java/com/thealgorithms/others/Sudoku.java new file mode 100644 index 000000000000..0839a376c5de --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Sudoku.java @@ -0,0 +1,126 @@ +package com.thealgorithms.others; + +final class Sudoku { + private Sudoku() { + } + + public static boolean isSafe(int[][] board, int row, int col, int num) { + // Row has the unique (row-clash) + 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; + if (board[row][d] == num) { + return false; + } + } + + // Column has the unique numbers (column-clash) + 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) { + return false; + } + } + + // Corresponding square has + // unique number (box-clash) + 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++) { + for (int d = boxColStart; 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 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) { + row = i; + col = j; + + // We still have some remaining + // missing values in Sudoku + isEmpty = false; + break; + } + } + if (!isEmpty) { + break; + } + } + + // No empty space left + if (isEmpty) { + return true; + } + + // Else for each-row backtrack + for (int num = 1; num <= n; num++) { + if (isSafe(board, row, col, num)) { + board[row][col] = num; + if (solveSudoku(board, n)) { + // print(board, n); + return true; + } else { + // replace it + board[row][col] = 0; + } + } + } + return false; + } + + public static void print(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++) { + System.out.print(board[r][d]); + System.out.print(" "); + } + System.out.print("\n"); + + 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}, + }; + int n = board.length; + + if (solveSudoku(board, n)) { + // print solution + print(board, n); + } else { + System.out.println("No solution"); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/TowerOfHanoi.java b/Java/src/main/java/com/thealgorithms/others/TowerOfHanoi.java new file mode 100644 index 000000000000..2216799b987a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/TowerOfHanoi.java @@ -0,0 +1,29 @@ +package com.thealgorithms.others; + +import java.util.Scanner; + +final class TowerOfHanoi { + private 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/Java/src/main/java/com/thealgorithms/others/TwoPointers.java b/Java/src/main/java/com/thealgorithms/others/TwoPointers.java new file mode 100644 index 000000000000..01391ec72e78 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/TwoPointers.java @@ -0,0 +1,44 @@ +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. + * + * <p> + * link: https://www.geeksforgeeks.org/two-pointers-technique/ + */ +final class TwoPointers { + private TwoPointers() { + } + + /** + * 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. + */ + public 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/Java/src/main/java/com/thealgorithms/others/Verhoeff.java b/Java/src/main/java/com/thealgorithms/others/Verhoeff.java new file mode 100644 index 000000000000..9088612aaa43 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/Verhoeff.java @@ -0,0 +1,171 @@ +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 + * errors, and all transposition errors involving two adjacent digits. + * + * <p> + * 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:</p> + * <ol> + * <li>multiplication table</li> + * <li>inverse table</li> + * <li>permutation table</li> + * </ol> + * + * @see <a href="https://en.wikipedia.org/wiki/Verhoeff_algorithm">Wiki. + * Verhoeff algorithm</a> + */ +public final class Verhoeff { + private 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}, + * {@code d(j,k) ≠ d(k, j)}. + * + * @see <a href="https://en.wikipedia.org/wiki/Dihedral_group">Wiki. + * Dihedral group</a> + */ + private static final byte[][] MULTIPLICATION_TABLE = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 2, 3, 4, 0, 6, 7, 8, 9, 5}, + {2, 3, 4, 0, 1, 7, 8, 9, 5, 6}, + {3, 4, 0, 1, 2, 8, 9, 5, 6, 7}, + {4, 0, 1, 2, 3, 9, 5, 6, 7, 8}, + {5, 9, 8, 7, 6, 0, 4, 3, 2, 1}, + {6, 5, 9, 8, 7, 1, 0, 4, 3, 2}, + {7, 6, 5, 9, 8, 2, 1, 0, 4, 3}, + {8, 7, 6, 5, 9, 3, 2, 1, 0, 4}, + {9, 8, 7, 6, 5, 4, 3, 2, 1, 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))}. + */ + private static final byte[][] PERMUTATION_TABLE = { + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, + {1, 5, 7, 6, 2, 8, 3, 0, 9, 4}, + {5, 8, 0, 3, 7, 9, 6, 1, 4, 2}, + {8, 9, 1, 6, 0, 4, 3, 5, 2, 7}, + {9, 4, 5, 3, 1, 2, 6, 8, 7, 0}, + {4, 2, 8, 6, 5, 7, 3, 9, 0, 1}, + {2, 7, 9, 3, 8, 0, 6, 4, 1, 5}, + {7, 0, 4, 6, 9, 1, 3, 2, 5, 8}, + }; + + /** + * Check input digits by Verhoeff algorithm. + * + * @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 + */ + public static boolean verhoeffCheck(String digits) { + checkInput(digits); + int[] numbers = toIntArray(digits); + + // The Verhoeff algorithm + int checksum = 0; + for (int i = 0; i < numbers.length; i++) { + int index = numbers.length - i - 1; + byte b = PERMUTATION_TABLE[i % 8][numbers[index]]; + checksum = MULTIPLICATION_TABLE[checksum][b]; + } + + return checksum == 0; + } + + /** + * 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 + */ + public static String addVerhoeffChecksum(String initialDigits) { + checkInput(initialDigits); + + // Add zero to end of input value + var modifiedDigits = initialDigits + "0"; + + int[] numbers = toIntArray(modifiedDigits); + + int checksum = 0; + for (int i = 0; i < numbers.length; i++) { + int index = numbers.length - i - 1; + byte b = PERMUTATION_TABLE[i % 8][numbers[index]]; + checksum = MULTIPLICATION_TABLE[checksum][b]; + } + checksum = MULTIPLICATIVE_INVERSE[checksum]; + + return initialDigits + checksum; + } + + public static void main(String[] args) { + System.out.println("Verhoeff algorithm usage examples:"); + var validInput = "2363"; + var invalidInput = "2364"; + checkAndPrint(validInput); + checkAndPrint(invalidInput); + + System.out.println("\nCheck digit generation example:"); + var input = "236"; + generateAndPrint(input); + } + + private static void checkAndPrint(String input) { + String validationResult = Verhoeff.verhoeffCheck(input) ? "valid" : "not valid"; + System.out.println("Input '" + input + "' is " + validationResult); + } + + private static void generateAndPrint(String input) { + String result = addVerhoeffChecksum(input); + System.out.println("Generate and add checksum to initial value '" + input + "'. Result: '" + result + "'"); + } + + private static void checkInput(String input) { + Objects.requireNonNull(input); + if (!input.matches("\\d+")) { + throw new IllegalArgumentException("Input '" + input + "' contains not only digits"); + } + } + + private static int[] toIntArray(String string) { + return string.chars().map(i -> Character.digit(i, 10)).toArray(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/cn/HammingDistance.java b/Java/src/main/java/com/thealgorithms/others/cn/HammingDistance.java new file mode 100644 index 000000000000..c8239d53d606 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/cn/HammingDistance.java @@ -0,0 +1,32 @@ +package com.thealgorithms.others.cn; + +public final class HammingDistance { + private HammingDistance() { + } + + private static void checkChar(char inChar) { + if (inChar != '0' && inChar != '1') { + throw new IllegalArgumentException("Input must be a binary string."); + } + } + + public static int compute(char charA, char charB) { + checkChar(charA); + checkChar(charB); + return charA == charB ? 0 : 1; + } + + public static int compute(String bitsStrA, String bitsStrB) { + if (bitsStrA.length() != bitsStrB.length()) { + throw new IllegalArgumentException("Input strings must have the same length."); + } + + int totalErrorBitCount = 0; + + for (int i = 0; i < bitsStrA.length(); i++) { + totalErrorBitCount += compute(bitsStrA.charAt(i), bitsStrB.charAt(i)); + } + + return totalErrorBitCount; + } +} diff --git a/Java/src/main/java/com/thealgorithms/others/countSetBits.java b/Java/src/main/java/com/thealgorithms/others/countSetBits.java new file mode 100644 index 000000000000..04e0d6f62e6e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/others/countSetBits.java @@ -0,0 +1,51 @@ +package com.thealgorithms.others; + +public class countSetBits { + + /** + * The below algorithm is called as Brian Kernighan's algorithm + * We can use Brian Kernighan’s algorithm to improve the above naive algorithm’s performance. + The idea is to only consider the set bits of an integer by turning off its rightmost set bit + (after counting it), so the next iteration of the loop considers the next rightmost bit. + + The expression n & (n-1) can be used to turn off the rightmost set bit of a number n. This + works as the expression n-1 flips all the bits after the rightmost set bit of n, including the + rightmost set bit itself. Therefore, n & (n-1) results in the last bit flipped of n. + + For example, consider number 52, which is 00110100 in binary, and has a total 3 bits set. + + 1st iteration of the loop: n = 52 + + 00110100 & (n) + 00110011 (n-1) + ~~~~~~~~ + 00110000 + + + 2nd iteration of the loop: n = 48 + + 00110000 & (n) + 00101111 (n-1) + ~~~~~~~~ + 00100000 + + + 3rd iteration of the loop: n = 32 + + 00100000 & (n) + 00011111 (n-1) + ~~~~~~~~ + 00000000 (n = 0) + + * @param num takes Long number whose number of set bit is to be found + * @return the count of set bits in the binary equivalent + */ + public long countsetBits(long num) { + long cnt = 0; + while (num > 0) { + cnt++; + num &= (num - 1); + } + return cnt; + } +} diff --git a/Java/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java b/Java/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java new file mode 100644 index 000000000000..b22e81fe560e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java @@ -0,0 +1,47 @@ +package com.thealgorithms.scheduling; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.List; + +/** + * Non-pre-emptive First Come First Serve scheduling. This can be understood here - + * https://www.scaler.com/topics/first-come-first-serve/ + */ +public class FCFSScheduling { + + private List<ProcessDetails> processes; + + FCFSScheduling(final List<ProcessDetails> processes) { + this.processes = processes; + } + + public void scheduleProcesses() { + evaluateWaitingTime(); + evaluateTurnAroundTime(); + } + + private void evaluateWaitingTime() { + int processesNumber = processes.size(); + + if (processesNumber == 0) { + return; + } + + int waitingTime = 0; + int burstTime = processes.get(0).getBurstTime(); + + processes.get(0).setWaitingTime(waitingTime); // for the first process, waiting time will be 0. + + for (int i = 1; i < processesNumber; i++) { + processes.get(i).setWaitingTime(waitingTime + burstTime); + waitingTime = processes.get(i).getWaitingTime(); + burstTime = processes.get(i).getBurstTime(); + } + } + + private void evaluateTurnAroundTime() { + for (final var process : processes) { + process.setTurnAroundTimeTime(process.getBurstTime() + process.getWaitingTime()); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java b/Java/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java new file mode 100644 index 000000000000..9bcd5df81056 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java @@ -0,0 +1,59 @@ +package com.thealgorithms.scheduling; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +/** + * Preemptive Priority Scheduling Algorithm + * @author [Bama Charan Chhandogi](https://www.github.com/BamaCharanChhandogi) + */ + +class Process { + String name; + int arrivalTime; + int burstTime; + int priority; + + Process(String name, int arrivalTime, int burstTime, int priority) { + this.name = name; + this.arrivalTime = arrivalTime; + this.burstTime = burstTime; + this.priority = priority; + } +} + +public final class PreemptivePriorityScheduling { + private PreemptivePriorityScheduling() { + } + public static List<String> preemptivePriorityScheduling(List<Process> processes) { + List<String> ganttChart = new ArrayList<>(); + PriorityQueue<Process> readyQueue = new PriorityQueue<>(Comparator.comparingInt(p -> - p.priority)); + + int currentTime = 0; + + while (!processes.isEmpty() || !readyQueue.isEmpty()) { + while (!processes.isEmpty() && processes.get(0).arrivalTime <= currentTime) { + readyQueue.add(processes.remove(0)); + } + + if (!readyQueue.isEmpty()) { + Process currentProcess = readyQueue.poll(); + + ganttChart.add(currentProcess.name); + currentProcess.burstTime--; + + if (currentProcess.burstTime > 0) { + readyQueue.add(currentProcess); + } + } else { + ganttChart.add("Idle"); + } + + currentTime++; + } + + return ganttChart; + } +} diff --git a/Java/src/main/java/com/thealgorithms/scheduling/RRScheduling.java b/Java/src/main/java/com/thealgorithms/scheduling/RRScheduling.java new file mode 100644 index 000000000000..991c9a4f6148 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/scheduling/RRScheduling.java @@ -0,0 +1,102 @@ +/** + * @author Md Asif Joardar + */ + +package com.thealgorithms.scheduling; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/** + * The Round-robin scheduling algorithm is a kind of preemptive First come, First Serve CPU + * Scheduling algorithm. This can be understood here - + * https://www.scaler.com/topics/round-robin-scheduling-in-os/ + */ + +public class RRScheduling { + private List<ProcessDetails> processes; + private int quantumTime; + + RRScheduling(final List<ProcessDetails> processes, int quantumTime) { + this.processes = processes; + this.quantumTime = quantumTime; + } + + public void scheduleProcesses() { + evaluateTurnAroundTime(); + evaluateWaitingTime(); + } + + private void evaluateTurnAroundTime() { + int processesNumber = processes.size(); + + if (processesNumber == 0) { + return; + } + + Queue<Integer> queue = new LinkedList<>(); + queue.add(0); + int currentTime = 0; // keep track of the time + int completed = 0; + int[] mark = new int[processesNumber]; + Arrays.fill(mark, 0); + mark[0] = 1; + + // a copy of burst time to store the remaining burst time + int[] remainingBurstTime = new int[processesNumber]; + for (int i = 0; i < processesNumber; i++) { + remainingBurstTime[i] = processes.get(i).getBurstTime(); + } + + while (completed != processesNumber) { + int index = queue.poll(); + + if (remainingBurstTime[index] == processes.get(index).getBurstTime()) { + currentTime = Math.max(currentTime, processes.get(index).getArrivalTime()); + } + + if (remainingBurstTime[index] - quantumTime > 0) { + remainingBurstTime[index] -= quantumTime; + currentTime += quantumTime; + } else { + currentTime += remainingBurstTime[index]; + processes.get(index).setTurnAroundTimeTime(currentTime - processes.get(index).getArrivalTime()); + completed++; + remainingBurstTime[index] = 0; + } + + // If some process has arrived when this process was executing, insert them into the + // queue. + for (int i = 1; i < processesNumber; i++) { + if (remainingBurstTime[i] > 0 && processes.get(i).getArrivalTime() <= currentTime && mark[i] == 0) { + mark[i] = 1; + queue.add(i); + } + } + + // If the current process has burst time remaining, push the process into the queue + // again. + if (remainingBurstTime[index] > 0) queue.add(index); + + // If the queue is empty, pick the first process from the list that is not completed. + if (queue.isEmpty()) { + for (int i = 1; i < processesNumber; i++) { + if (remainingBurstTime[i] > 0) { + mark[i] = 1; + queue.add(i); + break; + } + } + } + } + } + + private void evaluateWaitingTime() { + for (final var process : processes) { + process.setWaitingTime(process.getTurnAroundTimeTime() - process.getBurstTime()); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java b/Java/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java new file mode 100644 index 000000000000..ca2144e4924f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java @@ -0,0 +1,110 @@ +package com.thealgorithms.scheduling; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.ArrayList; + +/** + * Implementation of Shortest Job First Algorithm: The algorithm allows the waiting process with the + * minimal burst time to be executed first. see more here: + * https://www.guru99.com/shortest-job-first-sjf-scheduling.html + */ + +public class SJFScheduling { + protected ArrayList<ProcessDetails> processes; + protected ArrayList<String> schedule; + + /** + * a simple constructor + * @param processes a list of processes the user wants to schedule + * it also sorts the processes based on the time of their arrival + */ + SJFScheduling(final ArrayList<ProcessDetails> processes) { + this.processes = processes; + schedule = new ArrayList<>(); + sortByArrivalTime(); + } + protected void sortByArrivalTime() { + int size = processes.size(); + int i; + int j; + ProcessDetails temp; + for (i = 0; i < size; i++) { + for (j = i + 1; j < size - 1; j++) { + if (processes.get(j).getArrivalTime() > processes.get(j + 1).getArrivalTime()) { + temp = processes.get(j); + processes.set(j, processes.get(j + 1)); + processes.set(j + 1, temp); + } + } + } + } + + /** + * this functions returns the order of the executions + */ + + public void scheduleProcesses() { + ArrayList<ProcessDetails> ready = new ArrayList<>(); + + int size = processes.size(); + int runtime; + int time = 0; + int executed = 0; + int j; + int k = 0; + ProcessDetails running; + + if (size == 0) { + return; + } + + while (executed < size) { + while (k < size && processes.get(k).getArrivalTime() <= time) // here we find the processes that have arrived. + { + ready.add(processes.get(k)); + k++; + } + + running = findShortestJob(ready); + if (running == null) { + time++; + } else { + runtime = running.getBurstTime(); + for (j = 0; j < runtime; j++) { + time++; + } + schedule.add(running.getProcessId()); + ready.remove(running); + executed++; + } + } + } + + /** + * this function evaluates the shortest job of all the ready processes (based on a process + * burst time) + * @param readyProcesses an array list of ready processes + * @return returns the process' with the shortest burst time OR NULL if there are no ready + * processes + */ + private ProcessDetails findShortestJob(ArrayList<ProcessDetails> readyProcesses) { + if (readyProcesses.isEmpty()) { + return null; + } + int i; + int size = readyProcesses.size(); + int minBurstTime = readyProcesses.get(0).getBurstTime(); + int temp; + int positionOfShortestJob = 0; + + for (i = 1; i < size; i++) { + temp = readyProcesses.get(i).getBurstTime(); + if (minBurstTime > temp) { + minBurstTime = temp; + positionOfShortestJob = i; + } + } + + return readyProcesses.get(positionOfShortestJob); + } +} diff --git a/Java/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java b/Java/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java new file mode 100644 index 000000000000..99214fff20c4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java @@ -0,0 +1,70 @@ +package com.thealgorithms.scheduling; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.ArrayList; +import java.util.List; + +/** + * Implementation of Shortest Remaining Time First Scheduling Algorithm. + * In the SRTF scheduling algorithm, the process with the smallest amount of time remaining until completion is selected to execute. + * Example: + * Consider the processes p1, p2 and the following table with info about their arrival and burst time: + * Process | Burst Time | Arrival Time + * P1 | 6 ms | 0 ms + * P2 | 2 ms | 1 ms + * In this example, P1 will be executed at time = 0 until time = 1 when P2 arrives. At time = 2, P2 will be executed until time = 4. At time 4, P2 is done, and P1 is executed again to be done. + * That's a simple example of how the algorithm works. + * More information you can find here -> https://en.wikipedia.org/wiki/Shortest_remaining_time + */ +public class SRTFScheduling { + protected List<ProcessDetails> processes; + protected List<String> ready; + + /** + * Constructor + * @param processes ArrayList of ProcessDetails given as input + */ + public SRTFScheduling(ArrayList<ProcessDetails> processes) { + this.processes = new ArrayList<>(); + ready = new ArrayList<>(); + this.processes = processes; + } + + public void evaluateScheduling() { + int time = 0; + int cr = 0; // cr=current running process, time= units of time + int n = processes.size(); + int[] remainingTime = new int[n]; + + /* calculating remaining time of every process and total units of time */ + for (int i = 0; i < n; i++) { + remainingTime[i] = processes.get(i).getBurstTime(); + time += processes.get(i).getBurstTime(); + } + + /* if the first process doesn't arrive at 0, we have more units of time */ + if (processes.get(0).getArrivalTime() != 0) { + time += processes.get(0).getArrivalTime(); + } + + /* printing id of the process which is executed at every unit of time */ + // if the first process doesn't arrive at 0, we print only \n until it arrives + if (processes.get(0).getArrivalTime() != 0) { + for (int i = 0; i < processes.get(0).getArrivalTime(); i++) { + ready.add(null); + } + } + + for (int i = processes.get(0).getArrivalTime(); i < time; i++) { + /* checking if there's a process with remaining time less than current running process. + If we find it, then it executes. */ + for (int j = 0; j < n; j++) { + if (processes.get(j).getArrivalTime() <= i && (remainingTime[j] < remainingTime[cr] && remainingTime[j] > 0 || remainingTime[cr] == 0)) { + cr = j; + } + } + ready.add(processes.get(cr).getProcessId()); + remainingTime[cr]--; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/BinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/BinarySearch.java new file mode 100644 index 000000000000..22096307d144 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/BinarySearch.java @@ -0,0 +1,82 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +/** + * Binary search is one of the most popular algorithms The algorithm finds the + * position of a target value within a sorted array + * + * <p> + * 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 <T> is any comparable type + * @return index of the element + */ + @Override + public <T extends Comparable<T>> 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 <T extends Comparable<T>> 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.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java b/Java/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java new file mode 100644 index 000000000000..40b3cd0c20e3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java @@ -0,0 +1,77 @@ +package com.thealgorithms.searches; + +/* +To apply this method, the provided array must be strictly sorted. In this method, two pointers, one +at 0th row & the other at the last row are taken & the searching is done on the basis of the middle +element of the middle column. If that element is equal to target, its coordinates are returned, else +if it is smaller than the target, the rows above that element are ignored (because the elements +above it will also be smaller than the target), else that element is greater than the target, then +the rows below it are ignored. + */ +public final class BinarySearch2dArray { + private BinarySearch2dArray() { + } + + static int[] binarySearch(int[][] arr, int target) { + int rowCount = arr.length; + int colCount = arr[0].length; + + if (rowCount == 1) { + return binarySearch(arr, target, 0, 0, colCount); + } + + int startRow = 0; + int endRow = rowCount - 1; + int midCol = colCount / 2; + + while (startRow < endRow - 1) { + int midRow = startRow + (endRow - startRow) / 2; // getting the index of middle row + + if (arr[midRow][midCol] == target) { + return new int[] {midRow, midCol}; + } else if (arr[midRow][midCol] < target) + startRow = midRow; + else + endRow = midRow; + } + /* + if the above search fails to find the target element, these conditions will be used to + find the target element, which further uses the binary search algorithm in the places + which were left unexplored. + */ + if (arr[startRow][midCol] == target) + return new int[] { + startRow, + midCol, + }; + + if (arr[endRow][midCol] == target) return new int[] {endRow, midCol}; + + if (target <= arr[startRow][midCol - 1]) return binarySearch(arr, target, startRow, 0, midCol - 1); + + if (target >= arr[startRow][midCol + 1] && target <= arr[startRow][colCount - 1]) return binarySearch(arr, target, startRow, midCol + 1, colCount - 1); + + if (target <= arr[endRow][midCol - 1]) + return binarySearch(arr, target, endRow, 0, midCol - 1); + else + return binarySearch(arr, target, endRow, midCol + 1, colCount - 1); + } + + static int[] binarySearch(int[][] arr, int target, int row, int colStart, int colEnd) { + while (colStart <= colEnd) { + int midIndex = colStart + (colEnd - colStart) / 2; + + if (arr[row][midIndex] == target) + return new int[] { + row, + midIndex, + }; + else if (arr[row][midIndex] < target) + colStart = midIndex + 1; + else + colEnd = midIndex - 1; + } + + return new int[] {-1, -1}; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java b/Java/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java new file mode 100644 index 000000000000..debab98c67a8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java @@ -0,0 +1,49 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.datastructures.Node; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Queue; + +/** + * @author: caos321 + * @date: 31 October 2021 (Sunday) + * @wiki: https://en.wikipedia.org/wiki/Breadth-first_search + */ +public class BreadthFirstSearch<T> { + + private final List<T> visited = new ArrayList<>(); + + public Optional<Node<T>> search(final Node<T> node, final T value) { + if (node == null) { + return Optional.empty(); + } + if (node.getValue().equals(value)) { + // add root node to visited + visited.add(value); + return Optional.of(node); + } + visited.add(node.getValue()); + + Queue<Node<T>> queue = new ArrayDeque<>(node.getChildren()); + + while (!queue.isEmpty()) { + final Node<T> current = queue.poll(); + visited.add(current.getValue()); + + if (current.getValue().equals(value)) { + return Optional.of(current); + } + + queue.addAll(current.getChildren()); + } + + return Optional.empty(); + } + + public List<T> getVisited() { + return visited; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java b/Java/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java new file mode 100644 index 000000000000..781768d8049e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/DepthFirstSearch.java @@ -0,0 +1,32 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.datastructures.Node; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +/** + * @author: caos321 + * @date: 31 October 2021 (Sunday) + * @wiki: https://en.wikipedia.org/wiki/Depth-first_search + */ +public class DepthFirstSearch<T> { + + private final List<T> visited = new ArrayList<>(); + + public Optional<Node<T>> recursiveSearch(final Node<T> node, final Integer value) { + if (node == null) { + return Optional.empty(); + } + visited.add(node.getValue()); + if (node.getValue().equals(value)) { + return Optional.of(node); + } + + return node.getChildren().stream().map(v -> recursiveSearch(v, value)).flatMap(Optional::stream).findAny(); + } + + public List<T> getVisited() { + return visited; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/ExponentalSearch.java b/Java/src/main/java/com/thealgorithms/searches/ExponentalSearch.java new file mode 100644 index 000000000000..a856bd659720 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/ExponentalSearch.java @@ -0,0 +1,48 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +class ExponentialSearch implements SearchAlgorithm { + + public static void main(String[] args) { + 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)]; + + ExponentialSearch search = new ExponentialSearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); + } + + @Override + public <T extends Comparable<T>> int find(T[] array, T key) { + if (array[0] == key) { + return 0; + } + if (array[array.length - 1] == key) { + return array.length; + } + + int range = 1; + + while (range < array.length && array[range].compareTo(key) <= -1) { + range = range * 2; + } + + return Arrays.binarySearch(array, range / 2, Math.min(range, array.length), key); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/FibonacciSearch.java b/Java/src/main/java/com/thealgorithms/searches/FibonacciSearch.java new file mode 100644 index 000000000000..4fba6e257627 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/FibonacciSearch.java @@ -0,0 +1,71 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; + +/* + * Fibonacci Search is a popular algorithm which finds the position of a target value in + * a sorted array + * + * 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 <T> is any comparable type + * @return index of the element + */ + @Override + public <T extends Comparable<T>> int find(T[] array, T key) { + int fibMinus1 = 1; + int fibMinus2 = 0; + int fibNumber = fibMinus1 + fibMinus2; + int n = array.length; + + while (fibNumber < n) { + fibMinus2 = fibMinus1; + fibMinus1 = fibNumber; + fibNumber = fibMinus2 + fibMinus1; + } + + int offset = -1; + + while (fibNumber > 1) { + int i = Math.min(offset + fibMinus2, n - 1); + + if (array[i].compareTo(key) < 0) { + fibNumber = fibMinus1; + fibMinus1 = fibMinus2; + fibMinus2 = fibNumber - fibMinus1; + offset = i; + } else if (array[i].compareTo(key) > 0) { + fibNumber = fibMinus2; + fibMinus1 = fibMinus1 - fibMinus2; + fibMinus2 = fibNumber - fibMinus1; + } else { + return i; + } + } + + if (fibMinus1 == 1 && array[offset + 1] == key) { + return offset + 1; + } + + return -1; + } + + // Driver Program + public static void main(String[] args) { + Integer[] integers = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; + + int size = integers.length; + Integer shouldBeFound = 128; + FibonacciSearch fsearch = new FibonacciSearch(); + int atIndex = fsearch.find(integers, shouldBeFound); + + System.out.println("Should be found: " + shouldBeFound + ". Found " + integers[atIndex] + " at index " + atIndex + ". An array length " + size); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java b/Java/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java new file mode 100644 index 000000000000..8e601f9873b3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java @@ -0,0 +1,63 @@ +package com.thealgorithms.searches; + +import java.util.Scanner; + +/* + Problem Statement: + Given an array, find out how many times it has to been rotated + from its initial sorted position. + Input-Output: + Eg. [11,12,15,18,2,5,6,8] + It has been rotated: 4 times + (One rotation means putting the first element to the end) + Note: The array cannot contain duplicates + + Logic: + The position of the minimum element will give the number of times the array has been rotated + from its initial sorted position. + Eg. For [2,5,6,8,11,12,15,18], 1 rotation gives [5,6,8,11,12,15,18,2], 2 rotations + [6,8,11,12,15,18,2,5] and so on. Finding the minimum element will take O(N) time but, we can use + Binary Search to find the mimimum element, we can reduce the complexity to O(log N). If we look + at the rotated array, to identify the minimum element (say a[i]), we observe that + a[i-1]>a[i]<a[i+1]. + + 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 + */ +final class HowManyTimesRotated { + private 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++) { + a[i] = sc.nextInt(); + } + + System.out.println("The array has been rotated " + rotated(a) + " times"); + sc.close(); + } + + 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]) { + break; + } 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/Java/src/main/java/com/thealgorithms/searches/InterpolationSearch.java b/Java/src/main/java/com/thealgorithms/searches/InterpolationSearch.java new file mode 100644 index 000000000000..aa1ff412b6a7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/InterpolationSearch.java @@ -0,0 +1,70 @@ +package com.thealgorithms.searches; + +import java.util.Arrays; +import java.util.Random; +import java.util.stream.IntStream; + +/** + * Interpolation search algorithm implementation + * + * <p> + * 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; + int 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 + int shouldBeFound = integers[r.nextInt(size - 1)]; + + InterpolationSearch search = new InterpolationSearch(); + int atIndex = search.find(integers, shouldBeFound); + + System.out.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java new file mode 100644 index 000000000000..49a86e4e53a8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java @@ -0,0 +1,77 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Stream; + +/** + * 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. + * + * <p> + * 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 <T extends Comparable<T>> int find(T[] array, T key) { + int l; + int r; + int k; + int 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.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java b/Java/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java new file mode 100644 index 000000000000..e78acd6a7ef8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/IterativeTernarySearch.java @@ -0,0 +1,72 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Stream; + +/** + * 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 + * + * <p> + * 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 <T extends Comparable<T>> 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.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/JumpSearch.java b/Java/src/main/java/com/thealgorithms/searches/JumpSearch.java new file mode 100644 index 000000000000..f499cf8079cc --- /dev/null +++ b/Java/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 <tt>-1</tt> + */ + @Override + public <T extends Comparable<T>> 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/Java/src/main/java/com/thealgorithms/searches/KMPSearch.java b/Java/src/main/java/com/thealgorithms/searches/KMPSearch.java new file mode 100644 index 000000000000..3648a4b08b86 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/KMPSearch.java @@ -0,0 +1,73 @@ +package com.thealgorithms.searches; + +class KMPSearch { + + int kmpSearch(String pat, String txt) { + int m = pat.length(); + int n = txt.length(); + + // create lps[] that will hold the longest + // prefix suffix values for pattern + int[] lps = new int[m]; + int j = 0; // index for pat[] + + // Preprocess the pattern (calculate lps[] + // array) + computeLPSArray(pat, m, lps); + + int i = 0; // index for txt[] + while ((n - i) >= (m - j)) { + if (pat.charAt(j) == txt.charAt(i)) { + j++; + i++; + } + if (j == m) { + System.out.println("Found pattern " + + "at index " + (i - j)); + int index = (i - j); + j = lps[j - 1]; + return index; + } + // mismatch after j matches + else if (i < n && pat.charAt(j) != txt.charAt(i)) { + // Do not match lps[0..lps[j-1]] characters, + // they will match anyway + if (j != 0) + j = lps[j - 1]; + else + i = i + 1; + } + } + System.out.println("No pattern found"); + return -1; + } + + void computeLPSArray(String pat, int m, int[] lps) { + // length of the previous longest prefix suffix + int len = 0; + int i = 1; + lps[0] = 0; // lps[0] is always 0 + + // the loop calculates lps[i] for i = 1 to m-1 + while (i < m) { + if (pat.charAt(i) == pat.charAt(len)) { + len++; + lps[i] = len; + i++; + } else { // (pat[i] != pat[len]) + // This is tricky. Consider the example. + // AAACAAAA and i = 7. The idea is similar + // to search step. + if (len != 0) { + len = lps[len - 1]; + // Also, note that we do not increment + // i here + } else { // if (len == 0) + lps[i] = len; + i++; + } + } + } + } +} +// This code has been contributed by Amit Khandelwal. diff --git a/Java/src/main/java/com/thealgorithms/searches/LinearSearch.java b/Java/src/main/java/com/thealgorithms/searches/LinearSearch.java new file mode 100644 index 000000000000..57927b30a632 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/LinearSearch.java @@ -0,0 +1,55 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Random; +import java.util.stream.Stream; + +/** + * 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 + * + * <p> + * 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 <T extends Comparable<T>> 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.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/LinearSearchThread.java b/Java/src/main/java/com/thealgorithms/searches/LinearSearchThread.java new file mode 100644 index 000000000000..b354d312d1b3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/LinearSearchThread.java @@ -0,0 +1,71 @@ +package com.thealgorithms.searches; + +import java.util.Scanner; + +public final class LinearSearchThread { + private LinearSearchThread() { + } + + public static void main(String[] args) { + int[] list = new int[200]; + for (int j = 0; j < list.length; j++) { + list[j] = (int) (Math.random() * 100); + } + for (int y : list) { + System.out.print(y + " "); + } + System.out.println(); + System.out.print("Enter number to search for: "); + Scanner in = new Scanner(System.in); + int x = in.nextInt(); + Searcher t = new Searcher(list, 0, 50, x); + Searcher t1 = new Searcher(list, 50, 100, x); + Searcher t2 = new Searcher(list, 100, 150, x); + Searcher t3 = new Searcher(list, 150, 200, x); + t.start(); + t1.start(); + t2.start(); + t3.start(); + try { + t.join(); + t1.join(); + t2.join(); + t3.join(); + } catch (InterruptedException e) { + } + boolean found = t.getResult() || t1.getResult() || t2.getResult() || t3.getResult(); + System.out.println("Found = " + found); + in.close(); + } +} + +class Searcher extends Thread { + + private final int[] arr; + private final int left; + private final int right; + private final int x; + private boolean found; + + Searcher(int[] arr, int left, int right, int x) { + this.arr = arr; + this.left = left; + this.right = right; + this.x = x; + } + + @Override + public void run() { + int k = left; + found = false; + while (k < right && !found) { + if (arr[k++] == x) { + found = true; + } + } + } + + boolean getResult() { + return found; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/LowerBound.java b/Java/src/main/java/com/thealgorithms/searches/LowerBound.java new file mode 100644 index 000000000000..ee6f51e637f2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/LowerBound.java @@ -0,0 +1,89 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +/** + * 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. + * + * <p> + * This is an extension of BinarySearch. + * + * <p> + * 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.printf("Val: %d. Lower Bound Found %d at index %d. An array length %d%n", val, integers[atIndex], atIndex, size); + + boolean toCheck = integers[atIndex] >= val || integers[size - 1] < val; + System.out.printf("Lower Bound found at an index: %d. Is greater or max element: %b%n", 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 <T> is any comparable type + * @return index of the LowerBound element + */ + @Override + public <T extends Comparable<T>> 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 <T extends Comparable<T>> 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/Java/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java b/Java/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java new file mode 100644 index 000000000000..268c33cef610 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java @@ -0,0 +1,179 @@ +package com.thealgorithms.searches; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Random; + +/** + * 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<Node> 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(Node parent, boolean isPlayersTurn) { + this.parent = parent; + childNodes = new ArrayList<>(); + this.isPlayersTurn = isPlayersTurn; + playerWon = false; + score = 0; + visitCount = 0; + } + } + + static final int WIN_SCORE = 10; + static final int TIME_LIMIT = 500; // Time the algorithm will be running for (in milliseconds). + + public static void main(String[] args) { + MonteCarloTreeSearch mcts = new MonteCarloTreeSearch(); + + mcts.monteCarloTreeSearch(mcts.new Node(null, true)); + } + + /** + * 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. + */ + public Node monteCarloTreeSearch(Node rootNode) { + Node winnerNode; + double timeLimit; + + // Expand the root node. + addChildNodes(rootNode, 10); + + timeLimit = System.currentTimeMillis() + TIME_LIMIT; + + // Explore the tree until the time limit is reached. + while (System.currentTimeMillis() < timeLimit) { + Node promisingNode; + + // Get a promising node using UCT. + promisingNode = getPromisingNode(rootNode); + + // Expand the promising node. + if (promisingNode.childNodes.size() == 0) { + addChildNodes(promisingNode, 10); + } + + simulateRandomPlay(promisingNode); + } + + winnerNode = getWinnerNode(rootNode); + printScores(rootNode); + System.out.format("%nThe optimal node is: %02d%n", rootNode.childNodes.indexOf(winnerNode) + 1); + + return winnerNode; + } + + public void addChildNodes(Node node, int childCount) { + for (int i = 0; i < childCount; i++) { + node.childNodes.add(new Node(node, !node.isPlayersTurn)); + } + } + + /** + * 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. + */ + public Node getPromisingNode(Node rootNode) { + Node promisingNode = rootNode; + + // Iterate until a node that hasn't been expanded is found. + while (promisingNode.childNodes.size() != 0) { + double uctIndex = Double.MIN_VALUE; + int nodeIndex = 0; + + // Iterate through child nodes and pick the most promising one + // using UCT (Upper Confidence bounds applied to Trees). + for (int i = 0; i < promisingNode.childNodes.size(); i++) { + Node childNode = promisingNode.childNodes.get(i); + double uctTemp; + + // If child node has never been visited + // it will have the highest uct value. + if (childNode.visitCount == 0) { + nodeIndex = i; + break; + } + + uctTemp = ((double) childNode.score / childNode.visitCount) + 1.41 * Math.sqrt(Math.log(promisingNode.visitCount) / (double) childNode.visitCount); + + if (uctTemp > uctIndex) { + uctIndex = uctTemp; + nodeIndex = i; + } + } + + promisingNode = promisingNode.childNodes.get(nodeIndex); + } + + return promisingNode; + } + + /** + * 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) { + Random rand = new Random(); + Node tempNode = promisingNode; + boolean isPlayerWinner; + + // The following line randomly determines whether the simulated play is a win or loss. + // To use the MCTS algorithm correctly this should be a simulation of the nodes' current + // state of the game until it finishes (if possible) and use an evaluation function to + // determine how good or bad the play was. + // e.g. Play tic tac toe choosing random squares until the game ends. + promisingNode.playerWon = (rand.nextInt(6) == 0); + + isPlayerWinner = promisingNode.playerWon; + + // Back propagation of the random play. + while (tempNode != null) { + tempNode.visitCount++; + + // Add wining scores to bouth player and opponent depending on the turn. + if ((tempNode.isPlayersTurn && isPlayerWinner) || (!tempNode.isPlayersTurn && !isPlayerWinner)) { + tempNode.score += WIN_SCORE; + } + + tempNode = tempNode.parent; + } + } + + public Node getWinnerNode(Node rootNode) { + return Collections.max(rootNode.childNodes, Comparator.comparing(c -> c.score)); + } + + public void printScores(Node rootNode) { + System.out.println("N.\tScore\t\tVisits"); + + for (int i = 0; i < rootNode.childNodes.size(); i++) { + System.out.printf("%02d\t%d\t\t%d%n", i + 1, rootNode.childNodes.get(i).score, rootNode.childNodes.get(i).visitCount); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java new file mode 100644 index 000000000000..cdd256150871 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java @@ -0,0 +1,48 @@ +package com.thealgorithms.searches; + +// URL: https://www.geeksforgeeks.org/order-agnostic-binary-search/ + +/* Order Agnostic Binary Search is an algorithm where we do not know whether the given + sorted array is ascending or descending order. + We declare a boolean variable to find whether the array is ascending order. + In the while loop, we use the two pointer method (start and end) to get the middle element. + if the middle element is equal to our target element, then that is the answer. + If not, then we check if the array is ascending or descending order. + Depending upon the condition, respective statements will be executed and we will get our answer. + */ + +public final class OrderAgnosticBinarySearch { + private OrderAgnosticBinarySearch() { + } + + static int binSearchAlgo(int[] arr, int start, int end, int target) { + + // Checking whether the given array is ascending order + boolean ascOrd = arr[start] < arr[end]; + + while (start <= end) { + int middle = start + (end - start) / 2; + + // Check if the desired element is present at the middle position + if (arr[middle] == target) return middle; // returns the index of the middle element + + // Ascending order + if (ascOrd) { + if (arr[middle] < target) + start = middle + 1; + else + end = middle - 1; + } + + // Descending order + else { + if (arr[middle] > target) + start = middle + 1; + else + end = middle - 1; + } + } + // Element is not present + return -1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java new file mode 100644 index 000000000000..495e2e41bc5b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/PerfectBinarySearch.java @@ -0,0 +1,54 @@ +package com.thealgorithms.searches; + +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 + * + * <p> + * Worst-case performance O(log n) Best-case performance O(1) Average + * performance O(log n) Worst-case space complexity O(1) + * + * @author D Sunil (https://github.com/sunilnitdgp) + * @see SearchAlgorithm + */ + +public class PerfectBinarySearch<T> implements SearchAlgorithm { + + /** + * @param array is an array where the element should be found + * @param key is an element which should be found + * @param <T> is any comparable type + * @return index of the element + */ + @Override + public <T extends Comparable<T>> int find(T[] array, T key) { + return search(array, key, 0, array.length - 1); + } + + /** + * This method implements the Generic Binary Search iteratively. + * + * @param array The array to make the binary search + * @param key The number you are looking for + * @return the location of the key, or -1 if not found + */ + private static <T extends Comparable<T>> int search(T[] array, T key, int left, int right) { + while (left <= right) { + int median = (left + right) >>> 1; + int comp = key.compareTo(array[median]); + + if (comp == 0) { + return median; // Key found + } + + if (comp < 0) { + right = median - 1; // Adjust the right bound + } else { + left = median + 1; // Adjust the left bound + } + } + return -1; // Key not found + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/QuickSelect.java b/Java/src/main/java/com/thealgorithms/searches/QuickSelect.java new file mode 100644 index 000000000000..97eab4bb4046 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/QuickSelect.java @@ -0,0 +1,123 @@ +package com.thealgorithms.searches; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; + +/** + * An implementation of the Quickselect algorithm as described + * <a href="https://en.wikipedia.org/wiki/Median_of_medians">here</a>. + */ +public final class QuickSelect { + private QuickSelect() { + } + + /** + * Selects the {@code n}-th largest element of {@code list}, i.e. the element that would + * be at index n if the list was sorted. + * <p> + * Calling this function might change the order of elements in {@code list}. + * + * @param list the list of elements + * @param n the index + * @param <T> the type of list elements + * @return the n-th largest element in the list + * @throws IndexOutOfBoundsException if n is less than 0 or greater or equal to + * the number of elements in the list + * @throws IllegalArgumentException if the list is empty + * @throws NullPointerException if {@code list} is null + */ + public static <T extends Comparable<T>> T select(List<T> list, int n) { + Objects.requireNonNull(list, "The list of elements must not be null."); + + if (list.size() == 0) { + String msg = "The list of elements must not be empty."; + throw new IllegalArgumentException(msg); + } + + if (n < 0) { + String msg = "The index must not be negative."; + throw new IndexOutOfBoundsException(msg); + } + + if (n >= list.size()) { + String msg = "The index must be less than the number of elements."; + throw new IndexOutOfBoundsException(msg); + } + + int index = selectIndex(list, n); + return list.get(index); + } + + private static <T extends Comparable<T>> int selectIndex(List<T> list, int n) { + return selectIndex(list, 0, list.size() - 1, n); + } + + private static <T extends Comparable<T>> int selectIndex(List<T> list, int left, int right, int n) { + while (true) { + if (left == right) return left; + int pivotIndex = pivot(list, left, right); + pivotIndex = partition(list, left, right, pivotIndex, n); + if (n == pivotIndex) { + return n; + } else if (n < pivotIndex) { + right = pivotIndex - 1; + } else { + left = pivotIndex + 1; + } + } + } + + private static <T extends Comparable<T>> int partition(List<T> list, int left, int right, int pivotIndex, int n) { + T pivotValue = list.get(pivotIndex); + Collections.swap(list, pivotIndex, right); + int storeIndex = left; + + for (int i = left; i < right; i++) { + if (list.get(i).compareTo(pivotValue) < 0) { + Collections.swap(list, storeIndex, i); + storeIndex++; + } + } + + int storeIndexEq = storeIndex; + + for (int i = storeIndex; i < right; i++) { + if (list.get(i).compareTo(pivotValue) == 0) { + Collections.swap(list, storeIndexEq, i); + storeIndexEq++; + } + } + + Collections.swap(list, right, storeIndexEq); + + return (n < storeIndex) ? storeIndex : Math.min(n, storeIndexEq); + } + + private static <T extends Comparable<T>> int pivot(List<T> list, int left, int right) { + if (right - left < 5) { + return partition5(list, left, right); + } + + for (int i = left; i < right; i += 5) { + int subRight = i + 4; + if (subRight > right) { + subRight = right; + } + int median5 = partition5(list, i, subRight); + int rightIndex = left + (i - left) / 5; + Collections.swap(list, median5, rightIndex); + } + + int mid = (right - left) / 10 + left + 1; + int rightIndex = left + (right - left) / 5; + return selectIndex(list, left, rightIndex, mid); + } + + private static <T extends Comparable<T>> int partition5(List<T> list, int left, int right) { + List<T> ts = list.subList(left, right); + ts.sort(Comparator.naturalOrder()); + return (left + right) >>> 1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java b/Java/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java new file mode 100644 index 000000000000..cc8387f6c4f3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java @@ -0,0 +1,62 @@ +package com.thealgorithms.searches; + +// Implementation of Rabin Karp Algorithm + +public final class RabinKarpAlgorithm { + private RabinKarpAlgorithm() { + } + + private static final int ALPHABET_SIZE = 256; + + public static int search(String pattern, String text, int primeNumber) { + + int index = -1; // -1 here represents not found + int patternLength = pattern.length(); + int textLength = text.length(); + int hashForPattern = 0; + int hashForText = 0; + int h = 1; + + // The value of h would be "pow(d, patternLength-1)%primeNumber" + for (int i = 0; i < patternLength - 1; i++) h = (h * ALPHABET_SIZE) % primeNumber; + + // Calculate the hash value of pattern and first + // window of text + for (int i = 0; i < patternLength; i++) { + hashForPattern = (ALPHABET_SIZE * hashForPattern + pattern.charAt(i)) % primeNumber; + hashForText = (ALPHABET_SIZE * hashForText + text.charAt(i)) % primeNumber; + } + + // Slide the pattern over text one by one + for (int i = 0; i <= textLength - patternLength; i++) { + /* Check the hash values of current window of text + and pattern. If the hash values match then only + check for characters one by one*/ + + int j = 0; + if (hashForPattern == hashForText) { + /* Check for characters one by one */ + for (j = 0; j < patternLength; j++) { + if (text.charAt(i + j) != pattern.charAt(j)) break; + } + + // if hashForPattern == hashForText and pattern[0...patternLength-1] = text[i, i+1, ...i+patternLength-1] + if (j == patternLength) { + index = i; + return index; + } + } + + // Calculate hash value for next window of text: Remove + // leading digit, add trailing digit + if (i < textLength - patternLength) { + hashForText = (ALPHABET_SIZE * (hashForText - text.charAt(i) * h) + text.charAt(i + patternLength)) % primeNumber; + + // handling negative hashForText + if (hashForText < 0) hashForText = (hashForText + primeNumber); + } + } + return index; // return -1 if pattern does not found + } +} +// This code is contributed by nuclode diff --git a/Java/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java new file mode 100644 index 000000000000..6c6284e28019 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java @@ -0,0 +1,76 @@ +// Code by Pronay Debnath +// Created:- 1/10/2023 +// File Name should be RecursiveBinarySearch.java +// Explanation:- https://www.tutorialspoint.com/java-program-for-binary-search-recursive +package com.thealgorithms.searches; + +import java.util.Scanner; + +// Create a SearchAlgorithm class with a generic type +abstract class SearchAlgorithm<T extends Comparable<T>> { + // Abstract find method to be implemented by subclasses + public abstract int find(T[] arr, T target); +} + +public class RecursiveBinarySearch<T extends Comparable<T>> extends SearchAlgorithm<T> { + + // Override the find method as required + @Override + public int find(T[] arr, T target) { + // Call the recursive binary search function + return binsear(arr, 0, arr.length - 1, target); + } + + // Recursive binary search function + public int binsear(T[] arr, int left, int right, T target) { + if (right >= left) { + int mid = left + (right - left) / 2; + + // Compare the element at the middle with the target + int comparison = arr[mid].compareTo(target); + + // If the element is equal to the target, return its index + if (comparison == 0) { + return mid; + } + + // If the element is greater than the target, search in the left subarray + if (comparison > 0) { + return binsear(arr, left, mid - 1, target); + } + + // Otherwise, search in the right subarray + return binsear(arr, mid + 1, right, target); + } + + // Element is not present in the array + return -1; + } + + public static void main(String[] args) { + try (Scanner sc = new Scanner(System.in)) { + // User inputs + System.out.print("Enter the number of elements in the array: "); + int n = sc.nextInt(); + + Integer[] a = new Integer[n]; // You can change the array type as needed + + System.out.println("Enter the elements in sorted order:"); + + for (int i = 0; i < n; i++) { + a[i] = sc.nextInt(); + } + + System.out.print("Enter the target element to search for: "); + int t = sc.nextInt(); + + RecursiveBinarySearch<Integer> searcher = new RecursiveBinarySearch<>(); + int res = searcher.find(a, t); + + if (res == -1) + System.out.println("Element not found in the array."); + else + System.out.println("Element found at index " + res); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java new file mode 100644 index 000000000000..3b4b0b08377f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearch.java @@ -0,0 +1,47 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.MatrixSearchAlgorithm; + +/** + * The search is for any array which is sorted row and column-wise too. For ex : + * {{10, 20, 30, 40}, + * {15, 25, 35, 45}, + * {18, 28, 38, 48}, + * {21, 31, 41, 51}} + * + * This array is sorted in both row and column manner. + * In this two pointers are taken, the first points to the 0th row and the second one points to end + * column, and then the element corresponding to the pointers placed in the array is compared with + * the target that either its equal, greater or smaller than the target. If the element is equal to + * the target, the co-ordinates of that element is returned i.e. an array of the two pointers will + * be returned, else if the target is greater than corresponding element then the pointer pointing + * to the 0th row will be incremented by 1, else if the target is lesser than the corresponding + * element then the pointer pointing to the end column will be decremented by 1. And if the element + * doesn't exist in the array, an array + * {-1, -1} will be returned. + */ +public class RowColumnWiseSorted2dArrayBinarySearch implements MatrixSearchAlgorithm { + + @Override + public <T extends Comparable<T>> int[] find(T[][] matrix, T key) { + return search(matrix, key); + } + + public static <T extends Comparable<T>> int[] search(T[][] matrix, T target) { + int rowPointer = 0; // The pointer at 0th row + int colPointer = matrix.length - 1; // The pointer at end column + + while (rowPointer < matrix.length && colPointer >= 0) { + int comp = target.compareTo(matrix[rowPointer][colPointer]); + + if (comp == 0) { + return new int[] {rowPointer, colPointer}; + } else if (comp > 0) { + rowPointer++; // Incrementing the row pointer if the target is greater + } else { + colPointer--; // Decrementing the column pointer if the target is lesser + } + } + return new int[] {-1, -1}; // The not found condition + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java b/Java/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java new file mode 100644 index 000000000000..5c7a914e3bf2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java @@ -0,0 +1,76 @@ +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) + * + * <p> + * 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 final class SaddlebackSearch { + private 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; + int j; + int rows = sc.nextInt(); + int 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/Java/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java b/Java/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java new file mode 100644 index 000000000000..711da862a336 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/SearchInARowAndColWiseSortedMatrix.java @@ -0,0 +1,34 @@ +package com.thealgorithms.searches; + +public class SearchInARowAndColWiseSortedMatrix { + /** + * Search a key in row and column wise sorted matrix + * + * @param matrix matrix to be searched + * @param value Key being searched for + * @author Sadiul Hakim : https://github.com/sadiul-hakim + */ + + public int[] search(int[][] matrix, int value) { + int n = matrix.length; + // This variable iterates over rows + int i = 0; + // This variable iterates over columns + int j = n - 1; + int[] result = {-1, -1}; + + while (i < n && j >= 0) { + if (matrix[i][j] == value) { + result[0] = i; + result[1] = j; + return result; + } + if (value > matrix[i][j]) { + i++; + } else { + j--; + } + } + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java new file mode 100644 index 000000000000..c00bfc9da6f5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java @@ -0,0 +1,63 @@ +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). + * <p> + * For example, if x = 5, The answer should be 2 which is the floor value of √5. + * <p> + * 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 + */ +public final class SquareRootBinarySearch { + private SquareRootBinarySearch() { + } + + /** + * This is the driver method. + * + * @param args Command line arguments + */ + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + System.out.print("Enter a number you want to calculate square root of : "); + int num = sc.nextInt(); + long ans = squareRoot(num); + System.out.println("The square root is : " + ans); + sc.close(); + } + + /** + * 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 + */ + private static long squareRoot(long num) { + if (num == 0 || num == 1) { + return num; + } + long l = 1; + long r = num; + long ans = 0; + while (l <= r) { + long mid = l + (r - l) / 2; + if (mid == num / mid) { + return mid; + } else if (mid < num / mid) { + ans = mid; + l = mid + 1; + } else { + r = mid - 1; + } + } + return ans; + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/TernarySearch.java b/Java/src/main/java/com/thealgorithms/searches/TernarySearch.java new file mode 100644 index 000000000000..3395bc0b7f30 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/TernarySearch.java @@ -0,0 +1,82 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Arrays; +import java.util.Random; +import java.util.stream.Stream; + +/** + * 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. + * + * <p> + * 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 <T extends Comparable<T>> 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 <T extends Comparable<T>> 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.printf("Should be found: %d. Found %d at index %d. An array length %d%n", shouldBeFound, integers[atIndex], atIndex, size); + + int toCheck = Arrays.binarySearch(integers, shouldBeFound); + System.out.printf("Found by system method at an index: %d. Is equal: %b%n", toCheck, toCheck == atIndex); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/UnionFind.java b/Java/src/main/java/com/thealgorithms/searches/UnionFind.java new file mode 100644 index 000000000000..2effdf37bea5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/UnionFind.java @@ -0,0 +1,87 @@ +package com.thealgorithms.searches; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class UnionFind { + + private final int[] p; + private final 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; + } + + final int result = find(parent); + p[i] = result; + + return result; + } + + public void union(int x, int y) { + int r0 = find(x); + int r1 = find(y); + + if (r1 == r0) { + return; + } + + if (r[r0] > r[r1]) { + p[r1] = r0; + } else if (r[r1] > r[r0]) { + p[r0] = r1; + } else { + p[r1] = r0; + r[r0]++; + } + } + + public int count() { + List<Integer> parents = new ArrayList<>(); + for (int i = 0; i < p.length; i++) { + if (!parents.contains(find(i))) { + parents.add(find(i)); + } + } + return parents.size(); + } + + 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); + 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); + System.out.println("union 3 4 (should print 'p [0, 1, 1, 3, 3] r [0, 1, 0, 1, 0]'):"); + System.out.println(uf); + + uf.find(4); + System.out.println("find 4 (should print 'p [0, 1, 1, 3, 3] r [0, 1, 0, 1, 0]'):"); + System.out.println(uf); + + System.out.println("count (should print '3'):"); + System.out.println(uf.count()); + } +} diff --git a/Java/src/main/java/com/thealgorithms/searches/UpperBound.java b/Java/src/main/java/com/thealgorithms/searches/UpperBound.java new file mode 100644 index 000000000000..bbce617a143b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/UpperBound.java @@ -0,0 +1,87 @@ +package com.thealgorithms.searches; + +import com.thealgorithms.devutils.searches.SearchAlgorithm; +import java.util.Random; +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +/** + * 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. + * + * <p> + * This is an extension of BinarySearch. + * + * <p> + * 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.printf("Val: %d. Upper Bound Found %d at index %d. An array length %d%n", val, integers[atIndex], atIndex, size); + + boolean toCheck = integers[atIndex] > val || integers[size - 1] < val; + System.out.printf("Upper Bound found at an index: %d. Is greater or max element: %b%n", 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 <T> is any comparable type + * @return index of the UpperBound element + */ + @Override + public <T extends Comparable<T>> 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 <T extends Comparable<T>> 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/Java/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java b/Java/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java new file mode 100644 index 000000000000..acb9fb5cb3cd --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java @@ -0,0 +1,30 @@ +package com.thealgorithms.searches; +public final class sortOrderAgnosticBinarySearch { + private sortOrderAgnosticBinarySearch() { + } + public static int find(int[] arr, int key) { + int start = 0; + int end = arr.length - 1; + boolean arrDescending = arr[start] > arr[end]; // checking for Array is in ascending order or descending order. + while (start <= end) { + int mid = end - start / 2; + if (arr[mid] == key) { + return mid; + } + if (arrDescending) { // boolean is true then our array is in descending order + if (key < arr[mid]) { + start = mid + 1; + } else { + end = mid - 1; + } + } else { // otherwise our array is in ascending order + if (key > arr[mid]) { + start = mid + 1; + } else { + end = mid - 1; + } + } + } + return -1; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/BeadSort.java b/Java/src/main/java/com/thealgorithms/sorts/BeadSort.java new file mode 100644 index 000000000000..101a5c50af6d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/BeadSort.java @@ -0,0 +1,44 @@ +package com.thealgorithms.sorts; + +// BeadSort Algorithm(wikipedia) : https://en.wikipedia.org/wiki/Bead_sort +// BeadSort can't sort negative number, Character, String. It can sort positive number only + +public class BeadSort { + public int[] sort(int[] unsorted) { + int[] sorted = new int[unsorted.length]; + int max = 0; + for (int i = 0; i < unsorted.length; i++) { + max = Math.max(max, unsorted[i]); + } + + char[][] grid = new char[unsorted.length][max]; + int[] count = new int[max]; + + for (int i = 0; i < unsorted.length; i++) { + for (int j = 0; j < max; j++) { + grid[i][j] = '-'; + } + } + + for (int i = 0; i < max; i++) { + count[i] = 0; + } + + for (int i = 0; i < unsorted.length; i++) { + int k = 0; + for (int j = 0; j < unsorted[i]; j++) { + grid[count[max - k - 1]++][k] = '*'; + k++; + } + } + + for (int i = 0; i < unsorted.length; i++) { + int k = 0; + for (int j = 0; j < max && grid[unsorted.length - 1 - i][j] == '*'; j++) { + k++; + } + sorted[i] = k; + } + return sorted; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java b/Java/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java new file mode 100644 index 000000000000..13076c617c76 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java @@ -0,0 +1,29 @@ +package com.thealgorithms.sorts; + +public class BinaryInsertionSort { + + // Binary Insertion Sort method + public int[] binaryInsertSort(int[] array) { + for (int i = 1; i < array.length; i++) { + int temp = array[i]; + int low = 0; + int high = i - 1; + + while (low <= high) { + final int mid = (low + high) >>> 1; + if (temp < array[mid]) { + high = mid - 1; + } else { + low = mid + 1; + } + } + + for (int j = i; j >= low + 1; j--) { + array[j] = array[j - 1]; + } + + array[low] = temp; + } + return array; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/BitonicSort.java b/Java/src/main/java/com/thealgorithms/sorts/BitonicSort.java new file mode 100644 index 000000000000..b4b26299562f --- /dev/null +++ b/Java/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/Java/src/main/java/com/thealgorithms/sorts/BogoSort.java b/Java/src/main/java/com/thealgorithms/sorts/BogoSort.java new file mode 100644 index 000000000000..7a1f7b216437 --- /dev/null +++ b/Java/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 <T extends Comparable<T>> 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 <T> 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 extends Comparable<T>> 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/Java/src/main/java/com/thealgorithms/sorts/BubbleSort.java b/Java/src/main/java/com/thealgorithms/sorts/BubbleSort.java new file mode 100644 index 000000000000..6823c68d0a74 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/BubbleSort.java @@ -0,0 +1,33 @@ +package com.thealgorithms.sorts; + +/** + * @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 <T> the type of elements in the array. + * @return the sorted array. + */ + @Override + public <T extends Comparable<T>> 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 (SortUtils.greater(array[j], array[j + 1])) { + SortUtils.swap(array, j, j + 1); + swapped = true; + } + } + if (!swapped) { + break; + } + } + return array; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/BubbleSortRecursion.java b/Java/src/main/java/com/thealgorithms/sorts/BubbleSortRecursion.java new file mode 100644 index 000000000000..10197969e853 --- /dev/null +++ b/Java/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 extends Comparable<T>> 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 <T extends Comparable<T>> 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/Java/src/main/java/com/thealgorithms/sorts/BucketSort.java b/Java/src/main/java/com/thealgorithms/sorts/BucketSort.java new file mode 100644 index 000000000000..2a48cca0f433 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/BucketSort.java @@ -0,0 +1,119 @@ +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 final class BucketSort { + private 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 + */ + public static int[] 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<List<Integer>> 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<Integer> bucket : buckets) { + Collections.sort(bucket); + } + + /* concatenate buckets to origin array */ + int index = 0; + for (List<Integer> bucket : buckets) { + for (int value : bucket) { + arr[index++] = value; + } + } + + return arr; + } + + /** + * 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/Java/src/main/java/com/thealgorithms/sorts/CircleSort.java b/Java/src/main/java/com/thealgorithms/sorts/CircleSort.java new file mode 100644 index 000000000000..25c308b16e3c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/CircleSort.java @@ -0,0 +1,54 @@ +package com.thealgorithms.sorts; + +public class CircleSort implements SortAlgorithm { + + /* This method implements the circle sort + * @param array The array to be sorted + */ + @Override + public <T extends Comparable<T>> T[] sort(T[] array) { + int n = array.length; + if (n == 0) { + return array; + } + 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 <T extends Comparable<T>> Boolean doSort(T[] array, int left, int right) { + boolean swapped = false; + + if (left == right) { + return Boolean.FALSE; + } + + int low = left; + int high = right; + + while (low < high) { + if (array[low].compareTo(array[high]) > 0) { + SortUtils.swap(array, low, high); + swapped = true; + } + low++; + high--; + } + + if (low == high && array[low].compareTo(array[high + 1]) > 0) { + SortUtils.swap(array, low, high + 1); + swapped = true; + } + + int mid = left + (right - left) / 2; + Boolean leftHalf = doSort(array, left, mid); + Boolean rightHalf = doSort(array, mid + 1, right); + + return swapped || leftHalf || rightHalf; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java b/Java/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java new file mode 100644 index 000000000000..c88c7bd099f6 --- /dev/null +++ b/Java/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 extends Comparable<T>> T[] sort(T[] array) { + int length = array.length; + int left = 0; + int right = length - 1; + int swappedLeft; + int 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/Java/src/main/java/com/thealgorithms/sorts/CombSort.java b/Java/src/main/java/com/thealgorithms/sorts/CombSort.java new file mode 100644 index 000000000000..edf09a2eb3f8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/CombSort.java @@ -0,0 +1,91 @@ +package com.thealgorithms.sorts; + +/** + * Comb Sort algorithm implementation + * + * <p> + * Best-case performance O(n * log(n)) Worst-case performance O(n ^ 2) + * Worst-case space complexity O(1) + * + * <p> + * 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 Math.max(gap, 1); + } + + /** + * Function to sort arr[] using Comb + * + * @param arr - an array should be sorted + * @return sorted array + */ + @Override + public <T extends Comparable<T>> 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 (SortUtils.less(arr[i + gap], arr[i])) { + // Swap arr[i] and arr[i+gap] + SortUtils.swap(arr, i, i + gap); + swapped = true; + } + } + } + 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"); + SortUtils.print(arr); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/CountingSort.java b/Java/src/main/java/com/thealgorithms/sorts/CountingSort.java new file mode 100644 index 000000000000..e83271d9ee67 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -0,0 +1,93 @@ +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.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +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 extends Comparable<T>> 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 + * <p> + * Sorts the list in increasing order The method uses list elements as keys + * in the frequency map + */ + @Override + public <T extends Comparable<T>> List<T> sort(List<T> list) { + Map<T, Integer> frequency = new TreeMap<>(); + // The final output array + List<T> 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<T, Integer> 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 <T extends Comparable<T>> List<T> streamSort(List<T> 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<Integer> 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<String> 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/Java/src/main/java/com/thealgorithms/sorts/CycleSort.java b/Java/src/main/java/com/thealgorithms/sorts/CycleSort.java new file mode 100644 index 000000000000..0852abfaae24 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/CycleSort.java @@ -0,0 +1,100 @@ +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 extends Comparable<T>> 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 extends Comparable<T>> 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/Java/src/main/java/com/thealgorithms/sorts/DNFSort.java b/Java/src/main/java/com/thealgorithms/sorts/DNFSort.java new file mode 100644 index 000000000000..50ba8c89715b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/DNFSort.java @@ -0,0 +1,56 @@ +package com.thealgorithms.sorts; + +public final class DNFSort { + private DNFSort() { + } + + // Sort the input array, the array is assumed to + // have values in {0, 1, 2} + static void sort012(int[] a, int arrSize) { + int low = 0; + int high = arrSize - 1; + int mid = 0; + int temp; + while (mid <= high) { + switch (a[mid]) { + case 0: { + temp = a[low]; + a[low] = a[mid]; + a[mid] = temp; + low++; + mid++; + break; + } + case 1: + mid++; + break; + case 2: { + temp = a[mid]; + a[mid] = a[high]; + a[high] = temp; + high--; + break; + } + default: + throw new IllegalArgumentException("Unexpected value: " + a[mid]); + } + } + } + + /* Utility function to print array arr[] */ + static void printArray(int[] arr, int arrSize) { + for (int i = 0; i < arrSize; 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 arrSize = arr.length; + sort012(arr, arrSize); + System.out.println("Array after seggregation "); + printArray(arr, arrSize); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java b/Java/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java new file mode 100644 index 000000000000..60cb5aa7aa69 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/DualPivotQuickSort.java @@ -0,0 +1,106 @@ +package com.thealgorithms.sorts; + +/** + * Dual Pivot Quick Sort Algorithm + * + * @author Debasish Biswas (https://github.com/debasishbsws) * + * @see SortAlgorithm + */ +public class DualPivotQuickSort implements SortAlgorithm { + + /** + * This method implements the Dual pivot Quick Sort + * + * @param array The array to be sorted Sorts the array in increasing order + */ + @Override + public <T extends Comparable<T>> T[] sort(T[] array) { + dualPivotQuicksort(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 <T extends Comparable<T>> void dualPivotQuicksort(T[] array, int left, int right) { + if (left < right) { + int[] pivots = partition(array, left, right); + + dualPivotQuicksort(array, left, pivots[0] - 1); + dualPivotQuicksort(array, pivots[0] + 1, pivots[1] - 1); + dualPivotQuicksort(array, pivots[1] + 1, right); + } + } + + /** + * This method finds the partition indices 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 <T extends Comparable<T>> int[] partition(T[] array, int left, int right) { + if (array[left].compareTo(array[right]) > 0) swap(array, left, right); + + T pivot1 = array[left]; + T pivot2 = array[right]; + + int j = left + 1; + int less = left + 1; + int great = right - 1; + + while (less <= great) { + // If element is less than pivot1 + if (array[less].compareTo(pivot1) < 0) { + swap(array, less, left++); + } + + // If element is greater or equal to pivot2 + else if (array[less].compareTo(pivot2) >= 0) { + while (less < great && array[great].compareTo(pivot2) > 0) great--; + + swap(array, less, great--); + + if (array[less].compareTo(pivot1) < 0) swap(array, less, left++); + } + + less++; + } + j--; + great++; + // Bring the pivots to their appropriate positions + swap(array, left, j); + swap(array, right, great); + + // return the pivots' indices + return new int[] {less, great}; + } + + private static <T extends Comparable<T>> void swap(T[] array, int left, int right) { + T temp = array[left]; + array[left] = array[right]; + array[right] = temp; + } + + /** + * Main method + * + * @param args the command line arguments + */ + public static void main(String[] args) { + Integer[] array = {24, 8, -42, 75, -29, -77, 38, 57}; + DualPivotQuickSort dualPivotQuickSort = new DualPivotQuickSort(); + dualPivotQuickSort.sort(array); + for (int i = 0; i < array.length; i++) { + System.out.print(array[i] + " "); + } + } + + /* + * References: https://www.geeksforgeeks.org/dual-pivot-quicksort/ + */ +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java b/Java/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java new file mode 100644 index 000000000000..20b8f0ba1abc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java @@ -0,0 +1,42 @@ +package com.thealgorithms.sorts; + +/** + * The Dutch National Flag Sort sorts a sequence of values into three permutations which are defined + * by a value given as the indented middle. First permutation: values less than middle. Second + * permutation: values equal middle. Third permutation: values greater than middle. If no indented + * middle is given, this implementation will use a value from the given Array. This value is the one + * positioned in the arrays' middle if the arrays' length is odd. If the arrays' length is even, the + * value left to the middle will be used. More information and Pseudocode: + * https://en.wikipedia.org/wiki/Dutch_national_flag_problem + */ +public class DutchNationalFlagSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] unsorted) { + return dutchNationalFlagSort(unsorted, unsorted[(int) Math.ceil((unsorted.length) / 2.0) - 1]); + } + + public <T extends Comparable<T>> T[] sort(T[] unsorted, T intendedMiddle) { + return dutchNationalFlagSort(unsorted, intendedMiddle); + } + + private <T extends Comparable<T>> T[] dutchNationalFlagSort(T[] arr, T intendedMiddle) { + int i = 0; + int j = 0; + int k = arr.length - 1; + + while (j <= k) { + if (0 > arr[j].compareTo(intendedMiddle)) { + SortUtils.swap(arr, i, j); + j++; + i++; + } else if (0 < arr[j].compareTo(intendedMiddle)) { + SortUtils.swap(arr, j, k); + k--; + } else { + j++; + } + } + return arr; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/ExchangeSort.java b/Java/src/main/java/com/thealgorithms/sorts/ExchangeSort.java new file mode 100644 index 000000000000..28303430950c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/ExchangeSort.java @@ -0,0 +1,47 @@ +package com.thealgorithms.sorts; + +/** + * ExchangeSort is an implementation of the Exchange Sort algorithm. + * + * <p> + * Exchange sort works by comparing each element with all subsequent elements, + * swapping where needed, to ensure the correct placement of each element + * in the final sorted order. It iteratively performs this process for each + * element in the array. While it lacks the advantage of bubble sort in + * detecting sorted lists in one pass, it can be more efficient than bubble sort + * due to a constant factor (one less pass over the data to be sorted; half as + * many total comparisons) in worst-case scenarios. + * </p> + * + * <p> + * Reference: https://en.wikipedia.org/wiki/Sorting_algorithm#Exchange_sort + * </p> + * + * @author 555vedant (Vedant Kasar) + */ +class ExchangeSort implements SortAlgorithm { + /** + * Implementation of Exchange Sort Algorithm + * + * @param array the array to be sorted. + * @param <T> the type of elements in the array. + * @return the sorted array. + */ + @Override + public <T extends Comparable<T>> T[] sort(T[] array) { + for (int i = 0; i < array.length - 1; i++) { + for (int j = i + 1; j < array.length; j++) { + if (array[i].compareTo(array[j]) > 0) { + swap(array, i, j); + } + } + } + return array; + } + + private <T> void swap(T[] array, int i, int j) { + T temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/GnomeSort.java b/Java/src/main/java/com/thealgorithms/sorts/GnomeSort.java new file mode 100644 index 000000000000..9bef6a2837b5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/GnomeSort.java @@ -0,0 +1,71 @@ +package com.thealgorithms.sorts; + +/** + * Implementation of gnome sort + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @since 2018-04-10 + */ +public class GnomeSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] arr) { + int i = 1; + int j = 2; + while (i < arr.length) { + if (SortUtils.less(arr[i - 1], arr[i])) { + i = j++; + } else { + SortUtils.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 : "); + SortUtils.print(integers); + SortUtils.print(strings); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/HeapSort.java b/Java/src/main/java/com/thealgorithms/sorts/HeapSort.java new file mode 100644 index 000000000000..eec705ba476a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/HeapSort.java @@ -0,0 +1,56 @@ +package com.thealgorithms.sorts; + +/** + * Heap Sort Algorithm Implementation + * + * @see <a href="https://en.wikipedia.org/wiki/Heapsort">Heap Sort Algorithm</a> + */ +public class HeapSort implements SortAlgorithm { + + /** + * For simplicity, we are considering the heap root index as 1 instead of 0. + * It simplifies future calculations. Because of that we are decreasing the + * provided indexes by 1 in {@link #swap(Object[], int, int)} and + * {@link #less(Comparable[], int, int)} functions. + */ + @Override + public <T extends Comparable<T>> T[] sort(T[] unsorted) { + int n = unsorted.length; + heapify(unsorted, n); + while (n > 1) { + swap(unsorted, 1, n--); + siftDown(unsorted, 1, n); + } + return unsorted; + } + + private static <T extends Comparable<T>> void heapify(T[] unsorted, int n) { + for (int k = n / 2; k >= 1; k--) { + siftDown(unsorted, k, n); + } + } + + private static <T extends Comparable<T>> void siftDown(T[] unsorted, int k, int n) { + while (2 * k <= n) { + int j = 2 * k; + if (j < n && less(unsorted, j, j + 1)) { + j++; + } + if (!less(unsorted, k, j)) { + break; + } + swap(unsorted, k, j); + k = j; + } + } + + private static <T> void swap(T[] array, int idx, int idy) { + T swap = array[idx - 1]; + array[idx - 1] = array[idy - 1]; + array[idy - 1] = swap; + } + + private static <T extends Comparable<T>> boolean less(T[] array, int idx, int idy) { + return array[idx - 1].compareTo(array[idy - 1]) < 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/InsertionSort.java b/Java/src/main/java/com/thealgorithms/sorts/InsertionSort.java new file mode 100644 index 000000000000..3b8c286515bc --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/InsertionSort.java @@ -0,0 +1,89 @@ +package com.thealgorithms.sorts; + +import java.util.function.Function; + +class InsertionSort implements SortAlgorithm { + + /** + * Generic insertion sort algorithm in increasing order. + * + * @param array the array to be sorted. + * @param <T> the class of array. + * @return sorted array. + */ + @Override + public <T extends Comparable<T>> T[] sort(T[] array) { + return sort(array, 0, array.length); + } + + public <T extends Comparable<T>> T[] sort(T[] array, int lo, int hi) { + for (int i = lo; i < hi; i++) { + for (int j = i; j > lo && SortUtils.less(array[j], array[j - 1]); j--) { + SortUtils.swap(array, j, j - 1); + } + } + return array; + } + + /** + * Sentinel sort is a function which on the first step finds the minimal element in the provided + * array and puts it to the zero position, such a trick gives us an ability to avoid redundant + * comparisons like `j > 0` and swaps (we can move elements on position right, until we find + * the right position for the chosen element) on further step. + * + * @param array the array to be sorted + * @param <T> Generic type which extends Comparable interface. + * @return sorted array + */ + public <T extends Comparable<T>> T[] sentinelSort(T[] array) { + int minElemIndex = 0; + int n = array.length; + if (n < 1) return array; + + // put the smallest element to the 0 position as a sentinel, which will allow us to avoid + // redundant comparisons like `j > 0` further + for (int i = 1; i < n; i++) + if (SortUtils.less(array[i], array[minElemIndex])) minElemIndex = i; + SortUtils.swap(array, 0, minElemIndex); + + for (int i = 2; i < n; i++) { + int j = i; + T currentValue = array[i]; + while (SortUtils.less(currentValue, array[j - 1])) { + array[j] = array[j - 1]; + j--; + } + + array[j] = currentValue; + } + + return array; + } + + /** + * Driver Code + */ + public static void main(String[] args) { + int size = 100_000; + Double[] randomArray = SortUtilsRandomGenerator.generateArray(size); + Double[] copyRandomArray = new Double[size]; + System.arraycopy(randomArray, 0, copyRandomArray, 0, size); + + InsertionSort insertionSort = new InsertionSort(); + double insertionTime = measureApproxExecTime(insertionSort::sort, randomArray); + System.out.printf("Original insertion time: %5.2f sec.%n", insertionTime); + + double insertionSentinelTime = measureApproxExecTime(insertionSort::sentinelSort, copyRandomArray); + System.out.printf("Sentinel insertion time: %5.2f sec.%n", insertionSentinelTime); + + // ~ 1.5 time sentinel sort is faster, then classical Insertion sort implementation. + System.out.printf("Sentinel insertion is %f3.2 time faster than Original insertion sort%n", insertionTime / insertionSentinelTime); + } + + private static double measureApproxExecTime(Function<Double[], Double[]> sortAlgorithm, Double[] randomArray) { + long start = System.currentTimeMillis(); + sortAlgorithm.apply(randomArray); + long end = System.currentTimeMillis(); + return (end - start) / 1000.0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java b/Java/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java new file mode 100644 index 000000000000..930bb02c7ce7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/IntrospectiveSort.java @@ -0,0 +1,90 @@ +package com.thealgorithms.sorts; + +/** + * Introspective Sort Algorithm Implementation + * + * @see <a href="https://en.wikipedia.org/wiki/Introsort">IntroSort Algorithm</a> + */ +public class IntrospectiveSort implements SortAlgorithm { + + private static final int INSERTION_SORT_THRESHOLD = 16; + + @Override + public <T extends Comparable<T>> T[] sort(T[] a) { + int n = a.length; + introSort(a, 0, n - 1, 2 * (int) (Math.log(n) / Math.log(2))); + return a; + } + + private static <T extends Comparable<T>> void swap(T[] a, int i, int j) { + T temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } + + private static <T extends Comparable<T>> void introSort(T[] a, int low, int high, int depth) { + while (high - low > INSERTION_SORT_THRESHOLD) { + if (depth == 0) { + heapSort(a, low, high); + return; + } + int pivotIndex = partition(a, low, high); + introSort(a, pivotIndex + 1, high, depth - 1); + high = pivotIndex - 1; + } + insertionSort(a, low, high); + } + + private static <T extends Comparable<T>> int partition(T[] a, int low, int high) { + int pivotIndex = low + (int) (Math.random() * (high - low + 1)); + swap(a, pivotIndex, high); + T pivot = a[high]; + int i = low - 1; + for (int j = low; j <= high - 1; j++) { + if (a[j].compareTo(pivot) <= 0) { + i++; + swap(a, i, j); + } + } + swap(a, i + 1, high); + return i + 1; + } + + private static <T extends Comparable<T>> void insertionSort(T[] a, int low, int high) { + for (int i = low + 1; i <= high; i++) { + T key = a[i]; + int j = i - 1; + while (j >= low && a[j].compareTo(key) > 0) { + a[j + 1] = a[j]; + j--; + } + a[j + 1] = key; + } + } + + private static <T extends Comparable<T>> void heapSort(T[] a, int low, int high) { + for (int i = (high + low - 1) / 2; i >= low; i--) { + heapify(a, i, high - low + 1, low); + } + for (int i = high; i > low; i--) { + swap(a, low, i); + heapify(a, low, i - low, low); + } + } + + private static <T extends Comparable<T>> void heapify(T[] a, int i, int n, int low) { + int left = 2 * i - low + 1; + int right = 2 * i - low + 2; + int largest = i; + if (left < n && a[left].compareTo(a[largest]) > 0) { + largest = left; + } + if (right < n && a[right].compareTo(a[largest]) > 0) { + largest = right; + } + if (largest != i) { + swap(a, i, largest); + heapify(a, largest, n, low); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/LinkListSort.java b/Java/src/main/java/com/thealgorithms/sorts/LinkListSort.java new file mode 100644 index 000000000000..fdbfe3130e41 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/LinkListSort.java @@ -0,0 +1,317 @@ +/** + * Author : Siddhant Swarup Mallick + * Github : https://github.com/siddhant2002 + */ + +/** Program description - To sort the LinkList as per sorting technique */ + +package com.thealgorithms.sorts; + +import java.util.Arrays; + +public class LinkListSort { + + public static boolean isSorted(int[] p, int option) { + int[] a = p; + // Array is taken as input from test class + int[] b = p; + // array similar to a + int ch = option; + // Choice is choosed as any number from 1 to 3 (So the linked list will be + // sorted by Merge sort technique/Insertion sort technique/Heap sort technique) + switch (ch) { + case 1: + Task nm = new Task(); + Node start = null; + Node prev = null; + Node fresh; + Node ptr; + for (int i = 0; i < a.length; i++) { + // New nodes are created and values are added + fresh = new Node(); // Node class is called + fresh.val = a[i]; // Node val is stored + if (start == null) + start = fresh; + else + prev.next = fresh; + prev = fresh; + } + start = nm.sortByMergeSort(start); + // method is being called + int i = 0; + for (ptr = start; ptr != null; ptr = ptr.next) { + a[i++] = ptr.val; + // storing the sorted values in the array + } + Arrays.sort(b); + // array b is sorted and it will return true when checked with sorted list + LinkListSort uu = new LinkListSort(); + return uu.compare(a, b); + // The given array and the expected array is checked if both are same then true + // is displayed else false is displayed + case 2: + Node start1 = null; + Node prev1 = null; + Node fresh1; + Node ptr1; + for (int i1 = 0; i1 < a.length; i1++) { + // New nodes are created and values are added + fresh1 = new Node(); // New node is created + fresh1.val = a[i1]; // Value is stored in the value part of the node + if (start1 == null) + start1 = fresh1; + else + prev1.next = fresh1; + prev1 = fresh1; + } + Task1 kk = new Task1(); + start1 = kk.sortByInsertionSort(start1); + // method is being called + int i1 = 0; + for (ptr1 = start1; ptr1 != null; ptr1 = ptr1.next) { + a[i1++] = ptr1.val; + // storing the sorted values in the array + } + LinkListSort uu1 = new LinkListSort(); + // array b is not sorted and it will return false when checked with sorted list + return uu1.compare(a, b); + // The given array and the expected array is checked if both are same then true + // is displayed else false is displayed + case 3: + Task2 mm = new Task2(); + Node start2 = null; + Node prev2 = null; + Node fresh2; + Node ptr2; + for (int i2 = 0; i2 < a.length; i2++) { + // New nodes are created and values are added + fresh2 = new Node(); // Node class is created + fresh2.val = a[i2]; // Value is stored in the value part of the Node + if (start2 == null) + start2 = fresh2; + else + prev2.next = fresh2; + prev2 = fresh2; + } + start2 = mm.sortByHeapSort(start2); + // method is being called + int i3 = 0; + for (ptr2 = start2; ptr2 != null; ptr2 = ptr2.next) { + a[i3++] = ptr2.val; + // storing the sorted values in the array + } + Arrays.sort(b); + // array b is sorted and it will return true when checked with sorted list + LinkListSort uu2 = new LinkListSort(); + return uu2.compare(a, b); + // The given array and the expected array is checked if both are same then true + // is displayed else false is displayed + default: + // default is used incase user puts a unauthorized value + System.out.println("Wrong choice"); + } + // Switch case is used to call the classes as per the user requirement + return false; + } + + boolean compare(int[] a, int[] b) { + for (int i = 0; i < a.length; i++) { + if (a[i] != b[i]) return false; + } + return true; + // Both the arrays are checked for equalness. If both are equal then true is + // returned else false is returned + } + /** + * OUTPUT : + * Input - {89,56,98,123,26,75,12,40,39,68,91} is same for all the 3 classes + * Output: [12 26 39 40 56 68 75 89 91 98 123] is same for all the 3 classes + * 1st approach Time Complexity : O(n logn) + * Auxiliary Space Complexity : O(n) + * 2nd approach Time Complexity : O(n^2) + * Auxiliary Space Complexity : O(n) + * 3rd approach Time Complexity : O(n logn) + * Auxiliary Space Complexity : O(n) + */ +} + +class Node { + + int val; + Node next; + // Node class for creation of linklist nodes +} + +class Task { + + private int[] a; + + public Node sortByMergeSort(Node head) { + if (head == null || head.next == null) return head; + int c = count(head); + a = new int[c]; + // Array of size c is created + int i = 0; + for (Node ptr = head; ptr != null; ptr = ptr.next) { + a[i++] = ptr.val; + } + // values are stored in the array + i = 0; + task(a, 0, c - 1); + // task method will be executed + for (Node ptr = head; ptr != null; ptr = ptr.next) { + ptr.val = a[i++]; + // Value is stored in the linklist after being sorted + } + return head; + } + + int count(Node head) { + int c = 0; + Node ptr; + for (ptr = head; ptr != null; ptr = ptr.next) { + c++; + } + return c; + // This Method is used to count number of elements/nodes present in the linklist + // It will return a integer type value denoting the number of nodes present + } + + void task(int[] n, int i, int j) { + if (i < j) { + int m = (i + j) / 2; + task(n, i, m); + task(n, m + 1, j); + task1(n, i, m, j); + // Array is halved and sent for sorting + } + } + + void task1(int[] n, int s, int m, int e) { + int i = s; + int k = 0; + int j = m + 1; + int[] b = new int[e - s + 1]; + while (i <= m && j <= e) { + if (n[j] >= n[i]) + b[k++] = n[i++]; + else + b[k++] = n[j++]; + } + // Smallest number is stored after checking from both the arrays + while (i <= m) { + b[k++] = n[i++]; + } + while (j <= e) { + b[k++] = n[j++]; + } + for (int p = s; p <= e; p++) { + a[p] = b[p - s]; + } + } + // The method task and task1 is used to sort the linklist using merge sort +} + +class Task1 { + + public Node sortByInsertionSort(Node head) { + if (head == null || head.next == null) return head; + int c = count(head); + int[] a = new int[c]; + // Array of size c is created + a[0] = head.val; + int i; + Node ptr; + for (ptr = head.next, i = 1; ptr != null; ptr = ptr.next, i++) { + int j = i - 1; + while (j >= 0 && a[j] > ptr.val) { + // values are stored in the array + a[j + 1] = a[j]; + j--; + } + a[j + 1] = ptr.val; + } + i = 0; + for (ptr = head; ptr != null; ptr = ptr.next) { + ptr.val = a[i++]; + // Value is stored in the linklist after being sorted + } + return head; + } + + static int count(Node head) { + Node ptr; + int c = 0; + for (ptr = head; ptr != null; ptr = ptr.next) { + c++; + } + return c; + // This Method is used to count number of elements/nodes present in the linklist + // It will return a integer type value denoting the number of nodes present + } + // The method task and task1 is used to sort the linklist using insertion sort +} + +class Task2 { + + private int[] a; + + public Node sortByHeapSort(Node head) { + if (head == null || head.next == null) return head; + int c = count(head); + a = new int[c]; + // Array of size c is created + int i = 0; + for (Node ptr = head; ptr != null; ptr = ptr.next) { + a[i++] = ptr.val; + // values are stored in the array + } + i = 0; + task(a); + for (Node ptr = head; ptr != null; ptr = ptr.next) { + ptr.val = a[i++]; + // Value is stored in the linklist after being sorted + } + return head; + } + + int count(Node head) { + int c = 0; + Node ptr; + for (ptr = head; ptr != null; ptr = ptr.next) { + c++; + } + return c; + // This Method is used to count number of elements/nodes present in the linklist + // It will return a integer type value denoting the number of nodes present + } + + void task(int[] n) { + int k = n.length; + for (int i = k / 2 - 1; i >= 0; i--) { + task1(n, k, i); + } + for (int i = k - 1; i > 0; i--) { + int d = n[0]; + n[0] = n[i]; + n[i] = d; + task1(n, i, 0); + // recursive calling of task1 method + } + } + + void task1(int[] n, int k, int i) { + int p = i; + int l = 2 * i + 1; + int r = 2 * i + 2; + if (l < k && n[l] > n[p]) p = l; + if (r < k && n[r] > n[p]) p = r; + if (p != i) { + int d = n[p]; + n[p] = n[i]; + n[i] = d; + task1(n, k, p); + } + } + // The method task and task1 is used to sort the linklist using heap sort +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/MergeSort.java b/Java/src/main/java/com/thealgorithms/sorts/MergeSort.java new file mode 100644 index 000000000000..9949783ca21b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/MergeSort.java @@ -0,0 +1,69 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.less; + +/** + * Generic merge sort algorithm. + * + * @see SortAlgorithm + */ +class MergeSort implements SortAlgorithm { + + private Comparable[] aux; + + /** + * Generic merge sort algorithm implements. + * + * @param unsorted the array which should be sorted. + * @param <T> Comparable class. + * @return sorted array. + */ + @Override + public <T extends Comparable<T>> T[] sort(T[] unsorted) { + aux = new Comparable[unsorted.length]; + 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 <T extends Comparable<T>> 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. + */ + @SuppressWarnings("unchecked") + private <T extends Comparable<T>> void merge(T[] arr, int left, int mid, int right) { + int i = left; + int j = mid + 1; + System.arraycopy(arr, left, aux, left, right + 1 - left); + + for (int k = left; k <= right; k++) { + if (j > right) { + arr[k] = (T) aux[i++]; + } else if (i > mid) { + arr[k] = (T) aux[j++]; + } else if (less(aux[j], aux[i])) { + arr[k] = (T) aux[j++]; + } else { + arr[k] = (T) aux[i++]; + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java b/Java/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java new file mode 100644 index 000000000000..290c2df59c3d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java @@ -0,0 +1,73 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; +import java.util.Scanner; + +/*This code implements the mergeSort algorithm without extra space +For understanding about mergesort visit :https://www.geeksforgeeks.org/merge-sort/ + */ +public final class MergeSortNoExtraSpace { + private MergeSortNoExtraSpace() { + } + + public static void callMergeSort(int[] a, int n) { + int maxele = Arrays.stream(a).max().getAsInt() + 1; + mergeSort(a, 0, n - 1, maxele); + } + + public static void mergeSort(int[] a, int start, int end, int maxele) { // this function divides the array into 2 halves + if (start < end) { + int mid = (start + end) / 2; + mergeSort(a, start, mid, maxele); + mergeSort(a, mid + 1, end, maxele); + implementMergeSort(a, start, mid, end, maxele); + } + } + + public static void implementMergeSort(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(); + } + callMergeSort(a, n); + for (int i = 0; i < a.length; i++) { + System.out.print(a[i] + " "); + } + inp.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java b/Java/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java new file mode 100644 index 000000000000..f67ba631be0e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java @@ -0,0 +1,60 @@ +package com.thealgorithms.sorts; + +import java.util.ArrayList; +import java.util.List; + +public class MergeSortRecursive { + + List<Integer> arr; + + public MergeSortRecursive(List<Integer> arr) { + this.arr = arr; + } + + public List<Integer> mergeSort() { + return merge(arr); + } + + private static List<Integer> merge(List<Integer> arr) { + // base condition + if (arr.size() <= 1) { + return arr; + } + + int arrLength = arr.size(); + int half = arrLength / 2; + List<Integer> arrA = arr.subList(0, half); + List<Integer> arrB = arr.subList(half, arr.size()); + + // recursion + arrA = merge(arrA); + arrB = merge(arrB); + + return sort(arrA, arrB); + } + + private static List<Integer> sort(List<Integer> unsortedA, List<Integer> unsortedB) { + if (unsortedA.size() <= 0 && unsortedB.size() <= 0) { + return new ArrayList<>(); + } + if (unsortedA.size() <= 0) { + return unsortedB; + } + if (unsortedB.size() <= 0) { + return unsortedA; + } + if (unsortedA.get(0) <= unsortedB.get(0)) { + List<Integer> newAl = new ArrayList<Integer>() { + { add(unsortedA.get(0)); } + }; + newAl.addAll(sort(unsortedA.subList(1, unsortedA.size()), unsortedB)); + return newAl; + } else { + List<Integer> newAl = new ArrayList<Integer>() { + { add(unsortedB.get(0)); } + }; + newAl.addAll(sort(unsortedA, unsortedB.subList(1, unsortedB.size()))); + return newAl; + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/OddEvenSort.java b/Java/src/main/java/com/thealgorithms/sorts/OddEvenSort.java new file mode 100644 index 000000000000..fb6e4d2649cb --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/OddEvenSort.java @@ -0,0 +1,69 @@ +package com.thealgorithms.sorts; + +import java.util.Random; + +// https://en.wikipedia.org/wiki/Odd%E2%80%93even_sort +public final class OddEvenSort { + private OddEvenSort() { + } + + public static void main(String[] args) { + int[] arr = new int[100]; + + Random random = new Random(); + + // Print out unsorted elements + for (int i = 0; i < arr.length; ++i) { + arr[i] = random.nextInt(100) - 50; + System.out.println(arr[i]); + } + System.out.println("--------------"); + + oddEvenSort(arr); + + // Print Sorted elements + for (int i = 0; i < arr.length - 1; ++i) { + System.out.println(arr[i]); + assert arr[i] <= arr[i + 1]; + } + } + + /** + * Odd Even Sort algorithms implements + * + * @param arr the array contains elements + */ + public static void oddEvenSort(int[] arr) { + boolean sorted = false; + 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); + sorted = false; + } + } + + for (int i = 0; i < arr.length - 1; i += 2) { + if (arr[i] > arr[i + 1]) { + swap(arr, i, i + 1); + sorted = false; + } + } + } + } + + /** + * Helper function to swap two array values. + * + * @param arr the array contains elements + * @param i the first index to be swapped + * @param j the second index to be swapped + */ + private static void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/PancakeSort.java b/Java/src/main/java/com/thealgorithms/sorts/PancakeSort.java new file mode 100644 index 000000000000..cd3e89307238 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/PancakeSort.java @@ -0,0 +1,65 @@ +package com.thealgorithms.sorts; + +/** + * Implementation of pancake sort + * + * @author Podshivalov Nikita (https://github.com/nikitap492) + * @since 2018-04-10 + */ +public class PancakeSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> 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 (SortUtils.less(max, array[j])) { + max = array[j]; + index = j; + } + } + SortUtils.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); + SortUtils.print(arr); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java b/Java/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java new file mode 100644 index 000000000000..9c0ab45b6a3c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java @@ -0,0 +1,53 @@ +package com.thealgorithms.sorts; + +import java.util.ArrayList; + +public class PigeonholeSort { + + /* + This code implements the pigeonhole sort algorithm for the integer array, + but we can also implement this for string arrays too. + See https://www.geeksforgeeks.org/pigeonhole-sort/ + */ + void sort(Integer[] array) { + int maxElement = array[0]; + for (int element : array) { + if (element > maxElement) maxElement = element; + } + + int numOfPigeonholes = 1 + maxElement; + ArrayList<Integer>[] pigeonHole = new ArrayList[numOfPigeonholes]; + + for (int k = 0; k < numOfPigeonholes; k++) { + pigeonHole[k] = new ArrayList<>(); + } + + for (int t : array) { + pigeonHole[t].add(t); + } + + int k = 0; + for (ArrayList<Integer> ph : pigeonHole) { + for (int elements : ph) { + array[k] = elements; + k = k + 1; + } + } + } + + public static void main(String[] args) { + PigeonholeSort pigeonholeSort = new PigeonholeSort(); + Integer[] arr = {8, 3, 2, 7, 4, 6, 8}; + + System.out.print("Unsorted order is : "); + SortUtils.print(arr); + + pigeonholeSort.sort(arr); + + System.out.print("Sorted order is : "); + for (int i = 0; i < arr.length; i++) { + assert (arr[i]) <= (arr[i + 1]); + } + SortUtils.print(arr); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/QuickSort.java b/Java/src/main/java/com/thealgorithms/sorts/QuickSort.java new file mode 100644 index 000000000000..3ebdd96ce938 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/QuickSort.java @@ -0,0 +1,77 @@ +package com.thealgorithms.sorts; + +/** + * @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 extends Comparable<T>> 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 <T extends Comparable<T>> 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); + } + } + + /** + * Randomize 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 <T extends Comparable<T>> int randomPartition(T[] array, int left, int right) { + int randomIndex = left + (int) (Math.random() * (right - left + 1)); + SortUtils.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 <T extends Comparable<T>> int partition(T[] array, int left, int right) { + int mid = (left + right) >>> 1; + T pivot = array[mid]; + + while (left <= right) { + while (SortUtils.less(array[left], pivot)) { + ++left; + } + while (SortUtils.less(pivot, array[right])) { + --right; + } + if (left <= right) { + SortUtils.swap(array, left, right); + ++left; + --right; + } + } + return left; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/RadixSort.java b/Java/src/main/java/com/thealgorithms/sorts/RadixSort.java new file mode 100644 index 000000000000..a87097bf6e9d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/RadixSort.java @@ -0,0 +1,62 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; + +final class RadixSort { + private 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]--; + } + + System.arraycopy(output, 0, arr, 0, n); + } + + 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/Java/src/main/java/com/thealgorithms/sorts/SelectionSort.java b/Java/src/main/java/com/thealgorithms/sorts/SelectionSort.java new file mode 100644 index 000000000000..e43df7fe622e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SelectionSort.java @@ -0,0 +1,48 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.swap; + +public class SelectionSort implements SortAlgorithm { + + /** + * Generic selection sort algorithm in increasing order. + * + * @param arr the array to be sorted. + * @param <T> the class of array. + * @return sorted array. + */ + @Override + public <T extends Comparable<T>> 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) { + swap(arr, i, minIndex); + } + } + 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/Java/src/main/java/com/thealgorithms/sorts/ShellSort.java b/Java/src/main/java/com/thealgorithms/sorts/ShellSort.java new file mode 100644 index 000000000000..37a50e855698 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/ShellSort.java @@ -0,0 +1,46 @@ +package com.thealgorithms.sorts; + +public class ShellSort implements SortAlgorithm { + + /** + * Implements generic shell sort. + * + * @param array the array to be sorted. + * @param <T> the type of elements in the array. + * @return the sorted array. + */ + @Override + public <T extends Comparable<T>> 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 && SortUtils.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]; + } + SortUtils.print(toSort); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/SimpleSort.java b/Java/src/main/java/com/thealgorithms/sorts/SimpleSort.java new file mode 100644 index 000000000000..7aab7c784b92 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SimpleSort.java @@ -0,0 +1,53 @@ +package com.thealgorithms.sorts; + +public class SimpleSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] array) { + final int length = array.length; + + for (int i = 0; i < length; i++) { + for (int j = i + 1; j < length; j++) { + if (SortUtils.less(array[j], array[i])) { + T element = array[j]; + array[j] = array[i]; + array[i] = element; + } + } + } + + return array; + } + + public static void main(String[] args) { + // ==== Int ======= + Integer[] a = {3, 7, 45, 1, 33, 5, 2, 9}; + System.out.print("unsorted: "); + SortUtils.print(a); + System.out.println(); + + new SimpleSort().sort(a); + System.out.print("sorted: "); + SortUtils.print(a); + System.out.println(); + + // ==== String ======= + String[] b = { + "banana", + "berry", + "orange", + "grape", + "peach", + "cherry", + "apple", + "pineapple", + }; + System.out.print("unsorted: "); + SortUtils.print(b); + System.out.println(); + + new SimpleSort().sort(b); + System.out.print("sorted: "); + SortUtils.print(b); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/SlowSort.java b/Java/src/main/java/com/thealgorithms/sorts/SlowSort.java new file mode 100644 index 000000000000..dcd426b31c0d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SlowSort.java @@ -0,0 +1,29 @@ +package com.thealgorithms.sorts; + +/** + * @author Amir Hassan (https://github.com/ahsNT) + * @see SortAlgorithm + */ +public class SlowSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] unsortedArray) { + sort(unsortedArray, 0, unsortedArray.length - 1); + return unsortedArray; + } + + private <T extends Comparable<T>> void sort(T[] array, int i, int j) { + if (SortUtils.greaterOrEqual(i, j)) { + return; + } + final int m = (i + j) >>> 1; + sort(array, i, m); + sort(array, m + 1, j); + if (SortUtils.less(array[j], array[m])) { + T temp = array[j]; + array[j] = array[m]; + array[m] = temp; + } + sort(array, i, j - 1); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java b/Java/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java new file mode 100644 index 000000000000..7a3ded37bf3f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SortAlgorithm.java @@ -0,0 +1,30 @@ +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 extends Comparable<T>> 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<T extends Comparable<T>> List<T> sort(List<T> unsorted) { + return Arrays.asList(sort(unsorted.toArray((T[]) new Comparable[unsorted.size()]))); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/SortUtils.java b/Java/src/main/java/com/thealgorithms/sorts/SortUtils.java new file mode 100644 index 000000000000..fda1975189ec --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SortUtils.java @@ -0,0 +1,119 @@ +package com.thealgorithms.sorts; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +final class SortUtils { + private SortUtils() { + } + + /** + * Swaps two elements at the given positions in an array. + * + * @param array the array in which to swap elements + * @param i the index of the first element to swap + * @param j the index of the second element to swap + * @param <T> the type of elements in the array + */ + public static <T> void swap(T[] array, int i, int j) { + T temp = array[i]; + array[i] = array[j]; + array[j] = temp; + } + + /** + * Compares two elements to see if the first is less than the second. + * + * @param firstElement the first element to compare + * @param secondElement the second element to compare + * @return true if the first element is less than the second, false otherwise + */ + public static <T extends Comparable<T>> boolean less(T firstElement, T secondElement) { + return firstElement.compareTo(secondElement) < 0; + } + + /** + * Compares two elements to see if the first is greater than the second. + * + * @param firstElement the first element to compare + * @param secondElement the second element to compare + * @return true if the first element is greater than the second, false otherwise + */ + public static <T extends Comparable<T>> boolean greater(T firstElement, T secondElement) { + return firstElement.compareTo(secondElement) > 0; + } + + /** + * Compares two elements to see if the first is greater than or equal to the second. + * + * @param firstElement the first element to compare + * @param secondElement the second element to compare + * @return true if the first element is greater than or equal to the second, false otherwise + */ + static <T extends Comparable<T>> boolean greaterOrEqual(T firstElement, T secondElement) { + return firstElement.compareTo(secondElement) >= 0; + } + + /** + * Prints the elements of a list to standard output. + * + * @param listToPrint the list to print + */ + static void print(List<?> listToPrint) { + String result = listToPrint.stream().map(Object::toString).collect(Collectors.joining(" ")); + System.out.println(result); + } + + /** + * Prints the elements of an array to standard output. + * + * @param array the array to print + */ + static <T> void print(T[] array) { + System.out.println(Arrays.toString(array)); + } + + /** + * Flips the order of elements in the specified range of an array. + * + * @param array the array whose elements are to be flipped + * @param left the left boundary of the range to be flipped (inclusive) + * @param right the right boundary of the range to be flipped (inclusive) + */ + public static <T extends Comparable<T>> void flip(T[] array, int left, int right) { + while (left <= right) { + swap(array, left++, right--); + } + } + + /** + * Checks whether the array is sorted in ascending order. + * + * @param array the array to check + * @return true if the array is sorted in ascending order, false otherwise + */ + public static <T extends Comparable<T>> boolean isSorted(T[] array) { + for (int i = 1; i < array.length; i++) { + if (less(array[i], array[i - 1])) { + return false; + } + } + return true; + } + + /** + * Checks whether the list is sorted in ascending order. + * + * @param list the list to check + * @return true if the list is sorted in ascending order, false otherwise + */ + public static <T extends Comparable<T>> boolean isSorted(List<T> list) { + for (int i = 1; i < list.size(); i++) { + if (less(list.get(i), list.get(i - 1))) { + return false; + } + } + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java b/Java/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java new file mode 100644 index 000000000000..b048d0245b64 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java @@ -0,0 +1,46 @@ +package com.thealgorithms.sorts; + +import java.util.Random; + +public final class SortUtilsRandomGenerator { + private SortUtilsRandomGenerator() { + } + + private static final Random RANDOM; + private static final long SEED; + + static { + SEED = System.currentTimeMillis(); + RANDOM = new Random(SEED); + } + + /** + * Function to generate array of double values, with predefined size. + * + * @param size result array size + * @return array of Double values, randomly generated, each element is between [0, 1) + */ + public static Double[] generateArray(int size) { + Double[] arr = new Double[size]; + for (int i = 0; i < size; i++) arr[i] = generateDouble(); + return arr; + } + + /** + * Function to generate Double value. + * + * @return Double value [0, 1) + */ + public static Double generateDouble() { + return RANDOM.nextDouble(); + } + + /** + * Function to generate int value. + * + * @return int value [0, n) + */ + public static int generateInt(int n) { + return RANDOM.nextInt(n); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/StoogeSort.java b/Java/src/main/java/com/thealgorithms/sorts/StoogeSort.java new file mode 100644 index 000000000000..330f9752d1e4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/StoogeSort.java @@ -0,0 +1,51 @@ +package com.thealgorithms.sorts; + +/** + * @author Amir Hassan (https://github.com/ahsNT) + * @see SortAlgorithm + */ +public class StoogeSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] unsortedArray) { + sort(unsortedArray, 0, unsortedArray.length); + return unsortedArray; + } + + public <T extends Comparable<T>> T[] sort(T[] unsortedArray, int start, int end) { + if (SortUtils.less(unsortedArray[end - 1], unsortedArray[start])) { + T temp = unsortedArray[start]; + unsortedArray[start] = unsortedArray[end - 1]; + unsortedArray[end - 1] = temp; + } + + int len = end - start; + if (len > 2) { + int third = len / 3; + sort(unsortedArray, start, end - third); + sort(unsortedArray, start + third, end); + sort(unsortedArray, start, end - third); + } + return unsortedArray; + } + + public static void main(String[] args) { + StoogeSort stoogeSort = new StoogeSort(); + + Integer[] integerArray = {8, 84, 53, 953, 64, 2, 202}; + // Print integerArray unsorted + SortUtils.print(integerArray); + + stoogeSort.sort(integerArray); + // Print integerArray sorted + SortUtils.print(integerArray); + + String[] stringArray = {"g", "d", "a", "b", "f", "c", "e"}; + // Print stringArray unsorted + SortUtils.print(stringArray); + + stoogeSort.sort(stringArray); + // Print stringArray sorted + SortUtils.print(stringArray); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/StrandSort.java b/Java/src/main/java/com/thealgorithms/sorts/StrandSort.java new file mode 100644 index 000000000000..7e2251d70640 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/StrandSort.java @@ -0,0 +1,43 @@ +package com.thealgorithms.sorts; + +import java.util.Iterator; +import java.util.LinkedList; + +public final class StrandSort { + private StrandSort() { + } + + // note: the input list is destroyed + public static <E extends Comparable<? super E>> LinkedList<E> strandSort(LinkedList<E> list) { + if (list.size() <= 1) return list; + + LinkedList<E> result = new LinkedList<E>(); + while (list.size() > 0) { + LinkedList<E> sorted = new LinkedList<E>(); + sorted.add(list.removeFirst()); // same as remove() or remove(0) + for (Iterator<E> it = list.iterator(); it.hasNext();) { + E elem = it.next(); + if (sorted.peekLast().compareTo(elem) <= 0) { + sorted.addLast(elem); // same as add(elem) or add(0, elem) + it.remove(); + } + } + result = merge(sorted, result); + } + return result; + } + + private static <E extends Comparable<? super E>> LinkedList<E> merge(LinkedList<E> left, LinkedList<E> right) { + LinkedList<E> result = new LinkedList<E>(); + while (!left.isEmpty() && !right.isEmpty()) { + // change the direction of this comparison to change the direction of the sort + if (left.peek().compareTo(right.peek()) <= 0) + result.add(left.remove()); + else + result.add(right.remove()); + } + result.addAll(left); + result.addAll(right); + return result; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/SwapSort.java b/Java/src/main/java/com/thealgorithms/sorts/SwapSort.java new file mode 100644 index 000000000000..08ce988578f3 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/SwapSort.java @@ -0,0 +1,74 @@ +package com.thealgorithms.sorts; + +/** + * The idea of Swap-Sort is to count the number m of smaller values (that are in + * A) from each element of an array A(1...n) and then swap the element with the + * element in A(m+1). This ensures that the exchanged element is already in the + * correct, i.e. final, position. The disadvantage of this algorithm is that + * each element may only occur once, otherwise there is no termination. + */ +public class SwapSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] array) { + int len = array.length; + int index = 0; + + while (index < len - 1) { + int amountSmallerElements = this.getSmallerElementCount(array, index); + + if (amountSmallerElements > 0 && index != amountSmallerElements) { + T element = array[index]; + array[index] = array[amountSmallerElements]; + array[amountSmallerElements] = element; + } else { + index++; + } + } + + return array; + } + + private <T extends Comparable<T>> int getSmallerElementCount(T[] array, int index) { + int counter = 0; + for (int i = 0; i < array.length; i++) { + if (SortUtils.less(array[i], array[index])) { + counter++; + } + } + + return counter; + } + + public static void main(String[] args) { + // ==== Int ======= + Integer[] a = {3, 7, 45, 1, 33, 5, 2, 9}; + System.out.print("unsorted: "); + SortUtils.print(a); + System.out.println(); + + new SwapSort().sort(a); + System.out.print("sorted: "); + SortUtils.print(a); + System.out.println(); + + // ==== String ======= + String[] b = { + "banana", + "berry", + "orange", + "grape", + "peach", + "cherry", + "apple", + "pineapple", + }; + System.out.print("unsorted: "); + SortUtils.print(b); + System.out.println(); + + new SwapSort().sort(b); + System.out.print("sorted: "); + SortUtils.print(b); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/TimSort.java b/Java/src/main/java/com/thealgorithms/sorts/TimSort.java new file mode 100644 index 000000000000..85e16636c6ae --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/TimSort.java @@ -0,0 +1,50 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.less; + +/** + * This is simplified TimSort algorithm implementation. The original one is more complicated. + * <p> + * For more details @see <a href="https://en.wikipedia.org/wiki/Timsort">TimSort Algorithm</a> + */ +class TimSort implements SortAlgorithm { + private static final int SUB_ARRAY_SIZE = 32; + private Comparable[] aux; + + @Override + public <T extends Comparable<T>> T[] sort(T[] a) { + int n = a.length; + + InsertionSort insertionSort = new InsertionSort(); + for (int i = 0; i < n; i += SUB_ARRAY_SIZE) { + insertionSort.sort(a, i, Math.min(i + SUB_ARRAY_SIZE, n)); + } + + aux = new Comparable[n]; + for (int sz = SUB_ARRAY_SIZE; sz < n; sz = sz + sz) { + for (int lo = 0; lo < n - sz; lo += sz + sz) { + merge(a, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, n - 1)); + } + } + + return a; + } + + private <T extends Comparable<T>> void merge(T[] a, int lo, int mid, int hi) { + int i = lo; + int j = mid + 1; + System.arraycopy(a, lo, aux, lo, hi + 1 - lo); + + for (int k = lo; k <= hi; k++) { + if (j > hi) { + a[k] = (T) aux[i++]; + } else if (i > mid) { + a[k] = (T) aux[j++]; + } else if (less(aux[j], aux[i])) { + a[k] = (T) aux[j++]; + } else { + a[k] = (T) aux[i++]; + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/TopologicalSort.java b/Java/src/main/java/com/thealgorithms/sorts/TopologicalSort.java new file mode 100644 index 000000000000..dd3a763bb197 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/TopologicalSort.java @@ -0,0 +1,133 @@ +package com.thealgorithms.sorts; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; + +/** + * The Topological Sorting algorithm linearly orders a DAG or Directed Acyclic Graph into + * a linked list. A Directed Graph is proven to be acyclic when a DFS or Depth First Search is + * performed, yielding no back-edges. + * + * https://en.wikipedia.org/wiki/Topological_sorting + * + * @author Jonathan Taylor (https://github.com/Jtmonument) + * Based on Introduction to Algorithms 3rd Edition + */ +public final class TopologicalSort { + private TopologicalSort() { + } + + /* + * Enum to represent the colors for the depth first search + * */ + private enum Color { + WHITE, + GRAY, + BLACK, + } + + /* + * Class to represent vertices + * */ + private static class Vertex { + + /* + * Name of vertex + * */ + public final String label; + + /* + * Represents the category of visit in DFS + * */ + public Color color = Color.WHITE; + + /* + * The array of names of descendant vertices + * */ + public final ArrayList<String> next = new ArrayList<>(); + + Vertex(String label) { + this.label = label; + } + } + + /* + * Graph class uses the adjacency list representation + * */ + static class Graph { + + /* + * Adjacency list representation + * */ + private final HashMap<String, Vertex> adj = new LinkedHashMap<>(); + + /* + * Function to add an edge to the graph + * */ + public void addEdge(String label, String... next) { + adj.put(label, new Vertex(label)); + if (!next[0].isEmpty()) Collections.addAll(adj.get(label).next, next); + } + } + + /* + * Depth First Search + * + * DFS(G) + * for each vertex u ∈ G.V + * u.color = WHITE + * u.π = NIL + * time = 0 + * for each vertex u ∈ G.V + * if u.color == WHITE + * DFS-VISIT(G, u) + * + * Performed in Θ(V + E) time + * */ + public static LinkedList<String> sort(Graph graph) { + LinkedList<String> list = new LinkedList<>(); + graph.adj.forEach((name, vertex) -> { + if (vertex.color == Color.WHITE) { + list.addFirst(sort(graph, vertex, list)); + } + }); + return list; + } + + /* + * Depth First Search Visit + * + * DFS-Visit(G, u) + * time = time + 1 + * u.d = time + * u.color = GRAY + * for each v ∈ G.Adj[u] + * if v.color == WHITE + * v.π = u + * DFS-Visit(G, u) + * u.color = BLACK + * time = time + 1 + * u.f = time + * */ + private static String sort(Graph graph, Vertex u, LinkedList<String> list) { + u.color = Color.GRAY; + graph.adj.get(u.label).next.forEach(label -> { + if (graph.adj.get(label).color == Color.WHITE) { + list.addFirst(sort(graph, graph.adj.get(label), list)); + } else if (graph.adj.get(label).color == Color.GRAY) { + /* + * A back edge exists if an edge (u, v) connects a vertex u to its ancestor vertex v + * in a depth first tree. If v.d ≤ u.d < u.f ≤ v.f + * + * In many cases, we will not know u.f, but v.color denotes the type of edge + * */ + throw new RuntimeException("This graph contains a cycle. No linear ordering is possible. Back edge: " + u.label + " -> " + label); + } + }); + u.color = Color.BLACK; + return u.label; + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/TreeSort.java b/Java/src/main/java/com/thealgorithms/sorts/TreeSort.java new file mode 100644 index 000000000000..e060af542f98 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/TreeSort.java @@ -0,0 +1,118 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.sorts.SortUtils.print; + +import com.thealgorithms.datastructures.trees.BSTRecursiveGeneric; +import java.util.List; + +/** + * <h1> Implementation of the Tree Sort algorithm</h1> + * + * <p> + * 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 + * </p> + * + * @author Madhur Panwar (https://github.com/mdrpanwar) + */ +public class TreeSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] unsortedArray) { + return doTreeSortArray(unsortedArray); + } + + @Override + public <T extends Comparable<T>> List<T> sort(List<T> unsortedList) { + return doTreeSortList(unsortedList); + } + + private <T extends Comparable<T>> T[] doTreeSortArray(T[] unsortedArray) { + // create a generic BST tree + BSTRecursiveGeneric<T> tree = new BSTRecursiveGeneric<T>(); + + // add all elements to the tree + for (T element : unsortedArray) { + tree.add(element); + } + + // get the sorted list by inorder traversal of the tree + List<T> 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 <T extends Comparable<T>> List<T> doTreeSortList(List<T> unsortedList) { + // create a generic BST tree + BSTRecursiveGeneric<T> tree = new BSTRecursiveGeneric<T>(); + + // 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.printf("%-10s", "unsorted: "); + print(a); + a = treeSort.sort(a); + System.out.printf("%-10s", "sorted: "); + print(a); + System.out.println(); + + // ==== Integer List ======= + System.out.println("Testing for Integer List...."); + List<Integer> intList = List.of(3, -7, 45, 1, 343, -5, 2, 9); + System.out.printf("%-10s", "unsorted: "); + print(intList); + intList = treeSort.sort(intList); + System.out.printf("%-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.printf("%-10s", "unsorted: "); + print(b); + b = treeSort.sort(b); + System.out.printf("%-10s", "sorted: "); + print(b); + System.out.println(); + + // ==== String List ======= + System.out.println("Testing for String List...."); + List<String> stringList = List.of("banana", "berry", "orange", "grape", "peach", "cherry", "apple", "pineapple"); + System.out.printf("%-10s", "unsorted: "); + print(stringList); + stringList = treeSort.sort(stringList); + System.out.printf("%-10s", "sorted: "); + print(stringList); + } +} diff --git a/Java/src/main/java/com/thealgorithms/sorts/WiggleSort.java b/Java/src/main/java/com/thealgorithms/sorts/WiggleSort.java new file mode 100644 index 000000000000..c272b820d07a --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/sorts/WiggleSort.java @@ -0,0 +1,85 @@ +package com.thealgorithms.sorts; + +import static com.thealgorithms.maths.Ceil.ceil; +import static com.thealgorithms.maths.Floor.floor; +import static com.thealgorithms.searches.QuickSelect.select; + +import java.util.Arrays; + +/** + * A wiggle sort implementation based on John L.s' answer in + * https://cs.stackexchange.com/questions/125372/how-to-wiggle-sort-an-array-in-linear-time-complexity + * Also have a look at: + * https://cs.stackexchange.com/questions/125372/how-to-wiggle-sort-an-array-in-linear-time-complexity?noredirect=1&lq=1 + * Not all arrays are wiggle-sortable. This algorithm will find some obviously not wiggle-sortable + * arrays and throw an error, but there are some exceptions that won't be caught, for example [1, 2, + * 2]. + */ +public class WiggleSort implements SortAlgorithm { + + @Override + public <T extends Comparable<T>> T[] sort(T[] unsorted) { + return wiggleSort(unsorted); + } + + private int mapIndex(int index, int n) { + return ((2 * index + 1) % (n | 1)); + } + + /** + * Modified Dutch National Flag Sort. See also: sorts/DutchNationalFlagSort + * + * @param sortThis array to sort into group "greater", "equal" and "smaller" than median + * @param median defines the groups + * @param <T> extends interface Comparable + */ + private <T extends Comparable<T>> void triColorSort(T[] sortThis, T median) { + int n = sortThis.length; + int i = 0; + int j = 0; + int k = n - 1; + while (j <= k) { + if (0 < sortThis[mapIndex(j, n)].compareTo(median)) { + SortUtils.swap(sortThis, mapIndex(j, n), mapIndex(i, n)); + i++; + j++; + } else if (0 > sortThis[mapIndex(j, n)].compareTo(median)) { + SortUtils.swap(sortThis, mapIndex(j, n), mapIndex(k, n)); + k--; + } else { + j++; + } + } + } + + private <T extends Comparable<T>> T[] wiggleSort(T[] sortThis) { + // find the median using quickSelect (if the result isn't in the array, use the next greater + // value) + T median; + + median = select(Arrays.asList(sortThis), (int) floor(sortThis.length / 2.0)); + + int numMedians = 0; + + for (T sortThi : sortThis) { + if (0 == sortThi.compareTo(median)) { + numMedians++; + } + } + // added condition preventing off-by-one errors for odd arrays. + // https://cs.stackexchange.com/questions/150886/how-to-find-wiggle-sortable-arrays-did-i-misunderstand-john-l-s-answer?noredirect=1&lq=1 + if (sortThis.length % 2 == 1 && numMedians == ceil(sortThis.length / 2.0)) { + T smallestValue = select(Arrays.asList(sortThis), 0); + if (!(0 == smallestValue.compareTo(median))) { + throw new IllegalArgumentException("For odd Arrays if the median appears ceil(n/2) times, " + + "the median has to be the smallest values in the array."); + } + } + if (numMedians > ceil(sortThis.length / 2.0)) { + throw new IllegalArgumentException("No more than half the number of values may be the same."); + } + + triColorSort(sortThis, median); + return sortThis; + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java b/Java/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java new file mode 100644 index 000000000000..a8f5254b22c5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java @@ -0,0 +1,84 @@ +package com.thealgorithms.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 <a href="https://github.com/khalil2535">khalil2535<a> + * @author shellhub + */ +final class BalancedBrackets { + private 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<Character> bracketsStack = new Stack<>(); + for (char bracket : brackets.toCharArray()) { + switch (bracket) { + case '(': + case '[': + case '{': + bracketsStack.push(bracket); + break; + case ')': + case ']': + case '}': + if (bracketsStack.isEmpty() || !isPaired(bracketsStack.pop(), bracket)) { + return false; + } + break; + default: + /* other character is invalid */ + return false; + } + } + return bracketsStack.isEmpty(); + } + + public static void main(String[] args) { + assert isBalanced("[()]{}{[()()]()}"); + assert !isBalanced("[(])"); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java b/Java/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java new file mode 100644 index 000000000000..41d1c6408ee5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java @@ -0,0 +1,60 @@ +package com.thealgorithms.stacks; + +import java.util.Stack; + +public final class DecimalToAnyUsingStack { + private 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 <tt>number</tt> or <tt>radius</tt> 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<Character> 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/Java/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java b/Java/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java new file mode 100644 index 000000000000..2fb03de77de5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java @@ -0,0 +1,46 @@ +package com.thealgorithms.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.util.Scanner; +import java.util.Stack; + +public final class DuplicateBrackets { + private DuplicateBrackets() { + } + + public static boolean check(String str) { + Stack<Character> st = new Stack<>(); + + for (int i = 0; i < str.length(); i++) { + char ch = str.charAt(i); + if (ch == ')') { + if (st.peek() == '(') { + return true; + } else { + while (st.size() > 0 && st.peek() != '(') { + st.pop(); + } + st.pop(); + } + } else { + st.push(ch); + } + // System.out.println(st); + } + return false; + } + + public static void main(String[] args) throws Exception { + Scanner sc = new Scanner(System.in); + String str = sc.nextLine(); + System.out.println(check(str)); + sc.close(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java b/Java/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java new file mode 100644 index 000000000000..e3519978c6e5 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java @@ -0,0 +1,58 @@ +package com.thealgorithms.stacks; + +import java.util.Stack; + +public final class InfixToPostfix { + private 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<Character> 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/Java/src/main/java/com/thealgorithms/stacks/LargestRectangle.java b/Java/src/main/java/com/thealgorithms/stacks/LargestRectangle.java new file mode 100644 index 000000000000..0404d9c99508 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/LargestRectangle.java @@ -0,0 +1,38 @@ +package com.thealgorithms.stacks; + +import java.util.Stack; + +/** + * + * @author mohd rameez github.com/rameez471 + */ + +public final class LargestRectangle { + private LargestRectangle() { + } + + public static String largestRectanglehistogram(int[] heights) { + int n = heights.length; + int maxArea = 0; + Stack<int[]> st = new Stack<>(); + for (int i = 0; i < n; i++) { + int start = i; + while (!st.isEmpty() && st.peek()[1] > heights[i]) { + int[] tmp = st.pop(); + maxArea = Math.max(maxArea, tmp[1] * (i - tmp[0])); + start = tmp[0]; + } + st.push(new int[] {start, heights[i]}); + } + while (!st.isEmpty()) { + int[] tmp = st.pop(); + maxArea = Math.max(maxArea, tmp[1] * (n - tmp[0])); + } + return Integer.toString(maxArea); + } + + public static void main(String[] args) { + assert largestRectanglehistogram(new int[] {2, 1, 5, 6, 2, 3}).equals("10"); + assert largestRectanglehistogram(new int[] {2, 4}).equals("4"); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java b/Java/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java new file mode 100644 index 000000000000..d76122b16632 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java @@ -0,0 +1,107 @@ +package com.thealgorithms.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. + * <p> + * For example, + * <p> + * N = 7 + * arr[] = {10,20,30,50,10,70,30} + * <p> + * So the answer for the above would be : 70 30 20 10 10 10 10 + * <p> + * 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. + * + * @author sahil + */ +public final class MaximumMinimumWindow { + private MaximumMinimumWindow() { + } + + /** + * 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 + * @return result array + */ + public static int[] calculateMaxOfMin(int[] arr, int n) { + Stack<Integer> s = new Stack<>(); + int[] left = new int[n + 1]; + int[] right = new int[n + 1]; + for (int i = 0; i < n; i++) { + left[i] = -1; + right[i] = n; + } + + for (int i = 0; i < n; i++) { + while (!s.empty() && arr[s.peek()] >= arr[i]) { + s.pop(); + } + + if (!s.empty()) { + left[i] = s.peek(); + } + + s.push(i); + } + + while (!s.empty()) { + s.pop(); + } + + for (int i = n - 1; i >= 0; i--) { + while (!s.empty() && arr[s.peek()] >= arr[i]) { + s.pop(); + } + + if (!s.empty()) { + right[i] = s.peek(); + } + + s.push(i); + } + + int[] ans = new int[n + 1]; + for (int i = 0; i <= n; i++) { + ans[i] = 0; + } + + for (int i = 0; i < n; i++) { + int len = right[i] - left[i] - 1; + + ans[len] = Math.max(ans[len], arr[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++) { + System.out.print(ans[i] + " "); + } + return ans; + } + + public static void main(String[] args) { + int[] arr = new int[] {10, 20, 30, 50, 10, 70, 30}; + int[] target = new int[] {70, 30, 20, 10, 10, 10, 10}; + int[] res = calculateMaxOfMin(arr, arr.length); + assert Arrays.equals(target, res); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java b/Java/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java new file mode 100644 index 000000000000..f7cbea714eb0 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java @@ -0,0 +1,71 @@ +package com.thealgorithms.stacks; + +import java.util.Arrays; +import java.util.Stack; + +/* + Given an array "input" you need to print the first greater element for each element. + For a given element x of an array, the Next greater element of that element is the + first greater element to the right side of it. If no such element is present print -1. + + Example + input = { 2, 7, 3, 5, 4, 6, 8 }; + At i = 0 + Next greater element between (1 to n) is 7 + At i = 1 + Next greater element between (2 to n) is 8 + At i = 2 + Next greater element between (3 to n) is 5 + At i = 3 + Next greater element between (4 to n) is 6 + At i = 4 + Next greater element between (5 to n) is 6 + At i = 5 + Next greater element between (6 to n) is 8 + At i = 6 + Next greater element between (6 to n) is -1 + + result : [7, 8, 5, 6, 6, 8, -1] + + 1. If the stack is empty Push an element in the stack. + 2. If the stack is not empty: + a. compare the top element of the stack with next. + b. If next is greater than the top element, Pop element from the stack. + next is the next greater element for the popped element. + c. Keep popping from the stack while the popped element is smaller + than next. next becomes the next greater element for all such + popped elements. + d. Finally, push the next in the stack. + + 3. If elements are left in stack after completing while loop then their Next greater element is + -1. + */ + +public final class NextGreaterElement { + private NextGreaterElement() { + } + + public static int[] findNextGreaterElements(int[] array) { + if (array == null) { + return array; + } + + int[] result = new int[array.length]; + Stack<Integer> stack = new Stack<>(); + + for (int i = 0; i < array.length; i++) { + while (!stack.isEmpty() && array[stack.peek()] < array[i]) { + result[stack.pop()] = array[i]; + } + stack.push(i); + } + + return result; + } + + public static void main(String[] args) { + int[] input = {2, 7, 3, 5, 4, 6, 8}; + int[] result = findNextGreaterElements(input); + System.out.println(Arrays.toString(result)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java b/Java/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java new file mode 100644 index 000000000000..4d37da0e7c31 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java @@ -0,0 +1,70 @@ +package com.thealgorithms.stacks; + +import java.util.Arrays; +import java.util.Stack; + +/* + Given an array "input" you need to print the first smaller element for each element to the left + side of an array. For a given element x of an array, the Next Smaller element of that element is + the first smaller element to the left side of it. If no such element is present print -1. + + Example + input = { 2, 7, 3, 5, 4, 6, 8 }; + At i = 0 + No elements to left of it : -1 + At i = 1 + Next smaller element between (0 , 0) is 2 + At i = 2 + Next smaller element between (0 , 1) is 2 + At i = 3 + Next smaller element between (0 , 2) is 3 + At i = 4 + Next smaller element between (0 , 3) is 3 + At i = 5 + Next smaller element between (0 , 4) is 4 + At i = 6 + Next smaller element between (0 , 5) is 6 + + result : [-1, 2, 2, 3, 3, 4, 6] + + 1) Create a new empty stack st + + 2) Iterate over array "input" , where "i" goes from 0 to input.length -1. + a) We are looking for value just smaller than `input[i]`. So keep popping from "stack" + till elements in "stack.peek() >= input[i]" or stack becomes empty. + b) If the stack is non-empty, then the top element is our previous element. Else the + previous element does not exist. c) push input[i] in stack. 3) If elements are left then their + answer is -1 + */ + +public final class NextSmallerElement { + private NextSmallerElement() { + } + + public static int[] findNextSmallerElements(int[] array) { + // base case + if (array == null) { + return array; + } + Stack<Integer> stack = new Stack<>(); + int[] result = new int[array.length]; + Arrays.fill(result, -1); + + for (int i = 0; i < array.length; i++) { + while (!stack.empty() && stack.peek() >= array[i]) stack.pop(); + if (stack.empty()) { + result[i] = -1; + } else { + result[i] = stack.peek(); + } + stack.push(array[i]); + } + return result; + } + + public static void main(String[] args) { + int[] input = {2, 7, 3, 5, 4, 6, 8}; + int[] result = findNextSmallerElements(input); + System.out.println(Arrays.toString(result)); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java b/Java/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java new file mode 100644 index 000000000000..c69a511c2c17 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java @@ -0,0 +1,132 @@ +package com.thealgorithms.stacks; + +import java.util.Stack; + +/** + * Postfix to Infix implementation via Stack + * + * Function: String getPostfixToInfix(String postfix) + * Returns the Infix Expression for the given postfix parameter. + * + * Avoid using parentheses/brackets/braces for the postfix string. + * Postfix Expressions don't require these. + * + * + * @author nikslyon19 (Nikhil Bisht) + * + */ + +public final class PostfixToInfix { + private PostfixToInfix() { + } + + public static boolean isOperator(char token) { + switch (token) { + case '+': + case '-': + case '/': + case '*': + case '^': + return true; + default: + return false; + } + } + + public static boolean isValidPostfixExpression(String postfix) { + /* Postfix expression length should NOT be less than 3 */ + if (postfix.length() < 3) return false; + + /* First two characters should NOT be operators */ + if (isOperator(postfix.charAt(0))) return false; + if (isOperator(postfix.charAt(1))) return false; + + int operandCount = 0; + int operatorCount = 0; + + /* Traverse the postfix string to check if --> Number of operands = Number of operators + 1 + */ + for (int i = 0; i < postfix.length(); i++) { + char token = postfix.charAt(i); + + if (isOperator(token)) { + operatorCount++; + if (operatorCount >= operandCount) return false; + } else { + if (operatorCount == 0) { + operandCount++; + continue; + } + + if (operandCount != operatorCount + 1) return false; + + /* Operand count is set to 2 because:- + * + * 1) the previous set of operands & operators combined have become a single valid + * expression, which could be considered/assigned as a single operand. + * + * 2) the operand in the current iteration. + */ + operandCount = 2; + + /* Reset operator count */ + operatorCount = 0; + } + } + + return (operandCount == operatorCount + 1); + } + + public static String getPostfixToInfix(String postfix) { + String infix = ""; + + if (postfix.isEmpty()) return infix; + + /* Validate Postfix expression before proceeding with the Infix conversion */ + if (!isValidPostfixExpression(postfix)) { + throw new IllegalArgumentException("Invalid Postfix Expression"); + } + + Stack<String> stack = new Stack<>(); + StringBuilder valueString = new StringBuilder(); + + String operandA; + String operandB; + char operator; + + for (int index = 0; index < postfix.length(); index++) { + char token = postfix.charAt(index); + + if (!isOperator(token)) { + stack.push(Character.toString(token)); + continue; + } + + operator = token; + operandB = stack.pop(); + operandA = stack.pop(); + + valueString.append('('); + + valueString.append(operandA); + valueString.append(operator); + valueString.append(operandB); + + valueString.append(')'); + + stack.push(valueString.toString()); + valueString.setLength(0); + } + + infix = stack.pop(); + return infix; + } + + public static void main(String[] args) { + assert getPostfixToInfix("ABC+/").equals("(A/(B+C))"); + assert getPostfixToInfix("AB+CD+*").equals("((A+B)*(C+D))"); + assert getPostfixToInfix("AB+C+D+").equals("(((A+B)+C)+D)"); + assert getPostfixToInfix("ABCDE^*/-").equals("(A-(B/(C*(D^E))))"); + assert getPostfixToInfix("AB+CD^/E*FGH+-^").equals("((((A+B)/(C^D))*E)^(F-(G+H)))"); + } +} diff --git a/Java/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java b/Java/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java new file mode 100644 index 000000000000..d4b7c9222e1d --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/stacks/StackPostfixNotation.java @@ -0,0 +1,65 @@ +package com.thealgorithms.stacks; + +import java.util.Scanner; +import java.util.Stack; +import java.util.function.BiFunction; + +/** + * @brief Utility class evaluating postix expressions, cf. https://en.wikipedia.org/wiki/Reverse_Polish_notation + * @details The computation is done using Integers. + */ +public final class StackPostfixNotation { + private StackPostfixNotation() { + } + + private static BiFunction<Integer, Integer, Integer> getOperator(final String operationSymbol) { + // note the order of operands + switch (operationSymbol) { + case "+": + return (a, b) -> b + a; + case "-": + return (a, b) -> b - a; + case "*": + return (a, b) -> b * a; + case "/": + return (a, b) -> b / a; + default: + throw new IllegalArgumentException("exp contains an unknown operation."); + } + } + + private static void performOperation(Stack<Integer> s, final String operationSymbol) { + if (s.size() < 2) { + throw new IllegalArgumentException("exp is not a proper postfix expression (too few arguments)."); + } + s.push(getOperator(operationSymbol).apply(s.pop(), s.pop())); + } + + private static void consumeExpression(Stack<Integer> s, final String exp) { + Scanner tokens = new Scanner(exp); + + while (tokens.hasNext()) { + if (tokens.hasNextInt()) { + s.push(tokens.nextInt()); + } else { + performOperation(s, tokens.next()); + } + } + tokens.close(); + } + + /** + * @brief Evaluates the given postfix expression. + * @param exp the expression to evaluate. + * @return the value of the given expression. + * @exception IllegalArgumentException exp is not a valid postix expression. + */ + public static int postfixEvaluate(final String exp) { + Stack<Integer> s = new Stack<Integer>(); + consumeExpression(s, exp); + if (s.size() != 1) { + throw new IllegalArgumentException("exp is not a proper postfix expression."); + } + return s.pop(); + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/AhoCorasick.java b/Java/src/main/java/com/thealgorithms/strings/AhoCorasick.java new file mode 100644 index 000000000000..9ae9b88b8a80 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/AhoCorasick.java @@ -0,0 +1,249 @@ +/* + * Aho-Corasick String Matching Algorithm Implementation + * + * This code implements the Aho-Corasick algorithm, which is used for efficient + * string matching in a given text. It can find multiple patterns simultaneously + * and records their positions in the text. + * + * Author: Prabhat-Kumar-42 + * GitHub: https://github.com/Prabhat-Kumar-42 + */ + +package com.thealgorithms.strings; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.Map; +import java.util.Queue; + +public final class AhoCorasick { + private AhoCorasick() { + } + + // Trie Node Class + private static class Node { + // Represents a character in the trie + private HashMap<Character, Node> child = new HashMap<>(); // Child nodes of the current node + private Node suffixLink; // Suffix link to another node in the trie + private Node outputLink; // Output link to another node in the trie + private int patternInd; // Index of the pattern that ends at this node + + Node() { + this.suffixLink = null; + this.outputLink = null; + this.patternInd = -1; + } + + public HashMap<Character, Node> getChild() { + return child; + } + + public Node getSuffixLink() { + return suffixLink; + } + + public void setSuffixLink(final Node suffixLink) { + this.suffixLink = suffixLink; + } + + public Node getOutputLink() { + return outputLink; + } + + public void setOutputLink(final Node outputLink) { + this.outputLink = outputLink; + } + + public int getPatternInd() { + return patternInd; + } + + public void setPatternInd(final int patternInd) { + this.patternInd = patternInd; + } + } + + // Trie Class + public static class Trie { + + private Node root = null; // Root node of the trie + private final String[] patterns; // patterns according to which Trie is constructed + + public Trie(final String[] patterns) { + root = new Node(); // Initialize the root of the trie + this.patterns = patterns; + buildTrie(); + buildSuffixAndOutputLinks(); + } + + // builds AhoCorasick Trie + private void buildTrie() { + + // Loop through each input pattern and building Trie + for (int i = 0; i < patterns.length; i++) { + Node curr = root; // Start at the root of the trie for each pattern + + // Loop through each character in the current pattern + for (int j = 0; j < patterns[i].length(); j++) { + char c = patterns[i].charAt(j); // Get the current character + + // Check if the current node has a child for the current character + if (curr.getChild().containsKey(c)) { + curr = curr.getChild().get(c); // Update the current node to the child node + } else { + // If no child node exists, create a new one and add it to the current node's children + Node nn = new Node(); + curr.getChild().put(c, nn); + curr = nn; // Update the current node to the new child node + } + } + curr.setPatternInd(i); // Store the index of the pattern in the current leaf node + } + } + + private void initializeSuffixLinksForChildNodesOfTheRoot(Queue<Node> q) { + for (char rc : root.getChild().keySet()) { + Node childNode = root.getChild().get(rc); + q.add(childNode); // Add child node to the queue + childNode.setSuffixLink(root); // Set suffix link to the root + } + } + + private void buildSuffixAndOutputLinks() { + root.setSuffixLink(root); // Initialize the suffix link of the root to itself + Queue<Node> q = new LinkedList<>(); // Initialize a queue for BFS traversal + + initializeSuffixLinksForChildNodesOfTheRoot(q); + + while (!q.isEmpty()) { + Node currentState = q.poll(); // Get the current node for processing + + // Iterate through child nodes of the current node + for (char cc : currentState.getChild().keySet()) { + Node currentChild = currentState.getChild().get(cc); // Get the child node + Node parentSuffix = currentState.getSuffixLink(); // Get the parent's suffix link + + // Calculate the suffix link for the child based on the parent's suffix link + while (!parentSuffix.getChild().containsKey(cc) && parentSuffix != root) { + parentSuffix = parentSuffix.getSuffixLink(); + } + + // Set the calculated suffix link or default to root + if (parentSuffix.getChild().containsKey(cc)) { + currentChild.setSuffixLink(parentSuffix.getChild().get(cc)); + } else { + currentChild.setSuffixLink(root); + } + + q.add(currentChild); // Add the child node to the queue for further processing + } + + // Establish output links for nodes to efficiently identify patterns within patterns + if (currentState.getSuffixLink().getPatternInd() >= 0) { + currentState.setOutputLink(currentState.getSuffixLink()); + } else { + currentState.setOutputLink(currentState.getSuffixLink().getOutputLink()); + } + } + } + + private ArrayList<ArrayList<Integer>> initializePositionByStringIndexValue() { + ArrayList<ArrayList<Integer>> positionByStringIndexValue = new ArrayList<>(patterns.length); // Stores positions where patterns are found in the text + for (int i = 0; i < patterns.length; i++) { + positionByStringIndexValue.add(new ArrayList<Integer>()); + } + return positionByStringIndexValue; + } + + // Searches for patterns in the input text and records their positions + public ArrayList<ArrayList<Integer>> searchIn(final String text) { + var positionByStringIndexValue = initializePositionByStringIndexValue(); // Initialize a list to store positions of the current pattern + Node parent = root; // Start searching from the root node + + PatternPositionRecorder positionRecorder = new PatternPositionRecorder(positionByStringIndexValue); + + for (int i = 0; i < text.length(); i++) { + char ch = text.charAt(i); // Get the current character in the text + + // Check if the current node has a child for the current character + if (parent.getChild().containsKey(ch)) { + parent = parent.getChild().get(ch); // Update the current node to the child node + positionRecorder.recordPatternPositions(parent, i); // Use the method in PatternPositionRecorder to record positions + } else { + // If no child node exists for the character, backtrack using suffix links + while (parent != root && !parent.getChild().containsKey(ch)) { + parent = parent.getSuffixLink(); + } + if (parent.getChild().containsKey(ch)) { + i--; // Decrement i to reprocess the same character + } + } + } + + setUpStartPoints(positionByStringIndexValue); + return positionByStringIndexValue; + } + + // by default positionByStringIndexValue contains end-points. This function converts those + // endpoints to start points + private void setUpStartPoints(ArrayList<ArrayList<Integer>> positionByStringIndexValue) { + for (int i = 0; i < patterns.length; i++) { + for (int j = 0; j < positionByStringIndexValue.get(i).size(); j++) { + int endpoint = positionByStringIndexValue.get(i).get(j); + positionByStringIndexValue.get(i).set(j, endpoint - patterns[i].length() + 1); + } + } + } + } + + // Class to handle pattern position recording + private static class PatternPositionRecorder { + private ArrayList<ArrayList<Integer>> positionByStringIndexValue; + + // Constructor to initialize the recorder with the position list + PatternPositionRecorder(final ArrayList<ArrayList<Integer>> positionByStringIndexValue) { + this.positionByStringIndexValue = positionByStringIndexValue; + } + + /** + * Records positions for a pattern when it's found in the input text and follows + * output links to record positions of other patterns. + * + * @param parent The current node representing a character in the pattern trie. + * @param currentPosition The current position in the input text. + */ + public void recordPatternPositions(final Node parent, final int currentPosition) { + // Check if the current node represents the end of a pattern + if (parent.getPatternInd() > -1) { + // Add the current position to the list of positions for the found pattern + positionByStringIndexValue.get(parent.getPatternInd()).add(currentPosition); + } + + Node outputLink = parent.getOutputLink(); + // Follow output links to find and record positions of other patterns + while (outputLink != null) { + // Add the current position to the list of positions for the pattern linked by outputLink + positionByStringIndexValue.get(outputLink.getPatternInd()).add(currentPosition); + outputLink = outputLink.getOutputLink(); + } + } + } + // method to search for patterns in text + public static Map<String, ArrayList<Integer>> search(final String text, final String[] patterns) { + final var trie = new Trie(patterns); + final var positionByStringIndexValue = trie.searchIn(text); + return convert(positionByStringIndexValue, patterns); + } + + // method for converting results to a map + private static Map<String, ArrayList<Integer>> convert(final ArrayList<ArrayList<Integer>> positionByStringIndexValue, final String[] patterns) { + Map<String, ArrayList<Integer>> positionByString = new HashMap<>(); + for (int i = 0; i < patterns.length; i++) { + String pattern = patterns[i]; + ArrayList<Integer> positions = positionByStringIndexValue.get(i); + positionByString.put(pattern, new ArrayList<>(positions)); + } + return positionByString; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/Alphabetical.java b/Java/src/main/java/com/thealgorithms/strings/Alphabetical.java new file mode 100644 index 000000000000..de07dde2d510 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Alphabetical.java @@ -0,0 +1,36 @@ +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 + */ +final class Alphabetical { + private 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/Java/src/main/java/com/thealgorithms/strings/Anagrams.java b/Java/src/main/java/com/thealgorithms/strings/Anagrams.java new file mode 100644 index 000000000000..352d2308c5ea --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Anagrams.java @@ -0,0 +1,151 @@ +package com.thealgorithms.strings; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, + * typically using all the original letters exactly once.[1] + * For example, the word anagram itself can be rearranged into nag a ram, + * also the word binary into brainy and the word adobe into abode. + * Reference from https://en.wikipedia.org/wiki/Anagram + */ +public class Anagrams { + + // 4 approaches are provided for anagram checking. approach 2 and approach 3 are similar but + // differ in running time. + public static void main(String[] args) { + String first = "deal"; + String second = "lead"; + // All the below methods takes input but doesn't return any output to the main method. + Anagrams nm = new Anagrams(); + System.out.println(nm.approach2(first, second)); /* To activate methods for different approaches*/ + System.out.println(nm.approach1(first, second)); /* To activate methods for different approaches*/ + System.out.println(nm.approach3(first, second)); /* To activate methods for different approaches*/ + System.out.println(nm.approach4(first, second)); /* To activate methods for different approaches*/ + /** + * OUTPUT : + * first string ="deal" second string ="lead" + * Output: Anagram + * Input and output is constant for all four approaches + * 1st approach Time Complexity : O(n logn) + * Auxiliary Space Complexity : O(1) + * 2nd approach Time Complexity : O(n) + * Auxiliary Space Complexity : O(1) + * 3rd approach Time Complexity : O(n) + * Auxiliary Space Complexity : O(1) + * 4th approach Time Complexity : O(n) + * Auxiliary Space Complexity : O(n) + * 5th approach Time Complexity: O(n) + * Auxiliary Space Complexity: O(1) + */ + } + + boolean approach1(String s, String t) { + if (s.length() != t.length()) { + return false; + } else { + char[] c = s.toCharArray(); + char[] d = t.toCharArray(); + Arrays.sort(c); + Arrays.sort(d); /* In this approach the strings are stored in the character arrays and + both the arrays are sorted. After that both the arrays are compared + for checking anangram */ + + return Arrays.equals(c, d); + } + } + + boolean approach2(String a, String b) { + if (a.length() != b.length()) { + return false; + } else { + int[] m = new int[26]; + int[] n = new int[26]; + for (char c : a.toCharArray()) { + m[c - 'a']++; + } + // In this approach the frequency of both the strings are stored and after that the + // frequencies are iterated from 0 to 26(from 'a' to 'z' ). If the frequencies match + // then anagram message is displayed in the form of boolean format Running time and + // space complexity of this algo is less as compared to others + for (char c : b.toCharArray()) { + n[c - 'a']++; + } + for (int i = 0; i < 26; i++) { + if (m[i] != n[i]) { + return false; + } + } + return true; + } + } + + boolean approach3(String s, String t) { + if (s.length() != t.length()) { + return false; + } + // this is similar to approach number 2 but here the string is not converted to character + // array + else { + int[] a = new int[26]; + int[] b = new int[26]; + int k = s.length(); + for (int i = 0; i < k; i++) { + a[s.charAt(i) - 'a']++; + b[t.charAt(i) - 'a']++; + } + for (int i = 0; i < 26; i++) { + if (a[i] != b[i]) return false; + } + return true; + } + } + + boolean approach4(String s, String t) { + if (s.length() != t.length()) { + return false; + } + // This approach is done using hashmap where frequencies are stored and checked iteratively + // and if all the frequencies of first string match with the second string then anagram + // message is displayed in boolean format + else { + HashMap<Character, Integer> nm = new HashMap<>(); + HashMap<Character, Integer> kk = new HashMap<>(); + for (char c : s.toCharArray()) { + nm.put(c, nm.getOrDefault(c, 0) + 1); + } + for (char c : t.toCharArray()) { + kk.put(c, kk.getOrDefault(c, 0) + 1); + } + // It checks for equal frequencies by comparing key-value pairs of two hashmaps + return nm.equals(kk); + } + } + + boolean approach5(String s, String t) { + if (s.length() != t.length()) { + return false; + } + // Approach is different from above 4 aproaches. + // Here we initialize an array of size 26 where each element corresponds to the frequency of + // a character. + int[] freq = new int[26]; + // iterate through both strings, incrementing the frequency of each character in the first + // string and decrementing the frequency of each character in the second string. + for (int i = 0; i < s.length(); i++) { + int pos1 = s.charAt(i) - 'a'; + int pos2 = s.charAt(i) - 'a'; + freq[pos1]++; + freq[pos2]--; + } + // iterate through the frequency array and check if all the elements are zero, if so return + // true else false + for (int i = 0; i < 26; i++) { + if (freq[i] != 0) { + return false; + } + } + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/CharactersSame.java b/Java/src/main/java/com/thealgorithms/strings/CharactersSame.java new file mode 100644 index 000000000000..78ccbbea4898 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/CharactersSame.java @@ -0,0 +1,32 @@ +package com.thealgorithms.strings; + +public final class CharactersSame { + private 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/Java/src/main/java/com/thealgorithms/strings/CheckAnagrams.java b/Java/src/main/java/com/thealgorithms/strings/CheckAnagrams.java new file mode 100644 index 000000000000..7bf7cd9a7c66 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/CheckAnagrams.java @@ -0,0 +1,110 @@ +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 final class CheckAnagrams { + private CheckAnagrams() { + } + /** + * 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<Character, Integer> 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; + } + + /** + * If given strings contain Unicode symbols. + * The first 128 ASCII codes are identical to Unicode. + * This algorithm is case-sensitive. + * + * @param s1 the first string + * @param s2 the second string + * @return true if two string are anagrams, otherwise false + */ + public static boolean isAnagramsUnicode(String s1, String s2) { + int[] dict = new int[128]; + for (char ch : s1.toCharArray()) { + dict[ch]++; + } + for (char ch : s2.toCharArray()) { + dict[ch]--; + } + for (int e : dict) { + if (e != 0) { + return false; + } + } + return true; + } + + /** + * If given strings contain only lowercase English letters. + * <p> + * The main "trick": + * To map each character from the first string 's1' we need to subtract an integer value of 'a' character + * as 'dict' array starts with 'a' character. + * + * @param s1 the first string + * @param s2 the second string + * @return true if two string are anagrams, otherwise false + */ + public static boolean isAnagramsOptimised(String s1, String s2) { + // 26 - English alphabet length + int[] dict = new int[26]; + for (char ch : s1.toCharArray()) { + checkLetter(ch); + dict[ch - 'a']++; + } + for (char ch : s2.toCharArray()) { + checkLetter(ch); + dict[ch - 'a']--; + } + for (int e : dict) { + if (e != 0) { + return false; + } + } + return true; + } + + private static void checkLetter(char ch) { + int index = ch - 'a'; + if (index < 0 || index >= 26) { + throw new IllegalArgumentException("Strings must contain only lowercase English letters!"); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/CheckVowels.java b/Java/src/main/java/com/thealgorithms/strings/CheckVowels.java new file mode 100644 index 000000000000..44965cc9282c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/CheckVowels.java @@ -0,0 +1,36 @@ +package com.thealgorithms.strings; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * 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 + */ +public final class CheckVowels { + private CheckVowels() { + } + + private static final Set<Character> VOWELS = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u')); + + /** + * 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 == null) { + return false; + } + input = input.toLowerCase(); + for (int i = 0; i < input.length(); i++) { + if (VOWELS.contains(input.charAt(i))) { + return true; + } + } + return false; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/HammingDistance.java b/Java/src/main/java/com/thealgorithms/strings/HammingDistance.java new file mode 100644 index 000000000000..95c523ccd411 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/HammingDistance.java @@ -0,0 +1,34 @@ +package com.thealgorithms.strings; + +/* In information theory, the Hamming distance between two strings of equal length +is the number of positions at which the corresponding symbols are different. +https://en.wikipedia.org/wiki/Hamming_distance +*/ +public final class HammingDistance { + private HammingDistance() { + } + + /** + * calculate the hamming distance between two strings of equal length + * + * @param s1 the first string + * @param s2 the second string + * @return {@code int} hamming distance + * @throws Exception + */ + public static int calculateHammingDistance(String s1, String s2) throws Exception { + if (s1.length() != s2.length()) { + throw new Exception("String lengths must be equal"); + } + + int stringLength = s1.length(); + int counter = 0; + + for (int i = 0; i < stringLength; i++) { + if (s1.charAt(i) != s2.charAt(i)) { + counter++; + } + } + return counter; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/HorspoolSearch.java b/Java/src/main/java/com/thealgorithms/strings/HorspoolSearch.java new file mode 100644 index 000000000000..d9187cbf66c4 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/HorspoolSearch.java @@ -0,0 +1,185 @@ +package com.thealgorithms.strings; + +import java.util.HashMap; + +/** + * This class is not thread safe<br> + * <br> + * (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. + * <br> + * <a href=https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore%E2%80%93Horspool_algorithm>Wikipedia + * page</a><br> + * <br> + * + * <p> + * An explanation:<br> + * + * <p> + * 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.<br> + * <br> + * + * <p> + * 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.<br> + * <br> + * + * <p> + * 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 final class HorspoolSearch { + private HorspoolSearch() { + } + + private static HashMap<Character, Integer> 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 + + if (pattern.length() == 0) { // return failure, if pattern empty + return -1; + } + + 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<Character, Integer> calcShiftValues(String pattern) { + patternLength = pattern.length(); + HashMap<Character, Integer> 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/Java/src/main/java/com/thealgorithms/strings/Isomorphic.java b/Java/src/main/java/com/thealgorithms/strings/Isomorphic.java new file mode 100644 index 000000000000..088addc6ea45 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Isomorphic.java @@ -0,0 +1,39 @@ +package com.thealgorithms.strings; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public final class Isomorphic { + private Isomorphic() { + } + + public static boolean checkStrings(String s, String t) { + if (s.length() != t.length()) { + return false; + } + + // To mark the characters of string using MAP + // character of first string as KEY and another as VALUE + // now check occurence by keeping the track with SET data structure + Map<Character, Character> characterMap = new HashMap<Character, Character>(); + Set<Character> trackUinqueCharacter = new HashSet<Character>(); + + for (int i = 0; i < s.length(); i++) { + if (characterMap.containsKey(s.charAt(i))) { + if (t.charAt(i) != characterMap.get(s.charAt(i))) { + return false; + } + } else { + if (trackUinqueCharacter.contains(t.charAt(i))) { + return false; + } + + characterMap.put(s.charAt(i), t.charAt(i)); + } + trackUinqueCharacter.add(t.charAt(i)); + } + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java b/Java/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java new file mode 100644 index 000000000000..2e3ee25fb6ea --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java @@ -0,0 +1,53 @@ +package com.thealgorithms.strings; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class LetterCombinationsOfPhoneNumber { + private LetterCombinationsOfPhoneNumber() { + } + + static Character[][] numberToCharMap; + + protected static List<String> printWords(int[] numbers, int len, int numIndex, String s) { + if (len == numIndex) { + return new ArrayList<>(Collections.singleton(s)); + } + + List<String> 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<String> stringList = printWords(numbers, numbers.length, 0, ""); + stringList.stream().forEach(System.out::println); + } + + protected 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/Java/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java b/Java/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java new file mode 100644 index 000000000000..fa9171133a15 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java @@ -0,0 +1,50 @@ +package com.thealgorithms.strings; + +// Longest Palindromic Substring +import java.util.Scanner; + +final class LongestPalindromicSubstring { + private 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)); + sc.close(); + } +} + +class Solution { + + public String longestPalindrome(String s) { + if (s == null || s.length() == 0) { + return ""; + } + int n = s.length(); + String maxStr = ""; + for (int i = 0; i < n; ++i) { + for (int j = i; j < n; ++j) { + if (isValid(s, i, j)) { + if (j - i + 1 > maxStr.length()) { // update maxStr + maxStr = s.substring(i, j + 1); + } + } + } + } + return maxStr; + } + + private boolean isValid(String s, int lo, int hi) { + int n = hi - lo + 1; + for (int i = 0; i < n / 2; ++i) { + if (s.charAt(lo + i) != s.charAt(hi - i)) { + return false; + } + } + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/Lower.java b/Java/src/main/java/com/thealgorithms/strings/Lower.java new file mode 100644 index 000000000000..e20cc5f0f2f7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Lower.java @@ -0,0 +1,32 @@ +package com.thealgorithms.strings; + +public final class Lower { + private 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/Java/src/main/java/com/thealgorithms/strings/MyAtoi.java b/Java/src/main/java/com/thealgorithms/strings/MyAtoi.java new file mode 100644 index 000000000000..0aed13f936a7 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/MyAtoi.java @@ -0,0 +1,74 @@ +// Implement the myAtoi(string s) function, which converts a string to a 32-bit signed integer +// (similar to C/C++'s atoi function). Here is my implementation + +package com.thealgorithms.strings; + +public final class MyAtoi { + private MyAtoi() { + } + public static int myAtoi(String s) { + s = s.trim(); + char[] char1 = s.toCharArray(); + String number = ""; + boolean negative = false; + boolean zero = false; + boolean isDigit = false; + + for (char ch : char1) { + if (Character.isDigit(ch)) { + if (number.length() > 1 && !isDigit) { + number = "0"; + break; + } + isDigit = true; + if (zero) { + number = "0"; + break; + } + if (ch >= '0' && ch <= '9') number += ch; + } else if (ch == '-' && !isDigit) { + number += "0"; + negative = true; + } else if (ch == '+' && !isDigit) { + number += "0"; + } else if (ch == '.' && isDigit) { + break; + } else if (ch == '.') { + zero = true; + } else { + if (!isDigit) { + number = "0"; + } + break; + } + } + + if (!isDigit) { + return 0; + } + + number = number.replaceFirst("^0+(?!$)", ""); + + if (number.length() > 10 && negative) { + return -2147483648; + } else if (number.length() > 10) { + return 2147483647; + } else if (number.length() == 10 && negative) { + double db1 = Double.parseDouble(number); + if (db1 >= 2147483648d) { + return -2147483648; + } + } else if (number.length() == 10) { + double db1 = Double.parseDouble(number); + if (db1 > (2147483647)) { + return 2147483647; + } + } + + if (negative) { + return Integer.parseInt(number) * -1; + } + + return Integer.parseInt(number); + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/Palindrome.java b/Java/src/main/java/com/thealgorithms/strings/Palindrome.java new file mode 100644 index 000000000000..3567a371d70e --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Palindrome.java @@ -0,0 +1,58 @@ +package com.thealgorithms.strings; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Palindrome + */ +final class Palindrome { + private Palindrome() { + } + + /** + * Check if a string is palindrome string or not using String Builder + * + * @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 isPalindromeRecursion(s.substring(1, s.length() - 1)); + } + + /** + * Check if a string is palindrome string or not using two pointer technique + * + * @param s a string to check + * @return {@code true} if given string is palindrome, otherwise + * {@code false} + */ + public static boolean isPalindromeTwoPointer(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/Java/src/main/java/com/thealgorithms/strings/Pangram.java b/Java/src/main/java/com/thealgorithms/strings/Pangram.java new file mode 100644 index 000000000000..e0989ce86715 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Pangram.java @@ -0,0 +1,77 @@ +package com.thealgorithms.strings; + +import java.util.HashSet; + +/** + * Wikipedia: https://en.wikipedia.org/wiki/Pangram + */ +public final class Pangram { + private Pangram() { + } + + /** + * Test 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"); // L is missing + assert !isPangram("+-1234 This string is not alphabetical"); + assert !isPangram("\u0000/\\"); + } + + /** + * Checks if a String is considered a Pangram + * + * @param s The String to check + * @return {@code true} if s is a Pangram, otherwise {@code false} + */ + // alternative approach using Java Collection Framework + public static boolean isPangramUsingSet(String s) { + HashSet<Character> alpha = new HashSet<>(); + s = s.trim().toLowerCase(); + for (int i = 0; i < s.length(); i++) + if (s.charAt(i) != ' ') alpha.add(s.charAt(i)); + return alpha.size() == 26; + } + + /** + * Checks if a String is considered a Pangram + * + * @param s The String to check + * @return {@code true} if s is a Pangram, otherwise {@code false} + */ + public static boolean isPangram(String s) { + boolean[] lettersExisting = new boolean[26]; + for (char c : s.toCharArray()) { + int letterIndex = c - (Character.isUpperCase(c) ? 'A' : 'a'); + if (letterIndex >= 0 && letterIndex < lettersExisting.length) { + lettersExisting[letterIndex] = true; + } + } + for (boolean letterFlag : lettersExisting) { + if (!letterFlag) { + return false; + } + } + return true; + } + + /** + * Checks if a String is Pangram or not by checking if each alhpabet is present or not + * + * @param s The String to check + * @return {@code true} if s is a Pangram, otherwise {@code false} + */ + public static boolean isPangram2(String s) { + if (s.length() < 26) { + return false; + } + s = s.toLowerCase(); // Converting s to Lower-Case + for (char i = 'a'; i <= 'z'; i++) { + if (s.indexOf(i) == -1) { + return false; // if any alphabet is not present, return false + } + } + return true; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/PermuteString.java b/Java/src/main/java/com/thealgorithms/strings/PermuteString.java new file mode 100644 index 000000000000..f263292eb7bd --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/PermuteString.java @@ -0,0 +1,51 @@ +package com.thealgorithms.strings; + +/* +Backtracking algorithm used in the program:- + +>>Fix a character in the first position and swap the rest of the character with the first character. + Like in ABC, in the first iteration three strings are formed: ABC, BAC, and CBA by swapping A with + A, B and C respectively. +>>Repeat step 1 for the rest of the characters like fixing second character B and so on. +>>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 final class PermuteString { + private 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); + } + + // Function for generating different permutations of the string + 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++) { + // Swapping the string by fixing a character + str = swapString(str, start, i); + // Recursively calling function generatePermutation() for rest of the characters + generatePermutation(str, start + 1, end); + // Backtracking and swapping the characters again. + str = swapString(str, start, i); + } + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/ReverseString.java b/Java/src/main/java/com/thealgorithms/strings/ReverseString.java new file mode 100644 index 000000000000..b47a77e9226c --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/ReverseString.java @@ -0,0 +1,44 @@ +package com.thealgorithms.strings; + +/** + * Reverse String using different version + */ +public final class ReverseString { + private 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/Java/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java b/Java/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java new file mode 100644 index 000000000000..e180f6c3991b --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java @@ -0,0 +1,21 @@ +package com.thealgorithms.strings; + +/** + * Reverse String using Recursion + */ + +public final class ReverseStringRecursive { + private ReverseStringRecursive() { + } + /** + * @param str string to be reversed + * @return reversed string + */ + public static String reverse(String str) { + if (str.isEmpty()) { + return str; + } else { + return reverse(str.substring(1)) + str.charAt(0); + } + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java b/Java/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java new file mode 100644 index 000000000000..5f9d27b4e9e2 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/ReverseWordsInString.java @@ -0,0 +1,22 @@ +package com.thealgorithms.strings; + +import java.util.Arrays; +import java.util.Collections; + +public final class ReverseWordsInString { + + private ReverseWordsInString() { + } + + /** + * @brief Reverses words in the input string + * @param s the input string + * @return A string created by reversing the order of the words in {@code s} + */ + + public static String reverseWordsInString(final String s) { + var words = s.trim().split("\\s+"); + Collections.reverse(Arrays.asList(words)); + return String.join(" ", words); + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/Rotation.java b/Java/src/main/java/com/thealgorithms/strings/Rotation.java new file mode 100644 index 000000000000..e1352f1197b1 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Rotation.java @@ -0,0 +1,62 @@ +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 final class Rotation { + private 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/Java/src/main/java/com/thealgorithms/strings/StringCompression.java b/Java/src/main/java/com/thealgorithms/strings/StringCompression.java new file mode 100644 index 000000000000..131bd4165493 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/StringCompression.java @@ -0,0 +1,63 @@ +package com.thealgorithms.strings; +/* References : https://en.wikipedia.org/wiki/Run-length_encoding + * String compression algorithm deals with encoding the string, that is, shortening the size of the + * string + * @author Swarga-codes (https://github.com/Swarga-codes) + */ +public final class StringCompression { + private StringCompression() { + } + /** + * Returns the compressed or encoded string + * + * @param ch character array that contains the group of characters to be encoded + * @return the compressed character array as string + */ + public static String compress(String input) { + // Keeping the count as 1 since every element present will have atleast a count + // of 1 + int count = 1; + String compressedString = ""; + // Base condition to check whether the array is of size 1, if it is then we + // return the array + if (input.length() == 1) { + return "" + input.charAt(0); + } + // If the array has a length greater than 1 we move into this loop + for (int i = 0; i < input.length() - 1; i++) { + // here we check for similarity of the adjacent elements and change the count + // accordingly + if (input.charAt(i) == input.charAt(i + 1)) { + count = count + 1; + } + if ((i + 1) == input.length() - 1 && input.charAt(i + 1) == input.charAt(i)) { + compressedString = appendCount(compressedString, count, input.charAt(i)); + break; + } else if (input.charAt(i) != input.charAt(i + 1)) { + if ((i + 1) == input.length() - 1) { + compressedString = appendCount(compressedString, count, input.charAt(i)) + input.charAt(i + 1); + break; + } else { + compressedString = appendCount(compressedString, count, input.charAt(i)); + count = 1; + } + } + } + return compressedString; + } + /** + * @param res the resulting string + * @param count current count + * @param ch the character at a particular index + * @return the res string appended with the count + */ + public static String appendCount(String res, int count, char ch) { + if (count > 1) { + res += ch + "" + count; + count = 1; + } else { + res += ch + ""; + } + return res; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/Upper.java b/Java/src/main/java/com/thealgorithms/strings/Upper.java new file mode 100644 index 000000000000..0fc87a9da318 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/Upper.java @@ -0,0 +1,35 @@ +package com.thealgorithms.strings; + +public final class Upper { + private 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) { + if (s == null || "".equals(s)) { + return 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/Java/src/main/java/com/thealgorithms/strings/ValidParentheses.java b/Java/src/main/java/com/thealgorithms/strings/ValidParentheses.java new file mode 100644 index 000000000000..947a39da4bde --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/ValidParentheses.java @@ -0,0 +1,35 @@ +package com.thealgorithms.strings; +// Given a string s containing just the characters '(', ')', '{', '}', '[' and ']', determine +// if the input string is valid. An input string is valid if: Open brackets must be closed by +// the same type of brackets. Open brackets must be closed in the correct order. Every close +// bracket has a corresponding open bracket of the same type. + +public final class ValidParentheses { + private ValidParentheses() { + } + public static boolean isValid(String s) { + char[] stack = new char[s.length()]; + int head = 0; + for (char c : s.toCharArray()) { + switch (c) { + case '{': + case '[': + case '(': + stack[head++] = c; + break; + case '}': + if (head == 0 || stack[--head] != '{') return false; + break; + case ')': + if (head == 0 || stack[--head] != '(') return false; + break; + case ']': + if (head == 0 || stack[--head] != '[') return false; + break; + default: + throw new IllegalArgumentException("Unexpected character: " + c); + } + } + return head == 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/WordLadder.java b/Java/src/main/java/com/thealgorithms/strings/WordLadder.java new file mode 100644 index 000000000000..16d4e0a02452 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/WordLadder.java @@ -0,0 +1,94 @@ +package com.thealgorithms.strings; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +/* + **Problem Statement:** + A transformation sequence from word beginWord to word endWord using a dictionary wordList is a + sequence of words beginWord -> s1 -> s2 -> ... -> sk such that: + + Every adjacent pair of words differs by a single letter. + Every si for 1 <= i <= k is in wordList. Note that beginWord does not need to be in wordList. + sk == endWord + Given two words, beginWord and endWord, and a dictionary wordList, return the number of words in + the shortest transformation sequence from beginWord to endWord, or 0 if no such sequence exists. + + **Example 1:** + Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] + Output: 5 + Explanation: One shortest transformation sequence is "hit" -> "hot" -> "dot" -> "dog" -> cog", + which is 5 words long. + + **Example 2:** + Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"] + Output: 0 + Explanation: The endWord "cog" is not in wordList, therefore there is no valid transformation + sequence. + + **Constraints:** + 1 <= beginWord.length <= 10 + endWord.length == beginWord.length + 1 <= wordList.length <= 5000 + wordList[i].length == beginWord.length + beginWord, endWord, and wordList[i] consist of lowercase English letters. + beginWord != endWord + All the words in wordList are unique. + */ + +final class WordLadder { + private WordLadder() { + } + + /** + * This function finds the ladderLength + * + * @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. + */ + public static int ladderLength(String beginWord, String endWord, List<String> wordList) { + HashSet<String> set = new HashSet<>(wordList); + + if (!set.contains(endWord)) { + return 0; + } + + Queue<String> queue = new LinkedList<>(); + queue.offer(beginWord); + int level = 1; + + while (!queue.isEmpty()) { + int size = queue.size(); + for (int i = 0; i < size; i++) { + String curr = queue.poll(); + char[] wordsChars = curr.toCharArray(); + for (int j = 0; j < wordsChars.length; j++) { + char originalChars = wordsChars[j]; + for (char c = 'a'; c <= 'z'; c++) { + if (wordsChars[j] == c) { + continue; + } + wordsChars[j] = c; + String newWord = String.valueOf(wordsChars); + if (newWord.equals(endWord)) { + return level + 1; + } + if (set.contains(newWord)) { + set.remove(newWord); + queue.offer(newWord); + } + } + wordsChars[j] = originalChars; + } + } + level++; + } + return 0; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java b/Java/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java new file mode 100644 index 000000000000..99154542955f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java @@ -0,0 +1,45 @@ +package com.thealgorithms.strings; + +import java.util.HashMap; + +final class longestNonRepeativeSubstring { + private longestNonRepeativeSubstring() { + } + + public static int lengthOfLongestSubstring(String s) { + int max = 0; + int start = 0; + int i = 0; + HashMap<Character, Integer> map = new HashMap<>(); + + while (i < s.length()) { + char temp = s.charAt(i); + + // adding key to map if not present + if (!map.containsKey(temp)) map.put(temp, 0); + // checking if the first value is the dublicate value + else if (s.charAt(start) == temp) + start++; + // checking if the previous value is dublicate value + else if (s.charAt(i - 1) == temp) { + if (max < map.size()) max = map.size(); + map = new HashMap<>(); + start = i; + i--; + } + // last possible place where dublicate value can be is between start and i + else { + if (max < map.size()) max = map.size(); + while (s.charAt(start) != temp) { + map.remove(s.charAt(start)); + start++; + } + start++; + } + + i++; + } + if (max < map.size()) max = map.size(); + return max; + } +} diff --git a/Java/src/main/java/com/thealgorithms/strings/zigZagPattern/README.md b/Java/src/main/java/com/thealgorithms/strings/zigZagPattern/README.md new file mode 100644 index 000000000000..17e5ba6e26d8 --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/zigZagPattern/README.md @@ -0,0 +1,36 @@ +# About + +convert string into a zig-zagged string + +for example : + + string = "123456789" , numRows = 3 + ans = "159246837" + explanation + 1 5 9 + 2 4 6 8 + 3 7 + + string = "HelloWorldKotlin" , k = 4 + ans = "HoteWrollolKildn" + explanation + H o t + e W r o l + l o l K i + l d n + +# working + + if string size is smaller than numRows or numRows is smaller than 2 + than we can return string because it will make no changes to string. + If not than + we initiate three variable depth which is equalvalent to numRows , + height which starts with 1 and start with starting index of string. + than we generate spaces to skip using formula 2 + (( n - 1 ) * 2 ) + for both height and depth + with each iteration we decrement depth and increate height and start + by one also we keep contantating character on to new string with first + depth spaces and later height spaces that we generated using formula + if not zero + +# beats 80% of submission on leetcode \ No newline at end of file diff --git a/Java/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java b/Java/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java new file mode 100644 index 000000000000..2dfcf3909b8f --- /dev/null +++ b/Java/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java @@ -0,0 +1,39 @@ +package com.thealgorithms.strings.zigZagPattern; + +final class zigZagPattern { + private zigZagPattern() { + } + + public static String encode(String s, int numRows) { + if (numRows < 2 || s.length() < numRows) return s; + int start = 0; + int index = 0; + int height = 1; + int depth = numRows; + char[] zigZagedArray = new char[s.length()]; + while (depth != 0) { + int pointer = start; + int heightSpace = 2 + ((height - 2) * 2); + int depthSpace = 2 + ((depth - 2) * 2); + boolean bool = true; + while (pointer < s.length()) { + zigZagedArray[index++] = s.charAt(pointer); + if (heightSpace == 0) + pointer += depthSpace; + else if (depthSpace == 0) + pointer += heightSpace; + else if (bool) { + pointer += depthSpace; + bool = false; + } else { + pointer += heightSpace; + bool = true; + } + } + height++; + depth--; + start++; + } + return new String(zigZagedArray); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java b/Java/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java new file mode 100644 index 000000000000..177163b09ca1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java @@ -0,0 +1,57 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class AllPathsFromSourceToTargetTest { + + @Test + void testForFirstCase() { + int vertices = 4; + int[][] a = {{0, 1}, {0, 2}, {0, 3}, {2, 0}, {2, 1}, {1, 3}}; + int source = 2; + int destination = 3; + List<List<Integer>> list2 = List.of(List.of(2, 0, 1, 3), List.of(2, 0, 3), List.of(2, 1, 3)); + List<List<Integer>> list1 = AllPathsFromSourceToTarget.allPathsFromSourceToTarget(vertices, a, source, destination); + list2 = list1; + assertIterableEquals(list1, list2); + } + + @Test + void testForSecondCase() { + int vertices = 5; + int[][] a = {{0, 1}, {0, 2}, {0, 3}, {2, 0}, {2, 1}, {1, 3}, {1, 4}, {3, 4}, {2, 4}}; + int source = 0; + int destination = 4; + List<List<Integer>> list2 = List.of(List.of(0, 1, 3, 4), List.of(0, 1, 4), List.of(0, 2, 1, 3, 4), List.of(0, 2, 1, 4), List.of(0, 2, 4), List.of(0, 3, 4)); + List<List<Integer>> list1 = AllPathsFromSourceToTarget.allPathsFromSourceToTarget(vertices, a, source, destination); + list2 = list1; + assertIterableEquals(list1, list2); + } + + @Test + void testForThirdCase() { + int vertices = 6; + int[][] a = {{1, 0}, {2, 3}, {0, 4}, {1, 5}, {4, 3}, {0, 2}, {0, 3}, {1, 2}, {0, 5}, {3, 4}, {2, 5}, {2, 4}}; + int source = 1; + int destination = 5; + List<List<Integer>> list2 = List.of(List.of(1, 0, 2, 5), List.of(1, 0, 5), List.of(1, 5), List.of(1, 2, 5)); + List<List<Integer>> list1 = AllPathsFromSourceToTarget.allPathsFromSourceToTarget(vertices, a, source, destination); + list2 = list1; + assertIterableEquals(list1, list2); + } + + @Test + void testForFourthcase() { + int vertices = 3; + int[][] a = {{0, 1}, {0, 2}, {1, 2}}; + int source = 0; + int destination = 2; + List<List<Integer>> list2 = List.of(List.of(0, 1, 2), List.of(0, 2)); + List<List<Integer>> list1 = AllPathsFromSourceToTarget.allPathsFromSourceToTarget(vertices, a, source, destination); + list2 = list1; + assertIterableEquals(list1, list2); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java b/Java/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java new file mode 100644 index 000000000000..23fa5d54574c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.util.List; +import java.util.TreeSet; +import org.junit.jupiter.api.Test; + +public class ArrayCombinationTest { + + @Test + void testNBeingZeroOrLess() { + List<TreeSet<Integer>> zeroResult = ArrayCombination.combination(0, 1); + List<TreeSet<Integer>> negativeResult = ArrayCombination.combination(-1, 1); + assertNull(zeroResult); + assertNull(negativeResult); + } + + @Test + void testNoLengthElement() { + List<TreeSet<Integer>> result = ArrayCombination.combination(2, 0); + assertNull(result); + } + + @Test + void testLengthOne() { + List<TreeSet<Integer>> result = ArrayCombination.combination(2, 1); + assert result != null; + assertEquals(1, result.get(0).iterator().next()); + assertEquals(2, result.get(1).iterator().next()); + } + + @Test + void testLengthTwo() { + List<TreeSet<Integer>> result = ArrayCombination.combination(2, 2); + assert result != null; + Integer[] arr = result.get(0).toArray(new Integer[2]); + assertEquals(1, arr[0]); + assertEquals(2, arr[1]); + } + + @Test + void testLengthFive() { + List<TreeSet<Integer>> result = ArrayCombination.combination(10, 5); + assert result != null; + Integer[] arr = result.get(0).toArray(new Integer[5]); + assertEquals(1, arr[0]); + assertEquals(5, arr[4]); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/CombinationTest.java b/Java/src/test/java/com/thealgorithms/backtracking/CombinationTest.java new file mode 100644 index 000000000000..44edc3077fd5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/CombinationTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import java.util.TreeSet; +import org.junit.jupiter.api.Test; + +public class CombinationTest { + + @Test + void testNoElement() { + List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 0); + assertTrue(result == null); + } + + @Test + void testLengthOne() { + List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 1); + assertTrue(result.get(0).iterator().next() == 1); + assertTrue(result.get(1).iterator().next() == 2); + } + + @Test + void testLengthTwo() { + List<TreeSet<Integer>> result = Combination.combination(new Integer[] {1, 2}, 2); + Integer[] arr = result.get(0).toArray(new Integer[2]); + assertTrue(arr[0] == 1); + assertTrue(arr[1] == 2); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/FloodFillTest.java b/Java/src/test/java/com/thealgorithms/backtracking/FloodFillTest.java new file mode 100644 index 000000000000..8b860b5b46b0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/FloodFillTest.java @@ -0,0 +1,106 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class FloodFillTest { + + @Test + void testForEmptyImage() { + int[][] image = {}; + int[][] expected = {}; + + FloodFill.floodFill(image, 4, 5, 3, 2); + assertArrayEquals(expected, image); + } + + @Test + void testForSingleElementImage() { + int[][] image = {{1}}; + int[][] expected = {{3}}; + + FloodFill.floodFill(image, 0, 0, 3, 1); + assertArrayEquals(expected, image); + } + + @Test + void testForImageOne() { + int[][] image = { + {0, 0, 0, 0, 0, 0, 0}, + {0, 3, 3, 3, 3, 0, 0}, + {0, 3, 1, 1, 5, 0, 0}, + {0, 3, 1, 1, 5, 5, 3}, + {0, 3, 5, 5, 1, 1, 3}, + {0, 0, 0, 5, 1, 1, 3}, + {0, 0, 0, 3, 3, 3, 3}, + }; + + int[][] expected = { + {0, 0, 0, 0, 0, 0, 0}, + {0, 3, 3, 3, 3, 0, 0}, + {0, 3, 2, 2, 5, 0, 0}, + {0, 3, 2, 2, 5, 5, 3}, + {0, 3, 5, 5, 2, 2, 3}, + {0, 0, 0, 5, 2, 2, 3}, + {0, 0, 0, 3, 3, 3, 3}, + }; + + FloodFill.floodFill(image, 2, 2, 2, 1); + assertArrayEquals(expected, image); + } + + @Test + void testForImageTwo() { + int[][] image = { + {0, 0, 1, 1, 0, 0, 0}, + {1, 1, 3, 3, 3, 0, 0}, + {1, 3, 1, 1, 5, 0, 0}, + {0, 3, 1, 1, 5, 5, 3}, + {0, 3, 5, 5, 1, 1, 3}, + {0, 0, 0, 5, 1, 1, 3}, + {0, 0, 0, 1, 3, 1, 3}, + }; + + int[][] expected = { + {0, 0, 2, 2, 0, 0, 0}, + {2, 2, 3, 3, 3, 0, 0}, + {2, 3, 2, 2, 5, 0, 0}, + {0, 3, 2, 2, 5, 5, 3}, + {0, 3, 5, 5, 2, 2, 3}, + {0, 0, 0, 5, 2, 2, 3}, + {0, 0, 0, 2, 3, 2, 3}, + }; + + FloodFill.floodFill(image, 2, 2, 2, 1); + assertArrayEquals(expected, image); + } + + @Test + void testForImageThree() { + int[][] image = { + {1, 1, 2, 3, 1, 1, 1}, + {1, 0, 0, 1, 0, 0, 1}, + {1, 1, 1, 0, 3, 1, 2}, + }; + + int[][] expected = { + {4, 4, 2, 3, 4, 4, 4}, + {4, 0, 0, 4, 0, 0, 4}, + {4, 4, 4, 0, 3, 4, 2}, + }; + + FloodFill.floodFill(image, 0, 1, 4, 1); + assertArrayEquals(expected, image); + } + + @Test + void testForSameNewAndOldColor() { + int[][] image = {{1, 1, 2}, {1, 0, 0}, {1, 1, 1}}; + + int[][] expected = {{1, 1, 2}, {1, 0, 0}, {1, 1, 1}}; + + FloodFill.floodFill(image, 0, 1, 1, 1); + assertArrayEquals(expected, image); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/MColoringTest.java b/Java/src/test/java/com/thealgorithms/backtracking/MColoringTest.java new file mode 100644 index 000000000000..8b505abbc046 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/MColoringTest.java @@ -0,0 +1,57 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import org.junit.jupiter.api.Test; + +/** + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ +class MColoringTest { + + @Test + void testGraphColoring1() { + int n = 4; + int[][] graph = {{0, 1, 1, 1}, {1, 0, 1, 0}, {1, 1, 0, 1}, {1, 0, 1, 0}}; + int m = 3; // Number of colors + + assertEquals(1, MColoring.possiblePaint(createGraph(graph), n, m)); + } + + @Test + void testGraphColoring2() { + int n = 5; + int[][] graph = {{0, 1, 1, 1, 0}, {1, 0, 0, 1, 0}, {1, 0, 0, 1, 1}, {1, 1, 1, 0, 1}, {0, 0, 1, 1, 0}}; + int m = 2; // Number of colors + + assertEquals(0, MColoring.possiblePaint(createGraph(graph), n, m)); + } + + @Test + void testGraphColoring3() { + int n = 3; + int[][] graph = {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}}; + int m = 2; // Number of colors + + assertEquals(0, MColoring.possiblePaint(createGraph(graph), n, m)); + } + + private ArrayList<Node> createGraph(int[][] graph) { + int n = graph.length; + ArrayList<Node> nodes = new ArrayList<>(n + 1); + for (int i = 0; i <= n; i++) { + nodes.add(new Node()); + } + + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { // Use j = i + 1 to avoid setting edges twice + if (graph[i][j] > 0) { + nodes.get(i + 1).edges.add(j + 1); + nodes.get(j + 1).edges.add(i + 1); + } + } + } + return nodes; + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java b/Java/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java new file mode 100644 index 000000000000..edaca14af067 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java @@ -0,0 +1,73 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author onglipwei + * @create 2022-08-03 5:17 AM + */ +public class MazeRecursionTest { + + @Test + public void testMaze() { + // First create a 2 dimensions array to mimic a maze map + int[][] map = new int[8][7]; + int[][] map2 = new int[8][7]; + + // We use 1 to indicate wall + // Set the ceiling and floor to 1 + for (int i = 0; i < 7; i++) { + map[0][i] = 1; + map[7][i] = 1; + } + + // Then we set the left and right wall to 1 + for (int i = 0; i < 8; i++) { + map[i][0] = 1; + map[i][6] = 1; + } + + // Now we have created a maze with its wall initialized + + // Here we set the obstacle + map[3][1] = 1; + map[3][2] = 1; + + // clone another map for setWay2 method + for (int i = 0; i < map.length; i++) { + for (int j = 0; j < map[i].length; j++) { + map2[i][j] = map[i][j]; + } + } + + MazeRecursion.setWay(map, 1, 1); + MazeRecursion.setWay2(map2, 1, 1); + + int[][] expectedMap = new int[][] { + {1, 1, 1, 1, 1, 1, 1}, + {1, 2, 0, 0, 0, 0, 1}, + {1, 2, 2, 2, 0, 0, 1}, + {1, 1, 1, 2, 0, 0, 1}, + {1, 0, 0, 2, 0, 0, 1}, + {1, 0, 0, 2, 0, 0, 1}, + {1, 0, 0, 2, 2, 2, 1}, + {1, 1, 1, 1, 1, 1, 1}, + }; + + int[][] expectedMap2 = new int[][] { + {1, 1, 1, 1, 1, 1, 1}, + {1, 2, 2, 2, 2, 2, 1}, + {1, 0, 0, 0, 0, 2, 1}, + {1, 1, 1, 0, 0, 2, 1}, + {1, 0, 0, 0, 0, 2, 1}, + {1, 0, 0, 0, 0, 2, 1}, + {1, 0, 0, 0, 0, 2, 1}, + {1, 1, 1, 1, 1, 1, 1}, + }; + + assertArrayEquals(map, expectedMap); + assertArrayEquals(map2, expectedMap2); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java b/Java/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java new file mode 100644 index 000000000000..9da16061d8f4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class ParenthesesGeneratorTest { + @ParameterizedTest + @MethodSource("regularInputStream") + void regularInputTests(int input, List<String> expected) { + assertEquals(expected, ParenthesesGenerator.generateParentheses(input)); + } + + @ParameterizedTest + @MethodSource("negativeInputStream") + void throwsForNegativeInputTests(int input) { + assertThrows(IllegalArgumentException.class, () -> ParenthesesGenerator.generateParentheses(input)); + } + + private static Stream<Arguments> regularInputStream() { + return Stream.of(Arguments.of(0, List.of("")), Arguments.of(1, List.of("()")), Arguments.of(2, List.of("(())", "()()")), Arguments.of(3, List.of("((()))", "(()())", "(())()", "()(())", "()()()")), + Arguments.of(4, List.of("(((())))", "((()()))", "((())())", "((()))()", "(()(()))", "(()()())", "(()())()", "(())(())", "(())()()", "()((()))", "()(()())", "()(())()", "()()(())", "()()()()"))); + } + + private static Stream<Arguments> negativeInputStream() { + return Stream.of(Arguments.of(-1), Arguments.of(-5), Arguments.of(-10)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/PermutationTest.java b/Java/src/test/java/com/thealgorithms/backtracking/PermutationTest.java new file mode 100644 index 000000000000..76a714829109 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/PermutationTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class PermutationTest { + + @Test + void testNoElement() { + List<Integer[]> result = Permutation.permutation(new Integer[] {}); + assertEquals(result.get(0).length, 0); + } + + @Test + void testSingleElement() { + List<Integer[]> result = Permutation.permutation(new Integer[] {1}); + assertEquals(result.get(0)[0], 1); + } + + @Test + void testMultipleElements() { + List<Integer[]> result = Permutation.permutation(new Integer[] {1, 2}); + assertTrue(Arrays.equals(result.get(0), new Integer[] {1, 2})); + assertTrue(Arrays.equals(result.get(1), new Integer[] {2, 1})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java b/Java/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java new file mode 100644 index 000000000000..b14bce2b1920 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/PowerSumTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.backtracking; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class PowerSumTest { + + @Test + void testNumberZeroAndPowerZero() { + PowerSum powerSum = new PowerSum(); + int result = powerSum.powSum(0, 0); + assertEquals(1, result); + } + + @Test + void testNumberHundredAndPowerTwo() { + PowerSum powerSum = new PowerSum(); + int result = powerSum.powSum(100, 2); + assertEquals(3, result); + } + + @Test + void testNumberHundredAndPowerThree() { + PowerSum powerSum = new PowerSum(); + int result = powerSum.powSum(100, 3); + assertEquals(1, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java b/Java/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java new file mode 100644 index 000000000000..dac2e2675674 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public class SubsequenceFinderTest { + + @ParameterizedTest + @MethodSource("getTestCases") + void testGenerateAll(TestCase testData) { + final var actual = SubsequenceFinder.generateAll(testData.input()); + assertIterableEquals(testData.expected(), actual); + } + + static Stream<TestCase> getTestCases() { + return Stream.of(new TestCase(new ArrayList<>(), List.of(List.of())), new TestCase(List.of(1, 2), List.of(List.of(), List.of(2), List.of(1), List.of(1, 2))), + new TestCase(List.of("A", "B", "C"), List.of(List.of(), List.of("C"), List.of("B"), List.of("B", "C"), List.of("A"), List.of("A", "C"), List.of("A", "B"), List.of("A", "B", "C"))), + new TestCase(List.of(1, 2, 3), List.of(List.of(), List.of(3), List.of(2), List.of(2, 3), List.of(1), List.of(1, 3), List.of(1, 2), List.of(1, 2, 3))), new TestCase(List.of(2, 2), List.of(List.of(), List.of(2), List.of(2), List.of(2, 2)))); + } + + record TestCase(List<Object> input, List<List<Object>> expected) { + } +} diff --git a/Java/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java b/Java/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java new file mode 100644 index 000000000000..46f199747322 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/backtracking/WordSearchTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class WordSearchTest { + @Test + void test1() { + WordSearch ws = new WordSearch(); + char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; + String word = "ABCCED"; + assertTrue(ws.exist(board, word)); + } + + @Test + void test2() { + WordSearch ws = new WordSearch(); + char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; + String word = "SEE"; + assertTrue(ws.exist(board, word)); + } + + @Test + void test3() { + WordSearch ws = new WordSearch(); + char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}}; + String word = "ABCB"; + Assertions.assertFalse(ws.exist(board, word)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java new file mode 100644 index 000000000000..40de770e0c66 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java @@ -0,0 +1,13 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +public class BitSwapTest { + @Test + void testHighestSetBit() { + assertEquals(3, BitSwap.bitSwap(3, 0, 1)); + assertEquals(5, BitSwap.bitSwap(6, 0, 1)); + assertEquals(7, BitSwap.bitSwap(7, 1, 1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java new file mode 100644 index 000000000000..532f06f79ab3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +/** + * Test case for Highest Set Bit + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +class HighestSetBitTest { + + @Test + void testHighestSetBit() { + assertFalse(HighestSetBit.findHighestSetBit(0).isPresent()); + assertEquals(0, HighestSetBit.findHighestSetBit(1).get()); + assertEquals(1, HighestSetBit.findHighestSetBit(2).get()); + assertEquals(1, HighestSetBit.findHighestSetBit(3).get()); + assertEquals(2, HighestSetBit.findHighestSetBit(4).get()); + assertEquals(2, HighestSetBit.findHighestSetBit(5).get()); + assertEquals(2, HighestSetBit.findHighestSetBit(7).get()); + assertEquals(3, HighestSetBit.findHighestSetBit(8).get()); + assertEquals(3, HighestSetBit.findHighestSetBit(9).get()); + assertEquals(3, HighestSetBit.findHighestSetBit(15).get()); + assertEquals(4, HighestSetBit.findHighestSetBit(16).get()); + assertEquals(4, HighestSetBit.findHighestSetBit(17).get()); + assertEquals(4, HighestSetBit.findHighestSetBit(31).get()); + assertEquals(5, HighestSetBit.findHighestSetBit(32).get()); + assertEquals(5, HighestSetBit.findHighestSetBit(33).get()); + assertEquals(7, HighestSetBit.findHighestSetBit(255).get()); + assertEquals(8, HighestSetBit.findHighestSetBit(256).get()); + assertEquals(8, HighestSetBit.findHighestSetBit(511).get()); + assertEquals(9, HighestSetBit.findHighestSetBit(512).get()); + assertThrows(IllegalArgumentException.class, () -> HighestSetBit.findHighestSetBit(-37)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java new file mode 100644 index 000000000000..9bf804373438 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java @@ -0,0 +1,20 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Test case for Index Of Right Most SetBit + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +class IndexOfRightMostSetBitTest { + + @Test + void testIndexOfRightMostSetBit() { + assertEquals(3, IndexOfRightMostSetBit.indexOfRightMostSetBit(40)); + assertEquals(-1, IndexOfRightMostSetBit.indexOfRightMostSetBit(0)); + assertEquals(3, IndexOfRightMostSetBit.indexOfRightMostSetBit(-40)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java new file mode 100644 index 000000000000..0b2bfb0bb065 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java @@ -0,0 +1,17 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class IsEvenTest { + @Test + void testIsEven() { + assertTrue(IsEven.isEven(0)); + assertTrue(IsEven.isEven(2)); + assertTrue(IsEven.isEven(-12)); + assertFalse(IsEven.isEven(21)); + assertFalse(IsEven.isEven(-1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java new file mode 100644 index 000000000000..27bc93c31ae4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java @@ -0,0 +1,35 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +/** + * Test case for IsPowerTwo class + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public class IsPowerTwoTest { + @Test + public void testIsPowerTwo() { + // test some positive powers of 2 + assertTrue(IsPowerTwo.isPowerTwo(1)); + assertTrue(IsPowerTwo.isPowerTwo(2)); + assertTrue(IsPowerTwo.isPowerTwo(4)); + assertTrue(IsPowerTwo.isPowerTwo(16)); + assertTrue(IsPowerTwo.isPowerTwo(1024)); + + // test some negative numbers + assertFalse(IsPowerTwo.isPowerTwo(-1)); + assertFalse(IsPowerTwo.isPowerTwo(-2)); + assertFalse(IsPowerTwo.isPowerTwo(-4)); + + // test some numbers that are not powers of 2 + assertFalse(IsPowerTwo.isPowerTwo(0)); + assertFalse(IsPowerTwo.isPowerTwo(3)); + assertFalse(IsPowerTwo.isPowerTwo(5)); + assertFalse(IsPowerTwo.isPowerTwo(15)); + assertFalse(IsPowerTwo.isPowerTwo(1000)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java new file mode 100644 index 000000000000..1addde057181 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Test case for Non Repeating Number Finder + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +class NonRepeatingNumberFinderTest { + + @Test + void testNonRepeatingNumberFinder() { + int[] arr = {1, 2, 1, 2, 6}; + assertEquals(6, NonRepeatingNumberFinder.findNonRepeatingNumber(arr)); + int[] arr1 = {1, 2, 1, 2}; + assertEquals(0, NonRepeatingNumberFinder.findNonRepeatingNumber(arr1)); + int[] arr2 = {12}; + assertEquals(12, NonRepeatingNumberFinder.findNonRepeatingNumber(arr2)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java new file mode 100644 index 000000000000..13761ac23e44 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.bitmanipulation; + +/** + * test Cases of Numbers Different Signs + * @author Bama Charan Chhandogi + */ + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class NumbersDifferentSignsTest { + + @Test + void testDifferentSignsPositiveNegative() { + assertTrue(NumbersDifferentSigns.differentSigns(2, -1)); + } + + @Test + void testDifferentSignsNegativePositive() { + assertTrue(NumbersDifferentSigns.differentSigns(-3, 7)); + } + + @Test + void testSameSignsPositive() { + assertFalse(NumbersDifferentSigns.differentSigns(10, 20)); + } + + @Test + void testSameSignsNegative() { + assertFalse(NumbersDifferentSigns.differentSigns(-5, -8)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java new file mode 100644 index 000000000000..967a89a1ee97 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class ReverseBitsTest { + + @Test + void testReverseBits() { + assertEquals(0, ReverseBits.reverseBits(0)); + assertEquals(-1, ReverseBits.reverseBits(-1)); + assertEquals(964176192, ReverseBits.reverseBits(43261596)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java b/Java/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java new file mode 100644 index 000000000000..9cac8d670a4a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.bitmanipulation; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class SingleBitOperationsTest { + + @Test + public void flipBitTest() { + assertEquals(1, SingleBitOperations.flipBit(3, 1)); + assertEquals(11, SingleBitOperations.flipBit(3, 3)); + } + + @Test + public void setBitTest() { + assertEquals(5, SingleBitOperations.setBit(4, 0)); + assertEquals(4, SingleBitOperations.setBit(4, 2)); + assertEquals(5, SingleBitOperations.setBit(5, 0)); + assertEquals(14, SingleBitOperations.setBit(10, 2)); + assertEquals(15, SingleBitOperations.setBit(15, 3)); + assertEquals(2, SingleBitOperations.setBit(0, 1)); + } + + @Test + public void clearBitTest() { + assertEquals(5, SingleBitOperations.clearBit(7, 1)); + assertEquals(5, SingleBitOperations.clearBit(5, 1)); + } + + @Test + public void getBitTest() { + assertEquals(0, SingleBitOperations.getBit(6, 0)); + assertEquals(1, SingleBitOperations.getBit(7, 1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java b/Java/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java new file mode 100644 index 000000000000..ef5e634f781b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java @@ -0,0 +1,38 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class BlowfishTest { + + Blowfish blowfish = new Blowfish(); + + @Test + void testEncrypt() { + // given + String plainText = "123456abcd132536"; + String key = "aabb09182736ccdd"; + String expectedOutput = "d748ec383d3405f7"; + + // when + String cipherText = blowfish.encrypt(plainText, key); + + // then + assertEquals(expectedOutput, cipherText); + } + + @Test + void testDecrypt() { + // given + String cipherText = "d748ec383d3405f7"; + String key = "aabb09182736ccdd"; + String expectedOutput = "123456abcd132536"; + + // when + String plainText = blowfish.decrypt(cipherText, key); + + // then + assertEquals(expectedOutput, plainText); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/CaesarTest.java b/Java/src/test/java/com/thealgorithms/ciphers/CaesarTest.java new file mode 100644 index 000000000000..7aa41c4cf423 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/CaesarTest.java @@ -0,0 +1,46 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class CaesarTest { + + Caesar caesar = new Caesar(); + + @Test + void caesarEncryptTest() { + // given + String textToEncrypt = "Encrypt this text"; + + // when + String cipherText = caesar.encode(textToEncrypt, 5); + + // then + assertEquals("Jshwduy ymnx yjcy", cipherText); + } + + @Test + void caesarDecryptTest() { + // given + String encryptedText = "Jshwduy ymnx yjcy"; + + // when + String cipherText = caesar.decode(encryptedText, 5); + + // then + assertEquals("Encrypt this text", cipherText); + } + + @Test + void caesarBruteForce() { + // given + String encryptedText = "Jshwduy ymnx yjcy"; + + // when + String[] allPossibleAnswers = caesar.bruteforce(encryptedText); + + assertEquals(27, allPossibleAnswers.length); + assertEquals("Encrypt this text", allPossibleAnswers[5]); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/DESTest.java b/Java/src/test/java/com/thealgorithms/ciphers/DESTest.java new file mode 100644 index 000000000000..ddc643a6eb35 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/DESTest.java @@ -0,0 +1,55 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +// Test example taken from https://page.math.tu-berlin.de/~kant/teaching/hess/krypto-ws2006/des.htm +public class DESTest { + + DES des; + + @BeforeEach + public void setUp() { + des = new DES("0000111000110010100100100011001011101010011011010000110101110011"); + } + + @Test + void testEncrypt() { + // given + String plainText = "Your lips are smoother than vaseline\r\n"; + // This is equal to + // c0999fdde378d7ed727da00bca5a84ee47f269a4d6438190d9d52f78f5358499828ac9b453e0e653 in + // hexadecimal + String expectedOutput = "11000000100110011001111111011101111000110111100011010111111" + + "011010111001001111101101000000000101111001010010110101000010011101110010001111111001" + + "001101001101001001101011001000011100000011001000011011001110101010010111101111000111" + + "101010011010110000100100110011000001010001010110010011011010001010011111000001110011001010011"; + + // when + String cipherText = des.encrypt(plainText); + + // then + assertEquals(expectedOutput, cipherText); + } + + @Test + void testDecrypt() { + // given + // This is equal to + // c0999fdde378d7ed727da00bca5a84ee47f269a4d6438190d9d52f78f5358499828ac9b453e0e653 in + // hexadecimal + String cipherText = "11000000100110011001111111011101111000110111100011010111111" + + "011010111001001111101101000000000101111001010010110101000010011101110010001111111001" + + "001101001101001001101011001000011100000011001000011011001110101010010111101111000111" + + "101010011010110000100100110011000001010001010110010011011010001010011111000001110011001010011"; + String expectedOutput = "Your lips are smoother than vaseline\r\n"; + + // when + String plainText = des.decrypt(cipherText); + + // then + assertEquals(expectedOutput, plainText); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java b/Java/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java new file mode 100644 index 000000000000..fa497e4682e8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java @@ -0,0 +1,37 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class PlayfairTest { + + @Test + public void testEncryption() { + PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD"); + + String plaintext = "HELLO"; + String encryptedText = playfairCipher.encrypt(plaintext); + assertEquals("GYIZSC", encryptedText); + } + + @Test + public void testDecryption() { + PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD"); + + String encryptedText = "UDRIYP"; + String decryptedText = playfairCipher.decrypt(encryptedText); + assertEquals("NEBFVH", decryptedText); + } + + @Test + public void testEncryptionAndDecryption() { + PlayfairCipher playfairCipher = new PlayfairCipher("KEYWORD"); + + String plaintext = "PLAYFAIR"; + String encryptedText = playfairCipher.encrypt(plaintext); + String decryptedText = playfairCipher.decrypt(encryptedText); + + assertEquals(plaintext, decryptedText); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java b/Java/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java new file mode 100644 index 000000000000..543a2fe59685 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/PolybiusTest.java @@ -0,0 +1,45 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class PolybiusTest { + + @Test + void testEncrypt() { + // Given + String plaintext = "HELLOWORLD"; + + // When + String actual = Polybius.encrypt(plaintext); + + // Then + assertEquals("12042121244124322103", actual); + } + + @Test + void testDecrypt() { + // Given + String ciphertext = "12042121244124322103"; + + // When + String actual = Polybius.decrypt(ciphertext); + + // Then + assertEquals("HELLOWORLD", actual); + } + + @Test + void testIsTextTheSameAfterEncryptionAndDecryption() { + // Given + String plaintext = "HELLOWORLD"; + + // When + String encryptedText = Polybius.encrypt(plaintext); + String actual = Polybius.decrypt(encryptedText); + + // Then + assertEquals(plaintext, actual); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/RSATest.java b/Java/src/test/java/com/thealgorithms/ciphers/RSATest.java new file mode 100644 index 000000000000..c82f68d11f4c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/RSATest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class RSATest { + + RSA rsa = new RSA(1024); + + @Test + void testRSA() { + // given + String textToEncrypt = "Such secure"; + + // when + String cipherText = rsa.encrypt(textToEncrypt); + String decryptedText = rsa.decrypt(cipherText); + + // then + assertEquals("Such secure", decryptedText); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java b/Java/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java new file mode 100644 index 000000000000..f593a07d89b7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/SimpleSubCipherTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class SimpleSubCipherTest { + + SimpleSubCipher simpleSubCipher = new SimpleSubCipher(); + + @Test + void simpleSubCipherEncryptTest() { + // given + String text = "defend the east wall of the castle"; + String cipherSmall = "phqgiumeaylnofdxjkrcvstzwb"; + + // when + String cipherText = simpleSubCipher.encode(text, cipherSmall); + + // then + assertEquals("giuifg cei iprc tpnn du cei qprcni", cipherText); + } + + @Test + void simpleSubCipherDecryptTest() { + // given + String encryptedText = "giuifg cei iprc tpnn du cei qprcni"; + String cipherSmall = "phqgiumeaylnofdxjkrcvstzwb"; + + // when + String decryptedText = simpleSubCipher.decode(encryptedText, cipherSmall); + + // then + assertEquals("defend the east wall of the castle", decryptedText); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/VigenereTest.java b/Java/src/test/java/com/thealgorithms/ciphers/VigenereTest.java new file mode 100644 index 000000000000..c5935de95dfa --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/VigenereTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.ciphers; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class VigenereTest { + + Vigenere vigenere = new Vigenere(); + + @Test + void vigenereEncryptTest() { + // given + String text = "Hello World!"; + String key = "suchsecret"; + + // when + String cipherText = vigenere.encrypt(text, key); + + // then + assertEquals("Zynsg Yfvev!", cipherText); + } + + @Test + void vigenereDecryptTest() { + // given + String encryptedText = "Zynsg Yfvev!"; + String key = "suchsecret"; + + // when + String decryptedText = vigenere.decrypt(encryptedText, key); + + // then + assertEquals("Hello World!", decryptedText); + } +} diff --git a/Java/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java b/Java/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java new file mode 100644 index 000000000000..6ef478f95358 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java @@ -0,0 +1,96 @@ +package com.thealgorithms.ciphers.a5; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.BitSet; +import org.junit.jupiter.api.Test; + +// Basic tests for sanity check +class LFSRTest { + + // Represents 0100 1110 0010 1111 0100 1101 0111 1100 0001 1110 1011 1000 1000 1011 0011 1010 + // But we start reverse way because bitset starts from most right (1010) + byte[] sessionKeyBytes = { + 58, + (byte) 139, + (byte) 184, + 30, + 124, + 77, + 47, + 78, + }; + + // Represents 11 1010 1011 0011 1100 1011 + byte[] frameCounterBytes = {(byte) 203, (byte) 179, 58}; + + @Test + void initialize() { + BitSet sessionKey = BitSet.valueOf(sessionKeyBytes); + BitSet frameCounter = BitSet.valueOf(frameCounterBytes); + + BitSet expected = new BitSet(19); + expected.set(0); + expected.set(1); + expected.set(3); + expected.set(4); + expected.set(5); + expected.set(7); + expected.set(9); + expected.set(10); + expected.set(11); + expected.set(12); + expected.set(13); + expected.set(15); + expected.set(16); + expected.set(17); + + LFSR lfsr0 = new LFSR(19, 8, new int[] {13, 16, 17, 18}); + lfsr0.initialize(sessionKey, frameCounter); + assertEquals(expected.toString(), lfsr0.toString()); + } + + @Test + void clock() { + BitSet sessionKey = BitSet.valueOf(sessionKeyBytes); + BitSet frameCounter = BitSet.valueOf(frameCounterBytes); + + LFSR lfsr0 = new LFSR(19, 8, new int[] {13, 16, 17, 18}); + lfsr0.initialize(sessionKey, frameCounter); + + BitSet expected = new BitSet(19); + expected.set(0); + expected.set(1); + expected.set(2); + expected.set(4); + expected.set(5); + expected.set(6); + expected.set(8); + expected.set(10); + expected.set(11); + expected.set(12); + expected.set(13); + expected.set(14); + expected.set(16); + expected.set(17); + expected.set(18); + + lfsr0.clock(); + assertEquals(expected.toString(), lfsr0.toString()); + } + + @Test + void getClockBit() { + BitSet sessionKey = BitSet.valueOf(sessionKeyBytes); + BitSet frameCounter = BitSet.valueOf(frameCounterBytes); + + LFSR lfsr0 = new LFSR(19, 8, new int[] {13, 16, 17, 18}); + + assertFalse(lfsr0.getClockBit()); + + lfsr0.initialize(sessionKey, frameCounter); + + assertFalse(lfsr0.getClockBit()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java b/Java/src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java new file mode 100644 index 000000000000..2471f919a845 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/BinaryToDecimalTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryToDecimalTest { + + @Test + // Test converting binary to decimal + public void testBinaryToDecimal() { + // zeros at the starting should be removed + assertEquals(0, BinaryToDecimal.binaryToDecimal(0)); + assertEquals(1, BinaryToDecimal.binaryToDecimal(1)); + assertEquals(5, BinaryToDecimal.binaryToDecimal(101)); + assertEquals(63, BinaryToDecimal.binaryToDecimal(111111)); + assertEquals(512, BinaryToDecimal.binaryToDecimal(1000000000)); + } + + @Test + // Test converting negative binary numbers + public void testNegativeBinaryToDecimal() { + assertEquals(-1, BinaryToDecimal.binaryToDecimal(-1)); + assertEquals(-42, BinaryToDecimal.binaryToDecimal(-101010)); + } + + @Test + // Test converting binary numbers with large values + public void testLargeBinaryToDecimal() { + assertEquals(262144L, BinaryToDecimal.binaryToDecimal(1000000000000000000L)); + assertEquals(524287L, BinaryToDecimal.binaryToDecimal(1111111111111111111L)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java b/Java/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java new file mode 100644 index 000000000000..5cbdf39acb27 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryToHexadecimalTest { + + @Test + public void testBinaryToHexadecimal() { + assertEquals("6A", BinaryToHexadecimal.binToHex(1101010)); + assertEquals("C", BinaryToHexadecimal.binToHex(1100)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java b/Java/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java new file mode 100644 index 000000000000..c7018daecf23 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryToOctalTest { + + @Test + public void testBinaryToOctal() { + assertEquals("226", BinaryToOctal.convertBinaryToOctal(10010110)); + assertEquals("135", BinaryToOctal.convertBinaryToOctal(1011101)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java b/Java/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java new file mode 100644 index 000000000000..1105f457504e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class DecimalToHexaDecimalTest { + + @Test + public void testDecimalToHexaDecimal() { + assertEquals("000000be", DecimalToHexaDecimal.decToHex(190)); + assertEquals("00000708", DecimalToHexaDecimal.decToHex(1800)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/HexToOctTest.java b/Java/src/test/java/com/thealgorithms/conversions/HexToOctTest.java new file mode 100644 index 000000000000..5924aa31854b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/HexToOctTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class HexToOctTest { + + @Test + public void testHexToOct() { + assertEquals(110, HexToOct.decimal2octal(HexToOct.hex2decimal("48"))); + assertEquals(255, HexToOct.decimal2octal(HexToOct.hex2decimal("AD"))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java b/Java/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java new file mode 100644 index 000000000000..72a0a0174a93 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class HexaDecimalToBinaryTest { + + @Test + public void testHexaDecimalToBinary() { + HexaDecimalToBinary hexaDecimalToBinary = new HexaDecimalToBinary(); + assertEquals("1111111111111111111111111111111", hexaDecimalToBinary.convert("7fffffff")); + assertEquals("101010111100110111101111", hexaDecimalToBinary.convert("abcdef")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java b/Java/src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java new file mode 100644 index 000000000000..c9c2ab2161ed --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/HexaDecimalToDecimalTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class HexaDecimalToDecimalTest { + + @Test + public void testhexaDecimalToDecimal() { + assertEquals(161, HexaDecimalToDecimal.getHexaToDec("A1")); + assertEquals(428, HexaDecimalToDecimal.getHexaToDec("1ac")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java b/Java/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java new file mode 100644 index 000000000000..04768d034b93 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class IntegerToRomanTest { + + @Test + public void testIntegerToRoman() { + assertEquals("MCMXCIV", IntegerToRoman.integerToRoman(1994)); + assertEquals("LVIII", IntegerToRoman.integerToRoman(58)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java b/Java/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java new file mode 100644 index 000000000000..86cf692c5258 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class OctalToBinaryTest { + @Test + public void testConvertOctalToBinary() { + assertEquals(101, OctalToBinary.convertOctalToBinary(5)); + assertEquals(1001, OctalToBinary.convertOctalToBinary(11)); + assertEquals(101010, OctalToBinary.convertOctalToBinary(52)); + assertEquals(110, OctalToBinary.convertOctalToBinary(6)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java b/Java/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java new file mode 100644 index 000000000000..6e17ea14efc8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class OctalToDecimalTest { + + @Test + public void testOctalToDecimal() { + assertEquals(1465, OctalToDecimal.convertOctalToDecimal("2671")); + assertEquals(189, OctalToDecimal.convertOctalToDecimal("275")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java b/Java/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java new file mode 100644 index 000000000000..f71732b27d51 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class OctalToHexadecimalTest { + + @Test + public void testOctalToHexadecimal() { + assertEquals("1EA", OctalToHexadecimal.decimalToHex(OctalToHexadecimal.octToDec("752"))); + assertEquals("15E", OctalToHexadecimal.decimalToHex(OctalToHexadecimal.octToDec("536"))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java b/Java/src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java new file mode 100644 index 000000000000..c51986f2a8d9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/conversions/RomanToIntegerTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.conversions; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class RomanToIntegerTest { + + @Test + public void testRomanToInteger() { + assertEquals(1994, RomanToInteger.romanToInt("MCMXCIV")); + assertEquals(58, RomanToInteger.romanToInt("LVIII")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java b/Java/src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java new file mode 100644 index 000000000000..d6b137406827 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/bloomfilter/BloomFilterTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.datastructures.bloomfilter; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class BloomFilterTest { + + @Test + public void test1() { + BloomFilter<Integer> bloomFilter = new BloomFilter<>(3, 10); + bloomFilter.insert(3); + bloomFilter.insert(17); + + Assertions.assertTrue(bloomFilter.contains(3)); + Assertions.assertTrue(bloomFilter.contains(17)); + } + + @Test + public void test2() { + BloomFilter<String> bloomFilter = new BloomFilter<>(4, 20); + bloomFilter.insert("omar"); + bloomFilter.insert("mahamid"); + + Assertions.assertTrue(bloomFilter.contains("omar")); + Assertions.assertTrue(bloomFilter.contains("mahamid")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java b/Java/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java new file mode 100644 index 000000000000..9bc3b89ced9e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java @@ -0,0 +1,127 @@ +package com.thealgorithms.datastructures.buffers; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicIntegerArray; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; + +class CircularBufferTest { + private static final int BUFFER_SIZE = 10; + private CircularBuffer<Integer> buffer; + + @BeforeEach + void setUp() { + buffer = new CircularBuffer<>(BUFFER_SIZE); + } + + @Test + void isEmpty() { + assertTrue(buffer.isEmpty()); + buffer.put(generateInt()); + assertFalse(buffer.isEmpty()); + } + + @Test + void isFull() { + assertFalse(buffer.isFull()); + buffer.put(generateInt()); + assertFalse(buffer.isFull()); + + for (int i = 1; i < BUFFER_SIZE; i++) buffer.put(generateInt()); + assertTrue(buffer.isFull()); + } + + @Test + void get() { + assertNull(buffer.get()); + for (int i = 0; i < 100; i++) buffer.put(i); + for (int i = 0; i < BUFFER_SIZE; i++) assertEquals(i, buffer.get()); + assertNull(buffer.get()); + } + + @Test + void put() { + for (int i = 0; i < BUFFER_SIZE; i++) assertTrue(buffer.put(generateInt())); + assertFalse(buffer.put(generateInt())); + } + + @RepeatedTest(1000) + void concurrentTest() throws InterruptedException { + final int numberOfThreadsForProducers = 3; + final int numberOfThreadsForConsumers = 2; + final int numberOfItems = 300; + final CountDownLatch producerCountDownLatch = new CountDownLatch(numberOfItems); + final CountDownLatch consumerCountDownLatch = new CountDownLatch(numberOfItems); + final AtomicIntegerArray resultAtomicArray = new AtomicIntegerArray(numberOfItems); + + // We are running 2 ExecutorService simultaneously 1 - producer, 2 - consumer + // Run producer threads to populate buffer. + ExecutorService putExecutors = Executors.newFixedThreadPool(numberOfThreadsForProducers); + putExecutors.execute(() -> { + while (producerCountDownLatch.getCount() > 0) { + int count = (int) producerCountDownLatch.getCount(); + boolean put = buffer.put(count); + while (!put) put = buffer.put(count); + producerCountDownLatch.countDown(); + } + }); + + // Run consumer threads to retrieve the data from buffer. + ExecutorService getExecutors = Executors.newFixedThreadPool(numberOfThreadsForConsumers); + getExecutors.execute(() -> { + while (consumerCountDownLatch.getCount() > 0) { + int count = (int) consumerCountDownLatch.getCount(); + Integer item = buffer.get(); + while (item == null) item = buffer.get(); + resultAtomicArray.set(count - 1, item); + consumerCountDownLatch.countDown(); + } + }); + + producerCountDownLatch.await(); + consumerCountDownLatch.await(); + putExecutors.shutdown(); + getExecutors.shutdown(); + shutDownExecutorSafely(putExecutors); + shutDownExecutorSafely(getExecutors); + + List<Integer> resultArray = getSortedListFrom(resultAtomicArray); + for (int i = 0; i < numberOfItems; i++) { + int expectedItem = i + 1; + assertEquals(expectedItem, resultArray.get(i)); + } + } + + private int generateInt() { + return ThreadLocalRandom.current().nextInt(0, 100); + } + + private void shutDownExecutorSafely(ExecutorService executorService) { + try { + if (!executorService.awaitTermination(1_000, TimeUnit.MILLISECONDS)) executorService.shutdownNow(); + } catch (InterruptedException e) { + executorService.shutdownNow(); + } + } + + public List<Integer> getSortedListFrom(AtomicIntegerArray atomicArray) { + int length = atomicArray.length(); + ArrayList<Integer> result = new ArrayList<>(length); + for (int i = 0; i < length; i++) result.add(atomicArray.get(i)); + result.sort(Comparator.comparingInt(o -> o)); + return result; + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java b/Java/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java new file mode 100644 index 000000000000..6a94345d625e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/caches/LFUCacheTest.java @@ -0,0 +1,82 @@ +package com.thealgorithms.datastructures.caches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class LFUCacheTest { + + @Test + void testLFUCacheWithIntegerValueShouldPass() { + LFUCache<Integer, Integer> lfuCache = new LFUCache<>(5); + lfuCache.put(1, 10); + lfuCache.put(2, 20); + lfuCache.put(3, 30); + lfuCache.put(4, 40); + lfuCache.put(5, 50); + + // get method call will increase frequency of key 1 by 1 + assertEquals(10, lfuCache.get(1)); + + // this operation will remove value with key as 2 + lfuCache.put(6, 60); + + // will return null as value with key 2 is now evicted + assertEquals(null, lfuCache.get(2)); + + // should return 60 + assertEquals(60, lfuCache.get(6)); + + // this operation will remove value with key as 3 + lfuCache.put(7, 70); + + assertEquals(null, lfuCache.get(2)); + assertEquals(70, lfuCache.get(7)); + } + + @Test + void testLFUCacheWithStringValueShouldPass() { + LFUCache<Integer, String> lfuCache = new LFUCache<>(5); + lfuCache.put(1, "Alpha"); + lfuCache.put(2, "Beta"); + lfuCache.put(3, "Gamma"); + lfuCache.put(4, "Delta"); + lfuCache.put(5, "Eplison"); + + // get method call will increase frequency of key 1 by 1 + assertEquals("Alpha", lfuCache.get(1)); + + // this operation will remove value with key as 2 + lfuCache.put(6, "Digamma"); + + // will return null as value with key 2 is now evicted + assertEquals(null, lfuCache.get(2)); + + // should return string Digamma + assertEquals("Digamma", lfuCache.get(6)); + + // this operation will remove value with key as 3 + lfuCache.put(7, "Zeta"); + + assertEquals(null, lfuCache.get(2)); + assertEquals("Zeta", lfuCache.get(7)); + } + + /** + * test addNodeWithUpdatedFrequency method + * @author yuluo + */ + @Test + void testAddNodeWithUpdatedFrequency() { + LFUCache<Integer, String> lfuCache = new LFUCache<>(3); + lfuCache.put(1, "beijing"); + lfuCache.put(2, "shanghai"); + lfuCache.put(3, "gansu"); + + assertEquals("beijing", lfuCache.get(1)); + + lfuCache.put(1, "shanxi"); + + assertEquals("shanxi", lfuCache.get(1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java b/Java/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java new file mode 100644 index 000000000000..c56ada060022 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/caches/LRUCacheTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.datastructures.caches; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +public class LRUCacheTest { + + private static final int SIZE = 5; + + @Test + public void putAndGetIntegerValues() { + LRUCache<Integer, Integer> lruCache = new LRUCache<>(SIZE); + + for (int i = 0; i < SIZE; i++) { + lruCache.put(i, i); + } + + for (int i = 0; i < SIZE; i++) { + assertEquals(i, lruCache.get(i)); + } + } + + @Test + public void putAndGetStringValues() { + LRUCache<String, String> lruCache = new LRUCache<>(SIZE); + + for (int i = 0; i < SIZE; i++) { + lruCache.put("key" + i, "value" + i); + } + + for (int i = 0; i < SIZE; i++) { + assertEquals("value" + i, lruCache.get("key" + i)); + } + } + + @Test + public void nullKeysAndValues() { + LRUCache<Integer, Integer> mruCache = new LRUCache<>(SIZE); + mruCache.put(null, 2); + mruCache.put(6, null); + + assertEquals(2, mruCache.get(null)); + assertNull(mruCache.get(6)); + } + + @Test + public void overCapacity() { + LRUCache<Integer, Integer> mruCache = new LRUCache<>(SIZE); + + for (int i = 0; i < 10; i++) { + mruCache.put(i, i); + } + + assertEquals(9, mruCache.get(9)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java b/Java/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java new file mode 100644 index 000000000000..447feb38e788 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/caches/MRUCacheTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.datastructures.caches; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +public class MRUCacheTest { + + private static final int SIZE = 5; + + @Test + public void putAndGetIntegerValues() { + MRUCache<Integer, Integer> lruCache = new MRUCache<>(SIZE); + + for (int i = 0; i < SIZE; i++) { + lruCache.put(i, i); + } + + for (int i = 0; i < SIZE; i++) { + assertEquals(i, lruCache.get(i)); + } + } + + @Test + public void putAndGetStringValues() { + MRUCache<String, String> lruCache = new MRUCache<>(SIZE); + + for (int i = 0; i < SIZE; i++) { + lruCache.put("key" + i, "value" + i); + } + + for (int i = 0; i < SIZE; i++) { + assertEquals("value" + i, lruCache.get("key" + i)); + } + } + + @Test + public void nullKeysAndValues() { + MRUCache<Integer, Integer> mruCache = new MRUCache<>(SIZE); + mruCache.put(null, 2); + mruCache.put(6, null); + + assertEquals(2, mruCache.get(null)); + assertNull(mruCache.get(6)); + } + + @Test + public void overCapacity() { + MRUCache<Integer, Integer> mruCache = new MRUCache<>(SIZE); + + for (int i = 0; i < 10; i++) { + mruCache.put(i, i); + } + + assertEquals(9, mruCache.get(9)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java b/Java/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java new file mode 100644 index 000000000000..eb48c7d9e8d6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java @@ -0,0 +1,56 @@ +package com.thealgorithms.datastructures.crdt; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class GCounterTest { + @Test + void increment() { + GCounter counter = new GCounter(0, 3); + counter.increment(); + counter.increment(); + counter.increment(); + assertEquals(3, counter.value()); + } + + @Test + void merge() { + GCounter counter1 = new GCounter(0, 3); + counter1.increment(); + GCounter counter2 = new GCounter(1, 3); + counter2.increment(); + counter2.increment(); + GCounter counter3 = new GCounter(2, 3); + counter3.increment(); + counter3.increment(); + counter3.increment(); + counter1.merge(counter2); + counter1.merge(counter3); + counter2.merge(counter1); + counter3.merge(counter2); + assertEquals(6, counter1.value()); + assertEquals(6, counter2.value()); + assertEquals(6, counter3.value()); + } + + @Test + void compare() { + GCounter counter1 = new GCounter(0, 5); + GCounter counter2 = new GCounter(3, 5); + counter1.increment(); + counter1.increment(); + counter2.merge(counter1); + counter2.increment(); + counter2.increment(); + assertTrue(counter1.compare(counter2)); + counter1.increment(); + counter2.increment(); + counter2.merge(counter1); + assertTrue(counter1.compare(counter2)); + counter1.increment(); + assertFalse(counter1.compare(counter2)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java b/Java/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java new file mode 100644 index 000000000000..b4566aa9b1d8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.datastructures.crdt; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class GSetTest { + + @Test + void testAddElement() { + GSet<String> gSet = new GSet<>(); + gSet.addElement("apple"); + gSet.addElement("orange"); + + assertTrue(gSet.lookup("apple")); + assertTrue(gSet.lookup("orange")); + assertFalse(gSet.lookup("banana")); + } + + @Test + void testLookup() { + GSet<Integer> gSet = new GSet<>(); + gSet.addElement(1); + gSet.addElement(2); + + assertTrue(gSet.lookup(1)); + assertTrue(gSet.lookup(2)); + assertFalse(gSet.lookup(3)); + } + + @Test + void testCompare() { + GSet<String> gSet1 = new GSet<>(); + GSet<String> gSet2 = new GSet<>(); + gSet1.addElement("apple"); + gSet1.addElement("orange"); + gSet2.addElement("orange"); + assertFalse(gSet1.compare(gSet2)); + gSet2.addElement("apple"); + assertTrue(gSet1.compare(gSet2)); + gSet2.addElement("banana"); + assertTrue(gSet1.compare(gSet2)); + } + + @Test + void testMerge() { + GSet<String> gSet1 = new GSet<>(); + GSet<String> gSet2 = new GSet<>(); + + gSet1.addElement("apple"); + gSet1.addElement("orange"); + + gSet2.addElement("orange"); + gSet2.addElement("banana"); + + GSet<String> mergedSet = new GSet<>(); + mergedSet.merge(gSet1); + mergedSet.merge(gSet2); + + assertTrue(mergedSet.lookup("apple")); + assertTrue(mergedSet.lookup("orange")); + assertTrue(mergedSet.lookup("banana")); + assertFalse(mergedSet.lookup("grape")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java b/Java/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java new file mode 100644 index 000000000000..36593d6669f8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java @@ -0,0 +1,108 @@ +package com.thealgorithms.datastructures.crdt; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class LWWElementSetTest { + + private LWWElementSet set; + private final Bias bias = Bias.ADDS; + + @BeforeEach + void setUp() { + set = new LWWElementSet(); + } + + @Test + void testAdd() { + Element element = new Element("key1", 1, bias); + set.add(element); + + assertTrue(set.lookup(element)); + } + + @Test + void testRemove() { + Element element = new Element("key1", 1, bias); + set.add(element); + set.remove(element); + + assertFalse(set.lookup(element)); + } + + @Test + void testRemoveNonexistentElement() { + Element element = new Element("key1", 1, bias); + set.remove(element); + + assertFalse(set.lookup(element)); + } + + @Test + void testLookupNonexistentElement() { + Element element = new Element("key1", 1, bias); + + assertFalse(set.lookup(element)); + } + + @Test + void testCompareEqualSets() { + LWWElementSet otherSet = new LWWElementSet(); + + Element element = new Element("key1", 1, bias); + set.add(element); + otherSet.add(element); + + assertTrue(set.compare(otherSet)); + + otherSet.add(new Element("key2", 2, bias)); + assertTrue(set.compare(otherSet)); + } + + @Test + void testCompareDifferentSets() { + LWWElementSet otherSet = new LWWElementSet(); + + Element element1 = new Element("key1", 1, bias); + Element element2 = new Element("key2", 2, bias); + + set.add(element1); + otherSet.add(element2); + + assertFalse(set.compare(otherSet)); + } + + @Test + void testMerge() { + LWWElementSet otherSet = new LWWElementSet(); + + Element element1 = new Element("key1", 1, bias); + Element element2 = new Element("key2", 2, bias); + + set.add(element1); + otherSet.add(element2); + + set.merge(otherSet); + + assertTrue(set.lookup(element1)); + assertTrue(set.lookup(element2)); + } + + @Test + void testCompareTimestampsEqualTimestamps() { + LWWElementSet lwwElementSet = new LWWElementSet(); + + Element e1 = new Element("key1", 10, Bias.REMOVALS); + Element e2 = new Element("key1", 10, Bias.REMOVALS); + + assertTrue(lwwElementSet.compareTimestamps(e1, e2)); + + e1 = new Element("key1", 10, Bias.ADDS); + e2 = new Element("key1", 10, Bias.ADDS); + + assertFalse(lwwElementSet.compareTimestamps(e1, e2)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java b/Java/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java new file mode 100644 index 000000000000..f6d19a3e7b20 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java @@ -0,0 +1,88 @@ +package com.thealgorithms.datastructures.crdt; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Set; +import org.junit.jupiter.api.Test; + +class ORSetTest { + + @Test + void testContains() { + ORSet<String> orSet = new ORSet<>(); + orSet.add("A"); + assertTrue(orSet.contains("A")); + } + + @Test + void testAdd() { + ORSet<String> orSet = new ORSet<>(); + orSet.add("A"); + assertTrue(orSet.contains("A")); + } + + @Test + void testRemove() { + ORSet<String> orSet = new ORSet<>(); + orSet.add("A"); + orSet.add("A"); + orSet.remove("A"); + assertFalse(orSet.contains("A")); + } + + @Test + void testElements() { + ORSet<String> orSet = new ORSet<>(); + orSet.add("A"); + orSet.add("B"); + assertEquals(Set.of("A", "B"), orSet.elements()); + } + + @Test + void testCompareEqualSets() { + ORSet<String> orSet1 = new ORSet<>(); + ORSet<String> orSet2 = new ORSet<>(); + + orSet1.add("A"); + orSet2.add("A"); + orSet2.add("B"); + orSet2.add("C"); + orSet2.remove("C"); + orSet1.merge(orSet2); + orSet2.merge(orSet1); + orSet2.remove("B"); + + assertTrue(orSet1.compare(orSet2)); + } + + @Test + void testCompareDifferentSets() { + ORSet<String> orSet1 = new ORSet<>(); + ORSet<String> orSet2 = new ORSet<>(); + + orSet1.add("A"); + orSet2.add("B"); + + assertFalse(orSet1.compare(orSet2)); + } + + @Test + void testMerge() { + ORSet<String> orSet1 = new ORSet<>(); + ORSet<String> orSet2 = new ORSet<>(); + + orSet1.add("A"); + orSet1.add("A"); + orSet1.add("B"); + orSet1.remove("B"); + orSet2.add("B"); + orSet2.add("C"); + orSet2.remove("C"); + orSet1.merge(orSet2); + + assertTrue(orSet1.contains("A")); + assertTrue(orSet1.contains("B")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java b/Java/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java new file mode 100644 index 000000000000..4081b8ae01d8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java @@ -0,0 +1,56 @@ +package com.thealgorithms.datastructures.crdt; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class PNCounterTest { + + @Test + public void testIncrement() { + PNCounter counter = new PNCounter(0, 3); + counter.increment(); + assertEquals(1, counter.value()); + } + + @Test + public void testDecrement() { + PNCounter counter = new PNCounter(0, 3); + counter.decrement(); + assertEquals(-1, counter.value()); + } + + @Test + public void testIncrementAndDecrement() { + PNCounter counter = new PNCounter(0, 3); + counter.increment(); + counter.increment(); + counter.decrement(); + assertEquals(1, counter.value()); + } + + @Test + public void testCompare() { + PNCounter counter1 = new PNCounter(0, 3); + counter1.increment(); + PNCounter counter2 = new PNCounter(1, 3); + assertTrue(counter1.compare(counter2)); + counter2.increment(); + assertTrue(counter2.compare(counter1)); + counter1.decrement(); + assertFalse(counter1.compare(counter2)); + } + + @Test + public void testMerge() { + PNCounter counter1 = new PNCounter(0, 3); + counter1.increment(); + counter1.increment(); + PNCounter counter2 = new PNCounter(1, 3); + counter2.increment(); + counter1.merge(counter2); + assertEquals(3, counter1.value()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java b/Java/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java new file mode 100644 index 000000000000..dfe392a0d616 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.datastructures.crdt; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class TwoPSetTest { + + private TwoPSet<String> set; + + @BeforeEach + void setUp() { + set = new TwoPSet<>(); + } + + @Test + void testLookup() { + set.add("A"); + assertTrue(set.lookup("A")); + assertFalse(set.lookup("B")); + set.remove("A"); + assertFalse(set.lookup("A")); + } + + @Test + void testAdd() { + set.add("A"); + assertTrue(set.lookup("A")); + } + + @Test + void testRemove() { + set.add("A"); + set.remove("A"); + assertFalse(set.lookup("A")); + } + + @Test + void testCompare() { + TwoPSet<String> set1 = new TwoPSet<>(); + set1.add("A"); + set1.add("B"); + TwoPSet<String> set2 = new TwoPSet<>(); + set2.add("A"); + assertFalse(set1.compare(set2)); + set2.add("B"); + assertTrue(set1.compare(set2)); + set1.remove("A"); + assertFalse(set1.compare(set2)); + set2.remove("A"); + assertTrue(set1.compare(set2)); + } + + @Test + void testMerge() { + TwoPSet<String> set1 = new TwoPSet<>(); + set1.add("A"); + set1.add("B"); + TwoPSet<String> set2 = new TwoPSet<>(); + set2.add("B"); + set2.add("C"); + TwoPSet<String> mergedSet = set1.merge(set2); + assertTrue(mergedSet.lookup("A")); + assertTrue(mergedSet.lookup("B")); + assertTrue(mergedSet.lookup("C")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java b/Java/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java new file mode 100644 index 000000000000..a10a99d40496 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/disjointsetunion/DisjointSetUnionTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.datastructures.disjointsetunion; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DisjointSetUnionTest { + + @Test + public void testMakeSet() { + DisjointSetUnion<Integer> dsu = new DisjointSetUnion<>(); + Node<Integer> node = dsu.makeSet(1); + assertNotNull(node); + Assertions.assertEquals(node, node.parent); + } + + @Test + public void testUnionFindSet() { + DisjointSetUnion<Integer> dsu = new DisjointSetUnion<>(); + Node<Integer> node1 = dsu.makeSet(1); + Node<Integer> node2 = dsu.makeSet(2); + Node<Integer> node3 = dsu.makeSet(3); + Node<Integer> node4 = dsu.makeSet(4); + + dsu.unionSets(node1, node2); + dsu.unionSets(node3, node2); + dsu.unionSets(node3, node4); + dsu.unionSets(node1, node3); + + Node<Integer> root1 = dsu.findSet(node1); + Node<Integer> root2 = dsu.findSet(node2); + Node<Integer> root3 = dsu.findSet(node3); + Node<Integer> root4 = dsu.findSet(node4); + + Assertions.assertEquals(node1, node1.parent); + Assertions.assertEquals(node1, node2.parent); + Assertions.assertEquals(node1, node3.parent); + Assertions.assertEquals(node1, node4.parent); + + Assertions.assertEquals(node1, root1); + Assertions.assertEquals(node1, root2); + Assertions.assertEquals(node1, root3); + Assertions.assertEquals(node1, root4); + + Assertions.assertEquals(1, node1.rank); + Assertions.assertEquals(0, node2.rank); + Assertions.assertEquals(0, node3.rank); + Assertions.assertEquals(0, node4.rank); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java b/Java/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java new file mode 100644 index 000000000000..579e236699b3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java @@ -0,0 +1,193 @@ +package com.thealgorithms.datastructures.graphs; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.datastructures.graphs.BoruvkaAlgorithm.Graph; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class BoruvkaAlgorithmTest { + @Test + public void testBoruvkaMSTV9E14() { + List<BoruvkaAlgorithm.Edge> edges = new ArrayList<>(); + + edges.add(new BoruvkaAlgorithm.Edge(0, 1, 10)); + edges.add(new BoruvkaAlgorithm.Edge(0, 2, 12)); + edges.add(new BoruvkaAlgorithm.Edge(1, 2, 9)); + edges.add(new BoruvkaAlgorithm.Edge(1, 3, 8)); + edges.add(new BoruvkaAlgorithm.Edge(2, 4, 3)); + edges.add(new BoruvkaAlgorithm.Edge(2, 5, 1)); + edges.add(new BoruvkaAlgorithm.Edge(4, 5, 3)); + edges.add(new BoruvkaAlgorithm.Edge(4, 3, 7)); + edges.add(new BoruvkaAlgorithm.Edge(3, 6, 8)); + edges.add(new BoruvkaAlgorithm.Edge(3, 7, 5)); + edges.add(new BoruvkaAlgorithm.Edge(5, 7, 6)); + edges.add(new BoruvkaAlgorithm.Edge(6, 7, 9)); + edges.add(new BoruvkaAlgorithm.Edge(6, 8, 2)); + edges.add(new BoruvkaAlgorithm.Edge(7, 8, 11)); + + final var graph = new Graph(9, edges); + /** + * Adjacency matrix + * 0 1 2 3 4 5 6 7 8 + * 0 0 10 12 0 0 0 0 0 0 + * 1 10 0 9 8 0 0 0 0 0 + * 2 12 9 0 0 3 1 0 0 0 + * 3 0 8 0 0 7 0 8 5 0 + * 4 0 0 3 7 0 3 0 0 0 + * 5 0 0 1 0 3 0 0 6 0 + * 6 0 0 0 8 0 0 0 9 2 + * 7 0 0 0 5 0 6 9 0 11 + * 8 0 0 0 0 0 0 2 11 0 + */ + final var result = BoruvkaAlgorithm.boruvkaMST(graph); + assertEquals(8, result.size()); + assertEquals(43, computeTotalWeight(result)); + } + + @Test + void testBoruvkaMSTV2E1() { + List<BoruvkaAlgorithm.Edge> edges = new ArrayList<>(); + + edges.add(new BoruvkaAlgorithm.Edge(0, 1, 10)); + + final var graph = new Graph(2, edges); + + /** + * Adjacency matrix + * 0 1 + * 0 0 10 + * 1 10 0 + */ + final var result = BoruvkaAlgorithm.boruvkaMST(graph); + assertEquals(1, result.size()); + assertEquals(10, computeTotalWeight(result)); + } + + @Test + void testCompleteGraphK4() { + List<BoruvkaAlgorithm.Edge> edges = new ArrayList<>(); + edges.add(new BoruvkaAlgorithm.Edge(0, 1, 7)); + edges.add(new BoruvkaAlgorithm.Edge(0, 2, 2)); + edges.add(new BoruvkaAlgorithm.Edge(0, 3, 5)); + edges.add(new BoruvkaAlgorithm.Edge(1, 2, 3)); + edges.add(new BoruvkaAlgorithm.Edge(1, 3, 4)); + edges.add(new BoruvkaAlgorithm.Edge(2, 3, 1)); + + final var graph = new Graph(4, edges); + + /** + * Adjacency matrix + * 0 1 2 3 + * 0 0 7 2 5 + * 1 7 0 3 4 + * 2 2 3 0 1 + * 3 5 4 1 0 + */ + final var result = BoruvkaAlgorithm.boruvkaMST(graph); + assertEquals(3, result.size()); + assertEquals(6, computeTotalWeight(result)); + } + + @Test + void testNegativeVertices() { + Exception exception1 = assertThrows(IllegalArgumentException.class, () -> new Graph(-1, null)); + String expectedMessage = "Number of vertices must be positive"; + String actualMessage = exception1.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + void testEdgesNull() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> new Graph(0, null)); + String expectedMessage = "Edges list must not be null or empty"; + String actualMessage = exception.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + void testEdgesEmpty() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> new Graph(0, new ArrayList<>())); + String expectedMessage = "Edges list must not be null or empty"; + String actualMessage = exception.getMessage(); + + assertTrue(actualMessage.contains(expectedMessage)); + } + + @Test + void testEdgesRange() { + // Valid input + List<BoruvkaAlgorithm.Edge> validEdges = new ArrayList<>(); + validEdges.add(new BoruvkaAlgorithm.Edge(0, 1, 2)); + validEdges.add(new BoruvkaAlgorithm.Edge(1, 2, 3)); + final var validGraph = new BoruvkaAlgorithm.Graph(3, validEdges); + assertEquals(validEdges, validGraph.edges); + + // Edge source out of range + Exception exception1 = assertThrows(IllegalArgumentException.class, () -> { + List<BoruvkaAlgorithm.Edge> invalidEdges = new ArrayList<>(); + invalidEdges.add(new BoruvkaAlgorithm.Edge(-1, 1, 2)); + final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges); + assertEquals(invalidEdges, invalidGraph.edges); + }); + String expectedMessage1 = "Edge vertex out of range"; + String actualMessage1 = exception1.getMessage(); + + assertTrue(actualMessage1.contains(expectedMessage1)); + + // Edge source out of range + Exception exception2 = assertThrows(IllegalArgumentException.class, () -> { + List<BoruvkaAlgorithm.Edge> invalidEdges = new ArrayList<>(); + invalidEdges.add(new BoruvkaAlgorithm.Edge(1, 0, 2)); + final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges); + assertEquals(invalidEdges, invalidGraph.edges); + }); + String expectedMessage2 = "Edge vertex out of range"; + String actualMessage2 = exception2.getMessage(); + + assertTrue(actualMessage2.contains(expectedMessage2)); + + // Edge destination out of range + Exception exception3 = assertThrows(IllegalArgumentException.class, () -> { + List<BoruvkaAlgorithm.Edge> invalidEdges = new ArrayList<>(); + invalidEdges.add(new BoruvkaAlgorithm.Edge(0, -1, 2)); + final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges); + assertEquals(invalidEdges, invalidGraph.edges); + }); + String expectedMessage3 = "Edge vertex out of range"; + String actualMessage3 = exception3.getMessage(); + + assertTrue(actualMessage3.contains(expectedMessage3)); + + // Edge destination out of range + Exception exception4 = assertThrows(IllegalArgumentException.class, () -> { + List<BoruvkaAlgorithm.Edge> invalidEdges = new ArrayList<>(); + invalidEdges.add(new BoruvkaAlgorithm.Edge(0, 1, 2)); + final var invalidGraph = new BoruvkaAlgorithm.Graph(1, invalidEdges); + assertEquals(invalidEdges, invalidGraph.edges); + }); + String expectedMessage4 = "Edge vertex out of range"; + String actualMessage4 = exception4.getMessage(); + + assertTrue(actualMessage4.contains(expectedMessage4)); + } + + /** + * Computes the total weight of the Minimum Spanning Tree + * + * @param result list of edges in the Minimum Spanning Tree + * @return the total weight of the Minimum Spanning Tree + */ + int computeTotalWeight(final List<BoruvkaAlgorithm.Edge> result) { + int totalWeight = 0; + for (final var edge : result) { + totalWeight += edge.weight; + } + return totalWeight; + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java b/Java/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java new file mode 100644 index 000000000000..ed7c886d784e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.datastructures.graphs; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class HamiltonianCycleTest { + + private HamiltonianCycle hamiltonianCycle = new HamiltonianCycle(); + + @Test + void testFindHamiltonianCycleShouldReturnHamiltonianCycle() { + int[] expectedArray = {0, 1, 2, 4, 3, 0}; + int[][] inputArray = { + {0, 1, 0, 1, 0}, + {1, 0, 1, 1, 1}, + {0, 1, 0, 0, 1}, + {1, 1, 0, 0, 1}, + {0, 1, 1, 1, 0}, + }; + + assertArrayEquals(expectedArray, hamiltonianCycle.findHamiltonianCycle(inputArray)); + } + + @Test + void testFindHamiltonianCycleShouldReturnInfinityArray() { + int[] expectedArray = {-1, -1, -1, -1, -1, -1}; + + int[][] inputArray = { + {0, 1, 0, 1, 0}, + {1, 0, 1, 1, 1}, + {0, 1, 0, 0, 1}, + {1, 1, 0, 0, 0}, + {0, 1, 1, 0, 0}, + }; + + assertArrayEquals(expectedArray, hamiltonianCycle.findHamiltonianCycle(inputArray)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java b/Java/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java new file mode 100644 index 000000000000..c1e68acac2e6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java @@ -0,0 +1,79 @@ +package com.thealgorithms.datastructures.graphs; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class KosarajuTest { + + private Kosaraju kosaraju = new Kosaraju(); + + @Test + public void findStronglyConnectedComps() { + // Create a adjacency list of graph + var n = 8; + var adjList = new ArrayList<List<Integer>>(n); + + for (int i = 0; i < n; i++) { + adjList.add(new ArrayList<>()); + } + + adjList.get(0).add(1); + adjList.get(1).add(2); + adjList.get(2).add(0); + adjList.get(2).add(3); + adjList.get(3).add(4); + adjList.get(4).add(5); + adjList.get(4).add(7); + adjList.get(5).add(6); + adjList.get(6).add(4); + adjList.get(6).add(7); + + List<List<Integer>> actualResult = kosaraju.kosaraju(n, adjList); + List<List<Integer>> expectedResult = new ArrayList<>(); + /* + Expected result: + 0, 1, 2 + 3 + 5, 4, 6 + 7 + */ + expectedResult.add(Arrays.asList(1, 2, 0)); + expectedResult.add(Arrays.asList(3)); + expectedResult.add(Arrays.asList(5, 6, 4)); + expectedResult.add(Arrays.asList(7)); + assertTrue(expectedResult.equals(actualResult)); + } + + @Test + public void findStronglyConnectedCompsShouldGetSingleNodes() { + // Create a adjacency list of graph + var n = 8; + var adjList = new ArrayList<List<Integer>>(n); + + for (int i = 0; i < n; i++) { + adjList.add(new ArrayList<>()); + } + + adjList.get(0).add(1); + adjList.get(1).add(2); + adjList.get(2).add(3); + adjList.get(3).add(4); + adjList.get(4).add(5); + adjList.get(5).add(6); + adjList.get(6).add(7); + adjList.get(7).add(0); + + List<List<Integer>> actualResult = kosaraju.kosaraju(n, adjList); + List<List<Integer>> expectedResult = new ArrayList<>(); + /* + Expected result: + 0, 1, 2, 3, 4, 5, 6, 7 + */ + expectedResult.add(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 0)); + assertTrue(expectedResult.equals(actualResult)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java b/Java/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java new file mode 100644 index 000000000000..dc81d99dd0bf --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java @@ -0,0 +1,70 @@ +package com.thealgorithms.datastructures.graphs; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class TarjansAlgorithmTest { + + TarjansAlgorithm tarjansAlgo = new TarjansAlgorithm(); + + @Test + public void findStronglyConnectedComps() { + var v = 5; + var graph = new ArrayList<List<Integer>>(); + for (int i = 0; i < v; i++) { + graph.add(new ArrayList<>()); + } + graph.get(0).add(1); + graph.get(1).add(2); + graph.get(2).add(0); + graph.get(1).add(3); + graph.get(3).add(4); + + var actualResult = tarjansAlgo.stronglyConnectedComponents(v, graph); + /* + Expected result: + 0, 1, 2 + 3 + 4 + */ + List<List<Integer>> expectedResult = new ArrayList<>(); + + expectedResult.add(Arrays.asList(4)); + expectedResult.add(Arrays.asList(3)); + expectedResult.add(Arrays.asList(2, 1, 0)); + assertTrue(expectedResult.equals(actualResult)); + } + + @Test + public void findStronglyConnectedCompsShouldGetSingleNodes() { + // Create a adjacency list of graph + var n = 8; + var adjList = new ArrayList<List<Integer>>(n); + + for (int i = 0; i < n; i++) { + adjList.add(new ArrayList<>()); + } + + adjList.get(0).add(1); + adjList.get(1).add(2); + adjList.get(2).add(3); + adjList.get(3).add(4); + adjList.get(4).add(5); + adjList.get(5).add(6); + adjList.get(6).add(7); + adjList.get(7).add(0); + + List<List<Integer>> actualResult = tarjansAlgo.stronglyConnectedComponents(n, adjList); + List<List<Integer>> expectedResult = new ArrayList<>(); + /* + Expected result: + 7, 6, 5, 4, 3, 2, 1, 0 + */ + expectedResult.add(Arrays.asList(7, 6, 5, 4, 3, 2, 1, 0)); + assertTrue(expectedResult.equals(actualResult)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java b/Java/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java new file mode 100644 index 000000000000..b37657db5c05 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java @@ -0,0 +1,124 @@ +package com.thealgorithms.datastructures.graphs; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.datastructures.graphs.WelshPowell.Graph; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class WelshPowellTest { + + @Test + void testSimpleGraph() { + final var graph = WelshPowell.makeGraph(4, new int[][] {{0, 1}, {1, 2}, {2, 3}}); + int[] colors = WelshPowell.findColoring(graph); + assertTrue(isColoringValid(graph, colors)); + assertEquals(2, countDistinctColors(colors)); + } + + @Test + void testDisconnectedGraph() { + final var graph = WelshPowell.makeGraph(3, new int[][] {}); // No edges + int[] colors = WelshPowell.findColoring(graph); + assertTrue(isColoringValid(graph, colors)); + assertEquals(1, countDistinctColors(colors)); + } + + @Test + void testCompleteGraph() { + final var graph = WelshPowell.makeGraph(3, new int[][] {{0, 1}, {1, 2}, {2, 0}}); + int[] colors = WelshPowell.findColoring(graph); + assertTrue(isColoringValid(graph, colors)); + assertEquals(3, countDistinctColors(colors)); + } + + // The following test originates from the following website : https://www.geeksforgeeks.org/welsh-powell-graph-colouring-algorithm/ + @Test + void testComplexGraph() { + int[][] edges = { + {0, 7}, // A-H + {0, 1}, // A-B + {1, 3}, // B-D + {2, 3}, // C-D + {3, 8}, // D-I + {3, 10}, // D-K + {4, 10}, // E-K + {4, 5}, // E-F + {5, 6}, // F-G + {6, 10}, // G-K + {6, 7}, // G-H + {7, 8}, // H-I + {7, 9}, // H-J + {7, 10}, // H-K + {8, 9}, // I-J + {9, 10}, // J-K + }; + + final var graph = WelshPowell.makeGraph(11, edges); // 11 vertices from A (0) to K (10) + int[] colors = WelshPowell.findColoring(graph); + + assertTrue(isColoringValid(graph, colors), "The coloring should be valid with no adjacent vertices sharing the same color."); + assertEquals(3, countDistinctColors(colors), "The chromatic number of the graph should be 3."); + } + + @Test + void testNegativeVertices() { + assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(-1, new int[][] {}); }, "Number of vertices cannot be negative"); + } + + @Test + void testSelfLoop() { + assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0, 0}}); }, "Self-loops are not allowed"); + } + + @Test + void testInvalidVertex() { + assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0, 3}}); }, "Vertex out of bounds"); + assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0, -1}}); }, "Vertex out of bounds"); + } + + @Test + void testInvalidEdgeArray() { + assertThrows(IllegalArgumentException.class, () -> { WelshPowell.makeGraph(3, new int[][] {{0}}); }, "Edge array must have exactly two elements"); + } + + @Test + void testWithPreColoredVertex() { + // Create a linear graph with 4 vertices and edges connecting them in sequence + final var graph = WelshPowell.makeGraph(4, new int[][] {{0, 1}, {1, 2}, {2, 3}}); + + // Apply the Welsh-Powell coloring algorithm to the graph + int[] colors = WelshPowell.findColoring(graph); + + // Validate that the coloring is correct (no two adjacent vertices have the same color) + assertTrue(isColoringValid(graph, colors)); + + // Check if the algorithm has used at least 2 colors (expected for a linear graph) + assertTrue(countDistinctColors(colors) >= 2); + + // Verify that all vertices have been assigned a color + for (int color : colors) { + assertTrue(color >= 0); + } + } + + private boolean isColoringValid(Graph graph, int[] colors) { + if (Arrays.stream(colors).anyMatch(n -> n < 0)) { + return false; + } + for (int i = 0; i < graph.getNumVertices(); i++) { + for (int neighbor : graph.getAdjacencyList(i)) { + if (i != neighbor && colors[i] == colors[neighbor]) { + return false; // Adjacent vertices have the same color + } + } + } + return true; // No adjacent vertices share the same color + } + + private int countDistinctColors(int[] colors) { + return (int) Arrays.stream(colors).distinct().count(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java new file mode 100644 index 000000000000..14bddeae1c91 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java @@ -0,0 +1,94 @@ +package com.thealgorithms.datastructures.hashmap; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +import com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing; +import org.junit.jupiter.api.Test; + +class HashMapCuckooHashingTest { + + @Test + void insertKey() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + assertEquals(0, hashTable.getNumberOfKeysInTable()); + + hashTable.insertKey2HashTable(3); + + assertEquals(1, hashTable.getNumberOfKeysInTable()); + } + + @Test + void getKeyIndex() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + hashTable.insertKey2HashTable(8); + hashTable.insertKey2HashTable(4); + + assertNotEquals(-1, hashTable.findKeyInTable(8)); + } + + @Test + void containsKey() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + hashTable.insertKey2HashTable(8); + boolean contains = hashTable.checkTableContainsKey(8); + + assertTrue(contains); + } + + @Test + void removeKey() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + hashTable.insertKey2HashTable(3); + + int initialSize = hashTable.getNumberOfKeysInTable(); + + hashTable.deleteKeyFromHashTable(3); + + assertEquals(initialSize - 1, hashTable.getNumberOfKeysInTable()); + } + + @Test + void removeNone() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + try { + hashTable.deleteKeyFromHashTable(3); + } catch (Exception e) { + assertTrue(true); + return; + } + fail(); + } + + @Test + void reHashTableIncreasesTableSize() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + int initialSize = hashTable.getNumberOfKeysInTable(); + + hashTable.reHashTableIncreasesTableSize(); + + assertEquals(initialSize * 2, hashTable.getNumberOfKeysInTable()); + } + + @Test + void hashFunctionsAreDifferent() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + hashTable.insertKey2HashTable(33); + + assertNotEquals(hashTable.hashFunction1(3), hashTable.hashFunction2(3)); + } + + @Test + void avoidInfiniteLoops() { + HashMapCuckooHashing hashTable = new HashMapCuckooHashing(10); + hashTable.insertKey2HashTable(0); + hashTable.insertKey2HashTable(10); + hashTable.insertKey2HashTable(100); + + assertTrue(hashTable.checkTableContainsKey(0)); + assertTrue(hashTable.checkTableContainsKey(10)); + assertTrue(hashTable.checkTableContainsKey(100)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java new file mode 100644 index 000000000000..37e43d2aada3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class GenericHashMapUsingArrayListTest { + + @Test + void testGenericHashmapWhichUsesArrayAndBothKeyAndValueAreStrings() { + GenericHashMapUsingArrayList<String, String> map = new GenericHashMapUsingArrayList<>(); + map.put("USA", "Washington DC"); + map.put("Nepal", "Kathmandu"); + map.put("India", "New Delhi"); + map.put("Australia", "Sydney"); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals("Kathmandu", map.get("Nepal")); + assertEquals("Sydney", map.get("Australia")); + } + + @Test + void testGenericHashmapWhichUsesArrayAndKeyIsStringValueIsInteger() { + GenericHashMapUsingArrayList<String, Integer> map = new GenericHashMapUsingArrayList<>(); + map.put("USA", 87); + map.put("Nepal", 25); + map.put("India", 101); + map.put("Australia", 99); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals(25, map.get("Nepal")); + assertEquals(99, map.get("Australia")); + map.remove("Nepal"); + assertFalse(map.containsKey("Nepal")); + } + + @Test + void testGenericHashmapWhichUsesArrayAndKeyIsIntegerValueIsString() { + GenericHashMapUsingArrayList<Integer, String> map = new GenericHashMapUsingArrayList<>(); + map.put(101, "Washington DC"); + map.put(34, "Kathmandu"); + map.put(46, "New Delhi"); + map.put(89, "Sydney"); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals("Sydney", map.get(89)); + assertEquals("Washington DC", map.get(101)); + assertTrue(map.containsKey(46)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java new file mode 100644 index 000000000000..483e43bb5cb3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class GenericHashMapUsingArrayTest { + + @Test + void testGenericHashmapWhichUsesArrayAndBothKeyAndValueAreStrings() { + GenericHashMapUsingArray<String, String> map = new GenericHashMapUsingArray<>(); + map.put("USA", "Washington DC"); + map.put("Nepal", "Kathmandu"); + map.put("India", "New Delhi"); + map.put("Australia", "Sydney"); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals("Kathmandu", map.get("Nepal")); + assertEquals("Sydney", map.get("Australia")); + } + + @Test + void testGenericHashmapWhichUsesArrayAndKeyIsStringValueIsInteger() { + GenericHashMapUsingArray<String, Integer> map = new GenericHashMapUsingArray<>(); + map.put("USA", 87); + map.put("Nepal", 25); + map.put("India", 101); + map.put("Australia", 99); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals(25, map.get("Nepal")); + assertEquals(99, map.get("Australia")); + map.remove("Nepal"); + assertFalse(map.containsKey("Nepal")); + } + + @Test + void testGenericHashmapWhichUsesArrayAndKeyIsIntegerValueIsString() { + GenericHashMapUsingArray<Integer, String> map = new GenericHashMapUsingArray<>(); + map.put(101, "Washington DC"); + map.put(34, "Kathmandu"); + map.put(46, "New Delhi"); + map.put(89, "Sydney"); + assertNotNull(map); + assertEquals(4, map.size()); + assertEquals("Sydney", map.get(89)); + assertEquals("Washington DC", map.get(101)); + assertTrue(map.containsKey(46)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java new file mode 100644 index 000000000000..d0a72a1509ee --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/LinearProbingHashMapTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +class LinearProbingHashMapTest extends MapTest { + @Override + <Key extends Comparable<Key>, Value> Map<Key, Value> getMap() { + return new LinearProbingHashMap<>(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java new file mode 100644 index 000000000000..49133ba5ffb5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java @@ -0,0 +1,45 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class MajorityElementTest { + @Test + void testMajorityWithSingleMajorityElement() { + int[] nums = {1, 2, 3, 9, 9, 6, 7, 8, 9, 9, 9, 9}; + List<Integer> expected = new ArrayList<>(); + expected.add(9); + List<Integer> actual = MajorityElement.majority(nums); + assertEquals(expected, actual); + } + + @Test + void testMajorityWithMultipleMajorityElements() { + int[] nums = {1, 2, 3, 3, 4, 4, 4, 4}; + List<Integer> expected = new ArrayList<>(); + expected.add(4); + List<Integer> actual = MajorityElement.majority(nums); + assertEquals(expected, actual); + } + + @Test + void testMajorityWithNoMajorityElement() { + int[] nums = {1, 2, 4, 4, 5, 4}; + List<Integer> expected = new ArrayList<>(); + expected.add(4); + List<Integer> actual = MajorityElement.majority(nums); + assertEquals(expected, actual); + } + + @Test + void testMajorityWithEmptyArray() { + int[] nums = {}; + List<Integer> expected = Collections.emptyList(); + List<Integer> actual = MajorityElement.majority(nums); + assertEquals(expected, actual); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java new file mode 100644 index 000000000000..44551a8adac6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java @@ -0,0 +1,131 @@ +package com.thealgorithms.datastructures.hashmap.hashing; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Random; +import org.junit.jupiter.api.Test; + +abstract class MapTest { + abstract <Key extends Comparable<Key>, Value> Map<Key, Value> getMap(); + + @Test + void putTest() { + Map<Integer, String> map = getMap(); + + assertFalse(map.put(null, "-25")); + assertFalse(map.put(null, null)); + assertTrue(map.put(-25, "-25")); + assertTrue(map.put(33, "33")); + assertTrue(map.put(100, "100")); + assertTrue(map.put(100, "+100")); + assertTrue(map.put(100, null)); + } + + @Test + void getTest() { + Map<Integer, String> map = getMap(); + for (int i = -100; i < 100; i++) { + map.put(i, String.valueOf(i)); + } + + for (int i = -100; i < 100; i++) { + assertEquals(map.get(i), String.valueOf(i)); + } + + for (int i = 100; i < 200; i++) { + assertNull(map.get(i)); + } + + assertNull(map.get(null)); + } + + @Test + void deleteTest() { + Map<Integer, String> map = getMap(); + for (int i = -100; i < 100; i++) { + map.put(i, String.valueOf(i)); + } + + for (int i = 0; i < 100; i++) { + assertTrue(map.delete(i)); + } + + for (int i = 100; i < 200; i++) { + assertFalse(map.delete(i)); + } + + assertFalse(map.delete(null)); + } + + @Test + void containsTest() { + Map<Integer, String> map = getMap(); + for (int i = -100; i < 100; i++) { + map.put(i, String.valueOf(i)); + } + + for (int i = -50; i < 50; i++) { + assertTrue(map.contains(i)); + } + + for (int i = 100; i < 200; i++) { + assertFalse(map.contains(i)); + } + + assertFalse(map.contains(null)); + } + + @Test + void sizeTest() { + Map<Integer, String> map = getMap(); + assertEquals(map.size(), 0); + + for (int i = -100; i < 100; i++) { + map.put(i, String.valueOf(i)); + } + + assertEquals(map.size(), 200); + + for (int i = -50; i < 50; i++) { + map.delete(i); + } + + assertEquals(map.size(), 100); + } + + @Test + void keysTest() { + Map<Integer, String> map = getMap(); + Iterable<Integer> keys = map.keys(); + assertFalse(keys.iterator().hasNext()); + + for (int i = 100; i > -100; i--) { + map.put(i, String.valueOf(i)); + } + + keys = map.keys(); + int i = -100; + for (Integer key : keys) { + assertEquals(key, ++i); + } + } + + @Test + void hashTest() { + Map<Integer, String> map = getMap(); + int testSize = 100; + Random random = new Random(); + for (int i = 0; i < 1000; i++) { + int randomInt = random.nextInt(); + int hashIndex = map.hash(randomInt, testSize); + int negateHashIndex = map.hash(-randomInt, testSize); + assertTrue(hashIndex >= 0); + assertTrue(hashIndex < testSize); + assertTrue(negateHashIndex >= 0); + assertTrue(negateHashIndex < testSize); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java b/Java/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java new file mode 100644 index 000000000000..b414bab2b8a0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/heaps/FibonacciHeapTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.datastructures.heaps; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class FibonacciHeapTest { + + @Test + void testHeap() { + FibonacciHeap fibonacciHeap = new FibonacciHeap(); + fibonacciHeap.insert(5); + fibonacciHeap.insert(3); + fibonacciHeap.insert(1); + fibonacciHeap.insert(18); + fibonacciHeap.insert(33); + + Assertions.assertEquals(fibonacciHeap.findMin().getKey(), 1); + fibonacciHeap.deleteMin(); + Assertions.assertEquals(fibonacciHeap.findMin().getKey(), 3); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java b/Java/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java new file mode 100644 index 000000000000..f4c4c548ffbf --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.datastructures.heaps; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LeftistHeapTest { + + @Test + void testLeftistHeap() { + LeftistHeap heap = new LeftistHeap(); + Assertions.assertTrue(heap.isEmpty()); + heap.insert(6); + Assertions.assertTrue(!heap.isEmpty()); + heap.insert(2); + heap.insert(3); + heap.insert(1); + heap.inOrder(); + Assertions.assertTrue(heap.inOrder().toString().equals("[6, 2, 3, 1]")); + Assertions.assertTrue(heap.extractMin() == 1); + Assertions.assertTrue(heap.inOrder().toString().equals("[6, 2, 3]")); + heap.insert(8); + heap.insert(12); + heap.insert(4); + Assertions.assertTrue(heap.inOrder().toString().equals("[8, 3, 12, 2, 6, 4]")); + heap.clear(); + Assertions.assertTrue(heap.isEmpty()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java b/Java/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java new file mode 100644 index 000000000000..c4113b787de9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java @@ -0,0 +1,67 @@ +package com.thealgorithms.datastructures.lists; + +/** + * Test cases for QuickSortLinkedList + * Author: Prabhat-Kumar-42 + * GitHub: https://github.com/Prabhat-Kumar-42 + */ + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +public class QuickSortLinkedListTest { + + @Test + public void testSortEmptyList() { + SinglyLinkedList emptyList = new SinglyLinkedList(); + QuickSortLinkedList sorter = new QuickSortLinkedList(emptyList); + + // Test case: Sorting an empty list should result in an empty list + sorter.sortList(); + assertNull(emptyList.getHead()); + } + + @Test + public void testSortSingleNodeList() { + SinglyLinkedList singleNodeList = new SinglyLinkedList(); + singleNodeList.insert(5); + QuickSortLinkedList sorter = new QuickSortLinkedList(singleNodeList); + + // Test case: Sorting a list with a single node should result in the same list + sorter.sortList(); + assertEquals(5, singleNodeList.getHead().value); + assertNull(singleNodeList.getHead().next); + } + + @Test + public void testSortMultipleElementsList() { + SinglyLinkedList list = new SinglyLinkedList(); + list.insert(5); + list.insert(3); + list.insert(8); + list.insert(1); + list.insert(10); + list.insert(2); + list.insert(7); + list.insert(4); + list.insert(9); + list.insert(6); + QuickSortLinkedList sorter = new QuickSortLinkedList(list); + + // Test case: Sorting a list with multiple elements + sorter.sortList(); + assertEquals(1, list.getHead().value); + assertEquals(2, list.getHead().next.value); + assertEquals(3, list.getHead().next.next.value); + assertEquals(4, list.getHead().next.next.next.value); + assertEquals(5, list.getHead().next.next.next.next.value); + assertEquals(6, list.getHead().next.next.next.next.next.value); + assertEquals(7, list.getHead().next.next.next.next.next.next.value); + assertEquals(8, list.getHead().next.next.next.next.next.next.next.value); + assertEquals(9, list.getHead().next.next.next.next.next.next.next.next.value); + assertEquals(10, list.getHead().next.next.next.next.next.next.next.next.next.value); + assertNull(list.getHead().next.next.next.next.next.next.next.next.next.next); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java b/Java/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java new file mode 100644 index 000000000000..c03f5b14c641 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java @@ -0,0 +1,73 @@ +package com.thealgorithms.datastructures.lists; + +/** + * Test cases for Reverse K Group LinkedList + * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +public class ReverseKGroupTest { + + @Test + public void testReverseKGroupWithEmptyList() { + ReverseKGroup reverser = new ReverseKGroup(); + assertNull(reverser.reverseKGroup(null, 3)); + } + + @Test + public void testReverseKGroupWithSingleNodeList() { + ReverseKGroup reverser = new ReverseKGroup(); + Node singleNode = new Node(5); + Node result = reverser.reverseKGroup(singleNode, 2); + assertEquals(5, result.value); + assertNull(result.next); + } + + @Test + public void testReverseKGroupWithKEqualTo2() { + ReverseKGroup reverser = new ReverseKGroup(); + + // Create a list with multiple elements (1 -> 2 -> 3 -> 4 -> 5) + Node head; + head = new Node(1); + head.next = new Node(2); + head.next.next = new Node(3); + head.next.next.next = new Node(4); + head.next.next.next.next = new Node(5); + + // Test reverse with k=2 + Node result1 = reverser.reverseKGroup(head, 2); + assertEquals(2, result1.value); + assertEquals(1, result1.next.value); + assertEquals(4, result1.next.next.value); + assertEquals(3, result1.next.next.next.value); + assertEquals(5, result1.next.next.next.next.value); + assertNull(result1.next.next.next.next.next); + } + + @Test + public void testReverseKGroupWithKEqualTo3() { + ReverseKGroup reverser = new ReverseKGroup(); + + // Create a list with multiple elements (1 -> 2 -> 3 -> 4 -> 5) + Node head; + head = new Node(1); + head.next = new Node(2); + head.next.next = new Node(3); + head.next.next.next = new Node(4); + head.next.next.next.next = new Node(5); + + // Test reverse with k=3 + Node result = reverser.reverseKGroup(head, 3); + assertEquals(3, result.value); + assertEquals(2, result.next.value); + assertEquals(1, result.next.next.value); + assertEquals(4, result.next.next.next.value); + assertEquals(5, result.next.next.next.next.value); + assertNull(result.next.next.next.next.next); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java b/Java/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java new file mode 100644 index 000000000000..d3c020f8881b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java @@ -0,0 +1,73 @@ +package com.thealgorithms.datastructures.lists; + +/** + * Test cases for RotateSinglyLinkedLists + * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import org.junit.jupiter.api.Test; + +public class RotateSinglyLinkedListsTest { + + @Test + public void testRotateRightEmptyList() { + RotateSinglyLinkedLists rotator = new RotateSinglyLinkedLists(); + + // Test case: Rotate an empty list + assertNull(rotator.rotateRight(null, 2)); + } + + @Test + public void testRotateRightSingleNodeList() { + RotateSinglyLinkedLists rotator = new RotateSinglyLinkedLists(); + + // Test case: Rotate a list with one element + Node singleNode = new Node(5); + Node rotatedSingleNode = rotator.rotateRight(singleNode, 3); + assertEquals(5, rotatedSingleNode.value); + assertNull(rotatedSingleNode.next); + } + + @Test + public void testRotateRightMultipleElementsList() { + RotateSinglyLinkedLists rotator = new RotateSinglyLinkedLists(); + + // Test case: Rotate a list with multiple elements (Rotate by 2) + Node head = new Node(1); + head.next = new Node(2); + head.next.next = new Node(3); + head.next.next.next = new Node(4); + head.next.next.next.next = new Node(5); + + Node rotated1 = rotator.rotateRight(head, 2); + assertEquals(4, rotated1.value); + assertEquals(5, rotated1.next.value); + assertEquals(1, rotated1.next.next.value); + assertEquals(2, rotated1.next.next.next.value); + assertEquals(3, rotated1.next.next.next.next.value); + assertNull(rotated1.next.next.next.next.next); + } + + @Test + public void testRotateRightFullRotation() { + RotateSinglyLinkedLists rotator = new RotateSinglyLinkedLists(); + + // Test case: Rotate a list with multiple elements (Full rotation) + Node head = new Node(1); + head.next = new Node(2); + head.next.next = new Node(3); + head.next.next.next = new Node(4); + head.next.next.next.next = new Node(5); + + Node rotated3 = rotator.rotateRight(head, 7); + assertEquals(4, rotated3.value); + assertEquals(5, rotated3.next.value); + assertEquals(1, rotated3.next.next.value); + assertEquals(2, rotated3.next.next.next.value); + assertEquals(3, rotated3.next.next.next.next.value); + assertNull(rotated3.next.next.next.next.next); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java b/Java/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java new file mode 100644 index 000000000000..a47434083cdb --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java @@ -0,0 +1,260 @@ +package com.thealgorithms.datastructures.lists; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class SinglyLinkedListTest { + + /** + * Initialize a list with natural order values with pre-defined length + * @param length + * @return linked list with pre-defined number of nodes + */ + private SinglyLinkedList createSampleList(int length) { + List<Node> nodeList = new ArrayList<>(); + for (int i = 1; i <= length; i++) { + Node node = new Node(i); + nodeList.add(node); + } + + for (int i = 0; i < length - 1; i++) { + nodeList.get(i).next = nodeList.get(i + 1); + } + + return new SinglyLinkedList(nodeList.get(0), length); + } + + @Test + void detectLoop() { + // List has cycle + Node firstNode = new Node(1); + Node secondNode = new Node(2); + Node thirdNode = new Node(3); + Node fourthNode = new Node(4); + + firstNode.next = secondNode; + secondNode.next = thirdNode; + thirdNode.next = fourthNode; + fourthNode.next = firstNode; + + SinglyLinkedList listHasLoop = new SinglyLinkedList(firstNode, 4); + assertTrue(listHasLoop.detectLoop()); + + SinglyLinkedList listHasNoLoop = createSampleList(5); + assertFalse(listHasNoLoop.detectLoop()); + } + + @Test + void middle() { + int oddNumberOfNode = 7; + SinglyLinkedList list = createSampleList(oddNumberOfNode); + assertEquals(oddNumberOfNode / 2 + 1, list.middle().value); + int evenNumberOfNode = 8; + list = createSampleList(evenNumberOfNode); + assertEquals(evenNumberOfNode / 2, list.middle().value); + + // return null if empty + list = new SinglyLinkedList(); + assertNull(list.middle()); + + // return head if there is only one node + list = createSampleList(1); + assertEquals(list.getHead(), list.middle()); + } + + @Test + void swap() { + SinglyLinkedList list = createSampleList(5); + assertEquals(1, list.getHead().value); + assertEquals(5, list.getNth(4)); + list.swapNodes(1, 5); + assertEquals(5, list.getHead().value); + assertEquals(1, list.getNth(4)); + } + + @Test + void clear() { + SinglyLinkedList list = createSampleList(5); + assertEquals(5, list.size()); + list.clear(); + assertEquals(0, list.size()); + assertTrue(list.isEmpty()); + } + + @Test + void search() { + SinglyLinkedList list = createSampleList(10); + assertTrue(list.search(5)); + assertFalse(list.search(20)); + } + + @Test + void deleteNth() { + SinglyLinkedList list = createSampleList(10); + assertTrue(list.search(7)); + list.deleteNth(6); // Index 6 has value 7 + assertFalse(list.search(7)); + } + // Test to check whether the method reverseList() works fine + @Test + void reverseList() { + + // Creating a new LinkedList of size:4 + // The linkedlist will be 1->2->3->4->null + SinglyLinkedList list = createSampleList(4); + + // Reversing the LinkedList using reverseList() method and storing the head of the reversed + // linkedlist in a head node The reversed linkedlist will be 4->3->2->1->null + Node head = list.reverseListIter(list.getHead()); + + // Recording the Nodes after reversing the LinkedList + Node firstNode = head; // 4 + Node secondNode = firstNode.next; // 3 + Node thirdNode = secondNode.next; // 2 + Node fourthNode = thirdNode.next; // 1 + + // Checking whether the LinkedList is reversed or not by comparing the original list and + // reversed list nodes + assertEquals(1, fourthNode.value); + assertEquals(2, thirdNode.value); + assertEquals(3, secondNode.value); + assertEquals(4, firstNode.value); + } + + // Test to check whether implemented reverseList() method handles NullPointer Exception for + // TestCase where head==null + @Test + void reverseListNullPointer() { + // Creating a linkedlist with first node assigned to null + SinglyLinkedList list = new SinglyLinkedList(); + Node first = list.getHead(); + + // Reversing the linkedlist + Node head = list.reverseListIter(first); + + // checking whether the method works fine if the input is null + assertEquals(head, first); + } + + // Testing reverseList() method for a linkedlist of size: 20 + @Test + void reverseListTest() { + // Creating a new linkedlist + SinglyLinkedList list = createSampleList(20); + + // Reversing the LinkedList using reverseList() method and storing the head of the reversed + // linkedlist in a head node + Node head = list.reverseListIter(list.getHead()); + + // Storing the head in a temp variable, so that we cannot loose the track of head + Node temp = head; + + int i = 20; // This is for the comparison of values of nodes of the reversed linkedlist + // Checking whether the reverseList() method performed its task + while (temp != null && i > 0) { + assertEquals(i, temp.value); + temp = temp.next; + i--; + } + } + // This is Recursive Reverse List Test + // Test to check whether the method reverseListRec() works fine + void recursiveReverseList() { + // Create a linked list: 1 -> 2 -> 3 -> 4 -> 5 + SinglyLinkedList list = createSampleList(5); + + // Reversing the linked list using reverseList() method + Node head = list.reverseListRec(list.getHead()); + + // Check if the reversed list is: 5 -> 4 -> 3 -> 2 -> 1 + assertEquals(5, head.value); + assertEquals(4, head.next.value); + assertEquals(3, head.next.next.value); + assertEquals(2, head.next.next.next.value); + assertEquals(1, head.next.next.next.next.value); + } + + @Test + void recursiveReverseListNullPointer() { + // Create an empty linked list + SinglyLinkedList list = new SinglyLinkedList(); + Node first = list.getHead(); + + // Reversing the empty linked list + Node head = list.reverseListRec(first); + + // Check if the head remains the same (null) + assertNull(head); + } + + @Test + void recursiveReverseListTest() { + // Create a linked list with values from 1 to 20 + SinglyLinkedList list = createSampleList(20); + + // Reversing the linked list using reverseList() method + Node head = list.reverseListRec(list.getHead()); + + // Check if the reversed list has the correct values + int i = 20; + Node temp = head; + while (temp != null && i > 0) { + assertEquals(i, temp.value); + temp = temp.next; + i--; + } + } + + @Test + void readWithEnhancedForLoopTest() { + final var expeced = new ArrayList<Integer>(Arrays.asList(10, 20, 30)); + + SinglyLinkedList list = new SinglyLinkedList(); + for (final var x : expeced) { + list.insert(x); + } + + var readElements = new ArrayList<Integer>(); + for (final var x : list) { + readElements.add(x); + } + + assertEquals(readElements, expeced); + } + + @Test + void toStringTest() { + SinglyLinkedList list = new SinglyLinkedList(); + list.insert(1); + list.insert(2); + list.insert(3); + assertEquals("1->2->3", list.toString()); + } + + @Test + void toStringForEmptyListTest() { + SinglyLinkedList list = new SinglyLinkedList(); + assertEquals("", list.toString()); + } + + @Test + void countTest() { + SinglyLinkedList list = new SinglyLinkedList(); + list.insert(10); + list.insert(20); + assertEquals(2, list.count()); + } + + @Test + void countForEmptyListTest() { + SinglyLinkedList list = new SinglyLinkedList(); + assertEquals(0, list.count()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java b/Java/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java new file mode 100644 index 000000000000..c572739ffbbf --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java @@ -0,0 +1,110 @@ +package com.thealgorithms.datastructures.lists; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.stream.IntStream; +import org.junit.jupiter.api.Test; + +class SkipListTest { + + @Test + void add() { + SkipList<String> skipList = new SkipList<>(); + assertEquals(0, skipList.size()); + + skipList.add("value"); + + print(skipList); + assertEquals(1, skipList.size()); + } + + @Test + void get() { + SkipList<String> skipList = new SkipList<>(); + skipList.add("value"); + + String actualValue = skipList.get(0); + + print(skipList); + assertEquals("value", actualValue); + } + + @Test + void contains() { + SkipList<String> skipList = createSkipList(); + print(skipList); + + boolean contains = skipList.contains("b"); + + assertTrue(contains); + } + + @Test + void removeFromHead() { + SkipList<String> skipList = createSkipList(); + String mostLeftElement = skipList.get(0); + int initialSize = skipList.size(); + print(skipList); + + skipList.remove(mostLeftElement); + + print(skipList); + assertEquals(initialSize - 1, skipList.size()); + } + + @Test + void removeFromTail() { + SkipList<String> skipList = createSkipList(); + String mostRightValue = skipList.get(skipList.size() - 1); + int initialSize = skipList.size(); + print(skipList); + + skipList.remove(mostRightValue); + + print(skipList); + assertEquals(initialSize - 1, skipList.size()); + } + + @Test + void checkSortedOnLowestLayer() { + SkipList<String> skipList = new SkipList<>(); + String[] values = {"d", "b", "a", "c"}; + Arrays.stream(values).forEach(skipList::add); + print(skipList); + + String[] actualOrder = IntStream.range(0, values.length).mapToObj(skipList::get).toArray(String[] ::new); + + assertArrayEquals(new String[] {"a", "b", "c", "d"}, actualOrder); + } + + private SkipList<String> createSkipList() { + SkipList<String> skipList = new SkipList<>(); + String[] values = { + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + }; + Arrays.stream(values).forEach(skipList::add); + return skipList; + } + + /** + * Print Skip List representation to console. + * Optional method not involved in testing process. Used only for visualisation purposes. + * @param skipList to print + */ + private void print(SkipList<?> skipList) { + System.out.println(skipList); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java b/Java/src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java new file mode 100644 index 000000000000..faa0d0e952f9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/queues/LinkedQueueTest.java @@ -0,0 +1,26 @@ +package com.thealgorithms.datastructures.queues; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class LinkedQueueTest { + @Test + public void testQue() { + LinkedQueue<Integer> queue = new LinkedQueue<>(); + for (int i = 1; i < 5; i++) queue.enqueue(i); + + assertEquals(queue.peekRear(), 4); + assertEquals(queue.peek(2), 2); + + assertEquals(queue.peek(4), 4); + + final int[] element = {1}; + + // iterates over all the elements present + // as in the form of nodes + queue.forEach(integer -> { + if (element[0]++ != integer) throw new AssertionError(); + }); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java b/Java/src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java new file mode 100644 index 000000000000..1a3b5aadebb2 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/queues/PriorityQueuesTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.datastructures.queues; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class PriorityQueuesTest { + + @Test + void testPQInsertion() { + PriorityQueue myQueue = new PriorityQueue(4); + myQueue.insert(2); + Assertions.assertEquals(myQueue.peek(), 2); + + myQueue.insert(5); + myQueue.insert(3); + Assertions.assertEquals(myQueue.peek(), 5); + + myQueue.insert(10); + Assertions.assertEquals(myQueue.peek(), 10); + } + + @Test + void testPQDeletion() { + PriorityQueue myQueue = new PriorityQueue(4); + myQueue.insert(2); + myQueue.insert(5); + myQueue.insert(3); + myQueue.insert(10); + + myQueue.remove(); + Assertions.assertEquals(myQueue.peek(), 5); + myQueue.remove(); + myQueue.remove(); + Assertions.assertEquals(myQueue.peek(), 2); + } + + @Test + void testPQExtra() { + PriorityQueue myQueue = new PriorityQueue(4); + Assertions.assertEquals(myQueue.isEmpty(), true); + Assertions.assertEquals(myQueue.isFull(), false); + myQueue.insert(2); + myQueue.insert(5); + Assertions.assertEquals(myQueue.isFull(), false); + myQueue.insert(3); + myQueue.insert(10); + Assertions.assertEquals(myQueue.isEmpty(), false); + Assertions.assertEquals(myQueue.isFull(), true); + + myQueue.remove(); + Assertions.assertEquals(myQueue.getSize(), 3); + Assertions.assertEquals(myQueue.peek(), 5); + myQueue.remove(); + myQueue.remove(); + Assertions.assertEquals(myQueue.peek(), 2); + Assertions.assertEquals(myQueue.getSize(), 1); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java new file mode 100644 index 000000000000..aab3b82c45eb --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTFromSortedArrayTest.java @@ -0,0 +1,47 @@ +package com.thealgorithms.datastructures.trees; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 20/04/2023 + */ +public class BSTFromSortedArrayTest { + @Test + public void testNullArray() { + BinaryTree.Node actualBST = BSTFromSortedArray.createBST(null); + Assertions.assertNull(actualBST); + } + + @Test + public void testEmptyArray() { + BinaryTree.Node actualBST = BSTFromSortedArray.createBST(new int[] {}); + Assertions.assertNull(actualBST); + } + + @Test + public void testSingleElementArray() { + BinaryTree.Node actualBST = BSTFromSortedArray.createBST(new int[] {Integer.MIN_VALUE}); + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(actualBST)); + } + + @Test + public void testCreateBSTFromSmallArray() { + BinaryTree.Node actualBST = BSTFromSortedArray.createBST(new int[] {1, 2, 3}); + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(actualBST)); + } + + @Test + public void testCreateBSTFromLongerArray() { + int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + BinaryTree.Node actualBST = BSTFromSortedArray.createBST(array); + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(actualBST)); + } + + @Test + public void testShouldNotCreateBSTFromNonSortedArray() { + int[] array = {10, 2, 3, 4, 5, 6, 7, 8, 9, 1}; + BinaryTree.Node actualBST = BSTFromSortedArray.createBST(array); + Assertions.assertFalse(CheckBinaryTreeIsValidBST.isBST(actualBST)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java new file mode 100644 index 000000000000..f47e2ad5285d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTIterativeTest.java @@ -0,0 +1,61 @@ +package com.thealgorithms.datastructures.trees; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 23/04/2023 + */ +public class BSTIterativeTest { + @Test + public void testBSTIsCorrectlyConstructedFromOneNode() { + BSTIterative tree = new BSTIterative(); + tree.add(6); + + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(tree.getRoot())); + } + + @Test + public void testBSTIsCorrectlyCleanedAndEmpty() { + BSTIterative tree = new BSTIterative(); + + tree.add(6); + tree.remove(6); + + tree.add(12); + tree.add(1); + tree.add(2); + + tree.remove(1); + tree.remove(2); + tree.remove(12); + + Assertions.assertNull(tree.getRoot()); + } + + @Test + public void testBSTIsCorrectlyCleanedAndNonEmpty() { + BSTIterative tree = new BSTIterative(); + + tree.add(6); + tree.remove(6); + + tree.add(12); + tree.add(1); + tree.add(2); + + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(tree.getRoot())); + } + + @Test + public void testBSTIsCorrectlyConstructedFromMultipleNodes() { + BSTIterative tree = new BSTIterative(); + tree.add(7); + tree.add(1); + tree.add(5); + tree.add(100); + tree.add(50); + + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(tree.getRoot())); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java new file mode 100644 index 000000000000..07bcd2aa15b6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/BSTRecursiveTest.java @@ -0,0 +1,61 @@ +package com.thealgorithms.datastructures.trees; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 06/05/2023 + */ +public class BSTRecursiveTest { + @Test + public void testBSTIsCorrectlyConstructedFromOneNode() { + BSTRecursive tree = new BSTRecursive(); + tree.add(6); + + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(tree.getRoot())); + } + + @Test + public void testBSTIsCorrectlyCleanedAndEmpty() { + BSTRecursive tree = new BSTRecursive(); + + tree.add(6); + tree.remove(6); + + tree.add(12); + tree.add(1); + tree.add(2); + + tree.remove(1); + tree.remove(2); + tree.remove(12); + + Assertions.assertNull(tree.getRoot()); + } + + @Test + public void testBSTIsCorrectlyCleanedAndNonEmpty() { + BSTRecursive tree = new BSTRecursive(); + + tree.add(6); + tree.remove(6); + + tree.add(12); + tree.add(1); + tree.add(2); + + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(tree.getRoot())); + } + + @Test + public void testBSTIsCorrectlyConstructedFromMultipleNodes() { + BSTRecursive tree = new BSTRecursive(); + tree.add(7); + tree.add(1); + tree.add(5); + tree.add(100); + tree.add(50); + + Assertions.assertTrue(CheckBinaryTreeIsValidBST.isBST(tree.getRoot())); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java new file mode 100644 index 000000000000..b153c5d667de --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/BinaryTreeTest.java @@ -0,0 +1,76 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryTreeTest { + + // checks that adding populating the tree and searching for data + // retrieves the expected data + @Test + void test1() { + BinaryTree t = new BinaryTree(); + t.put(3); + t.put(5); + t.put(7); + t.put(9); + t.put(12); + + assertEquals(t.find(5).data, 5); + assertEquals(t.find(7).data, 7); + } + + // checks that removing data from the tree + // properly removes and makes the new root the expected new root + @Test + void test2() { + BinaryTree t = new BinaryTree(); + t.put(3); + t.put(5); + t.put(7); + t.put(9); + t.put(12); + t.remove(3); + t.remove(5); + t.remove(7); + + assertEquals(t.getRoot().data, 9); + } + + // checks that removing an unexistend node returns false + // as specified by the documentation of the function + @Test + void test3() { + BinaryTree t = new BinaryTree(); + t.put(3); + t.put(5); + t.put(7); + t.put(9); + t.put(12); + + assertEquals(t.remove(9), true); + assertEquals(t.remove(398745987), false); + } + + // check if the bfs, inOrder, preOrder and postOrder functions + // worg as expected, also increases the coverage measures in + // JaCoCo + @Test + void test4() { + BinaryTree t = new BinaryTree(); + t.put(3); + t.put(5); + t.put(7); + t.put(9); + t.put(12); + + t.bfs(t.find(12)); + t.inOrder(t.getRoot()); + t.preOrder(t.getRoot()); + t.postOrder(t.getRoot()); + + assertEquals(t.remove(9), true); + assertEquals(t.remove(398745987), false); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java new file mode 100644 index 000000000000..779c68137e42 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTreeTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; +import org.junit.jupiter.api.Test; + +public class CeilInBinarySearchTreeTest { + + @Test + public void testRootNull() { + assertNull(CeilInBinarySearchTree.getCeil(null, 9)); + } + + @Test + public void testKeyPresentRootIsCeil() { + final Node root = TreeTestUtils.createTree(new Integer[] {100, 10, 200}); + assertEquals(100, CeilInBinarySearchTree.getCeil(root, 100).data); + } + + @Test + public void testKeyPresentLeafIsCeil() { + final Node root = TreeTestUtils.createTree(new Integer[] {100, 10, 200}); + assertEquals(10, CeilInBinarySearchTree.getCeil(root, 10).data); + } + + @Test + public void testKeyAbsentRootIsCeil() { + final Node root = TreeTestUtils.createTree(new Integer[] {100, 10, 200, 5, 50, 150, 300}); + assertEquals(100, CeilInBinarySearchTree.getCeil(root, 75).data); + } + + @Test + public void testKeyAbsentLeafIsCeil() { + final Node root = TreeTestUtils.createTree(new Integer[] {100, 10, 200, 5, 50, 150, 300}); + assertEquals(50, CeilInBinarySearchTree.getCeil(root, 40).data); + } + + @Test + public void testKeyAbsentLeftMostNodeIsCeil() { + final Node root = TreeTestUtils.createTree(new Integer[] {100, 10, 200, 5, 50, 150, 300}); + assertEquals(5, CeilInBinarySearchTree.getCeil(root, 1).data); + } + + @Test + public void testKeyAbsentCeilIsNull() { + final Node root = TreeTestUtils.createTree(new Integer[] {100, 10, 200, 5, 50, 150, 300}); + assertNull(CeilInBinarySearchTree.getCeil(root, 400)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java new file mode 100644 index 000000000000..bf7b946143f9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBSTTest.java @@ -0,0 +1,61 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 17/02/2023 + */ +public class CheckBinaryTreeIsValidBSTTest { + @Test + public void testRootNull() { + assertTrue(CheckBinaryTreeIsValidBST.isBST(null)); + } + + @Test + public void testOneNode() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {Integer.MIN_VALUE}); + assertTrue(CheckBinaryTreeIsValidBST.isBST(root)); + } + + /* + 9 + / \ + 7 13 + /\ / \ + 3 8 10 20 + */ + @Test + public void testBinaryTreeIsBST() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, 13, 3, 8, 10, 20}); + assertTrue(CheckBinaryTreeIsValidBST.isBST(root)); + } + + /* + 9 + / \ + 7 13 + /\ / \ + 3 8 10 13 <--- duplicated node + */ + @Test + public void testBinaryTreeWithDuplicatedNodesIsNotBST() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, 13, 3, 8, 10, 13}); + assertFalse(CheckBinaryTreeIsValidBST.isBST(root)); + } + + /* + 9 + / \ + 7 13 + /\ / \ + 3 8 10 12 <---- violates BST rule, needs to be more than 13 (parent node) + */ + @Test + public void testBinaryTreeIsNotBST() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, 13, 3, 8, 10, 12}); + assertFalse(CheckBinaryTreeIsValidBST.isBST(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java new file mode 100644 index 000000000000..0eb234d618ed --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalancedTest.java @@ -0,0 +1,84 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +/** + * Test check both implemented ways, iterative and recursive algorithms. + * + * @author Albina Gimaletdinova on 26/06/2023 + */ +public class CheckIfBinaryTreeBalancedTest { + @Test + public void testRootNull() { + assertTrue(CheckIfBinaryTreeBalanced.isBalancedRecursive(null)); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedIterative(null)); + } + + @Test + public void testOneNode() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {Integer.MIN_VALUE}); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedRecursive(root)); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedIterative(root)); + } + + /* + 9 <-- Math.abs(height(left) - height(right)) == 0 + / \ + 7 13 + /\ / \ + 3 8 10 20 +*/ + @Test + public void testBinaryTreeIsBalancedEqualSubtreeHeights() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, 13, 3, 8, 10, 20}); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedRecursive(root)); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedIterative(root)); + } + + /* + 9 <-- Math.abs(height(left) - height(right)) == 1 + / \ + 7 13 + /\ + 3 8 +*/ + @Test + public void testBinaryTreeIsBalancedWithDifferentHeights() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, 13, 3, 8}); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedRecursive(root)); + assertTrue(CheckIfBinaryTreeBalanced.isBalancedIterative(root)); + } + + /* + 9 <-- only left tree exists, Math.abs(height(left) - height(right)) > 1 + / + 7 + /\ + 3 8 + */ + @Test + public void testBinaryTreeNotBalanced() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, null, 3, 8}); + assertFalse(CheckIfBinaryTreeBalanced.isBalancedRecursive(root)); + assertFalse(CheckIfBinaryTreeBalanced.isBalancedIterative(root)); + } + + /* + 9 <-- Math.abs(height(left) - height(right)) > 1 + / \ + 7 13 + /\ + 3 8 + / + 11 +*/ + @Test + public void testBinaryTreeNotBalancedBecauseLeftTreeNotBalanced() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {9, 7, 13, 3, 8, null, null, 11}); + assertFalse(CheckIfBinaryTreeBalanced.isBalancedRecursive(root)); + assertFalse(CheckIfBinaryTreeBalanced.isBalancedIterative(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java new file mode 100644 index 000000000000..a610a32aa91f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetricTest.java @@ -0,0 +1,35 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +/** + * @author kumanoit on 10/10/22 IST 1:02 AM + */ +public class CheckTreeIsSymmetricTest { + + @Test + public void testRootNull() { + assertTrue(CheckTreeIsSymmetric.isSymmetric(null)); + } + + @Test + public void testSingleNodeTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {100}); + assertTrue(CheckTreeIsSymmetric.isSymmetric(root)); + } + + @Test + public void testSymmetricTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 2, 3, 4, 4, 3}); + assertTrue(CheckTreeIsSymmetric.isSymmetric(root)); + } + + @Test + public void testNonSymmetricTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 2, 3, 5, 4, 3}); + assertFalse(CheckTreeIsSymmetric.isSymmetric(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java new file mode 100644 index 000000000000..10f7aa667230 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorderTest.java @@ -0,0 +1,102 @@ +package com.thealgorithms.datastructures.trees; + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 14/05/2023 + */ +public class CreateBinaryTreeFromInorderPreorderTest { + @Test + public void testOnNullArraysShouldReturnNullTree() { + // when + BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(null, null); + BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(null, null); + + // then + Assertions.assertNull(root); + Assertions.assertNull(rootOpt); + } + + @Test + public void testOnEmptyArraysShouldCreateNullTree() { + // given + Integer[] preorder = {}; + Integer[] inorder = {}; + + // when + BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder); + BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder); + + // then + Assertions.assertNull(root); + Assertions.assertNull(rootOpt); + } + + @Test + public void testOnSingleNodeTreeShouldCreateCorrectTree() { + // given + Integer[] preorder = {1}; + Integer[] inorder = {1}; + + // when + BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder); + BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder); + + // then + checkTree(preorder, inorder, root); + checkTree(preorder, inorder, rootOpt); + } + + @Test + public void testOnRightSkewedTreeShouldCreateCorrectTree() { + // given + Integer[] preorder = {1, 2, 3, 4}; + Integer[] inorder = {1, 2, 3, 4}; + + // when + BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder); + BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder); + + // then + checkTree(preorder, inorder, root); + checkTree(preorder, inorder, rootOpt); + } + + @Test + public void testOnLeftSkewedTreeShouldCreateCorrectTree() { + // given + Integer[] preorder = {1, 2, 3, 4}; + Integer[] inorder = {4, 3, 2, 1}; + + // when + BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder); + BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder); + + // then + checkTree(preorder, inorder, root); + checkTree(preorder, inorder, rootOpt); + } + + @Test + public void testOnNormalTreeShouldCreateCorrectTree() { + // given + Integer[] preorder = {3, 9, 20, 15, 7}; + Integer[] inorder = {9, 3, 15, 20, 7}; + + // when + BinaryTree.Node root = CreateBinaryTreeFromInorderPreorder.createTree(preorder, inorder); + BinaryTree.Node rootOpt = CreateBinaryTreeFromInorderPreorder.createTreeOptimized(preorder, inorder); + + // then + checkTree(preorder, inorder, root); + checkTree(preorder, inorder, rootOpt); + } + + private static void checkTree(Integer[] preorder, Integer[] inorder, BinaryTree.Node root) { + Assertions.assertNotNull(root); + Assertions.assertEquals(PreOrderTraversal.iterativePreOrder(root), Arrays.asList(preorder)); + Assertions.assertEquals(InorderTraversal.iterativeInorder(root), Arrays.asList(inorder)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java new file mode 100644 index 000000000000..e65beb891606 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/InorderTraversalTest.java @@ -0,0 +1,52 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 21/02/2023 + */ +public class InorderTraversalTest { + @Test + public void testNullRoot() { + assertEquals(Collections.emptyList(), InorderTraversal.recursiveInorder(null)); + assertEquals(Collections.emptyList(), InorderTraversal.iterativeInorder(null)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + */ + @Test + public void testRecursiveInorder() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + List<Integer> expected = List.of(4, 2, 5, 1, 6, 3, 7); + + assertEquals(expected, InorderTraversal.recursiveInorder(root)); + assertEquals(expected, InorderTraversal.iterativeInorder(root)); + } + + /* + 5 + \ + 6 + \ + 7 + \ + 8 + */ + @Test + public void testRecursiveInorderNonBalanced() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {5, null, 6, null, 7, null, 8}); + List<Integer> expected = List.of(5, 6, 7, 8); + + assertEquals(expected, InorderTraversal.recursiveInorder(root)); + assertEquals(expected, InorderTraversal.iterativeInorder(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java new file mode 100644 index 000000000000..49babb033e81 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/KDTreeTest.java @@ -0,0 +1,63 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class KDTreeTest { + + KDTree.Point pointOf(int x, int y) { + return new KDTree.Point(new int[] {x, y}); + } + + @Test + void findMin() { + int[][] coordinates = { + {30, 40}, + {5, 25}, + {70, 70}, + {10, 12}, + {50, 30}, + {35, 45}, + }; + KDTree kdTree = new KDTree(coordinates); + + assertEquals(5, kdTree.findMin(0).getCoordinate(0)); + assertEquals(12, kdTree.findMin(1).getCoordinate(1)); + } + + @Test + void delete() { + int[][] coordinates = { + {30, 40}, + {5, 25}, + {70, 70}, + {10, 12}, + {50, 30}, + {35, 45}, + }; + KDTree kdTree = new KDTree(coordinates); + + kdTree.delete(pointOf(30, 40)); + assertEquals(35, kdTree.getRoot().getPoint().getCoordinate(0)); + assertEquals(45, kdTree.getRoot().getPoint().getCoordinate(1)); + } + + @Test + void findNearest() { + int[][] coordinates = { + {2, 3}, + {5, 4}, + {9, 6}, + {4, 7}, + {8, 1}, + {7, 2}, + }; + KDTree kdTree = new KDTree(coordinates); + + assertEquals(pointOf(7, 2), kdTree.findNearest(pointOf(7, 2))); + assertEquals(pointOf(8, 1), kdTree.findNearest(pointOf(8, 1))); + assertEquals(pointOf(2, 3), kdTree.findNearest(pointOf(1, 1))); + assertEquals(pointOf(5, 4), kdTree.findNearest(pointOf(5, 5))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java new file mode 100644 index 000000000000..e8294a323463 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java @@ -0,0 +1,60 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class LazySegmentTreeTest { + + @Test + void build() { + int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + LazySegmentTree lazySegmentTree = new LazySegmentTree(arr); + assertEquals(55, lazySegmentTree.getRoot().getValue()); + assertEquals(15, lazySegmentTree.getRoot().getLeft().getValue()); + assertEquals(40, lazySegmentTree.getRoot().getRight().getValue()); + } + + @Test + void update() { + int[] arr = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + LazySegmentTree lazySegmentTree = new LazySegmentTree(arr); + assertEquals(10, lazySegmentTree.getRoot().getValue()); + + lazySegmentTree.updateRange(0, 2, 1); + assertEquals(12, lazySegmentTree.getRoot().getValue()); + + lazySegmentTree.updateRange(1, 3, 1); + assertEquals(14, lazySegmentTree.getRoot().getValue()); + + lazySegmentTree.updateRange(6, 8, 1); + assertEquals(16, lazySegmentTree.getRoot().getValue()); + + lazySegmentTree.updateRange(3, 9, 1); + assertEquals(22, lazySegmentTree.getRoot().getValue()); + } + + @Test + void get() { + int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + LazySegmentTree lazySegmentTree = new LazySegmentTree(arr); + assertEquals(55, lazySegmentTree.getRange(0, 10)); + assertEquals(3, lazySegmentTree.getRange(0, 2)); + assertEquals(19, lazySegmentTree.getRange(8, 10)); + assertEquals(44, lazySegmentTree.getRange(1, 9)); + } + + @Test + void updateAndGet() { + int[] arr = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + LazySegmentTree lazySegmentTree = new LazySegmentTree(arr); + + for (int i = 0; i < 10; i++) + for (int j = i + 1; j < 10; j++) { + lazySegmentTree.updateRange(i, j, 1); + assertEquals(j - i, lazySegmentTree.getRange(i, j)); + lazySegmentTree.updateRange(i, j, -1); + assertEquals(0, lazySegmentTree.getRange(i, j)); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java new file mode 100644 index 000000000000..ee807bccc5f1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/LevelOrderTraversalTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 08/02/2023 + */ +public class LevelOrderTraversalTest { + @Test + public void testRootNull() { + assertEquals(Collections.emptyList(), LevelOrderTraversal.traverse(null)); + } + + @Test + public void testSingleNodeTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {50}); + assertEquals(List.of(List.of(50)), LevelOrderTraversal.traverse(root)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + */ + @Test + public void testLevelOrderTraversalCompleteTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + assertEquals(List.of(List.of(1), List.of(2, 3), List.of(4, 5, 6, 7)), LevelOrderTraversal.traverse(root)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + / \ + 8 9 + */ + @Test + public void testLevelOrderTraversalDifferentHeight() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7, null, null, 8, null, null, 9}); + assertEquals(List.of(List.of(1), List.of(2, 3), List.of(4, 5, 6, 7), List.of(8, 9)), LevelOrderTraversal.traverse(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java new file mode 100644 index 000000000000..3acc7f07c087 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/PostOrderTraversalTest.java @@ -0,0 +1,54 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * Given tree is traversed in a 'post-order' way: LEFT -> RIGHT -> ROOT. + * + * @author Albina Gimaletdinova on 21/02/2023 + */ +public class PostOrderTraversalTest { + @Test + public void testNullRoot() { + assertEquals(Collections.emptyList(), PostOrderTraversal.recursivePostOrder(null)); + assertEquals(Collections.emptyList(), PostOrderTraversal.iterativePostOrder(null)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + */ + @Test + public void testPostOrder() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + List<Integer> expected = List.of(4, 5, 2, 6, 7, 3, 1); + + assertEquals(expected, PostOrderTraversal.recursivePostOrder(root)); + assertEquals(expected, PostOrderTraversal.iterativePostOrder(root)); + } + + /* + 5 + \ + 6 + \ + 7 + \ + 8 + */ + @Test + public void testPostOrderNonBalanced() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {5, null, 6, null, 7, null, 8}); + List<Integer> expected = List.of(8, 7, 6, 5); + + assertEquals(expected, PostOrderTraversal.recursivePostOrder(root)); + assertEquals(expected, PostOrderTraversal.iterativePostOrder(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java new file mode 100644 index 000000000000..b194da01485b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/PreOrderTraversalTest.java @@ -0,0 +1,52 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 17/02/2023 + */ +public class PreOrderTraversalTest { + @Test + public void testNullRoot() { + assertEquals(Collections.emptyList(), PreOrderTraversal.recursivePreOrder(null)); + assertEquals(Collections.emptyList(), PreOrderTraversal.iterativePreOrder(null)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + */ + @Test + public void testRecursivePreOrder() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + List<Integer> expected = List.of(1, 2, 4, 5, 3, 6, 7); + + assertEquals(expected, PreOrderTraversal.recursivePreOrder(root)); + assertEquals(expected, PreOrderTraversal.iterativePreOrder(root)); + } + + /* + 5 + \ + 6 + \ + 7 + \ + 8 + */ + @Test + public void testRecursivePreOrderNonBalanced() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {5, null, 6, null, 7, null, 8}); + List<Integer> expected = List.of(5, 6, 7, 8); + + assertEquals(expected, PreOrderTraversal.recursivePreOrder(root)); + assertEquals(expected, PreOrderTraversal.iterativePreOrder(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java new file mode 100644 index 000000000000..440222880517 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/SameTreesCheckTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 12/01/2023 + */ +public class SameTreesCheckTest { + @Test + public void testBothRootsAreNull() { + assertTrue(SameTreesCheck.check(null, null)); + } + + @Test + public void testOneRootIsNull() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {100}); + assertFalse(SameTreesCheck.check(root, null)); + } + + @Test + public void testSingleNodeTreesAreSame() { + final BinaryTree.Node p = TreeTestUtils.createTree(new Integer[] {100}); + final BinaryTree.Node q = TreeTestUtils.createTree(new Integer[] {100}); + assertTrue(SameTreesCheck.check(p, q)); + } + + /* + 1 1 + / \ / \ + 2 3 2 3 + /\ /\ /\ /\ + 4 5 6 7 4 5 6 7 + */ + @Test + public void testSameTreesIsSuccessful() { + final BinaryTree.Node p = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + final BinaryTree.Node q = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + assertTrue(SameTreesCheck.check(p, q)); + } + + /* + 1 1 + / \ / \ + 2 3 2 3 + /\ /\ /\ / + 4 5 6 7 4 5 6 + */ + @Test + public void testSameTreesFails() { + final BinaryTree.Node p = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + final BinaryTree.Node q = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6}); + assertFalse(SameTreesCheck.check(p, q)); + } + + /* + 1 1 + / \ + 2 2 + */ + @Test + public void testTreesWithDifferentStructure() { + final BinaryTree.Node p = TreeTestUtils.createTree(new Integer[] {1, 2}); + final BinaryTree.Node q = TreeTestUtils.createTree(new Integer[] {1, null, 2}); + assertFalse(SameTreesCheck.check(p, q)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java new file mode 100644 index 000000000000..9628e86b9bff --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java @@ -0,0 +1,46 @@ +package com.thealgorithms.datastructures.trees; + +import com.thealgorithms.datastructures.trees.BinaryTree.Node; +import java.util.LinkedList; +import java.util.Queue; + +public final class TreeTestUtils { + private TreeTestUtils() { + } + + /** + * Creates a binary tree with given values + * + * @param values: Level order representation of tree + * @return Root of a binary tree + */ + public static Node createTree(final Integer[] values) { + if (values == null || values.length == 0 || values[0] == null) { + throw new IllegalArgumentException("Values array should not be empty or null."); + } + final Node root = new Node(values[0]); + final Queue<Node> queue = new LinkedList<>(); + queue.add(root); + int end = 1; + while (end < values.length) { + final Node node = queue.remove(); + if (values[end] == null) { + node.left = null; + } else { + node.left = new Node(values[end]); + queue.add(node.left); + } + end++; + if (end < values.length) { + if (values[end] == null) { + node.right = null; + } else { + node.right = new Node(values[end]); + queue.add(node.right); + } + } + end++; + } + return root; + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java new file mode 100644 index 000000000000..cc89c9813fa8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversalTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 13/01/2023 + */ +public class VerticalOrderTraversalTest { + @Test + public void testRootNull() { + assertEquals(Collections.emptyList(), VerticalOrderTraversal.verticalTraversal(null)); + } + + @Test + public void testSingleNodeTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {50}); + assertEquals(List.of(50), VerticalOrderTraversal.verticalTraversal(root)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + */ + @Test + public void testVerticalTraversalCompleteTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + assertEquals(List.of(4, 2, 1, 5, 6, 3, 7), VerticalOrderTraversal.verticalTraversal(root)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + / \ + 8 9 + */ + @Test + public void testVerticalTraversalDifferentHeight() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7, null, null, 8, null, null, 9}); + assertEquals(List.of(4, 2, 8, 1, 5, 6, 3, 9, 7), VerticalOrderTraversal.verticalTraversal(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java b/Java/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java new file mode 100644 index 000000000000..eb5c0e3ce4df --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/datastructures/trees/ZigzagTraversalTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.datastructures.trees; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Collections; +import java.util.List; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 11/01/2023 + */ +public class ZigzagTraversalTest { + @Test + public void testRootNull() { + assertEquals(Collections.emptyList(), ZigzagTraversal.traverse(null)); + } + + @Test + public void testSingleNodeTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {50}); + assertEquals(List.of(List.of(50)), ZigzagTraversal.traverse(root)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + */ + @Test + public void testZigzagTraversalCompleteTree() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7}); + assertEquals(List.of(List.of(1), List.of(3, 2), List.of(4, 5, 6, 7)), ZigzagTraversal.traverse(root)); + } + + /* + 1 + / \ + 2 3 + /\ /\ + 4 5 6 7 + / \ + 8 9 + */ + @Test + public void testZigzagTraversalDifferentHeight() { + final BinaryTree.Node root = TreeTestUtils.createTree(new Integer[] {1, 2, 3, 4, 5, 6, 7, null, null, 8, null, null, 9}); + assertEquals(List.of(List.of(1), List.of(3, 2), List.of(4, 5, 6, 7), List.of(9, 8)), ZigzagTraversal.traverse(root)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java b/Java/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java new file mode 100644 index 000000000000..ccada6e061e1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java @@ -0,0 +1,38 @@ +package com.thealgorithms.divideandconquer; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryExponentiationTest { + + @Test + public void testCalculatePower() { + assertEquals(1, BinaryExponentiation.calculatePower(1, 10000000)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 100000000)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 1000000000)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 10000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 100000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 1000000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 10000000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 100000000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 1000000000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 10000000000000000L)); + assertEquals(1, BinaryExponentiation.calculatePower(1, 100000000000000000L)); + } + + @Test + public void testPower() { + assertEquals(1, new BinaryExponentiation().power(1, 10000000)); + assertEquals(1, new BinaryExponentiation().power(1, 100000000)); + assertEquals(1, new BinaryExponentiation().power(1, 1000000000)); + assertEquals(1, new BinaryExponentiation().power(1, 10000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 100000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 1000000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 10000000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 100000000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 1000000000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 10000000000000000L)); + assertEquals(1, new BinaryExponentiation().power(1, 100000000000000000L)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java b/Java/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java new file mode 100644 index 000000000000..1ec45a863e1a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java @@ -0,0 +1,41 @@ +package com.thealgorithms.divideandconquer; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class StrassenMatrixMultiplicationTest { + + StrassenMatrixMultiplication smm = new StrassenMatrixMultiplication(); + + // Strassen Matrix Multiplication can only be allplied to matrices of size 2^n + // and has to be a Square Matrix + + @Test + public void strassenMatrixMultiplicationTest2x2() { + int[][] a = {{1, 2}, {3, 4}}; + int[][] b = {{5, 6}, {7, 8}}; + int[][] expResult = {{19, 22}, {43, 50}}; + int[][] actResult = smm.multiply(a, b); + assertArrayEquals(expResult, actResult); + } + + @Test + void strassenMatrixMultiplicationTest4x4() { + int[][] a = {{1, 2, 5, 4}, {9, 3, 0, 6}, {4, 6, 3, 1}, {0, 2, 0, 6}}; + int[][] b = {{1, 0, 4, 1}, {1, 2, 0, 2}, {0, 3, 1, 3}, {1, 8, 1, 2}}; + int[][] expResult = {{7, 51, 13, 28}, {18, 54, 42, 27}, {11, 29, 20, 27}, {8, 52, 6, 16}}; + int[][] actResult = smm.multiply(a, b); + assertArrayEquals(expResult, actResult); + } + + @Test + + void strassenMatrixMultiplicationTestNegetiveNumber4x4() { + int[][] a = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; + int[][] b = {{1, -2, -3, 4}, {4, -3, -2, 1}, {5, -6, -7, 8}, {8, -7, -6, -5}}; + int[][] expResult = {{56, -54, -52, 10}, {128, -126, -124, 42}, {200, -198, -196, 74}, {272, -270, -268, 106}}; + int[][] actResult = smm.multiply(a, b); + assertArrayEquals(expResult, actResult); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java new file mode 100644 index 000000000000..a065bb8c2a10 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class CatalanNumberTest { + + @Test + public void testCatalanNumber() { + assertEquals(42, CatalanNumber.findNthCatalan(5)); + assertEquals(16796, CatalanNumber.findNthCatalan(10)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java new file mode 100644 index 000000000000..bc569cc294b0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class EggDroppingTest { + + @Test + void hasMultipleEggSingleFloor() { + assertEquals(1, EggDropping.minTrials(3, 1)); + } + + @Test + void hasSingleEggSingleFloor() { + assertEquals(1, EggDropping.minTrials(1, 1)); + } + + @Test + void hasSingleEggMultipleFloor() { + assertEquals(3, EggDropping.minTrials(1, 3)); + } + + @Test + void hasMultipleEggMultipleFloor() { + assertEquals(7, EggDropping.minTrials(100, 101)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java new file mode 100644 index 000000000000..d220a2bb512e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class KnapsackMemoizationTest { + + KnapsackMemoization knapsackMemoization = new KnapsackMemoization(); + + @Test + void test1() { + int[] weight = {1, 3, 4, 5}; + int[] value = {1, 4, 5, 7}; + int capacity = 10; + assertEquals(13, knapsackMemoization.knapSack(capacity, weight, value, weight.length)); + } + + @Test + void test2() { + int[] weight = {95, 4, 60, 32, 23, 72, 80, 62, 65, 46}; + int[] value = {55, 10, 47, 5, 4, 50, 8, 61, 85, 87}; + int capacity = 269; + assertEquals(295, knapsackMemoization.knapSack(capacity, weight, value, weight.length)); + } + + @Test + void test3() { + int[] weight = {10, 20, 30}; + int[] value = {60, 100, 120}; + int capacity = 50; + assertEquals(220, knapsackMemoization.knapSack(capacity, weight, value, weight.length)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java new file mode 100644 index 000000000000..3ff733db7e15 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java @@ -0,0 +1,81 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class KnapsackTest { + @Test + public void testKnapSackBasic() { + int[] weights = {2, 3, 4, 5}; + int[] values = {3, 4, 5, 6}; + int weightCapacity = 5; + int expected = 7; // Maximum value should be 7 (items 1 and 4). + int result = Knapsack.knapSack(weightCapacity, weights, values); + assertEquals(expected, result); + } + + @Test + public void testKnapSackEmpty() { + int[] weights = {}; + int[] values = {}; + int weightCapacity = 10; + int expected = 0; // With no items, the result should be 0. + int result = Knapsack.knapSack(weightCapacity, weights, values); + assertEquals(expected, result); + } + + @Test + public void testKnapSackNoCapacity() { + int[] weights = {2, 3, 4}; + int[] values = {3, 4, 5}; + int weightCapacity = 0; + int expected = 0; // With no capacity, the result should be 0. + int result = Knapsack.knapSack(weightCapacity, weights, values); + assertEquals(expected, result); + } + + @Test + public void testKnapSackMaxCapacity() { + int[] weights = {2, 3, 4, 5}; + int[] values = {3, 4, 5, 6}; + int weightCapacity = 10; + int expected = 13; // Maximum value should be 13 (items 1, 3, and 4). + int result = Knapsack.knapSack(weightCapacity, weights, values); + assertEquals(expected, result); + } + + @Test + public void testKnapSackThrowsForInputsOfDifferentLength() { + int[] weights = {2, 3, 4}; + int[] values = {3, 4, 5, 6}; // Different length values array. + int weightCapacity = 5; + assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, values); }); + } + + @Test + public void testKnapSackThrowsForNullInputs() { + int[] weights = {2, 3, 4}; + int[] values = {3, 4, 6}; + int weightCapacity = 5; + assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, null, values); }); + assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, null); }); + } + + @Test + public void testKnapSackThrowsForNegativeCapacity() { + int[] weights = {2, 3, 4, 5}; + int[] values = {3, 4, 5, 6}; + int weightCapacity = -5; + assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, values); }); + } + + @Test + public void testKnapSackThrowsForNegativeWeight() { + int[] weights = {2, 0, 4}; + int[] values = {3, 4, 6}; + int weightCapacity = 5; + assertThrows(IllegalArgumentException.class, () -> { Knapsack.knapSack(weightCapacity, weights, values); }); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java new file mode 100644 index 000000000000..ad4c4c7c53e0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java @@ -0,0 +1,45 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.function.ToIntBiFunction; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class LevenshteinDistanceTests { + + @ParameterizedTest + @MethodSource("testCases") + public void testLevenshteinDistance(final int expected, final String str1, final String str2, final ToIntBiFunction<String, String> dist) { + assertEquals(expected, dist.applyAsInt(str1, str2)); + assertEquals(expected, dist.applyAsInt(str2, str1)); + assertEquals(0, dist.applyAsInt(str1, str1)); + assertEquals(0, dist.applyAsInt(str2, str2)); + } + + private static Stream<Arguments> testCases() { + final Object[][] testData = { + {0, "", ""}, + {0, "Hello, World!", "Hello, World!"}, + {4, "", "Rust"}, + {3, "horse", "ros"}, + {6, "tan", "elephant"}, + {8, "execute", "intention"}, + {1, "a", "b"}, + {1, "a", "aa"}, + {1, "a", ""}, + {1, "a", "ab"}, + {1, "a", "ba"}, + {2, "a", "bc"}, + {2, "a", "cb"}, + }; + + final List<ToIntBiFunction<String, String>> methods = Arrays.asList(LevenshteinDistance::naiveLevenshteinDistance, LevenshteinDistance::optimizedLevenshteinDistance); + + return Stream.of(testData).flatMap(input -> methods.stream().map(method -> Arguments.of(input[0], input[1], input[2], method))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java new file mode 100644 index 000000000000..5135105592a5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java @@ -0,0 +1,49 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class LongestIncreasingSubsequenceTests { + @FunctionalInterface + public interface IntArrayToInt { + int apply(int[] array); + } + + @ParameterizedTest + @MethodSource("testCases") + public void testLongestIncreasingSubsequence(final int expected, final int[] input, final IntArrayToInt method) { + assertEquals(expected, method.apply(input)); + } + + private static Stream<Arguments> testCases() { + final Object[][] testData = { + {0, new int[] {}}, + {1, new int[] {1}}, + {1, new int[] {2, 2}}, + {1, new int[] {3, 3, 3}}, + {1, new int[] {4, 4, 4, 4}}, + {1, new int[] {5, 5, 5, 5, 5}}, + {2, new int[] {1, 2}}, + {2, new int[] {1, 2, 2, 2, 2}}, + {2, new int[] {1, 0, 2}}, + {3, new int[] {1, 10, 2, 30}}, + {3, new int[] {5, 8, 3, 7, 9, 1}}, + {6, new int[] {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}}, + {4, new int[] {10, 9, 2, 5, 3, 7, 101, 18}}, + {4, new int[] {10, 10, 9, 9, 2, 2, 5, 5, 3, 3, 7, 7, 101, 101, 18, 18}}, + {4, new int[] {0, 1, 0, 3, 2, 3}}, + {2, new int[] {1, 1, 2, 2, 2}}, + {3, new int[] {1, 1, 2, 2, 2, 3, 3, 3, 3}}, + }; + + final List<IntArrayToInt> methods = Arrays.asList(LongestIncreasingSubsequence::lis, LongestIncreasingSubsequence::findLISLen); + + return Stream.of(testData).flatMap(input -> methods.stream().map(method -> Arguments.of(input[0], input[1], method))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest b/Java/src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest new file mode 100644 index 000000000000..b2b28ffd3019 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/LongestValidParenthesesTest @@ -0,0 +1,51 @@ +package com.thealgorithms.dynamicprogramming; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class LongestValidParenthesesTest { + + LongestValidParentheses longestValidParentheses = new LongestValidParentheses(); + + @Test + void shouldReturnZeroWhenSingleOpeningParenthesisIsGiven() { + String input = "("; + int validLength = longestValidParentheses.getLongestValidParentheses(input); + assertEquals(0, validLength); + } + + @Test + void shouldReturnZeroWhenSingleClosingParenthesisIsGiven() { + String input = ")"; + int validLength = longestValidParentheses.getLongestValidParentheses(input); + assertEquals(0, validLength); + } + + @Test + void shouldReturnZeroWhenNullStringIsGiven() { + String input = ""; + int validLength = longestValidParentheses.getLongestValidParentheses(input); + assertEquals(0, validLength); + } + + @Test + void shouldReturnTwoWhenTwoBalancedParenthesesAreGiven() { + String input = "()"; + int validLength = longestValidParentheses.getLongestValidParentheses(input); + assertEquals(2, validLength); + } + + @Test + void shouldReturnLengthWhenInputStringIsValid() { + String input = "()((()))"; + int validLength = longestValidParentheses.getLongestValidParentheses(input); + assertEquals(8, validLength); + } + + @Test + void shouldReturnValidLengthWhenInputStringIsGiven() { + String input = "((()((())))"; + int validLength = longestValidParentheses.getLongestValidParentheses(input); + assertEquals(10, validLength); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java new file mode 100644 index 000000000000..5c722c3c0036 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/MinimumPathSumTest.java @@ -0,0 +1,50 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MinimumPathSumTest { + + @Test + public void testMinimumPathSumWithRegularGrid() { + int[][] grid = {{1, 3, 1}, {1, 5, 1}, {4, 2, 1}}; + assertEquals(7, MinimumPathSum.minimumPathSum(grid)); + } + + @Test + public void testMinimumPathSumWithOneRowOneColumnGrid() { + int[][] grid = {{2}}; + assertEquals(2, MinimumPathSum.minimumPathSum(grid)); + } + + @Test + public void testMinimumPathSumWithEmptyGrid() { + int[][] grid = {{}}; + assertEquals(0, MinimumPathSum.minimumPathSum(grid)); + } + + @Test + public void testMinimumPathSumWithOneColumnGrid() { + int[][] grid = {{1}, {2}, {3}}; + assertEquals(6, MinimumPathSum.minimumPathSum(grid)); + } + + @Test + public void testMinimumPathSumGridOneRowGrid() { + int[][] grid = {{1, 2, 3}}; + assertEquals(6, MinimumPathSum.minimumPathSum(grid)); + } + + @Test + public void testMinimumPathSumWithDiffRowAndColumnGrid() { + int[][] grid = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + assertEquals(30, MinimumPathSum.minimumPathSum(grid)); + } + + @Test + public void testMinimumPathSumWithNegativeNumberGrid() { + int[][] grid = {{1, 3, 1}, {3, 4, 1}, {4, -3, 1}}; + assertEquals(6, MinimumPathSum.minimumPathSum(grid)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java new file mode 100644 index 000000000000..1f14320244ea --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/MinimumSumPartitionTest.java @@ -0,0 +1,44 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class MinimumSumPartitionTest { + @Test + public void testMinimumSumPartitionWithEvenSum() { + int[] array = {1, 6, 11, 4}; + assertEquals(0, MinimumSumPartition.minimumSumPartition(array)); + } + + @Test + public void testMinimumSumPartitionWithOddSum() { + int[] array = {36, 7, 46, 40}; + assertEquals(23, MinimumSumPartition.minimumSumPartition(array)); + } + + @Test + public void testMinimumSumPartitionWithSingleElement() { + int[] array = {7}; + assertEquals(7, MinimumSumPartition.minimumSumPartition(array)); + } + + @Test + public void testMinimumSumPartitionWithLargeNumbers() { + int[] array = {100, 200, 300, 400, 500}; + assertEquals(100, MinimumSumPartition.minimumSumPartition(array)); + } + + @Test + public void testMinimumSumPartitionWithEmptyArray() { + int[] array = {}; + assertEquals(0, MinimumSumPartition.minimumSumPartition(array)); + } + + @Test + public void testMinimumSumPartitionThrowsForNegativeArray() { + int[] array = {4, 1, -6, 7}; + assertThrows(IllegalArgumentException.class, () -> { MinimumSumPartition.minimumSumPartition(array); }); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java new file mode 100644 index 000000000000..173ed00488d0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java @@ -0,0 +1,98 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author georgioct@csd.auth.gr + */ +public class OptimalJobSchedulingTest { + + @Test + public void testOptimalJobScheduling1() { + + int numberProcesses = 5; + int numberMachines = 4; + + int[][] run = {{5, 1, 3, 2}, {4, 2, 1, 3}, {1, 5, 2, 1}, {2, 3, 4, 2}, {1, 1, 3, 1}}; + + int[][] transfer = {{0, 1, 2, 4}, {1, 0, 2, 3}, {2, 2, 0, 1}, {4, 3, 1, 0}}; + + OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, run, transfer); + + opt.execute(); + + int[][] costs = {{5, 1, 3, 2}, {6, 3, 4, 5}, {5, 8, 6, 6}, {7, 9, 10, 8}, {8, 9, 12, 9}}; + + for (int i = 0; i < numberProcesses; i++) { + + for (int j = 0; j < numberMachines; j++) { + + assertEquals(costs[i][j], opt.getCost(i, j)); + } + } + } + + @Test + public void testOptimalJobScheduling2() { + + int numberProcesses = 3; + int numberMachines = 3; + + int[][] run = {{5, 1, 3}, {4, 2, 1}, {1, 5, 2}}; + + int[][] transfer = {{0, 1, 2}, {1, 0, 2}, {2, 2, 0}}; + + OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, run, transfer); + + opt.execute(); + + int[][] costs = {{5, 1, 3}, {6, 3, 4}, {5, 8, 6}}; + + for (int i = 0; i < numberProcesses; i++) { + + for (int j = 0; j < numberMachines; j++) { + + assertEquals(costs[i][j], opt.getCost(i, j)); + } + } + } + + @Test + public void testOptimalJobScheduling3() { + + int numberProcesses = 6; + int numberMachines = 4; + + int[][] run = { + {5, 1, 3, 2}, + {4, 2, 1, 1}, + {1, 5, 2, 6}, + {1, 1, 2, 3}, + {2, 1, 4, 6}, + {3, 2, 2, 3}, + }; + + int[][] transfer = { + {0, 1, 2, 1}, + {1, 0, 2, 3}, + {2, 2, 0, 2}, + {1, 3, 2, 0}, + }; + + OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, run, transfer); + + opt.execute(); + + int[][] costs = {{5, 1, 3, 2}, {6, 3, 4, 3}, {5, 8, 6, 9}, {6, 7, 8, 9}, {8, 8, 12, 13}, {11, 10, 12, 12}}; + + for (int i = 0; i < numberProcesses; i++) { + + for (int j = 0; j < numberMachines; j++) { + + assertEquals(costs[i][j], opt.getCost(i, j)); + } + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java new file mode 100644 index 000000000000..098893f41771 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java @@ -0,0 +1,25 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class PartitionProblemTest { + @Test + public void testIfSumOfTheArrayIsOdd() { + assertFalse(PartitionProblem.partition(new int[] {1, 2, 2})); + } + @Test + public void testIfSizeOfTheArrayIsOne() { + assertFalse(PartitionProblem.partition(new int[] {2})); + } + @Test + public void testIfSumOfTheArrayIsEven1() { + assertTrue(PartitionProblem.partition(new int[] {1, 2, 3, 6})); + } + @Test + public void testIfSumOfTheArrayIsEven2() { + assertFalse(PartitionProblem.partition(new int[] {1, 2, 3, 8})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java new file mode 100644 index 000000000000..c76f89deb600 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java @@ -0,0 +1,29 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class SubsetCountTest { + @Test + void hasMultipleSubset() { + int[] arr = new int[] {1, 2, 3, 3}; + assertEquals(3, SubsetCount.getCount(arr, 6)); + } + @Test + void singleElementSubset() { + int[] arr = new int[] {1, 1, 1, 1}; + assertEquals(4, SubsetCount.getCount(arr, 1)); + } + + @Test + void hasMultipleSubsetSO() { + int[] arr = new int[] {1, 2, 3, 3}; + assertEquals(3, SubsetCount.getCountSO(arr, 6)); + } + @Test + void singleSubsetSO() { + int[] arr = new int[] {1, 1, 1, 1}; + assertEquals(1, SubsetCount.getCountSO(arr, 4)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java new file mode 100644 index 000000000000..9df35447eefa --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java @@ -0,0 +1,18 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class SumOfSubsetTest { + + @Test + void basicCheck() { + assertFalse(SumOfSubset.subsetSum(new int[] {1, 2, 7, 10, 9}, 4, 14)); + assertFalse(SumOfSubset.subsetSum(new int[] {2, 15, 1, 6, 7}, 4, 4)); + assertTrue(SumOfSubset.subsetSum(new int[] {7, 3, 2, 5, 8}, 4, 14)); + assertTrue(SumOfSubset.subsetSum(new int[] {4, 3, 2, 1}, 3, 5)); + assertTrue(SumOfSubset.subsetSum(new int[] {1, 7, 2, 9, 10}, 4, 13)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java new file mode 100644 index 000000000000..434a1825dfec --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java @@ -0,0 +1,24 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Test class for {@code Tribonacci}. + */ +public class TribonacciTest { + + /** + * Tests the Tribonacci computation for a set of known values. + */ + @Test + public void testKnownValues() { + assertEquals(0, Tribonacci.compute(0), "The 0th Tribonacci should be 0."); + assertEquals(1, Tribonacci.compute(1), "The 1st Tribonacci should be 1."); + assertEquals(1, Tribonacci.compute(2), "The 2nd Tribonacci should be 1."); + assertEquals(2, Tribonacci.compute(3), "The 3rd Tribonacci should be 2."); + assertEquals(4, Tribonacci.compute(4), "The 4th Tribonacci should be 4."); + assertEquals(7, Tribonacci.compute(5), "The 5th Tribonacci should be 7."); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java new file mode 100644 index 000000000000..386938d28ec9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java @@ -0,0 +1,59 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class UniquePathsTests { + + @Test + public void testUniquePaths3x3() { + assertEquals(6, UniquePaths.uniquePaths(3, 3)); + } + + @Test + public void testUniquePaths1x1() { + assertEquals(1, UniquePaths.uniquePaths(1, 1)); + } + + @Test + public void testUniquePaths3x7() { + assertEquals(28, UniquePaths.uniquePaths(3, 7)); + } + + @Test + public void testUniquePaths7x3() { + assertEquals(28, UniquePaths.uniquePaths(7, 3)); + } + + @Test + public void testUniquePaths100x100() { + assertThrows(ArithmeticException.class, () -> UniquePaths.uniquePaths(100, 100)); + } + + @Test + public void testUniquePathsII3x3() { + assertEquals(6, UniquePaths.uniquePaths2(3, 3)); + } + + @Test + public void testUniquePathsII1x1() { + assertEquals(1, UniquePaths.uniquePaths2(1, 1)); + } + + @Test + public void testUniquePathsII3x7() { + assertEquals(28, UniquePaths.uniquePaths2(3, 7)); + } + + @Test + public void testUniquePathsII7x3() { + assertEquals(28, UniquePaths.uniquePaths2(7, 3)); + } + + @Test + public void testUniquePathsII100x100() { + assertThrows(ArithmeticException.class, () -> UniquePaths.uniquePaths2(100, 100)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java new file mode 100644 index 000000000000..56cd4ffe7d44 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.dynamicprogramming; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class WildcardMatchingTest { + + @Test + public void testMatchingPattern() { + assertTrue(WildcardMatching.isMatch("aa", "a*")); + assertTrue(WildcardMatching.isMatch("adceb", "*a*b")); + } + + @Test + public void testNonMatchingPattern() { + assertFalse(WildcardMatching.isMatch("cb", "?a")); + assertFalse(WildcardMatching.isMatch("acdcb", "a*c?b")); + assertFalse(WildcardMatching.isMatch("mississippi", "m*issi*iss?*i")); + } + + @Test + public void testEmptyPattern() { + assertTrue(WildcardMatching.isMatch("", "")); + assertFalse(WildcardMatching.isMatch("abc", "")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/dynamicprogramming/climbStairsTest.java b/Java/src/test/java/com/thealgorithms/dynamicprogramming/climbStairsTest.java new file mode 100644 index 000000000000..7df3127eec82 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/dynamicprogramming/climbStairsTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class climbStairsTest { + + @Test + void climbStairsTestForTwo() { + assertEquals(2, ClimbingStairs.numberOfWays(2)); + } + + @Test + void climbStairsTestForZero() { + assertEquals(0, ClimbingStairs.numberOfWays(0)); + } + + @Test + void climbStairsTestForOne() { + assertEquals(1, ClimbingStairs.numberOfWays(1)); + } + + @Test + void climbStairsTestForFive() { + assertEquals(8, ClimbingStairs.numberOfWays(5)); + } + + @Test + void climbStairsTestForThree() { + assertEquals(3, ClimbingStairs.numberOfWays(3)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java b/Java/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java new file mode 100644 index 000000000000..e59cd6b860cc --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java @@ -0,0 +1,16 @@ +package com.thealgorithms.geometry; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class GrahamScanTest { + @Test + void testGrahamScan() { + GrahamScan.Point[] points = {new GrahamScan.Point(0, 3), new GrahamScan.Point(1, 1), new GrahamScan.Point(2, 2), new GrahamScan.Point(4, 4), new GrahamScan.Point(0, 0), new GrahamScan.Point(1, 2), new GrahamScan.Point(3, 1), new GrahamScan.Point(3, 3)}; + String expectedResult = "[(0, 0), (3, 1), (4, 4), (0, 3)]"; + + GrahamScan graham = new GrahamScan(points); + assertEquals(expectedResult, graham.hull().toString()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java b/Java/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java new file mode 100644 index 000000000000..a997c198a39b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java @@ -0,0 +1,42 @@ +package com.thealgorithms.greedyalgorithms; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +public class ActivitySelectionTest { + @Test + public void testActivitySelection() { + int[] start = {1, 3, 0, 5, 8, 5}; + int[] end = {2, 4, 6, 7, 9, 9}; + + ArrayList<Integer> result = ActivitySelection.activitySelection(start, end); + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0, 1, 3, 4)); + + assertEquals(expected, result); + } + + @Test + public void testSingleActivity() { + int[] start = {1}; + int[] end = {2}; + + ArrayList<Integer> result = ActivitySelection.activitySelection(start, end); + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0)); + + assertEquals(expected, result); + } + + @Test + public void testNoOverlap() { + int[] start = {1, 2, 3}; + int[] end = {2, 3, 4}; + + ArrayList<Integer> result = ActivitySelection.activitySelection(start, end); + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0, 1, 2)); + + assertEquals(expected, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java b/Java/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java new file mode 100644 index 000000000000..e9d267712a05 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/greedyalgorithms/CoinChangeTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.greedyalgorithms; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +public class CoinChangeTest { + @Test + public void testCoinChangeProblemWithValidAmount() { + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(500, 50, 20, 20, 1)); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(591); + assertEquals(expected, coins); + } + + @Test + public void testCoinChangeProblemWithLargeAmount() { + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2000)); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(2000); + assertEquals(expected, coins); + } + + @Test + public void testCoinChangeProblemWithPartialCoins2() { + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(500, 50, 20)); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(570); + assertEquals(expected, coins); + } + + @Test + public void testCoinChangeProblemWithSmallAmount() { + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2, 1)); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(3); + assertEquals(expected, coins); + } + + @Test + public void testCoinChangeProblemWithLargeAmountAndMultipleDenominations() { + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2000, 2000, 2000, 2000, 500, 500, 500, 100, 100, 100, 100, 50, 20, 20, 5, 2, 2)); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(9999); + assertEquals(expected, coins); + } + + @Test + public void testCoinChangeProblemWithAllDenominations() { + ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(2000, 500, 100, 100, 100, 50, 20, 10, 5, 2, 1)); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(2888); + assertEquals(expected, coins); + } + + @Test + public void testCoinChangeProblemWithZeroAmount() { + ArrayList<Integer> expected = new ArrayList<>(); + ArrayList<Integer> coins = CoinChange.coinChangeProblem(0); + assertEquals(expected, coins); + } +} diff --git a/Java/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java b/Java/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java new file mode 100644 index 000000000000..34ec354ba6f0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.greedyalgorithms; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class FractionalKnapsackTest { + + @Test + public void testFractionalKnapsackWithExampleCase() { + int[] weight = {10, 20, 30}; + int[] value = {60, 100, 120}; + int capacity = 50; + assertEquals(240, FractionalKnapsack.fractionalKnapsack(weight, value, capacity)); + } + + @Test + public void testFractionalKnapsackWithZeroCapacity() { + int[] weight = {10, 20, 30}; + int[] value = {60, 100, 120}; + int capacity = 0; + assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity)); + } + + @Test + public void testFractionalKnapsackWithEmptyItems() { + int[] weight = {}; + int[] value = {}; + int capacity = 50; + assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java b/Java/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java new file mode 100644 index 000000000000..b679121689a1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.greedyalgorithms; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Collections; +import org.junit.jupiter.api.Test; + +public class JobSequencingTest { + @Test + public void testJobSequencingWithExampleCase() { + ArrayList<JobSequencing.Job> jobs = new ArrayList<>(); + jobs.add(new JobSequencing.Job('a', 2, 100)); + jobs.add(new JobSequencing.Job('b', 1, 19)); + jobs.add(new JobSequencing.Job('c', 2, 27)); + jobs.add(new JobSequencing.Job('d', 1, 25)); + jobs.add(new JobSequencing.Job('e', 3, 15)); + Collections.sort(jobs); + String jobSequence = JobSequencing.findJobSequence(jobs, jobs.size()); + + assertEquals("Job Sequence: c -> a -> e", jobSequence); + } +} diff --git a/Java/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java b/Java/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java new file mode 100644 index 000000000000..04f6900d14db --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/greedyalgorithms/MinimizingLatenessTest.java @@ -0,0 +1,43 @@ +package com.thealgorithms.greedyalgorithms; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.greedyalgorithms.MinimizingLateness.Job; +import org.junit.jupiter.api.Test; + +public class MinimizingLatenessTest { + + @Test + void testCalculateLateness() { + // Test case with three jobs + Job job1 = new Job("Job1", 4, 6); + Job job2 = new Job("Job2", 2, 8); + Job job3 = new Job("Job3", 1, 9); + Job job4 = new Job("Job4", 5, 9); + Job job5 = new Job("Job5", 4, 10); + Job job6 = new Job("Job6", 3, 5); + + MinimizingLateness.calculateLateness(job1, job2, job3, job4, job5, job6); + + // Check lateness for each job + assertEquals(6, job4.lateness); + assertEquals(0, job6.lateness); + assertEquals(1, job2.lateness); + } + + @Test + void testCheckStartTime() { + + Job job1 = new Job("Job1", 2, 5); + Job job2 = new Job("Job2", 1, 7); + Job job3 = new Job("Job3", 3, 8); + Job job4 = new Job("Job4", 2, 4); + Job job5 = new Job("Job5", 4, 10); + + MinimizingLateness.calculateLateness(job1, job2, job3, job4, job5); + + assertEquals(2, job1.startTime); + assertEquals(5, job3.startTime); + assertEquals(8, job5.startTime); + } +} diff --git a/Java/src/test/java/com/thealgorithms/io/BufferedReaderTest.java b/Java/src/test/java/com/thealgorithms/io/BufferedReaderTest.java new file mode 100644 index 000000000000..baccf319d15e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/io/BufferedReaderTest.java @@ -0,0 +1,97 @@ +package com.thealgorithms.io; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import org.junit.jupiter.api.Test; + +class BufferedReaderTest { + @Test + public void testPeeks() throws IOException { + String text = "Hello!\nWorld!"; + int len = text.length(); + byte[] bytes = text.getBytes(); + + ByteArrayInputStream input = new ByteArrayInputStream(bytes); + BufferedReader reader = new BufferedReader(input); + + // read the first letter + assertEquals(reader.read(), 'H'); + len--; + assertEquals(reader.available(), len); + + // position: H[e]llo!\nWorld! + // reader.read() will be == 'e' + assertEquals(reader.peek(1), 'l'); + assertEquals(reader.peek(2), 'l'); // second l + assertEquals(reader.peek(3), 'o'); + } + + @Test + public void testMixes() throws IOException { + String text = "Hello!\nWorld!"; + int len = text.length(); + byte[] bytes = text.getBytes(); + + ByteArrayInputStream input = new ByteArrayInputStream(bytes); + BufferedReader reader = new BufferedReader(input); + + // read the first letter + assertEquals(reader.read(), 'H'); // first letter + len--; + + assertEquals(reader.peek(1), 'l'); // third later (second letter after 'H') + assertEquals(reader.read(), 'e'); // second letter + len--; + assertEquals(reader.available(), len); + + // position: H[e]llo!\nWorld! + assertEquals(reader.peek(2), 'o'); // second l + assertEquals(reader.peek(3), '!'); + assertEquals(reader.peek(4), '\n'); + + assertEquals(reader.read(), 'l'); // third letter + assertEquals(reader.peek(1), 'o'); // fourth letter + + for (int i = 0; i < 6; i++) reader.read(); + try { + System.out.println((char) reader.peek(4)); + } catch (Exception ignored) { + System.out.println("[cached intentional error]"); + // intentional, for testing purpose + } + } + + @Test + public void testBlockPractical() throws IOException { + String text = "!Hello\nWorld!"; + byte[] bytes = text.getBytes(); + int len = bytes.length; + + ByteArrayInputStream input = new ByteArrayInputStream(bytes); + BufferedReader reader = new BufferedReader(input); + + assertEquals(reader.peek(), 'H'); + assertEquals(reader.read(), '!'); // read the first letter + len--; + + // this only reads the next 5 bytes (Hello) because + // the default buffer size = 5 + assertEquals(new String(reader.readBlock()), "Hello"); + len -= 5; + assertEquals(reader.available(), len); + + // maybe kind of a practical demonstration / use case + if (reader.read() == '\n') { + assertEquals(reader.read(), 'W'); + assertEquals(reader.read(), 'o'); + + // the rest of the blocks + assertEquals(new String(reader.readBlock()), "rld!"); + } else { + // should not reach + throw new IOException("Something not right"); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/ADTFractionTest.java b/Java/src/test/java/com/thealgorithms/maths/ADTFractionTest.java new file mode 100644 index 000000000000..938c7d558841 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/ADTFractionTest.java @@ -0,0 +1,52 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class ADTFractionTest { + + private final ADTFraction fraction1 = new ADTFraction(3, 5); + private final ADTFraction fraction2 = new ADTFraction(7, 8); + + @Test + void testConstructorWithDenominatorEqualToZero() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> new ADTFraction(1, 0)); + assertEquals("Denominator cannot be 0", exception.getMessage()); + } + + @Test + public void testPlus() { + assertEquals(new ADTFraction(59, 40), fraction1.plus(fraction2)); + } + + @Test + public void testTimes() { + assertEquals(new ADTFraction(12, 5), fraction1.times(4)); + assertEquals(new ADTFraction(21, 40), fraction1.times(fraction2)); + } + + @Test + public void testReciprocal() { + assertEquals(new ADTFraction(5, 3), fraction1.reciprocal()); + } + + @Test + public void testValue() { + assertEquals(0.6F, fraction1.value()); + } + + @Test + public void testEqualsAndHashCode() { + ADTFraction fraction3 = new ADTFraction(3, 5); + assertTrue(fraction1.equals(fraction3) && fraction3.equals(fraction1)); + assertEquals(fraction1.hashCode(), fraction3.hashCode()); + } + + @Test + public void testToString() { + assertEquals("3/5", fraction1.toString()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java b/Java/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java new file mode 100644 index 000000000000..85ffb91e27f4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AbsoluteMaxTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class AbsoluteMaxTest { + + @Test + void testGetMaxValue() { + assertEquals(16, AbsoluteMax.getMaxValue(-2, 0, 16)); + assertEquals(-22, AbsoluteMax.getMaxValue(-3, -10, -22)); + assertEquals(-888, AbsoluteMax.getMaxValue(-888)); + } + + @Test + void testGetMaxValueWithNoArguments() { + assertThrows(IllegalArgumentException.class, AbsoluteMax::getMaxValue); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java b/Java/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java new file mode 100644 index 000000000000..4b676ca634f7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AbsoluteMinTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class AbsoluteMinTest { + + @Test + void testGetMinValue() { + assertEquals(0, AbsoluteMin.getMinValue(4, 0, 16)); + assertEquals(-2, AbsoluteMin.getMinValue(3, -10, -2)); + } + + @Test + void testGetMinValueWithNoArguments() { + Exception exception = assertThrows(IllegalArgumentException.class, () -> AbsoluteMin.getMinValue()); + assertEquals("Numbers array cannot be empty", exception.getMessage()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java b/Java/src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java new file mode 100644 index 000000000000..f87652253641 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AbsoluteValueTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; + +public class AbsoluteValueTest { + + @Test + void testGetAbsValue() { + Stream.generate(() -> ThreadLocalRandom.current().nextInt()).limit(1000).forEach(number -> assertEquals(Math.abs(number), AbsoluteValue.getAbsValue(number))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AliquotSumTest.java b/Java/src/test/java/com/thealgorithms/maths/AliquotSumTest.java new file mode 100644 index 000000000000..94631637fc4f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AliquotSumTest.java @@ -0,0 +1,20 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class AliquotSumTest { + + @Test + void testGetMaxValue() { + assertEquals(0, AliquotSum.getAliquotValue(1)); + assertEquals(6, AliquotSum.getAliquotValue(6)); + assertEquals(9, AliquotSum.getAliquotValue(15)); + assertEquals(1, AliquotSum.getAliquotValue(19)); + assertEquals(0, AliquotSum.getAliquotSum(1)); + assertEquals(6, AliquotSum.getAliquotSum(6)); + assertEquals(9, AliquotSum.getAliquotSum(15)); + assertEquals(1, AliquotSum.getAliquotSum(19)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AmicableNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/AmicableNumberTest.java new file mode 100644 index 000000000000..14679f22636a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AmicableNumberTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.maths; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Set; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class AmicableNumberTest { + private static final String INVALID_RANGE_EXCEPTION_MESSAGE = "Given range of values is invalid!"; + private static final String INVALID_NUMBERS_EXCEPTION_MESSAGE = "Input numbers must be natural!"; + + @Test + public void testShouldThrowExceptionWhenInvalidRangeProvided() { + checkInvalidRange(0, 0); + checkInvalidRange(0, 1); + checkInvalidRange(1, 0); + checkInvalidRange(10, -1); + checkInvalidRange(-1, 10); + } + + @Test + public void testShouldThrowExceptionWhenInvalidNumbersProvided() { + checkInvalidNumbers(0, 0); + checkInvalidNumbers(0, 1); + checkInvalidNumbers(1, 0); + } + + @Test + public void testAmicableNumbers() { + assertThat(AmicableNumber.isAmicableNumber(220, 284)).isTrue(); + assertThat(AmicableNumber.isAmicableNumber(1184, 1210)).isTrue(); + assertThat(AmicableNumber.isAmicableNumber(2620, 2924)).isTrue(); + } + + @Test + public void testShouldFindAllAmicableNumbersInRange() { + // given + var expectedResult = Set.of(Pair.of(220, 284), Pair.of(1184, 1210), Pair.of(2620, 2924)); + + // when + Set<Pair<Integer, Integer>> result = AmicableNumber.findAllInRange(1, 3000); + + // then + Assertions.assertTrue(result.containsAll(expectedResult)); + } + + private static void checkInvalidRange(int from, int to) { + IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> AmicableNumber.findAllInRange(from, to)); + Assertions.assertEquals(exception.getMessage(), INVALID_RANGE_EXCEPTION_MESSAGE); + } + + private static void checkInvalidNumbers(int a, int b) { + IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> AmicableNumber.isAmicableNumber(a, b)); + Assertions.assertEquals(exception.getMessage(), INVALID_NUMBERS_EXCEPTION_MESSAGE); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AreaTest.java b/Java/src/test/java/com/thealgorithms/maths/AreaTest.java new file mode 100644 index 000000000000..b28afb85fbc3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AreaTest.java @@ -0,0 +1,103 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +/** + * @author Amarildo Aliaj + */ +class AreaTest { + + @Test + void testSurfaceAreaCube() { + assertEquals(6.0, Area.surfaceAreaCube(1)); + } + + @Test + void testSurfaceAreaSphere() { + assertEquals(12.566370614359172, Area.surfaceAreaSphere(1)); + } + + @Test + void testSurfaceAreaRectangle() { + assertEquals(200.0, Area.surfaceAreaRectangle(10, 20)); + } + + @Test + void testSurfaceAreaCylinder() { + assertEquals(18.84955592153876, Area.surfaceAreaCylinder(1, 2)); + } + + @Test + void testSurfaceAreaSquare() { + assertEquals(100.0, Area.surfaceAreaSquare(10)); + } + + @Test + void testSurfaceAreaTriangle() { + assertEquals(50.0, Area.surfaceAreaTriangle(10, 10)); + } + + @Test + void testSurfaceAreaParallelogram() { + assertEquals(200.0, Area.surfaceAreaParallelogram(10, 20)); + } + + @Test + void testSurfaceAreaTrapezium() { + assertEquals(450.0, Area.surfaceAreaTrapezium(10, 20, 30)); + } + + @Test + void testSurfaceAreaCircle() { + assertEquals(1256.6370614359173, Area.surfaceAreaCircle(20)); + } + + @Test + void surfaceAreaHemisphere() { + assertEquals(235.61944901923448, Area.surfaceAreaHemisphere(5)); + } + + @Test + void surfaceAreaCone() { + assertEquals(301.59289474462014, Area.surfaceAreaCone(6, 8)); + } + + @Test + void testAllIllegalInput() { + assertAll(() + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaCube(0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaSphere(0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaRectangle(0, 10)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaRectangle(10, 0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaCylinder(0, 1)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaCylinder(1, 0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaSquare(0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaTriangle(0, 1)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaTriangle(1, 0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaParallelogram(0, 1)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaParallelogram(1, 0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaTrapezium(0, 1, 1)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaTrapezium(1, 0, 1)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaTrapezium(1, 1, 0)), + () + -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaCircle(0)), + () -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaHemisphere(0)), () -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaCone(1, 0)), () -> assertThrows(IllegalArgumentException.class, () -> Area.surfaceAreaCone(0, 1))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/ArmstrongTest.java b/Java/src/test/java/com/thealgorithms/maths/ArmstrongTest.java new file mode 100644 index 000000000000..e5d0d9eb3c43 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/ArmstrongTest.java @@ -0,0 +1,25 @@ +package com.thealgorithms.maths; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +/** + * @author satyabarghav + * @since 4/10/2023 + */ +class ArmstrongTest { + + @Test + void testIsArmstrong() { + Armstrong armstrong = new Armstrong(); + assertThat(armstrong.isArmstrong(0)).isTrue(); + assertThat(armstrong.isArmstrong(1)).isTrue(); + assertThat(armstrong.isArmstrong(153)).isTrue(); + assertThat(armstrong.isArmstrong(371)).isTrue(); + assertThat(armstrong.isArmstrong(1634)).isTrue(); + assertThat(armstrong.isArmstrong(200)).isFalse(); + assertThat(armstrong.isArmstrong(548834)).isTrue(); + assertThat(armstrong.isArmstrong(9474)).isTrue(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java b/Java/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java new file mode 100644 index 000000000000..cacfe5904faa --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AutoCorrelationTest.java @@ -0,0 +1,37 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +/** + * Test class for AutoCorrelation class + * + * @author Athina-Frederiki Swinkels + * @version 2.0 + */ + +public class AutoCorrelationTest { + + @ParameterizedTest + @CsvSource({"1;2;1;1, 1;3;5;7;5;3;1", "1;2;3, 3;8;14;8;3", "1.5;2.3;3.1;4.2, 6.3;14.31;23.6;34.79;23.6;14.31;6.3"}) + + public void testAutoCorrelationParameterized(String input, String expected) { + double[] array = convertStringToArray(input); + double[] expectedResult = convertStringToArray(expected); + + double[] result = AutoCorrelation.autoCorrelation(array); + + assertArrayEquals(expectedResult, result, 0.0001); + } + + private double[] convertStringToArray(String input) { + String[] elements = input.split(";"); + double[] result = new double[elements.length]; + for (int i = 0; i < elements.length; i++) { + result[i] = Double.parseDouble(elements[i]); + } + return result; + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java new file mode 100644 index 000000000000..0a366cd1adbe --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class AutomorphicNumberTest { + + @Test + void testAutomorphicNumber() { + int[] trueTestCases = {0, 1, 25, 625, 12890625}; + int[] falseTestCases = {-5, 2, 26, 1234}; + for (Integer n : trueTestCases) { + assertTrue(AutomorphicNumber.isAutomorphic(n)); + assertTrue(AutomorphicNumber.isAutomorphic2(n)); + assertTrue(AutomorphicNumber.isAutomorphic3(String.valueOf(n))); + } + for (Integer n : falseTestCases) { + assertFalse(AutomorphicNumber.isAutomorphic(n)); + assertFalse(AutomorphicNumber.isAutomorphic2(n)); + assertFalse(AutomorphicNumber.isAutomorphic3(String.valueOf(n))); + } + assertTrue(AutomorphicNumber.isAutomorphic3("59918212890625")); // Special case for BigInteger + assertFalse(AutomorphicNumber.isAutomorphic3("12345678912345")); // Special case for BigInteger + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/AverageTest.java b/Java/src/test/java/com/thealgorithms/maths/AverageTest.java new file mode 100644 index 000000000000..c5c751938f5d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/AverageTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class AverageTest { + + private static final double SMALL_VALUE = 0.00001d; + + @Test + public void testAverageDouble12() { + double[] numbers = {3d, 6d, 9d, 12d, 15d, 18d, 21d}; + Assertions.assertEquals(12d, Average.average(numbers), SMALL_VALUE); + } + + @Test + public void testAverageDouble20() { + double[] numbers = {5d, 10d, 15d, 20d, 25d, 30d, 35d}; + Assertions.assertEquals(20d, Average.average(numbers), SMALL_VALUE); + } + + @Test + public void testAverageDouble() { + double[] numbers = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d}; + Assertions.assertEquals(4.5d, Average.average(numbers), SMALL_VALUE); + } + + @Test + public void testAverageInt() { + int[] numbers = {2, 4, 10}; + Assertions.assertEquals(5, Average.average(numbers)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/BinaryPowTest.java b/Java/src/test/java/com/thealgorithms/maths/BinaryPowTest.java new file mode 100644 index 000000000000..f9b019e8fad4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/BinaryPowTest.java @@ -0,0 +1,16 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinaryPowTest { + + @Test + void testBinPow() { + assertEquals(4, BinaryPow.binPow(2, 2)); + assertEquals(256, BinaryPow.binPow(4, 4)); + assertEquals(729, BinaryPow.binPow(9, 3)); + assertEquals(262144, BinaryPow.binPow(8, 6)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java b/Java/src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java new file mode 100644 index 000000000000..58cfcbad57fb --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/BinomialCoefficientTest.java @@ -0,0 +1,16 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class BinomialCoefficientTest { + + @Test + void testBinomialCoefficient() { + assertEquals(190, BinomialCoefficient.binomialCoefficient(20, 2)); + assertEquals(792, BinomialCoefficient.binomialCoefficient(12, 5)); + assertEquals(84, BinomialCoefficient.binomialCoefficient(9, 3)); + assertEquals(1, BinomialCoefficient.binomialCoefficient(17, 17)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/CeilTest.java b/Java/src/test/java/com/thealgorithms/maths/CeilTest.java new file mode 100644 index 000000000000..5596760a8c40 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/CeilTest.java @@ -0,0 +1,17 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class CeilTest { + + @Test + void testCeil() { + assertEquals(8, Ceil.ceil(7.057)); + assertEquals(8, Ceil.ceil(7.004)); + assertEquals(-13, Ceil.ceil(-13.004)); + assertEquals(1, Ceil.ceil(.98)); + assertEquals(-11, Ceil.ceil(-11.357)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java b/Java/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java new file mode 100644 index 000000000000..4e88d1e91bac --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java @@ -0,0 +1,41 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class CollatzConjectureTest { + + static CollatzConjecture cConjecture; + + @BeforeAll + static void setUp() { + cConjecture = new CollatzConjecture(); + } + + @Test + void nextNumberFromEvenNumber() { + assertEquals(25, cConjecture.nextNumber(50)); + } + + @Test + void nextNumberFromOddNumber() { + assertEquals(154, cConjecture.nextNumber(51)); + } + + @Test + void collatzConjecture() { + final List<Integer> expected = List.of(35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1); + assertIterableEquals(expected, cConjecture.collatzConjecture(35)); + } + + @Test + void sequenceOfNotNaturalFirstNumber() { + assertThrows(IllegalArgumentException.class, () -> cConjecture.collatzConjecture(0)); + assertThrows(IllegalArgumentException.class, () -> cConjecture.collatzConjecture(-1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/CombinationsTest.java b/Java/src/test/java/com/thealgorithms/maths/CombinationsTest.java new file mode 100644 index 000000000000..f260b1e11494 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/CombinationsTest.java @@ -0,0 +1,26 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class CombinationsTest { + + @Test + void testCombination() { + assertEquals(1, Combinations.combinations(1, 1)); + assertEquals(252, Combinations.combinations(10, 5)); + assertEquals(20, Combinations.combinations(6, 3)); + assertEquals(15504, Combinations.combinations(20, 5)); + } + + @Test + void testCombinationOptimised() { + assertEquals(100, Combinations.combinationsOptimized(100, 1)); + assertEquals(1, Combinations.combinationsOptimized(1, 1)); + assertEquals(252, Combinations.combinationsOptimized(10, 5)); + assertEquals(20, Combinations.combinationsOptimized(6, 3)); + assertEquals(15504, Combinations.combinationsOptimized(20, 5)); + assertEquals(2535650040L, Combinations.combinationsOptimized(200, 5)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java b/Java/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java new file mode 100644 index 000000000000..a7e4f14fb3af --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/CrossCorrelationTest.java @@ -0,0 +1,37 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +/** + * Test class for CrossCorrelation class + * + * @author Athina-Frederiki Swinkels + * @version 2.0 + */ +public class CrossCorrelationTest { + + @ParameterizedTest + @CsvSource({"1;2;1;1, 1;1;2;1, 1;4;6;6;5;2;1", "1;2;3, 1;2;3;4;5, 5;14;26;20;14;8;3", "1;2;3;4;5, 1;2;3, 3;8;14;20;26;14;5", "1.5;2.3;3.1;4.2, 1.1;2.2;3.3, 4.95;10.89;16.94;23.21;12.65;4.62"}) + + public void testCrossCorrelationParameterized(String input1, String input2, String expected) { + double[] array1 = convertStringToArray(input1); + double[] array2 = convertStringToArray(input2); + double[] expectedResult = convertStringToArray(expected); + + double[] result = CrossCorrelation.crossCorrelation(array1, array2); + + assertArrayEquals(expectedResult, result, 0.0001); + } + + private double[] convertStringToArray(String input) { + String[] elements = input.split(";"); + double[] result = new double[elements.length]; + for (int i = 0; i < elements.length; i++) { + result[i] = Double.parseDouble(elements[i]); + } + return result; + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/DigitalRootTest.java b/Java/src/test/java/com/thealgorithms/maths/DigitalRootTest.java new file mode 100644 index 000000000000..eeeeb5431507 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/DigitalRootTest.java @@ -0,0 +1,18 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class DigitalRootTest { + + @Test + void testDigitalroot() { + assertEquals(4, DigitalRoot.digitalRoot(4)); + assertEquals(9, DigitalRoot.digitalRoot(9)); + assertEquals(4, DigitalRoot.digitalRoot(49)); + assertEquals(6, DigitalRoot.digitalRoot(78)); + assertEquals(4, DigitalRoot.digitalRoot(1228)); + assertEquals(5, DigitalRoot.digitalRoot(71348)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java b/Java/src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java new file mode 100644 index 000000000000..3a14b80dd4f9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/DistanceFormulaTest.java @@ -0,0 +1,86 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class DistanceFormulaTest { + + @Test + void euclideanTest1() { + Assertions.assertEquals(DistanceFormula.euclideanDistance(1, 1, 2, 2), 1.4142135623730951); + } + + @Test + void euclideanTest2() { + Assertions.assertEquals(DistanceFormula.euclideanDistance(1, 3, 8, 0), 7.0710678118654755); + } + + @Test + void euclideanTest3() { + Assertions.assertEquals(DistanceFormula.euclideanDistance(2.4, 9.1, 55.1, 100), 110.91911467371168); + } + + @Test + void euclideanTest4() { + Assertions.assertEquals(DistanceFormula.euclideanDistance(1000, 13, 20000, 84), 19022.067605809836); + } + + @Test + public void manhattantest1() { + assertEquals(DistanceFormula.manhattanDistance(1, 2, 3, 4), 4); + } + + @Test + public void manhattantest2() { + assertEquals(DistanceFormula.manhattanDistance(6.5, 8.4, 20.1, 13.6), 18.8); + } + + @Test + public void manhattanTest3() { + assertEquals(DistanceFormula.manhattanDistance(10.112, 50, 8, 25.67), 26.442); + } + + @Test + public void hammingTest1() { + int[] array1 = {1, 1, 1, 1}; + int[] array2 = {0, 0, 0, 0}; + assertEquals(DistanceFormula.hammingDistance(array1, array2), 4); + } + + @Test + public void hammingTest2() { + int[] array1 = {1, 1, 1, 1}; + int[] array2 = {1, 1, 1, 1}; + assertEquals(DistanceFormula.hammingDistance(array1, array2), 0); + } + + @Test + public void hammingTest3() { + int[] array1 = {1, 0, 0, 1, 1, 0, 1, 1, 0}; + int[] array2 = {0, 1, 0, 0, 1, 1, 1, 0, 0}; + assertEquals(DistanceFormula.hammingDistance(array1, array2), 5); + } + + @Test + public void minkowskiTest1() { + double[] array1 = {1, 3, 8, 5}; + double[] array2 = {4, 2, 6, 9}; + assertEquals(DistanceFormula.minkowskiDistance(array1, array2, 1), 10); + } + + @Test + public void minkowskiTest2() { + double[] array1 = {1, 3, 8, 5}; + double[] array2 = {4, 2, 6, 9}; + assertEquals(DistanceFormula.minkowskiDistance(array1, array2, 2), 5.477225575051661); + } + + @Test + public void minkowskiTest3() { + double[] array1 = {1, 3, 8, 5}; + double[] array2 = {4, 2, 6, 9}; + assertEquals(DistanceFormula.minkowskiDistance(array1, array2, 3), 4.641588833612778); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java new file mode 100644 index 000000000000..cd93edfae61d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class DudeneyNumberTest { + @ParameterizedTest + @CsvSource({"1", "512", "4913", "5832", "17576", "19683"}) + void positiveDudeneyBase10Power3(final int n) { + assertTrue(DudeneyNumber.isDudeney(n)); + } + + @ParameterizedTest + @CsvSource({"2", "19", "21", "125", "27", "343", "729", "19682", "19684"}) + void negativeDudeneyBase10Power3(final int n) { + assertFalse(DudeneyNumber.isDudeney(n)); + } + + @ParameterizedTest + @CsvSource({"0", "-1"}) + void throwsInputLessThanOne(final int n) { + assertThrows(IllegalArgumentException.class, () -> DudeneyNumber.isDudeney(n)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FFTTest.java b/Java/src/test/java/com/thealgorithms/maths/FFTTest.java new file mode 100644 index 000000000000..696ab5a24732 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FFTTest.java @@ -0,0 +1,138 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; + +import java.util.ArrayList; +import org.junit.jupiter.api.Test; + +class FFTTest { + + // Testing the simple function getReal + @Test + void getRealtest() { + FFT.Complex complex = new FFT.Complex(1.0, 1.0); + assertEquals(1.0, complex.getReal()); + } + + // Testing the simple function getImaginary + @Test + void getImaginaryTest() { + FFT.Complex complex = new FFT.Complex(); + assertEquals(0.0, complex.getImaginary()); + } + + // Testing the function add, assertEqual test + @Test + void addTest() { + FFT.Complex complex1 = new FFT.Complex(1.0, 1.0); + FFT.Complex complex2 = new FFT.Complex(2.0, 2.0); + double add = complex1.add(complex2).getReal(); + assertEquals(3.0, add); + } + + // Testing the function add, assertNotEqual test + @Test + void addFalseTest() { + FFT.Complex complex1 = new FFT.Complex(1.0, 1.0); + FFT.Complex complex2 = new FFT.Complex(2.0, 2.0); + double add = complex1.add(complex2).getReal(); + assertNotEquals(2.0, add); + } + + // Testing the function substract, assertEqual test + @Test + void subtractTest() { + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + FFT.Complex complex2 = new FFT.Complex(1.0, 1.0); + double sub = complex1.subtract(complex2).getReal(); + assertEquals(1.0, sub); + } + + // Testing the function multiply complex, assertEqual test + @Test + void multiplyWithComplexTest() { + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + FFT.Complex complex2 = new FFT.Complex(1.0, 1.0); + double multiReal = complex1.multiply(complex2).getReal(); + double multiImg = complex1.multiply(complex2).getImaginary(); + assertEquals(0.0, multiReal); + assertEquals(4.0, multiImg); + } + + // Testing the function multiply scalar, assertEqual test + @Test + void multiplyWithScalarTest() { + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + + double multiReal = complex1.multiply(2).getReal(); + double multiImg = complex1.multiply(3).getImaginary(); + assertEquals(4.0, multiReal); + assertEquals(6.0, multiImg); + } + + // Testing the function conjugate, assertEqual test + @Test + void conjugateTest() { + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + double conReal = complex1.conjugate().getReal(); + double conImg = complex1.conjugate().getImaginary(); + assertEquals(2.0, conReal); + assertEquals(-2.0, conImg); + } + + // Testing the function abs, assertEqual test + @Test + void abs() { + FFT.Complex complex1 = new FFT.Complex(2.0, 3.0); + double abs = complex1.abs(); + assertEquals(Math.sqrt(13), abs); + } + + // Testing the function divide complex, assertEqual test. + @Test + void divideWithComplexTest() { + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + FFT.Complex complex2 = new FFT.Complex(1.0, 2.0); + double divReal = complex1.divide(complex2).getReal(); + double divImg = complex1.divide(complex2).getImaginary(); + assertEquals(1.2, divReal); + assertEquals(-0.4, divImg); + } + + // Testing the function divide scalar, assertEqual test. + @Test + void divideWithScalarTest() { + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + double divReal = complex1.divide(2).getReal(); + double divImg = complex1.divide(2).getImaginary(); + assertEquals(1, divReal); + assertEquals(1, divImg); + } + + // Testing the function fft, assertEqual test. + // https://scistatcalc.blogspot.com/2013/12/fft-calculator.html used this link to + // ensure the result + @Test + void fft() { + ArrayList<FFT.Complex> arr = new ArrayList<FFT.Complex>(); + FFT.Complex complex1 = new FFT.Complex(2.0, 2.0); + FFT.Complex complex2 = new FFT.Complex(1.0, 3.0); + FFT.Complex complex3 = new FFT.Complex(3.0, 1.0); + FFT.Complex complex4 = new FFT.Complex(2.0, 2.0); + + arr.add(complex1); + arr.add(complex2); + arr.add(complex3); + arr.add(complex4); + arr = FFT.fft(arr, false); + double realV1 = arr.get(0).getReal(); + double realV2 = arr.get(2).getReal(); + double imgV1 = arr.get(0).getImaginary(); + double imgV2 = arr.get(2).getImaginary(); + assertEquals(8.0, realV1); + assertEquals(2.0, realV2); + assertEquals(8.0, imgV1); + assertEquals(-2.0, imgV2); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java b/Java/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java new file mode 100644 index 000000000000..db18b46356b4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class FactorialRecursionTest { + @ParameterizedTest + @MethodSource("inputStream") + void testFactorialRecursion(long expected, int number) { + assertEquals(expected, FactorialRecursion.factorial(number)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(1, 0), Arguments.of(1, 1), Arguments.of(2, 2), Arguments.of(6, 3), Arguments.of(120, 5)); + } + + @Test + void testThrowsForNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> FactorialRecursion.factorial(-1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FactorialTest.java b/Java/src/test/java/com/thealgorithms/maths/FactorialTest.java new file mode 100644 index 000000000000..b38dc45589ee --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FactorialTest.java @@ -0,0 +1,24 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class FactorialTest { + private static final String EXCEPTION_MESSAGE = "Input number cannot be negative"; + + @Test + public void testWhenInvalidInoutProvidedShouldThrowException() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> Factorial.factorial(-1)); + assertEquals(exception.getMessage(), EXCEPTION_MESSAGE); + } + + @Test + public void testCorrectFactorialCalculation() { + assertEquals(1, Factorial.factorial(0)); + assertEquals(1, Factorial.factorial(1)); + assertEquals(120, Factorial.factorial(5)); + assertEquals(3628800, Factorial.factorial(10)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java b/Java/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java new file mode 100644 index 000000000000..a3416a6bc871 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java @@ -0,0 +1,50 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.junit.jupiter.api.Test; + +public class FastInverseSqrtTests { + + @Test + void testForOneElement() { + assertFalse(FastInverseSqrt.inverseSqrt(1332)); + // calls for the 2nd inverse method + } + + @Test + void testForsecond() { + assertFalse(FastInverseSqrt.inverseSqrt(1332f)); + // calls for the 1st inverse method + } + + @Test + void testForThird() { + assertFalse(FastInverseSqrt.inverseSqrt(1)); + } + + @Test + void testForFourth() { + assertFalse(FastInverseSqrt.inverseSqrt(1f)); + } + + @Test + void testForFifth() { + assertFalse(FastInverseSqrt.inverseSqrt(4522)); + } + + @Test + void testForSixth() { + assertFalse(FastInverseSqrt.inverseSqrt(4522f)); + } + + @Test + void testForSeventh() { + assertFalse(FastInverseSqrt.inverseSqrt(21)); + } + + @Test + void testForEighth() { + assertFalse(FastInverseSqrt.inverseSqrt(21f)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java b/Java/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java new file mode 100644 index 000000000000..2c81a6304d8f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java @@ -0,0 +1,71 @@ +package com.thealgorithms.maths; + +import java.math.BigDecimal; +import java.util.Optional; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 25/07/2023 + */ +public class FibonacciJavaStreamsTest { + private static final String EXCEPTION_MESSAGE = "Input index cannot be null or negative!"; + + @Test + public void testWithNegativeIndexShouldThrowException() { + Exception exception = Assertions.assertThrows(IllegalArgumentException.class, () -> FibonacciJavaStreams.calculate(new BigDecimal(-1))); + Assertions.assertEquals(EXCEPTION_MESSAGE, exception.getMessage()); + } + + @Test + public void testCheckTheFirst4SequenceElements() { + checkElement(BigDecimal.ZERO, BigDecimal.ZERO); + checkElement(BigDecimal.ONE, BigDecimal.ONE); + checkElement(new BigDecimal(2), BigDecimal.ONE); + checkElement(new BigDecimal(3), new BigDecimal(2)); + } + + @Test + public void testCheck10thSequenceElement() { + checkElement(new BigDecimal(10), new BigDecimal(55)); + } + + @Test + public void testCheck20thSequenceElement() { + checkElement(new BigDecimal(20), new BigDecimal(6765)); + } + + @Test + public void testCheck30thSequenceElement() { + checkElement(new BigDecimal(30), new BigDecimal(832040)); + } + + @Test + public void testCheck40thSequenceElement() { + checkElement(new BigDecimal(40), new BigDecimal(102334155)); + } + + @Test + public void testCheck50thSequenceElement() { + checkElement(new BigDecimal(50), new BigDecimal(12586269025L)); + } + + @Test + public void testCheck100thSequenceElement() { + checkElement(new BigDecimal(100), new BigDecimal("354224848179261915075")); + } + + @Test + public void testCheck200thSequenceElement() { + checkElement(new BigDecimal(200), new BigDecimal("280571172992510140037611932413038677189525")); + } + + private static void checkElement(BigDecimal index, BigDecimal expected) { + // when + Optional<BigDecimal> result = FibonacciJavaStreams.calculate(index); + + // then + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals(result.get(), expected); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java b/Java/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java new file mode 100644 index 000000000000..93aec39765d4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FibonacciLoopTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.math.BigInteger; +import org.junit.jupiter.api.Test; + +public class FibonacciLoopTest { + @Test + public void checkValueAtZero() { + assertEquals(BigInteger.ZERO, FibonacciLoop.compute(0)); + } + + @Test + public void checkValueAtOne() { + assertEquals(BigInteger.ONE, FibonacciLoop.compute(1)); + } + + @Test + public void checkValueAtTwo() { + assertEquals(BigInteger.ONE, FibonacciLoop.compute(2)); + } + + @Test + public void checkRecurrenceRelation() { + for (int i = 0; i < 100; ++i) { + assertEquals(FibonacciLoop.compute(i + 2), FibonacciLoop.compute(i + 1).add(FibonacciLoop.compute(i))); + } + } + + @Test + public void checkNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> { FibonacciLoop.compute(-1); }); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java b/Java/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java new file mode 100644 index 000000000000..6ba81639a11a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FibonacciNumberCheckTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * Fibonacci Sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144... + * + * @author Albina Gimaletdinova on 01/07/2023 + */ +public class FibonacciNumberCheckTest { + @Test + public void testNumberIsFibonacciNumber() { + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(1)); + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(2)); + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(21)); + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(6765)); // 20th number + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(832040)); // 30th number + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(102334155)); // 40th number + Assertions.assertTrue(FibonacciNumberCheck.isFibonacciNumber(701408733)); // 45th number + } + + @Test + public void testNumberIsNotFibonacciNumber() { + Assertions.assertFalse(FibonacciNumberCheck.isFibonacciNumber(9)); + Assertions.assertFalse(FibonacciNumberCheck.isFibonacciNumber(10)); + Assertions.assertFalse(FibonacciNumberCheck.isFibonacciNumber(145)); + Assertions.assertFalse(FibonacciNumberCheck.isFibonacciNumber(701408734)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java b/Java/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java new file mode 100644 index 000000000000..e3f7bf3e0fed --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FibonacciNumberGoldenRationTest.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.math.BigInteger; +import org.junit.jupiter.api.Test; + +public class FibonacciNumberGoldenRationTest { + + @Test + public void returnsCorrectValues() { + for (int n = 0; n <= FibonacciNumberGoldenRation.MAX_ARG; ++n) { + final var actual = FibonacciNumberGoldenRation.compute(n); + final var expected = FibonacciLoop.compute(n); + assertEquals(expected, BigInteger.valueOf(actual)); + } + } + + @Test + public void throwsIllegalArgumentExceptionForNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> { FibonacciNumberGoldenRation.compute(-1); }); + } + + @Test + public void throwsIllegalArgumentExceptionForLargeInput() { + assertThrows(IllegalArgumentException.class, () -> { FibonacciNumberGoldenRation.compute(FibonacciNumberGoldenRation.MAX_ARG + 1); }); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java b/Java/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java new file mode 100644 index 000000000000..d54cae67209f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FindMaxRecursionTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class FindMaxRecursionTest { + + @ParameterizedTest + @MethodSource("inputStream") + void numberTests(int expected, int[] input) { + Assertions.assertEquals(expected, FindMaxRecursion.max(input)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {-1, 0}), Arguments.of(-1, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), Arguments.of(9, new int[] {3, -2, 3, 9, -4, -4, 8}), Arguments.of(3, new int[] {3})); + } + + @Test + public void testFindMaxThrowsExceptionForEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> FindMaxRecursion.max(new int[] {})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FindMaxTest.java b/Java/src/test/java/com/thealgorithms/maths/FindMaxTest.java new file mode 100644 index 000000000000..a863a2c8586b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FindMaxTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class FindMaxTest { + + @ParameterizedTest + @MethodSource("inputStream") + void numberTests(int expected, int[] input) { + Assertions.assertEquals(expected, FindMax.findMax(input)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(10, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {-1, 0}), Arguments.of(-1, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), Arguments.of(9, new int[] {3, -2, 3, 9, -4, -4, 8})); + } + + @Test + public void testFindMaxThrowsExceptionForEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> FindMax.findMax(new int[] {})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java b/Java/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java new file mode 100644 index 000000000000..3c36702b881d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FindMinRecursionTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class FindMinRecursionTest { + + @ParameterizedTest + @MethodSource("inputStream") + void numberTests(int expected, int[] input) { + Assertions.assertEquals(expected, FindMinRecursion.min(input)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(-1, new int[] {-1, 0}), Arguments.of(-10, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), Arguments.of(-4, new int[] {3, -2, 3, 9, -4, -4, 8}), Arguments.of(3, new int[] {3})); + } + + @Test + public void testFindMaxThrowsExceptionForEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> FindMinRecursion.min(new int[] {})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FindMinTest.java b/Java/src/test/java/com/thealgorithms/maths/FindMinTest.java new file mode 100644 index 000000000000..e713c0191ea1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FindMinTest.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class FindMinTest { + + @ParameterizedTest + @MethodSource("inputStream") + void numberTests(int expected, int[] input) { + Assertions.assertEquals(expected, FindMin.findMin(input)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(1, new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), Arguments.of(5, new int[] {5, 5, 5, 5, 5}), Arguments.of(0, new int[] {0, 192, 384, 576}), Arguments.of(-1, new int[] {-1, 2, 5, 10}), Arguments.of(-10, new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}), + Arguments.of(-4, new int[] {4, -3, 8, 9, -4, -4, 10})); + } + + @Test + public void testFindMinThrowsExceptionForEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> FindMin.findMin(new int[] {})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FloorTest.java b/Java/src/test/java/com/thealgorithms/maths/FloorTest.java new file mode 100644 index 000000000000..19aed70ccb71 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FloorTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +public class FloorTest { + @Test + public void testFloorWholeNumber() { + assertEquals(0, Floor.floor(0)); + assertEquals(1, Floor.floor(1)); + assertEquals(-1, Floor.floor(-1)); + assertEquals(42, Floor.floor(42)); + assertEquals(-42, Floor.floor(-42)); + } + + @Test + public void testFloorDoubleNumber() { + assertEquals(0, Floor.floor(0.1)); + assertEquals(1, Floor.floor(1.9)); + assertEquals(-2, Floor.floor(-1.1)); + assertEquals(-43, Floor.floor(-42.7)); + } + + @Test + public void testFloorNegativeZero() { + assertEquals(-0.0, Floor.floor(-0.0)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java new file mode 100644 index 000000000000..a5fd867e900e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/FrizzyNumberTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; +public class FrizzyNumberTest { + @Test + public void testFrizziesForBase2() { + assertEquals(1, FrizzyNumber.getNthFrizzy(2, 1)); + assertEquals(3, FrizzyNumber.getNthFrizzy(2, 3)); + assertEquals(1000, FrizzyNumber.getNthFrizzy(2, 1000)); + } + + @Test + public void testFrizziesForBase3() { + assertEquals(1, FrizzyNumber.getNthFrizzy(3, 1)); + assertEquals(3, FrizzyNumber.getNthFrizzy(3, 2)); + assertEquals(29430, FrizzyNumber.getNthFrizzy(3, 1000)); + } + + @Test + public void testFrizziesForBase69() { + assertEquals(1, FrizzyNumber.getNthFrizzy(69, 1)); + assertEquals(69, FrizzyNumber.getNthFrizzy(69, 2)); + assertEquals(328510, FrizzyNumber.getNthFrizzy(69, 9)); + assertEquals(333340, FrizzyNumber.getNthFrizzy(69, 15)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/GCDTest.java b/Java/src/test/java/com/thealgorithms/maths/GCDTest.java new file mode 100644 index 000000000000..5a659664fd29 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/GCDTest.java @@ -0,0 +1,57 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class GCDTest { + + @Test + void test1() { + Assertions.assertThrows(ArithmeticException.class, () -> GCD.gcd(-1, 0)); + } + + @Test + void test2() { + Assertions.assertThrows(ArithmeticException.class, () -> GCD.gcd(10, -2)); + } + + @Test + void test3() { + Assertions.assertThrows(ArithmeticException.class, () -> GCD.gcd(-5, -3)); + } + + @Test + void test4() { + Assertions.assertEquals(GCD.gcd(0, 2), 2); + } + + @Test + void test5() { + Assertions.assertEquals(GCD.gcd(10, 0), 10); + } + + @Test + void test6() { + Assertions.assertEquals(GCD.gcd(1, 0), 1); + } + + @Test + void test7() { + Assertions.assertEquals(GCD.gcd(9, 6), 3); + } + + @Test + void testArrayGcd1() { + Assertions.assertEquals(GCD.gcd(new int[] {9, 6}), 3); + } + + @Test + void testArrayGcd2() { + Assertions.assertEquals(GCD.gcd(new int[] {2 * 3 * 5 * 7, 2 * 5 * 5 * 5, 2 * 5 * 11, 5 * 5 * 5 * 13}), 5); + } + + @Test + void testArrayGcdForEmptyInput() { + Assertions.assertEquals(GCD.gcd(new int[] {}), 0); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/GaussianTest.java b/Java/src/test/java/com/thealgorithms/maths/GaussianTest.java new file mode 100644 index 000000000000..16b8da1338e7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/GaussianTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.maths; + +import static com.thealgorithms.maths.Gaussian.gaussian; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import org.junit.jupiter.api.Test; + +public class GaussianTest { + + // easy pass test for the whole class. Matrix of 2*3. + @Test + void passTest1() { + ArrayList<Double> list = new ArrayList<Double>(); + ArrayList<Double> gaussian = new ArrayList<Double>(); + ArrayList<Double> answer = new ArrayList<Double>(); + answer.add(0.0); + answer.add(1.0); + + int matrixSize = 2; + list.add(1.0); + list.add(1.0); + list.add(1.0); + list.add(2.0); + list.add(1.0); + list.add(1.0); + gaussian = gaussian(matrixSize, list); + + assertEquals(answer, gaussian); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/GenericRootTest.java b/Java/src/test/java/com/thealgorithms/maths/GenericRootTest.java new file mode 100644 index 000000000000..50858cde1ef0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/GenericRootTest.java @@ -0,0 +1,24 @@ +package com.thealgorithms.maths; + +import static java.util.Map.entry; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Map; +import org.junit.jupiter.api.Test; + +public class GenericRootTest { + private final Map<Integer, Integer> testCases = Map.ofEntries(entry(0, 0), entry(1, 1), entry(12345, 6), entry(123, 6), entry(15937, 7), entry(222222, 3), entry(99999, 9)); + @Test + public void testGenericRoot() { + for (final var tc : testCases.entrySet()) { + assertEquals(tc.getValue(), GenericRoot.genericRoot(tc.getKey())); + } + } + + @Test + public void testGenericRootWithNegativeInputs() { + for (final var tc : testCases.entrySet()) { + assertEquals(tc.getValue(), GenericRoot.genericRoot(-tc.getKey())); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java new file mode 100644 index 000000000000..af1c459f3d7f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java @@ -0,0 +1,25 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class HarshadNumberTest { + + @Test + public void harshadNumber() { + + assertTrue(HarshadNumber.isHarshad(18)); + assertFalse(HarshadNumber.isHarshad(-18)); + assertFalse(HarshadNumber.isHarshad(19)); + assertTrue(HarshadNumber.isHarshad(999999999)); + assertFalse(HarshadNumber.isHarshad(0)); + + assertTrue(HarshadNumber.isHarshad("18")); + assertFalse(HarshadNumber.isHarshad("-18")); + assertFalse(HarshadNumber.isHarshad("19")); + assertTrue(HarshadNumber.isHarshad("999999999")); + assertTrue(HarshadNumber.isHarshad("99999999999100")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java b/Java/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java new file mode 100644 index 000000000000..22cecf4dc960 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/HeronsFormulaTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class HeronsFormulaTest { + + @Test + void test1() { + Assertions.assertEquals(HeronsFormula.herons(3, 4, 5), 6.0); + } + + @Test + void test2() { + Assertions.assertEquals(HeronsFormula.herons(24, 30, 18), 216.0); + } + + @Test + void test3() { + Assertions.assertEquals(HeronsFormula.herons(1, 1, 1), 0.4330127018922193); + } + + @Test + void test4() { + Assertions.assertEquals(HeronsFormula.herons(4, 5, 8), 8.181534085976786); + } + + @Test + public void testCalculateAreaWithInvalidInput() { + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 2, 3); }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(2, 1, 3); }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(3, 2, 1); }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 3, 2); }); + + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 1, 0); }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(1, 0, 1); }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { HeronsFormula.herons(0, 1, 1); }); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/JosephusProblemTest.java b/Java/src/test/java/com/thealgorithms/maths/JosephusProblemTest.java new file mode 100644 index 000000000000..650b8dd578f7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/JosephusProblemTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class JosephusProblemTest { + + @Test + void testJosephusProblem() { + assertEquals(3, JosephusProblem.findTheWinner(5, 2)); + assertEquals(5, JosephusProblem.findTheWinner(6, 4)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java b/Java/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java new file mode 100644 index 000000000000..05e58cf88e22 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java @@ -0,0 +1,85 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class KaprekarNumbersTest { + + @Test + void testFor1() { + assertTrue(KaprekarNumbers.isKaprekarNumber(1)); + } + + @Test + void testFor45() { + assertTrue(KaprekarNumbers.isKaprekarNumber(45)); + } + + @Test + void testFor297() { + assertTrue(KaprekarNumbers.isKaprekarNumber(297)); + } + + @Test + void testFor2223() { + assertTrue(KaprekarNumbers.isKaprekarNumber(2223)); + } + + @Test + void testFor857143() { + assertTrue(KaprekarNumbers.isKaprekarNumber(857143)); + } + + @Test + void testFor3() { + assertFalse(KaprekarNumbers.isKaprekarNumber(3)); + } + + @Test + void testFor26() { + assertFalse(KaprekarNumbers.isKaprekarNumber(26)); + } + + @Test + void testFor98() { + assertFalse(KaprekarNumbers.isKaprekarNumber(98)); + } + + @Test + void testForRangeOfNumber() { + try { + List<Long> rangedNumbers = KaprekarNumbers.kaprekarNumberInRange(1, 100000); + long[] allTheNumbers = { + 1, + 9, + 45, + 55, + 99, + 297, + 703, + 999, + 2223, + 2728, + 4950, + 5050, + 7272, + 7777, + 9999, + 17344, + 22222, + 77778, + 82656, + 95121, + 99999, + }; + for (long i : allTheNumbers) { + assert rangedNumbers.contains(i); + } + } catch (Exception e) { + assert false; + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java b/Java/src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java new file mode 100644 index 000000000000..d6baec2e97a7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/LeastCommonMultipleTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class LeastCommonMultipleTest { + + /* + * Test for first number greater than second number + */ + @Test + public void testForFirst() { + int result = LeastCommonMultiple.lcm(6, 8); + int expected = 24; + Assertions.assertEquals(result, expected); + } + + /* + * Test for second number greater than first number + */ + @Test + public void testForSecond() { + int result = LeastCommonMultiple.lcm(8, 6); + int expected = 24; + Assertions.assertEquals(result, expected); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java new file mode 100644 index 000000000000..705f1a1006fa --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/LeonardoNumberTest.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class LeonardoNumberTest { + @Test + void leonardoNumberNegative() { + assertThrows(ArithmeticException.class, () -> LeonardoNumber.leonardoNumber(-1)); + } + @Test + void leonardoNumberZero() { + assertEquals(1, LeonardoNumber.leonardoNumber(0)); + } + @Test + void leonardoNumberOne() { + assertEquals(1, LeonardoNumber.leonardoNumber(1)); + } + @Test + void leonardoNumberFive() { + assertEquals(15, LeonardoNumber.leonardoNumber(5)); + } + @Test + void leonardoNumberTwenty() { + assertEquals(21891, LeonardoNumber.leonardoNumber(20)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java b/Java/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java new file mode 100644 index 000000000000..a2763047acf0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java @@ -0,0 +1,63 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class LiouvilleLambdaFunctionTest { + + @Test + void testLiouvilleLambdaMustThrowExceptionIfNumberIsZero() { + // given + int number = 0; + String expectedMessage = "Number must be greater than zero."; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { LiouvilleLambdaFunction.liouvilleLambda(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } + + @Test + void testLiouvilleLambdaMustThrowExceptionIfNumberIsNegative() { + // given + int number = -1; + String expectedMessage = "Number must be greater than zero."; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { LiouvilleLambdaFunction.liouvilleLambda(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } + + @Test + void testLiouvilleLambdaMustReturnNegativeOne() { + // given + int number = 11; + int expectedOutput = -1; + + // when + int actualOutput = LiouvilleLambdaFunction.liouvilleLambda(number); + + // then + assertEquals(expectedOutput, actualOutput); + } + + @Test + void testLiouvilleLambdaMustReturnPositiveOne() { + // given + int number = 10; + int expectedOutput = 1; + + // when + int actualOutput = LiouvilleLambdaFunction.liouvilleLambda(number); + + // then + assertEquals(expectedOutput, actualOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/LongDivisionTest.java b/Java/src/test/java/com/thealgorithms/maths/LongDivisionTest.java new file mode 100644 index 000000000000..24f757f8f3ad --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/LongDivisionTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class LongDivisionTest { + + // Requirement: Dividend (positive) is greater than divisor (positive), returns correct integer + // after division + @Test + void testOne() { + assertEquals(3, LongDivision.divide(10, 3)); + } + + // Requirement: Dividend (positive) is greater than divisor (negative), returns correct integer + // after division + @Test + void testTwo() { + assertEquals(-2, LongDivision.divide(7, -3)); + } + + // Requirement: Dividend (positive) is greater than divisor (negative), returns correct integer + // after division Basically the same as in the first test + @Test + void testThree() { + assertEquals(10, LongDivision.divide(105, 10)); + } + + // Requirement: Dividend (negative), divisor (positive), returns correct integer after division + // Tests the case where the dividend is less than 0. + @Test + void testNegativeDividend() { + assertEquals(-1, LongDivision.divide(-5, 3)); + } + + // Requirement: Dividend (positive), divisor (positive), returns correct integer after division + // Tests the case where the dividend is less than the divisor. The test should return 0 in this + // case. + @Test + void testDividendLessThanDivisor() { + assertEquals(0, LongDivision.divide(3, 5)); + } + + // Requirement: Dividend (neither), divisor (positive), returns correct integer after division + // Tests the case where the dividend is 0. This should return a 0. + @Test + void testDividendIsZero() { + assertEquals(0, LongDivision.divide(0, 5)); + } + + // Requirement: Dividend (positive), divisor (neither), returns correct integer after division + // Tests the case where the divisor is 0. This should return a 0. + @Test + void testDivisionByZero() { + assertEquals(0, LongDivision.divide(5, 0)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java b/Java/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java new file mode 100644 index 000000000000..3576268c5d0c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/LucasSeriesTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class LucasSeriesTest { + @Test + void lucasSeriesTwo() { + assertEquals(2, LucasSeries.lucasSeries(1)); + assertEquals(2, LucasSeries.lucasSeriesIteration(1)); + } + @Test + void lucasSeriesOne() { + assertEquals(1, LucasSeries.lucasSeries(2)); + assertEquals(1, LucasSeries.lucasSeriesIteration(2)); + } + @Test + void lucasSeriesSeven() { + assertEquals(7, LucasSeries.lucasSeries(5)); + assertEquals(7, LucasSeries.lucasSeriesIteration(5)); + } + @Test + void lucasSeriesEleven() { + assertEquals(123, LucasSeries.lucasSeries(11)); + assertEquals(123, LucasSeries.lucasSeriesIteration(11)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MatrixRankTest.java b/Java/src/test/java/com/thealgorithms/maths/MatrixRankTest.java new file mode 100644 index 000000000000..415b84ec43f8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MatrixRankTest.java @@ -0,0 +1,45 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class MatrixRankTest { + + private static Stream<Arguments> validInputStream() { + return Stream.of(Arguments.of(3, new double[][] {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}}), Arguments.of(0, new double[][] {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}), Arguments.of(1, new double[][] {{1}}), Arguments.of(2, new double[][] {{1, 2}, {3, 4}}), + Arguments.of(2, new double[][] {{3, -1, 2}, {-3, 1, 2}, {-6, 2, 4}}), Arguments.of(3, new double[][] {{2, 3, 0, 1}, {1, 0, 1, 2}, {-1, 1, 1, -2}, {1, 5, 3, -1}}), Arguments.of(1, new double[][] {{1, 2, 3}, {3, 6, 9}}), + Arguments.of(2, new double[][] {{0.25, 0.5, 0.75, 2}, {1.5, 3, 4.5, 6}, {1, 2, 3, 4}})); + } + + private static Stream<Arguments> invalidInputStream() { + return Stream.of(Arguments.of((Object) new double[][] {{1, 2}, {10}, {100, 200, 300}}), // jagged array + Arguments.of((Object) new double[][] {}), // empty matrix + Arguments.of((Object) new double[][] {{}, {}}), // empty row + Arguments.of((Object) null), // null matrix + Arguments.of((Object) new double[][] {{1, 2}, null}) // null row + ); + } + + @ParameterizedTest + @MethodSource("validInputStream") + void computeRankTests(int expectedRank, double[][] matrix) { + int originalHashCode = Arrays.deepHashCode(matrix); + int rank = MatrixRank.computeRank(matrix); + int newHashCode = Arrays.deepHashCode(matrix); + + assertEquals(expectedRank, rank); + assertEquals(originalHashCode, newHashCode); + } + + @ParameterizedTest + @MethodSource("invalidInputStream") + void computeRankWithInvalidMatrix(double[][] matrix) { + assertThrows(IllegalArgumentException.class, () -> MatrixRank.computeRank(matrix)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MaxValueTest.java b/Java/src/test/java/com/thealgorithms/maths/MaxValueTest.java new file mode 100644 index 000000000000..3c0fe8447c12 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MaxValueTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MaxValueTest { + @Test + public void maxTest() { + assertEquals(-1, MaxValue.max(-1, -3)); + assertEquals(3, MaxValue.max(3, 2)); + assertEquals(5, MaxValue.max(5, 5)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MeansTest.java b/Java/src/test/java/com/thealgorithms/maths/MeansTest.java new file mode 100644 index 000000000000..a1c07e25bea3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MeansTest.java @@ -0,0 +1,72 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.Vector; +import org.assertj.core.util.Lists; +import org.assertj.core.util.Sets; +import org.junit.jupiter.api.Test; + +class MeansTest { + + @Test + void arithmeticMeanZeroNumbers() throws IllegalArgumentException { + List<Double> numbers = new ArrayList<>(); + assertThrows(IllegalArgumentException.class, () -> Means.arithmetic(numbers)); + } + + @Test + void geometricMeanZeroNumbers() throws IllegalArgumentException { + List<Double> numbers = new ArrayList<>(); + assertThrows(IllegalArgumentException.class, () -> Means.geometric(numbers)); + } + + @Test + void harmonicMeanZeroNumbers() throws IllegalArgumentException { + List<Double> numbers = new ArrayList<>(); + assertThrows(IllegalArgumentException.class, () -> Means.harmonic(numbers)); + } + + @Test + void arithmeticMeanSingleNumber() { + List<Double> numbers = Lists.newArrayList(2.5); + assertEquals(2.5, Means.arithmetic(numbers)); + } + + @Test + void geometricMeanSingleNumber() { + Set<Double> numbers = Sets.newHashSet(Lists.newArrayList(2.5)); + assertEquals(2.5, Means.geometric(numbers)); + } + + @Test + void harmonicMeanSingleNumber() { + LinkedHashSet<Double> numbers = Sets.newLinkedHashSet(2.5); + assertEquals(2.5, Means.harmonic(numbers)); + } + + @Test + void arithmeticMeanMultipleNumbers() { + Set<Double> numbers = Sets.newTreeSet(1d, 2.5, 83.3, 25.9999, 46.0001, 74.7, 74.5); + assertEquals(44, Means.arithmetic(numbers)); + } + + @Test + void geometricMeanMultipleNumbers() { + LinkedList<Double> numbers = new LinkedList<>() {}; + numbers.addAll(Lists.newArrayList(1d, 2d, 3d, 4d, 5d, 6d, 1.25)); + assertEquals(2.6426195539300585, Means.geometric(numbers)); + } + + @Test + void harmonicMeanMultipleNumbers() { + Vector<Double> numbers = new Vector<>(Lists.newArrayList(1d, 2.5, 83.3, 25.9999, 46.0001, 74.7, 74.5)); + assertEquals(4.6697322801074135, Means.harmonic(numbers)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MedianTest.java b/Java/src/test/java/com/thealgorithms/maths/MedianTest.java new file mode 100644 index 000000000000..d2b637abd3cb --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MedianTest.java @@ -0,0 +1,37 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MedianTest { + @Test + void medianSingleValue() { + int[] arr = {0}; + assertEquals(0, Median.median(arr)); + } + + @Test + void medianTwoValues() { + int[] arr = {1, 2}; + assertEquals(1.5, Median.median(arr)); + } + + @Test + void medianThreeValues() { + int[] arr = {1, 2, 3}; + assertEquals(2, Median.median(arr)); + } + + @Test + void medianDecimalValueReturn() { + int[] arr = {1, 2, 3, 4, 5, 6, 8, 9}; + assertEquals(4.5, Median.median(arr)); + } + + @Test + void medianNegativeValues() { + int[] arr = {-27, -16, -7, -4, -2, -1}; + assertEquals(-5.5, Median.median(arr)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java b/Java/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java new file mode 100644 index 000000000000..d547cecf24cd --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class MillerRabinPrimalityCheckTest { + @Test + void testDeterministicMillerRabinForPrimes() { + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(2)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(37)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(123457)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(6472601713L)); + } + @Test + void testDeterministicMillerRabinForNotPrimes() { + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(1)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(35)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(123453)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(647260175)); + } + @Test + void testMillerRabinForPrimes() { + assertTrue(MillerRabinPrimalityCheck.millerRabin(11, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(97, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(6720589, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(9549401549L, 5)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MinValueTest.java b/Java/src/test/java/com/thealgorithms/maths/MinValueTest.java new file mode 100644 index 000000000000..beb0ccb1a571 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MinValueTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MinValueTest { + @Test + public void minTest() { + assertEquals(-1, MinValue.min(-1, 3)); + assertEquals(2, MinValue.min(3, 2)); + assertEquals(5, MinValue.min(5, 5)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java b/Java/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java new file mode 100644 index 000000000000..f3a6514ce633 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java @@ -0,0 +1,154 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class MobiusFunctionTest { + + @Test + void testMobiusForZero() { + // given + int number = 0; + String expectedMessage = "Number must be greater than zero."; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { MobiusFunction.mobius(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } + + @Test + void testMobiusForNegativeNumber() { + // given + int number = -1; + String expectedMessage = "Number must be greater than zero."; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { MobiusFunction.mobius(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } + + @Test + void testMobiusFunction() { + int[] expectedResultArray = { + 1, + -1, + -1, + 0, + -1, + 1, + -1, + 0, + 0, + 1, + -1, + 0, + -1, + 1, + 1, + 0, + -1, + 0, + -1, + 0, + 1, + 1, + -1, + 0, + 0, + 1, + 0, + 0, + -1, + -1, + -1, + 0, + 1, + 1, + 1, + 0, + -1, + 1, + 1, + 0, + -1, + -1, + -1, + 0, + 0, + 1, + -1, + 0, + 0, + 0, + 1, + 0, + -1, + 0, + 1, + 0, + 1, + 1, + -1, + 0, + -1, + 1, + 0, + 0, + 1, + -1, + -1, + 0, + 1, + -1, + -1, + 0, + -1, + 1, + 0, + 0, + 1, + -1, + -1, + 0, + 0, + 1, + -1, + 0, + 1, + 1, + 1, + 0, + -1, + 0, + 1, + 0, + 1, + 1, + 1, + 0, + -1, + 0, + 0, + 0, + }; + + for (int i = 1; i <= 100; i++) { + // given + int expectedValue = expectedResultArray[i - 1]; + + // when + int actualValue = MobiusFunction.mobius(i); + + // then + assertEquals(expectedValue, actualValue); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/ModeTest.java b/Java/src/test/java/com/thealgorithms/maths/ModeTest.java new file mode 100644 index 000000000000..629fd8bd580a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/ModeTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class ModeTest { + @ParameterizedTest + @MethodSource("tcStream") + void basicTest(final int[] expected, final int[] numbers) { + assertArrayEquals(expected, Mode.mode(numbers)); + } + + private static Stream<Arguments> tcStream() { + return Stream.of(Arguments.of(null, new int[] {}), Arguments.of(new int[] {5}, new int[] {5}), Arguments.of(new int[] {1, 2, 3, 4, 5}, new int[] {1, 2, 3, 4, 5}), Arguments.of(new int[] {1, 2, 3, 4, 5}, new int[] {5, 4, 3, 2, 1}), + Arguments.of(new int[] {7}, new int[] {7, 9, 9, 4, 5, 6, 7, 7, 8}), Arguments.of(new int[] {7, 9}, new int[] {7, 9, 9, 4, 5, 6, 7, 7, 9})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java new file mode 100644 index 000000000000..3fe58dadf8a5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/NthUglyNumberTest.java @@ -0,0 +1,79 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import org.junit.jupiter.api.Test; + +public class NthUglyNumberTest { + @Test + public void testGetWithNewObject() { + HashMap<Integer, Long> testCases = new HashMap<>(); + testCases.put(0, 1L); + testCases.put(1, 2L); + testCases.put(2, 3L); + testCases.put(3, 4L); + testCases.put(4, 5L); + testCases.put(5, 6L); + testCases.put(9, 12L); + testCases.put(19, 36L); + testCases.put(52, 270L); + testCases.put(1078, 84934656L); + testCases.put(1963, 6973568802L); + + for (final var tc : testCases.entrySet()) { + var uglyNumbers = new NthUglyNumber(new int[] {2, 3, 5}); + assertEquals(uglyNumbers.get(tc.getKey()), tc.getValue()); + + var otherUglyNumbers = new NthUglyNumber(new int[] {5, 25, 6, 2, 3, 5}); + assertEquals(otherUglyNumbers.get(tc.getKey()), tc.getValue()); + } + } + + @Test + public void testGetWithSameObject() { + HashMap<Integer, Long> testCases = new HashMap<>(); + testCases.put(0, 1L); + testCases.put(1, 2L); + testCases.put(2, 3L); + testCases.put(3, 4L); + testCases.put(4, 5L); + testCases.put(5, 6L); + testCases.put(6, 7L); + testCases.put(1499, 1984500L); + testCases.put(1572, 2449440L); + testCases.put(1658, 3072000L); + testCases.put(6625, 4300800000L); + + var uglyNumbers = new NthUglyNumber(new int[] {7, 2, 5, 3}); + for (final var tc : testCases.entrySet()) { + assertEquals(uglyNumbers.get(tc.getKey()), tc.getValue()); + } + + assertEquals(uglyNumbers.get(999), 385875); + } + + @Test + public void testGetWithBase1() { + var uglyNumbers = new NthUglyNumber(new int[] {1}); + assertEquals(uglyNumbers.get(10), 1); + } + + @Test + public void testGetWithBase2() { + var uglyNumbers = new NthUglyNumber(new int[] {2}); + assertEquals(uglyNumbers.get(5), 32); + } + + @Test + public void testGetThrowsAnErrorForNegativeInput() { + var uglyNumbers = new NthUglyNumber(new int[] {1, 2}); + assertThrows(IllegalArgumentException.class, () -> uglyNumbers.get(-1)); + } + + @Test + public void testConstructorThrowsAnErrorForEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> new NthUglyNumber(new int[] {})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java b/Java/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java new file mode 100644 index 000000000000..799052b22d83 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.function.IntFunction; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class NumberOfDigitsTest { + + @ParameterizedTest + @MethodSource("testCases") + void testNumberOfDigits(final int expected, final int number, final IntFunction<Integer> methodUnderTest) { + assertEquals(expected, methodUnderTest.apply(number)); + assertEquals(expected, methodUnderTest.apply(-number)); + } + + private static Stream<Arguments> testCases() { + final Integer[][] inputs = new Integer[][] { + {3, 100}, + {1, 0}, + {2, 12}, + {3, 123}, + {4, 1234}, + {5, 12345}, + {6, 123456}, + {7, 1234567}, + {8, 12345678}, + {9, 123456789}, + {9, 987654321}, + }; + + final IntFunction<Integer>[] methods = new IntFunction[] {NumberOfDigits::numberOfDigits, NumberOfDigits::numberOfDigitsFast, NumberOfDigits::numberOfDigitsFaster, NumberOfDigits::numberOfDigitsRecursion}; + + return Stream.of(inputs).flatMap(input -> Stream.of(methods).map(method -> Arguments.of(input[0], input[1], method))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java new file mode 100644 index 000000000000..a70100c0b913 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PalindromeNumberTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 01/07/2023 + */ +public class PalindromeNumberTest { + @Test + public void testNumbersArePalindromes() { + Assertions.assertTrue(PalindromeNumber.isPalindrome(0)); + Assertions.assertTrue(PalindromeNumber.isPalindrome(1)); + Assertions.assertTrue(PalindromeNumber.isPalindrome(2332)); + Assertions.assertTrue(PalindromeNumber.isPalindrome(12321)); + } + + @Test + public void testNumbersAreNotPalindromes() { + Assertions.assertFalse(PalindromeNumber.isPalindrome(12)); + Assertions.assertFalse(PalindromeNumber.isPalindrome(990)); + Assertions.assertFalse(PalindromeNumber.isPalindrome(1234)); + } + + @Test + public void testIfNegativeInputThenExceptionExpected() { + IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> PalindromeNumber.isPalindrome(-1)); + Assertions.assertEquals(exception.getMessage(), "Input parameter must not be negative!"); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java b/Java/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java new file mode 100644 index 000000000000..7649e21eb231 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/ParseIntegerTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Albina Gimaletdinova on 01/07/2023 + */ +public class ParseIntegerTest { + private static final String NULL_PARAMETER_MESSAGE = "Input parameter must not be null!"; + private static final String EMPTY_PARAMETER_MESSAGE = "Input parameter must not be empty!"; + private static final String INCORRECT_FORMAT_MESSAGE = "Input parameter of incorrect format"; + + @Test + public void testNullInput() { + IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> ParseInteger.parseInt(null)); + Assertions.assertEquals(exception.getMessage(), NULL_PARAMETER_MESSAGE); + } + + @Test + public void testEmptyInput() { + IllegalArgumentException exception = Assertions.assertThrows(IllegalArgumentException.class, () -> ParseInteger.parseInt("")); + Assertions.assertEquals(exception.getMessage(), EMPTY_PARAMETER_MESSAGE); + } + + @Test + public void testInputOfIncorrectFormat() { + IllegalArgumentException exception = Assertions.assertThrows(NumberFormatException.class, () -> ParseInteger.parseInt("+0a123")); + Assertions.assertTrue(exception.getMessage().contains(INCORRECT_FORMAT_MESSAGE)); + + exception = Assertions.assertThrows(NumberFormatException.class, () -> ParseInteger.parseInt("b")); + Assertions.assertTrue(exception.getMessage().contains(INCORRECT_FORMAT_MESSAGE)); + } + + @Test + public void testPositiveValueIsSuccessfullyConverted() { + Assertions.assertEquals(ParseInteger.parseInt("0"), Integer.parseInt("0")); + Assertions.assertEquals(ParseInteger.parseInt("123"), Integer.parseInt("123")); + Assertions.assertEquals(ParseInteger.parseInt("0123"), Integer.parseInt("0123")); + Assertions.assertEquals(ParseInteger.parseInt("+0123"), Integer.parseInt("+0123")); + Assertions.assertEquals(ParseInteger.parseInt("+123"), Integer.parseInt("+123")); + } + + @Test + public void testNegativeValueIsSuccessfullyConverted() { + Assertions.assertEquals(ParseInteger.parseInt("-1"), Integer.parseInt("-1")); + Assertions.assertEquals(ParseInteger.parseInt("-123"), Integer.parseInt("-123")); + Assertions.assertEquals(ParseInteger.parseInt("-0123"), Integer.parseInt("-0123")); + Assertions.assertEquals(ParseInteger.parseInt("-00123"), Integer.parseInt("-00123")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java b/Java/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java new file mode 100644 index 000000000000..a1512aacb30d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class PascalTriangleTest { + + @Test + void testForOne() { + int[][] result = PascalTriangle.pascal(1); + int[][] expected = {{1}}; + assertArrayEquals(result, expected); + } + + @Test + void testForTwo() { + int[][] result = PascalTriangle.pascal(2); + int[][] expected = {{1, 0}, {1, 1}}; + assertArrayEquals(result, expected); + } + + @Test + void testForFive() { + int[][] result = PascalTriangle.pascal(5); + int[][] expected = { + {1, 0, 0, 0, 0}, + {1, 1, 0, 0, 0}, + {1, 2, 1, 0, 0}, + {1, 3, 3, 1, 0}, + {1, 4, 6, 4, 1}, + }; + assertArrayEquals(result, expected); + } + + @Test + void testForEight() { + int[][] result = PascalTriangle.pascal(8); + int[][] expected = { + {1, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 0, 0, 0, 0}, + {1, 2, 1, 0, 0, 0, 0, 0}, + {1, 3, 3, 1, 0, 0, 0, 0}, + {1, 4, 6, 4, 1, 0, 0, 0}, + {1, 5, 10, 10, 5, 1, 0, 0}, + {1, 6, 15, 20, 15, 6, 1, 0}, + {1, 7, 21, 35, 35, 21, 7, 1}, + }; + assertArrayEquals(expected, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PerfectCubeTest.java b/Java/src/test/java/com/thealgorithms/maths/PerfectCubeTest.java new file mode 100644 index 000000000000..806f5493918c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PerfectCubeTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class PerfectCubeTest { + + @Test + public void perfectCube() { + + Assertions.assertTrue(PerfectCube.isPerfectCube(-27)); + Assertions.assertTrue(PerfectCube.isPerfectCubeMathCbrt(-27)); + Assertions.assertTrue(PerfectCube.isPerfectCube(-1)); + Assertions.assertTrue(PerfectCube.isPerfectCubeMathCbrt(-1)); + Assertions.assertTrue(PerfectCube.isPerfectCube(0)); + Assertions.assertTrue(PerfectCube.isPerfectCubeMathCbrt(0)); + Assertions.assertTrue(PerfectCube.isPerfectCube(1)); + Assertions.assertTrue(PerfectCube.isPerfectCubeMathCbrt(1)); + Assertions.assertTrue(PerfectCube.isPerfectCube(8)); + Assertions.assertTrue(PerfectCube.isPerfectCubeMathCbrt(8)); + Assertions.assertTrue(PerfectCube.isPerfectCube(27)); + Assertions.assertTrue(PerfectCube.isPerfectCubeMathCbrt(27)); + + Assertions.assertFalse(PerfectCube.isPerfectCube(-9)); + Assertions.assertFalse(PerfectCube.isPerfectCubeMathCbrt(-9)); + Assertions.assertFalse(PerfectCube.isPerfectCube(2)); + Assertions.assertFalse(PerfectCube.isPerfectCubeMathCbrt(2)); + Assertions.assertFalse(PerfectCube.isPerfectCube(4)); + Assertions.assertFalse(PerfectCube.isPerfectCubeMathCbrt(4)); + Assertions.assertFalse(PerfectCube.isPerfectCube(30)); + Assertions.assertFalse(PerfectCube.isPerfectCubeMathCbrt(30)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java new file mode 100644 index 000000000000..0433ba80cfa4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class PerfectNumberTest { + + @Test + public void perfectNumber() { + int[] trueTestCases = {6, 28, 496, 8128, 33550336}; + int[] falseTestCases = {-6, 0, 1, 9, 123}; + for (Integer n : trueTestCases) { + assertTrue(PerfectNumber.isPerfectNumber(n)); + assertTrue(PerfectNumber.isPerfectNumber2(n)); + } + for (Integer n : falseTestCases) { + assertFalse(PerfectNumber.isPerfectNumber(n)); + assertFalse(PerfectNumber.isPerfectNumber2(n)); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java b/Java/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java new file mode 100644 index 000000000000..08c96bc71f9b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PerfectSquareTest.java @@ -0,0 +1,19 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class PerfectSquareTest { + @ParameterizedTest + @ValueSource(ints = {0, 1, 2 * 2, 3 * 3, 4 * 4, 5 * 5, 6 * 6, 7 * 7, 8 * 8, 9 * 9, 10 * 10, 11 * 11, 123 * 123}) + void positiveTest(final int number) { + Assertions.assertTrue(PerfectSquare.isPerfectSquare(number)); + } + + @ParameterizedTest + @ValueSource(ints = {-1, -2, -3, -4, -5, -100, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 17, 99, 101, 257, 999, 1001}) + void negativeTest(final int number) { + Assertions.assertFalse(PerfectSquare.isPerfectSquare(number)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PerimeterTest.java b/Java/src/test/java/com/thealgorithms/maths/PerimeterTest.java new file mode 100644 index 000000000000..94d3d3ae0577 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PerimeterTest.java @@ -0,0 +1,51 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PerimeterTest { + + // Perimeter of Regular polygon + @Test + void testcase1() { + Assertions.assertEquals(20.0, Perimeter.perimeterRegularPolygon(4, 5)); + } + + @Test + void testcase2() { + Assertions.assertEquals(30.0, Perimeter.perimeterRegularPolygon(5, 6)); + } + + // Perimeter of Rectangle + @Test + void testcase3() { + Assertions.assertEquals(18.0, Perimeter.perimeterRectangle(4, 5)); + } + + @Test + void testcase4() { + Assertions.assertEquals(14.0, Perimeter.perimeterRectangle(4, 3)); + } + + // Circumference/Perimeter of a circle + @Test + void testcase5() { + Assertions.assertEquals(31.41592653589793, Perimeter.perimeterCircle(5)); + } + + @Test + void testcase6() { + Assertions.assertEquals(43.982297150257104, Perimeter.perimeterCircle(7)); + } + + // Perimeter of Irregular polygon + @Test + void testcase7() { + Assertions.assertEquals(12.0, Perimeter.perimeterIrregularPolygon(4, 5, 3)); + } + + @Test + void testcase8() { + Assertions.assertEquals(21.0, Perimeter.perimeterIrregularPolygon(3, 4, 5, 3, 6)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PollardRhoTest.java b/Java/src/test/java/com/thealgorithms/maths/PollardRhoTest.java new file mode 100644 index 000000000000..3e2270a66a98 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PollardRhoTest.java @@ -0,0 +1,49 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class PollardRhoTest { + + @Test + void testPollardRhoForNumber315MustReturn5() { + // given + int number = 315; + int expectedResult = 5; + + // when + int actualResult = PollardRho.pollardRho(number); + + // then + assertEquals(expectedResult, actualResult); + } + + @Test + void testPollardRhoForNumber187MustReturn11() { + // given + int number = 187; + int expectedResult = 11; + + // when + int actualResult = PollardRho.pollardRho(number); + + // then + assertEquals(expectedResult, actualResult); + } + + @Test + void testPollardRhoForNumber239MustThrowException() { + // given + int number = 239; + String expectedMessage = "GCD cannot be found."; + + // when + Exception exception = assertThrows(RuntimeException.class, () -> { PollardRho.pollardRho(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java b/Java/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java new file mode 100644 index 000000000000..ac8d2be17d7c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PowerOfTwoOrNotTest.java @@ -0,0 +1,24 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class PowerOfTwoOrNotTest { + @Test + public void testPowerOfTwoOrNotForPowersOfTwo() { + final var powersOfTwo = new int[] {1, 2, 4, 8, 16, 32, 64}; + for (final var n : powersOfTwo) { + assertTrue(PowerOfTwoOrNot.checkIfPowerOfTwoOrNot(n)); + } + } + + @Test + public void testPowerOfTwoOrNotForNotPowersOfTwo() { + final var notPowersOfTwo = new int[] {-16, -8, -6, -5, -4, -3, -2, -1, 0, 3, 5, 6, 7, 9, 10, 11, 33, 63, 65, 1000, 9999}; + for (final var n : notPowersOfTwo) { + assertFalse(PowerOfTwoOrNot.checkIfPowerOfTwoOrNot(n)); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java b/Java/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java new file mode 100644 index 000000000000..705cc6672818 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java @@ -0,0 +1,20 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * Test case for Power using Recursion + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +class PowerUsingRecursionTest { + + @Test + void testPowerUsingRecursion() { + assertEquals(32.0, PowerUsingRecursion.power(2.0, 5)); + assertEquals(97.65625, PowerUsingRecursion.power(2.5, 5)); + assertEquals(81, PowerUsingRecursion.power(3, 4)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java b/Java/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java new file mode 100644 index 000000000000..c3e1634c51fe --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PrimeCheckTest.java @@ -0,0 +1,42 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PrimeCheckTest { + + @Test + void test1() { + Assertions.assertTrue(PrimeCheck.isPrime(2)); + } + + @Test + void test2() { + Assertions.assertFalse(PrimeCheck.isPrime(-1)); + } + + @Test + void test3() { + Assertions.assertFalse(PrimeCheck.isPrime(4)); + } + + @Test + void test4() { + Assertions.assertTrue(PrimeCheck.isPrime(5)); + } + + @Test + void test5() { + Assertions.assertFalse(PrimeCheck.isPrime(15)); + } + + @Test + void test6() { + Assertions.assertTrue(PrimeCheck.isPrime(11)); + } + + @Test + void test7() { + Assertions.assertFalse(PrimeCheck.isPrime(49)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java b/Java/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java new file mode 100644 index 000000000000..abe6068c2022 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class PrimeFactorizationTest { + + @Test + void testpFactorsMustReturnEmptyList() { + // given + int n = 0; + + // then + assertTrue(PrimeFactorization.pfactors(n).isEmpty()); + } + + @Test + void testpFactorsMustReturnNonEmptyList() { + // given + int n = 198; + int expectedListSize = 4; + + // when + List<Integer> actualResultList = PrimeFactorization.pfactors(n); + + // then + assertEquals(expectedListSize, actualResultList.size()); + assertEquals(2, actualResultList.get(0)); + assertEquals(3, actualResultList.get(1)); + assertEquals(3, actualResultList.get(2)); + assertEquals(11, actualResultList.get(3)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PronicNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/PronicNumberTest.java new file mode 100644 index 000000000000..5a31981bed5c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PronicNumberTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class PronicNumberTest { + + @Test + void testForPronicNumber() { + // given + int number = 30; + + // when + boolean result = PronicNumber.isPronic(number); + + // then + assertTrue(result); + } + + @Test + void testForNonPronicNumber() { + // given + int number = 21; + + // when + boolean result = PronicNumber.isPronic(number); + + // then + assertFalse(result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java b/Java/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java new file mode 100644 index 000000000000..13ea58155dec --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java @@ -0,0 +1,22 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class PythagoreanTripleTest { + + @Test + public void testPythagoreanTriple() { + assertTrue(PythagoreanTriple.isPythagTriple(3, 4, 5)); + assertTrue(PythagoreanTriple.isPythagTriple(6, 8, 10)); + assertTrue(PythagoreanTriple.isPythagTriple(9, 12, 15)); + assertTrue(PythagoreanTriple.isPythagTriple(12, 16, 20)); + assertTrue(PythagoreanTriple.isPythagTriple(15, 20, 25)); + assertTrue(PythagoreanTriple.isPythagTriple(18, 24, 30)); + assertFalse(PythagoreanTriple.isPythagTriple(5, 20, 30)); + assertFalse(PythagoreanTriple.isPythagTriple(6, 8, 100)); + assertFalse(PythagoreanTriple.isPythagTriple(-2, -2, 2)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java new file mode 100644 index 000000000000..e870962b185e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/ReverseNumberTest.java @@ -0,0 +1,29 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import org.junit.jupiter.api.Test; + +public class ReverseNumberTest { + + @Test + public void testReverseNumber() { + HashMap<Integer, Integer> testCases = new HashMap<>(); + testCases.put(0, 0); + testCases.put(1, 1); + testCases.put(10, 1); + testCases.put(123, 321); + testCases.put(7890, 987); + + for (final var tc : testCases.entrySet()) { + assertEquals(ReverseNumber.reverseNumber(tc.getKey()), tc.getValue()); + } + } + + @Test + public void testReverseNumberThrowsExceptionForNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> ReverseNumber.reverseNumber(-1)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java b/Java/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java new file mode 100644 index 000000000000..c744614e5cfa --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SecondMinMaxTest.java @@ -0,0 +1,58 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class SecondMinMaxTest { + + private static final String EXP_MSG_ARR_LEN_LESS_2 = "Input array must have length of at least two"; + private static final String EXP_MSG_ARR_SAME_ELE = "Input array should have at least 2 distinct elements"; + + public static class TestCase { + public TestCase(final int[] inInputArray, final int inSecondMin, final int inSecondMax) { + inputArray = inInputArray; + secondMin = inSecondMin; + secondMax = inSecondMax; + } + final int[] inputArray; + final int secondMin; + final int secondMax; + } + + @Test + public void testForEmptyInputArray() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> SecondMinMax.findSecondMin(new int[] {})); + assertEquals(exception.getMessage(), EXP_MSG_ARR_LEN_LESS_2); + } + + @Test + public void testForArrayWithSingleElement() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> SecondMinMax.findSecondMax(new int[] {1})); + assertEquals(exception.getMessage(), EXP_MSG_ARR_LEN_LESS_2); + } + + @Test + public void testForArrayWithSameElements() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> SecondMinMax.findSecondMin(new int[] {1, 1, 1, 1})); + assertEquals(exception.getMessage(), EXP_MSG_ARR_SAME_ELE); + } + + @ParameterizedTest + @MethodSource("inputStream") + void numberTests(final TestCase tc) { + Assertions.assertEquals(tc.secondMax, SecondMinMax.findSecondMax(tc.inputArray)); + Assertions.assertEquals(tc.secondMin, SecondMinMax.findSecondMin(tc.inputArray)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(new TestCase(new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 2, 9)), Arguments.of(new TestCase(new int[] {5, 4, 5, 5, 5}, 5, 4)), Arguments.of(new TestCase(new int[] {-1, 0}, 0, -1)), + Arguments.of(new TestCase(new int[] {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1}, -9, -2)), Arguments.of(new TestCase(new int[] {3, -2, 3, 9, -4, -4, 8}, -2, 8))); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java b/Java/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java new file mode 100644 index 000000000000..d7e16e02602b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SquareFreeIntegerTest.java @@ -0,0 +1,83 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class SquareFreeIntegerTest { + + @Test + void testIsSquareFreeInteger() { + + // given + List<Integer> listOfSquareFreeIntegers = List.of(1, 2, 3, 5, 6, 7, 10, 11, 13, 14, 15, 17, 19, 21, 22, 23, 26, 29, 30, 31, 33, 34, 35, 37, 38, 39, 41, 42, 43, 46, 47, 51, 53, 55, 57, 58, 59, 61, 62, 65, 66, 67, 69, 70, 71, 73, 74, 77, 78, 79, 82, 83, 85, 86, 87, 89, 91, 93, 94, 95, 97, 101, + 102, 103, 105, 106, 107, 109, 110, 111, 113, 114, 115, 118, 119, 122, 123, 127, 129, 130, 131, 133, 134, 137, 138, 139, 141, 142, 143, 145, 146, 149, 151, 154, 155, 157, 158, 159, 161, 163, 165, 166, 167, 170, 173, 174, 177, 178, 179, 181, 182, 183, 185, 186, 187, 190, 191, 193, 194, + 195, 197, 199, 201, 202, 203, 205, 206, 209, 210, 211, 213, 214, 215, 217, 218, 219, 221, 222, 223, 226, 227, 229, 230, 231, 233, 235, 237, 238, 239, 241, 246, 247, 249, 251, 253, 254, 255, 257, 258, 259, 262, 263, 265, 266, 267, 269, 271, 273, 274, 277, 278, 281, 282, 283, 285, 286, + 287, 290, 291, 293, 295, 298, 299, 301, 302, 303, 305, 307, 309, 310, 311, 313, 314, 317, 318, 319, 321, 322, 323, 326, 327, 329, 330, 331, 334, 335, 337, 339, 341, 345, 346, 347, 349, 353, 354, 355, 357, 358, 359, 362, 365, 366, 367, 370, 371, 373, 374, 377, 379, 381, 382, 383, 385, + 386, 389, 390, 391, 393, 394, 395, 397, 398, 399, 401, 402, 403, 406, 407, 409, 410, 411, 413, 415, 417, 418, 419, 421, 422, 426, 427, 429, 430, 431, 433, 434, 435, 437, 438, 439, 442, 443, 445, 446, 447, 449, 451, 453, 454, 455, 457, 458, 461, 462, 463, 465, 466, 467, 469, 470, 471, + 473, 474, 478, 479, 481, 482, 483, 485, 487, 489, 491, 493, 494, 497, 498, 499, 501, 502, 503, 505, 506, 509, 510, 511, 514, 515, 517, 518, 519, 521, 523, 526, 527, 530, 533, 534, 535, 537, 538, 541, 542, 543, 545, 546, 547, 551, 553, 554, 555, 557, 559, 561, 562, 563, 565, 566, 569, + 570, 571, 573, 574, 577, 579, 581, 582, 583, 586, 587, 589, 590, 591, 593, 595, 597, 598, 599, 601, 602, 606, 607, 609, 610, 611, 613, 614, 615, 617, 618, 619, 622, 623, 626, 627, 629, 631, 633, 634, 635, 638, 641, 642, 643, 645, 646, 647, 649, 651, 653, 654, 655, 658, 659, 661, 662, + 663, 665, 667, 669, 670, 671, 673, 674, 677, 678, 679, 681, 682, 683, 685, 687, 689, 690, 691, 694, 695, 697, 698, 699, 701, 703, 705, 706, 707, 709, 710, 713, 714, 715, 717, 718, 719, 721, 723, 727, 730, 731, 733, 734, 737, 739, 741, 742, 743, 745, 746, 749, 751, 753, 754, 755, 757, + 758, 759, 761, 762, 763, 766, 767, 769, 770, 771, 773, 777, 778, 779, 781, 782, 785, 786, 787, 789, 790, 791, 793, 794, 795, 797, 798, 799, 802, 803, 805, 806, 807, 809, 811, 813, 814, 815, 817, 818, 821, 822, 823, 826, 827, 829, 830, 831, 834, 835, 838, 839, 842, 843, 849, 851, 853, + 854, 857, 858, 859, 861, 862, 863, 865, 866, 869, 870, 871, 874, 877, 878, 879, 881, 883, 885, 886, 887, 889, 890, 893, 894, 895, 897, 898, 899, 901, 902, 903, 905, 906, 907, 910, 911, 913, 914, 915, 917, 919, 921, 922, 923, 926, 929, 930, 933, 934, 935, 937, 938, 939, 941, 942, 943, + 946, 947, 949, 951, 953, 955, 957, 958, 959, 962, 965, 966, 967, 969, 970, 971, 973, 974, 977, 978, 979, 982, 983, 985, 986, 987, 989, 991, 993, 994, 995, 997, 998, 1001, 1002, 1003, 1005, 1006, 1007, 1009, 1010, 1011, 1013, 1015, 1018, 1019, 1021, 1022, 1023, 1027, 1030, 1031, 1033, + 1034, 1037, 1038, 1039, 1041, 1042, 1043, 1045, 1046, 1047, 1049, 1051, 1054, 1055, 1057, 1059, 1061, 1063, 1065, 1066, 1067, 1069, 1070, 1073, 1074, 1077, 1079, 1081, 1082, 1085, 1086, 1087, 1090, 1091, 1093, 1094, 1095, 1097, 1099, 1101, 1102, 1103, 1105, 1106, 1109, 1110, 1111, 1113, + 1114, 1115, 1117, 1118, 1119, 1121, 1122, 1123, 1126, 1129, 1130, 1131, 1133, 1135, 1137, 1138, 1139, 1141, 1142, 1145, 1146, 1147, 1149, 1151, 1153, 1154, 1155, 1157, 1158, 1159, 1162, 1163, 1165, 1166, 1167, 1169, 1171, 1173, 1174, 1177, 1178, 1181, 1182, 1185, 1186, 1187, 1189, 1190, + 1191, 1193, 1194, 1195, 1198, 1199, 1201, 1202, 1203, 1205, 1207, 1209, 1211, 1213, 1214, 1217, 1218, 1219, 1221, 1222, 1223, 1226, 1227, 1229, 1230, 1231, 1234, 1235, 1237, 1238, 1239, 1241, 1243, 1245, 1246, 1247, 1249, 1253, 1254, 1255, 1257, 1258, 1259, 1261, 1262, 1263, 1265, 1266, + 1267, 1270, 1271, 1273, 1277, 1279, 1281, 1282, 1283, 1285, 1286, 1289, 1290, 1291, 1293, 1294, 1295, 1297, 1298, 1299, 1301, 1302, 1303, 1306, 1307, 1309, 1310, 1311, 1313, 1315, 1317, 1318, 1319, 1321, 1322, 1326, 1327, 1329, 1330, 1333, 1334, 1335, 1337, 1338, 1339, 1342, 1343, 1345, + 1346, 1347, 1349, 1351, 1353, 1354, 1355, 1357, 1358, 1361, 1362, 1363, 1365, 1366, 1367, 1370, 1371, 1373, 1374, 1378, 1379, 1381, 1382, 1383, 1385, 1387, 1389, 1390, 1391, 1393, 1394, 1397, 1398, 1399, 1401, 1402, 1403, 1405, 1406, 1407, 1409, 1410, 1411, 1414, 1415, 1417, 1418, 1419, + 1423, 1426, 1427, 1429, 1430, 1433, 1434, 1435, 1437, 1438, 1439, 1441, 1442, 1443, 1446, 1447, 1451, 1453, 1454, 1455, 1457, 1459, 1461, 1462, 1463, 1465, 1466, 1469, 1471, 1473, 1474, 1477, 1478, 1479, 1481, 1482, 1483, 1486, 1487, 1489, 1490, 1491, 1493, 1495, 1497, 1498, 1499, 1501, + 1502, 1505, 1506, 1507, 1509, 1510, 1511, 1513, 1514, 1515, 1517, 1518, 1522, 1523, 1526, 1527, 1529, 1531, 1533, 1534, 1535, 1537, 1538, 1541, 1542, 1543, 1545, 1546, 1547, 1549, 1551, 1553, 1554, 1555, 1558, 1559, 1561, 1562, 1563, 1565, 1567, 1569, 1570, 1571, 1574, 1577, 1578, 1579, + 1581, 1582, 1583, 1585, 1586, 1589, 1590, 1591, 1594, 1595, 1597, 1598, 1599, 1601, 1603, 1605, 1606, 1607, 1609, 1610, 1613, 1614, 1615, 1618, 1619, 1621, 1622, 1623, 1626, 1627, 1630, 1631, 1633, 1634, 1635, 1637, 1639, 1641, 1642, 1643, 1645, 1646, 1649, 1651, 1653, 1654, 1655, 1657, + 1658, 1659, 1661, 1662, 1663, 1667, 1669, 1670, 1671, 1673, 1677, 1678, 1679, 1685, 1686, 1687, 1689, 1691, 1693, 1695, 1697, 1698, 1699, 1702, 1703, 1705, 1706, 1707, 1709, 1711, 1713, 1714, 1717, 1718, 1721, 1722, 1723, 1726, 1727, 1729, 1730, 1731, 1733, 1735, 1738, 1739, 1741, 1742, + 1743, 1745, 1747, 1749, 1751, 1753, 1754, 1757, 1758, 1759, 1761, 1762, 1763, 1765, 1766, 1767, 1769, 1770, 1771, 1774, 1777, 1778, 1779, 1781, 1783, 1785, 1786, 1787, 1789, 1790, 1793, 1794, 1795, 1797, 1798, 1799, 1801, 1802, 1803, 1806, 1807, 1810, 1811, 1814, 1817, 1819, 1821, 1822, + 1823, 1826, 1829, 1830, 1831, 1833, 1834, 1835, 1837, 1838, 1839, 1841, 1842, 1843, 1846, 1847, 1851, 1853, 1855, 1857, 1858, 1861, 1865, 1866, 1867, 1869, 1870, 1871, 1873, 1874, 1877, 1878, 1879, 1882, 1883, 1885, 1886, 1887, 1889, 1891, 1893, 1894, 1895, 1897, 1898, 1901, 1902, 1903, + 1905, 1906, 1907, 1909, 1910, 1913, 1914, 1915, 1918, 1919, 1921, 1923, 1927, 1929, 1930, 1931, 1933, 1934, 1937, 1938, 1939, 1941, 1942, 1943, 1945, 1946, 1947, 1949, 1951, 1954, 1955, 1957, 1958, 1959, 1961, 1963, 1965, 1966, 1967, 1969, 1970, 1973, 1974, 1977, 1978, 1979, 1981, 1982, + 1983, 1985, 1986, 1987, 1990, 1991, 1993, 1994, 1995, 1997, 1999, 2001, 2002, 2003, 2005, 2006, 2010, 2011, 2013, 2014, 2015, 2017, 2018, 2019, 2021, 2022, 2026, 2027, 2029, 2030, 2031, 2033, 2035, 2037, 2038, 2039, 2041, 2042, 2045, 2046, 2047, 2049, 2051, 2053, 2054, 2055, 2059, 2062, + 2063, 2065, 2066, 2067, 2069, 2071, 2073, 2074, 2077, 2078, 2081, 2082, 2083, 2085, 2086, 2087, 2089, 2090, 2091, 2093, 2094, 2095, 2098, 2099, 2101, 2102, 2103, 2105, 2109, 2110, 2111, 2113, 2114, 2117, 2118, 2119, 2121, 2122, 2123, 2126, 2127, 2129, 2130, 2131, 2134, 2135, 2137, 2138, + 2139, 2141, 2143, 2145, 2146, 2147, 2149, 2153, 2154, 2155, 2157, 2158, 2159, 2161, 2162, 2163, 2165, 2167, 2170, 2171, 2173, 2174, 2177, 2179, 2181, 2182, 2183, 2185, 2186, 2189, 2190, 2191, 2193, 2194, 2195, 2198, 2199, 2201, 2202, 2203, 2206, 2207, 2210, 2211, 2213, 2215, 2217, 2218, + 2219, 2221, 2222, 2226, 2227, 2229, 2230, 2231, 2233, 2234, 2235, 2237, 2238, 2239, 2242, 2243, 2245, 2246, 2247, 2249, 2251, 2253, 2255, 2257, 2258, 2261, 2262, 2263, 2265, 2266, 2267, 2269, 2270, 2271, 2273, 2274, 2278, 2279, 2281, 2282, 2283, 2285, 2287, 2289, 2290, 2291, 2293, 2294, + 2297, 2298, 2301, 2302, 2305, 2306, 2307, 2309, 2310, 2311, 2314, 2315, 2317, 2318, 2319, 2321, 2323, 2326, 2327, 2329, 2330, 2333, 2334, 2335, 2337, 2338, 2339, 2341, 2342, 2343, 2345, 2346, 2347, 2351, 2353, 2354, 2355, 2357, 2359, 2361, 2362, 2363, 2365, 2369, 2370, 2371, 2373, 2374, + 2377, 2378, 2379, 2381, 2382, 2383, 2386, 2387, 2389, 2390, 2391, 2393, 2395, 2397, 2398, 2399, 2402, 2405, 2406, 2407, 2409, 2410, 2411, 2413, 2414, 2415, 2417, 2418, 2419, 2422, 2423, 2426, 2427, 2429, 2431, 2433, 2434, 2435, 2437, 2438, 2441, 2442, 2443, 2445, 2446, 2447, 2449, 2451, + 2453, 2454, 2455, 2458, 2459, 2461, 2462, 2463, 2465, 2467, 2469, 2470, 2471, 2473, 2474, 2477, 2478, 2479, 2481, 2482, 2483, 2485, 2486, 2487, 2489, 2490, 2491, 2494, 2495, 2497, 2498); + + for (int i = 1; i <= 2500; i++) { + // when + boolean isNumberSquareFree = SquareFreeInteger.isSquareFreeInteger(i); + boolean isNumberPresentInList = listOfSquareFreeIntegers.contains(i); + + // then + assertEquals(isNumberSquareFree, isNumberPresentInList); + } + } + + @Test + void testIsSquareFreeIntegerThrowExceptionIfNumberIsZero() { + // given + int number = 0; + String expectedMessage = "Number must be greater than zero."; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { SquareFreeInteger.isSquareFreeInteger(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } + + @Test + void testIsSquareFreeIntegerMustThrowExceptionIfNumberIsNegative() { + // given + int number = -1; + String expectedMessage = "Number must be greater than zero."; + + // when + Exception exception = assertThrows(IllegalArgumentException.class, () -> { SquareFreeInteger.isSquareFreeInteger(number); }); + String actualMessage = exception.getMessage(); + + // then + assertEquals(expectedMessage, actualMessage); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java b/Java/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java new file mode 100644 index 000000000000..067b68962bdb --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonTestMethod.java @@ -0,0 +1,22 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SquareRootWithNewtonRaphsonTestMethod { + + @Test + void testfor1() { + Assertions.assertEquals(1, SquareRootWithNewtonRaphsonMethod.squareRoot(1)); + } + + @Test + void testfor2() { + Assertions.assertEquals(1.414213562373095, SquareRootWithNewtonRaphsonMethod.squareRoot(2)); + } + + @Test + void testfor625() { + Assertions.assertEquals(25.0, SquareRootWithNewtonRaphsonMethod.squareRoot(625)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java b/Java/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java new file mode 100644 index 000000000000..77446d30df32 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class SquareRootwithBabylonianMethodTest { + + @Test + void testfor4() { + Assertions.assertEquals(2, SquareRootWithBabylonianMethod.squareRoot(4)); + } + + @Test + void testfor1() { + Assertions.assertEquals(1, SquareRootWithBabylonianMethod.squareRoot(1)); + } + + @Test + void testfor2() { + Assertions.assertEquals(1.4142135381698608, SquareRootWithBabylonianMethod.squareRoot(2)); + } + + @Test + void testfor625() { + Assertions.assertEquals(25, SquareRootWithBabylonianMethod.squareRoot(625)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/StandardDeviationTest.java b/Java/src/test/java/com/thealgorithms/maths/StandardDeviationTest.java new file mode 100644 index 000000000000..2c10d2d14f3e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/StandardDeviationTest.java @@ -0,0 +1,37 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class StandardDeviationTest { + + @Test + void test1() { + double[] t1 = new double[] {1, 1, 1, 1, 1}; + Assertions.assertEquals(StandardDeviation.stdDev(t1), 0.0); + } + + @Test + void test2() { + double[] t2 = new double[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + Assertions.assertEquals(StandardDeviation.stdDev(t2), 2.8722813232690143); + } + + @Test + void test3() { + double[] t3 = new double[] {1.1, 8.5, 20.3, 2.4, 6.2}; + Assertions.assertEquals(StandardDeviation.stdDev(t3), 6.8308125431752265); + } + + @Test + void test4() { + double[] t4 = new double[] { + 3.14, + 2.22222, + 9.89898989, + 100.00045, + 56.7, + }; + Assertions.assertEquals(StandardDeviation.stdDev(t4), 38.506117353865775); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/StandardScoreTest.java b/Java/src/test/java/com/thealgorithms/maths/StandardScoreTest.java new file mode 100644 index 000000000000..436b1fd011c6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/StandardScoreTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class StandardScoreTest { + + @Test + void test1() { + Assertions.assertEquals(StandardScore.zScore(2, 0, 5), 0.4); + } + + @Test + void test2() { + Assertions.assertEquals(StandardScore.zScore(1, 1, 1), 0.0); + } + + @Test + void test3() { + Assertions.assertEquals(StandardScore.zScore(2.5, 1.8, 0.7), 1.0); + } + + @Test + void test4() { + Assertions.assertEquals(StandardScore.zScore(8.9, 3, 4.2), 1.4047619047619049); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java b/Java/src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java new file mode 100644 index 000000000000..2269291e06c1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/StrobogrammaticNumberTest.java @@ -0,0 +1,19 @@ +package com.thealgorithms.maths; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class StrobogrammaticNumberTest { + + @Test + void testIsStrobogrammatic() { + StrobogrammaticNumber strobogrammaticNumber = new StrobogrammaticNumber(); + assertThat(strobogrammaticNumber.isStrobogrammatic("69")).isTrue(); + assertThat(strobogrammaticNumber.isStrobogrammatic("88")).isTrue(); + assertThat(strobogrammaticNumber.isStrobogrammatic("818")).isTrue(); + assertThat(strobogrammaticNumber.isStrobogrammatic("101")).isTrue(); + assertThat(strobogrammaticNumber.isStrobogrammatic("609")).isTrue(); + assertThat(strobogrammaticNumber.isStrobogrammatic("120")).isFalse(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java b/Java/src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java new file mode 100644 index 000000000000..527cef2c187d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SumOfArithmeticSeriesTest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class SumOfArithmeticSeriesTest { + @Test + public void testSumFrom1To10() { + assertEquals(55.0, SumOfArithmeticSeries.sumOfSeries(1.0, 1.0, 10)); + } + + @Test + public void testSumOfOddNumbers1To19() { + assertEquals(100.0, SumOfArithmeticSeries.sumOfSeries(1.0, 2.0, 10)); + } + + @Test + public void testA() { + assertEquals(460.0, SumOfArithmeticSeries.sumOfSeries(1.0, 10.0, 10)); + } + + @Test + public void testB() { + assertEquals(5.5, SumOfArithmeticSeries.sumOfSeries(0.1, 0.1, 10)); + } + + @Test + public void testC() { + assertEquals(49600.0, SumOfArithmeticSeries.sumOfSeries(1, 10, 100)); + } + + @Test + public void testForZeroTerms() { + assertEquals(0.0, SumOfArithmeticSeries.sumOfSeries(1.0, 100.0, 0), 0.00001); + } + + @Test + public void testIfThrowsExceptionForNegativeNumberOfTerms() { + assertThrows(IllegalArgumentException.class, () -> SumOfArithmeticSeries.sumOfSeries(1.0, 1.0, -1)); + } + + @Test + public void testWithSingleTerm() { + assertEquals(123.0, SumOfArithmeticSeries.sumOfSeries(123.0, 5.0, 1)); + } + + @Test + public void testWithZeroCommonDiff() { + assertEquals(100.0, SumOfArithmeticSeries.sumOfSeries(1.0, 0.0, 100)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java b/Java/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java new file mode 100644 index 000000000000..76aca44a2220 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SumOfDigitsTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.maths; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class SumOfDigitsTest { + @ParameterizedTest + @MethodSource("testCases") + void sumOfDigitsTest(final int expected, final int input) { + Assertions.assertEquals(expected, SumOfDigits.sumOfDigits(input)); + } + + @ParameterizedTest + @MethodSource("testCases") + void sumOfDigitsRecursionTest(final int expected, final int input) { + Assertions.assertEquals(expected, SumOfDigits.sumOfDigitsRecursion(input)); + } + + @ParameterizedTest + @MethodSource("testCases") + void sumOfDigitsFastTest(final int expected, final int input) { + Assertions.assertEquals(expected, SumOfDigits.sumOfDigitsFast(input)); + } + + private static Stream<Arguments> testCases() { + return Stream.of(Arguments.of(0, 0), Arguments.of(1, 1), Arguments.of(15, 12345), Arguments.of(6, -123), Arguments.of(1, -100000), Arguments.of(8, 512)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java b/Java/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java new file mode 100644 index 000000000000..1eab73c67642 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java @@ -0,0 +1,40 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class SumWithoutArithmeticOperatorsTest { + SumWithoutArithmeticOperators obj = new SumWithoutArithmeticOperators(); + + @Test + void addZerotoZero() { + assertEquals(0, obj.getSum(0, 0)); + } + + @Test + void addZerotoNumber() { + assertEquals(5, obj.getSum(0, 5)); + assertEquals(28, obj.getSum(28, 0)); + } + + @Test + void addOddtoEven() { + assertEquals(13, obj.getSum(3, 10)); + assertEquals(55, obj.getSum(49, 6)); + } + + @Test + void addEventoOdd() { + assertEquals(13, obj.getSum(10, 3)); + assertEquals(41, obj.getSum(40, 1)); + } + + @Test + void addRandoms() { + assertEquals(88, obj.getSum(44, 44)); + assertEquals(370, obj.getSum(100, 270)); + assertEquals(3, obj.getSum(1, 2)); + assertEquals(5, obj.getSum(2, 3)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/TestArmstrong.java b/Java/src/test/java/com/thealgorithms/maths/TestArmstrong.java new file mode 100644 index 000000000000..60f4f2431189 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/TestArmstrong.java @@ -0,0 +1,15 @@ +package com.thealgorithms.maths; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +public class TestArmstrong { + + @Test + public void testArmstrong() { + Armstrong armstrong = new Armstrong(); + assertThat(armstrong.isArmstrong(371)).isTrue(); + assertThat(armstrong.isArmstrong(200)).isFalse(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java b/Java/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java new file mode 100644 index 000000000000..e214b0ada347 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/TwinPrimeTest.java @@ -0,0 +1,60 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class TwinPrimeTest { + + @Test + void shouldReturn7() { + // given + int number = 5; + int expectedResult = 7; + + // when + int actualResult = TwinPrime.getTwinPrime(number); + + // then + assertEquals(expectedResult, actualResult); + } + + @Test + void shouldReturn5() { + // given + int number = 3; + int expectedResult = 5; + + // when + int actualResult = TwinPrime.getTwinPrime(number); + + // then + assertEquals(expectedResult, actualResult); + } + + @Test + void shouldReturnNegative1() { + // given + int number = 4; + int expectedResult = -1; + + // when + int actualResult = TwinPrime.getTwinPrime(number); + + // then + assertEquals(expectedResult, actualResult); + } + + @Test + void shouldReturn19() { + // given + int number = 17; + int expectedResult = 19; + + // when + int actualResult = TwinPrime.getTwinPrime(number); + + // then + assertEquals(expectedResult, actualResult); + } +} diff --git a/Java/src/test/java/com/thealgorithms/maths/VolumeTest.java b/Java/src/test/java/com/thealgorithms/maths/VolumeTest.java new file mode 100644 index 000000000000..1bdb3ae80040 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/maths/VolumeTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class VolumeTest { + + @Test + public void volume() { + + /* test cube */ + assertTrue(Volume.volumeCube(7) == 343.0); + + /* test cuboid */ + assertTrue(Volume.volumeCuboid(2, 5, 7) == 70.0); + + /* test sphere */ + assertTrue(Volume.volumeSphere(7) == 1436.7550402417319); + + /* test cylinder */ + assertTrue(Volume.volumeCylinder(3, 7) == 197.92033717615698); + + /* test hemisphere */ + assertTrue(Volume.volumeHemisphere(7) == 718.3775201208659); + + /* test cone */ + assertTrue(Volume.volumeCone(3, 7) == 65.97344572538566); + + /* test prism */ + assertTrue(Volume.volumePrism(10, 2) == 20.0); + + /* test pyramid */ + assertTrue(Volume.volumePyramid(10, 3) == 10.0); + } +} diff --git a/Java/src/test/java/com/thealgorithms/misc/MapReduceTest.java b/Java/src/test/java/com/thealgorithms/misc/MapReduceTest.java new file mode 100644 index 000000000000..c79c40701cc1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/misc/MapReduceTest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.misc; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MapReduceTest { + @Test + public void testMapReduceWithSingleWordSentence() { + String oneWordSentence = "Hactober"; + String result = MapReduce.mapreduce(oneWordSentence); + + assertEquals("Hactober: 1", result); + } + + @Test + public void testMapReduceWithMultipleWordSentence() { + String multipleWordSentence = "I Love Love HactoberFest"; + String result = MapReduce.mapreduce(multipleWordSentence); + + assertEquals("I: 1,Love: 2,HactoberFest: 1", result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java b/Java/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java new file mode 100644 index 000000000000..ec3a84b86c5b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.misc; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class MedianOfMatrixtest { + + @Test + public void testMedianWithOddNumberOfElements() { + List<List<Integer>> matrix = new ArrayList<>(); + matrix.add(Arrays.asList(1, 3, 5)); + matrix.add(Arrays.asList(2, 4, 6)); + matrix.add(Arrays.asList(7, 8, 9)); + + int result = MedianOfMatrix.median(matrix); + + assertEquals(5, result); + } + + @Test + public void testMedianWithEvenNumberOfElements() { + List<List<Integer>> matrix = new ArrayList<>(); + matrix.add(Arrays.asList(2, 4)); + matrix.add(Arrays.asList(1, 3)); + + int result = MedianOfMatrix.median(matrix); + + assertEquals(2, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java b/Java/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java new file mode 100644 index 000000000000..90910d511ca0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/misc/MedianOfRunningArrayTest.java @@ -0,0 +1,199 @@ +package com.thealgorithms.misc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +/** + * Test case for Median Of Running Array Problem. + * @author Ansh Shah (https://github.com/govardhanshah456) + */ + +public class MedianOfRunningArrayTest { + private static final String EXCEPTION_MESSAGE = "Enter at least 1 element, Median of empty list is not defined!"; + + @Test + public void testWhenInvalidInoutProvidedShouldThrowException() { + var stream = new MedianOfRunningArrayInteger(); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> stream.median()); + assertEquals(exception.getMessage(), EXCEPTION_MESSAGE); + } + + @Test + public void testWithNegativeValues() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(-1); + assertEquals(-1, stream.median()); + stream.insert(-2); + assertEquals(-1, stream.median()); + stream.insert(-3); + assertEquals(-2, stream.median()); + } + + @Test + public void testWithSingleValues() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(-1); + assertEquals(-1, stream.median()); + } + + @Test + public void testWithRandomValues() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(10); + assertEquals(10, stream.median()); + + stream.insert(5); + assertEquals(7, stream.median()); + + stream.insert(20); + assertEquals(10, stream.median()); + + stream.insert(15); + assertEquals(12, stream.median()); + + stream.insert(25); + assertEquals(15, stream.median()); + + stream.insert(30); + assertEquals(17, stream.median()); + + stream.insert(35); + assertEquals(20, stream.median()); + + stream.insert(1); + assertEquals(17, stream.median()); + } + + @Test + public void testWithNegativeAndPositiveValues() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(-1); + assertEquals(-1, stream.median()); + stream.insert(2); + assertEquals(0, stream.median()); + stream.insert(-3); + assertEquals(-1, stream.median()); + } + + @Test + public void testWithDuplicateValues() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(-1); + assertEquals(-1, stream.median()); + stream.insert(-1); + assertEquals(-1, stream.median()); + stream.insert(-1); + assertEquals(-1, stream.median()); + } + + @Test + public void testWithDuplicateValuesB() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(10); + stream.insert(20); + stream.insert(10); + stream.insert(10); + stream.insert(20); + stream.insert(0); + stream.insert(50); + assertEquals(10, stream.median()); + } + + @Test + public void testWithLargeValues() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(1000000); + assertEquals(1000000, stream.median()); + stream.insert(12000); + assertEquals(506000, stream.median()); + stream.insert(15000000); + assertEquals(1000000, stream.median()); + stream.insert(2300000); + assertEquals(1650000, stream.median()); + } + + @Test + public void testWithLargeCountOfValues() { + var stream = new MedianOfRunningArrayInteger(); + for (int i = 1; i <= 1000; i++) stream.insert(i); + assertEquals(500, stream.median()); + } + + @Test + public void testWithThreeValuesInDescendingOrder() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(30); + stream.insert(20); + stream.insert(10); + assertEquals(20, stream.median()); + } + + @Test + public void testWithThreeValuesInOrder() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(10); + stream.insert(20); + stream.insert(30); + assertEquals(20, stream.median()); + } + + @Test + public void testWithThreeValuesNotInOrderA() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(30); + stream.insert(10); + stream.insert(20); + assertEquals(20, stream.median()); + } + + @Test + public void testWithThreeValuesNotInOrderB() { + var stream = new MedianOfRunningArrayInteger(); + stream.insert(20); + stream.insert(10); + stream.insert(30); + assertEquals(20, stream.median()); + } + + @Test + public void testWithFloatValues() { + var stream = new MedianOfRunningArrayFloat(); + stream.insert(20.0f); + assertEquals(20.0f, stream.median()); + stream.insert(10.5f); + assertEquals(15.25f, stream.median()); + stream.insert(30.0f); + assertEquals(20.0f, stream.median()); + } + + @Test + public void testWithByteValues() { + var stream = new MedianOfRunningArrayByte(); + stream.insert((byte) 120); + assertEquals((byte) 120, stream.median()); + stream.insert((byte) -120); + assertEquals((byte) 0, stream.median()); + stream.insert((byte) 127); + assertEquals((byte) 120, stream.median()); + } + + @Test + public void testWithLongValues() { + var stream = new MedianOfRunningArrayLong(); + stream.insert(120000000L); + assertEquals(120000000L, stream.median()); + stream.insert(92233720368547757L); + assertEquals(46116860244273878L, stream.median()); + } + + @Test + public void testWithDoubleValues() { + var stream = new MedianOfRunningArrayDouble(); + stream.insert(12345.67891); + assertEquals(12345.67891, stream.median()); + stream.insert(23456789.98); + assertEquals(Double.valueOf(11734567.83), stream.median(), .01); + } +} diff --git a/Java/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java b/Java/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java new file mode 100644 index 000000000000..0da0cf0f804a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/misc/MirrorOfMatrixTest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.misc; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class MirrorOfMatrixTest { + + @Test + void testMirrorMatrixRegularMatrix() { + int[][] originalMatrix = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; + int[][] expectedMirrorMatrix = {{3, 2, 1}, {6, 5, 4}, {9, 8, 7}}; + int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); + } + + @Test + void testMirrorMatrixEmptyMatrix() { + int[][] originalMatrix = {}; + int[][] expectedMirrorMatrix = {}; + int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); + } + + @Test + void testMirrorMatrixSingleElementMatrix() { + int[][] originalMatrix = {{42}}; + int[][] expectedMirrorMatrix = {{42}}; + int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); + } + + @Test + void testMirrorMatrixMultipleRowsOneColumnMatrix() { + int[][] originalMatrix = {{1}, {2}, {3}, {4}}; + int[][] expectedMirrorMatrix = {{1}, {2}, {3}, {4}}; + int[][] mirroredMatrix = MirrorOfMatrix.mirrorMatrix(originalMatrix); + assertArrayEquals(expectedMirrorMatrix, mirroredMatrix); + } + + @Test + void testMirrorMatrixNullInput() { + int[][] originalMatrix = null; + assertNull(MirrorOfMatrix.mirrorMatrix(originalMatrix)); + } + + @Test + void testMirrotMarixThrows() { + assertThrows(IllegalArgumentException.class, () -> MirrorOfMatrix.mirrorMatrix(new int[][] {{1}, {2, 3}})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java b/Java/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java new file mode 100644 index 000000000000..ae0d6ae0674d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/misc/PalindromeSinglyLinkedListTest.java @@ -0,0 +1,70 @@ +package com.thealgorithms.misc; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.datastructures.lists.SinglyLinkedList; +import org.junit.jupiter.api.Test; + +public class PalindromeSinglyLinkedListTest { + @Test + public void testWithEmptyList() { + assertTrue(PalindromeSinglyLinkedList.isPalindrome(new SinglyLinkedList())); + } + + @Test + public void testWithSingleElement() { + var exampleList = new SinglyLinkedList(); + exampleList.insert(100); + assertTrue(PalindromeSinglyLinkedList.isPalindrome(exampleList)); + } + + @Test + public void testWithListWithOddLengthPositive() { + var exampleList = new SinglyLinkedList(); + exampleList.insert(1); + exampleList.insert(2); + exampleList.insert(1); + assertTrue(PalindromeSinglyLinkedList.isPalindrome(exampleList)); + } + + @Test + public void testWithListWithOddLengthPositive2() { + var exampleList = new SinglyLinkedList(); + exampleList.insert(3); + exampleList.insert(2); + exampleList.insert(1); + exampleList.insert(2); + exampleList.insert(3); + assertTrue(PalindromeSinglyLinkedList.isPalindrome(exampleList)); + } + + @Test + public void testWithListWithEvenLengthPositive() { + var exampleList = new SinglyLinkedList(); + exampleList.insert(10); + exampleList.insert(20); + exampleList.insert(20); + exampleList.insert(10); + assertTrue(PalindromeSinglyLinkedList.isPalindrome(exampleList)); + } + + @Test + public void testWithListWithOddLengthNegative() { + var exampleList = new SinglyLinkedList(); + exampleList.insert(1); + exampleList.insert(2); + exampleList.insert(2); + assertFalse(PalindromeSinglyLinkedList.isPalindrome(exampleList)); + } + + @Test + public void testWithListWithEvenLengthNegative() { + var exampleList = new SinglyLinkedList(); + exampleList.insert(10); + exampleList.insert(20); + exampleList.insert(20); + exampleList.insert(20); + assertFalse(PalindromeSinglyLinkedList.isPalindrome(exampleList)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java b/Java/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java new file mode 100644 index 000000000000..86e73ac0547c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/misc/TwoSumProblemTest.java @@ -0,0 +1,61 @@ +package com.thealgorithms.misc; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.jupiter.api.Test; + +/** + * Test case for Two sum Problem. + * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) + */ + +public class TwoSumProblemTest { + + @Test + void testTwoSumExists() { + final int[] values = new int[] {2, 7, 11, 15}; + final int target = 9; + final var expected = Pair.of(0, 1); // values[0] + values[1] = 2 + 7 = 9 + assertEquals(expected, TwoSumProblem.twoSum(values, target).get()); + } + + @Test + void testTwoSumNoSolution() { + final int[] values = new int[] {2, 7, 11, 15}; + final int target = 3; + assertFalse(TwoSumProblem.twoSum(values, target).isPresent()); + } + + @Test + void testTwoSumMultipleSolutions() { + final int[] values = {3, 3}; + final int target = 6; + final var expected = Pair.of(0, 1); // values[0] + values[1] = 3 + 3 = 6 + assertEquals(expected, TwoSumProblem.twoSum(values, target).get()); + } + + @Test + void testTwoSumMultipleSolution() { + final int[] values = {3, 4, 3, 3}; + final int target = 6; + final var expected = Pair.of(0, 2); // values[0] + values[2] = 3 + 3 = 6 + assertEquals(expected, TwoSumProblem.twoSum(values, target).get()); + } + + @Test + void testTwoSumNegativeNumbers() { + final int[] values = {-1, -2, -3, -4, -5}; + final int target = -8; + final var expected = Pair.of(2, 4); // values[2] + values[4] = -3 + (-5) = -8 + assertEquals(expected, TwoSumProblem.twoSum(values, target).get()); + } + + @Test + void testTwoSumNoSolutionDuplicatedInputs() { + final int[] values = {0, 0, 0}; + final int target = 100; + assertFalse(TwoSumProblem.twoSum(values, target).isPresent()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java b/Java/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java new file mode 100644 index 000000000000..355f107ddb61 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java @@ -0,0 +1,47 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class ArrayLeftRotationTest { + + @Test + void testForOneElement() { + int[] arr = {3}; + int[] result = ArrayLeftRotation.rotateLeft(arr, 3); + assertArrayEquals(arr, result); + } + + @Test + void testForZeroStep() { + int[] arr = {3, 1, 5, 8, 6}; + int[] result = ArrayLeftRotation.rotateLeft(arr, 0); + assertArrayEquals(arr, result); + } + + @Test + void testForEqualSizeStep() { + int[] arr = {3, 1, 5, 8, 6}; + int[] result = ArrayLeftRotation.rotateLeft(arr, 5); + assertArrayEquals(arr, result); + } + + @Test + void testForLowerSizeStep() { + int[] arr = {3, 1, 5, 8, 6}; + int n = 2; + int[] expected = {5, 8, 6, 3, 1}; + int[] result = ArrayLeftRotation.rotateLeft(arr, n); + assertArrayEquals(expected, result); + } + + @Test + void testForHigherSizeStep() { + int[] arr = {3, 1, 5, 8, 6}; + int n = 7; + int[] expected = {5, 8, 6, 3, 1}; + int[] result = ArrayLeftRotation.rotateLeft(arr, n); + assertArrayEquals(expected, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/ArrayRightRotation.java b/Java/src/test/java/com/thealgorithms/others/ArrayRightRotation.java new file mode 100644 index 000000000000..11e4f44500b1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/ArrayRightRotation.java @@ -0,0 +1,30 @@ +package com.thealgorithms.others; + +public final class ArrayRightRotation { + private ArrayRightRotation() { + } + public static int[] rotateRight(int[] arr, int k) { + if (arr == null || arr.length == 0 || k < 0) { + throw new IllegalArgumentException("Invalid input"); + } + + int n = arr.length; + k = k % n; // Handle cases where k is larger than the array length + + reverseArray(arr, 0, n - 1); + reverseArray(arr, 0, k - 1); + reverseArray(arr, k, n - 1); + + return arr; + } + + private static void reverseArray(int[] arr, int start, int end) { + while (start < end) { + int temp = arr[start]; + arr[start] = arr[end]; + arr[end] = temp; + start++; + end--; + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java b/Java/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java new file mode 100644 index 000000000000..f132d56dd9cd --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/ArrayRightRotationTest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class ArrayRightRotationTest { + + @Test + void testArrayRightRotation() { + int[] arr = {1, 2, 3, 4, 5, 6, 7}; + int k = 3; + int[] expected = {5, 6, 7, 1, 2, 3, 4}; + int[] result = ArrayRightRotation.rotateRight(arr, k); + assertArrayEquals(expected, result); + } + + @Test + void testArrayRightRotationWithZeroSteps() { + int[] arr = {1, 2, 3, 4, 5, 6, 7}; + int k = 0; + int[] expected = {1, 2, 3, 4, 5, 6, 7}; + int[] result = ArrayRightRotation.rotateRight(arr, k); + assertArrayEquals(expected, result); + } + + @Test + void testArrayRightRotationWithEqualSizeSteps() { + int[] arr = {1, 2, 3, 4, 5, 6, 7}; + int k = arr.length; + int[] expected = {1, 2, 3, 4, 5, 6, 7}; + int[] result = ArrayRightRotation.rotateRight(arr, k); + assertArrayEquals(expected, result); + } + + @Test + void testArrayRightRotationWithLowerSizeSteps() { + int[] arr = {1, 2, 3, 4, 5, 6, 7}; + int k = 2; + int[] expected = {6, 7, 1, 2, 3, 4, 5}; + int[] result = ArrayRightRotation.rotateRight(arr, k); + assertArrayEquals(expected, result); + } + + @Test + void testArrayRightRotationWithHigherSizeSteps() { + int[] arr = {1, 2, 3, 4, 5, 6, 7}; + int k = 10; + int[] expected = {5, 6, 7, 1, 2, 3, 4}; + int[] result = ArrayRightRotation.rotateRight(arr, k); + assertArrayEquals(expected, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/BestFitCPUTest.java b/Java/src/test/java/com/thealgorithms/others/BestFitCPUTest.java new file mode 100644 index 000000000000..296cf1ca1c04 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/BestFitCPUTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +/** + * author Alexandros Lemonaris + */ +class BestFitCPUTest { + + int[] sizeOfBlocks; + int[] sizeOfProcesses; + ArrayList<Integer> memAllocation = new ArrayList<>(); + ArrayList<Integer> testMemAllocation; + MemoryManagementAlgorithms bestFit = new BestFitCPU(); + + @Test + void testFitForUseOfOneBlock() { + // test1 - 2 processes shall fit to one block instead of using a different block each + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 5, 15, 2}; + memAllocation = bestFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(3, 0, 2, 2)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForEqualProcecesses() { + // test2 + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 10, 10, 10}; + memAllocation = bestFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(3, 1, 2, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForNoEmptyBlockCell() { + // test3 for more processes than blocks - no empty space left to none of the blocks + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 12, 10, 7}; + memAllocation = bestFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(0, 1, 2, 2)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForSameInputDifferentQuery() { + // test4 for more processes than blocks - one element does not fit due to input series + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 7, 10, 12}; + memAllocation = bestFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(0, 1, 2, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForMoreBlocksNoFit() { + // test5 for more blocks than processes + sizeOfBlocks = new int[] {5, 4, -1, 3, 6}; + sizeOfProcesses = new int[] {10, 11}; + memAllocation = bestFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(-255, -255)); + assertEquals(testMemAllocation, memAllocation); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/BoyerMooreTest.java b/Java/src/test/java/com/thealgorithms/others/BoyerMooreTest.java new file mode 100644 index 000000000000..b6620793d267 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/BoyerMooreTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.others; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class BoyerMooreTest { + + @ParameterizedTest + @MethodSource("inputStreamWithExistingMajority") + void checkWhenMajorityExists(int expected, int[] input) { + Assertions.assertEquals(expected, BoyerMoore.findMajor(input).get()); + } + + private static Stream<Arguments> inputStreamWithExistingMajority() { + return Stream.of(Arguments.of(5, new int[] {5, 5, 5, 2}), Arguments.of(10, new int[] {10, 10, 20}), Arguments.of(10, new int[] {10, 20, 10}), Arguments.of(10, new int[] {20, 10, 10}), Arguments.of(4, new int[] {1, 4, 2, 4, 4, 5, 4}), Arguments.of(-1, new int[] {-1})); + } + + @ParameterizedTest + @MethodSource("inputStreamWithoutMajority") + void checkWhenMajorityExists(int[] input) { + Assertions.assertFalse(BoyerMoore.findMajor(input).isPresent()); + } + + private static Stream<Arguments> inputStreamWithoutMajority() { + return Stream.of(Arguments.of(new int[] {10, 10, 20, 20, 30, 30}), Arguments.of(new int[] {10, 20, 30, 40, 50}), Arguments.of(new int[] {1, 2}), Arguments.of(new int[] {})); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/CRC16Test.java b/Java/src/test/java/com/thealgorithms/others/CRC16Test.java new file mode 100644 index 000000000000..bf309928bbf4 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/CRC16Test.java @@ -0,0 +1,19 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class CRC16Test { + @Test + void testCRC16() { + // given + String textToCRC16 = "hacktoberfest!"; + + // when + String resultCRC16 = CRC16.crc16(textToCRC16); // Algorithm CRC16-CCITT-FALSE + + // then + assertEquals("10FC", resultCRC16); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java b/Java/src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java new file mode 100644 index 000000000000..a581a35bf963 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/CRCAlgorithmTest.java @@ -0,0 +1,29 @@ + +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class CRCAlgorithmTest { + + @Test + void test1() { + CRCAlgorithm c = new CRCAlgorithm("10010101010100101010010000001010010101010", 10, 0.0); + + // A bit-error rate of 0.0 should not provide any wrong messages + c.changeMess(); + c.divideMessageWithP(false); + assertEquals(c.getWrongMess(), 0); + } + + @Test + void test2() { + CRCAlgorithm c = new CRCAlgorithm("10010101010100101010010000001010010101010", 10, 1.0); + + // A bit error rate of 1.0 should not provide any correct messages + c.changeMess(); + c.divideMessageWithP(false); + assertEquals(c.getCorrectMess(), 0); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/ConwayTest.java b/Java/src/test/java/com/thealgorithms/others/ConwayTest.java new file mode 100644 index 000000000000..f4c3051a1fe2 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/ConwayTest.java @@ -0,0 +1,41 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ConwayTest { + @Test + public void testGenerateWith1() { + assertEquals("31131211131221", Conway.generateList("1", 8).get(7)); + } + + @Test + public void testGenerateWith123456() { + assertEquals( + "13211321322113311213212312311211131122211213211331121321122112133221123113112221131112212211131221121321131211132221123113112221131112311332211211131221131211132211121312211231131112311211232221143113112221131112311332111213122112311311123112112322211531131122211311123113321112131221123113111231121123222116", + Conway.generateList("123456", 20).get(11)); + } + + @Test + public void testGenerateWith1A1Z3E1R1T3G1F1D2E1S1C() { + assertEquals( + "311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211A311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211Z111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122111213122112311311222113111221131221221321132132211331121321231231121113112221121321133112132112211213322112311311222113111231133211121312211231131122211322311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121122132112311321322112111312211312113221133211322112211213322112132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113213221133112132123222113221321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123113221231231121113213221231221132221222112112322211E311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211R311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211T111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122111213122112311311222113111221131221221321132132211331121321231231121113112221121321133112132112211213322112311311222113111231133211121312211231131122211322311311222112111312211311123113322112132113212231121113112221121321132122211322212221121123222112111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121122132112311321322112111312211312113221133211322112211213322112132113213221133112132123123112111311222112132113311213211231232112311311222112111312211311123113322112132113213221133112132123222113221321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123113221231231121113213221231221132221222112112322211G311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211F311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211D111312211312111322212321121113121112131112132112311321322112111312212321121113122112131112131221121321132132211231131122211331121321232221121113122113121122132112311321322112111312211312111322211213111213122112132113121113222112132113213221133112132123222112311311222113111231132231121113112221121321133112132112211213322112111312211312111322212311222122132113213221123113112221133112132123222112111312211312111322212311322123123112111321322123122113222122211211232221121113122113121113222123211211131211121311121321123113213221121113122123211211131221121311121312211213211321322112311311222113311213212322211211131221131211221321123113213221121113122113121113222112131112131221121321131211132221121321132132211331121321232221123113112221131112311322311211131122211213211331121321122112133221121113122113121113222123112221221321132132211231131122211331121321232221121113122113121113222123113221231231121113213221231221132221222112112322211E311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211S311311222113111231133211121312211231131112311211133112111312211213211312111322211231131122111213122112311311222112111331121113112221121113122113121113222112132113213221232112111312111213322112311311222113111221221113122112132113121113222112311311222113111231133221121113311211131122211211131221131112311332211211131221131211132221232112111312111213322112132113213221133112132113221321123113213221121113122123211211131221222112112322211231131122211311123113321112132132112211131221131211132221121321132132212321121113121112133221123113112221131112311332111213211322111213111213211231131211132211121311222113321132211221121332211C", + Conway.generateList("1A1Z3E1R1T3G1F1D2E1S1C", 20).get(19)); + } + + @Test + public void testGenerateNextElementWith1() { + assertEquals("11", Conway.generateNextElement("1")); + } + + @Test + public void testGenerateNextElementWith123456() { + assertEquals("111213141516", Conway.generateNextElement("123456")); + } + + @Test + public void testGenerateNextElementWith1A1Z3E1R1T3G1F1D2E1S1C() { + assertEquals("111A111Z131E111R111T131G111F111D121E111S111C", Conway.generateNextElement("1A1Z3E1R1T3G1F1D2E1S1C")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/CountCharTest.java b/Java/src/test/java/com/thealgorithms/others/CountCharTest.java new file mode 100644 index 000000000000..382ba4246400 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/CountCharTest.java @@ -0,0 +1,16 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class CountCharTest { + + @Test + void testCountCharacters() { + String input = "12345"; + int expectedValue = 5; + + assertEquals(expectedValue, CountChar.countCharacters(input)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java b/Java/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java new file mode 100644 index 000000000000..f2e6944c06d2 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java @@ -0,0 +1,57 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.dynamicprogramming.CountFriendsPairing; +import org.junit.jupiter.api.Test; + +public class CountFriendsPairingTest { + + @Test + void testForOneElement() { + int[] a = {1, 2, 2}; + assertTrue(CountFriendsPairing.countFriendsPairing(3, a)); + } + + @Test + void testForTwoElements() { + int[] a = {1, 2, 2, 3}; + assertTrue(CountFriendsPairing.countFriendsPairing(4, a)); + } + + @Test + void testForThreeElements() { + int[] a = {1, 2, 2, 3, 3}; + assertTrue(CountFriendsPairing.countFriendsPairing(5, a)); + } + + @Test + void testForFourElements() { + int[] a = {1, 2, 2, 3, 3, 4}; + assertTrue(CountFriendsPairing.countFriendsPairing(6, a)); + } + + @Test + void testForFiveElements() { + int[] a = {1, 2, 2, 3, 3, 4, 4}; + assertTrue(CountFriendsPairing.countFriendsPairing(7, a)); + } + + @Test + void testForSixElements() { + int[] a = {1, 2, 2, 3, 3, 4, 4, 4}; + assertTrue(CountFriendsPairing.countFriendsPairing(8, a)); + } + + @Test + void testForSevenElements() { + int[] a = {1, 2, 2, 3, 3, 4, 4, 4, 5}; + assertTrue(CountFriendsPairing.countFriendsPairing(9, a)); + } + + @Test + void testForEightElements() { + int[] a = {1, 2, 2, 3, 3, 4, 4, 4, 5, 5}; + assertTrue(CountFriendsPairing.countFriendsPairing(10, a)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/CountWordsTest.java b/Java/src/test/java/com/thealgorithms/others/CountWordsTest.java new file mode 100644 index 000000000000..d5ebe654b325 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/CountWordsTest.java @@ -0,0 +1,37 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import org.junit.jupiter.api.Test; + +class CountWordsTest { + @Test + public void testWordCount() { + HashMap<String, Integer> testCases = new HashMap<>(); + testCases.put("", 0); + testCases.put(null, 0); + testCases.put("aaaa bbb cccc", 3); + testCases.put("note extra spaces here", 4); + testCases.put(" a b c d e ", 5); + + for (final var tc : testCases.entrySet()) { + assertEquals(CountWords.wordCount(tc.getKey()), tc.getValue()); + } + } + + @Test + public void testSecondaryWordCount() { + HashMap<String, Integer> testCases = new HashMap<>(); + testCases.put("", 0); + testCases.put(null, 0); + testCases.put("aaaa bbb cccc", 3); + testCases.put("this-is-one-word!", 1); + testCases.put("What, about, this? Hmmm----strange", 4); + testCases.put("word1 word-2 word-3- w?o,r.d.@!@#$&*()<>4", 4); + + for (final var tc : testCases.entrySet()) { + assertEquals(CountWords.secondaryWordCount(tc.getKey()), tc.getValue()); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/EulersFunctionTest.java b/Java/src/test/java/com/thealgorithms/others/EulersFunctionTest.java new file mode 100644 index 000000000000..b80926b8c2dc --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/EulersFunctionTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import org.junit.jupiter.api.Test; + +class EulersFunctionTest { + @Test + public void testGetEuler() { + HashMap<Integer, Integer> testCases = new HashMap<>(); + testCases.put(1, 1); + testCases.put(2, 1); + testCases.put(3, 2); + testCases.put(4, 2); + testCases.put(5, 4); + testCases.put(6, 2); + testCases.put(10, 4); + testCases.put(21, 12); + testCases.put(69, 44); + testCases.put(47, 46); + testCases.put(46, 22); + testCases.put(55, 40); + testCases.put(34, 16); + testCases.put(20, 8); + testCases.put(20, 8); + testCases.put(1024, 512); + + for (final var tc : testCases.entrySet()) { + assertEquals(tc.getValue(), EulersFunction.getEuler(tc.getKey())); + } + } + + @Test + public void testGetEulerThrowsExceptionForNonPositiveInput() { + assertThrows(IllegalArgumentException.class, () -> EulersFunction.getEuler(0)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java b/Java/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java new file mode 100644 index 000000000000..57b6e189b116 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +/** + * author Alexandros Lemonaris + */ +class FirstFitCPUTest { + + int[] sizeOfBlocks; + int[] sizeOfProcesses; + ArrayList<Integer> memAllocation = new ArrayList<>(); + ArrayList<Integer> testMemAllocation; + MemoryManagementAlgorithms firstFit = new FirstFitCPU(); + + @Test + void testFitForUseOfOneBlock() { + // test1 - no use of one block for two processes + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 5, 15, 2}; + memAllocation = firstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(1, 0, 2, 1)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForEqualProcecesses() { + // test2 + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 10, 10, 10}; + memAllocation = firstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(1, 2, 3, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForNoEmptyBlockCell() { + // test3 for more processes than blocks - no empty space left to none of the blocks + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 12, 10, 7}; + memAllocation = firstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(0, 1, 2, 2)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForSameInputDifferentQuery() { + // test4 for more processes than blocks - one element does not fit due to input series + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 7, 10, 12}; + memAllocation = firstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(0, 1, 2, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForMoreBlocksNoFit() { + // test5 for more blocks than processes + sizeOfBlocks = new int[] {5, 4, -1, 3, 6}; + sizeOfProcesses = new int[] {10, 11}; + memAllocation = firstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(-255, -255)); + assertEquals(testMemAllocation, memAllocation); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java b/Java/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java new file mode 100644 index 000000000000..25b211657c5d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java @@ -0,0 +1,57 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.dynamicprogramming.KadaneAlgorithm; +import org.junit.jupiter.api.Test; + +public class KadaneAlogrithmTest { + + @Test + void testForOneElement() { + int[] a = {-1}; + assertTrue(KadaneAlgorithm.maxSum(a, -1)); + } + + @Test + void testForTwoElements() { + int[] a = {-2, 1}; + assertTrue(KadaneAlgorithm.maxSum(a, 1)); + } + + @Test + void testForThreeElements() { + int[] a = {5, 3, 12}; + assertTrue(KadaneAlgorithm.maxSum(a, 20)); + } + + @Test + void testForFourElements() { + int[] a = {-1, -3, -7, -4}; + assertTrue(KadaneAlgorithm.maxSum(a, -1)); + } + + @Test + void testForFiveElements() { + int[] a = {4, 5, 3, 0, 2}; + assertTrue(KadaneAlgorithm.maxSum(a, 14)); + } + + @Test + void testForSixElements() { + int[] a = {-43, -45, 47, 12, 87, -13}; + assertTrue(KadaneAlgorithm.maxSum(a, 146)); + } + + @Test + void testForSevenElements() { + int[] a = {9, 8, 2, 23, 13, 6, 7}; + assertTrue(KadaneAlgorithm.maxSum(a, 68)); + } + + @Test + void testForEightElements() { + int[] a = {9, -5, -5, -2, 4, 5, 0, 1}; + assertTrue(KadaneAlgorithm.maxSum(a, 10)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/LineSweepTest.java b/Java/src/test/java/com/thealgorithms/others/LineSweepTest.java new file mode 100644 index 000000000000..6bf6ef5b3002 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/LineSweepTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.others; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +public class LineSweepTest { + + @Test + void testForOverlap() { + int[][] arr = {{0, 10}, {7, 20}, {15, 24}}; + assertTrue(LineSweep.isOverlap(arr)); + } + + @Test + void testForNoOverlap() { + int[][] arr = {{0, 10}, {11, 20}, {21, 24}}; + assertFalse(LineSweep.isOverlap(arr)); + } + @Test + void testForOverlapWhenEndAEqualsStartBAndViceVersa() { + int[][] arr = {{0, 10}, {10, 20}, {21, 24}}; + assertTrue(LineSweep.isOverlap(arr)); + } + @Test + void testForMaximumEndPoint() { + int[][] arr = {{10, 20}, {1, 100}, {14, 16}, {1, 8}}; + assertEquals(100, LineSweep.findMaximumEndPoint(arr)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/LinkListSortTest.java b/Java/src/test/java/com/thealgorithms/others/LinkListSortTest.java new file mode 100644 index 000000000000..100593b1f756 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/LinkListSortTest.java @@ -0,0 +1,57 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.sorts.LinkListSort; +import org.junit.jupiter.api.Test; + +public class LinkListSortTest { + + @Test + void testForOneElement() { + int[] a = {56}; + assertTrue(LinkListSort.isSorted(a, 2)); + } + + @Test + void testForTwoElements() { + int[] a = {6, 4}; + assertTrue(LinkListSort.isSorted(a, 1)); + } + + @Test + void testForThreeElements() { + int[] a = {875, 253, 12}; + assertTrue(LinkListSort.isSorted(a, 3)); + } + + @Test + void testForFourElements() { + int[] a = {86, 32, 87, 13}; + assertTrue(LinkListSort.isSorted(a, 1)); + } + + @Test + void testForFiveElements() { + int[] a = {6, 5, 3, 0, 9}; + assertTrue(LinkListSort.isSorted(a, 1)); + } + + @Test + void testForSixElements() { + int[] a = {9, 65, 432, 32, 47, 327}; + assertTrue(LinkListSort.isSorted(a, 3)); + } + + @Test + void testForSevenElements() { + int[] a = {6, 4, 2, 1, 3, 6, 7}; + assertTrue(LinkListSort.isSorted(a, 1)); + } + + @Test + void testForEightElements() { + int[] a = {123, 234, 145, 764, 322, 367, 768, 34}; + assertTrue(LinkListSort.isSorted(a, 2)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java b/Java/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java new file mode 100644 index 000000000000..c8e173ab8362 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/LowestBasePalindromeTest.java @@ -0,0 +1,80 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import org.junit.jupiter.api.Test; + +public class LowestBasePalindromeTest { + @Test + public void testIsPalindromicPositive() { + assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>())); + assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1)))); + assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 1)))); + assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2, 1)))); + assertTrue(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2, 2, 1)))); + } + + @Test + public void testIsPalindromicNegative() { + assertFalse(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2)))); + assertFalse(LowestBasePalindrome.isPalindromic(new ArrayList<Integer>(Arrays.asList(1, 2, 1, 1)))); + } + + @Test + public void testIsPalindromicInBasePositive() { + assertTrue(LowestBasePalindrome.isPalindromicInBase(101, 10)); + assertTrue(LowestBasePalindrome.isPalindromicInBase(1, 190)); + assertTrue(LowestBasePalindrome.isPalindromicInBase(0, 11)); + assertTrue(LowestBasePalindrome.isPalindromicInBase(10101, 10)); + assertTrue(LowestBasePalindrome.isPalindromicInBase(23, 22)); + } + + @Test + public void testIsPalindromicInBaseNegative() { + assertFalse(LowestBasePalindrome.isPalindromicInBase(1010, 10)); + assertFalse(LowestBasePalindrome.isPalindromicInBase(123, 10)); + } + + @Test + public void testIsPalindromicInBaseThrowsExceptionForNegativeNumbers() { + assertThrows(IllegalArgumentException.class, () -> LowestBasePalindrome.isPalindromicInBase(-1, 5)); + } + + @Test + public void testIsPalindromicInBaseThrowsExceptionForWrongBases() { + assertThrows(IllegalArgumentException.class, () -> LowestBasePalindrome.isPalindromicInBase(10, 1)); + } + + @Test + public void testLowestBasePalindrome() { + HashMap<Integer, Integer> testCases = new HashMap<>(); + testCases.put(0, 2); + testCases.put(1, 2); + testCases.put(2, 3); + testCases.put(3, 2); + testCases.put(10, 3); + testCases.put(11, 10); + testCases.put(15, 2); + testCases.put(39, 12); + testCases.put(44, 10); + testCases.put(58, 28); + testCases.put(69, 22); + testCases.put(79, 78); + testCases.put(87, 28); + testCases.put(90, 14); + testCases.put(5591, 37); + testCases.put(5895, 130); + testCases.put(9950, 198); + testCases.put(9974, 4986); + + for (final var tc : testCases.entrySet()) { + assertEquals(LowestBasePalindrome.lowestBasePalindrome(tc.getKey()), tc.getValue()); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java b/Java/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java new file mode 100644 index 000000000000..a8e168ffa13a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MaximumSumOfDistinctSubarraysWithLengthKTest { + @Test + public void sampleTestCase1() { + assertEquals(15, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(3, 1, 5, 4, 2, 9, 9, 9)); + } + + @Test + public void sampleTestCase2() { + assertEquals(0, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(3, 4, 4, 4)); + } + + @Test + public void sampleTestCase3() { + assertEquals(12, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(3, 9, 9, 9, 1, 2, 3)); + } + + @Test + public void edgeCase1() { + assertEquals(0, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(0, 9, 9, 9)); + } + + @Test + public void edgeCase2() { + assertEquals(0, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(5, 9, 9, 9)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java b/Java/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java new file mode 100644 index 000000000000..3b657e441b1c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java @@ -0,0 +1,49 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.dynamicprogramming.NewManShanksPrime; +import org.junit.jupiter.api.Test; + +public class NewManShanksPrimeTest { + + @Test + void testOne() { + assertTrue(NewManShanksPrime.nthManShanksPrime(1, 1)); + } + + @Test + void testTwo() { + assertTrue(NewManShanksPrime.nthManShanksPrime(2, 3)); + } + + @Test + void testThree() { + assertTrue(NewManShanksPrime.nthManShanksPrime(3, 7)); + } + + @Test + void testFour() { + assertTrue(NewManShanksPrime.nthManShanksPrime(4, 17)); + } + + @Test + void testFive() { + assertTrue(NewManShanksPrime.nthManShanksPrime(5, 41)); + } + + @Test + void testSix() { + assertTrue(NewManShanksPrime.nthManShanksPrime(6, 99)); + } + + @Test + void testSeven() { + assertTrue(NewManShanksPrime.nthManShanksPrime(7, 239)); + } + + @Test + void testEight() { + assertTrue(NewManShanksPrime.nthManShanksPrime(8, 577)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/NextFitTest.java b/Java/src/test/java/com/thealgorithms/others/NextFitTest.java new file mode 100644 index 000000000000..75fb3ab7c261 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/NextFitTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +/** + * author Alexandros Lemonaris + */ +class NextFitCPUTest { + + int[] sizeOfBlocks; + int[] sizeOfProcesses; + ArrayList<Integer> memAllocation = new ArrayList<>(); + ArrayList<Integer> testMemAllocation; + MemoryManagementAlgorithms nextFit = new NextFit(); + + @Test + void testFitForUseOfOneBlock() { + // test1 - third process does not fit because of algorithms procedure + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 5, 15, 2}; + memAllocation = nextFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(1, 2, -255, 2)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForEqualProcecesses() { + // test2 + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 10, 10, 10}; + memAllocation = nextFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(1, 2, 3, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForNoEmptyBlockCell() { + // test3 for more processes than blocks - no empty space left to none of the blocks + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 12, 10, 7}; + memAllocation = nextFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(0, 1, 2, 2)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForSameInputDifferentQuery() { + // test4 for more processes than blocks - one element does not fit due to input series + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 7, 10, 12}; + memAllocation = nextFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(0, 1, 2, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForMoreBlocksNoFit() { + // test5 for more blocks than processes + sizeOfBlocks = new int[] {5, 4, -1, 3, 6}; + sizeOfProcesses = new int[] {10, 11}; + memAllocation = nextFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(-255, -255)); + assertEquals(testMemAllocation, memAllocation); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/PasswordGenTest.java b/Java/src/test/java/com/thealgorithms/others/PasswordGenTest.java new file mode 100644 index 000000000000..57de329c8f09 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/PasswordGenTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class PasswordGenTest { + + @Test + public void failGenerationWithSameMinMaxLengthTest() { + int length = 10; + assertThrows(IllegalArgumentException.class, () -> { PasswordGen.generatePassword(length, length); }); + } + + @Test + public void generateOneCharacterPassword() { + String tempPassword = PasswordGen.generatePassword(1, 2); + assertTrue(tempPassword.length() == 1); + } + + @Test + public void failGenerationWithMinLengthSmallerThanMaxLengthTest() { + int minLength = 10; + int maxLength = 5; + assertThrows(IllegalArgumentException.class, () -> { PasswordGen.generatePassword(minLength, maxLength); }); + } + + @Test + public void generatePasswordNonEmptyTest() { + String tempPassword = PasswordGen.generatePassword(8, 16); + assertTrue(tempPassword.length() != 0); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/SieveOfEratosthenesTest.java b/Java/src/test/java/com/thealgorithms/others/SieveOfEratosthenesTest.java new file mode 100644 index 000000000000..207c51465c99 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/SieveOfEratosthenesTest.java @@ -0,0 +1,46 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class SieveOfEratosthenesTest { + @Test + public void testfFindPrimesTill1() { + assertArrayEquals(new int[] {}, SieveOfEratosthenes.findPrimesTill(1)); + } + + @Test + public void testfFindPrimesTill2() { + assertArrayEquals(new int[] {2}, SieveOfEratosthenes.findPrimesTill(2)); + } + + @Test + public void testfFindPrimesTill4() { + var primesTill4 = new int[] {2, 3}; + assertArrayEquals(primesTill4, SieveOfEratosthenes.findPrimesTill(3)); + assertArrayEquals(primesTill4, SieveOfEratosthenes.findPrimesTill(4)); + } + + @Test + public void testfFindPrimesTill40() { + var primesTill40 = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}; + assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(37)); + assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(38)); + assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(39)); + assertArrayEquals(primesTill40, SieveOfEratosthenes.findPrimesTill(40)); + } + + @Test + public void testfFindPrimesTill240() { + var primesTill240 = new int[] {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239}; + assertArrayEquals(primesTill240, SieveOfEratosthenes.findPrimesTill(239)); + assertArrayEquals(primesTill240, SieveOfEratosthenes.findPrimesTill(240)); + } + + @Test + public void testFindPrimesTillThrowsExceptionForNonPositiveInput() { + assertThrows(IllegalArgumentException.class, () -> SieveOfEratosthenes.findPrimesTill(0)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java b/Java/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java new file mode 100644 index 000000000000..986e72ea45b5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java @@ -0,0 +1,26 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class TestPrintMatrixInSpiralOrder { + @Test + public void testOne() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + var printClass = new PrintAMatrixInSpiralOrder(); + List<Integer> res = printClass.print(matrix, matrix.length, matrix[0].length); + List<Integer> list = List.of(3, 4, 5, 6, 7, 12, 18, 27, 34, 33, 32, 31, 30, 23, 14, 8, 9, 10, 11, 17, 26, 25, 24, 15, 16); + assertIterableEquals(res, list); + } + + @Test + public void testTwo() { + int[][] matrix = {{2, 2}}; + var printClass = new PrintAMatrixInSpiralOrder(); + List<Integer> res = printClass.print(matrix, matrix.length, matrix[0].length); + List<Integer> list = List.of(2, 2); + assertIterableEquals(res, list); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/TwoPointersTest.java b/Java/src/test/java/com/thealgorithms/others/TwoPointersTest.java new file mode 100644 index 000000000000..e8fe41b0bdaf --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/TwoPointersTest.java @@ -0,0 +1,44 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class TwoPointersTest { + + @Test + void twoPointersFirstTestCase() { + int[] arr = {2, 6, 9, 22, 121}; + int key = 28; + assertTrue(TwoPointers.isPairedSum(arr, key)); + } + + @Test + void twoPointersSecondTestCase() { + int[] arr = {-1, -12, 12, 0, 8}; + int key = 0; + assertTrue(TwoPointers.isPairedSum(arr, key)); + } + + @Test + void twoPointersThirdTestCase() { + int[] arr = {12, 35, 12, 152, 0}; + int key = 13; + assertFalse(TwoPointers.isPairedSum(arr, key)); + } + + @Test + void twoPointersFourthTestCase() { + int[] arr = {-2, 5, -1, 52, 31}; + int key = -3; + assertTrue(TwoPointers.isPairedSum(arr, key)); + } + + @Test + void twoPointersFiftiethTestCase() { + int[] arr = {25, 1, 0, 61, 21}; + int key = 12; + assertFalse(TwoPointers.isPairedSum(arr, key)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java b/Java/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java new file mode 100644 index 000000000000..eb69f6056132 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java @@ -0,0 +1,79 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +/** + * author Alexandros Lemonaris + */ +class WorstFitCPUTest { + + int[] sizeOfBlocks; + int[] sizeOfProcesses; + ArrayList<Integer> memAllocation = new ArrayList<>(); + ArrayList<Integer> testMemAllocation; + MemoryManagementAlgorithms worstFit = new WorstFitCPU(); + + @Test + void testFitForUseOfOneBlock() { + // test1 + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 5, 15, 2}; + memAllocation = worstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(2, 1, -255, 3)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForEqualProcecesses() { + // test2 + sizeOfBlocks = new int[] {5, 12, 17, 10}; + sizeOfProcesses = new int[] {10, 10, 10, 10}; + memAllocation = worstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(2, 1, 3, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForNoEmptyBlockCell() { + // test3 - could suits best, bad use of memory allocation due to worstFit algorithm + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 12, 10, 7}; + memAllocation = worstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(2, 1, 2, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForSameInputDifferentQuery() { + // test4 same example different series - same results + sizeOfBlocks = new int[] {5, 12, 17}; + sizeOfProcesses = new int[] {5, 7, 10, 12}; + memAllocation = worstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(2, 1, 2, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitForMoreBlocksNoFit() { + // test5 for more blocks than processes + sizeOfBlocks = new int[] {5, 4, -1, 3, 6}; + sizeOfProcesses = new int[] {10, 11}; + memAllocation = worstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(-255, -255)); + assertEquals(testMemAllocation, memAllocation); + } + + @Test + void testFitBadCase() { + // test6 for only two process fit + sizeOfBlocks = new int[] {7, 17, 7, 5, 6}; + sizeOfProcesses = new int[] {8, 10, 10, 8, 8, 8}; + memAllocation = worstFit.fitProcess(sizeOfBlocks, sizeOfProcesses); + testMemAllocation = new ArrayList<>(Arrays.asList(1, -255, -255, 1, -255, -255)); + assertEquals(testMemAllocation, memAllocation); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java b/Java/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java new file mode 100644 index 000000000000..669f928cd247 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/cn/HammingDistanceTest.java @@ -0,0 +1,82 @@ +package com.thealgorithms.others.cn; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; + +public class HammingDistanceTest { + @Test + public void checkForDifferentBits() { + int answer = HammingDistance.compute("000", "011"); + Assertions.assertThat(answer).isEqualTo(2); + } + + /* + + 1 0 1 0 1 + 1 1 1 1 0 + ---------- + 0 1 0 1 1 + + + */ + @Test + public void checkForDifferentBitsLength() { + int answer = HammingDistance.compute("10101", "11110"); + Assertions.assertThat(answer).isEqualTo(3); + } + + @Test + public void checkForSameBits() { + String someBits = "111"; + int answer = HammingDistance.compute(someBits, someBits); + Assertions.assertThat(answer).isEqualTo(0); + } + + @Test + public void checkForLongDataBits() { + int answer = HammingDistance.compute("10010101101010000100110100", "00110100001011001100110101"); + Assertions.assertThat(answer).isEqualTo(7); + } + + @Test + public void mismatchDataBits() { + Exception ex = org.junit.jupiter.api.Assertions.assertThrows(IllegalArgumentException.class, () -> { HammingDistance.compute("100010", "00011"); }); + + Assertions.assertThat(ex.getMessage()).contains("must have the same length"); + } + + @Test + public void mismatchDataBits2() { + Exception ex = org.junit.jupiter.api.Assertions.assertThrows(IllegalArgumentException.class, () -> { HammingDistance.compute("1", "11"); }); + + Assertions.assertThat(ex.getMessage()).contains("must have the same length"); + } + + @Test + public void checkForLongDataBitsSame() { + String someBits = "10010101101010000100110100"; + int answer = HammingDistance.compute(someBits, someBits); + Assertions.assertThat(answer).isEqualTo(0); + } + + @Test + public void checkForEmptyInput() { + String someBits = ""; + int answer = HammingDistance.compute(someBits, someBits); + Assertions.assertThat(answer).isEqualTo(0); + } + + @Test + public void checkForInputOfLength1() { + String someBits = "0"; + int answer = HammingDistance.compute(someBits, someBits); + Assertions.assertThat(answer).isEqualTo(0); + } + + @Test + public void computeThrowsExceptionWhenInputsAreNotBitStrs() { + Exception ex = org.junit.jupiter.api.Assertions.assertThrows(IllegalArgumentException.class, () -> { HammingDistance.compute("1A", "11"); }); + + Assertions.assertThat(ex.getMessage()).contains("must be a binary string"); + } +} diff --git a/Java/src/test/java/com/thealgorithms/others/countSetBitsTest.java b/Java/src/test/java/com/thealgorithms/others/countSetBitsTest.java new file mode 100644 index 000000000000..1429aac8daff --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/others/countSetBitsTest.java @@ -0,0 +1,17 @@ +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class countSetBitsTest { + + @Test + void testSetBits() { + countSetBits csb = new countSetBits(); + assertEquals(1L, csb.countsetBits(16)); + assertEquals(4, csb.countsetBits(15)); + assertEquals(5, csb.countsetBits(10000)); + assertEquals(5, csb.countsetBits(31)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java b/Java/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java new file mode 100644 index 000000000000..87b3d12c8dcf --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java @@ -0,0 +1,46 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class FCFSSchedulingTest { + + @Test + public void testingProcesses() { + List<ProcessDetails> processes = addProcessesForFCFS(); + final FCFSScheduling fcfsScheduling = new FCFSScheduling(processes); // for sending to FCFS + + fcfsScheduling.scheduleProcesses(); + + assertEquals(3, processes.size()); + + assertEquals("P1", processes.get(0).getProcessId()); + assertEquals(0, processes.get(0).getWaitingTime()); + assertEquals(10, processes.get(0).getTurnAroundTimeTime()); + + assertEquals("P2", processes.get(1).getProcessId()); + assertEquals(10, processes.get(1).getWaitingTime()); + assertEquals(15, processes.get(1).getTurnAroundTimeTime()); + + assertEquals("P3", processes.get(2).getProcessId()); + assertEquals(15, processes.get(2).getWaitingTime()); + assertEquals(23, processes.get(2).getTurnAroundTimeTime()); + } + + private List<ProcessDetails> addProcessesForFCFS() { + final ProcessDetails process1 = new ProcessDetails("P1", 0, 10); + final ProcessDetails process2 = new ProcessDetails("P2", 1, 5); + final ProcessDetails process3 = new ProcessDetails("P3", 2, 8); + + final List<ProcessDetails> processDetails = new ArrayList<>(); + processDetails.add(process1); + processDetails.add(process2); + processDetails.add(process3); + + return processDetails; + } +} diff --git a/Java/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java b/Java/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java new file mode 100644 index 000000000000..61e2a2ac2690 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.scheduling; + +/** + * Test Cases of Preemptive Priority Scheduling Algorithm + * @author [Bama Charan Chhandogi](https://www.github.com/BamaCharanChhandogi) + */ + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +class PreemptivePrioritySchedulingTest { + + @Test + void testPreemptivePriorityScheduling() { + // Arrange + List<Process> processes = new ArrayList<>(); + processes.add(new Process("P1", 0, 5, 10)); + processes.add(new Process("P2", 1, 4, 20)); + processes.add(new Process("P3", 2, 2, 30)); + processes.add(new Process("P4", 4, 1, 40)); + + List<String> expectedGanttChart = Arrays.asList("P1", "P2", "P3", "P3", "P4", "P2", "P2", "P2", "P1", "P1", "P1", "P1"); + + // Act + List<String> actualGanttChart = PreemptivePriorityScheduling.preemptivePriorityScheduling(processes); + + // Assert + assertEquals(expectedGanttChart, actualGanttChart); + } +} diff --git a/Java/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java b/Java/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java new file mode 100644 index 000000000000..3da526601f5f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java @@ -0,0 +1,63 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +class RRSchedulingTest { + @Test + public void testingProcesses() { + List<ProcessDetails> processes = addProcessesForRR(); + final RRScheduling rrScheduling = new RRScheduling(processes, 4); // for sending to RR with quantum value 4 + + rrScheduling.scheduleProcesses(); + + assertEquals(6, processes.size()); + + assertEquals("P1", processes.get(0).getProcessId()); + assertEquals(12, processes.get(0).getWaitingTime()); + assertEquals(17, processes.get(0).getTurnAroundTimeTime()); + + assertEquals("P2", processes.get(1).getProcessId()); + assertEquals(16, processes.get(1).getWaitingTime()); + assertEquals(22, processes.get(1).getTurnAroundTimeTime()); + + assertEquals("P3", processes.get(2).getProcessId()); + assertEquals(6, processes.get(2).getWaitingTime()); + assertEquals(9, processes.get(2).getTurnAroundTimeTime()); + + assertEquals("P4", processes.get(3).getProcessId()); + assertEquals(8, processes.get(3).getWaitingTime()); + assertEquals(9, processes.get(3).getTurnAroundTimeTime()); + + assertEquals("P5", processes.get(4).getProcessId()); + assertEquals(15, processes.get(4).getWaitingTime()); + assertEquals(20, processes.get(4).getTurnAroundTimeTime()); + + assertEquals("P6", processes.get(5).getProcessId()); + assertEquals(11, processes.get(5).getWaitingTime()); + assertEquals(15, processes.get(5).getTurnAroundTimeTime()); + } + + private List<ProcessDetails> addProcessesForRR() { + final ProcessDetails process1 = new ProcessDetails("P1", 0, 5); + final ProcessDetails process2 = new ProcessDetails("P2", 1, 6); + final ProcessDetails process3 = new ProcessDetails("P3", 2, 3); + final ProcessDetails process4 = new ProcessDetails("P4", 3, 1); + final ProcessDetails process5 = new ProcessDetails("P5", 4, 5); + final ProcessDetails process6 = new ProcessDetails("P6", 6, 4); + + final List<ProcessDetails> processDetails = new ArrayList<>(); + processDetails.add(process1); + processDetails.add(process2); + processDetails.add(process3); + processDetails.add(process4); + processDetails.add(process5); + processDetails.add(process6); + + return processDetails; + } +} diff --git a/Java/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java b/Java/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java new file mode 100644 index 000000000000..aab5c64c847f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java @@ -0,0 +1,110 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.ArrayList; +import org.junit.jupiter.api.Test; + +class SJFSchedulingTest { + private ArrayList<ProcessDetails> process; + void initialisation0() { + + process = new ArrayList<>(); + process.add(new ProcessDetails("1", 0, 6)); + process.add(new ProcessDetails("2", 1, 2)); + } + void initialisation1() { + + process = new ArrayList<>(); + process.add(new ProcessDetails("1", 0, 6)); + process.add(new ProcessDetails("2", 1, 2)); + process.add(new ProcessDetails("3", 4, 3)); + process.add(new ProcessDetails("4", 3, 1)); + process.add(new ProcessDetails("5", 6, 4)); + process.add(new ProcessDetails("6", 5, 5)); + } + + void initialisation2() { + + process = new ArrayList<>(); + process.add(new ProcessDetails("1", 0, 3)); + process.add(new ProcessDetails("2", 1, 2)); + process.add(new ProcessDetails("3", 2, 1)); + } + void initialisation3() { + process = new ArrayList<>(); + process.add(new ProcessDetails("1", 0, 3)); + process.add(new ProcessDetails("2", 5, 2)); + process.add(new ProcessDetails("3", 9, 1)); + } + @Test + void constructor() { + initialisation0(); + SJFScheduling a = new SJFScheduling(process); + assertEquals(6, a.processes.get(0).getBurstTime()); + assertEquals(2, a.processes.get(1).getBurstTime()); + } + + @Test + void sort() { + initialisation1(); + SJFScheduling a = new SJFScheduling(process); + a.sortByArrivalTime(); + assertEquals("1", a.processes.get(0).getProcessId()); + assertEquals("2", a.processes.get(1).getProcessId()); + assertEquals("3", a.processes.get(3).getProcessId()); + assertEquals("4", a.processes.get(2).getProcessId()); + assertEquals("5", a.processes.get(5).getProcessId()); + assertEquals("6", a.processes.get(4).getProcessId()); + } + + @Test + void scheduling() { + initialisation1(); + SJFScheduling a = new SJFScheduling(process); + a.scheduleProcesses(); + assertEquals("1", a.schedule.get(0)); + assertEquals("4", a.schedule.get(1)); + assertEquals("2", a.schedule.get(2)); + assertEquals("3", a.schedule.get(3)); + assertEquals("5", a.schedule.get(4)); + assertEquals("6", a.schedule.get(5)); + } + + @Test + void schedulingOfTwoProcesses() { + initialisation0(); + SJFScheduling a = new SJFScheduling(process); + a.scheduleProcesses(); + assertEquals("1", a.schedule.get(0)); + assertEquals("2", a.schedule.get(1)); + } + + @Test + void schedulingOfAShortestJobArrivingLast() { + initialisation2(); + SJFScheduling a = new SJFScheduling(process); + a.scheduleProcesses(); + assertEquals("1", a.schedule.get(0)); + assertEquals("3", a.schedule.get(1)); + assertEquals("2", a.schedule.get(2)); + } + @Test + void schedulingWithProcessesNotComingBackToBack() { + initialisation3(); + SJFScheduling a = new SJFScheduling(process); + a.scheduleProcesses(); + assertEquals("1", a.schedule.get(0)); + assertEquals("2", a.schedule.get(1)); + assertEquals("3", a.schedule.get(2)); + } + @Test + void schedulingOfNothing() { + process = new ArrayList<>(); + SJFScheduling a = new SJFScheduling(process); + a.scheduleProcesses(); + assertTrue(a.schedule.isEmpty()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java b/Java/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java new file mode 100644 index 000000000000..9cec31130164 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java @@ -0,0 +1,61 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.thealgorithms.devutils.entities.ProcessDetails; +import java.util.ArrayList; +import org.junit.jupiter.api.Test; + +class SRTFSchedulingTest { + ArrayList<ProcessDetails> processes; + + public void initialization() { + processes = new ArrayList<>(); + processes.add(new ProcessDetails("4", 0, 3)); + processes.add(new ProcessDetails("3", 1, 8)); + processes.add(new ProcessDetails("1", 2, 6)); + processes.add(new ProcessDetails("5", 4, 4)); + processes.add(new ProcessDetails("2", 5, 2)); + } + + @Test + public void constructor() { + initialization(); + SRTFScheduling s = new SRTFScheduling(processes); + assertEquals(3, s.processes.get(0).getBurstTime()); + assertEquals(8, s.processes.get(1).getBurstTime()); + assertEquals(6, s.processes.get(2).getBurstTime()); + assertEquals(4, s.processes.get(3).getBurstTime()); + assertEquals(2, s.processes.get(4).getBurstTime()); + } + + @Test + void evaluateScheduling() { + initialization(); + SRTFScheduling s = new SRTFScheduling(processes); + s.evaluateScheduling(); + assertEquals("4", s.ready.get(0)); + assertEquals("4", s.ready.get(1)); + assertEquals("4", s.ready.get(2)); + assertEquals("1", s.ready.get(3)); + assertEquals("5", s.ready.get(4)); + assertEquals("2", s.ready.get(5)); + assertEquals("2", s.ready.get(6)); + assertEquals("5", s.ready.get(7)); + assertEquals("5", s.ready.get(8)); + assertEquals("5", s.ready.get(9)); + assertEquals("1", s.ready.get(10)); + assertEquals("1", s.ready.get(11)); + assertEquals("1", s.ready.get(12)); + assertEquals("1", s.ready.get(13)); + assertEquals("1", s.ready.get(14)); + assertEquals("3", s.ready.get(15)); + assertEquals("3", s.ready.get(16)); + assertEquals("3", s.ready.get(17)); + assertEquals("3", s.ready.get(18)); + assertEquals("3", s.ready.get(19)); + assertEquals("3", s.ready.get(20)); + assertEquals("3", s.ready.get(21)); + assertEquals("3", s.ready.get(22)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java b/Java/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java new file mode 100644 index 000000000000..18f0afc6a0a6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java @@ -0,0 +1,157 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +public class BinarySearch2dArrayTest { + + @Test + // valid test case + public void binarySearch2dArrayTestMiddle() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 6; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(1, ans[0]); + assertEquals(1, ans[1]); + } + + @Test + // valid test case + public void binarySearch2dArrayTestMiddleSide() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 8; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(1, ans[0]); + assertEquals(3, ans[1]); + } + + @Test + // valid test case + public void binarySearch2dArrayTestUpper() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 2; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(0, ans[0]); + assertEquals(1, ans[1]); + } + + @Test + // valid test case + public void binarySearch2dArrayTestUpperSide() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 1; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(0, ans[0]); + assertEquals(0, ans[1]); + } + + @Test + // valid test case + public void binarySearch2dArrayTestLower() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 10; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(2, ans[0]); + assertEquals(1, ans[1]); + } + + @Test + // valid test case + public void binarySearch2dArrayTestLowerSide() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 11; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(2, ans[0]); + assertEquals(2, ans[1]); + } + + @Test + // valid test case + public void binarySearch2dArrayTestNotFound() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 101; + + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(-1, ans[0]); + assertEquals(-1, ans[1]); + } + + /** + * Test if the method works with input arrays consisting only of one row. + */ + @Test + public void binarySearch2dArrayTestOneRow() { + int[][] arr = {{1, 2, 3, 4}}; + int target = 2; + + // Assert that the requirement, that the array only has one row, is fulfilled. + assertEquals(arr.length, 1); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(0, ans[0]); + assertEquals(1, ans[1]); + } + + /** + * Test if the method works with the target in the middle of the input. + */ + @Test + public void binarySearch2dArrayTestTargetInMiddle() { + int[][] arr = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}; + int target = 8; + // Assert that the requirement, that the target is in the middle row and middle column, is + // fulfilled. + assertEquals(arr[arr.length / 2][arr[0].length / 2], target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(1, ans[0]); + assertEquals(2, ans[1]); + } + + /** + * Test if the method works with the target in the middle column, + * in the row above the middle row. + */ + @Test + public void binarySearch2dArrayTestTargetAboveMiddleRowInMiddleColumn() { + int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; + int target = 3; + + // Assert that the requirement, that he target is in the middle column, + // in an array with an even number of columns, and on the row "above" the middle row. + assertEquals(arr[0].length % 2, 0); + assertEquals(arr[arr.length / 2 - 1][arr[0].length / 2], target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); + System.out.println(Arrays.toString(ans)); + assertEquals(0, ans[0]); + assertEquals(2, ans[1]); + } + + /** + * Test if the method works with an empty array. + */ + @Test + public void binarySearch2dArrayTestEmptyArray() { + int[][] arr = {}; + int target = 5; + + // Assert that an empty array is not valid input for the method. + assertThrows(ArrayIndexOutOfBoundsException.class, () -> BinarySearch2dArray.binarySearch(arr, target)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java b/Java/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java new file mode 100644 index 000000000000..2a32a4ddb46c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java @@ -0,0 +1,104 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.datastructures.Node; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class BreadthFirstSearchTest { + private Node<String> root; + private BreadthFirstSearch<String> bfs; + + // Tree structure: + // + // A + // / | \ + // B C D + // / \ + // E F + + @BeforeEach + public void setUp() { + // nodes declaration + root = new Node<>("A"); + + var nodeB = new Node<>("B"); + var nodeC = new Node<>("C"); + var nodeD = new Node<>("D"); + + var nodeE = new Node<>("E"); + var nodeF = new Node<>("F"); + + // tree initialization + root.addChild(nodeB); + root.addChild(nodeC); + root.addChild(nodeD); + + nodeB.addChild(nodeE); + nodeB.addChild(nodeF); + + // create an instance to monitor the visited nodes + bfs = new BreadthFirstSearch<>(); + } + + @Test + public void testSearchRoot() { + String expectedValue = "A"; + List<String> expectedPath = List.of("A"); + + // check value + Optional<Node<String>> value = bfs.search(root, expectedValue); + assertEquals(expectedValue, value.orElse(new Node<>("")).getValue()); + + // check path + assertArrayEquals(expectedPath.toArray(), bfs.getVisited().toArray()); + } + + @Test + public void testSearchF() { + String expectedValue = "F"; + List<String> expectedPath = List.of("A", "B", "C", "D", "E", "F"); + + // check value + Optional<Node<String>> value = Optional.of(bfs.search(root, expectedValue).orElse(new Node<>(null))); + assertEquals(expectedValue, value.get().getValue()); + + // check path + assertArrayEquals(expectedPath.toArray(), bfs.getVisited().toArray()); + } + + @Test + void testSearchNull() { + List<String> expectedPath = List.of("A", "B", "C", "D", "E", "F"); + Optional<Node<String>> node = bfs.search(root, null); + + // check value + assertTrue(node.isEmpty()); + + // check path + assertArrayEquals(expectedPath.toArray(), bfs.getVisited().toArray()); + } + + @Test + void testNullRoot() { + var value = bfs.search(null, "B"); + assertTrue(value.isEmpty()); + } + + @Test + void testSearchValueThatNotExists() { + List<String> expectedPath = List.of("A", "B", "C", "D", "E", "F"); + var value = bfs.search(root, "Z"); + + // check that the value is empty because it's not exists in the tree + assertTrue(value.isEmpty()); + + // check path is the whole list + assertArrayEquals(expectedPath.toArray(), bfs.getVisited().toArray()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java b/Java/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java new file mode 100644 index 000000000000..af21b570fd7c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java @@ -0,0 +1,93 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.thealgorithms.datastructures.Node; +import java.util.List; +import java.util.Optional; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class DepthFirstSearchTest { + + private Node<Integer> root; + private DepthFirstSearch<Integer> dfs; + + // + // Tree structure: + // 1 + // / | \ + // 2 3 4 + // / \ + // 5 6 + + @BeforeEach + public void setUp() { + // nodes declaration + root = new Node<>(1); + + var nodeB = new Node<>(2); + var nodeC = new Node<>(3); + var nodeD = new Node<>(4); + + var nodeE = new Node<>(5); + var nodeF = new Node<>(6); + + // tree initialization + root.addChild(nodeB); + root.addChild(nodeC); + root.addChild(nodeD); + + nodeB.addChild(nodeE); + nodeB.addChild(nodeF); + + // create an instance to monitor the visited nodes + dfs = new DepthFirstSearch<>(); + } + + @Test + public void testSearchRoot() { + Integer expectedValue = 1; + List<Integer> expectedPath = List.of(1); + + // check value + Optional<Node<Integer>> value = dfs.recursiveSearch(root, expectedValue); + assertEquals(expectedValue, value.orElse(new Node<>(null)).getValue()); + + // check path + assertArrayEquals(expectedPath.toArray(), dfs.getVisited().toArray()); + } + + @Test + public void testSearch4() { + Integer expectedValue = 4; + List<Integer> expectedPath = List.of(1, 2, 5, 6, 3, 4); + + // check value + Optional<Node<Integer>> value = dfs.recursiveSearch(root, expectedValue); + assertEquals(expectedValue, value.orElse(new Node<>(null)).getValue()); + + // check path + assertArrayEquals(expectedPath.toArray(), dfs.getVisited().toArray()); + } + + @Test + void testNullRoot() { + var value = dfs.recursiveSearch(null, 4); + assertTrue(value.isEmpty()); + } + + @Test + void testSearchValueThatNotExists() { + List<Integer> expectedPath = List.of(1, 2, 5, 6, 3, 4); + var value = dfs.recursiveSearch(root, 10); + + // check that the value is empty because it's not exists in the tree + assertTrue(value.isEmpty()); + + // check path is the whole list + assertArrayEquals(expectedPath.toArray(), dfs.getVisited().toArray()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java b/Java/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java new file mode 100644 index 000000000000..7d52e9fb4eca --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java @@ -0,0 +1,16 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class HowManyTimesRotatedTest { + + @Test + public void testHowManyTimesRotated() { + int[] arr1 = {5, 1, 2, 3, 4}; + assertEquals(1, HowManyTimesRotated.rotated(arr1)); + int[] arr2 = {15, 17, 2, 3, 5}; + assertEquals(2, HowManyTimesRotated.rotated(arr2)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/KMPSearchTest.java b/Java/src/test/java/com/thealgorithms/searches/KMPSearchTest.java new file mode 100644 index 000000000000..cb804ac6a6a3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/KMPSearchTest.java @@ -0,0 +1,63 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +class KMPSearchTest { + + @Test + // valid test case + public void kmpSearchTestLast() { + String txt = "ABABDABACDABABCABAB"; + String pat = "ABABCABAB"; + KMPSearch kmpSearch = new KMPSearch(); + int value = kmpSearch.kmpSearch(pat, txt); + System.out.println(value); + assertEquals(value, 10); + } + + @Test + // valid test case + public void kmpSearchTestFront() { + String txt = "AAAAABAAABA"; + String pat = "AAAA"; + KMPSearch kmpSearch = new KMPSearch(); + int value = kmpSearch.kmpSearch(pat, txt); + System.out.println(value); + assertEquals(value, 0); + } + + @Test + // valid test case + public void kmpSearchTestMiddle() { + String txt = "AAACAAAAAC"; + String pat = "AAAA"; + KMPSearch kmpSearch = new KMPSearch(); + int value = kmpSearch.kmpSearch(pat, txt); + System.out.println(value); + assertEquals(value, 4); + } + + @Test + // valid test case + public void kmpSearchTestNotFound() { + String txt = "AAABAAAA"; + String pat = "AAAA"; + KMPSearch kmpSearch = new KMPSearch(); + int value = kmpSearch.kmpSearch(pat, txt); + System.out.println(value); + assertEquals(value, 4); + } + + @Test + // not valid test case + public void kmpSearchTest4() { + String txt = "AABAAA"; + String pat = "AAAA"; + KMPSearch kmpSearch = new KMPSearch(); + int value = kmpSearch.kmpSearch(pat, txt); + System.out.println(value); + assertEquals(value, -1); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java b/Java/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java new file mode 100644 index 000000000000..03502eec00d1 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java @@ -0,0 +1,67 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class OrderAgnosticBinarySearchTest { + @Test + // valid Test Case + public void elementInMiddle() { + int[] arr = {10, 20, 30, 40, 50}; + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 30); + System.out.println(answer); + int expected = 2; + assertEquals(expected, answer); + } + + @Test + // valid Test Case + public void rightHalfDescOrder() { + int[] arr = {50, 40, 30, 20, 10}; + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 10); + System.out.println(answer); + int expected = 4; + assertEquals(expected, answer); + } + + @Test + // valid test case + public void leftHalfDescOrder() { + int[] arr = {50, 40, 30, 20, 10}; + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 50); + System.out.println(answer); + int expected = 0; + assertEquals(expected, answer); + } + + @Test + // valid test case + public void rightHalfAscOrder() { + int[] arr = {10, 20, 30, 40, 50}; + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 50); + System.out.println(answer); + int expected = 4; + assertEquals(expected, answer); + } + + @Test + // valid test case + public void leftHalfAscOrder() { + int[] arr = {10, 20, 30, 40, 50}; + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 10); + System.out.println(answer); + int expected = 0; + assertEquals(expected, answer); + } + + @Test + // valid test case + public void elementNotFound() { + int[] arr = {10, 20, 30, 40, 50}; + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 100); + System.out.println(answer); + int expected = -1; + assertEquals(expected, answer); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java b/Java/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java new file mode 100644 index 000000000000..6eab20f45467 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java @@ -0,0 +1,44 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author D Sunil (https://github.com/sunilnitdgp) + * @see PerfectBinarySearch + */ +public class PerfectBinarySearchTest { + + @Test + public void testIntegerBinarySearch() { + Integer[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + PerfectBinarySearch<Integer> binarySearch = new PerfectBinarySearch<>(); + + // Test cases for elements present in the array + assertEquals(0, binarySearch.find(array, 1)); // First element + assertEquals(4, binarySearch.find(array, 5)); // Middle element + assertEquals(9, binarySearch.find(array, 10)); // Last element + assertEquals(6, binarySearch.find(array, 7)); // Element in the middle + + // Test cases for elements not in the array + assertEquals(-1, binarySearch.find(array, 0)); // Element before the array + assertEquals(-1, binarySearch.find(array, 11)); // Element after the array + assertEquals(-1, binarySearch.find(array, 100)); // Element not in the array + } + + @Test + public void testStringBinarySearch() { + String[] array = {"apple", "banana", "cherry", "date", "fig"}; + PerfectBinarySearch<String> binarySearch = new PerfectBinarySearch<>(); + + // Test cases for elements not in the array + assertEquals(-1, binarySearch.find(array, "apricot")); // Element not in the array + assertEquals(-1, binarySearch.find(array, "bananaa")); // Element not in the array + + // Test cases for elements present in the array + assertEquals(0, binarySearch.find(array, "apple")); // First element + assertEquals(2, binarySearch.find(array, "cherry")); // Middle element + assertEquals(4, binarySearch.find(array, "fig")); // Last element + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/QuickSelectTest.java b/Java/src/test/java/com/thealgorithms/searches/QuickSelectTest.java new file mode 100644 index 000000000000..dd04c85b76ae --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/QuickSelectTest.java @@ -0,0 +1,231 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import org.junit.jupiter.api.Test; + +class QuickSelectTest { + + @Test + void quickSelectMinimumOfOneElement() { + List<Integer> elements = Collections.singletonList(42); + int minimum = QuickSelect.select(elements, 0); + assertEquals(42, minimum); + } + + @Test + void quickSelectMinimumOfTwoElements() { + List<Integer> elements1 = Arrays.asList(42, 90); + List<Integer> elements2 = Arrays.asList(90, 42); + + int minimum1 = QuickSelect.select(elements1, 0); + int minimum2 = QuickSelect.select(elements2, 0); + + assertEquals(42, minimum1); + assertEquals(42, minimum2); + } + + @Test + void quickSelectMinimumOfThreeElements() { + List<Integer> elements1 = Arrays.asList(1, 2, 3); + List<Integer> elements2 = Arrays.asList(2, 1, 3); + List<Integer> elements3 = Arrays.asList(2, 3, 1); + + int minimum1 = QuickSelect.select(elements1, 0); + int minimum2 = QuickSelect.select(elements2, 0); + int minimum3 = QuickSelect.select(elements3, 0); + + assertEquals(1, minimum1); + assertEquals(1, minimum2); + assertEquals(1, minimum3); + } + + @Test + void quickSelectMinimumOfManyElements() { + List<Integer> elements = generateRandomIntegers(NUM_RND_ELEMENTS); + int actual = QuickSelect.select(elements, 0); + int expected = elements.stream().min(Comparator.naturalOrder()).get(); + assertEquals(expected, actual); + } + + @Test + void quickSelectMaximumOfOneElement() { + List<Integer> elements = Collections.singletonList(42); + int maximum = QuickSelect.select(elements, 0); + assertEquals(42, maximum); + } + + @Test + void quickSelectMaximumOfTwoElements() { + List<Integer> elements1 = Arrays.asList(42, 90); + List<Integer> elements2 = Arrays.asList(90, 42); + + int maximum1 = QuickSelect.select(elements1, 1); + int maximum2 = QuickSelect.select(elements2, 1); + + assertEquals(90, maximum1); + assertEquals(90, maximum2); + } + + @Test + void quickSelectMaximumOfThreeElements() { + List<Integer> elements1 = Arrays.asList(1, 2, 3); + List<Integer> elements2 = Arrays.asList(2, 1, 3); + List<Integer> elements3 = Arrays.asList(2, 3, 1); + + int maximum1 = QuickSelect.select(elements1, 2); + int maximum2 = QuickSelect.select(elements2, 2); + int maximum3 = QuickSelect.select(elements3, 2); + + assertEquals(3, maximum1); + assertEquals(3, maximum2); + assertEquals(3, maximum3); + } + + @Test + void quickSelectMaximumOfManyElements() { + List<Integer> elements = generateRandomIntegers(NUM_RND_ELEMENTS); + int actual = QuickSelect.select(elements, NUM_RND_ELEMENTS - 1); + int expected = elements.stream().max(Comparator.naturalOrder()).get(); + assertEquals(expected, actual); + } + + @Test + void quickSelectMedianOfOneElement() { + List<Integer> elements = Collections.singletonList(42); + int median = QuickSelect.select(elements, 0); + assertEquals(42, median); + } + + @Test + void quickSelectMedianOfThreeElements() { + List<Integer> elements1 = Arrays.asList(1, 2, 3); + List<Integer> elements2 = Arrays.asList(2, 1, 3); + List<Integer> elements3 = Arrays.asList(2, 3, 1); + + int median1 = QuickSelect.select(elements1, 1); + int median2 = QuickSelect.select(elements2, 1); + int median3 = QuickSelect.select(elements3, 1); + + assertEquals(2, median1); + assertEquals(2, median2); + assertEquals(2, median3); + } + + @Test + void quickSelectMedianOfManyElements() { + int medianIndex = NUM_RND_ELEMENTS / 2; + List<Integer> elements = generateRandomIntegers(NUM_RND_ELEMENTS); + int actual = QuickSelect.select(elements, medianIndex); + + List<Integer> elementsSorted = getSortedCopyOfList(elements); + assertEquals(elementsSorted.get(medianIndex), actual); + } + + @Test + void quickSelect30thPercentileOf10Elements() { + List<Integer> elements = generateRandomIntegers(10); + int actual = QuickSelect.select(elements, 2); + + List<Integer> elementsSorted = getSortedCopyOfList(elements); + assertEquals(elementsSorted.get(2), actual); + } + + @Test + void quickSelect30thPercentileOfManyElements() { + int percentile30th = NUM_RND_ELEMENTS / 10 * 3; + List<Integer> elements = generateRandomIntegers(NUM_RND_ELEMENTS); + int actual = QuickSelect.select(elements, percentile30th); + + List<Integer> elementsSorted = getSortedCopyOfList(elements); + assertEquals(elementsSorted.get(percentile30th), actual); + } + + @Test + void quickSelect70thPercentileOf10Elements() { + List<Integer> elements = generateRandomIntegers(10); + int actual = QuickSelect.select(elements, 6); + + List<Integer> elementsSorted = getSortedCopyOfList(elements); + assertEquals(elementsSorted.get(6), actual); + } + + @Test + void quickSelect70thPercentileOfManyElements() { + int percentile70th = NUM_RND_ELEMENTS / 10 * 7; + List<Integer> elements = generateRandomIntegers(NUM_RND_ELEMENTS); + int actual = QuickSelect.select(elements, percentile70th); + + List<Integer> elementsSorted = getSortedCopyOfList(elements); + assertEquals(elementsSorted.get(percentile70th), actual); + } + + @Test + void quickSelectMedianOfThreeCharacters() { + List<Character> elements = Arrays.asList('X', 'Z', 'Y'); + char actual = QuickSelect.select(elements, 1); + assertEquals(actual, 'Y'); + } + + @Test + void quickSelectMedianOfManyCharacters() { + List<Character> elements = generateRandomCharacters(NUM_RND_ELEMENTS); + char actual = QuickSelect.select(elements, NUM_RND_ELEMENTS / 30); + + List<Character> elementsSorted = getSortedCopyOfList(elements); + assertEquals(elementsSorted.get(NUM_RND_ELEMENTS / 30), actual); + } + + @Test + void quickSelectNullList() { + NullPointerException exception = assertThrows(NullPointerException.class, () -> QuickSelect.select(null, 0)); + String expectedMsg = "The list of elements must not be null."; + assertEquals(expectedMsg, exception.getMessage()); + } + + @Test + void quickSelectEmptyList() { + List<String> objects = Collections.emptyList(); + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> QuickSelect.select(objects, 0)); + String expectedMsg = "The list of elements must not be empty."; + assertEquals(expectedMsg, exception.getMessage()); + } + + @Test + void quickSelectIndexOutOfLeftBound() { + IndexOutOfBoundsException exception = assertThrows(IndexOutOfBoundsException.class, () -> QuickSelect.select(Collections.singletonList(1), -1)); + String expectedMsg = "The index must not be negative."; + assertEquals(expectedMsg, exception.getMessage()); + } + + @Test + void quickSelectIndexOutOfRightBound() { + IndexOutOfBoundsException exception = assertThrows(IndexOutOfBoundsException.class, () -> QuickSelect.select(Collections.singletonList(1), 1)); + String expectedMsg = "The index must be less than the number of elements."; + assertEquals(expectedMsg, exception.getMessage()); + } + + private static final int NUM_RND_ELEMENTS = 99; + private static final Random RANDOM = new Random(42); + private static final int ASCII_A = 0x41; + private static final int ASCII_Z = 0x5A; + + private static List<Integer> generateRandomIntegers(int n) { + return RANDOM.ints(n).boxed().collect(Collectors.toList()); + } + + private static List<Character> generateRandomCharacters(int n) { + return RANDOM.ints(n, ASCII_A, ASCII_Z).mapToObj(i -> (char) i).collect(Collectors.toList()); + } + + private static <T extends Comparable<T>> List<T> getSortedCopyOfList(List<T> list) { + return list.stream().sorted().collect(Collectors.toList()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java b/Java/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java new file mode 100644 index 000000000000..40e1acce9c3a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java @@ -0,0 +1,17 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +class RabinKarpAlgorithmTest { + + @ParameterizedTest + @CsvSource({"This is an example for rabin karp algorithmn, algorithmn, 101", "AAABBDDG, AAA, 137", "AAABBCCBB, BBCC, 101", "AAABBCCBB, BBCC, 131", "AAAABBBBCCC, CCC, 41", "ABCBCBCAAB, AADB, 293", "Algorithm The Algorithm, Algorithm, 101"}) + void rabinKarpAlgorithmTestExample(String txt, String pat, int q) { + int indexFromOurAlgorithm = RabinKarpAlgorithm.search(pat, txt, q); + int indexFromLinearSearch = txt.indexOf(pat); + assertEquals(indexFromOurAlgorithm, indexFromLinearSearch); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java b/Java/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java new file mode 100644 index 000000000000..0a2794f9e8d7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java @@ -0,0 +1,41 @@ +// Created by Pronay Debnath +// Date:- 1/10/2023 +// Test file updated with JUnit tests +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; // Import the JUnit 5 Test annotation + +public class RecursiveBinarySearchTest { + + @Test + public void testBinarySearch() { + // Create an instance of GenericBinarySearch + RecursiveBinarySearch<Integer> searcher = new RecursiveBinarySearch<>(); + + // Test case 1: Element found in the array + Integer[] arr1 = {1, 2, 3, 4, 5}; + int target1 = 3; + int result1 = searcher.binsear(arr1, 0, arr1.length - 1, target1); + assertEquals(2, result1); + + // Test case 2: Element not found in the array + Integer[] arr2 = {1, 2, 3, 4, 5}; + int target2 = 6; + int result2 = searcher.binsear(arr2, 0, arr2.length - 1, target2); + assertEquals(-1, result2); + + // Test case 3: Element found at the beginning of the array + Integer[] arr3 = {10, 20, 30, 40, 50}; + int target3 = 10; + int result3 = searcher.binsear(arr3, 0, arr3.length - 1, target3); + assertEquals(0, result3); + + // Test case 4: Element found at the end of the array + Integer[] arr4 = {10, 20, 30, 40, 50}; + int target4 = 50; + int result4 = searcher.binsear(arr4, 0, arr4.length - 1, target4); + assertEquals(4, result4); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java b/Java/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java new file mode 100644 index 000000000000..39ac5bf037ea --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java @@ -0,0 +1,113 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class RowColumnWiseSorted2dArrayBinarySearchTest { + + @Test + public void rowColumnSorted2dArrayBinarySearchTestMiddle() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 35; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {1, 2}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestSide() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 48; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {2, 3}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestUpper() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 20; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {0, 1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestUpperSide() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 40; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {0, 3}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestLower() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 31; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {3, 1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestLowerSide() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 51; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {3, 3}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } + + @Test + public void rowColumnSorted2dArrayBinarySearchTestNotFound() { + Integer[][] arr = { + {10, 20, 30, 40}, + {15, 25, 35, 45}, + {18, 28, 38, 48}, + {21, 31, 41, 51}, + }; + Integer target = 101; + int[] ans = RowColumnWiseSorted2dArrayBinarySearch.search(arr, target); + int[] expected = {-1, -1}; + assertEquals(expected[0], ans[0]); + assertEquals(expected[1], ans[1]); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java b/Java/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java new file mode 100644 index 000000000000..014fb4bd24af --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java @@ -0,0 +1,27 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class TestSearchInARowAndColWiseSortedMatrix { + @Test + public void searchItem() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + + var test = new SearchInARowAndColWiseSortedMatrix(); + int[] res = test.search(matrix, 16); + int[] expectedResult = {2, 2}; + assertArrayEquals(expectedResult, res); + } + + @Test + public void notFound() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + + var test = new SearchInARowAndColWiseSortedMatrix(); + int[] res = test.search(matrix, 96); + int[] expectedResult = {-1, -1}; + assertArrayEquals(expectedResult, res); + } +} diff --git a/Java/src/test/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearchTest.java b/Java/src/test/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearchTest.java new file mode 100644 index 000000000000..04ed00ae85b9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearchTest.java @@ -0,0 +1,26 @@ +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class sortOrderAgnosticBinarySearchTest { + + @Test + public void testAscending() { + int[] arr = {1, 2, 3, 4, 5}; // for ascending order. + int target = 2; + int ans = sortOrderAgnosticBinarySearch.find(arr, target); + int excepted = 1; + assertEquals(excepted, ans); + } + + @Test + public void testDescending() { + int[] arr = {5, 4, 3, 2, 1}; // for descending order. + int target = 2; + int ans = sortOrderAgnosticBinarySearch.find(arr, target); + int excepted = 3; + assertEquals(excepted, ans); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/BeadSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/BeadSortTest.java new file mode 100644 index 000000000000..2ab60b205cd5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/BeadSortTest.java @@ -0,0 +1,42 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class BeadSortTest { + // BeadSort can't sort negative number, Character, String. It can sort positive number only + private BeadSort beadSort = new BeadSort(); + + @Test + public void beadSortEmptyArray() { + int[] inputArray = {}; + int[] outputArray = beadSort.sort(inputArray); + int[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void beadSortSingleIntegerArray() { + int[] inputArray = {4}; + int[] outputArray = beadSort.sort(inputArray); + int[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortNonDuplicateIntegerArray() { + int[] inputArray = {6, 1, 99, 27, 15, 23, 36}; + int[] outputArray = beadSort.sort(inputArray); + int[] expectedOutput = {1, 6, 15, 23, 27, 36, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortDuplicateIntegerArray() { + int[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23}; + int[] outputArray = beadSort.sort(inputArray); + int[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36}; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java new file mode 100644 index 000000000000..bdd0702942a2 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class BinaryInsertionSortTest { + + BinaryInsertionSort bis = new BinaryInsertionSort(); + + @Test + // valid test case + public void binaryInsertionSortTestNonDuplicate() { + int[] array = {1, 0, 2, 5, 3, 4, 9, 8, 10, 6, 7}; + int[] expResult = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + int[] actResult = bis.binaryInsertSort(array); + assertArrayEquals(expResult, actResult); + } + + @Test + public void binaryInsertionSortTestDuplicate() { + int[] array = {1, 1, 1, 5, 9, 8, 7, 2, 6}; + int[] expResult = {1, 1, 1, 2, 5, 6, 7, 8, 9}; + int[] actResult = bis.binaryInsertSort(array); + assertArrayEquals(expResult, actResult); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/BogoSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/BogoSortTest.java new file mode 100644 index 000000000000..3ebfb7a305b0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/BogoSortTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class BogoSortTest { + + private BogoSort bogoSort = new BogoSort(); + + @Test + public void bogoSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortSingleIntegerArray() { + Integer[] inputArray = {4}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortSingleStringArray() { + String[] inputArray = {"s"}; + String[] outputArray = bogoSort.sort(inputArray); + String[] expectedOutput = {"s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortNonDuplicateIntegerArray() { + Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortDuplicateIntegerArray() { + Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; + Integer[] outputArray = bogoSort.sort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortNonDuplicateStringArray() { + String[] inputArray = {"s", "b", "k", "a", "d", "c", "h"}; + String[] outputArray = bogoSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "c", "d", "h", "k", "s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bogoSortDuplicateStringArray() { + String[] inputArray = {"s", "b", "d", "a", "d", "c", "h", "b"}; + String[] outputArray = bogoSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"}; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java new file mode 100644 index 000000000000..8690a3f5435c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/BubbleSortTest.java @@ -0,0 +1,94 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Aitor Fidalgo (https://github.com/aitorfi) + * @see BubbleSort + */ +public class BubbleSortTest { + + private BubbleSort bubbleSort = new BubbleSort(); + + @Test + public void bubbleSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = bubbleSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortSingleIntegerElementArray() { + Integer[] inputArray = {4}; + Integer[] outputArray = bubbleSort.sort(inputArray); + Integer[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortSingleStringElementArray() { + String[] inputArray = {"s"}; + String[] outputArray = bubbleSort.sort(inputArray); + String[] expectedOutput = {"s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortIntegerArray() { + Integer[] inputArray = {4, 23, -6, 78, 1, 54, 23, -6, -231, 9, 12}; + Integer[] outputArray = bubbleSort.sort(inputArray); + Integer[] expectedOutput = { + -231, + -6, + -6, + 1, + 4, + 9, + 12, + 23, + 23, + 54, + 78, + }; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bubbleSortStringArray() { + String[] inputArray = { + "cbf", + "auk", + "ó", + "(b", + "a", + ")", + "au", + "á", + "cba", + "auk", + "(a", + "bhy", + "cba", + }; + String[] outputArray = bubbleSort.sort(inputArray); + String[] expectedOutput = { + "(a", + "(b", + ")", + "a", + "au", + "auk", + "auk", + "bhy", + "cba", + "cba", + "cbf", + "á", + "ó", + }; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/BucketSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/BucketSortTest.java new file mode 100644 index 000000000000..bd9d2e3d60cf --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/BucketSortTest.java @@ -0,0 +1,48 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class BucketSortTest { + + @Test + public void bucketSortSingleIntegerArray() { + int[] inputArray = {4}; + int[] outputArray = BucketSort.bucketSort(inputArray); + int[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bucketSortNonDuplicateIntegerArray() { + int[] inputArray = {6, 1, 99, 27, 15, 23, 36}; + int[] outputArray = BucketSort.bucketSort(inputArray); + int[] expectedOutput = {1, 6, 15, 23, 27, 36, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bucketSortDuplicateIntegerArray() { + int[] inputArray = {6, 1, 27, 15, 23, 27, 36, 23}; + int[] outputArray = BucketSort.bucketSort(inputArray); + int[] expectedOutput = {1, 6, 15, 23, 23, 27, 27, 36}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bucketSortNonDuplicateIntegerArrayWithNegativeNum() { + int[] inputArray = {6, -1, 99, 27, -15, 23, -36}; + int[] outputArray = BucketSort.bucketSort(inputArray); + int[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void bucketSortDuplicateIntegerArrayWithNegativeNum() { + int[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; + int[] outputArray = BucketSort.bucketSort(inputArray); + int[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/CircleSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/CircleSortTest.java new file mode 100644 index 000000000000..d113473272b7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/CircleSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +class CircleSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new CircleSort(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java new file mode 100644 index 000000000000..56628b78de02 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/CocktailShakerSortTest.java @@ -0,0 +1,68 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Tabbygray (https://github.com/Tabbygray) + * @see CocktailShakerSort + */ +public class CocktailShakerSortTest { + + private CocktailShakerSort cocktailShakerSort = new CocktailShakerSort(); + + @Test + public void cocktailShakerSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = cocktailShakerSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void cocktailShakerSortSingleStringElementArray() { + String[] inputArray = {"Test"}; + String[] outputArray = cocktailShakerSort.sort(inputArray); + String[] expectedOutput = {"Test"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void cocktailShakerSortIntegerArray() { + Integer[] inputArray = {2, 92, 1, 33, -33, 27, 5, 100, 78, 99, -100}; + Integer[] outputArray = cocktailShakerSort.sort(inputArray); + Integer[] expectedOutput = {-100, -33, 1, 2, 5, 27, 33, 78, 92, 99, 100}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void cocktailShakerSortStringArray() { + String[] inputArray = { + "g3x1", + "dN62", + "oMdr", + "KL2b", + "JddJ", + "mvE8", + "Ej7Q", + "n7n7", + "LGTg", + "2E1w", + }; + String[] outputArray = cocktailShakerSort.sort(inputArray); + String[] expectedOutput = { + "2E1w", + "Ej7Q", + "JddJ", + "KL2b", + "LGTg", + "dN62", + "g3x1", + "mvE8", + "n7n7", + "oMdr", + }; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/CombSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/CombSortTest.java new file mode 100644 index 000000000000..e33fc388c1c5 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/CombSortTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Tabbygray (https://github.com/Tabbygray) + * @see CombSort + */ + +public class CombSortTest { + + private CombSort combSort = new CombSort(); + + @Test + public void combSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = combSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void combSortSingleStringElement() { + String[] inputArray = {"Test"}; + String[] outputArray = combSort.sort(inputArray); + String[] expectedArray = {"Test"}; + assertArrayEquals(outputArray, expectedArray); + } + + @Test + public void combSortStringArray() { + String[] inputArray = {"4gp8", "aBJ2", "85cW", "Pmk9", "ewZO", "meuU", "RhNd", "5TKB", "eDd5", "zzyo"}; + String[] outputArray = combSort.sort(inputArray); + String[] expectedArray = {"4gp8", "5TKB", "85cW", "Pmk9", "RhNd", "aBJ2", "eDd5", "ewZO", "meuU", "zzyo"}; + assertArrayEquals(outputArray, expectedArray); + } + + @Test + public void combSortIntegerArray() { + Integer[] inputArray = {36, 98, -51, -23, 66, -58, 31, 25, -30, 40}; + Integer[] outputArray = combSort.sort(inputArray); + Integer[] expectedArray = {-58, -51, -30, -23, 25, 31, 36, 40, 66, 98}; + assertArrayEquals(outputArray, expectedArray); + } + + @Test + public void combSortDoubleArray() { + Double[] inputArray = {0.8335545399, 0.9346214114, 0.3096396752, 0.6433840668, 0.3973191975, 0.6118850724, 0.0553975453, 0.1961108601, 0.6172800885, 0.1065247772}; + Double[] outputArray = combSort.sort(inputArray); + Double[] expectedArray = { + 0.0553975453, + 0.1065247772, + 0.1961108601, + 0.3096396752, + 0.3973191975, + 0.6118850724, + 0.6172800885, + 0.6433840668, + 0.8335545399, + 0.9346214114, + }; + assertArrayEquals(outputArray, expectedArray); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java new file mode 100644 index 000000000000..112f38277776 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/DualPivotQuickSortTest.java @@ -0,0 +1,62 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Debasish Biswas (https://github.com/debasishbsws) + * @see DualPivotQuickSort + */ +class DualPivotQuickSortTest { + + private DualPivotQuickSort dualPivotquickSort = new DualPivotQuickSort(); + + @Test + void quickSortEmptyArrayShouldPass() { + Integer[] array = {}; + Integer[] sorted = dualPivotquickSort.sort(array); + Integer[] expected = {}; + assertArrayEquals(expected, sorted); + } + + @Test + void quickSortSingleValueArrayShouldPass() { + Integer[] array = {7}; + Integer[] sorted = dualPivotquickSort.sort(array); + Integer[] expected = {7}; + assertArrayEquals(expected, sorted); + } + + @Test + void quickSortWithIntegerArrayShouldPass() { + Integer[] array = {49, 4, 36, 9, 144, 1}; + Integer[] sorted = dualPivotquickSort.sort(array); + Integer[] expected = {1, 4, 9, 36, 49, 144}; + assertArrayEquals(expected, sorted); + } + + @Test + void quickSortForArrayWithNegativeValuesShouldPass() { + Integer[] array = {49, -36, -124, -49, 12, 9}; + Integer[] sorted = dualPivotquickSort.sort(array); + Integer[] expected = {-124, -49, -36, 9, 12, 49}; + assertArrayEquals(expected, sorted); + } + + @Test + void quickSortForArrayWithDuplicateValuesShouldPass() { + Integer[] array = {36, 1, 49, 1, 4, 9}; + Integer[] sorted = dualPivotquickSort.sort(array); + Integer[] expected = {1, 1, 4, 9, 36, 49}; + assertArrayEquals(expected, sorted); + } + + @Test + void quickSortWithStringArrayShouldPass() { + String[] array = {"cat", "ant", "eat", "boss", "dog", "apple"}; + String[] sorted = dualPivotquickSort.sort(array); + String[] expected = {"ant", "apple", "boss", "cat", "dog", "eat"}; + assertArrayEquals(expected, sorted); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java new file mode 100644 index 000000000000..c7581e7c8f7b --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java @@ -0,0 +1,112 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class DutchNationalFlagSortTest { + + @Test + /* + 1 will be used as intended middle. + Partitions on the result array: [ smaller than 1 , equal 1, greater than 1] + */ + void testOddDnfs() { + Integer[] integers = {1, 3, 1, 4, 0}; + Integer[] integersResult = {0, 1, 1, 4, 3}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(integers); + assertArrayEquals(integers, integersResult); + } + + @Test + /* + 3 will be used as intended middle. + Partitions on the result array: [ smaller than 3 , equal 3, greater than 3] + */ + void testEvenDnfs() { + Integer[] integers = {8, 1, 3, 1, 4, 0}; + Integer[] integersResult = {0, 1, 1, 3, 4, 8}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(integers); + assertArrayEquals(integers, integersResult); + } + + @Test + /* + "b" will be used as intended middle. + Partitions on the result array: [ smaller than b , equal b, greater than b] + */ + void testEvenStringsDnfs() { + String[] strings = {"a", "d", "b", "s", "e", "e"}; + String[] stringsResult = {"a", "b", "s", "e", "e", "d"}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(strings); + assertArrayEquals(strings, stringsResult); + } + + @Test + /* + "b" will be used as intended middle. + Partitions on the result array: [ smaller than b , equal b, greater than b] + */ + void testOddStringsDnfs() { + String[] strings = {"a", "d", "b", "s", "e"}; + String[] stringsResult = {"a", "b", "s", "e", "d"}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(strings); + assertArrayEquals(strings, stringsResult); + } + + @Test + /* + 0 will be used as intended middle. + Partitions on the result array: [ smaller than 0 , equal 0, greater than 0] + */ + void testOddMidGivenDnfs() { + Integer[] integers = {1, 3, 1, 4, 0}; + Integer[] integersResult = {0, 1, 4, 3, 1}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(integers, 0); + assertArrayEquals(integers, integersResult); + } + + @Test + /* + 4 will be used as intended middle. + Partitions on the result array: [ smaller than 4 , equal 4, greater than 4] + */ + void testEvenMidGivenDnfs() { + Integer[] integers = {8, 1, 3, 1, 4, 0}; + Integer[] integersResult = {0, 1, 3, 1, 4, 8}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(integers, 4); + assertArrayEquals(integers, integersResult); + } + + @Test + /* + "s" will be used as intended middle. + Partitions on the result array: [ smaller than s , equal s, greater than s] + */ + void testEvenStringsMidGivenDnfs() { + String[] strings = {"a", "d", "b", "s", "e", "e"}; + String[] stringsResult = {"a", "d", "b", "e", "e", "s"}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(strings, "s"); + assertArrayEquals(strings, stringsResult); + } + + @Test + /* + "e" will be used as intended middle. + Partitions on the result array: [ smaller than e , equal e, greater than e] + */ + void testOddStringsMidGivenDnfs() { + String[] strings = {"a", "d", "b", "s", "e"}; + String[] stringsResult = {"a", "d", "b", "e", "s"}; + DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); + dutchNationalFlagSort.sort(strings, "e"); + assertArrayEquals(strings, stringsResult); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java new file mode 100644 index 000000000000..6c4271fa9e19 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/ExchangeSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class ExchangeSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new ExchangeSort(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java new file mode 100644 index 000000000000..d86546472580 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/GnomeSortTest.java @@ -0,0 +1,82 @@ +package com.thealgorithms.sorts; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class GnomeSortTest { + + private GnomeSort gnomeSort = new GnomeSort(); + + @Test + @DisplayName("GnomeSort empty Array") + public void gnomeSortEmptyArray() { + Integer[] inputArray = {}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEmpty(); + } + + @Test + @DisplayName("GnomeSort single Integer Array") + public void singleIntegerArray() { + Integer[] inputArray = {4}; + Integer[] expectedOutput = {4}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("GnomeSort non duplicate Integer Array") + public void gnomeSortNonDuplicateIntegerArray() { + Integer[] inputArray = {6, 3, 87, 99, 27, 4}; + Integer[] expectedOutput = {3, 4, 6, 27, 87, 99}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("GnomeSort Integer Array with duplicates") + public void gnomeSortDuplicateIntegerArray() { + Integer[] inputArray = {6, 3, 87, 3, 99, 27, 4, 27}; + Integer[] expectedOutput = {3, 3, 4, 6, 27, 27, 87, 99}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("GnomeSort negative Integer Array with duplicates") + public void gnomeSortNegativeDuplicateIntegerArray() { + Integer[] inputArray = {6, 3, -87, 3, 99, -27, 4, -27}; + Integer[] expectedOutput = {-87, -27, -27, 3, 3, 4, 6, 99}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("GnomeSort single String Array") + public void singleStringArray() { + String[] inputArray = {"b"}; + String[] expectedOutput = {"b"}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("GnomeSort non duplicate String Array") + public void gnomeSortNonDuplicateStringArray() { + String[] inputArray = {"He", "A", "bc", "lo", "n", "bcp", "mhp", "d"}; + String[] expectedOutput = {"A", "He", "bc", "bcp", "d", "lo", "mhp", "n"}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("GnomeSort String Array with duplicates") + public void gnomeSortDuplicateStringArray() { + String[] inputArray = {"He", "A", "bc", "lo", "n", "bcp", "mhp", "bcp"}; + String[] expectedOutput = {"A", "He", "bc", "bcp", "bcp", "lo", "mhp", "n"}; + gnomeSort.sort(inputArray); + assertThat(inputArray).isEqualTo(expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/HeapSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/HeapSortTest.java new file mode 100644 index 000000000000..90b2ebd68bc6 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/HeapSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class HeapSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new HeapSort(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java new file mode 100644 index 000000000000..78744973355d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java @@ -0,0 +1,114 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.function.Function; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class InsertionSortTest { + private InsertionSort insertionSort; + + @BeforeEach + void setUp() { + insertionSort = new InsertionSort(); + } + + @Test + void insertionSortSortEmptyArrayShouldPass() { + testEmptyArray(insertionSort::sort); + testEmptyArray(insertionSort::sentinelSort); + } + + private void testEmptyArray(Function<Integer[], Integer[]> sortAlgorithm) { + Integer[] array = {}; + Integer[] sorted = sortAlgorithm.apply(array); + Integer[] expected = {}; + assertArrayEquals(expected, sorted); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void insertionSortClassicalSortSingleValueArrayShouldPass() { + testSingleValue(insertionSort::sort); + testSingleValue(insertionSort::sentinelSort); + } + + private void testSingleValue(Function<Integer[], Integer[]> sortAlgorithm) { + Integer[] array = {7}; + Integer[] sorted = sortAlgorithm.apply(array); + Integer[] expected = {7}; + assertArrayEquals(expected, sorted); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void insertionSortClassicalWithIntegerArrayShouldPass() { + testIntegerArray(insertionSort::sort); + testIntegerArray(insertionSort::sentinelSort); + } + + private void testIntegerArray(Function<Integer[], Integer[]> sortAlgorithm) { + Integer[] array = {49, 4, 36, 9, 144, 1}; + Integer[] sorted = sortAlgorithm.apply(array); + Integer[] expected = {1, 4, 9, 36, 49, 144}; + assertArrayEquals(expected, sorted); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void insertionSortClassicalForArrayWithNegativeValuesShouldPass() { + testWithNegativeValues(insertionSort::sort); + testWithNegativeValues(insertionSort::sentinelSort); + } + + private void testWithNegativeValues(Function<Integer[], Integer[]> sortAlgorithm) { + Integer[] array = {49, -36, -144, -49, 1, 9}; + Integer[] sorted = sortAlgorithm.apply(array); + Integer[] expected = {-144, -49, -36, 1, 9, 49}; + assertArrayEquals(expected, sorted); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void insertionSortClassicalForArrayWithDuplicateValuesShouldPass() { + testWithDuplicates(insertionSort::sort); + testWithDuplicates(insertionSort::sentinelSort); + } + + private void testWithDuplicates(Function<Integer[], Integer[]> sortAlgorithm) { + Integer[] array = {36, 1, 49, 1, 4, 9}; + Integer[] sorted = sortAlgorithm.apply(array); + Integer[] expected = {1, 1, 4, 9, 36, 49}; + assertArrayEquals(expected, sorted); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void insertionSortClassicalWithStringArrayShouldPass() { + testWithStringArray(insertionSort::sort); + testWithStringArray(insertionSort::sentinelSort); + } + + private void testWithStringArray(Function<String[], String[]> sortAlgorithm) { + String[] array = {"c", "a", "e", "b", "d"}; + String[] sorted = sortAlgorithm.apply(array); + String[] expected = {"a", "b", "c", "d", "e"}; + assertArrayEquals(expected, sorted); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void insertionSortClassicalWithRandomArrayPass() { + testWithRandomArray(insertionSort::sort); + testWithRandomArray(insertionSort::sentinelSort); + } + + private void testWithRandomArray(Function<Double[], Double[]> sortAlgorithm) { + int randomSize = SortUtilsRandomGenerator.generateInt(10_000); + Double[] array = SortUtilsRandomGenerator.generateArray(randomSize); + Double[] sorted = sortAlgorithm.apply(array); + assertTrue(SortUtils.isSorted(sorted)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java new file mode 100644 index 000000000000..a5c6905f7514 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java @@ -0,0 +1,63 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class IntrospectiveSortTest { + @Test + // valid test case + public void strandSortNonDuplicateTest() { + Integer[] expectedArray = {1, 2, 3, 4, 5}; + Integer[] actualList = new IntrospectiveSort().sort(expectedArray); + assertArrayEquals(expectedArray, actualList); + } + + @Test + // valid test case + public void strandSortDuplicateTest() { + Integer[] expectedArray = {2, 2, 2, 5, 7}; + Integer[] actualList = new IntrospectiveSort().sort(expectedArray); + assertArrayEquals(expectedArray, actualList); + } + + @Test + // valid test case + public void strandSortEmptyTest() { + Integer[] expectedArray = {}; + Integer[] actualList = new IntrospectiveSort().sort(expectedArray); + assertArrayEquals(expectedArray, actualList); + } + + @Test + // valid test case + public void strandSortNullTest() { + Integer[] expectedArray = null; + assertThrows(NullPointerException.class, () -> { new IntrospectiveSort().sort(expectedArray); }); + } + + @Test + // valid test case + public void strandSortNegativeTest() { + Integer[] expectedArray = {-1, -2, -3, -4, -5}; + Integer[] actualList = new IntrospectiveSort().sort(expectedArray); + assertArrayEquals(expectedArray, actualList); + } + + @Test + // valid test case + public void strandSortNegativeAndPositiveTest() { + Integer[] expectedArray = {-1, -2, -3, 4, 5}; + Integer[] actualList = new IntrospectiveSort().sort(expectedArray); + assertArrayEquals(expectedArray, actualList); + } + + @Test + // valid test case + public void allSameTest() { + Integer[] expectedArray = {1, 1, 1, 1, 1}; + Integer[] actualList = new IntrospectiveSort().sort(expectedArray); + assertArrayEquals(expectedArray, actualList); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java b/Java/src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java new file mode 100644 index 000000000000..0e7874584c3f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/MergeSortRecursiveTest.java @@ -0,0 +1,32 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class MergeSortRecursiveTest { + + // private MergeSortRecursive mergeSortRecursive = new MergeSortRecursive(); + + @Test + void testMergeSortRecursiveCase1() { + MergeSortRecursive mergeSortRecursive = new MergeSortRecursive(Arrays.asList(5, 12, 9, 3, 15, 88)); + + List<Integer> expected = Arrays.asList(3, 5, 9, 12, 15, 88); + List<Integer> sorted = mergeSortRecursive.mergeSort(); + + assertEquals(expected, sorted); + } + + @Test + void testMergeSortRecursiveCase2() { + MergeSortRecursive mergeSortRecursive = new MergeSortRecursive(Arrays.asList(-3, 5, 3, 4, 3, 7, 40, -20, 30, 0)); + + List<Integer> expected = Arrays.asList(-20, -3, 0, 3, 3, 4, 5, 7, 30, 40); + List<Integer> sorted = mergeSortRecursive.mergeSort(); + + assertEquals(expected, sorted); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/MergeSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/MergeSortTest.java new file mode 100644 index 000000000000..af06e360a038 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/MergeSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +public class MergeSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new MergeSort(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java new file mode 100644 index 000000000000..a7d0a58e229d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/OddEvenSortTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Tabbygray (https://github.com/Tabbygray) + * @see OddEvenSort + */ + +public class OddEvenSortTest { + @Test + public void oddEvenSortEmptyArray() { + int[] inputArray = {}; + OddEvenSort.oddEvenSort(inputArray); + int[] expectedOutput = {}; + assertArrayEquals(inputArray, expectedOutput); + } + + @Test + public void oddEvenSortNaturalNumberArray() { + int[] inputArray = {18, 91, 86, 60, 21, 44, 37, 78, 98, 67}; + OddEvenSort.oddEvenSort(inputArray); + int[] expectedOutput = {18, 21, 37, 44, 60, 67, 78, 86, 91, 98}; + assertArrayEquals(inputArray, expectedOutput); + } + + @Test + public void oddEvenSortIntegerArray() { + int[] inputArray = {57, 69, -45, 12, -85, 3, -76, 36, 67, -14}; + OddEvenSort.oddEvenSort(inputArray); + int[] expectedOutput = {-85, -76, -45, -14, 3, 12, 36, 57, 67, 69}; + assertArrayEquals(inputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java new file mode 100644 index 000000000000..8d26532a1acd --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/PancakeSortTest.java @@ -0,0 +1,80 @@ +package com.thealgorithms.sorts; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class PancakeSortTest { + + private PancakeSort pancakeSort = new PancakeSort(); + + @Test + @DisplayName("Empty Array pancakeSort") + public void pancakeSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEmpty(); + } + + @Test + @DisplayName("PancakeSort single Integer Array") + public void pancakeSort() { + Integer[] inputArray = {2}; + Integer[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(inputArray); + } + + @Test + @DisplayName("PancakeSort non duplicate Integer Array") + public void pancakeSortNonDuplicateIntegerArray() { + Integer[] inputArray = {2, 1, 77, 34, 14, 56, 8}; + Integer[] expectedOutput = {1, 2, 8, 14, 34, 56, 77}; + Integer[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("PancakeSort Integer Array with duplicates") + public void pancakeSortDuplicateIntegerArray() { + Integer[] inputArray = {2, 1, 77, 34, 14, 77, 56, 14, 8}; + Integer[] expectedOutput = {1, 2, 8, 14, 14, 34, 56, 77, 77}; + Integer[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("PancakeSort negative Integer Array with duplicates") + public void pancakeSortNegativeDuplicateIntegerArray() { + Integer[] inputArray = {2, 1, 77, -34, -14, 77, 56, -14, 8}; + Integer[] expectedOutput = {-34, -14, -14, 1, 2, 8, 56, 77, 77}; + Integer[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("PancakeSort single String Array") + public void pancakeSortSingleStringArray() { + String[] inputArray = {"W"}; + String[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(inputArray); + } + + @Test + @DisplayName("PancakeSort non duplicate String Array") + public void pancakeSortNonDuplicateStringArray() { + String[] inputArray = {"W", "A", "d", "be", "jk", "hb", "bgh"}; + String[] expectedOutput = {"A", "W", "be", "bgh", "d", "hb", "jk"}; + String[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(expectedOutput); + } + + @Test + @DisplayName("PancakeSort String Array with duplicates") + public void pancakeSortDuplicateStringArray() { + String[] inputArray = {"W", "A", "d", "be", "jk", "hb", "bgh", "bgh", "W"}; + String[] expectedOutput = {"A", "W", "W", "be", "bgh", "bgh", "d", "hb", "jk"}; + String[] outputArray = pancakeSort.sort(inputArray); + assertThat(outputArray).isEqualTo(expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/QuickSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/QuickSortTest.java new file mode 100644 index 000000000000..fca57626b75f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/QuickSortTest.java @@ -0,0 +1,12 @@ +package com.thealgorithms.sorts; + +/** + * @author Akshay Dubey (https://github.com/itsAkshayDubey) + * @see QuickSort + */ +class QuickSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new QuickSort(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java new file mode 100644 index 000000000000..83fbd1ece909 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java @@ -0,0 +1,35 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +class SelectionSortTest { + + @Test + // valid test case + void integerArrTest() { + Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; + SelectionSort selectionSort = new SelectionSort(); + + assertArrayEquals(new Integer[] {1, 4, 6, 9, 12, 23, 54, 78, 231}, selectionSort.sort(arr)); + } + + @Test + // valid test case + void stringArrTest() { + String[] arr = {"c", "a", "e", "b", "d"}; + SelectionSort selectionSort = new SelectionSort(); + + assertArrayEquals(new String[] {"a", "b", "c", "d", "e"}, selectionSort.sort(arr)); + } + + @Test + // invalid test case + void emptyArrTest() { + Integer[] arr = {}; + SelectionSort selectionSort = new SelectionSort(); + + assertArrayEquals(new Integer[] {}, selectionSort.sort(arr)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/ShellSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/ShellSortTest.java new file mode 100644 index 000000000000..73be91b397bd --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/ShellSortTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class ShellSortTest { + + private ShellSort shellSort = new ShellSort(); + + @Test + public void shellSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = shellSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void shellSortSingleIntegerArray() { + Integer[] inputArray = {4}; + Integer[] outputArray = shellSort.sort(inputArray); + Integer[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void shellSortSingleStringArray() { + String[] inputArray = {"s"}; + String[] outputArray = shellSort.sort(inputArray); + String[] expectedOutput = {"s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void shellSortNonDuplicateIntegerArray() { + Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; + Integer[] outputArray = shellSort.sort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void shellSortDuplicateIntegerArray() { + Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; + Integer[] outputArray = shellSort.sort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void shellSortNonDuplicateStringArray() { + String[] inputArray = {"s", "b", "k", "a", "d", "c", "h"}; + String[] outputArray = shellSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "c", "d", "h", "k", "s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void shellSortDuplicateStringArray() { + String[] inputArray = {"s", "b", "d", "a", "d", "c", "h", "b"}; + String[] outputArray = shellSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"}; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/SimpleSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/SimpleSortTest.java new file mode 100644 index 000000000000..e476b97b96e0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/SimpleSortTest.java @@ -0,0 +1,66 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class SimpleSortTest { + + private SimpleSort simpleSort = new SimpleSort(); + + @Test + public void simpleSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = simpleSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void simpleSortSingleIntegerArray() { + Integer[] inputArray = {4}; + Integer[] outputArray = simpleSort.sort(inputArray); + Integer[] expectedOutput = {4}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void simpleSortSingleStringArray() { + String[] inputArray = {"s"}; + String[] outputArray = simpleSort.sort(inputArray); + String[] expectedOutput = {"s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void simpleSortNonDuplicateIntegerArray() { + Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; + Integer[] outputArray = simpleSort.sort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void simpleSortDuplicateIntegerArray() { + Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; + Integer[] outputArray = simpleSort.sort(inputArray); + Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void simpleSortNonDuplicateStringArray() { + String[] inputArray = {"s", "b", "k", "a", "d", "c", "h"}; + String[] outputArray = simpleSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "c", "d", "h", "k", "s"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void simpleSortDuplicateStringArray() { + String[] inputArray = {"s", "b", "d", "a", "d", "c", "h", "b"}; + String[] outputArray = simpleSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"}; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/SlowSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/SlowSortTest.java new file mode 100644 index 000000000000..d4d9eaa1c275 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/SlowSortTest.java @@ -0,0 +1,79 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Rebecca Velez (https://github.com/rebeccavelez) + * @see SlowSort + */ + +public class SlowSortTest { + + private SlowSort slowSort = new SlowSort(); + + @Test + public void slowSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortSingleIntegerElementArray() { + Integer[] inputArray = {5}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {5}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortSingleStringElementArray() { + String[] inputArray = {"k"}; + String[] outputArray = slowSort.sort(inputArray); + String[] expectedOutput = {"k"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortIntegerArray() { + Integer[] inputArray = {8, 84, 53, -683, 953, 64, 2, 202, 98, -10}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {-683, -10, 2, 8, 53, 64, 84, 98, 202, 953}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortDuplicateIntegerArray() { + Integer[] inputArray = {8, 84, 8, -2, 953, 64, 2, 953, 98}; + Integer[] outputArray = slowSort.sort(inputArray); + Integer[] expectedOutput = {-2, 2, 8, 8, 64, 84, 98, 953, 953}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortStringArray() { + String[] inputArray = {"g", "d", "a", "b", "f", "c", "e"}; + String[] outputArray = slowSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "c", "d", "e", "f", "g"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortDuplicateStringArray() { + String[] inputArray = {"g", "d", "a", "g", "b", "f", "d", "c", "e"}; + String[] outputArray = slowSort.sort(inputArray); + String[] expectedOutput = {"a", "b", "c", "d", "d", "e", "f", "g", "g"}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void slowSortStringSymbolArray() { + String[] inputArray = {"cbf", "auk", "ó", "(b", "a", ")", "au", "á", "cba", "auk", "(a", "bhy", "cba"}; + String[] outputArray = slowSort.sort(inputArray); + String[] expectedOutput = {"(a", "(b", ")", "a", "au", "auk", "auk", "bhy", "cba", "cba", "cbf", "á", "ó"}; + assertArrayEquals(outputArray, expectedOutput); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java b/Java/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java new file mode 100644 index 000000000000..16571b3b9d24 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/SortUtilsRandomGeneratorTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.sorts; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.RepeatedTest; +import org.junit.jupiter.api.Test; + +class SortUtilsRandomGeneratorTest { + + @RepeatedTest(1000) + void generateArray() { + int size = 1_000; + Double[] doubles = SortUtilsRandomGenerator.generateArray(size); + assertThat(doubles).hasSize(size); + assertThat(doubles).doesNotContainNull(); + } + + @Test + void generateArrayEmpty() { + int size = 0; + Double[] doubles = SortUtilsRandomGenerator.generateArray(size); + assertThat(doubles).hasSize(size); + } + + @RepeatedTest(1000) + void generateDouble() { + Double randomDouble = SortUtilsRandomGenerator.generateDouble(); + assertThat(randomDouble).isBetween(0.0, 1.0); + assertThat(randomDouble).isNotEqualTo(1.0); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java b/Java/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java new file mode 100644 index 000000000000..591b53891ee7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java @@ -0,0 +1,70 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.List; +import org.junit.jupiter.api.Test; + +class SortUtilsTest { + + @Test + void isSortedEmptyArray() { + Double[] emptyArray = {}; + assertTrue(SortUtils.isSorted(emptyArray)); + } + + @Test + void isSortedWithSingleElement() { + Double[] singleElementArray = {1.0}; + assertTrue(SortUtils.isSorted(singleElementArray)); + } + + @Test + void isSortedArrayTrue() { + Integer[] array = {1, 1, 2, 3, 5, 8, 11}; + assertTrue(SortUtils.isSorted(array)); + + Integer[] identicalArray = {1, 1, 1, 1, 1}; + assertTrue(SortUtils.isSorted(identicalArray)); + + Double[] doubles = {-15.123, -15.111, 0.0, 0.12, 0.15}; + assertTrue(SortUtils.isSorted(doubles)); + } + + @Test + void isSortedArrayFalse() { + Double[] array = {1.0, 3.0, -0.15}; + assertFalse(SortUtils.isSorted(array)); + + Integer[] array2 = {14, 15, 16, 1}; + assertFalse(SortUtils.isSorted(array2)); + + Integer[] array3 = {5, 4, 3, 2, 1}; + assertFalse(SortUtils.isSorted(array3)); + } + + @Test + void isSortedListTrue() { + List<Integer> list = List.of(1, 1, 2, 3, 5, 8, 11); + assertTrue(SortUtils.isSorted(list)); + + List<Integer> identicalList = List.of(1, 1, 1, 1, 1); + assertTrue(SortUtils.isSorted(identicalList)); + + List<Double> doubles = List.of(-15.123, -15.111, 0.0, 0.12, 0.15); + assertTrue(SortUtils.isSorted(doubles)); + } + + @Test + void isSortedListFalse() { + List<Double> list = List.of(1.0, 3.0, -0.15); + assertFalse(SortUtils.isSorted(list)); + + List<Integer> array2 = List.of(14, 15, 16, 1); + assertFalse(SortUtils.isSorted(array2)); + + List<Integer> array3 = List.of(5, 4, 3, 2, 1); + assertFalse(SortUtils.isSorted(array3)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java b/Java/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java new file mode 100644 index 000000000000..113bff2b5b0d --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java @@ -0,0 +1,170 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.Test; + +public abstract class SortingAlgorithmTest { + abstract SortAlgorithm getSortAlgorithm(); + + @Test + void shouldAcceptWhenEmptyArrayIsPassed() { + Integer[] array = new Integer[] {}; + Integer[] expected = new Integer[] {}; + + Integer[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenEmptyListIsPassed() { + List<Integer> list = new ArrayList<>(); + List<Integer> expected = new ArrayList<>(); + + List<Integer> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenSingleValuedArrayIsPassed() { + Integer[] array = new Integer[] {2}; + Integer[] expected = new Integer[] {2}; + + Integer[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenSingleValuedListIsPassed() { + List<Integer> list = List.of(2); + List<Integer> expected = List.of(2); + + List<Integer> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenListWithAllPositiveValuesIsPassed() { + Integer[] array = new Integer[] {60, 7, 55, 9, 999, 3}; + Integer[] expected = new Integer[] {3, 7, 9, 55, 60, 999}; + + Integer[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenArrayWithAllPositiveValuesIsPassed() { + List<Integer> list = List.of(60, 7, 55, 9, 999, 3); + List<Integer> expected = List.of(3, 7, 9, 55, 60, 999); + + List<Integer> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenArrayWithAllNegativeValuesIsPassed() { + Integer[] array = new Integer[] {-60, -7, -55, -9, -999, -3}; + Integer[] expected = new Integer[] {-999, -60, -55, -9, -7, -3}; + + Integer[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenListWithAllNegativeValuesIsPassed() { + List<Integer> list = List.of(-60, -7, -55, -9, -999, -3); + List<Integer> expected = List.of(-999, -60, -55, -9, -7, -3); + + List<Integer> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenArrayWithRealNumberValuesIsPassed() { + Integer[] array = new Integer[] {60, -7, 55, 9, -999, -3}; + Integer[] expected = new Integer[] {-999, -7, -3, 9, 55, 60}; + + Integer[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenListWithRealNumberValuesIsPassed() { + List<Integer> list = List.of(60, -7, 55, 9, -999, -3); + List<Integer> expected = List.of(-999, -7, -3, 9, 55, 60); + + List<Integer> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenArrayWithDuplicateValueIsPassed() { + Integer[] array = new Integer[] {60, 7, 55, 55, 999, 3}; + Integer[] expected = new Integer[] {3, 7, 55, 55, 60, 999}; + + Integer[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenListWithDuplicateValueIsPassed() { + List<Integer> list = List.of(60, 7, 55, 55, 999, 3); + List<Integer> expected = List.of(3, 7, 55, 55, 60, 999); + + List<Integer> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenStringValueArrayIsPassed() { + String[] array = {"z", "a", "x", "b", "y"}; + String[] expected = {"a", "b", "x", "y", "z"}; + + String[] sorted = getSortAlgorithm().sort(array); + + assertArrayEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenStringValueListIsPassed() { + List<String> list = List.of("z", "a", "x", "b", "y"); + List<String> expected = List.of("a", "b", "x", "y", "z"); + + List<String> sorted = getSortAlgorithm().sort(list); + + assertIterableEquals(expected, sorted); + } + + @Test + void shouldAcceptWhenRandomArrayIsPassed() { + int randomSize = SortUtilsRandomGenerator.generateInt(10_000); + Double[] array = SortUtilsRandomGenerator.generateArray(randomSize); + Double[] sorted = getSortAlgorithm().sort(array); + assertTrue(SortUtils.isSorted(sorted)); + } + + @Test + void shouldAcceptWhenRandomListIsPassed() { + int randomSize = SortUtilsRandomGenerator.generateInt(10_000); + Double[] array = SortUtilsRandomGenerator.generateArray(randomSize); + List<Double> list = List.of(array); + List<Double> sorted = getSortAlgorithm().sort(list); + assertTrue(SortUtils.isSorted(sorted)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/StrandSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/StrandSortTest.java new file mode 100644 index 000000000000..91e85c81e5ec --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/StrandSortTest.java @@ -0,0 +1,34 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.Arrays; +import java.util.LinkedList; +import org.junit.jupiter.api.Test; + +class StrandSortTest { + + @Test + // valid test case + public void strandSortNonDuplicateTest() { + int[] expectedArray = {1, 2, 3, 4, 5}; + LinkedList<Integer> actualList = StrandSort.strandSort(new LinkedList<Integer>(Arrays.asList(3, 1, 2, 4, 5))); + int[] actualArray = new int[actualList.size()]; + for (int i = 0; i < actualList.size(); i++) { + actualArray[i] = actualList.get(i); + } + assertArrayEquals(expectedArray, actualArray); + } + + @Test + // valid test case + public void strandSortDuplicateTest() { + int[] expectedArray = {2, 2, 2, 5, 7}; + LinkedList<Integer> actualList = StrandSort.strandSort(new LinkedList<Integer>(Arrays.asList(7, 2, 2, 2, 5))); + int[] actualArray = new int[actualList.size()]; + for (int i = 0; i < actualList.size(); i++) { + actualArray[i] = actualList.get(i); + } + assertArrayEquals(expectedArray, actualArray); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/TimSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/TimSortTest.java new file mode 100644 index 000000000000..38e29d6eadd3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/TimSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +class TimSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new TimSort(); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java new file mode 100644 index 000000000000..de115b458fe7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java @@ -0,0 +1,62 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.thealgorithms.sorts.TopologicalSort.Graph; +import java.util.LinkedList; +import org.junit.jupiter.api.Test; + +class TopologicalSortTest { + + @Test + void successTest() { + /* + * Professor Bumstead example DAG. Each directed edge means that garment u must be put on + * before garment v. + * */ + Graph graph = new Graph(); + graph.addEdge("shirt", "tie", "belt"); + graph.addEdge("tie", "jacket"); + graph.addEdge("belt", "jacket"); + graph.addEdge("watch", ""); + graph.addEdge("undershorts", "pants", "shoes"); + graph.addEdge("shoes", ""); + graph.addEdge("socks", "shoes"); + graph.addEdge("jacket", ""); + graph.addEdge("pants", "belt", "shoes"); + LinkedList<String> expected = new LinkedList<>(); + expected.add("socks"); + expected.add("undershorts"); + expected.add("pants"); + expected.add("shoes"); + expected.add("watch"); + expected.add("shirt"); + expected.add("belt"); + expected.add("tie"); + expected.add("jacket"); + assertIterableEquals(expected, TopologicalSort.sort(graph)); + } + + @Test + public void failureTest() { + /* + * Graph example from Geeks For Geeks + * https://www.geeksforgeeks.org/tree-back-edge-and-cross-edges-in-dfs-of-graph/ + * */ + Graph graph = new Graph(); + graph.addEdge("1", "2", "3", "8"); + graph.addEdge("2", "4"); + graph.addEdge("3", "5"); + graph.addEdge("4", "6"); + graph.addEdge("5", "4", "7", "8"); + graph.addEdge("6", "2"); + graph.addEdge("7", ""); + graph.addEdge("8", ""); + Exception exception = assertThrows(RuntimeException.class, () -> TopologicalSort.sort(graph)); + String expected = "This graph contains a cycle. No linear ordering is possible. " + + "Back edge: 6 -> 2"; + assertEquals(exception.getMessage(), expected); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/TreeSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/TreeSortTest.java new file mode 100644 index 000000000000..5fb4c18e953e --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/TreeSortTest.java @@ -0,0 +1,54 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +/** + * @author Tabbygray (https://github.com/Tabbygray) + * @see TreeSort + */ + +public class TreeSortTest { + private TreeSort treeSort = new TreeSort(); + + @Test + public void treeSortEmptyArray() { + Integer[] inputArray = {}; + Integer[] outputArray = treeSort.sort(inputArray); + Integer[] expectedOutput = {}; + assertArrayEquals(outputArray, expectedOutput); + } + + @Test + public void treeSortSingleStringElement() { + String[] inputArray = {"Test"}; + String[] outputArray = treeSort.sort(inputArray); + String[] expectedArray = {"Test"}; + assertArrayEquals(outputArray, expectedArray); + } + + @Test + public void treeSortStringArray() { + String[] inputArray = {"F6w9", "l1qz", "dIxH", "larj", "kRzy", "vnNH", "3ftM", "hc4n", "C5Qi", "btGF"}; + String[] outputArray = treeSort.sort(inputArray); + String[] expectedArray = {"3ftM", "C5Qi", "F6w9", "btGF", "dIxH", "hc4n", "kRzy", "l1qz", "larj", "vnNH"}; + assertArrayEquals(outputArray, expectedArray); + } + + @Test + public void treeSortIntegerArray() { + Integer[] inputArray = {-97, -44, -4, -85, -92, 74, 79, -26, 76, -5}; + Integer[] outputArray = treeSort.sort(inputArray); + Integer[] expectedArray = {-97, -92, -85, -44, -26, -5, -4, 74, 76, 79}; + assertArrayEquals(outputArray, expectedArray); + } + + @Test + public void treeSortDoubleArray() { + Double[] inputArray = {0.8047485045, 0.4493112337, 0.8298433723, 0.2691406748, 0.2482782839, 0.5976243420, 0.6746235284, 0.0552623569, 0.3515624123, 0.0536747336}; + Double[] outputArray = treeSort.sort(inputArray); + Double[] expectedArray = {0.0536747336, 0.0552623569, 0.2482782839, 0.2691406748, 0.3515624123, 0.4493112337, 0.5976243420, 0.6746235284, 0.8047485045, 0.8298433723}; + assertArrayEquals(outputArray, expectedArray); + } +} diff --git a/Java/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java b/Java/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java new file mode 100644 index 000000000000..c5d57d63cf38 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java @@ -0,0 +1,73 @@ +package com.thealgorithms.sorts; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +public class WiggleSortTest { + + @Test + void wiggleTestNumbersEven() { + WiggleSort wiggleSort = new WiggleSort(); + Integer[] values = {1, 2, 3, 4}; + Integer[] result = {1, 4, 2, 3}; + wiggleSort.sort(values); + assertArrayEquals(values, result); + } + + @Test + void wiggleTestNumbersOdd() { + WiggleSort wiggleSort = new WiggleSort(); + Integer[] values = {1, 2, 3, 4, 5}; + Integer[] result = {3, 5, 1, 4, 2}; + wiggleSort.sort(values); + assertArrayEquals(values, result); + } + + @Test + void wiggleTestNumbersOddDuplicates() { + WiggleSort wiggleSort = new WiggleSort(); + Integer[] values = {7, 2, 2, 2, 5}; + Integer[] result = {2, 7, 2, 5, 2}; + wiggleSort.sort(values); + assertArrayEquals(values, result); + } + + @Test + void wiggleTestNumbersOddMultipleDuplicates() { + WiggleSort wiggleSort = new WiggleSort(); + Integer[] values = {1, 1, 2, 2, 5}; + Integer[] result = {2, 5, 1, 2, 1}; + wiggleSort.sort(values); + assertArrayEquals(values, result); + } + + @Test + void wiggleTestNumbersEvenMultipleDuplicates() { + WiggleSort wiggleSort = new WiggleSort(); + Integer[] values = {1, 1, 2, 2, 2, 5}; + Integer[] result = {2, 5, 1, 2, 1, 2}; + wiggleSort.sort(values); + System.out.println(Arrays.toString(values)); + assertArrayEquals(values, result); + } + + @Test + void wiggleTestNumbersEvenDuplicates() { + WiggleSort wiggleSort = new WiggleSort(); + Integer[] values = {1, 2, 4, 4}; + Integer[] result = {1, 4, 2, 4}; + wiggleSort.sort(values); + assertArrayEquals(values, result); + } + + @Test + void wiggleTestStrings() { + WiggleSort wiggleSort = new WiggleSort(); + String[] values = {"a", "b", "d", "c"}; + String[] result = {"a", "d", "b", "c"}; + wiggleSort.sort(values); + assertArrayEquals(values, result); + } +} diff --git a/Java/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java b/Java/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java new file mode 100644 index 000000000000..a8d8e0d3d9dc --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java @@ -0,0 +1,43 @@ +package com.thealgorithms.stacks; + +import static java.util.Map.entry; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Map; +import org.junit.jupiter.api.Test; + +public class StackPostfixNotationTest { + @Test + public void testEvaluate() { + final Map<String, Integer> testCases = Map.ofEntries(entry("1 1 +", 2), entry("2 3 *", 6), entry("6 2 /", 3), entry("-5 -2 -", -3), entry("5 2 + 3 *", 21), entry("-5", -5)); + for (final var tc : testCases.entrySet()) { + assertEquals(tc.getValue(), StackPostfixNotation.postfixEvaluate(tc.getKey())); + } + } + + @Test + public void testIfEvaluateThrowsExceptionForEmptyInput() { + assertThrows(IllegalArgumentException.class, () -> StackPostfixNotation.postfixEvaluate("")); + } + + @Test + public void testIfEvaluateThrowsExceptionForInproperInput() { + assertThrows(IllegalArgumentException.class, () -> StackPostfixNotation.postfixEvaluate("3 3 3")); + } + + @Test + public void testIfEvaluateThrowsExceptionForInputWithUnknownOperation() { + assertThrows(IllegalArgumentException.class, () -> StackPostfixNotation.postfixEvaluate("3 3 !")); + } + + @Test + public void testIfEvaluateThrowsExceptionForInputWithTooFewArgsA() { + assertThrows(IllegalArgumentException.class, () -> StackPostfixNotation.postfixEvaluate("+")); + } + + @Test + public void testIfEvaluateThrowsExceptionForInputWithTooFewArgsB() { + assertThrows(IllegalArgumentException.class, () -> StackPostfixNotation.postfixEvaluate("2 +")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java b/Java/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java new file mode 100644 index 000000000000..caaca561143f --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/AhoCorasickTest.java @@ -0,0 +1,120 @@ +/* + * Tests For Aho-Corasick String Matching Algorithm + * + * Author: Prabhat-Kumar-42 + * GitHub: https://github.com/Prabhat-Kumar-42 + */ + +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +/** + * This class contains test cases for the Aho-Corasick String Matching Algorithm. + * The Aho-Corasick algorithm is used to efficiently find all occurrences of multiple + * patterns in a given text. + */ +class AhoCorasickTest { + private String[] patterns; // The array of patterns to search for + private String text; // The input text to search within + + /** + * This method sets up the test environment before each test case. + * It initializes the patterns and text to be used for testing. + */ + @BeforeEach + void setUp() { + patterns = new String[] {"ACC", "ATC", "CAT", "GCG", "C", "T"}; + text = "GCATCG"; + } + + /** + * Test searching for multiple patterns in the input text. + * The expected results are defined for each pattern. + */ + @Test + void testSearch() { + // Define the expected results for each pattern + final var expected = Map.of("ACC", new ArrayList<>(Arrays.asList()), "ATC", new ArrayList<>(Arrays.asList(2)), "CAT", new ArrayList<>(Arrays.asList(1)), "GCG", new ArrayList<>(Arrays.asList()), "C", new ArrayList<>(Arrays.asList(1, 4)), "T", new ArrayList<>(Arrays.asList(3))); + assertEquals(expected, AhoCorasick.search(text, patterns)); + } + + /** + * Test searching with an empty pattern array. + * The result should be an empty map. + */ + @Test + void testEmptyPatterns() { + // Define an empty pattern array + final var emptyPatterns = new String[] {}; + assertTrue(AhoCorasick.search(text, emptyPatterns).isEmpty()); + } + + /** + * Test searching for patterns that are not present in the input text. + * The result should be an empty list for each pattern. + */ + @Test + void testPatternNotFound() { + // Define patterns that are not present in the text + final var searchPatterns = new String[] {"XYZ", "123"}; + final var expected = Map.of("XYZ", new ArrayList<Integer>(), "123", new ArrayList<Integer>()); + assertEquals(expected, AhoCorasick.search(text, searchPatterns)); + } + + /** + * Test searching for patterns that start at the beginning of the input text. + * The expected position for each pattern is 0. + */ + @Test + void testPatternAtBeginning() { + // Define patterns that start at the beginning of the text + final var searchPatterns = new String[] {"GC", "GCA", "GCAT"}; + final var expected = Map.of("GC", new ArrayList<Integer>(Arrays.asList(0)), "GCA", new ArrayList<Integer>(Arrays.asList(0)), "GCAT", new ArrayList<Integer>(Arrays.asList(0))); + assertEquals(expected, AhoCorasick.search(text, searchPatterns)); + } + + /** + * Test searching for patterns that end at the end of the input text. + * The expected positions are 4, 3, and 2 for the patterns. + */ + @Test + void testPatternAtEnd() { + // Define patterns that end at the end of the text + final var searchPatterns = new String[] {"CG", "TCG", "ATCG"}; + final var expected = Map.of("CG", new ArrayList<Integer>(Arrays.asList(4)), "TCG", new ArrayList<Integer>(Arrays.asList(3)), "ATCG", new ArrayList<Integer>(Arrays.asList(2))); + assertEquals(expected, AhoCorasick.search(text, searchPatterns)); + } + + /** + * Test searching for patterns with multiple occurrences in the input text. + * The expected sizes are 1 and 1, and the expected positions are 2 and 3 + * for the patterns "AT" and "T" respectively. + */ + @Test + void testMultipleOccurrencesOfPattern() { + // Define patterns with multiple occurrences in the text + final var searchPatterns = new String[] {"AT", "T"}; + final var expected = Map.of("AT", new ArrayList<Integer>(Arrays.asList(2)), "T", new ArrayList<Integer>(Arrays.asList(3))); + assertEquals(expected, AhoCorasick.search(text, searchPatterns)); + } + + /** + * Test searching for patterns in a case-insensitive manner. + * The search should consider patterns regardless of their case. + */ + @Test + void testCaseInsensitiveSearch() { + // Define patterns with different cases + final var searchPatterns = new String[] {"gca", "aTc", "C"}; + final var expected = Map.of("gca", new ArrayList<Integer>(), "aTc", new ArrayList<Integer>(), "C", new ArrayList<Integer>(Arrays.asList(1, 4))); + assertEquals(expected, AhoCorasick.search(text, searchPatterns)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java b/Java/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java new file mode 100644 index 000000000000..083239152ec2 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java @@ -0,0 +1,30 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class AlphabeticalTest { + + @Test + public void isAlphabetical() { + // expected to be true + String input1 = "abcdefghijklmno"; + String input2 = "abcdxxxyzzzz"; + String input3 = "fpw"; + + // expected to be false + String input4 = "123a"; + String input5 = "abcABC"; + String input6 = "abcdefghikjlmno"; + + assertTrue(Alphabetical.isAlphabetical(input1)); + assertTrue(Alphabetical.isAlphabetical(input2)); + assertTrue(Alphabetical.isAlphabetical(input3)); + + assertFalse(Alphabetical.isAlphabetical(input4)); + assertFalse(Alphabetical.isAlphabetical(input5)); + assertFalse(Alphabetical.isAlphabetical(input6)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/AnagramsTest.java b/Java/src/test/java/com/thealgorithms/strings/AnagramsTest.java new file mode 100644 index 000000000000..ba530cffb017 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/AnagramsTest.java @@ -0,0 +1,23 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class AnagramsTest { + + @Test + public void isAlphabetical() { + String input1 = "late"; + Anagrams anagrams = new Anagrams(); + assertTrue(anagrams.approach1(input1, "tale")); + assertTrue(anagrams.approach1(input1, "teal")); + assertTrue(anagrams.approach2(input1, "tale")); + assertTrue(anagrams.approach2(input1, "teal")); + assertTrue(anagrams.approach3(input1, "tale")); + assertTrue(anagrams.approach3(input1, "teal")); + assertTrue(anagrams.approach4(input1, "tale")); + assertTrue(anagrams.approach4(input1, "teal")); + assertTrue(anagrams.approach5(input1, "teal")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/CharacterSameTest.java b/Java/src/test/java/com/thealgorithms/strings/CharacterSameTest.java new file mode 100644 index 000000000000..d91b5f2f55e9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/CharacterSameTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class CharacterSameTest { + + @Test + public void isAllCharactersSame() { + String input1 = "aaa"; + String input2 = "abc"; + String input3 = "1 1 1 1"; + String input4 = "111"; + String input5 = ""; + String input6 = " "; + String input7 = ". "; + + assertTrue(CharactersSame.isAllCharactersSame(input1)); + assertFalse(CharactersSame.isAllCharactersSame(input2)); + assertFalse(CharactersSame.isAllCharactersSame(input3)); + assertTrue(CharactersSame.isAllCharactersSame(input4)); + assertTrue(CharactersSame.isAllCharactersSame(input5)); + assertTrue(CharactersSame.isAllCharactersSame(input6)); + assertFalse(CharactersSame.isAllCharactersSame(input7)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java b/Java/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java new file mode 100644 index 000000000000..82a75a130ef0 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/CheckAnagramsTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class CheckAnagramsTest { + private static final String MESSAGE = "Strings must contain only lowercase English letters!"; + + // CHECK METHOD isAnagrams() + @Test + public void testCheckAnagrams() { + String testString1 = "STUDY"; + String testString2 = "DUSTY"; + Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2)); + } + + @Test + public void testCheckFalseAnagrams() { + String testString1 = "STUDY"; + String testString2 = "random"; + Assertions.assertFalse(CheckAnagrams.isAnagrams(testString1, testString2)); + } + + @Test + public void testCheckSameWordAnagrams() { + String testString1 = "STUDY"; + Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString1)); + } + + @Test + public void testCheckDifferentCasesAnagram() { + String testString1 = "STUDY"; + String testString2 = "dusty"; + Assertions.assertTrue(CheckAnagrams.isAnagrams(testString1, testString2)); + } + + // CHECK METHOD isAnagramsUnicode() + // Below tests work with strings which consist of Unicode symbols & the algorithm is case-sensitive. + @Test + public void testStringAreValidAnagramsCaseSensitive() { + Assertions.assertTrue(CheckAnagrams.isAnagramsUnicode("Silent", "liSten")); + Assertions.assertTrue(CheckAnagrams.isAnagramsUnicode("This is a string", "is This a string")); + } + + @Test + public void testStringAreNotAnagramsCaseSensitive() { + Assertions.assertFalse(CheckAnagrams.isAnagramsUnicode("Silent", "Listen")); + Assertions.assertFalse(CheckAnagrams.isAnagramsUnicode("This is a string", "Is this a string")); + } + + // CHECK METHOD isAnagramsOptimised() + // Below tests work with strings which consist of only lowercase English letters + @Test + public void testOptimisedAlgorithmStringsAreValidAnagrams() { + Assertions.assertTrue(CheckAnagrams.isAnagramsOptimised("silent", "listen")); + Assertions.assertTrue(CheckAnagrams.isAnagramsOptimised("mam", "amm")); + } + + @Test + public void testOptimisedAlgorithmShouldThrowExceptionWhenStringsContainUppercaseLetters() { + IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> CheckAnagrams.isAnagramsOptimised("Silent", "Listen")); + Assertions.assertEquals(exception.getMessage(), MESSAGE); + + exception = assertThrows(IllegalArgumentException.class, () -> Assertions.assertFalse(CheckAnagrams.isAnagramsOptimised("This is a string", "Is this a string"))); + Assertions.assertEquals(exception.getMessage(), MESSAGE); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java b/Java/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java new file mode 100644 index 000000000000..713b53f0b634 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java @@ -0,0 +1,17 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class CheckVowelsTest { + + @Test + public void isVowel() { + assertTrue(CheckVowels.hasVowels("foo")); + assertTrue(CheckVowels.hasVowels("bar")); + assertFalse(CheckVowels.hasVowels("why")); + assertFalse(CheckVowels.hasVowels("myths")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/HammingDistanceTest.java b/Java/src/test/java/com/thealgorithms/strings/HammingDistanceTest.java new file mode 100644 index 000000000000..e0fbdb1442a7 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/HammingDistanceTest.java @@ -0,0 +1,24 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +public class HammingDistanceTest { + + @Test + void testHammingDistance() throws Exception { + assertEquals(HammingDistance.calculateHammingDistance("", ""), 0); + assertEquals(HammingDistance.calculateHammingDistance("java", "java"), 0); + assertEquals(HammingDistance.calculateHammingDistance("karolin", "kathrin"), 3); + assertEquals(HammingDistance.calculateHammingDistance("kathrin", "kerstin"), 4); + assertEquals(HammingDistance.calculateHammingDistance("00000", "11111"), 5); + } + + @Test + void testNotEqualStringLengths() { + Exception exception = assertThrows(Exception.class, () -> HammingDistance.calculateHammingDistance("ab", "abc")); + assertEquals("String lengths must be equal", exception.getMessage()); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java b/Java/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java new file mode 100644 index 000000000000..9649a89a3325 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java @@ -0,0 +1,87 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class HorspoolSearchTest { + + @Test + void testFindFirstMatch() { + int index = HorspoolSearch.findFirst("World", "Hello World"); + assertEquals(6, index); + } + + @Test + void testFindFirstNotMatch() { + int index = HorspoolSearch.findFirst("hell", "Hello World"); + assertEquals(-1, index); + } + + @Test + void testFindFirstPatternLongerText() { + int index = HorspoolSearch.findFirst("Hello World!!!", "Hello World"); + assertEquals(-1, index); + } + + @Test + void testFindFirstPatternEmpty() { + int index = HorspoolSearch.findFirst("", "Hello World"); + assertEquals(-1, index); + } + + @Test + void testFindFirstTextEmpty() { + int index = HorspoolSearch.findFirst("Hello", ""); + assertEquals(-1, index); + } + + @Test + void testFindFirstPatternAndTextEmpty() { + int index = HorspoolSearch.findFirst("", ""); + assertEquals(-1, index); + } + + @Test + void testFindFirstSpecialCharacter() { + int index = HorspoolSearch.findFirst("$3**", "Hello $3**$ World"); + assertEquals(6, index); + } + + @Test + void testFindFirstInsensitiveMatch() { + int index = HorspoolSearch.findFirstInsensitive("hello", "Hello World"); + assertEquals(0, index); + } + + @Test + void testFindFirstInsensitiveNotMatch() { + int index = HorspoolSearch.findFirstInsensitive("helo", "Hello World"); + assertEquals(-1, index); + } + + @Test + void testGetLastComparisons() { + HorspoolSearch.findFirst("World", "Hello World"); + int lastSearchNumber = HorspoolSearch.getLastComparisons(); + assertEquals(7, lastSearchNumber); + } + + @Test + void testGetLastComparisonsNotMatch() { + HorspoolSearch.findFirst("Word", "Hello World"); + int lastSearchNumber = HorspoolSearch.getLastComparisons(); + assertEquals(3, lastSearchNumber); + } + + @Test + void testFindFirstPatternNull() { + assertThrows(NullPointerException.class, () -> HorspoolSearch.findFirst(null, "Hello World")); + } + + @Test + void testFindFirstTextNull() { + assertThrows(NullPointerException.class, () -> HorspoolSearch.findFirst("Hello", null)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/IsomorphicTest.java b/Java/src/test/java/com/thealgorithms/strings/IsomorphicTest.java new file mode 100644 index 000000000000..0dac47551868 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/IsomorphicTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public final class IsomorphicTest { + private IsomorphicTest() { + } + + @Test + public static void main(String[] args) { + String str1 = "abbbbaac"; + String str2 = "kffffkkd"; + + String str3 = "xyxyxy"; + String str4 = "bnbnbn"; + + String str5 = "ghjknnmm"; + String str6 = "wertpopo"; + + String str7 = "aaammmnnn"; + String str8 = "ggghhhbbj"; + + assertTrue(Isomorphic.checkStrings(str1, str2)); + assertTrue(Isomorphic.checkStrings(str3, str4)); + assertFalse(Isomorphic.checkStrings(str5, str6)); + assertFalse(Isomorphic.checkStrings(str7, str8)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java b/Java/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java new file mode 100644 index 000000000000..4ffbddcb44a8 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java @@ -0,0 +1,45 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class LetterCombinationsOfPhoneNumberTest { + + @Test + public void letterCombinationsOfPhoneNumber() { + LetterCombinationsOfPhoneNumber.generateNumberToCharMap(); + + // ** Test 1 ** + // Input: digits = "" + // Output: [] + int[] numbers1 = {}; + List<String> output1 = Arrays.asList(""); + assertTrue(LetterCombinationsOfPhoneNumber.printWords(numbers1, numbers1.length, 0, "").equals(output1)); + + // ** Test 2 ** + // Input: digits = "2" + // Output: ["a","b","c"] + int[] numbers2 = {2}; + List<String> output2 = Arrays.asList("a", "b", "c"); + assertTrue(LetterCombinationsOfPhoneNumber.printWords(numbers2, numbers2.length, 0, "").equals(output2)); + + // ** Test 3 ** + // Input: digits = "23" + // Output: ["ad","ae","af","bd","be","bf","cd","ce","cf"] + int[] numbers3 = {2, 3}; + List<String> output3 = Arrays.asList("ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"); + assertTrue(LetterCombinationsOfPhoneNumber.printWords(numbers3, numbers3.length, 0, "").equals(output3)); + + // ** Test 4 ** + // Input: digits = "234" + // Output: ["adg", "adh", "adi", "aeg", "aeh", "aei", "afg", "afh", "afi", + // "bdg", "bdh", "bdi", "beg", "beh", "bei", "bfg", "bfh", "bfi", "cdg", "cdh", + // "cdi", "ceg", "ceh", "cei", "cfg", "cfh", "cfi"] + int[] numbers4 = {2, 3, 4}; + List<String> output4 = Arrays.asList("adg", "adh", "adi", "aeg", "aeh", "aei", "afg", "afh", "afi", "bdg", "bdh", "bdi", "beg", "beh", "bei", "bfg", "bfh", "bfi", "cdg", "cdh", "cdi", "ceg", "ceh", "cei", "cfg", "cfh", "cfi"); + assertTrue(LetterCombinationsOfPhoneNumber.printWords(numbers4, numbers4.length, 0, "").equals(output4)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/LowerTest.java b/Java/src/test/java/com/thealgorithms/strings/LowerTest.java new file mode 100644 index 000000000000..e0abb921a593 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/LowerTest.java @@ -0,0 +1,18 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class LowerTest { + @Test + public void toLowerCase() { + String input1 = "hello world"; + String input2 = "HelLO WoRld"; + String input3 = "HELLO WORLD"; + + assertEquals("hello world", Lower.toLowerCase(input1)); + assertEquals("hello world", Lower.toLowerCase(input2)); + assertEquals("hello world", Lower.toLowerCase(input3)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/MyAtoiTest.java b/Java/src/test/java/com/thealgorithms/strings/MyAtoiTest.java new file mode 100644 index 000000000000..45f9158571e9 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/MyAtoiTest.java @@ -0,0 +1,43 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class MyAtoiTest { + + @Test + void testOne() { + assertEquals(42, MyAtoi.myAtoi("42")); + } + + @Test + void testTwo() { + assertEquals(-42, MyAtoi.myAtoi(" -42")); + } + + @Test + void testThree() { + assertEquals(4193, MyAtoi.myAtoi("4193 with words")); + } + + @Test + void testFour() { + assertEquals(0, MyAtoi.myAtoi("0")); + } + + @Test + void testFive() { + assertEquals(5678, MyAtoi.myAtoi("5678")); + } + + @Test + void testSix() { + assertEquals(42, MyAtoi.myAtoi("+42")); + } + + @Test + void testSeven() { + assertEquals(0, MyAtoi.myAtoi(" +0 ")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/PalindromeTest.java b/Java/src/test/java/com/thealgorithms/strings/PalindromeTest.java new file mode 100644 index 000000000000..f07736c37890 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/PalindromeTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.strings; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PalindromeTest { + + @Test + public void palindrome() { + + String[] palindromes = {null, "", "aba", "123321", "kayak"}; + for (String s : palindromes) { + Assertions.assertTrue(Palindrome.isPalindrome(s) && Palindrome.isPalindromeRecursion(s) && Palindrome.isPalindromeTwoPointer(s)); + } + + String[] notPalindromes = {"abb", "abc", "abc123", "kayaks"}; + for (String s : notPalindromes) { + Assertions.assertFalse(Palindrome.isPalindrome(s) || Palindrome.isPalindromeRecursion(s) || Palindrome.isPalindromeTwoPointer(s)); + } + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/PangramTest.java b/Java/src/test/java/com/thealgorithms/strings/PangramTest.java new file mode 100644 index 000000000000..00ecb909b2de --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/PangramTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class PangramTest { + + @Test + public void testPangram() { + assertTrue(Pangram.isPangram("The quick brown fox jumps over the lazy dog")); + assertFalse(Pangram.isPangram("The quick brown fox jumps over the azy dog")); // L is missing + assertFalse(Pangram.isPangram("+-1234 This string is not alphabetical")); + assertFalse(Pangram.isPangram("\u0000/\\ Invalid characters are alright too")); + + assertTrue(Pangram.isPangram2("The quick brown fox jumps over the lazy dog")); + assertFalse(Pangram.isPangram2("The quick brown fox jumps over the azy dog")); // L is missing + assertFalse(Pangram.isPangram2("+-1234 This string is not alphabetical")); + assertFalse(Pangram.isPangram2("\u0000/\\ Invalid characters are alright too")); + + assertTrue(Pangram.isPangramUsingSet("The quick brown fox jumps over the lazy dog")); + assertFalse(Pangram.isPangramUsingSet("The quick brown fox jumps over the azy dog")); // L is missing + assertFalse(Pangram.isPangramUsingSet("+-1234 This string is not alphabetical")); + assertFalse(Pangram.isPangramUsingSet("\u0000/\\ Invalid characters are alright too")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java b/Java/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java new file mode 100644 index 000000000000..b33037f37cfd --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ReverseStringRecursiveTest { + @Test + void shouldAcceptWhenEmptyStringIsPassed() { + String expected = ""; + String reversed = ReverseStringRecursive.reverse(""); + + assertEquals(expected, reversed); + } + + @Test + void shouldAcceptNotWhenWhenSingleCharacterIsPassed() { + String expected = "a"; + String reversed = ReverseStringRecursive.reverse("a"); + + assertEquals(expected, reversed); + } + + @Test + void shouldAcceptWhenStringIsPassed() { + String expected = "dlroWolleH"; + String reversed = ReverseStringRecursive.reverse("HelloWorld"); + + assertEquals(expected, reversed); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/ReverseStringTest.java b/Java/src/test/java/com/thealgorithms/strings/ReverseStringTest.java new file mode 100644 index 000000000000..e73f7afce8eb --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/ReverseStringTest.java @@ -0,0 +1,31 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class ReverseStringTest { + + @Test + public void testReverseString() { + String input1 = "Hello World"; + String input2 = "helloworld"; + String input3 = "123456789"; + String input4 = ""; + + String expectedOutput1 = "dlroW olleH"; + String expectedOutput2 = "dlrowolleh"; + String expectedOutput3 = "987654321"; + String expectedOutput4 = ""; + + assertEquals(ReverseString.reverse(input1), expectedOutput1); + assertEquals(ReverseString.reverse(input2), expectedOutput2); + assertEquals(ReverseString.reverse(input3), expectedOutput3); + assertEquals(ReverseString.reverse(input4), expectedOutput4); + + assertEquals(ReverseString.reverse2(input1), expectedOutput1); + assertEquals(ReverseString.reverse2(input2), expectedOutput2); + assertEquals(ReverseString.reverse2(input3), expectedOutput3); + assertEquals(ReverseString.reverse2(input4), expectedOutput4); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java b/Java/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java new file mode 100644 index 000000000000..7cab6aa7c698 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/ReverseWordsInStringTest.java @@ -0,0 +1,19 @@ +package com.thealgorithms.strings; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class ReverseWordsInStringTest { + @ParameterizedTest + @MethodSource("inputStream") + void numberTests(String expected, String input) { + Assertions.assertEquals(expected, ReverseWordsInString.reverseWordsInString(input)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of("blue is Sky", "Sky is blue"), Arguments.of("blue is Sky", "Sky \n is \t \n blue "), Arguments.of("", ""), Arguments.of("", " "), Arguments.of("", "\t")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/RotationTest.java b/Java/src/test/java/com/thealgorithms/strings/RotationTest.java new file mode 100644 index 000000000000..911ff87d29ad --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/RotationTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class RotationTest { + + @Test + public void testRotation() { + assertEquals("eksge", Rotation.rotation("geeks", 2)); + assertEquals("anasban", Rotation.rotation("bananas", 3)); + assertEquals("abracadabra", Rotation.rotation("abracadabra", 0)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/StringCompressionTest.java b/Java/src/test/java/com/thealgorithms/strings/StringCompressionTest.java new file mode 100644 index 000000000000..bbd56c19dc23 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/StringCompressionTest.java @@ -0,0 +1,14 @@ +package com.thealgorithms.strings; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +public class StringCompressionTest { + @ParameterizedTest + @CsvSource({"a,a", "aabbb,a2b3", "abbbc,ab3c", "aabccd,a2bc2d"}) + void stringCompressionTest(String input, String expectedOutput) { + String output = StringCompression.compress(input); + assertEquals(expectedOutput, output); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/UpperTest.java b/Java/src/test/java/com/thealgorithms/strings/UpperTest.java new file mode 100644 index 000000000000..5413c77b913a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/UpperTest.java @@ -0,0 +1,18 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class UpperTest { + + @Test + public void toUpperCase() { + String input1 = "hello world"; + String input2 = "hElLo WoRlD"; + String input3 = "HELLO WORLD"; + assertEquals("HELLO WORLD", Upper.toUpperCase(input1)); + assertEquals("HELLO WORLD", Upper.toUpperCase(input2)); + assertEquals("HELLO WORLD", Upper.toUpperCase(input3)); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java b/Java/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java new file mode 100644 index 000000000000..22deb4b14d3c --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java @@ -0,0 +1,24 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +public class ValidParenthesesTest { + + @Test + void testOne() { + assertTrue(ValidParentheses.isValid("()")); + } + + @Test + void testTwo() { + assertTrue(ValidParentheses.isValid("()[]{}")); + } + + @Test + void testThree() { + assertFalse(ValidParentheses.isValid("(]")); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/WordLadderTest.java b/Java/src/test/java/com/thealgorithms/strings/WordLadderTest.java new file mode 100644 index 000000000000..4f1d07ebdc4a --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/WordLadderTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.strings; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Test; + +public class WordLadderTest { + + @Test + public void testWordLadder() { + + /** + * Test 1: + * Input: beginWord = "hit", endWord = "cog", wordList = + * ["hot","dot","dog","lot","log","cog"] + * Output: 5 + * Explanation: One shortest transformation sequence is + * "hit" -> "hot" -> "dot" -> "dog" -> cog" + * which is 5 words long. + */ + + List<String> wordList1 = Arrays.asList("hot", "dot", "dog", "lot", "log", "cog"); + assertEquals(WordLadder.ladderLength("hit", "cog", wordList1), 5); + + /** + * Test 2: + * Input: beginWord = "hit", endWord = "cog", wordList = + * ["hot","dot","dog","lot","log"] + * Output: 0 + * Explanation: The endWord "cog" is not in wordList, + * therefore there is no valid transformation sequence. + */ + + List<String> wordList2 = Arrays.asList("hot", "dot", "dog", "lot", "log"); + assertEquals(WordLadder.ladderLength("hit", "cog", wordList2), 0); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/longestNonRepeativeSubstringTest.java b/Java/src/test/java/com/thealgorithms/strings/longestNonRepeativeSubstringTest.java new file mode 100644 index 000000000000..2dce8cf38c05 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/longestNonRepeativeSubstringTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.strings; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class longestNonRepeativeSubstringTest { + + @Test + public void palindrome() { + String input1 = "HelloWorld"; + String input2 = "javaIsAProgrammingLanguage"; + Assertions.assertEquals(longestNonRepeativeSubstring.lengthOfLongestSubstring(input1), 5); + Assertions.assertEquals(longestNonRepeativeSubstring.lengthOfLongestSubstring(input2), 9); + } +} diff --git a/Java/src/test/java/com/thealgorithms/strings/zigZagPattern/zigZagPatternTest.java b/Java/src/test/java/com/thealgorithms/strings/zigZagPattern/zigZagPatternTest.java new file mode 100644 index 000000000000..02904ddcf6c3 --- /dev/null +++ b/Java/src/test/java/com/thealgorithms/strings/zigZagPattern/zigZagPatternTest.java @@ -0,0 +1,15 @@ +package com.thealgorithms.strings.zigZagPattern; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class zigZagPatternTest { + + @Test + public void palindrome() { + String input1 = "HelloWorldFromJava"; + String input2 = "javaIsAProgrammingLanguage"; + Assertions.assertEquals(zigZagPattern.encode(input1, 4), "HooeWrrmalolFJvlda"); + Assertions.assertEquals(zigZagPattern.encode(input2, 4), "jAaLgasPrmgaaevIrgmnnuaoig"); + } +} diff --git a/README.md b/README.md index 16237a32f974..d60d5104c385 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # The Algorithms - Java [![Build](https://github.com/TheAlgorithms/Java/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/TheAlgorithms/Java/actions/workflows/build.yml) +[![codecov](https://codecov.io/gh/TheAlgorithms/Java/graph/badge.svg?token=XAdPyqTIqR)](https://codecov.io/gh/TheAlgorithms/Java) [![Discord chat](https://img.shields.io/discord/808045925556682782.svg?logo=discord&colorB=7289DA&style=flat-square)](https://discord.gg/c7MnfGFGa6) [![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/TheAlgorithms/Java) diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 000000000000..5ada9361d03c --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,198 @@ +<?xml version="1.0"?> +<!DOCTYPE module PUBLIC + "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" + "https://checkstyle.org/dtds/configuration_1_3.dtd"> + +<!-- + + Checkstyle configuration that checks the sun coding conventions from: + + - the Java Language Specification at + https://docs.oracle.com/javase/specs/jls/se11/html/index.html + + - the Sun Code Conventions at https://www.oracle.com/java/technologies/javase/codeconventions-contents.html + + - the Javadoc guidelines at + https://www.oracle.com/technical-resources/articles/java/javadoc-tool.html + + - the JDK Api documentation https://docs.oracle.com/en/java/javase/11/ + + - some best practices + + Checkstyle is very configurable. Be sure to read the documentation at + https://checkstyle.org (or in your downloaded distribution). + + Most Checks are configurable, be sure to consult the documentation. + + To completely disable a check, just comment it out or delete it from the file. + To suppress certain violations please review suppression filters. + + Finally, it is worth reading the documentation. + +--> + +<module name="Checker"> + <!-- + If you set the basedir property below, then all reported file + names will be relative to the specified directory. See + https://checkstyle.org/config.html#Checker + + <property name="basedir" value="${basedir}"/> + --> + <property name="severity" value="error"/> + + <property name="fileExtensions" value="java, properties, xml"/> + + <!-- Excludes all 'module-info.java' files --> + <!-- See https://checkstyle.org/filefilters/index.html --> + <module name="BeforeExecutionExclusionFileFilter"> + <property name="fileNamePattern" value="module\-info\.java$"/> + </module> + + <!-- https://checkstyle.org/filters/suppressionfilter.html --> + <module name="SuppressionFilter"> + <property name="file" value="${org.checkstyle.sun.suppressionfilter.config}" + default="checkstyle-suppressions.xml" /> + <property name="optional" value="true"/> + </module> + + <!-- Checks that a package-info.java file exists for each package. --> + <!-- See https://checkstyle.org/checks/javadoc/javadocpackage.html#JavadocPackage --> + <!-- TODO <module name="JavadocPackage"/> --> + + <!-- Checks whether files end with a new line. --> + <!-- See https://checkstyle.org/checks/misc/newlineatendoffile.html --> + <module name="NewlineAtEndOfFile"/> + + <!-- Checks that property files contain the same keys. --> + <!-- See https://checkstyle.org/checks/misc/translation.html --> + <module name="Translation"/> + + <!-- Checks for Size Violations. --> + <!-- See https://checkstyle.org/checks/sizes/index.html --> + <!-- TODO <module name="FileLength"/> --> + <!-- TODO <module name="LineLength"> + <property name="fileExtensions" value="java"/> + </module> --> + + <!-- Checks for whitespace --> + <!-- See https://checkstyle.org/checks/whitespace/index.html --> + <!-- TODO <module name="FileTabCharacter"/> --> + + <!-- Miscellaneous other checks. --> + <!-- See https://checkstyle.org/checks/misc/index.html --> + <module name="RegexpSingleline"> + <property name="format" value="\s+$"/> + <property name="minimum" value="0"/> + <property name="maximum" value="0"/> + <property name="message" value="Line has trailing spaces."/> + </module> + + <!-- Checks for Headers --> + <!-- See https://checkstyle.org/checks/header/index.html --> + <!-- <module name="Header"> --> + <!-- <property name="headerFile" value="${checkstyle.header.file}"/> --> + <!-- <property name="fileExtensions" value="java"/> --> + <!-- </module> --> + + <module name="TreeWalker"> + + <!-- Checks for Javadoc comments. --> + <!-- See https://checkstyle.org/checks/javadoc/index.html --> + <!-- TODO <module name="InvalidJavadocPosition"/> --> + <!-- TODO <module name="JavadocMethod"/> --> + <!-- TODO <module name="JavadocType"/> --> + <!-- TODO <module name="JavadocVariable"/> --> + <!-- TODO <module name="JavadocStyle"/> --> + <!-- TODO <module name="MissingJavadocMethod"/> --> + + <!-- Checks for Naming Conventions. --> + <!-- See https://checkstyle.org/checks/naming/index.html --> + <module name="ConstantName"/> + <module name="LocalFinalVariableName"/> + <module name="LocalVariableName"/> + <module name="MemberName"/> + <module name="MethodName"/> + <module name="PackageName"/> + <module name="ParameterName"/> + <module name="StaticVariableName"/> + <!-- TODO <module name="TypeName"/> --> + + <!-- Checks for imports --> + <!-- See https://checkstyle.org/checks/imports/index.html --> + <module name="AvoidStarImport"/> + <module name="IllegalImport"/> <!-- defaults to sun.* packages --> + <module name="RedundantImport"/> + <module name="UnusedImports"> + <property name="processJavadoc" value="false"/> + </module> + + <!-- Checks for Size Violations. --> + <!-- See https://checkstyle.org/checks/sizes/index.html --> + <module name="MethodLength"/> + <module name="ParameterNumber"/> + + <!-- Checks for whitespace --> + <!-- See https://checkstyle.org/checks/whitespace/index.html --> + <module name="EmptyForIteratorPad"/> + <!-- TODO <module name="GenericWhitespace"/> --> + <module name="MethodParamPad"/> + <!-- TODO <module name="NoWhitespaceAfter"/> --> + <module name="NoWhitespaceBefore"/> + <!-- TODO <module name="OperatorWrap"/> --> + <!-- TODO <module name="ParenPad"/> --> + <module name="TypecastParenPad"/> + <module name="WhitespaceAfter"/> + <!-- TODO <module name="WhitespaceAround"/> --> + + <!-- Modifier Checks --> + <!-- See https://checkstyle.org/checks/modifier/index.html --> + <module name="ModifierOrder"/> + <module name="RedundantModifier"/> + + <!-- Checks for blocks. You know, those {}'s --> + <!-- See https://checkstyle.org/checks/blocks/index.html --> + <!-- TODO <module name="AvoidNestedBlocks"/> --> + <!-- TODO <module name="EmptyBlock"/> --> + <!-- TODO <module name="LeftCurly"/> --> + <!-- TODO <module name="NeedBraces"/> --> + <!-- TODO <module name="RightCurly"/> --> + + <!-- Checks for common coding problems --> + <!-- See https://checkstyle.org/checks/coding/index.html --> + <module name="EmptyStatement"/> + <module name="EqualsHashCode"/> + <!-- TODO <module name="HiddenField"/> --> + <module name="IllegalInstantiation"/> + <module name="InnerAssignment"/> + <!-- TODO <module name="MagicNumber"/> --> + <module name="MissingSwitchDefault"/> + <module name="MultipleVariableDeclarations"/> + <module name="SimplifyBooleanExpression"/> + <module name="SimplifyBooleanReturn"/> + + <!-- Checks for class design --> + <!-- See https://checkstyle.org/checks/design/index.html --> + <!-- TODO <module name="DesignForExtension"/> --> + <module name="FinalClass"/> + <module name="HideUtilityClassConstructor"/> + <module name="InterfaceIsType"/> + <!-- TODO <module name="VisibilityModifier"/> --> + + <!-- Miscellaneous other checks. --> + <!-- See https://checkstyle.org/checks/misc/index.html --> + <module name="ArrayTypeStyle"/> + <!-- TODO <module name="FinalParameters"/> --> + <!-- TODO <module name="TodoComment"/> --> + <module name="UpperEll"/> + + <!-- https://checkstyle.org/filters/suppressionxpathfilter.html --> + <module name="SuppressionXpathFilter"> + <property name="file" value="${org.checkstyle.sun.suppressionxpathfilter.config}" + default="checkstyle-xpath-suppressions.xml" /> + <property name="optional" value="true"/> + </module> + + </module> + +</module> diff --git a/pmd-exclude.properties b/pmd-exclude.properties new file mode 100644 index 000000000000..400863992ed0 --- /dev/null +++ b/pmd-exclude.properties @@ -0,0 +1,92 @@ +com.thealgorithms.bitmanipulation.SingleBitOperations=UselessParentheses +com.thealgorithms.ciphers.AffineCipher=UselessParentheses +com.thealgorithms.ciphers.ColumnarTranspositionCipher=UnnecessaryFullyQualifiedName +com.thealgorithms.ciphers.DES=UselessParentheses +com.thealgorithms.ciphers.HillCipher=UselessParentheses +com.thealgorithms.ciphers.RSA=UselessParentheses +com.thealgorithms.conversions.AnyBaseToAnyBase=UselessParentheses +com.thealgorithms.conversions.AnytoAny=UselessParentheses +com.thealgorithms.conversions.HexToOct=UselessParentheses +com.thealgorithms.conversions.IntegerToRoman=UnnecessaryFullyQualifiedName +com.thealgorithms.datastructures.crdt.LWWElementSet=UselessParentheses +com.thealgorithms.datastructures.crdt.Pair=UnusedPrivateField +com.thealgorithms.datastructures.graphs.A_Star=UselessParentheses +com.thealgorithms.datastructures.graphs.AdjacencyMatrixGraph=CollapsibleIfStatements,UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.datastructures.graphs.BipartiteGrapfDFS=CollapsibleIfStatements +com.thealgorithms.datastructures.graphs.Kruskal=UselessParentheses +com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing=UselessParentheses +com.thealgorithms.datastructures.heaps.FibonacciHeap=UselessParentheses +com.thealgorithms.datastructures.heaps.HeapElement=UselessParentheses +com.thealgorithms.datastructures.heaps.HeapNode=UselessParentheses +com.thealgorithms.datastructures.lists.DoublyLinkedList=UselessParentheses +com.thealgorithms.datastructures.lists.SearchSinglyLinkedListRecursion=UselessParentheses +com.thealgorithms.datastructures.lists.SinglyLinkedList=UnusedLocalVariable +com.thealgorithms.datastructures.queues.PriorityQueue=UselessParentheses +com.thealgorithms.datastructures.stacks.NodeStack=UnnecessaryFullyQualifiedName,UnusedFormalParameter +com.thealgorithms.datastructures.stacks.StackArray=UselessParentheses +com.thealgorithms.datastructures.trees.CheckBinaryTreeIsValidBST=UselessParentheses +com.thealgorithms.datastructures.trees.SegmentTree=UselessParentheses +com.thealgorithms.devutils.nodes.LargeTreeNode=UselessParentheses +com.thealgorithms.devutils.nodes.SimpleNode=UselessParentheses +com.thealgorithms.devutils.nodes.SimpleTreeNode=UselessParentheses +com.thealgorithms.devutils.nodes.TreeNode=UselessParentheses +com.thealgorithms.divideandconquer.ClosestPair=UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.divideandconquer.Point=UselessParentheses +com.thealgorithms.dynamicprogramming.MatrixChainMultiplication=UselessParentheses +com.thealgorithms.dynamicprogramming.ShortestSuperSequence=UselessParentheses +com.thealgorithms.dynamicprogramming.UniquePaths=UnnecessarySemicolon +com.thealgorithms.dynamicprogramming.WineProblem=UselessParentheses +com.thealgorithms.maths.BinomialCoefficient=UselessParentheses +com.thealgorithms.maths.Complex=UselessParentheses +com.thealgorithms.maths.DistanceFormulaTest=UnnecessaryFullyQualifiedName +com.thealgorithms.maths.FibonacciJavaStreamsTest=BigIntegerInstantiation +com.thealgorithms.maths.Gaussian=UselessParentheses +com.thealgorithms.maths.GcdSolutionWrapper=UselessParentheses +com.thealgorithms.maths.HeronsFormula=UselessParentheses +com.thealgorithms.maths.KaprekarNumbers=UselessParentheses +com.thealgorithms.maths.KeithNumber=UselessParentheses +com.thealgorithms.maths.LeonardoNumber=UselessParentheses +com.thealgorithms.maths.LinearDiophantineEquationsSolver=UselessParentheses +com.thealgorithms.maths.MatrixUtil=BigIntegerInstantiation,UselessParentheses +com.thealgorithms.maths.RomanNumeralUtil=UselessParentheses +com.thealgorithms.maths.SecondMinMax=UselessParentheses +com.thealgorithms.maths.SecondMinMaxTest=UnnecessaryFullyQualifiedName +com.thealgorithms.maths.StandardDeviation=UselessParentheses +com.thealgorithms.maths.SumOfArithmeticSeries=UselessParentheses +com.thealgorithms.maths.TrinomialTriangle=UselessParentheses +com.thealgorithms.maths.VampireNumber=CollapsibleIfStatements +com.thealgorithms.maths.Volume=UselessParentheses +com.thealgorithms.matrixexponentiation.Fibonacci=UnnecessaryFullyQualifiedName +com.thealgorithms.misc.Sparsity=UselessParentheses +com.thealgorithms.misc.ThreeSumProblem=UselessParentheses +com.thealgorithms.misc.WordBoggle=UselessParentheses +com.thealgorithms.others.CRC16=UselessParentheses +com.thealgorithms.others.Damm=UnnecessaryFullyQualifiedName +com.thealgorithms.others.Luhn=UnnecessaryFullyQualifiedName +com.thealgorithms.others.Mandelbrot=UselessParentheses +com.thealgorithms.others.MaximumSumOfDistinctSubarraysWithLengthK=CollapsibleIfStatements +com.thealgorithms.others.MiniMaxAlgorithm=UselessParentheses +com.thealgorithms.others.PageRank=UselessParentheses +com.thealgorithms.others.PerlinNoise=UselessParentheses +com.thealgorithms.others.QueueUsingTwoStacks=UselessParentheses +com.thealgorithms.others.QueueWithStack=UselessParentheses +com.thealgorithms.others.Trieac=UselessParentheses +com.thealgorithms.others.Verhoeff=UnnecessaryFullyQualifiedName +com.thealgorithms.searches.InterpolationSearch=UselessParentheses +com.thealgorithms.searches.KMPSearch=UselessParentheses +com.thealgorithms.searches.LinearSearchThread=EmptyCatchBlock +com.thealgorithms.searches.RabinKarpAlgorithm=UselessParentheses +com.thealgorithms.sorts.BubbleSortRecursion=UselessParentheses +com.thealgorithms.sorts.CircleSort=EmptyControlStatement +com.thealgorithms.sorts.CombSort=UselessParentheses +com.thealgorithms.sorts.DutchNationalFlagSort=UselessParentheses +com.thealgorithms.sorts.LinkListSort=EmptyControlStatement,UnusedLocalVariable +com.thealgorithms.sorts.MergeSortNoExtraSpace=UselessParentheses +com.thealgorithms.sorts.PigeonholeSort=UselessParentheses +com.thealgorithms.sorts.RadixSort=UselessParentheses +com.thealgorithms.sorts.WiggleSort=UselessParentheses +com.thealgorithms.stacks.PostfixToInfix=UselessParentheses +com.thealgorithms.strings.HorspoolSearch=UnnecessaryFullyQualifiedName,UselessParentheses +com.thealgorithms.strings.MyAtoi=UselessParentheses +com.thealgorithms.strings.Palindrome=UselessParentheses +com.thealgorithms.strings.Solution=CollapsibleIfStatements diff --git a/pom.xml b/pom.xml index 86922e1f0a98..b8fb946eeb5a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,9 +10,9 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.source>17</maven.compiler.source> - <maven.compiler.target>17</maven.compiler.target> - <assertj.version>3.23.1</assertj.version> + <maven.compiler.source>21</maven.compiler.source> + <maven.compiler.target>21</maven.compiler.target> + <assertj.version>3.26.0</assertj.version> </properties> <dependencyManagement> @@ -20,7 +20,7 @@ <dependency> <groupId>org.junit</groupId> <artifactId>junit-bom</artifactId> - <version>5.8.2</version> + <version>5.10.2</version> <type>pom</type> <scope>import</scope> </dependency> @@ -31,7 +31,7 @@ <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> - <version>5.9.0</version> + <version>5.10.2</version> <scope>test</scope> </dependency> <dependency> @@ -44,18 +44,18 @@ <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> - <version>5.9.0</version> + <version>5.10.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> - <version>3.12.0</version> + <version>3.14.0</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> - <version>4.4</version> + <version>4.5.0-M1</version> </dependency> </dependencies> @@ -63,17 +63,97 @@ <plugins> <plugin> <artifactId>maven-surefire-plugin</artifactId> - <version>2.22.2</version> + <version>3.2.5</version> + <configuration> + <forkNode implementation="org.apache.maven.plugin.surefire.extensions.SurefireForkNodeFactory"/> + </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> - <version>3.10.1</version> + <version>3.13.0</version> + <configuration> + <source>21</source> + <target>21</target> + <compilerArgs> + <arg>-Xlint:all</arg> + <arg>-Xlint:-auxiliaryclass</arg> + <arg>-Xlint:-rawtypes</arg> + <arg>-Xlint:-unchecked</arg> + <arg>-Xlint:-lossy-conversions</arg> + <arg>-Werror</arg> + </compilerArgs> + </configuration> + </plugin> + <plugin> + <groupId>org.jacoco</groupId> + <artifactId>jacoco-maven-plugin</artifactId> + <version>0.8.12</version> + <executions> + <execution> + <goals> + <goal>prepare-agent</goal> + </goals> + </execution> + <execution> + <id>generate-code-coverage-report</id> + <phase>test</phase> + <goals> + <goal>report</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <version>3.3.1</version> + <configuration> + <configLocation>checkstyle.xml</configLocation> + <consoleOutput>true</consoleOutput> + <includeTestSourceDirectory>true</includeTestSourceDirectory> + <violationSeverity>warning</violationSeverity> + </configuration> + <dependencies> + <dependency> + <groupId>com.puppycrawl.tools</groupId> + <artifactId>checkstyle</artifactId> + <version>10.17.0</version> + </dependency> + </dependencies> + </plugin> + <plugin> + <groupId>com.github.spotbugs</groupId> + <artifactId>spotbugs-maven-plugin</artifactId> + <version>4.8.5.0</version> + <configuration> + <excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile> + <includeTests>true</includeTests> + <plugins> + <plugin> + <groupId>com.mebigfatguy.fb-contrib</groupId> + <artifactId>fb-contrib</artifactId> + <version>7.6.4</version> + </plugin> + <plugin> + <groupId>com.h3xstream.findsecbugs</groupId> + <artifactId>findsecbugs-plugin</artifactId> + <version>1.13.0</version> + </plugin> + </plugins> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-pmd-plugin</artifactId> + <version>3.22.0</version> <configuration> - <source>17</source> - <target>17</target> + <printFailingErrors>true</printFailingErrors> + <includeTests>true</includeTests> + <linkXRef>false</linkXRef> + <excludeFromFailureFile>pmd-exclude.properties</excludeFromFailureFile> </configuration> </plugin> </plugins> </build> -</project> \ No newline at end of file +</project> diff --git a/spotbugs-exclude.xml b/spotbugs-exclude.xml new file mode 100644 index 000000000000..f621c84dd4bf --- /dev/null +++ b/spotbugs-exclude.xml @@ -0,0 +1,250 @@ +<FindBugsFilter> + <Match> + <Bug pattern="DM_DEFAULT_ENCODING" /> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP2" /> + </Match> + <Match> + <Bug pattern="DMI_RANDOM_USED_ONLY_ONCE" /> + </Match> + <Match> + <Bug pattern="SF_SWITCH_NO_DEFAULT" /> + </Match> + <Match> + <Bug pattern="RV_RETURN_VALUE_IGNORED_NO_SIDE_EFFECT" /> + </Match> + <Match> + <Bug pattern="DM_NEXTINT_VIA_NEXTDOUBLE" /> + </Match> + <Match> + <Bug pattern="NM_CLASS_NAMING_CONVENTION" /> + </Match> + <Match> + <Bug pattern="SIC_INNER_SHOULD_BE_STATIC" /> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP" /> + </Match> + <Match> + <Bug pattern="EI_EXPOSE_REP" /> + </Match> + <Match> + <Bug pattern="SBSC_USE_STRINGBUFFER_CONCATENATION" /> + </Match> + <Match> + <Bug pattern="PA_PUBLIC_PRIMITIVE_ATTRIBUTE" /> + </Match> + <Match> + <Bug pattern="MS_PKGPROTECT" /> + </Match> + <Match> + <Bug pattern="SE_COMPARATOR_SHOULD_BE_SERIALIZABLE" /> + </Match> + <Match> + <Bug pattern="INT_BAD_REM_BY_1" /> + </Match> + <Match> + <Bug pattern="NM_METHOD_NAMING_CONVENTION" /> + </Match> + <Match> + <Bug pattern="ICAST_IDIV_CAST_TO_DOUBLE" /> + </Match> + <Match> + <Bug pattern="FE_FLOATING_POINT_EQUALITY" /> + </Match> + <Match> + <Bug pattern="CT_CONSTRUCTOR_THROW" /> + </Match> + <Match> + <Bug pattern="URF_UNREAD_FIELD" /> + </Match> + <Match> + <Bug pattern="RC_REF_COMPARISON" /> + </Match> + <Match> + <Bug pattern="MS_EXPOSE_REP" /> + </Match> + <Match> + <Bug pattern="IM_BAD_CHECK_FOR_ODD" /> + </Match> + <Match> + <Bug pattern="WMI_WRONG_MAP_ITERATOR" /> + </Match> + <Match> + <Bug pattern="DM_BOXED_PRIMITIVE_FOR_PARSING" /> + </Match> + <Match> + <Bug pattern="UWF_UNWRITTEN_FIELD" /> + </Match> + <Match> + <Bug pattern="DLS_DEAD_LOCAL_STORE" /> + </Match> + <Match> + <Bug pattern="UWF_NULL_FIELD" /> + </Match> + <Match> + <Bug pattern="NP_UNWRITTEN_FIELD" /> + </Match> + <Match> + <Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" /> + </Match> + <Match> + <Bug pattern="NP_IMMEDIATE_DEREFERENCE_OF_READLINE" /> + </Match> + <Match> + <Bug pattern="EQ_COMPARETO_USE_OBJECT_EQUALS" /> + </Match> + <Match> + <Bug pattern="SA_FIELD_SELF_ASSIGNMENT" /> + </Match> + <Match> + <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" /> + </Match> + <Match> + <Bug pattern="RV_ABSOLUTE_VALUE_OF_HASHCODE" /> + </Match> + <!-- fb-contrib --> + <Match> + <Bug pattern="OCP_OVERLY_CONCRETE_PARAMETER" /> + </Match> + <Match> + <Bug pattern="LSC_LITERAL_STRING_COMPARISON" /> + </Match> + <Match> + <Bug pattern="CE_CLASS_ENVY" /> + </Match> + <Match> + <Bug pattern="PSC_PRESIZE_COLLECTIONS" /> + </Match> + <Match> + <Bug pattern="SACM_STATIC_ARRAY_CREATED_IN_METHOD" /> + </Match> + <Match> + <Bug pattern="LUI_USE_SINGLETON_LIST" /> + </Match> + <Match> + <Bug pattern="CLI_CONSTANT_LIST_INDEX" /> + </Match> + <Match> + <Bug pattern="BED_BOGUS_EXCEPTION_DECLARATION" /> + </Match> + <Match> + <Bug pattern="CNC_COLLECTION_NAMING_CONFUSION" /> + </Match> + <Match> + <Bug pattern="TR_TAIL_RECURSION" /> + </Match> + <Match> + <Bug pattern="USBR_UNNECESSARY_STORE_BEFORE_RETURN" /> + </Match> + <Match> + <Bug pattern="SPP_USE_ISEMPTY" /> + </Match> + <Match> + <Bug pattern="BL_BURYING_LOGIC" /> + </Match> + <Match> + <Bug pattern="OI_OPTIONAL_ISSUES_USES_IMMEDIATE_EXECUTION" /> + </Match> + <Match> + <Bug pattern="PCOA_PARTIALLY_CONSTRUCTED_OBJECT_ACCESS" /> + </Match> + <Match> + <Bug pattern="UTWR_USE_TRY_WITH_RESOURCES" /> + </Match> + <Match> + <Bug pattern="MUI_CONTAINSKEY_BEFORE_GET" /> + </Match> + <Match> + <Bug pattern="IMC_IMMATURE_CLASS_PRINTSTACKTRACE" /> + </Match> + <Match> + <Bug pattern="UCPM_USE_CHARACTER_PARAMETERIZED_METHOD" /> + </Match> + <Match> + <Bug pattern="SUA_SUSPICIOUS_UNINITIALIZED_ARRAY" /> + </Match> + <Match> + <Bug pattern="SPP_USE_MATH_CONSTANT" /> + </Match> + <Match> + <Bug pattern="UJM_UNJITABLE_METHOD" /> + </Match> + <Match> + <Bug pattern="SEC_SIDE_EFFECT_CONSTRUCTOR" /> + </Match> + <Match> + <Bug pattern="MDM_STRING_BYTES_ENCODING" /> + </Match> + <Match> + <Bug pattern="PMB_POSSIBLE_MEMORY_BLOAT" /> + </Match> + <Match> + <Bug pattern="LSYC_LOCAL_SYNCHRONIZED_COLLECTION" /> + </Match> + <Match> + <Bug pattern="IOI_USE_OF_FILE_STREAM_CONSTRUCTORS" /> + </Match> + <Match> + <Bug pattern="UP_UNUSED_PARAMETER" /> + </Match> + <Match> + <Bug pattern="DSOC_DUBIOUS_SET_OF_COLLECTIONS" /> + </Match> + <Match> + <Bug pattern="NAB_NEEDLESS_BOX_TO_UNBOX" /> + </Match> + <Match> + <Bug pattern="FPL_FLOATING_POINT_LOOPS" /> + </Match> + <Match> + <Bug pattern="ITU_INAPPROPRIATE_TOSTRING_USE" /> + </Match> + <Match> + <Bug pattern="DMC_DUBIOUS_MAP_COLLECTION" /> + </Match> + <Match> + <Bug pattern="SPP_PASSING_THIS_AS_PARM" /> + </Match> + <Match> + <Bug pattern="FCBL_FIELD_COULD_BE_LOCAL" /> + </Match> + <Match> + <Bug pattern="CFS_CONFUSING_FUNCTION_SEMANTICS" /> + </Match> + <Match> + <Bug pattern="PRMC_POSSIBLY_REDUNDANT_METHOD_CALLS" /> + </Match> + <Match> + <Bug pattern="FCCD_FIND_CLASS_CIRCULAR_DEPENDENCY" /> + </Match> + <Match> + <Bug pattern="PL_PARALLEL_LISTS" /> + </Match> + <Match> + <Bug pattern="PCAIL_POSSIBLE_CONSTANT_ALLOCATION_IN_LOOP" /> + </Match> + <Match> + <Bug pattern="STT_STRING_PARSING_A_FIELD" /> + </Match> + <Match> + <Bug pattern="IMC_IMMATURE_CLASS_BAD_SERIALVERSIONUID" /> + </Match> + <Match> + <Bug pattern="SUI_CONTAINS_BEFORE_ADD" /> + </Match> + <Match> + <Bug pattern="DRE_DECLARED_RUNTIME_EXCEPTION" /> + </Match> + <Match> + <Bug pattern="SLS_SUSPICIOUS_LOOP_SEARCH" /> + </Match> + <!-- find-sec-bugs --> + <Match> + <Bug pattern="PREDICTABLE_RANDOM" /> + </Match> + <Match> + <Bug pattern="HARD_CODE_KEY" /> + </Match> +</FindBugsFilter> diff --git a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java index 71bf012d2835..dd43ab780bed 100644 --- a/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java +++ b/src/main/java/com/thealgorithms/backtracking/AllPathsFromSourceToTarget.java @@ -3,24 +3,32 @@ * Github : https://github.com/siddhant2002 */ -/** Program description - To find all possible paths from source to destination*/ - -/**Wikipedia link -> https://en.wikipedia.org/wiki/Shortest_path_problem */ +/** Program description - To find all possible paths from source to destination */ +/** Wikipedia link -> https://en.wikipedia.org/wiki/Shortest_path_problem */ package com.thealgorithms.backtracking; -import java.util.*; +import java.util.ArrayList; +import java.util.List; + public class AllPathsFromSourceToTarget { - // No. of vertices in graph + /** + * Common variables to "AllPathsFromSourceToTarget" class. + * + * 1) Number of vertices in graph. + * 2) List to store the paths from source to destiny. + * 3) Adjacency list. + */ private final int v; - - // To store the paths from source to destination static List<List<Integer>> nm = new ArrayList<>(); - // adjacency list private ArrayList<Integer>[] adjList; - // Constructor + /** + * Constructor. + * @param vertices Number of vertices. + */ + public AllPathsFromSourceToTarget(int vertices) { // initialise vertex count @@ -30,7 +38,10 @@ public AllPathsFromSourceToTarget(int vertices) { initAdjList(); } - // utility method to initialise adjacency list + /** + * Creates an ArrayList for each position in adjList. + */ + private void initAdjList() { adjList = new ArrayList[v]; @@ -39,37 +50,56 @@ private void initAdjList() { } } - // add edge from u to v + /** + * Add edge from u to v + * + * @param u Value to select list. + * @param v Value to introduce. + */ + public void addEdge(int u, int v) { - // Add v to u's list. adjList[u].add(v); } + /** + * + * @param s Value of source + * @param d Value of destiny. + */ + public void storeAllPaths(int s, int d) { + // Array composed by boolean´s objects with v like lenght boolean[] isVisited = new boolean[v]; + // This ArrayList stores the track. ArrayList<Integer> pathList = new ArrayList<>(); - // add source to path[] pathList.add(s); - // Call recursive utility + // Call recursive function utility. storeAllPathsUtil(s, d, isVisited, pathList); } - // A recursive function to print all paths from 'u' to 'd'. - // isVisited[] keeps track of vertices in current path. - // localPathList<> stores actual vertices in the current path + /** + * + * Function to StoreAllPaths + * + * @param u Value of source + * @param d Value of destiny + * @param isVisited array to keeps track of vertices in current path. + * @param localPathList stores actual vertices in the current path + */ + private void storeAllPathsUtil(Integer u, Integer d, boolean[] isVisited, List<Integer> localPathList) { + //If node u is equals to d the path has benn completly found it. if (u.equals(d)) { nm.add(new ArrayList<>(localPathList)); return; } - // Mark the current node + // Mark the current node as visited. isVisited[u] = true; // Recursion for all the vertices adjacent to current vertex - for (Integer i : adjList[u]) { if (!isVisited[i]) { // store current node in path[] @@ -81,21 +111,33 @@ private void storeAllPathsUtil(Integer u, Integer d, boolean[] isVisited, List<I } } - // Mark the current node + // Mark the current node as false to release it and be used by others. isVisited[u] = false; } - // Driver program + /** + * + * Driver program + * + * @param vertices number of vertices of the graph + * @param a represents the aristas of the graph. + * @param source value of source. + * @param destination value of destiny. + * @return A List composed by diferent lists that stores all the possible paths to the destiny. + */ + public static List<List<Integer>> allPathsFromSourceToTarget(int vertices, int[][] a, int source, int destination) { // Create a sample graph AllPathsFromSourceToTarget g = new AllPathsFromSourceToTarget(vertices); + + // edges are added for (int[] i : a) { g.addEdge(i[0], i[1]); - // edges are added } - g.storeAllPaths(source, destination); + // method call to store all possible paths + g.storeAllPaths(source, destination); + return nm; - // returns all possible paths from source to destination } } diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java index ed5a0c933226..a0b886e6be8a 100644 --- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java +++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java @@ -1,12 +1,15 @@ package com.thealgorithms.backtracking; -import java.util.*; +import java.util.List; +import java.util.TreeSet; /** * Finds all permutations of 1...n of length k * @author TheClerici (<a href="https://github.com/TheClerici">git-TheClerici</a>) */ -public class ArrayCombination { +public final class ArrayCombination { + private ArrayCombination() { + } private static int length; /** diff --git a/src/main/java/com/thealgorithms/backtracking/Combination.java b/src/main/java/com/thealgorithms/backtracking/Combination.java index 4b44a46d8595..80c11ce737fa 100644 --- a/src/main/java/com/thealgorithms/backtracking/Combination.java +++ b/src/main/java/com/thealgorithms/backtracking/Combination.java @@ -1,12 +1,17 @@ package com.thealgorithms.backtracking; -import java.util.*; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.TreeSet; /** * Finds all permutations of given array * @author Alan Piao (<a href="https://github.com/cpiao3">git-Alan Piao</a>) */ -public class Combination { +public final class Combination { + private Combination() { + } private static int length; diff --git a/src/main/java/com/thealgorithms/backtracking/KnightsTour.java b/src/main/java/com/thealgorithms/backtracking/KnightsTour.java index 27b7f66c1f63..2287b39da385 100644 --- a/src/main/java/com/thealgorithms/backtracking/KnightsTour.java +++ b/src/main/java/com/thealgorithms/backtracking/KnightsTour.java @@ -1,6 +1,8 @@ package com.thealgorithms.backtracking; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; /* * Problem Statement: - @@ -24,10 +26,12 @@ 51 46 55 44 53 4 21 12 */ -public class KnightsTour { +public final class KnightsTour { + private KnightsTour() { + } - private static final int base = 12; - private static final int[][] moves = { + private static final int BASE = 12; + private static final int[][] MOVES = { {1, -2}, {2, -1}, {2, 1}, @@ -41,19 +45,19 @@ public class KnightsTour { private static int total; // total squares in chess public static void main(String[] args) { - grid = new int[base][base]; - total = (base - 4) * (base - 4); + 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)); + int row = 2 + (int) (Math.random() * (BASE - 4)); + int col = 2 + (int) (Math.random() * (BASE - 4)); grid[row][col] = 1; @@ -95,7 +99,7 @@ private static boolean solve(int row, int column, int count) { private static List<int[]> neighbors(int row, int column) { List<int[]> neighbour = new ArrayList<>(); - for (int[] m : moves) { + for (int[] m : MOVES) { int x = m[0]; int y = m[1]; if (grid[row + y][column + x] == 0) { @@ -109,7 +113,7 @@ private static List<int[]> 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) { + for (int[] m : MOVES) { if (grid[row + m[1]][column + m[0]] == 0) { num++; } diff --git a/src/main/java/com/thealgorithms/backtracking/MColoring.java b/src/main/java/com/thealgorithms/backtracking/MColoring.java index 93b17941566a..20c42e59e8a1 100644 --- a/src/main/java/com/thealgorithms/backtracking/MColoring.java +++ b/src/main/java/com/thealgorithms/backtracking/MColoring.java @@ -1,6 +1,10 @@ package com.thealgorithms.backtracking; -import java.util.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Queue; +import java.util.Set; /** * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) @@ -10,7 +14,9 @@ class Node { Set<Integer> edges = new HashSet<Integer>(); } -public class MColoring { +public final class MColoring { + private MColoring() { + } static int possiblePaint(ArrayList<Node> nodes, int n, int m) { // Create a visited array of n nodes diff --git a/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java b/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java index 23fc0689fd57..f7eae01e449a 100644 --- a/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java +++ b/src/main/java/com/thealgorithms/backtracking/MazeRecursion.java @@ -1,6 +1,8 @@ package com.thealgorithms.backtracking; -public class MazeRecursion { +public final class MazeRecursion { + private MazeRecursion() { + } public static void mazeRecursion() { // First create a 2 dimensions array to mimic a maze map diff --git a/src/main/java/com/thealgorithms/backtracking/NQueens.java b/src/main/java/com/thealgorithms/backtracking/NQueens.java index e40b82915cc9..e21a8bb7174c 100644 --- a/src/main/java/com/thealgorithms/backtracking/NQueens.java +++ b/src/main/java/com/thealgorithms/backtracking/NQueens.java @@ -32,7 +32,9 @@ * queen is not placed safely. If there is no such way then return an empty list * as solution */ -public class NQueens { +public final class NQueens { + private NQueens() { + } public static void main(String[] args) { placeQueens(1); diff --git a/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java b/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java new file mode 100644 index 000000000000..8bbed4106251 --- /dev/null +++ b/src/main/java/com/thealgorithms/backtracking/ParenthesesGenerator.java @@ -0,0 +1,50 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class generates all valid combinations of parentheses for a given number of pairs using backtracking. + */ +public final class ParenthesesGenerator { + private ParenthesesGenerator() { + } + + /** + * Generates all valid combinations of parentheses for a given number of pairs. + * + * @param n The number of pairs of parentheses. + * @return A list of strings representing valid combinations of parentheses. + * @throws IllegalArgumentException if n is less than 0. + */ + public static List<String> generateParentheses(final int n) { + if (n < 0) { + throw new IllegalArgumentException("The number of pairs of parentheses cannot be nagative"); + } + List<String> result = new ArrayList<>(); + generateParenthesesHelper(result, "", 0, 0, n); + return result; + } + + /** + * Helper function for generating all valid combinations of parentheses recursively. + * + * @param result The list to store valid combinations. + * @param current The current combination being formed. + * @param open The number of open parentheses. + * @param close The number of closed parentheses. + * @param n The total number of pairs of parentheses. + */ + private static void generateParenthesesHelper(List<String> result, final String current, final int open, final int close, final int n) { + if (current.length() == n * 2) { + result.add(current); + return; + } + if (open < n) { + generateParenthesesHelper(result, current + "(", open + 1, close, n); + } + if (close < open) { + generateParenthesesHelper(result, current + ")", open, close + 1, n); + } + } +} diff --git a/src/main/java/com/thealgorithms/backtracking/Permutation.java b/src/main/java/com/thealgorithms/backtracking/Permutation.java index 5d88c846087e..21d26e53980f 100644 --- a/src/main/java/com/thealgorithms/backtracking/Permutation.java +++ b/src/main/java/com/thealgorithms/backtracking/Permutation.java @@ -7,7 +7,9 @@ * Finds all permutations of given array * @author Alan Piao (<a href="https://github.com/cpiao3">Git-Alan Piao</a>) */ -public class Permutation { +public final class Permutation { + private Permutation() { + } /** * Find all permutations of given array using backtracking diff --git a/src/main/java/com/thealgorithms/backtracking/PowerSum.java b/src/main/java/com/thealgorithms/backtracking/PowerSum.java index 72af17d48bd4..6617ea326a1c 100644 --- a/src/main/java/com/thealgorithms/backtracking/PowerSum.java +++ b/src/main/java/com/thealgorithms/backtracking/PowerSum.java @@ -8,32 +8,33 @@ */ public class PowerSum { - private int count = 0, sum = 0; + private int count = 0; + private int sum = 0; - public int powSum(int N, int X) { - Sum(N, X, 1); + 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) { + 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) { + 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); + 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); + sum -= power(i, x); } - if (power(i, X) < N) { + 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); + sum(n, x, i + 1); } } diff --git a/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java b/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java new file mode 100644 index 000000000000..4a159dbfe0b1 --- /dev/null +++ b/src/main/java/com/thealgorithms/backtracking/SubsequenceFinder.java @@ -0,0 +1,54 @@ +package com.thealgorithms.backtracking; + +import java.util.ArrayList; +import java.util.List; + +/** + * Class generates all subsequences for a given list of elements using backtracking + */ +public final class SubsequenceFinder { + private SubsequenceFinder() { + } + + /** + * Find all subsequences of given list using backtracking + * + * @param sequence a list of items on the basis of which we need to generate all subsequences + * @param <T> the type of elements in the array + * @return a list of all subsequences + */ + public static <T> List<List<T>> generateAll(List<T> sequence) { + List<List<T>> allSubSequences = new ArrayList<>(); + if (sequence.isEmpty()) { + allSubSequences.add(new ArrayList<>()); + return allSubSequences; + } + List<T> currentSubsequence = new ArrayList<>(); + backtrack(sequence, currentSubsequence, 0, allSubSequences); + return allSubSequences; + } + + /** + * Iterate through each branch of states + * We know that each state has exactly two branching + * It terminates when it reaches the end of the given sequence + * + * @param sequence all elements + * @param currentSubsequence current subsequence + * @param index current index + * @param allSubSequences contains all sequences + * @param <T> the type of elements which we generate + */ + private static <T> void backtrack(List<T> sequence, List<T> currentSubsequence, final int index, List<List<T>> allSubSequences) { + assert index <= sequence.size(); + if (index == sequence.size()) { + allSubSequences.add(new ArrayList<>(currentSubsequence)); + return; + } + + backtrack(sequence, currentSubsequence, index + 1, allSubSequences); + currentSubsequence.add(sequence.get(index)); + backtrack(sequence, currentSubsequence, index + 1, allSubSequences); + currentSubsequence.removeLast(); + } +} diff --git a/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java index 398b6bbb67bb..6b53b1aa182b 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/HighestSetBit.java @@ -12,7 +12,7 @@ public final class HighestSetBit { private HighestSetBit() { } - public final static Optional<Integer> findHighestSetBit(int num) { + public static Optional<Integer> findHighestSetBit(int num) { if (num < 0) { throw new IllegalArgumentException("Input cannot be negative"); } diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java b/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java index dc8a217875f9..b825916a8674 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBit.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -public class IndexOfRightMostSetBit { +public final class IndexOfRightMostSetBit { + private IndexOfRightMostSetBit() { + } public static int indexOfRightMostSetBit(int n) { if (n == 0) { return -1; // No set bits diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java b/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java index b6bdc25fcc2b..09d5383322ff 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/IsEven.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -public class IsEven { +public final class IsEven { + private IsEven() { + } public static boolean isEven(int number) { return (number & 1) == 0; } diff --git a/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java b/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java index d379cb3f0593..54d28d4d22cc 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/IsPowerTwo.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -public class IsPowerTwo { +public final class IsPowerTwo { + private IsPowerTwo() { + } public static boolean isPowerTwo(int number) { if (number <= 0) { return false; diff --git a/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java b/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java index bd4bdb0becae..07476a8b9476 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinder.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -public class NonRepeatingNumberFinder { +public final class NonRepeatingNumberFinder { + private NonRepeatingNumberFinder() { + } public static int findNonRepeatingNumber(int[] arr) { int result = 0; diff --git a/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java b/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java index ed586296776f..8e0946f0eb23 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/NumbersDifferentSigns.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi */ -public class NumbersDifferentSigns { +public final class NumbersDifferentSigns { + private NumbersDifferentSigns() { + } public static boolean differentSigns(int num1, int num2) { return (num1 ^ num2) < 0; diff --git a/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java b/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java index e9d1ad61996f..e8f2930d3afe 100644 --- a/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java +++ b/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi */ -public class ReverseBits { +public final class ReverseBits { + private ReverseBits() { + } public static int reverseBits(int n) { int result = 0; diff --git a/src/main/java/com/thealgorithms/ciphers/AES.java b/src/main/java/com/thealgorithms/ciphers/AES.java index e310d7189b2a..cd04395e1b72 100644 --- a/src/main/java/com/thealgorithms/ciphers/AES.java +++ b/src/main/java/com/thealgorithms/ciphers/AES.java @@ -7,7 +7,9 @@ * This class is build to demonstrate the application of the AES-algorithm on a * single 128-Bit block of data. */ -public class AES { +public final class AES { + private AES() { + } /** * Precalculated values for x to the power of 2 in Rijndaels galois field. diff --git a/src/main/java/com/thealgorithms/ciphers/AESEncryption.java b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java index 169fc10e5269..14582205442f 100644 --- a/src/main/java/com/thealgorithms/ciphers/AESEncryption.java +++ b/src/main/java/com/thealgorithms/ciphers/AESEncryption.java @@ -3,7 +3,12 @@ import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; -import javax.crypto.*; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec; /** @@ -12,7 +17,9 @@ * hence in the following program we display it in hexadecimal format of the * underlying bytes. */ -public class AESEncryption { +public final class AESEncryption { + private AESEncryption() { + } private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); private static Cipher aesCipher; diff --git a/src/main/java/com/thealgorithms/ciphers/AffineCipher.java b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java index 9ff63ddfe7c5..bcf3a5b0167b 100644 --- a/src/main/java/com/thealgorithms/ciphers/AffineCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/AffineCipher.java @@ -1,6 +1,8 @@ package com.thealgorithms.ciphers; -class AffineCipher { +final class AffineCipher { + private AffineCipher() { + } // Key values of a and b static int a = 17; @@ -25,7 +27,7 @@ static String encryptMessage(char[] msg) { static String decryptCipher(String cipher) { String msg = ""; - int a_inv = 0; + int aInv = 0; int flag = 0; // Find a^-1 (the multiplicative inverse of a @@ -36,7 +38,7 @@ static String decryptCipher(String cipher) { // Check if (a*i)%26 == 1, // then i will be the multiplicative inverse of a if (flag == 1) { - a_inv = i; + aInv = i; } } for (int i = 0; i < cipher.length(); i++) { @@ -44,7 +46,7 @@ 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) (((aInv * ((cipher.charAt(i) + 'A' - b)) % 26)) + 'A'); } else { // else simply append space character msg += cipher.charAt(i); } diff --git a/src/main/java/com/thealgorithms/ciphers/Blowfish.java b/src/main/java/com/thealgorithms/ciphers/Blowfish.java index fc7c5d04fcb0..a8fa6fc56088 100644 --- a/src/main/java/com/thealgorithms/ciphers/Blowfish.java +++ b/src/main/java/com/thealgorithms/ciphers/Blowfish.java @@ -11,7 +11,7 @@ public class Blowfish { // Initializing substitution boxes - String[][] S = { + String[][] sBox = { { "d1310ba6", "98dfb5ac", @@ -1047,7 +1047,7 @@ public class Blowfish { }; // Initializing subkeys with digits of pi - String[] P = { + String[] subKeys = { "243f6a88", "85a308d3", "13198a2e", @@ -1154,7 +1154,7 @@ private String f(String plainText) { for (int i = 0; i < 8; i += 2) { // column number for S-box is a 8-bit value long col = Long.parseUnsignedLong(hexToBin(plainText.substring(i, i + 2)), 2); - a[i / 2] = S[i / 2][(int) col]; + a[i / 2] = sBox[i / 2][(int) col]; } ans = addBin(a[0], a[1]); ans = xor(ans, a[2]); @@ -1165,9 +1165,9 @@ private String f(String plainText) { // generate subkeys private void keyGenerate(String key) { int j = 0; - for (int i = 0; i < P.length; i++) { + for (int i = 0; i < subKeys.length; i++) { // XOR-ing 32-bit parts of the key with initial subkeys - P[i] = xor(P[i], key.substring(j, j + 8)); + subKeys[i] = xor(subKeys[i], key.substring(j, j + 8)); j = (j + 8) % key.length(); } @@ -1175,10 +1175,11 @@ private void keyGenerate(String key) { // round function private String round(int time, String plainText) { - String left, right; + String left; + String right; left = plainText.substring(0, 8); right = plainText.substring(8, 16); - left = xor(left, P[time]); + left = xor(left, subKeys[time]); // output from F function String fOut = f(left); @@ -1206,8 +1207,8 @@ String encrypt(String plainText, String key) { // postprocessing String right = plainText.substring(0, 8); String left = plainText.substring(8, 16); - right = xor(right, P[16]); - left = xor(left, P[17]); + right = xor(right, subKeys[16]); + left = xor(left, subKeys[17]); return left + right; } @@ -1228,8 +1229,8 @@ String decrypt(String cipherText, String key) { // postprocessing String right = cipherText.substring(0, 8); String left = cipherText.substring(8, 16); - right = xor(right, P[1]); - left = xor(left, P[0]); + right = xor(right, subKeys[1]); + left = xor(left, subKeys[0]); return left + right; } } diff --git a/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java b/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java index 89a0a88654ae..e59cfb12d816 100644 --- a/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/ColumnarTranspositionCipher.java @@ -7,7 +7,9 @@ * * @author <a href="https://github.com/freitzzz">freitzzz</a> */ -public class ColumnarTranspositionCipher { +public final class ColumnarTranspositionCipher { + private ColumnarTranspositionCipher() { + } private static String keyword; private static Object[][] table; diff --git a/src/main/java/com/thealgorithms/ciphers/DES.java b/src/main/java/com/thealgorithms/ciphers/DES.java index 119ad69767e2..7f3eed70f3c2 100644 --- a/src/main/java/com/thealgorithms/ciphers/DES.java +++ b/src/main/java/com/thealgorithms/ciphers/DES.java @@ -8,7 +8,7 @@ public class DES { private String key; - private String subKeys[]; + private final String[] subKeys; private void sanitize(String key) { int length = key.length(); @@ -32,66 +32,68 @@ public void setKey(String key) { this.key = key; } - // Permutation table to convert initial 64 bit key to 56 bit key - private static int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; + // Permutation table to convert initial 64-bit key to 56 bit key + private static final int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; // Lookup table used to shift the initial key, in order to generate the subkeys - private static int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + private static final int[] KEY_SHIFTS = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; // Table to convert the 56 bit subkeys to 48 bit subkeys - private static int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; + private static final int[] PC2 = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; - // Initial permutatation of each 64 but message block - private static int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; + // Initial permutation of each 64 but message block + private static final int[] IP = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; // Expansion table to convert right half of message blocks from 32 bits to 48 bits - private static int[] expansion = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; + private static final int[] EXPANSION = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; // The eight substitution boxes are defined below - private static int[][] s1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}; + private static final int[][] S1 = {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}; - private static int[][] s2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}; + private static final int[][] S2 = {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}; - private static int[][] s3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}; + private static final int[][] S3 = {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}; - private static int[][] s4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}; + private static final int[][] S4 = {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}; - private static int[][] s5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}; + private static final int[][] S5 = {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}; - private static int[][] s6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}; + private static final int[][] S6 = {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}; - private static int[][] s7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}; + private static final int[][] S7 = {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}; - private static int[][] s8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}; + private static final int[][] S8 = {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}; - private static int[][][] s = {s1, s2, s3, s4, s5, s6, s7, s8}; + private static final int[][][] S = {S1, S2, S3, S4, S5, S6, S7, S8}; - // Permutation table, used in the feistel function post s-box usage - static int[] permutation = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; + // Permutation table, used in the Feistel function post s-box usage + static final int[] PERMUTATION = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; // Table used for final inversion of the message box after 16 rounds of Feistel Function - static int[] IPinverse = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; + static final int[] IP_INVERSE = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; private String[] getSubkeys(String originalKey) { - StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via PC1 - int i, j; + StringBuilder permutedKey = new StringBuilder(); // Initial permutation of keys via pc1 + int i; + int j; for (i = 0; i < 56; i++) { permutedKey.append(originalKey.charAt(PC1[i] - 1)); } - String subKeys[] = new String[16]; + String[] subKeys = new String[16]; String initialPermutedKey = permutedKey.toString(); - String C0 = initialPermutedKey.substring(0, 28), D0 = initialPermutedKey.substring(28); + String c0 = initialPermutedKey.substring(0, 28); + String d0 = initialPermutedKey.substring(28); // We will now operate on the left and right halves of the permutedKey for (i = 0; i < 16; i++) { - String Cn = C0.substring(KEY_SHIFTS[i]) + C0.substring(0, KEY_SHIFTS[i]); - String Dn = D0.substring(KEY_SHIFTS[i]) + D0.substring(0, KEY_SHIFTS[i]); - subKeys[i] = Cn + Dn; - C0 = Cn; // Re-assign the values to create running permutation - D0 = Dn; + String cN = c0.substring(KEY_SHIFTS[i]) + c0.substring(0, KEY_SHIFTS[i]); + String dN = d0.substring(KEY_SHIFTS[i]) + d0.substring(0, KEY_SHIFTS[i]); + subKeys[i] = cN + dN; + c0 = cN; // Re-assign the values to create running permutation + d0 = dN; } - // Let us shrink the keys to 48 bits (well, characters here) using PC2 + // Let us shrink the keys to 48 bits (well, characters here) using pc2 for (i = 0; i < 16; i++) { String key = subKeys[i]; permutedKey.setLength(0); @@ -104,8 +106,9 @@ private String[] getSubkeys(String originalKey) { return subKeys; } - private String XOR(String a, String b) { - int i, l = a.length(); + private String xOR(String a, String b) { + int i; + int l = a.length(); StringBuilder xor = new StringBuilder(); for (i = 0; i < l; i++) { int firstBit = a.charAt(i) - 48; // 48 is '0' in ascii @@ -116,7 +119,8 @@ private String XOR(String a, String b) { } private String createPaddedString(String s, int desiredLength, char pad) { - int i, l = s.length(); + int i; + int l = s.length(); StringBuilder paddedString = new StringBuilder(); int diff = desiredLength - l; for (i = 0; i < diff; i++) { @@ -137,9 +141,9 @@ private String feistel(String messageBlock, String key) { int i; StringBuilder expandedKey = new StringBuilder(); for (i = 0; i < 48; i++) { - expandedKey.append(messageBlock.charAt(expansion[i] - 1)); + expandedKey.append(messageBlock.charAt(EXPANSION[i] - 1)); } - String mixedKey = XOR(expandedKey.toString(), key); + String mixedKey = xOR(expandedKey.toString(), key); StringBuilder substitutedString = new StringBuilder(); // Let us now use the s-boxes to transform each 6 bit (length here) block to 4 bits @@ -147,45 +151,46 @@ private String feistel(String messageBlock, String key) { String block = mixedKey.substring(i, i + 6); int row = (block.charAt(0) - 48) * 2 + (block.charAt(5) - 48); int col = (block.charAt(1) - 48) * 8 + (block.charAt(2) - 48) * 4 + (block.charAt(3) - 48) * 2 + (block.charAt(4) - 48); - String substitutedBlock = pad(Integer.toBinaryString(s[i / 6][row][col]), 4); + String substitutedBlock = pad(Integer.toBinaryString(S[i / 6][row][col]), 4); substitutedString.append(substitutedBlock); } StringBuilder permutedString = new StringBuilder(); for (i = 0; i < 32; i++) { - permutedString.append(substitutedString.charAt(permutation[i] - 1)); + permutedString.append(substitutedString.charAt(PERMUTATION[i] - 1)); } return permutedString.toString(); } - private String encryptBlock(String message, String keys[]) { + private String encryptBlock(String message, String[] keys) { StringBuilder permutedMessage = new StringBuilder(); int i; for (i = 0; i < 64; i++) { permutedMessage.append(message.charAt(IP[i] - 1)); } - String L0 = permutedMessage.substring(0, 32), R0 = permutedMessage.substring(32); + String e0 = permutedMessage.substring(0, 32); + String f0 = permutedMessage.substring(32); // Iterate 16 times for (i = 0; i < 16; i++) { - String Ln = R0; // Previous Right block - String Rn = XOR(L0, feistel(R0, keys[i])); - L0 = Ln; - R0 = Rn; + String eN = f0; // Previous Right block + String fN = xOR(e0, feistel(f0, keys[i])); + e0 = eN; + f0 = fN; } - String combinedBlock = R0 + L0; // Reverse the 16th block + String combinedBlock = f0 + e0; // Reverse the 16th block permutedMessage.setLength(0); for (i = 0; i < 64; i++) { - permutedMessage.append(combinedBlock.charAt(IPinverse[i] - 1)); + permutedMessage.append(combinedBlock.charAt(IP_INVERSE[i] - 1)); } return permutedMessage.toString(); } // To decode, we follow the same process as encoding, but with reversed keys - private String decryptBlock(String message, String keys[]) { - String reversedKeys[] = new String[keys.length]; + private String decryptBlock(String message, String[] keys) { + String[] reversedKeys = new String[keys.length]; for (int i = 0; i < keys.length; i++) { reversedKeys[i] = keys[keys.length - i - 1]; } @@ -198,7 +203,9 @@ private String decryptBlock(String message, String keys[]) { */ public String encrypt(String message) { StringBuilder encryptedMessage = new StringBuilder(); - int l = message.length(), i, j; + int l = message.length(); + int i; + int j; if (l % 8 != 0) { int desiredLength = (l / 8 + 1) * 8; l = desiredLength; @@ -223,14 +230,16 @@ public String encrypt(String message) { */ public String decrypt(String message) { StringBuilder decryptedMessage = new StringBuilder(); - int l = message.length(), i, j; + int l = message.length(); + int i; + int j; if (l % 64 != 0) { throw new IllegalArgumentException("Encrypted message should be a multiple of 64 characters in length"); } for (i = 0; i < l; i += 64) { String block = message.substring(i, i + 64); - String result = decryptBlock(block.toString(), subKeys); - byte res[] = new byte[8]; + String result = decryptBlock(block, subKeys); + byte[] res = new byte[8]; for (j = 0; j < 64; j += 8) { res[j / 8] = (byte) Integer.parseInt(result.substring(j, j + 8), 2); } diff --git a/src/main/java/com/thealgorithms/ciphers/HillCipher.java b/src/main/java/com/thealgorithms/ciphers/HillCipher.java index a3226cef7de1..780009c2f1d6 100644 --- a/src/main/java/com/thealgorithms/ciphers/HillCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/HillCipher.java @@ -11,7 +11,9 @@ * for encryption. The cipher key and plaintext/ciphertext are user inputs. * @author Ojasva Jain */ -public class HillCipher { +public final class HillCipher { + private HillCipher() { + } static Scanner userInput = new Scanner(System.in); @@ -33,7 +35,7 @@ static void encrypt(String message) { validateDeterminant(keyMatrix, matrixSize); int[][] messageVector = new int[matrixSize][1]; - String CipherText = ""; + String cipherText = ""; int[][] cipherMatrix = new int[matrixSize][1]; int j = 0; while (j < message.length()) { @@ -46,7 +48,8 @@ static void encrypt(String message) { System.out.println(messageVector[i][0]); j++; } - int x, i; + int x; + int i; for (i = 0; i < matrixSize; i++) { cipherMatrix[i][0] = 0; @@ -57,10 +60,10 @@ static void encrypt(String message) { cipherMatrix[i][0] = cipherMatrix[i][0] % 26; } for (i = 0; i < matrixSize; i++) { - CipherText += (char) (cipherMatrix[i][0] + 65); + cipherText += (char) (cipherMatrix[i][0] + 65); } } - System.out.println("Ciphertext: " + CipherText); + System.out.println("Ciphertext: " + cipherText); } // Following function decrypts a message @@ -81,7 +84,7 @@ static void decrypt(String message) { // solving for the required plaintext message int[][] messageVector = new int[n][1]; - String PlainText = ""; + String plainText = ""; int[][] plainMatrix = new int[n][1]; int j = 0; while (j < message.length()) { @@ -94,7 +97,8 @@ static void decrypt(String message) { System.out.println(messageVector[i][0]); j++; } - int x, i; + int x; + int i; for (i = 0; i < n; i++) { plainMatrix[i][0] = 0; @@ -105,15 +109,18 @@ static void decrypt(String message) { plainMatrix[i][0] = plainMatrix[i][0] % 26; } for (i = 0; i < n; i++) { - PlainText += (char) (plainMatrix[i][0] + 65); + plainText += (char) (plainMatrix[i][0] + 65); } } - System.out.println("Plaintext: " + PlainText); + System.out.println("Plaintext: " + plainText); } // Determinant calculator public static int determinant(int[][] a, int n) { - int det = 0, sign = 1, p = 0, q = 0; + int det = 0; + int sign = 1; + int p = 0; + int q = 0; if (n == 1) { det = a[0][0]; @@ -142,7 +149,6 @@ public static int determinant(int[][] a, int n) { // 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"); diff --git a/src/main/java/com/thealgorithms/ciphers/Polybius.java b/src/main/java/com/thealgorithms/ciphers/Polybius.java index 7b5a27807bc4..6b3cd6ccae81 100644 --- a/src/main/java/com/thealgorithms/ciphers/Polybius.java +++ b/src/main/java/com/thealgorithms/ciphers/Polybius.java @@ -13,9 +13,11 @@ * @author Hikmet ÇAKIR * @since 08-07-2022+03:00 */ -public class Polybius { +public final class Polybius { + private Polybius() { + } - private static final char[][] key = { + private static final char[][] KEY = { // 0 1 2 3 4 /* 0 */ {'A', 'B', 'C', 'D', 'E'}, /* 1 */ {'F', 'G', 'H', 'I', 'J'}, @@ -26,9 +28,9 @@ public class Polybius { private static String findLocationByCharacter(final char character) { final StringBuilder location = new StringBuilder(); - for (int i = 0; i < key.length; i++) { - for (int j = 0; j < key[i].length; j++) { - if (character == key[i][j]) { + for (int i = 0; i < KEY.length; i++) { + for (int j = 0; j < KEY[i].length; j++) { + if (character == KEY[i][j]) { location.append(i).append(j); break; } @@ -53,7 +55,7 @@ public static String decrypt(final String ciphertext) { for (int i = 0; i < chars.length; i += 2) { int pozitionX = Character.getNumericValue(chars[i]); int pozitionY = Character.getNumericValue(chars[i + 1]); - plaintext.append(key[pozitionX][pozitionY]); + plaintext.append(KEY[pozitionX][pozitionY]); } return plaintext.toString(); } diff --git a/src/main/java/com/thealgorithms/ciphers/ProductCipher.java b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java index 5b1d46fe9a9a..d7eaea757001 100644 --- a/src/main/java/com/thealgorithms/ciphers/ProductCipher.java +++ b/src/main/java/com/thealgorithms/ciphers/ProductCipher.java @@ -2,7 +2,9 @@ import java.util.Scanner; -class ProductCipher { +final class ProductCipher { + private ProductCipher() { + } public static void main(String[] args) { try (Scanner sc = new Scanner(System.in)) { @@ -24,8 +26,8 @@ public static void main(String[] args) { // Transposition encryption String transpositionInput = substitutionOutput.toString(); - int modulus; - if ((modulus = transpositionInput.length() % n) != 0) { + int modulus = transpositionInput.length() % n; + if (modulus != 0) { modulus = n - modulus; for (; modulus != 0; modulus--) { @@ -66,7 +68,6 @@ public static void main(String[] args) { System.out.println("Plaintext: "); System.out.println(plaintext); - sc.close(); } } } diff --git a/src/main/java/com/thealgorithms/ciphers/RSA.java b/src/main/java/com/thealgorithms/ciphers/RSA.java index aea15c3554c0..f50e501e68c8 100644 --- a/src/main/java/com/thealgorithms/ciphers/RSA.java +++ b/src/main/java/com/thealgorithms/ciphers/RSA.java @@ -47,7 +47,7 @@ public synchronized BigInteger decrypt(BigInteger encryptedMessage) { /** * Generate a new public and private key set. */ - public synchronized void generateKeys(int bits) { + public final synchronized void generateKeys(int bits) { SecureRandom r = new SecureRandom(); BigInteger p = new BigInteger(bits / 2, 100, r); BigInteger q = new BigInteger(bits / 2, 100, r); diff --git a/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java b/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java index 12e93717a3de..3cac558237c2 100644 --- a/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java +++ b/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java @@ -26,10 +26,10 @@ public boolean clock() { private boolean getMajorityBit() { Map<Boolean, Integer> bitCount = new TreeMap<>(); - bitCount.put(false, 0); - bitCount.put(true, 0); + bitCount.put(Boolean.FALSE, 0); + bitCount.put(Boolean.TRUE, 0); registers.forEach(lfsr -> bitCount.put(lfsr.getClockBit(), bitCount.get(lfsr.getClockBit()) + 1)); - return bitCount.get(false) <= bitCount.get(true); + return bitCount.get(Boolean.FALSE) <= bitCount.get(Boolean.TRUE); } } diff --git a/src/main/java/com/thealgorithms/ciphers/a5/Utils.java b/src/main/java/com/thealgorithms/ciphers/a5/Utils.java index abdd11d6b72d..b4addf18dd9d 100644 --- a/src/main/java/com/thealgorithms/ciphers/a5/Utils.java +++ b/src/main/java/com/thealgorithms/ciphers/a5/Utils.java @@ -7,7 +7,9 @@ import java.util.BitSet; -public class Utils { +public final class Utils { + private Utils() { + } public static boolean increment(BitSet bits, int size) { int i = size - 1; diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java index 7a87fd15be23..4bd9c74a1751 100644 --- a/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java +++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToAnyBase.java @@ -13,7 +13,9 @@ * @author Michael Rolland * @version 2017.10.10 */ -public class AnyBaseToAnyBase { +public final class AnyBaseToAnyBase { + private AnyBaseToAnyBase() { + } /** * Smallest and largest base you want to accept as valid input @@ -25,7 +27,8 @@ public class AnyBaseToAnyBase { public static void main(String[] args) { Scanner in = new Scanner(System.in); String n; - int b1, b2; + int b1; + int b2; while (true) { try { System.out.print("Enter number: "); @@ -130,7 +133,8 @@ 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; + int decimalValue = 0; + int charB2; char charB1; String output = ""; // Go through every character of n diff --git a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java index 20f15bc2ff39..6b4b14adc955 100644 --- a/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java +++ b/src/main/java/com/thealgorithms/conversions/AnyBaseToDecimal.java @@ -4,7 +4,9 @@ * @author Varun Upadhyay (<a href="https://github.com/varunu28">...</a>) */ // Driver program -public class AnyBaseToDecimal { +public final class AnyBaseToDecimal { + private AnyBaseToDecimal() { + } public static void main(String[] args) { assert convertToDecimal("1010", 2) == Integer.valueOf("1010", 2); diff --git a/src/main/java/com/thealgorithms/conversions/AnytoAny.java b/src/main/java/com/thealgorithms/conversions/AnytoAny.java index 052d6dba6953..801e493032e0 100644 --- a/src/main/java/com/thealgorithms/conversions/AnytoAny.java +++ b/src/main/java/com/thealgorithms/conversions/AnytoAny.java @@ -6,14 +6,18 @@ // number. // sn ,sb,db ---> ()dn . this is what we have to do . -public class AnytoAny { +public final class AnytoAny { + private 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; + int m = 1; + int dec = 0; + int dn = 0; while (sn != 0) { dec = dec + (sn % 10) * m; m *= sb; diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java index fdf9df7b2467..67b815ab6466 100644 --- a/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java +++ b/src/main/java/com/thealgorithms/conversions/BinaryToDecimal.java @@ -5,10 +5,15 @@ /** * This class converts a Binary number to a Decimal number */ -class BinaryToDecimal { +final class BinaryToDecimal { + private BinaryToDecimal() { + } public static long binaryToDecimal(long binNum) { - long binCopy, d, s = 0, power = 0; + long binCopy; + long d; + long s = 0; + long power = 0; binCopy = binNum; while (binCopy != 0) { d = binCopy % 10; diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java index 011b60a952b8..a19baba39715 100644 --- a/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java +++ b/src/main/java/com/thealgorithms/conversions/BinaryToHexadecimal.java @@ -1,13 +1,16 @@ package com.thealgorithms.conversions; -import java.util.*; +import java.util.HashMap; +import java.util.Scanner; /** * Converts any Binary Number to a Hexadecimal Number * * @author Nishita Aggarwal */ -public class BinaryToHexadecimal { +public final class BinaryToHexadecimal { + private BinaryToHexadecimal() { + } /** * This method converts a binary number to a hexadecimal number. diff --git a/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java b/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java index 70bad812141b..6fef090287ab 100644 --- a/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java +++ b/src/main/java/com/thealgorithms/conversions/BinaryToOctal.java @@ -7,7 +7,9 @@ * * @author Zachary Jones */ -public class BinaryToOctal { +public final class BinaryToOctal { + private BinaryToOctal() { + } /** * Main method @@ -30,7 +32,8 @@ public static void main(String[] args) { */ public static String convertBinaryToOctal(int binary) { String octal = ""; - int currBit = 0, j = 1; + int currBit = 0; + int j = 1; while (binary != 0) { int code3 = 0; for (int i = 0; i < 3; i++) { diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java index 2d0223a4c448..019c4026bfb5 100644 --- a/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java +++ b/src/main/java/com/thealgorithms/conversions/DecimalToAnyBase.java @@ -8,7 +8,9 @@ * @author Varun Upadhyay (<a href="https://github.com/varunu28">...</a>) */ // Driver Program -public class DecimalToAnyBase { +public final class DecimalToAnyBase { + private DecimalToAnyBase() { + } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java b/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java index a6119cfbc9bc..471724ff9966 100644 --- a/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java +++ b/src/main/java/com/thealgorithms/conversions/DecimalToBinary.java @@ -5,7 +5,9 @@ /** * This class converts a Decimal number to a Binary number */ -class DecimalToBinary { +final class DecimalToBinary { + private DecimalToBinary() { + } /** * Main Method @@ -22,7 +24,10 @@ public static void main(String[] args) { * conventional algorithm. */ public static void conventionalConversion() { - int n, b = 0, c = 0, d; + int n; + int b = 0; + int c = 0; + int d; Scanner input = new Scanner(System.in); System.out.printf("Conventional conversion.%n Enter the decimal number: "); n = input.nextInt(); @@ -40,7 +45,10 @@ public static void conventionalConversion() { * algorithm */ public static void bitwiseConversion() { - int n, b = 0, c = 0, d; + int n; + int b = 0; + int c = 0; + int d; Scanner input = new Scanner(System.in); System.out.printf("Bitwise conversion.%n Enter the decimal number: "); n = input.nextInt(); diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java b/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java index 3564acbe568c..78838c6107b7 100644 --- a/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java +++ b/src/main/java/com/thealgorithms/conversions/DecimalToHexaDecimal.java @@ -1,12 +1,14 @@ package com.thealgorithms.conversions; // hex = [0 - 9] -> [A - F] -class DecimalToHexaDecimal { +final class DecimalToHexaDecimal { + private DecimalToHexaDecimal() { + } - private static final int sizeOfIntInHalfBytes = 8; - private static final int numberOfBitsInAHalfByte = 4; - private static final int halfByte = 0x0F; - private static final char[] hexDigits = { + private static final int SIZE_OF_INT_IN_HALF_BYTES = 8; + private static final int NUMBER_OF_BITS_IN_HALF_BYTE = 4; + private static final int HALF_BYTE = 0x0F; + private static final char[] HEX_DIGITS = { '0', '1', '2', @@ -27,12 +29,12 @@ class DecimalToHexaDecimal { // 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; + StringBuilder hexBuilder = new StringBuilder(SIZE_OF_INT_IN_HALF_BYTES); + hexBuilder.setLength(SIZE_OF_INT_IN_HALF_BYTES); + for (int i = SIZE_OF_INT_IN_HALF_BYTES - 1; i >= 0; --i) { + int j = dec & HALF_BYTE; + hexBuilder.setCharAt(i, HEX_DIGITS[j]); + dec >>= NUMBER_OF_BITS_IN_HALF_BYTE; } return hexBuilder.toString().toLowerCase(); } diff --git a/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java b/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java index 0f72f462c753..4bc3a6e7af8c 100644 --- a/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java +++ b/src/main/java/com/thealgorithms/conversions/DecimalToOctal.java @@ -5,7 +5,9 @@ /** * This class converts Decimal numbers to Octal Numbers */ -public class DecimalToOctal { +public final class DecimalToOctal { + private DecimalToOctal() { + } /** * Main Method @@ -16,7 +18,11 @@ public class DecimalToOctal { // 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; + int n; + int k; + int d; + int s = 0; + int c = 0; System.out.print("Decimal number: "); n = sc.nextInt(); k = n; diff --git a/src/main/java/com/thealgorithms/conversions/HexToOct.java b/src/main/java/com/thealgorithms/conversions/HexToOct.java index 2a57fbde5c41..97a8be16b2e0 100644 --- a/src/main/java/com/thealgorithms/conversions/HexToOct.java +++ b/src/main/java/com/thealgorithms/conversions/HexToOct.java @@ -7,7 +7,9 @@ * * @author Tanmay Joshi */ -public class HexToOct { +public final class HexToOct { + private HexToOct() { + } /** * This method converts a Hexadecimal number to a decimal number @@ -54,7 +56,8 @@ public static int decimal2octal(int q) { */ public static void main(String[] args) { String hexadecnum; - int decnum, octalnum; + int decnum; + int octalnum; Scanner scan = new Scanner(System.in); System.out.print("Enter Hexadecimal Number : "); diff --git a/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java b/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java index 5372c95f23d4..b6228488dc76 100644 --- a/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java +++ b/src/main/java/com/thealgorithms/conversions/HexaDecimalToBinary.java @@ -2,9 +2,6 @@ // Hex [0-9],[A-F] -> Binary [0,1] public class HexaDecimalToBinary { - - private final int LONG_BITS = 8; - public String convert(String numHex) { // String a HexaDecimal: int conHex = Integer.parseInt(numHex, 16); @@ -15,7 +12,8 @@ public String convert(String numHex) { } public String completeDigits(String binNum) { - for (int i = binNum.length(); i < LONG_BITS; i++) { + final int longBits = 8; + for (int i = binNum.length(); i < longBits; i++) { binNum = "0" + binNum; } return binNum; diff --git a/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java b/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java index 7675c83ebcfa..003781da9d5e 100644 --- a/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java +++ b/src/main/java/com/thealgorithms/conversions/HexaDecimalToDecimal.java @@ -2,7 +2,9 @@ import java.util.Scanner; -public class HexaDecimalToDecimal { +public final class HexaDecimalToDecimal { + private HexaDecimalToDecimal() { + } // convert hexadecimal to decimal public static int getHexaToDec(String hex) { @@ -18,20 +20,20 @@ public static int getHexaToDec(String hex) { // 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; + String hexaInput; + int decOutput; Scanner scan = new Scanner(System.in); System.out.print("Enter Hexadecimal Number : "); - hexa_Input = scan.nextLine(); + hexaInput = scan.nextLine(); // convert hexadecimal to decimal - dec_output = getHexaToDec(hexa_Input); + decOutput = getHexaToDec(hexaInput); /* Pass the string to the getHexaToDec function - and it returns the decimal form in the variable dec_output. + and it returns the decimal form in the variable decOutput. */ - System.out.println("Number in Decimal: " + dec_output); + System.out.println("Number in Decimal: " + decOutput); scan.close(); } } diff --git a/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java b/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java index b81cfd773d75..9c031df9504d 100644 --- a/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java +++ b/src/main/java/com/thealgorithms/conversions/IntegerToRoman.java @@ -7,9 +7,11 @@ * ('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 { +public final class IntegerToRoman { + private IntegerToRoman() { + } - private static int[] allArabianRomanNumbers = new int[] { + private static final int[] ALL_ROMAN_NUMBERS_IN_ARABIC = new int[] { 1000, 900, 500, @@ -24,7 +26,7 @@ public class IntegerToRoman { 4, 1, }; - private static String[] allRomanNumbers = new String[] { + private static final String[] ALL_ROMAN_NUMBERS = new String[] { "M", "CM", "D", @@ -48,13 +50,13 @@ public static String integerToRoman(int num) { StringBuilder builder = new StringBuilder(); - for (int a = 0; a < allArabianRomanNumbers.length; a++) { - int times = num / allArabianRomanNumbers[a]; + for (int a = 0; a < ALL_ROMAN_NUMBERS_IN_ARABIC.length; a++) { + int times = num / ALL_ROMAN_NUMBERS_IN_ARABIC[a]; for (int b = 0; b < times; b++) { - builder.append(allRomanNumbers[a]); + builder.append(ALL_ROMAN_NUMBERS[a]); } - num -= times * allArabianRomanNumbers[a]; + num -= times * ALL_ROMAN_NUMBERS_IN_ARABIC[a]; } return builder.toString(); diff --git a/src/main/java/com/thealgorithms/conversions/OctalToBinary.java b/src/main/java/com/thealgorithms/conversions/OctalToBinary.java index 4dd581bd6116..6b01c2f65cfe 100644 --- a/src/main/java/com/thealgorithms/conversions/OctalToBinary.java +++ b/src/main/java/com/thealgorithms/conversions/OctalToBinary.java @@ -6,7 +6,9 @@ * @author Bama Charan Chhandogi */ -public class OctalToBinary { +public final class OctalToBinary { + private OctalToBinary() { + } public static long convertOctalToBinary(int octalNumber) { long binaryNumber = 0; int digitPosition = 1; diff --git a/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java b/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java index d4916a3dbcca..187f0ed1e2ea 100644 --- a/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java +++ b/src/main/java/com/thealgorithms/conversions/OctalToDecimal.java @@ -7,7 +7,9 @@ * * @author Zachary Jones */ -public class OctalToDecimal { +public final class OctalToDecimal { + private OctalToDecimal() { + } /** * Main method diff --git a/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java b/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java index 5edd94c38430..5cc97fde12aa 100644 --- a/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java +++ b/src/main/java/com/thealgorithms/conversions/OctalToHexadecimal.java @@ -7,7 +7,9 @@ * * @author Tanmay Joshi */ -public class OctalToHexadecimal { +public final class OctalToHexadecimal { + private OctalToHexadecimal() { + } /** * This method converts a Octal number to a decimal number diff --git a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java index 65cb00fc0ad0..84cbff09db6b 100644 --- a/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java +++ b/src/main/java/com/thealgorithms/conversions/RgbHsvConversion.java @@ -13,7 +13,9 @@ * (description adapted from <a href="https://en.wikipedia.org/wiki/RGB_color_model">[1]</a> and * <a href="https://en.wikipedia.org/wiki/HSL_and_HSV">[2]</a>). */ -public class RgbHsvConversion { +public final class RgbHsvConversion { + private RgbHsvConversion() { + } public static void main(String[] args) { // Expected RGB-values taken from https://www.rapidtables.com/convert/color/hsv-to-rgb.html diff --git a/src/main/java/com/thealgorithms/conversions/RomanToInteger.java b/src/main/java/com/thealgorithms/conversions/RomanToInteger.java index fddb56232c58..cf2d4145858f 100644 --- a/src/main/java/com/thealgorithms/conversions/RomanToInteger.java +++ b/src/main/java/com/thealgorithms/conversions/RomanToInteger.java @@ -1,14 +1,13 @@ package com.thealgorithms.conversions; -import java.util.*; +import java.util.HashMap; +import java.util.Map; -public class RomanToInteger { - - private static Map<Character, Integer> map = new HashMap<Character, Integer>() { - /** - * */ - private static final long serialVersionUID = 87605733047260530L; +public final class RomanToInteger { + private RomanToInteger() { + } + private static final Map<Character, Integer> ROMAN_TO_INT = new HashMap<>() { { put('I', 1); put('V', 5); @@ -25,31 +24,31 @@ public class RomanToInteger { /** * This function convert Roman number into Integer * - * @param A Roman number string + * @param a Roman number string * @return integer */ - public static int romanToInt(String A) { - A = A.toUpperCase(); + 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); + 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; + // checking current Number greater than previous or not + newPrev = ROMAN_TO_INT.get(prev) > newPrev ? ROMAN_TO_INT.get(prev) : newPrev; } - int currentNum = map.get(c); + int currentNum = ROMAN_TO_INT.get(c); - // if current number greater then prev max previous then add + // if current number greater than prev max previous then add if (currentNum >= newPrev) { sum += currentNum; } else { - // subtract upcoming number until upcoming number not greater then prev max + // subtract upcoming number until upcoming number not greater than prev max sum -= currentNum; } diff --git a/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java b/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java index d991f5f31faf..4d13b8b7fd55 100644 --- a/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java +++ b/src/main/java/com/thealgorithms/conversions/TurkishToLatinConversion.java @@ -7,7 +7,9 @@ * * @author Özgün Gökşenli */ -public class TurkishToLatinConversion { +public final class TurkishToLatinConversion { + private TurkishToLatinConversion() { + } /** * Main method @@ -58,7 +60,7 @@ public static String convertTurkishToLatin(String param) { 'G', }; for (int i = 0; i < turkishChars.length; i++) { - param = param.replaceAll(new String(new char[] {turkishChars[i]}), new String(new char[] {latinChars[i]})); + param = param.replaceAll(String.valueOf(turkishChars[i]), String.valueOf(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 index c82b9124bebc..ff5c832baeaf 100644 --- a/src/main/java/com/thealgorithms/datastructures/bags/Bag.java +++ b/src/main/java/com/thealgorithms/datastructures/bags/Bag.java @@ -13,7 +13,7 @@ public class Bag<Element> implements Iterable<Element> { private Node<Element> firstElement; // first element of the bag private int size; // size of bag - private static class Node<Element> { + private static final class Node<Element> { private Element content; private Node<Element> nextElement; @@ -80,7 +80,7 @@ private class ListIterator<Element> implements Iterator<Element> { private Node<Element> currentElement; - public ListIterator(Node<Element> firstElement) { + ListIterator(Node<Element> firstElement) { currentElement = firstElement; } diff --git a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java index db85afa18c81..a327690d7896 100644 --- a/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java +++ b/src/main/java/com/thealgorithms/datastructures/bloomfilter/BloomFilter.java @@ -42,7 +42,7 @@ private class Hash<T> { int index; - public Hash(int index) { + Hash(int index) { this.index = index; } diff --git a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java index 5e1c815ff9b3..63295b83abe6 100644 --- a/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java +++ b/src/main/java/com/thealgorithms/datastructures/buffers/CircularBuffer.java @@ -43,7 +43,7 @@ private static class CircularPointer { private int pointer; private final int max; - public CircularPointer(int pointer, int max) { + CircularPointer(int pointer, int max) { this.pointer = pointer; this.max = max; } diff --git a/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java b/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java index 03a1d59e1b20..6e37b4a7109d 100644 --- a/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java +++ b/src/main/java/com/thealgorithms/datastructures/caches/LFUCache.java @@ -17,7 +17,7 @@ private class Node { private Node previous; private Node next; - public Node(K key, V value, int frequency) { + Node(K key, V value, int frequency) { this.key = key; this.value = value; this.frequency = frequency; diff --git a/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java b/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java index fcb7d975bdb4..97818ff83351 100644 --- a/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java +++ b/src/main/java/com/thealgorithms/datastructures/caches/LRUCache.java @@ -126,10 +126,10 @@ static final class Entry<I, J> { private I key; private J value; - public Entry() { + Entry() { } - public Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) { + Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) { this.preEntry = preEntry; this.nextEntry = nextEntry; this.key = key; diff --git a/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java b/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java index 30f914968c3b..9c155be8b195 100644 --- a/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java +++ b/src/main/java/com/thealgorithms/datastructures/caches/MRUCache.java @@ -124,10 +124,10 @@ static final class Entry<I, J> { private I key; private J value; - public Entry() { + Entry() { } - public Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) { + Entry(Entry<I, J> preEntry, Entry<I, J> nextEntry, I key, J value) { this.preEntry = preEntry; this.nextEntry = nextEntry; this.key = key; diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java b/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java index 63364f858ec5..25b01bce19f3 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/GCounter.java @@ -17,7 +17,7 @@ */ class GCounter { - private final Map<Integer, Integer> P; + private final Map<Integer, Integer> counterMap; private final int myId; private final int n; @@ -26,13 +26,13 @@ class GCounter { * * @param n The number of nodes in the cluster. */ - public GCounter(int myId, int n) { + GCounter(int myId, int n) { this.myId = myId; this.n = n; - this.P = new HashMap<>(); + this.counterMap = new HashMap<>(); for (int i = 0; i < n; i++) { - P.put(i, 0); + counterMap.put(i, 0); } } @@ -40,7 +40,7 @@ public GCounter(int myId, int n) { * Increments the counter for the current node. */ public void increment() { - P.put(myId, P.get(myId) + 1); + counterMap.put(myId, counterMap.get(myId) + 1); } /** @@ -50,7 +50,7 @@ public void increment() { */ public int value() { int sum = 0; - for (int v : P.values()) { + for (int v : counterMap.values()) { sum += v; } return sum; @@ -64,7 +64,7 @@ public int value() { */ public boolean compare(GCounter other) { for (int i = 0; i < n; i++) { - if (this.P.get(i) > other.P.get(i)) { + if (this.counterMap.get(i) > other.counterMap.get(i)) { return false; } } @@ -78,7 +78,7 @@ public boolean compare(GCounter other) { */ public void merge(GCounter other) { for (int i = 0; i < n; i++) { - this.P.put(i, Math.max(this.P.get(i), other.P.get(i))); + this.counterMap.put(i, Math.max(this.counterMap.get(i), other.counterMap.get(i))); } } } diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java index 722c916ab0ce..2c6ce8a427d1 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java @@ -26,7 +26,7 @@ class Element { * @param timestamp The timestamp associated with the element. * @param bias The bias of the element (ADDS or REMOVALS). */ - public Element(String key, int timestamp, Bias bias) { + Element(String key, int timestamp, Bias bias) { this.key = key; this.timestamp = timestamp; this.bias = bias; @@ -49,7 +49,7 @@ class LWWElementSet { /** * Constructs an empty LWWElementSet. */ - public LWWElementSet() { + LWWElementSet() { this.addSet = new HashMap<>(); this.removeSet = new HashMap<>(); } @@ -124,14 +124,14 @@ public void merge(LWWElementSet other) { * @return True if the first element's timestamp is greater or the bias is ADDS and timestamps are equal. */ public boolean compareTimestamps(Element e, Element other) { - if (!e.bias.equals(other.bias)) { + if (e.bias != other.bias) { throw new IllegalArgumentException("Invalid bias value"); } Bias bias = e.bias; int timestampComparison = Integer.compare(e.timestamp, other.timestamp); if (timestampComparison == 0) { - return !bias.equals(Bias.ADDS); + return bias != Bias.ADDS; } return timestampComparison < 0; } diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java b/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java index 828e0b0804b3..53c21dcbd108 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/PNCounter.java @@ -17,8 +17,8 @@ */ class PNCounter { - private final Map<Integer, Integer> P; - private final Map<Integer, Integer> N; + private final Map<Integer, Integer> pCounter; + private final Map<Integer, Integer> nCounter; private final int myId; private final int n; @@ -28,15 +28,15 @@ class PNCounter { * @param myId The identifier of the current node. * @param n The number of nodes in the cluster. */ - public PNCounter(int myId, int n) { + PNCounter(int myId, int n) { this.myId = myId; this.n = n; - this.P = new HashMap<>(); - this.N = new HashMap<>(); + this.pCounter = new HashMap<>(); + this.nCounter = new HashMap<>(); for (int i = 0; i < n; i++) { - P.put(i, 0); - N.put(i, 0); + pCounter.put(i, 0); + nCounter.put(i, 0); } } @@ -44,14 +44,14 @@ public PNCounter(int myId, int n) { * Increments the increment counter for the current node. */ public void increment() { - P.put(myId, P.get(myId) + 1); + pCounter.put(myId, pCounter.get(myId) + 1); } /** * Increments the decrement counter for the current node. */ public void decrement() { - N.put(myId, N.get(myId) + 1); + nCounter.put(myId, nCounter.get(myId) + 1); } /** @@ -60,8 +60,8 @@ public void decrement() { * @return The total value of the counter. */ public int value() { - int sumP = P.values().stream().mapToInt(Integer::intValue).sum(); - int sumN = N.values().stream().mapToInt(Integer::intValue).sum(); + int sumP = pCounter.values().stream().mapToInt(Integer::intValue).sum(); + int sumN = nCounter.values().stream().mapToInt(Integer::intValue).sum(); return sumP - sumN; } @@ -76,7 +76,7 @@ public boolean compare(PNCounter other) { throw new IllegalArgumentException("Cannot compare PN-Counters with different number of nodes"); } for (int i = 0; i < n; i++) { - if (this.P.get(i) > other.P.get(i) && this.N.get(i) > other.N.get(i)) { + if (this.pCounter.get(i) > other.pCounter.get(i) && this.nCounter.get(i) > other.nCounter.get(i)) { return false; } } @@ -93,8 +93,8 @@ public void merge(PNCounter other) { throw new IllegalArgumentException("Cannot merge PN-Counters with different number of nodes"); } for (int i = 0; i < n; i++) { - this.P.put(i, Math.max(this.P.get(i), other.P.get(i))); - this.N.put(i, Math.max(this.N.get(i), other.N.get(i))); + this.pCounter.put(i, Math.max(this.pCounter.get(i), other.pCounter.get(i))); + this.nCounter.put(i, Math.max(this.nCounter.get(i), other.nCounter.get(i))); } } } diff --git a/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java b/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java index f6f0276e0c35..cfec2e3b2c37 100644 --- a/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java +++ b/src/main/java/com/thealgorithms/datastructures/dynamicarray/DynamicArray.java @@ -1,6 +1,10 @@ package com.thealgorithms.datastructures.dynamicarray; -import java.util.*; +import java.util.Arrays; +import java.util.ConcurrentModificationException; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Objects; import java.util.function.Consumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -117,7 +121,8 @@ private void fastRemove(final Object[] elements, final int index) { System.arraycopy(elements, index + 1, elements, index, newSize - index); } - elements[this.size = newSize] = null; + this.size = newSize; + this.elements[this.size] = null; } private E getElement(final int index) { @@ -149,7 +154,7 @@ public Iterator<E> iterator() { return new DynamicArrayIterator(); } - private class DynamicArrayIterator implements Iterator<E> { + private final class DynamicArrayIterator implements Iterator<E> { private int cursor; diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java b/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java index 8cd28378d9d3..b1af21eb6ff2 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/A_Star.java @@ -3,9 +3,15 @@ */ package com.thealgorithms.datastructures.graphs; -import java.util.*; - -public class A_Star { +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; + +public final class A_Star { + private A_Star() { + } private static class Graph { @@ -14,7 +20,7 @@ private static class Graph { private ArrayList<ArrayList<Edge>> graph; // Initialise ArrayLists in Constructor - public Graph(int size) { + Graph(int size) { this.graph = new ArrayList<>(); for (int i = 0; i < size; i++) { this.graph.add(new ArrayList<>()); @@ -38,7 +44,7 @@ private static class Edge { private int to; private int weight; - public Edge(int from, int to, int weight) { + Edge(int from, int to, int weight) { this.from = from; this.to = to; this.weight = weight; @@ -64,7 +70,7 @@ private static class PathAndDistance { private ArrayList<Integer> path; // list of visited nodes in this path. private int estimated; // heuristic value associated to the last node od the path (current node). - public PathAndDistance(int distance, ArrayList<Integer> path, int estimated) { + PathAndDistance(int distance, ArrayList<Integer> path, int estimated) { this.distance = distance; this.path = path; this.estimated = estimated; diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java b/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java index 9f5022b44465..522e19787e8c 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BellmanFord.java @@ -1,6 +1,6 @@ package com.thealgorithms.datastructures.graphs; -import java.util.*; +import java.util.Scanner; class BellmanFord /* * Implementation of Bellman ford to detect negative cycles. Graph accepts @@ -11,7 +11,8 @@ class BellmanFord /* */ { - int vertex, edge; + int vertex; + int edge; private Edge[] edges; private int index = 0; @@ -23,7 +24,8 @@ class BellmanFord /* class Edge { - int u, v; + int u; + int v; int w; /** @@ -31,7 +33,7 @@ class Edge { * @param v End vertex * @param c Weight */ - public Edge(int a, int b, int c) { + Edge(int a, int b, int c) { u = a; v = b; w = c; @@ -58,7 +60,14 @@ public static void main(String[] args) { public void go() { // shows distance to all vertices // Interactive run for understanding the try ( // class first time. Assumes source vertex is 0 and Scanner sc = new Scanner(System.in)) { - int i, v, e, u, ve, w, j, neg = 0; + int i; + int v; + int e; + int u; + int ve; + int w; + int j; + int neg = 0; System.out.println("Enter no. of vertices and edges please"); v = sc.nextInt(); e = sc.nextInt(); @@ -107,7 +116,6 @@ public void go() { // shows distance to all vertices // Interactive run for unde System.out.println(); } } - sc.close(); } } @@ -120,7 +128,11 @@ public void show(int source, int end, Edge[] arr) { // be created by using addEdge() method and passed by calling getEdgeArray() // method // Just shows results of computation, if graph is passed to it. The // graph should - int i, j, v = vertex, e = edge, neg = 0; + int i; + int j; + int v = vertex; + int e = edge; + int neg = 0; double[] dist = new double[v]; // Distance array for holding the finalized shortest path // distance between source // and all vertices diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java index a4827d8881b3..4cc14bfd38de 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BipartiteGrapfDFS.java @@ -14,16 +14,18 @@ * * Output : YES */ -public class BipartiteGrapfDFS { +public final class BipartiteGrapfDFS { + private BipartiteGrapfDFS() { + } - private static boolean bipartite(int V, ArrayList<ArrayList<Integer>> adj, int[] color, int node) { + private static boolean bipartite(int v, ArrayList<ArrayList<Integer>> 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)) { + if (!bipartite(v, adj, color, it)) { return false; } } else if (color[it] == color[node]) { @@ -33,14 +35,14 @@ private static boolean bipartite(int V, ArrayList<ArrayList<Integer>> adj, int[] return true; } - public static boolean isBipartite(int V, ArrayList<ArrayList<Integer>> adj) { + public static boolean isBipartite(int v, ArrayList<ArrayList<Integer>> adj) { // Code here - int[] color = new int[V + 1]; + int[] color = new int[v + 1]; Arrays.fill(color, -1); - for (int i = 0; i < V; i++) { + for (int i = 0; i < v; i++) { if (color[i] == -1) { - if (!bipartite(V, adj, color, i)) { + if (!bipartite(v, adj, color, i)) { return false; } } @@ -52,23 +54,23 @@ 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) { - String[] S = read.readLine().trim().split(" "); - int V = Integer.parseInt(S[0]); - int E = Integer.parseInt(S[1]); + String[] str1 = read.readLine().trim().split(" "); + int numVertices = Integer.parseInt(str1[0]); + int numEdges = Integer.parseInt(str1[1]); ArrayList<ArrayList<Integer>> adj = new ArrayList<>(); - for (int i = 0; i < V; i++) { + for (int i = 0; i < numVertices; i++) { adj.add(new ArrayList<>()); } - 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); + for (int i = 0; i < numEdges; i++) { + String[] str2 = read.readLine().trim().split(" "); + int vertexU = Integer.parseInt(str2[0]); + int vertexV = Integer.parseInt(str2[1]); + adj.get(vertexU).add(vertexV); + adj.get(vertexV).add(vertexU); } - boolean ans = isBipartite(V, adj); + boolean ans = isBipartite(numVertices, adj); if (ans) { System.out.println("YES"); } else { diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java b/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java index b0add255f59a..d2b76e8e06b1 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/ConnectedComponent.java @@ -15,16 +15,17 @@ class Node { E name; - public Node(E name) { + Node(E name) { this.name = name; } } class Edge { - Node startNode, endNode; + Node startNode; + Node endNode; - public Edge(Node startNode, Node endNode) { + Edge(Node startNode, Node endNode) { this.startNode = startNode; this.endNode = endNode; } @@ -33,7 +34,7 @@ public Edge(Node startNode, Node endNode) { ArrayList<Edge> edgeList; ArrayList<Node> nodeList; - public Graph() { + Graph() { edgeList = new ArrayList<Edge>(); nodeList = new ArrayList<Node>(); } @@ -46,7 +47,8 @@ public Graph() { * @param endNode the ending Node from the edge */ public void addEdge(E startNode, E endNode) { - Node start = null, end = null; + Node start = null; + Node end = null; for (Node node : nodeList) { if (startNode.compareTo(node.name) == 0) { start = node; @@ -107,7 +109,9 @@ public ArrayList<Node> depthFirstSearch(Node n, ArrayList<Node> visited) { } } -public class ConnectedComponent { +public final class ConnectedComponent { + private ConnectedComponent() { + } public static void main(String[] args) { Graph<Character> graphChars = new Graph<>(); diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java b/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java index 5d5bd3c7469c..b67c5512e622 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Cycles.java @@ -5,12 +5,13 @@ class Cycle { - private int nodes, edges; + private final int nodes; + private final int edges; private int[][] adjacencyMatrix; private boolean[] visited; ArrayList<ArrayList<Integer>> cycles = new ArrayList<ArrayList<Integer>>(); - public Cycle() { + Cycle() { Scanner in = new Scanner(System.in); System.out.print("Enter the no. of nodes: "); nodes = in.nextInt(); @@ -27,7 +28,8 @@ public Cycle() { System.out.println("Enter the details of each edges <Start Node> <End Node>"); for (int i = 0; i < edges; i++) { - int start, end; + int start; + int end; start = in.nextInt(); end = in.nextInt(); adjacencyMatrix[start][end] = 1; @@ -78,7 +80,9 @@ public void printAll() { } } -public class Cycles { +public final class Cycles { + private Cycles() { + } public static void main(String[] args) { Cycle c = new Cycle(); diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java b/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java index 59f0d0116762..8503aa48ec37 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java @@ -8,17 +8,18 @@ class dijkstras { int k = 9; - int minDist(int[] dist, Boolean[] Set) { - int min = Integer.MAX_VALUE, min_index = -1; + int minDist(int[] dist, Boolean[] set) { + int min = Integer.MAX_VALUE; + int minIndex = -1; for (int r = 0; r < k; r++) { - if (!Set[r] && dist[r] <= min) { + if (!set[r] && dist[r] <= min) { min = dist[r]; - min_index = r; + minIndex = r; } } - return min_index; + return minIndex; } void print(int[] dist) { @@ -30,22 +31,22 @@ void print(int[] dist) { void dijkstra(int[][] graph, int src) { int[] dist = new int[k]; - Boolean[] Set = new Boolean[k]; + Boolean[] set = new Boolean[k]; for (int i = 0; i < k; i++) { dist[i] = Integer.MAX_VALUE; - Set[i] = false; + set[i] = Boolean.FALSE; } dist[src] = 0; for (int c = 0; c < k - 1; c++) { - int u = minDist(dist, Set); + int u = minDist(dist, set); - Set[u] = true; + set[u] = Boolean.TRUE; for (int v = 0; v < k; v++) { - if (!Set[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) { + if (!set[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v]; } } diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java b/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java index b295fb08c1dc..d47ffe3aa27d 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/FloydWarshall.java @@ -4,31 +4,31 @@ public class FloydWarshall { - private int[][] DistanceMatrix; + 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 + distanceMatrix = new int[numberofvertices + 1][numberofvertices + 1]; // stores the value of distance from all the possible path form the source // vertex to destination vertex // The matrix is initialized with 0's by default this.numberofvertices = numberofvertices; } - public void floydwarshall(int[][] AdjacencyMatrix) { // calculates all the distances from source to destination vertex + public void floydwarshall(int[][] adjacencyMatrix) { // calculates all the distances from source to destination vertex for (int source = 1; source <= numberofvertices; source++) { for (int destination = 1; destination <= numberofvertices; destination++) { - DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination]; + 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]) { // calculated distance it get replaced as + if (distanceMatrix[source][intermediate] + distanceMatrix[intermediate][destination] < distanceMatrix[source][destination]) { // calculated distance it get replaced as // new shortest distance // if the new // distance calculated is less then the // earlier shortest - DistanceMatrix[source][destination] = DistanceMatrix[source][intermediate] + DistanceMatrix[intermediate][destination]; + distanceMatrix[source][destination] = distanceMatrix[source][intermediate] + distanceMatrix[intermediate][destination]; } } } @@ -40,7 +40,7 @@ public void floydwarshall(int[][] AdjacencyMatrix) { // calculates all the dista 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.print(distanceMatrix[source][destination] + "\t"); } System.out.println(); } diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java b/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java index 77cea399c173..b0970f36ddc5 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java @@ -6,7 +6,7 @@ class AdjacencyListGraph<E extends Comparable<E>> { ArrayList<Vertex> vertices; - public AdjacencyListGraph() { + AdjacencyListGraph() { vertices = new ArrayList<>(); } @@ -15,7 +15,7 @@ private class Vertex { E data; ArrayList<Vertex> adjacentVertices; - public Vertex(E data) { + Vertex(E data) { adjacentVertices = new ArrayList<>(); this.data = data; } @@ -75,7 +75,8 @@ public boolean removeEdge(E from, E to) { * already did */ public boolean addEdge(E from, E to) { - Vertex fromV = null, toV = null; + Vertex fromV = null; + Vertex toV = null; for (Vertex v : vertices) { if (from.compareTo(v.data) == 0) { // see if from vertex already exists fromV = v; @@ -120,7 +121,9 @@ public String toString() { } } -public class Graphs { +public final class Graphs { + private Graphs() { + } public static void main(String[] args) { AdjacencyListGraph<Integer> graph = new AdjacencyListGraph<>(); diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java b/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java index 0016abef2419..65483eeeb65c 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java @@ -8,7 +8,8 @@ */ public class HamiltonianCycle { - private int V, pathCount; + private int vertex; + private int pathCount; private int[] cycle; private int[][] graph; @@ -21,8 +22,8 @@ public class HamiltonianCycle { * else returns 1D array with value -1. */ public int[] findHamiltonianCycle(int[][] graph) { - this.V = graph.length; - this.cycle = new int[this.V + 1]; + this.vertex = graph.length; + this.cycle = new int[this.vertex + 1]; // Initialize path array with -1 value for (int i = 0; i < this.cycle.length; i++) { @@ -52,17 +53,17 @@ public int[] findHamiltonianCycle(int[][] graph) { * @returns true if path is found false otherwise */ public boolean isPathFound(int vertex) { - boolean isLastVertexConnectedToStart = this.graph[vertex][0] == 1 && this.pathCount == this.V; + boolean isLastVertexConnectedToStart = this.graph[vertex][0] == 1 && this.pathCount == this.vertex; if (isLastVertexConnectedToStart) { return true; } /** all vertices selected but last vertex not linked to 0 **/ - if (this.pathCount == this.V) { + if (this.pathCount == this.vertex) { return false; } - for (int v = 0; v < this.V; v++) { + for (int v = 0; v < this.vertex; v++) { /** if connected **/ if (this.graph[vertex][v] == 1) { /** add to path **/ diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java index e978ddc1e764..145071890d76 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java @@ -130,7 +130,9 @@ ArrayList<E> topSortOrder() { /** * A driver class that sorts a given graph in topological order. */ -public class KahnsAlgorithm { +public final class KahnsAlgorithm { + private KahnsAlgorithm() { + } public static void main(String[] args) { // Graph definition and initialization diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java index bf5afcd13fda..eb5b65d5c0d4 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java @@ -23,7 +23,7 @@ private static class Edge { private int to; private int weight; - public Edge(int from, int to, int weight) { + Edge(int from, int to, int weight) { this.from = from; this.to = to; this.weight = weight; diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java b/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java index 0348a60bc135..902553f9a54c 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/MatrixGraphs.java @@ -12,7 +12,9 @@ * * @author Unknown */ -public class MatrixGraphs { +public final class MatrixGraphs { + private MatrixGraphs() { + } public static void main(String[] args) { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10); @@ -46,17 +48,17 @@ class AdjacencyMatrixGraph { /** * The number of vertices in the graph */ - private int _numberOfVertices; + private int vertexCount; /** * The number of edges in the graph */ - private int _numberOfEdges; + private int edgeCount; /** * The adjacency matrix for the graph */ - private int[][] _adjacency; + private int[][] adjMatrix; /** * Static variables to define whether or not an edge exists in the adjacency @@ -68,7 +70,7 @@ class AdjacencyMatrixGraph { /** * Constructor */ - public AdjacencyMatrixGraph(int givenNumberOfVertices) { + AdjacencyMatrixGraph(int givenNumberOfVertices) { this.setNumberOfVertices(givenNumberOfVertices); this.setNumberOfEdges(0); this.setAdjacency(new int[givenNumberOfVertices][givenNumberOfVertices]); @@ -85,16 +87,16 @@ public AdjacencyMatrixGraph(int givenNumberOfVertices) { * @param newNumberOfVertices the new number of vertices */ private void setNumberOfVertices(int newNumberOfVertices) { - this._numberOfVertices = newNumberOfVertices; + this.vertexCount = newNumberOfVertices; } /** - * Getter for `this._numberOfVertices` + * Getter for `this.vertexCount` * * @return the number of vertices in the graph */ public int numberOfVertices() { - return this._numberOfVertices; + return this.vertexCount; } /** @@ -104,16 +106,16 @@ public int numberOfVertices() { * */ private void setNumberOfEdges(int newNumberOfEdges) { - this._numberOfEdges = newNumberOfEdges; + this.edgeCount = newNumberOfEdges; } /** - * Getter for `this._numberOfEdges` + * Getter for `this.edgeCount` * * @return the number of edges */ public int numberOfEdges() { - return this._numberOfEdges; + return this.edgeCount; } /** @@ -122,7 +124,7 @@ public int numberOfEdges() { * @param newAdjacency the new adjaceny matrix */ private void setAdjacency(int[][] newAdjacency) { - this._adjacency = newAdjacency; + this.adjMatrix = newAdjacency; } /** @@ -131,7 +133,7 @@ private void setAdjacency(int[][] newAdjacency) { * @return the adjacency matrix */ private int[][] adjacency() { - return this._adjacency; + return this.adjMatrix; } /** @@ -220,12 +222,12 @@ public boolean removeEdge(int from, int to) { */ public List<Integer> depthFirstOrder(int startVertex) { // If the startVertex is invalid, return an empty list - if (startVertex >= _numberOfVertices || startVertex < 0) { + if (startVertex >= vertexCount || startVertex < 0) { return new ArrayList<Integer>(); } // Create an array to track the visited vertices - boolean[] visited = new boolean[_numberOfVertices]; + boolean[] visited = new boolean[vertexCount]; // Create a list to keep track of the order of our traversal ArrayList<Integer> orderList = new ArrayList<Integer>(); @@ -257,7 +259,7 @@ private void depthFirstOrder(int currentVertex, boolean[] visited, List<Integer> orderList.add(currentVertex); // Get the adjacency array for this vertex - int[] adjacent = _adjacency[currentVertex]; + int[] adjacent = adjMatrix[currentVertex]; for (int i = 0; i < adjacent.length; i++) { // we are considering exploring, recurse on it // If an edge exists between the // currentVertex and the vertex if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) { @@ -275,12 +277,12 @@ private void depthFirstOrder(int currentVertex, boolean[] visited, List<Integer> */ public List<Integer> breadthFirstOrder(int startVertex) { // If the specified startVertex is invalid, return an empty list - if (startVertex >= _numberOfVertices || startVertex < 0) { + if (startVertex >= vertexCount || startVertex < 0) { return new ArrayList<Integer>(); } // Create an array to keep track of the visited vertices - boolean[] visited = new boolean[_numberOfVertices]; + boolean[] visited = new boolean[vertexCount]; // Create a list to keep track of the ordered vertices ArrayList<Integer> orderList = new ArrayList<Integer>(); @@ -307,7 +309,7 @@ public List<Integer> breadthFirstOrder(int startVertex) { // Get the adjacency array for the currentVertex and // check each node - int[] adjacent = _adjacency[currentVertex]; + int[] adjacent = adjMatrix[currentVertex]; for (int vertex = 0; vertex < adjacent.length; vertex++) { // vertex we are considering exploring, we add it to the queue // If an // edge exists between the current vertex and the if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) { @@ -334,7 +336,7 @@ public String toString() { for (int i = 0; i < this.numberOfVertices(); i++) { s = s + i + " : "; for (int j = 0; j < this.numberOfVertices(); j++) { - s = s + this._adjacency[i][j] + " "; + s = s + this.adjMatrix[i][j] + " "; } s = s + "\n"; } diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java b/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java index e61e2b6ac6ee..7e11862786f6 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/PrimMST.java @@ -14,16 +14,17 @@ class PrimMST { // 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; + int min = Integer.MAX_VALUE; + int minIndex = -1; for (int v = 0; v < V; v++) { if (!mstSet[v] && key[v] < min) { min = key[v]; - min_index = v; + minIndex = v; } } - return min_index; + return minIndex; } // A utility function to print the constructed MST stored in @@ -50,7 +51,7 @@ void primMST(int[][] graph) { // Initialize all keys as INFINITE for (int i = 0; i < V; i++) { key[i] = Integer.MAX_VALUE; - mstSet[i] = false; + mstSet[i] = Boolean.FALSE; } // Always include first 1st vertex in MST. @@ -65,7 +66,7 @@ void primMST(int[][] graph) { int u = minKey(key, mstSet); // Add the picked vertex to the MST Set - mstSet[u] = true; + mstSet[u] = Boolean.TRUE; // Update key value and parent index of the adjacent // vertices of the picked vertex. Consider only those diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java index 293ea5837823..987e73a2a5d5 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithm.java @@ -56,11 +56,11 @@ public class TarjansAlgorithm { // Timer for tracking lowtime and insertion time - private int Time; + private int time; - private List<List<Integer>> SCClist = new ArrayList<List<Integer>>(); + private List<List<Integer>> sccList = new ArrayList<List<Integer>>(); - public List<List<Integer>> stronglyConnectedComponents(int V, List<List<Integer>> graph) { + public List<List<Integer>> stronglyConnectedComponents(int v, List<List<Integer>> graph) { // Initially all vertices as unvisited, insertion and low time are undefined @@ -68,32 +68,32 @@ public List<List<Integer>> stronglyConnectedComponents(int V, List<List<Integer> // lowTime: indicates the earliest visited vertex (the vertex with minimum insertion time) // that can be reached from a subtree rooted with a particular node. - int[] lowTime = new int[V]; - int[] insertionTime = new int[V]; - for (int i = 0; i < V; i++) { + int[] lowTime = new int[v]; + int[] insertionTime = new int[v]; + for (int i = 0; i < v; i++) { insertionTime[i] = -1; lowTime[i] = -1; } // To check if element is present in stack - boolean[] isInStack = new boolean[V]; + boolean[] isInStack = new boolean[v]; // Store nodes during DFS Stack<Integer> st = new Stack<Integer>(); - for (int i = 0; i < V; i++) { + for (int i = 0; i < v; i++) { if (insertionTime[i] == -1) stronglyConnCompsUtil(i, lowTime, insertionTime, isInStack, st, graph); } - return SCClist; + return sccList; } private void stronglyConnCompsUtil(int u, int[] lowTime, int[] insertionTime, boolean[] isInStack, Stack<Integer> st, List<List<Integer>> graph) { // Initialize insertion time and lowTime value of current node - insertionTime[u] = Time; - lowTime[u] = Time; - Time += 1; + insertionTime[u] = time; + lowTime[u] = time; + time += 1; // Push current node into stack isInStack[u] = true; @@ -123,7 +123,7 @@ private void stronglyConnCompsUtil(int u, int[] lowTime, int[] insertionTime, bo scc.add(w); isInStack[w] = false; } - SCClist.add(scc); + sccList.add(scc); } } } diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java index 3b823f02388d..0981638d4903 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/WelshPowell.java @@ -17,7 +17,7 @@ public final class WelshPowell { private WelshPowell() { } - static class Graph { + static final class Graph { private HashSet<Integer>[] adjacencyLists; private Graph(int vertices) { diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java index 5a1ab7b6174b..9fbb2ff0ad62 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArray.java @@ -19,8 +19,8 @@ public GenericHashMapUsingArray() { // 75, then adding 76th item it will double the size, copy all elements // & then add 76th item. - private void initBuckets(int N) { - buckets = new LinkedList[N]; + private void initBuckets(int n) { + buckets = new LinkedList[n]; for (int i = 0; i < buckets.length; i++) { buckets[i] = new LinkedList<>(); } diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java index e45d827afec7..a1ef457f3432 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayList.java @@ -105,7 +105,7 @@ private class Node { K key; V val; - public Node(K key, V val) { + Node(K key, V val) { this.key = key; this.val = val; } diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java index 053751ebbc51..b48502b51d08 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/HashMapCuckooHashing.java @@ -12,21 +12,21 @@ public class HashMapCuckooHashing { private int tableSize; // size of the hash table private Integer[] buckets; // array representing the table - private final Integer AVAILABLE; + private final Integer emptySlot; private int size; // number of elements in the hash table private int thresh; // threshold for infinite loop checking /** * Constructor initializes buckets array, hsize, and creates dummy object - * for AVAILABLE + * for emptySlot * * @param tableSize the desired size of the hash map */ public HashMapCuckooHashing(int tableSize) { this.buckets = new Integer[tableSize]; this.tableSize = tableSize; - this.AVAILABLE = Integer.MIN_VALUE; + this.emptySlot = Integer.MIN_VALUE; this.size = 0; this.thresh = (int) (Math.log(tableSize) / Math.log(2)) + 2; } @@ -66,8 +66,10 @@ public int hashFunction2(int key) { */ public void insertKey2HashTable(int key) { - Integer wrappedInt = key, temp; - int hash, loopCounter = 0; + Integer wrappedInt = key; + Integer temp; + int hash; + int loopCounter = 0; if (isFull()) { System.out.println("Hash table is full, lengthening & rehashing table"); @@ -82,7 +84,7 @@ public void insertKey2HashTable(int key) { loopCounter++; hash = hashFunction1(key); - if ((buckets[hash] == null) || Objects.equals(buckets[hash], AVAILABLE)) { + if ((buckets[hash] == null) || Objects.equals(buckets[hash], emptySlot)) { buckets[hash] = wrappedInt; size++; checkLoadFactor(); @@ -93,7 +95,7 @@ public void insertKey2HashTable(int key) { buckets[hash] = wrappedInt; wrappedInt = temp; hash = hashFunction2(temp); - if (Objects.equals(buckets[hash], AVAILABLE)) { + if (Objects.equals(buckets[hash], emptySlot)) { buckets[hash] = wrappedInt; size++; checkLoadFactor(); @@ -122,7 +124,7 @@ public void insertKey2HashTable(int key) { public void reHashTableIncreasesTableSize() { HashMapCuckooHashing newT = new HashMapCuckooHashing(tableSize * 2); for (int i = 0; i < tableSize; i++) { - if (buckets[i] != null && !Objects.equals(buckets[i], AVAILABLE)) { + if (buckets[i] != null && !Objects.equals(buckets[i], emptySlot)) { newT.insertKey2HashTable(this.buckets[i]); } } @@ -144,14 +146,14 @@ public void deleteKeyFromHashTable(int key) { } if (Objects.equals(buckets[hash], wrappedInt)) { - buckets[hash] = AVAILABLE; + buckets[hash] = emptySlot; size--; return; } hash = hashFunction2(key); if (Objects.equals(buckets[hash], wrappedInt)) { - buckets[hash] = AVAILABLE; + buckets[hash] = emptySlot; size--; return; } @@ -163,7 +165,7 @@ public void deleteKeyFromHashTable(int key) { */ public void displayHashtable() { for (int i = 0; i < tableSize; i++) { - if ((buckets[i] == null) || Objects.equals(buckets[i], AVAILABLE)) { + if ((buckets[i] == null) || Objects.equals(buckets[i], emptySlot)) { System.out.println("Bucket " + i + ": Empty"); } else { System.out.println("Bucket " + i + ": " + buckets[i].toString()); @@ -213,7 +215,7 @@ public boolean checkTableContainsKey(int key) { public double checkLoadFactor() { double factor = (double) size / tableSize; if (factor > .7) { - System.out.printf("Load factor is %.2f , rehashing table\n", factor); + System.out.printf("Load factor is %.2f , rehashing table%n", factor); reHashTableIncreasesTableSize(); } return factor; @@ -227,7 +229,7 @@ public double checkLoadFactor() { public boolean isFull() { boolean response = true; for (int i = 0; i < tableSize; i++) { - if (buckets[i] == null || Objects.equals(buckets[i], AVAILABLE)) { + if (buckets[i] == null || Objects.equals(buckets[i], emptySlot)) { return false; } } diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java index ad3f617cef5a..54bd10de50fa 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Intersection.java @@ -12,7 +12,7 @@ import java.util.List; import java.util.Map; -public class Intersection { +public final class Intersection { public static List<Integer> intersection(int[] arr1, int[] arr2) { if (arr1 == null || arr2 == null || arr1.length == 0 || arr2.length == 0) { diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java index d68e01284ddd..082fd4b5ab2a 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/Main.java @@ -2,13 +2,16 @@ import java.util.Scanner; -public class Main { +public final class Main { + private Main() { + } public static void main(String[] args) { - int choice, key; + int choice; + int key; HashMap h = new HashMap(7); - Scanner In = new Scanner(System.in); + Scanner scan = new Scanner(System.in); while (true) { System.out.println("Enter your Choice :"); @@ -17,18 +20,18 @@ public static void main(String[] args) { System.out.println("3. Print Table"); System.out.println("4. Exit"); - choice = In.nextInt(); + choice = scan.nextInt(); switch (choice) { case 1: { System.out.println("Enter the Key: "); - key = In.nextInt(); + key = scan.nextInt(); h.insertHash(key); break; } case 2: { System.out.println("Enter the Key delete: "); - key = In.nextInt(); + key = scan.nextInt(); h.deleteHash(key); break; } @@ -38,9 +41,12 @@ public static void main(String[] args) { break; } case 4: { - In.close(); + scan.close(); return; } + default: { + throw new IllegalArgumentException("Unexpected value: " + choice); + } } } } diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java index 94d370b66976..5a4a56e9b37d 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MainCuckooHashing.java @@ -2,13 +2,16 @@ import java.util.Scanner; -public class MainCuckooHashing { +public final class MainCuckooHashing { + private MainCuckooHashing() { + } public static void main(String[] args) { - int choice, key; + int choice; + int key; HashMapCuckooHashing h = new HashMapCuckooHashing(7); - Scanner In = new Scanner(System.in); + Scanner scan = new Scanner(System.in); while (true) { System.out.println("_________________________"); @@ -21,18 +24,18 @@ public static void main(String[] args) { System.out.println("6. Check load factor"); System.out.println("7. Rehash Current Table"); - choice = In.nextInt(); + choice = scan.nextInt(); switch (choice) { case 1: { System.out.println("Enter the Key: "); - key = In.nextInt(); + key = scan.nextInt(); h.insertKey2HashTable(key); break; } case 2: { System.out.println("Enter the Key delete: "); - key = In.nextInt(); + key = scan.nextInt(); h.deleteKeyFromHashTable(key); break; } @@ -42,23 +45,26 @@ public static void main(String[] args) { break; } case 4: { - In.close(); + scan.close(); return; } case 5: { System.out.println("Enter the Key to find and print: "); - key = In.nextInt(); + key = scan.nextInt(); System.out.println("Key: " + key + " is at index: " + h.findKeyInTable(key) + "\n"); break; } case 6: { - System.out.printf("Load factor is: %.2f\n", h.checkLoadFactor()); + System.out.printf("Load factor is: %.2f%n", h.checkLoadFactor()); break; } case 7: { h.reHashTableIncreasesTableSize(); break; } + default: { + throw new IllegalArgumentException("Unexpected value: " + choice); + } } } } diff --git a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java index e3364b0e16fb..bfa5759a41b9 100644 --- a/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java +++ b/src/main/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElement.java @@ -8,7 +8,9 @@ This class finds the majority element(s) in an array of integers. A majority element is an element that appears more than or equal to n/2 times, where n is the length of the array. */ -public class MajorityElement { +public final class MajorityElement { + private MajorityElement() { + } /* This method returns the majority element(s) in the given array of integers. @param nums: an array of integers diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java b/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java index f18e4d4a960f..11af3f39981c 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/EmptyHeapException.java @@ -10,4 +10,8 @@ public class EmptyHeapException extends Exception { public EmptyHeapException(String message) { super(message); } + + public EmptyHeapException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java index 23c26cfd0aab..d546b7cc88d4 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/GenericHeap.java @@ -1,6 +1,7 @@ package com.thealgorithms.datastructures.heaps; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; public class GenericHeap<T extends Comparable<T>> { diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java index cfec2b3c54bd..59cb9dfab700 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/LeftistHeap.java @@ -13,14 +13,17 @@ */ public class LeftistHeap { - private class Node { - private int element, npl; - private Node left, right; + private static final class Node { + private final int element; + private int npl; + private Node left; + private Node right; // Node constructor setting the data element and left/right pointers to null private Node(int element) { this.element = element; - left = right = null; + left = null; + right = null; npl = 0; } } @@ -88,7 +91,7 @@ public void insert(int a) { } // Returns and removes the minimum element in the heap - public int extract_min() { + public int extractMin() { // If is empty return -1 if (isEmpty()) return -1; @@ -98,17 +101,17 @@ public int extract_min() { } // Function returning a list of an in order traversal of the data structure - public ArrayList<Integer> in_order() { + public ArrayList<Integer> inOrder() { ArrayList<Integer> lst = new ArrayList<>(); - in_order_aux(root, lst); + inOrderAux(root, lst); return new ArrayList<>(lst); } // Auxiliary function for in_order - private void in_order_aux(Node n, ArrayList<Integer> lst) { + private void inOrderAux(Node n, ArrayList<Integer> lst) { if (n == null) return; - in_order_aux(n.left, lst); + inOrderAux(n.left, lst); lst.add(n.element); - in_order_aux(n.right, lst); + inOrderAux(n.right, lst); } } diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java index faf9fb92e5ca..9a584da0411c 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MaxHeap.java @@ -91,7 +91,7 @@ private HeapElement extractMax() { } @Override - public void insertElement(HeapElement element) { + public final void insertElement(HeapElement element) { maxHeap.add(element); toggleUp(maxHeap.size()); } @@ -123,7 +123,7 @@ public HeapElement getElement() throws EmptyHeapException { try { return extractMax(); } catch (Exception e) { - throw new EmptyHeapException("Heap is empty. Error retrieving element"); + throw new EmptyHeapException("Heap is empty. Error retrieving element", e); } } } diff --git a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java index 288a1932ddad..f7ff0ec5a73d 100644 --- a/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java +++ b/src/main/java/com/thealgorithms/datastructures/heaps/MinHeap.java @@ -85,7 +85,7 @@ private HeapElement extractMin() { } @Override - public void insertElement(HeapElement element) { + public final void insertElement(HeapElement element) { minHeap.add(element); toggleUp(minHeap.size()); } @@ -117,7 +117,7 @@ public HeapElement getElement() throws EmptyHeapException { try { return extractMin(); } catch (Exception e) { - throw new EmptyHeapException("Heap is empty. Error retrieving element"); + throw new EmptyHeapException("Heap is empty. Error retrieving element", e); } } } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java index c42b10455d14..6eb9d75fe58f 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CircleLinkedList.java @@ -2,7 +2,7 @@ public class CircleLinkedList<E> { - private static class Node<E> { + private static final class Node<E> { Node<E> next; E value; diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java b/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java index 182c8f75fe55..441c95702050 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CreateAndDetectLoop.java @@ -2,7 +2,9 @@ import java.util.Scanner; -public class CreateAndDetectLoop { +public final class CreateAndDetectLoop { + private CreateAndDetectLoop() { + } /** * Prints the linked list. @@ -79,7 +81,7 @@ public static void main(String[] args) { System.out.println("Enter the number of elements to be inserted: "); int n = sc.nextInt(); - System.out.printf("Enter the %d elements: \n", n); + System.out.printf("Enter the %d elements: %n", n); while (n-- > 0) { singlyLinkedList.insert(sc.nextInt()); } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java index 22399bd6a459..b4fa9c51d4dc 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/CursorLinkedList.java @@ -108,25 +108,25 @@ 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)) { + T tempElement = cursorSpace[head].element; + int tempNext = cursorSpace[head].next; + if (tempElement.equals(element)) { free(head); - head = temp_next; + head = tempNext; } 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); + int prevIndex = head; + int currentIndex = cursorSpace[prevIndex].next; + + while (currentIndex != -1) { + T currentElement = cursorSpace[currentIndex].element; + if (currentElement.equals(element)) { + cursorSpace[prevIndex].next = cursorSpace[currentIndex].next; + free(currentIndex); break; } - prev_index = current_index; - current_index = cursorSpace[prev_index].next; + prevIndex = currentIndex; + currentIndex = cursorSpace[prevIndex].next; } } @@ -134,11 +134,11 @@ public void remove(T element) { } private void free(int index) { - Node<T> os_node = cursorSpace[os]; - int os_next = os_node.next; + Node<T> osNode = cursorSpace[os]; + int osNext = osNode.next; cursorSpace[os].next = index; cursorSpace[index].element = null; - cursorSpace[index].next = os_next; + cursorSpace[index].next = osNext; } public void append(T element) { diff --git a/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java index 89117786c35e..58898ddc0fcf 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/DoublyLinkedList.java @@ -13,7 +13,7 @@ * * @author Unknown */ -public class DoublyLinkedList { +public final class DoublyLinkedList { /** * Head refers to the front of the list @@ -110,7 +110,7 @@ class Link { * * @param value Value of node */ - public Link(int value) { + Link(int value) { this.value = value; } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java index 80b36b8e4ab1..99ab09f81c1c 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/MergeSortedArrayList.java @@ -6,7 +6,9 @@ /** * @author https://github.com/shellhub */ -public class MergeSortedArrayList { +public final class MergeSortedArrayList { + private MergeSortedArrayList() { + } public static void main(String[] args) { List<Integer> listA = new ArrayList<>(); 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 index 7206ccecf25e..a714eda18bcd 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/Merge_K_SortedLinkedlist.java @@ -13,15 +13,15 @@ public class Merge_K_SortedLinkedlist { * This function merge K sorted LinkedList * * @param a array of LinkedList - * @param N size of array + * @param n size of array * @return node */ - Node mergeKList(Node[] a, int N) { + Node mergeKList(Node[] a, int n) { // Min Heap PriorityQueue<Node> min = new PriorityQueue<>(Comparator.comparingInt(x -> x.data)); // adding head of all linkedList in min heap - min.addAll(Arrays.asList(a).subList(0, N)); + min.addAll(Arrays.asList(a).subList(0, n)); // Make new head among smallest heads in K linkedList Node head = min.poll(); @@ -43,7 +43,7 @@ Node mergeKList(Node[] a, int N) { return head; } - private class Node { + private final class Node { private int data; private Node next; diff --git a/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java b/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java index bd599e2ab91f..3c4b9331266c 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/ReverseKGroup.java @@ -23,17 +23,17 @@ public Node reverse(Node head, int count, int k) { Node prev = null; int count1 = 0; Node curr = head; - Node Next = null; + Node next = null; while (curr != null && count1 < k) { - Next = curr.next; + next = curr.next; curr.next = prev; prev = curr; - curr = Next; + curr = next; count1++; } - if (Next != null) { - head.next = reverse(Next, count - k, k); + if (next != null) { + head.next = reverse(next, count - k, k); } return prev; } diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java index f379e9eccded..bca3c77f2724 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/SinglyLinkedList.java @@ -82,13 +82,15 @@ public void swapNodes(int valueFirst, int valueSecond) { if (valueFirst == valueSecond) { return; } - Node previousA = null, currentA = head; + Node previousA = null; + Node currentA = head; while (currentA != null && currentA.value != valueFirst) { previousA = currentA; currentA = currentA.next; } - Node previousB = null, currentB = head; + Node previousB = null; + Node currentB = head; while (currentB != null && currentB.value != valueSecond) { previousB = currentB; currentB = currentB.next; diff --git a/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java b/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java index 33e3fd7cdb20..3309ab24917d 100644 --- a/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java +++ b/src/main/java/com/thealgorithms/datastructures/lists/SkipList.java @@ -1,6 +1,11 @@ package com.thealgorithms.datastructures.lists; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Random; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -222,7 +227,7 @@ private static class Node<E> { private final List<Node<E>> backward; @SuppressWarnings("unchecked") - public Node(E value, int height) { + Node(E value, int height) { this.value = value; this.height = height; diff --git a/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java index 9530c5a69d8c..cd3761bdcf75 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java @@ -54,7 +54,8 @@ public int deQueue() { int res = arr[beginningOfQueue]; arr[beginningOfQueue] = Integer.MIN_VALUE; if (beginningOfQueue == topOfQueue) { - beginningOfQueue = topOfQueue = -1; + beginningOfQueue = -1; + topOfQueue = -1; } else if (beginningOfQueue + 1 == size) { beginningOfQueue = 0; } else { diff --git a/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java index b9331569e131..ec1e15e415b8 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/GenericArrayListQueue.java @@ -15,7 +15,7 @@ public class GenericArrayListQueue<T> { /** * The generic ArrayList for the queue T is the generic element */ - ArrayList<T> _queue = new ArrayList<>(); + ArrayList<T> elementList = new ArrayList<>(); /** * Checks if the queue has elements (not empty). @@ -23,7 +23,7 @@ public class GenericArrayListQueue<T> { * @return True if the queue has elements. False otherwise. */ private boolean hasElements() { - return !_queue.isEmpty(); + return !elementList.isEmpty(); } /** @@ -35,7 +35,7 @@ private boolean hasElements() { public T peek() { T result = null; if (this.hasElements()) { - result = _queue.get(0); + result = elementList.get(0); } return result; } @@ -47,7 +47,7 @@ public T peek() { * @return True if the element was added successfully */ public boolean add(T element) { - return _queue.add(element); + return elementList.add(element); } /** @@ -58,7 +58,7 @@ public boolean add(T element) { public T pull() { T result = null; if (this.hasElements()) { - result = _queue.remove(0); + result = elementList.remove(0); } return result; } diff --git a/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java b/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java index 8b33e08c3808..171f24e09396 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/LinkedQueue.java @@ -11,15 +11,15 @@ static class Node<T> { T data; Node<T> next; - public Node() { + Node() { this(null); } - public Node(T data) { + Node(T data) { this(data, null); } - public Node(T data, Node<T> next) { + Node(T data, Node<T> next) { this.data = data; this.next = next; } @@ -44,7 +44,9 @@ public Node(T data, Node<T> next) { * Init LinkedQueue */ public LinkedQueue() { - front = rear = new Node<>(); + + front = new Node<>(); + rear = front; } /** @@ -146,7 +148,11 @@ public boolean hasNext() { @Override public T next() { - return (node = node.next).data; + if (hasNext()) { + node = node.next; + return node.data; + } + throw new NoSuchElementException(); } }; } diff --git a/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java b/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java index dec25d2ff694..16a0c1673886 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/PriorityQueues.java @@ -30,7 +30,7 @@ class PriorityQueue { * Default Constructor */ - public PriorityQueue() { + PriorityQueue() { /* If capacity is not defined, default size of 11 would be used * capacity=max+1 because we cant access 0th element of PQ, and to * accomodate (max)th elements we need capacity to be max+1. @@ -50,7 +50,7 @@ public PriorityQueue() { * @param size Size of the queue */ - public PriorityQueue(int size) { + PriorityQueue(int size) { maxSize = size + 1; queueArray = new int[maxSize]; nItems = 0; diff --git a/src/main/java/com/thealgorithms/datastructures/queues/Queues.java b/src/main/java/com/thealgorithms/datastructures/queues/Queues.java index bcc292b3e9a9..2f364b7cbb6b 100644 --- a/src/main/java/com/thealgorithms/datastructures/queues/Queues.java +++ b/src/main/java/com/thealgorithms/datastructures/queues/Queues.java @@ -38,7 +38,7 @@ class Queue { /** * init with DEFAULT_CAPACITY */ - public Queue() { + Queue() { this(DEFAULT_CAPACITY); } @@ -47,7 +47,7 @@ public Queue() { * * @param size Size of the new queue */ - public Queue(int size) { + Queue(int size) { maxSize = size; queueArray = new int[size]; front = 0; @@ -152,7 +152,9 @@ public String toString() { * * @author Unknown */ -public class Queues { +public final class Queues { + private Queues() { + } /** * Main method diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java index 900d697f36f7..7c4f334cd617 100644 --- a/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/NodeStack.java @@ -11,20 +11,20 @@ public class NodeStack<Item> { * Entry point for the program. */ public static void main(String[] args) { - NodeStack<Integer> Stack = new NodeStack<Integer>(); + NodeStack<Integer> stack = new NodeStack<Integer>(); - Stack.push(3); - Stack.push(4); - Stack.push(5); + stack.push(3); + stack.push(4); + stack.push(5); System.out.println("Testing :"); - Stack.print(); // prints : 5 4 3 + stack.print(); // prints : 5 4 3 - Integer x = Stack.pop(); // x = 5 - Stack.push(1); - Stack.push(8); - Integer y = Stack.peek(); // y = 8 + 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 + stack.print(); // prints : 8 1 4 3 System.out.println("Testing :"); System.out.println("x : " + x); diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java index c9d2ea05778b..84e9df96e0d9 100644 --- a/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/ReverseStack.java @@ -8,7 +8,9 @@ * * @author Ishika Agarwal, 2021 */ -public class ReverseStack { +public final class ReverseStack { + private ReverseStack() { + } public static void main(String[] args) { try (Scanner sc = new Scanner(System.in)) { @@ -20,7 +22,6 @@ public static void main(String[] args) { for (i = 0; i < n; i++) { stack.push(sc.nextInt()); } - sc.close(); reverseStack(stack); System.out.println("The reversed stack is:"); while (!stack.isEmpty()) { diff --git a/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java b/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java index 0463018fde82..52b1c1d86c94 100644 --- a/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java +++ b/src/main/java/com/thealgorithms/datastructures/stacks/StackOfLinkedList.java @@ -6,7 +6,9 @@ * @author Varun Upadhyay (https://github.com/varunu28) */ // An implementation of a Stack using a Linked List -class StackOfLinkedList { +final class StackOfLinkedList { + private StackOfLinkedList() { + } public static void main(String[] args) { LinkedListStack stack = new LinkedListStack(); @@ -33,7 +35,7 @@ class Node { public int data; public Node next; - public Node(int data) { + Node(int data) { this.data = data; this.next = null; } @@ -60,7 +62,7 @@ class LinkedListStack { /** * Init properties */ - public LinkedListStack() { + LinkedListStack() { head = null; size = 0; } diff --git a/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java index 1032daa240f8..052da616fe8e 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/AVLSimple.java @@ -112,10 +112,10 @@ private int bf(Node node) { private Node rightRotate(Node c) { Node b = c.left; - Node T3 = b.right; + Node t3 = b.right; b.right = c; - c.left = T3; + c.left = t3; c.height = Math.max(height(c.left), height(c.right)) + 1; b.height = Math.max(height(b.left), height(b.right)) + 1; return b; @@ -123,10 +123,10 @@ private Node rightRotate(Node c) { private Node leftRotate(Node c) { Node b = c.right; - Node T3 = b.left; + Node t3 = b.left; b.left = c; - c.right = T3; + c.right = t3; c.height = Math.max(height(c.left), height(c.right)) + 1; b.height = Math.max(height(b.left), height(b.right)) + 1; return b; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java b/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java index b56a71421ed3..7b959b085353 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/AVLTree.java @@ -9,7 +9,9 @@ private class Node { private int key; private int balance; private int height; - private Node left, right, parent; + private Node left; + private Node right; + private Node parent; Node(int k, Node p) { key = k; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java b/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java index 9066a6f231be..1962eaa0a106 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/BSTFromSortedArray.java @@ -9,7 +9,9 @@ * left half recursively to create left subtree 3. Use the right half * recursively to create right subtree */ -public class BSTFromSortedArray { +public final class BSTFromSortedArray { + private BSTFromSortedArray() { + } public static Node createBST(int[] array) { if (array == null || array.length == 0) { return null; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java b/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java index d699b436d6b9..d4d677a4cda0 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/BinaryTree.java @@ -47,7 +47,7 @@ static class Node { * * @param value Value to put in the node */ - public Node(int value) { + Node(int value) { data = value; left = null; right = null; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java b/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java index 6e1454f6859b..f238b5e9fe8d 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/CeilInBinarySearchTree.java @@ -42,7 +42,9 @@ * subtree. If left subtree returns a non-null value then that will be ceil * otherwise the root is ceil */ -public class CeilInBinarySearchTree { +public final class CeilInBinarySearchTree { + private CeilInBinarySearchTree() { + } public static Node getCeil(Node root, int key) { if (root == null) { diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java b/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java index c034452f7221..0c2b44d78d74 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/CheckBinaryTreeIsValidBST.java @@ -8,7 +8,9 @@ * where 'min' and 'max' values represent the child nodes (left, right). * 2. The smallest possible node value is Integer.MIN_VALUE, the biggest - Integer.MAX_VALUE. */ -public class CheckBinaryTreeIsValidBST { +public final class CheckBinaryTreeIsValidBST { + private CheckBinaryTreeIsValidBST() { + } public static boolean isBST(BinaryTree.Node root) { return isBSTUtil(root, Integer.MIN_VALUE, Integer.MAX_VALUE); } diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java b/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java index 566536256558..9aa4d5a1fef2 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/CheckIfBinaryTreeBalanced.java @@ -14,7 +14,9 @@ * * @author [Ian Cowan](<a href="https://github.com/iccowan">Git-Ian Cowan</a>) */ -public class CheckIfBinaryTreeBalanced { +public final class CheckIfBinaryTreeBalanced { + private CheckIfBinaryTreeBalanced() { + } /** * Recursive is BT balanced implementation * diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java b/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java index def455dde051..17d84bf11d54 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/CheckTreeIsSymmetric.java @@ -30,7 +30,9 @@ * * @author kumanoit on 10/10/22 IST 12:52 AM */ -public class CheckTreeIsSymmetric { +public final class CheckTreeIsSymmetric { + private CheckTreeIsSymmetric() { + } public static boolean isSymmetric(Node root) { if (root == null) { diff --git a/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java b/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java index 8303c658dfb8..04caa0b9e9d2 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/CreateBinaryTreeFromInorderPreorder.java @@ -17,7 +17,9 @@ * Complexity: Time: O(n) hashmap reduced iteration to find index in inorder * array Space: O(n) space taken by hashmap */ -public class CreateBinaryTreeFromInorderPreorder { +public final class CreateBinaryTreeFromInorderPreorder { + private CreateBinaryTreeFromInorderPreorder() { + } public static Node createTree(final Integer[] preorder, final Integer[] inorder) { if (preorder == null || inorder == null) { return null; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java b/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java index 5cd28202229e..5378a01f6642 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/FenwickTree.java @@ -3,12 +3,12 @@ public class FenwickTree { private int n; - private int[] fen_t; + private int[] fenTree; /* 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]; + this.fenTree = new int[n + 1]; } /* A function which will add the element val at index i*/ @@ -16,7 +16,7 @@ public void update(int i, int val) { // As index starts from 0, increment the index by 1 i += 1; while (i <= n) { - fen_t[i] += val; + fenTree[i] += val; i += i & (-i); } } @@ -27,7 +27,7 @@ public int query(int i) { i += 1; int cumSum = 0; while (i > 0) { - cumSum += fen_t[i]; + cumSum += fenTree[i]; i -= i & (-i); } return cumSum; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java b/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java index d348467815c7..a2e36f33dd4b 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/GenericTree.java @@ -16,7 +16,7 @@ */ public class GenericTree { - private static class Node { + private static final class Node { int data; ArrayList<Node> child = new ArrayList<>(); @@ -25,10 +25,10 @@ private static class Node { private final Node root; public GenericTree() { // Constructor Scanner scn = new Scanner(System.in); - root = create_treeG(null, 0, scn); + root = createTreeG(null, 0, scn); } - private Node create_treeG(Node node, int childIndex, Scanner scanner) { + private Node createTreeG(Node node, int childIndex, Scanner scanner) { // display if (node == null) { System.out.println("Enter root's data"); @@ -41,7 +41,7 @@ private Node create_treeG(Node node, int childIndex, Scanner scanner) { System.out.println("number of children"); int number = scanner.nextInt(); for (int i = 0; i < number; i++) { - Node child = create_treeG(node, i, scanner); + Node child = createTreeG(node, i, scanner); node.child.add(child); } return node; @@ -51,17 +51,17 @@ private Node create_treeG(Node node, int childIndex, Scanner scanner) { * Function to display the generic tree */ public void display() { // Helper function - display_1(root); + display1(root); } - private void display_1(Node parent) { + private void display1(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)); + display1(parent.child.get(i)); } } diff --git a/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java index 6441375568ad..3bae17ed1bb8 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/InorderTraversal.java @@ -25,7 +25,9 @@ * * @author Albina Gimaletdinova on 21/02/2023 */ -public class InorderTraversal { +public final class InorderTraversal { + private InorderTraversal() { + } public static List<Integer> recursiveInorder(BinaryTree.Node root) { List<Integer> result = new ArrayList<>(); recursiveInorder(root, result); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java b/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java index 577c0055d9b6..e5528c392bb8 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/KDTree.java @@ -68,19 +68,23 @@ public int getDimension() { return coordinates.length; } - public Point(int[] coordinates) { + Point(int[] coordinates) { this.coordinates = coordinates; } @Override public boolean equals(Object obj) { if (obj instanceof Point other) { - if (other.getDimension() != this.getDimension()) return false; return Arrays.equals(other.coordinates, this.coordinates); } return false; } + @Override + public int hashCode() { + return Arrays.hashCode(coordinates); + } + @Override public String toString() { return Arrays.toString(coordinates); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/LCA.java b/src/main/java/com/thealgorithms/datastructures/trees/LCA.java index d45f0d4f4301..95a289493007 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/LCA.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/LCA.java @@ -3,26 +3,30 @@ import java.util.ArrayList; import java.util.Scanner; -public class LCA { +public final class LCA { + private LCA() { + } - private static final Scanner scanner = new Scanner(System.in); + private static final Scanner SCANNER = new Scanner(System.in); public static void main(String[] args) { // The adjacency list representation of a tree: ArrayList<ArrayList<Integer>> adj = new ArrayList<>(); // v is the number of vertices and e is the number of edges - int v = scanner.nextInt(), e = v - 1; + int v = SCANNER.nextInt(); + int e = v - 1; for (int i = 0; i < v; i++) { adj.add(new ArrayList<Integer>()); } // Storing the given tree as an adjacency list - int to, from; + int to; + int from; for (int i = 0; i < e; i++) { - to = scanner.nextInt(); - from = scanner.nextInt(); + to = SCANNER.nextInt(); + from = SCANNER.nextInt(); adj.get(to).add(from); adj.get(from).add(to); @@ -38,7 +42,8 @@ public static void main(String[] args) { dfs(adj, 0, -1, parent, depth); // Inputting the two vertices whose LCA is to be calculated - int v1 = scanner.nextInt(), v2 = scanner.nextInt(); + int v1 = SCANNER.nextInt(); + int v2 = SCANNER.nextInt(); // Outputting the LCA System.out.println(getLCA(v1, v2, depth, parent)); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java b/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java index b5a9db9f5e11..1d8febff4b5f 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/LazySegmentTree.java @@ -10,12 +10,14 @@ public class LazySegmentTree { */ static class Node { - private final int start, end; // start and end of the segment represented by this node + private final int start; + private final int end; // start and end of the segment represented by this node private int value; // value is the sum of all elements in the range [start, end) private int lazy; // lazied value that should be added to children nodes - Node left, right; // left and right children + Node left; + Node right; // left and right children - public Node(int start, int end, int value) { + Node(int start, int end, int value) { this.start = start; this.end = end; this.value = value; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java index e61085cf4def..f91aa303f66c 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/LevelOrderTraversal.java @@ -5,7 +5,9 @@ import java.util.List; import java.util.Queue; -public class LevelOrderTraversal { +public final class LevelOrderTraversal { + private LevelOrderTraversal() { + } public static List<List<Integer>> traverse(BinaryTree.Node root) { if (root == null) { diff --git a/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java index f7afb60ac348..50dc88381a24 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/PostOrderTraversal.java @@ -1,6 +1,10 @@ package com.thealgorithms.datastructures.trees; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; /** * Given tree is traversed in a 'post-order' way: LEFT -> RIGHT -> ROOT. @@ -22,7 +26,9 @@ * * @author Albina Gimaletdinova on 21/02/2023 */ -public class PostOrderTraversal { +public final class PostOrderTraversal { + private PostOrderTraversal() { + } public static List<Integer> recursivePostOrder(BinaryTree.Node root) { List<Integer> result = new ArrayList<>(); recursivePostOrder(root, result); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java index d0a5bc4ac3f0..6a0eef369407 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/PreOrderTraversal.java @@ -25,7 +25,9 @@ * * @author Albina Gimaletdinova on 17/02/2023 */ -public class PreOrderTraversal { +public final class PreOrderTraversal { + private PreOrderTraversal() { + } public static List<Integer> recursivePreOrder(BinaryTree.Node root) { List<Integer> result = new ArrayList<>(); recursivePreOrder(root, result); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java b/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java index a2dbeca5ebac..3ef664f3fa7d 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/PrintTopViewofTree.java @@ -10,12 +10,14 @@ class TreeNode { // Members int key; - TreeNode left, right; + TreeNode left; + TreeNode right; // Constructor - public TreeNode(int key) { + TreeNode(int key) { this.key = key; - left = right = null; + left = null; + right = null; } } @@ -27,7 +29,7 @@ class QItem { TreeNode node; int hd; - public QItem(TreeNode n, int h) { + QItem(TreeNode n, int h) { node = n; hd = h; } @@ -39,11 +41,11 @@ class Tree { TreeNode root; // Constructors - public Tree() { + Tree() { root = null; } - public Tree(TreeNode n) { + Tree(TreeNode n) { root = n; } @@ -58,13 +60,13 @@ public void printTopView() { HashSet<Integer> set = new HashSet<>(); // Create a queue and add root to it - Queue<QItem> Q = new LinkedList<QItem>(); - Q.add(new QItem(root, 0)); // Horizontal distance of root is 0 + Queue<QItem> queue = new LinkedList<QItem>(); + queue.add(new QItem(root, 0)); // Horizontal distance of root is 0 // Standard BFS or level order traversal loop - while (!Q.isEmpty()) { + while (!queue.isEmpty()) { // Remove the front item and get its details - QItem qi = Q.remove(); + QItem qi = queue.remove(); int hd = qi.hd; TreeNode n = qi.node; @@ -77,17 +79,19 @@ public void printTopView() { // Enqueue left and right children of current node if (n.left != null) { - Q.add(new QItem(n.left, hd - 1)); + queue.add(new QItem(n.left, hd - 1)); } if (n.right != null) { - Q.add(new QItem(n.right, hd + 1)); + queue.add(new QItem(n.right, hd + 1)); } } } } // Driver class to test above methods -public class PrintTopViewofTree { +public final class PrintTopViewofTree { + private PrintTopViewofTree() { + } public static void main(String[] args) { /* Create following Binary Tree diff --git a/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java b/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java index ebdcba40ae7c..01222b739ff0 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/RedBlackBST.java @@ -7,13 +7,16 @@ */ public class RedBlackBST { - private final int R = 0; - private final int B = 1; + private static final int RED = 0; + private static final int BLACK = 1; private class Node { - int key = -1, color = B; - Node left = nil, right = nil, p = nil; + int key = -1; + int color = BLACK; + Node left = nil; + Node right = nil; + Node p = nil; Node(int key) { this.key = key; @@ -28,7 +31,7 @@ public void printTree(Node node) { return; } printTree(node.left); - System.out.print(((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); + System.out.print(((node.color == RED) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); printTree(node.right); } @@ -36,7 +39,7 @@ 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"); + System.out.print(((node.color == RED) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); printTreepre(node.left); printTreepre(node.right); } @@ -63,10 +66,10 @@ private void insert(Node node) { Node temp = root; if (root == nil) { root = node; - node.color = B; + node.color = BLACK; node.p = nil; } else { - node.color = R; + node.color = RED; while (true) { if (node.key < temp.key) { if (temp.left == nil) { @@ -91,15 +94,15 @@ private void insert(Node node) { } private void fixTree(Node node) { - while (node.p.color == R) { + while (node.p.color == RED) { 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; + if (y != nil && y.color == RED) { + node.p.color = BLACK; + y.color = BLACK; + node.p.p.color = RED; node = node.p.p; continue; } @@ -107,15 +110,15 @@ private void fixTree(Node node) { node = node.p; rotateLeft(node); } - node.p.color = B; - node.p.p.color = R; + node.p.color = BLACK; + node.p.p.color = RED; 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; + if (y != nil && y.color == RED) { + node.p.color = BLACK; + y.color = BLACK; + node.p.p.color = RED; node = node.p.p; continue; } @@ -123,12 +126,12 @@ private void fixTree(Node node) { node = node.p; rotateRight(node); } - node.p.color = B; - node.p.p.color = R; + node.p.color = BLACK; + node.p.p.color = RED; rotateLeft(node.p.p); } } - root.color = B; + root.color = BLACK; } void rotateLeft(Node node) { @@ -201,7 +204,8 @@ Node treeMinimum(Node subTreeRoot) { } boolean delete(Node z) { - if ((z = findNode(z, root)) == null) { + Node result = findNode(z, root); + if (result == null) { return false; } Node x; @@ -230,67 +234,67 @@ boolean delete(Node z) { y.left.p = y; y.color = z.color; } - if (yorigcolor == B) { + if (yorigcolor == BLACK) { deleteFixup(x); } return true; } void deleteFixup(Node x) { - while (x != root && x.color == B) { + while (x != root && x.color == BLACK) { if (x == x.p.left) { Node w = x.p.right; - if (w.color == R) { - w.color = B; - x.p.color = R; + if (w.color == RED) { + w.color = BLACK; + x.p.color = RED; rotateLeft(x.p); w = x.p.right; } - if (w.left.color == B && w.right.color == B) { - w.color = R; + if (w.left.color == BLACK && w.right.color == BLACK) { + w.color = RED; x = x.p; continue; - } else if (w.right.color == B) { - w.left.color = B; - w.color = R; + } else if (w.right.color == BLACK) { + w.left.color = BLACK; + w.color = RED; rotateRight(w); w = x.p.right; } - if (w.right.color == R) { + if (w.right.color == RED) { w.color = x.p.color; - x.p.color = B; - w.right.color = B; + x.p.color = BLACK; + w.right.color = BLACK; rotateLeft(x.p); x = root; } } else { Node w = x.p.left; - if (w.color == R) { - w.color = B; - x.p.color = R; + if (w.color == RED) { + w.color = BLACK; + x.p.color = RED; rotateRight(x.p); w = x.p.left; } - if (w.right.color == B && w.left.color == B) { - w.color = R; + if (w.right.color == BLACK && w.left.color == BLACK) { + w.color = RED; x = x.p; continue; - } else if (w.left.color == B) { - w.right.color = B; - w.color = R; + } else if (w.left.color == BLACK) { + w.right.color = BLACK; + w.color = RED; rotateLeft(w); w = x.p.left; } - if (w.left.color == R) { + if (w.left.color == RED) { w.color = x.p.color; - x.p.color = B; - w.left.color = B; + x.p.color = BLACK; + w.left.color = BLACK; rotateRight(x.p); x = root; } } } - x.color = B; + x.color = BLACK; } public void insertDemo() { diff --git a/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java b/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java index aede2a23b544..883eadd1840a 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/SameTreesCheck.java @@ -32,7 +32,9 @@ * * @author Albina Gimaletdinova on 13/01/2023 */ -public class SameTreesCheck { +public final class SameTreesCheck { + private SameTreesCheck() { + } public static boolean check(BinaryTree.Node p, BinaryTree.Node q) { if (p == null && q == null) { return true; diff --git a/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java b/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java index 295628334516..57b3edc163ca 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/SegmentTree.java @@ -2,7 +2,7 @@ public class SegmentTree { - private int[] seg_t; + private int[] segTree; private int n; private int[] arr; @@ -10,38 +10,38 @@ public class SegmentTree { public SegmentTree(int n, int[] arr) { this.n = n; int x = (int) (Math.ceil(Math.log(n) / Math.log(2))); - int seg_size = 2 * (int) Math.pow(2, x) - 1; + int segSize = 2 * (int) Math.pow(2, x) - 1; - this.seg_t = new int[seg_size]; + this.segTree = new int[segSize]; this.arr = 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) { + public final int constructTree(int[] arr, int start, int end, int index) { if (start == end) { - this.seg_t[index] = arr[start]; + this.segTree[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); - return this.seg_t[index]; + this.segTree[index] = constructTree(arr, start, mid, index * 2 + 1) + constructTree(arr, mid + 1, end, index * 2 + 2); + return this.segTree[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) { + private void updateTree(int start, int end, int index, int diff, int segIndex) { if (index < start || index > end) { return; } - this.seg_t[seg_index] += diff; + this.segTree[segIndex] += 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, segIndex * 2 + 1); + updateTree(mid + 1, end, index, diff, segIndex * 2 + 2); } } @@ -58,17 +58,17 @@ public void update(int index, int value) { /* 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]; + private int getSumTree(int start, int end, int qStart, int qEnd, int segIndex) { + if (qStart <= start && qEnd >= end) { + return this.segTree[segIndex]; } - if (q_start > end || q_end < start) { + if (qStart > end || qEnd < 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)); + return (getSumTree(start, mid, qStart, qEnd, segIndex * 2 + 1) + getSumTree(mid + 1, end, qStart, qEnd, segIndex * 2 + 2)); } /* A function to query the sum of the subarray [start...end]*/ diff --git a/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java b/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java index eeb253d9d342..cf56731fb079 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/TreeRandomNode.java @@ -26,10 +26,11 @@ the inOrder() method to store the values in the arraylist, then find the size of public class TreeRandomNode { - private class Node { + private final class Node { int item; - Node left, right; + Node left; + Node right; } // Using an arraylist to store the inorder traversal of the given binary tree diff --git a/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java index a42b4370de68..c1d15390d4b9 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/VerticalOrderTraversal.java @@ -20,7 +20,9 @@ the sequence will be : 4 2 7 1 5 9 3 8 6 10 */ -public class VerticalOrderTraversal { +public final class VerticalOrderTraversal { + private VerticalOrderTraversal() { + } /*Function that receives a root Node and prints the tree in Vertical Order.*/ @@ -45,7 +47,8 @@ public static ArrayList<Integer> verticalTraversal(BinaryTree.Node root) { /* min and max stores leftmost and right most index to later print the tree in vertical fashion.*/ - int max = 0, min = 0; + int max = 0; + int min = 0; queue.offer(root); index.offer(0); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java b/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java index d5bfd68e97e4..84fe0eb2c42a 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/ZigzagTraversal.java @@ -1,6 +1,10 @@ package com.thealgorithms.datastructures.trees; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.LinkedList; +import java.util.List; /** * Given a binary tree. @@ -30,7 +34,9 @@ * * @author Albina Gimaletdinova on 11/01/2023 */ -public class ZigzagTraversal { +public final class ZigzagTraversal { + private ZigzagTraversal() { + } public static List<List<Integer>> traverse(BinaryTree.Node root) { if (root == null) { return List.of(); diff --git a/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java b/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java index 913ccda3828c..6c53666e5856 100644 --- a/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java +++ b/src/main/java/com/thealgorithms/datastructures/trees/nearestRightKey.java @@ -3,10 +3,12 @@ import java.util.Scanner; import java.util.concurrent.ThreadLocalRandom; -class Main { +final class NearestRightKey { + private NearestRightKey() { + } public static void main(String[] args) { - NRKTree root = BuildTree(); + NRKTree root = buildTree(); Scanner sc = new Scanner(System.in); System.out.print("Enter first number: "); int inputX0 = sc.nextInt(); @@ -15,7 +17,7 @@ public static void main(String[] args) { sc.close(); } - public static NRKTree BuildTree() { + public static NRKTree buildTree() { int randomX = ThreadLocalRandom.current().nextInt(0, 100 + 1); NRKTree root = new NRKTree(null, null, randomX); @@ -53,13 +55,13 @@ class NRKTree { public NRKTree right; public int data; - public NRKTree(int x) { + NRKTree(int x) { this.left = null; this.right = null; this.data = x; } - public NRKTree(NRKTree right, NRKTree left, int x) { + NRKTree(NRKTree right, NRKTree left, int x) { this.left = left; this.right = right; this.data = x; diff --git a/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java b/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java index a70b16b0d069..de829585891a 100644 --- a/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java +++ b/src/main/java/com/thealgorithms/divideandconquer/BinaryExponentiation.java @@ -27,14 +27,15 @@ public static long calculatePower(long x, long y) { } // iterative function to calculate a to the power of b - long power(long N, long M) { - long power = N, sum = 1; - while (M > 0) { - if ((M & 1) == 1) { + long power(long n, long m) { + long power = n; + long sum = 1; + while (m > 0) { + if ((m & 1) == 1) { sum *= power; } power = power * power; - M = M >> 1; + m = m >> 1; } return sum; } diff --git a/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java b/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java index 4c25066a3553..86a6f3e11483 100644 --- a/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java +++ b/src/main/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplication.java @@ -18,124 +18,124 @@ public class StrassenMatrixMultiplication { // Function to multiply matrices - public int[][] multiply(int[][] A, int[][] B) { - int n = A.length; + public int[][] multiply(int[][] a, int[][] b) { + int n = a.length; - int[][] R = new int[n][n]; + int[][] mat = new int[n][n]; if (n == 1) { - R[0][0] = A[0][0] * B[0][0]; + mat[0][0] = a[0][0] * b[0][0]; } else { // Dividing Matrix into parts // by storing sub-parts to variables - int[][] A11 = new int[n / 2][n / 2]; - int[][] A12 = new int[n / 2][n / 2]; - int[][] A21 = new int[n / 2][n / 2]; - int[][] A22 = new int[n / 2][n / 2]; - int[][] B11 = new int[n / 2][n / 2]; - int[][] B12 = new int[n / 2][n / 2]; - int[][] B21 = new int[n / 2][n / 2]; - int[][] B22 = new int[n / 2][n / 2]; + int[][] a11 = new int[n / 2][n / 2]; + int[][] a12 = new int[n / 2][n / 2]; + int[][] a21 = new int[n / 2][n / 2]; + int[][] a22 = new int[n / 2][n / 2]; + int[][] b11 = new int[n / 2][n / 2]; + 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); + 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); + 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)); + // m1:=(A1+A3)×(B1+B2) + int[][] m1 = multiply(add(a11, a22), add(b11, b22)); - // M2:=(A2+A4)×(B3+B4) - int[][] M2 = multiply(add(A21, A22), B11); + // m2:=(A2+A4)×(B3+B4) + int[][] m2 = multiply(add(a21, a22), b11); - // M3:=(A1−A4)×(B1+A4) - int[][] M3 = multiply(A11, sub(B12, B22)); + // m3:=(A1−A4)×(B1+A4) + int[][] m3 = multiply(a11, sub(b12, b22)); - // M4:=A1×(B2−B4) - int[][] M4 = multiply(A22, sub(B21, B11)); + // m4:=A1×(B2−B4) + int[][] m4 = multiply(a22, sub(b21, b11)); - // M5:=(A3+A4)×(B1) - int[][] M5 = multiply(add(A11, A12), B22); + // m5:=(A3+A4)×(B1) + int[][] m5 = multiply(add(a11, a12), b22); - // M6:=(A1+A2)×(B4) - int[][] M6 = multiply(sub(A21, A11), add(B11, B12)); + // m6:=(A1+A2)×(B4) + int[][] m6 = multiply(sub(a21, a11), add(b11, b12)); - // M7:=A4×(B3−B1) - int[][] M7 = multiply(sub(A12, A22), add(B21, B22)); + // m7:=A4×(B3−B1) + int[][] m7 = multiply(sub(a12, a22), add(b21, b22)); - // P:=M2+M3−M6−M7 - int[][] C11 = add(sub(add(M1, M4), M5), M7); + // P:=m2+m3−m6−m7 + int[][] c11 = add(sub(add(m1, m4), m5), m7); - // Q:=M4+M6 - int[][] C12 = add(M3, M5); + // Q:=m4+m6 + int[][] c12 = add(m3, m5); - // R:=M5+M7 - int[][] C21 = add(M2, M4); + // mat:=m5+m7 + int[][] c21 = add(m2, m4); - // S:=M1−M3−M4−M5 - int[][] C22 = add(sub(add(M1, M3), M2), M6); + // S:=m1−m3−m4−m5 + int[][] c22 = add(sub(add(m1, m3), m2), m6); - join(C11, R, 0, 0); - join(C12, R, 0, n / 2); - join(C21, R, n / 2, 0); - join(C22, R, n / 2, n / 2); + join(c11, mat, 0, 0); + join(c12, mat, 0, n / 2); + join(c21, mat, n / 2, 0); + join(c22, mat, n / 2, n / 2); } - return R; + return mat; } // Function to subtract two matrices - public int[][] sub(int[][] A, int[][] B) { - int n = A.length; + public int[][] sub(int[][] a, int[][] b) { + int n = a.length; - int[][] C = new int[n][n]; + int[][] c = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { - C[i][j] = A[i][j] - B[i][j]; + c[i][j] = a[i][j] - b[i][j]; } } - return C; + return c; } // Function to add two matrices - public int[][] add(int[][] A, int[][] B) { - int n = A.length; + public int[][] add(int[][] a, int[][] b) { + int n = a.length; - int[][] C = new int[n][n]; + int[][] c = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { - C[i][j] = A[i][j] + B[i][j]; + c[i][j] = a[i][j] + b[i][j]; } } - return C; + return c; } // 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++) { - C[i1][j1] = P[i2][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]; } } } // 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++) { - P[i2][j2] = C[i1][j1]; + 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]; } } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java b/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java index 7deb81448b55..b041cfc478d6 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/BoardPath.java @@ -25,7 +25,9 @@ */ -public class BoardPath { +public final class BoardPath { + private BoardPath() { + } public static long startTime; public static long endTime; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java b/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java index 52d7bffa4980..3fa8728930cb 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/BoundaryFill.java @@ -4,50 +4,52 @@ * Java program for Boundary fill algorithm. * @author Akshay Dubey (https://github.com/itsAkshayDubey) */ -public class BoundaryFill { +public final class BoundaryFill { + private BoundaryFill() { + } /** * Get the color at the given co-odrinates of a 2D image * * @param image The image to be filled - * @param x_co_ordinate The x co-ordinate of which color is to be obtained - * @param y_co_ordinate The y co-ordinate of which color is to be obtained + * @param xCoordinate The x co-ordinate of which color is to be obtained + * @param yCoordinate The y co-ordinate of which color is to be obtained */ - public static int getPixel(int[][] image, int x_co_ordinate, int y_co_ordinate) { - return image[x_co_ordinate][y_co_ordinate]; + public static int getPixel(int[][] image, int xCoordinate, int yCoordinate) { + return image[xCoordinate][yCoordinate]; } /** * Put the color at the given co-odrinates of a 2D image * * @param image The image to be filed - * @param x_co_ordinate The x co-ordinate at which color is to be filled - * @param y_co_ordinate The y co-ordinate at which color is to be filled + * @param xCoordinate The x co-ordinate at which color is to be filled + * @param yCoordinate The y co-ordinate at which color is to be filled */ - public static void putPixel(int[][] image, int x_co_ordinate, int y_co_ordinate, int new_color) { - image[x_co_ordinate][y_co_ordinate] = new_color; + public static void putPixel(int[][] image, int xCoordinate, int yCoordinate, int newColor) { + image[xCoordinate][yCoordinate] = newColor; } /** * Fill the 2D image with new color * * @param image The image to be filed - * @param x_co_ordinate The x co-ordinate at which color is to be filled - * @param y_co_ordinate The y co-ordinate at which color is to be filled - * @param new_color The new color which to be filled in the image - * @param boundary_color The old color which is to be replaced in the image + * @param xCoordinate The x co-ordinate at which color is to be filled + * @param yCoordinate The y co-ordinate at which color is to be filled + * @param newColor The new color which to be filled in the image + * @param boundaryColor The old color which is to be replaced in the image */ - public static void boundaryFill(int[][] image, int x_co_ordinate, int y_co_ordinate, int new_color, int boundary_color) { - if (x_co_ordinate >= 0 && y_co_ordinate >= 0 && getPixel(image, x_co_ordinate, y_co_ordinate) != new_color && getPixel(image, x_co_ordinate, y_co_ordinate) != boundary_color) { - putPixel(image, x_co_ordinate, y_co_ordinate, new_color); - boundaryFill(image, x_co_ordinate + 1, y_co_ordinate, new_color, boundary_color); - boundaryFill(image, x_co_ordinate - 1, y_co_ordinate, new_color, boundary_color); - boundaryFill(image, x_co_ordinate, y_co_ordinate + 1, new_color, boundary_color); - boundaryFill(image, x_co_ordinate, y_co_ordinate - 1, new_color, boundary_color); - boundaryFill(image, x_co_ordinate + 1, y_co_ordinate - 1, new_color, boundary_color); - boundaryFill(image, x_co_ordinate - 1, y_co_ordinate + 1, new_color, boundary_color); - boundaryFill(image, x_co_ordinate + 1, y_co_ordinate + 1, new_color, boundary_color); - boundaryFill(image, x_co_ordinate - 1, y_co_ordinate - 1, new_color, boundary_color); + public static void boundaryFill(int[][] image, int xCoordinate, int yCoordinate, int newColor, int boundaryColor) { + if (xCoordinate >= 0 && yCoordinate >= 0 && getPixel(image, xCoordinate, yCoordinate) != newColor && getPixel(image, xCoordinate, yCoordinate) != boundaryColor) { + putPixel(image, xCoordinate, yCoordinate, newColor); + boundaryFill(image, xCoordinate + 1, yCoordinate, newColor, boundaryColor); + boundaryFill(image, xCoordinate - 1, yCoordinate, newColor, boundaryColor); + boundaryFill(image, xCoordinate, yCoordinate + 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate, yCoordinate - 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate + 1, yCoordinate - 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate - 1, yCoordinate + 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate + 1, yCoordinate + 1, newColor, boundaryColor); + boundaryFill(image, xCoordinate - 1, yCoordinate - 1, newColor, boundaryColor); } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java index 77d997fc2adc..b433c44b9077 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/BruteForceKnapsack.java @@ -2,13 +2,15 @@ /* A Naive recursive implementation of 0-1 Knapsack problem */ -public class BruteForceKnapsack { +public final class BruteForceKnapsack { + private BruteForceKnapsack() { + } // 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) { + static int knapSack(int w, int[] wt, int[] val, int n) { // Base Case - if (n == 0 || W == 0) { + if (n == 0 || w == 0) { return 0; } @@ -16,13 +18,13 @@ static int knapSack(int W, int[] wt, int[] val, int n) { // 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); + 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 Math.max(val[n - 1] + knapSack(W - wt[n - 1], wt, val, n - 1), knapSack(W, wt, val, n - 1)); + return Math.max(val[n - 1] + knapSack(w - wt[n - 1], wt, val, n - 1), knapSack(w, wt, val, n - 1)); } } @@ -30,8 +32,8 @@ static int knapSack(int W, int[] wt, int[] val, int n) { public static void main(String[] args) { int[] val = new int[] {60, 100, 120}; int[] wt = new int[] {10, 20, 30}; - int W = 50; + int w = 50; int n = val.length; - System.out.println(knapSack(W, wt, val, n)); + System.out.println(knapSack(w, wt, val, n)); } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java b/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java index 5db7d39f1d99..8658bca3df52 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/CatalanNumber.java @@ -10,7 +10,9 @@ */ import java.util.Scanner; -public class CatalanNumber { +public final class CatalanNumber { + private CatalanNumber() { + } /** * This method finds the nth Catalan number diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java b/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java index 58ba1351109c..d79ed3c23e13 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ClimbingStairs.java @@ -5,7 +5,9 @@ Link : https://medium.com/analytics-vidhya/leetcode-q70-climbing-stairs-easy-444a4aae54e8 */ -public class ClimbingStairs { +public final class ClimbingStairs { + private ClimbingStairs() { + } public static int numberOfWays(int n) { diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java b/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java index b5be0b2660bf..12cc29faa923 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/CoinChange.java @@ -3,7 +3,9 @@ /** * @author Varun Upadhyay (https://github.com/varunu28) */ -public class CoinChange { +public final class CoinChange { + private CoinChange() { + } // Driver Program public static void main(String[] args) { @@ -56,9 +58,9 @@ public static int minimumCoins(int[] coins, int amount) { 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; + int subRes = minimumCoins[i - coin]; + if (subRes != Integer.MAX_VALUE && subRes + 1 < minimumCoins[i]) { + minimumCoins[i] = subRes + 1; } } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java b/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java index e18725405394..8c70c9c3fada 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/CountFriendsPairing.java @@ -15,7 +15,9 @@ package com.thealgorithms.dynamicprogramming; -public class CountFriendsPairing { +public final class CountFriendsPairing { + private CountFriendsPairing() { + } public static boolean countFriendsPairing(int n, int[] a) { int[] dp = new int[n + 1]; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java b/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java index 84f9cf6a83d8..e1be3ead5895 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/DiceThrow.java @@ -13,7 +13,9 @@ And it can be done using Dynamic Programming(DP). // Code ----> // Java program to find number of ways to get sum 'x' with 'n' // dice where every dice has 'm' faces -class DP { +final class DP { + private DP() { + } /* The main function that returns the number of ways to get sum 'x' with 'n' dice and 'm' with m * faces. */ diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java b/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java index 68877811092e..6db30514db68 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/EditDistance.java @@ -24,7 +24,9 @@ */ import java.util.Scanner; -public class EditDistance { +public final class EditDistance { + private EditDistance() { + } public static int minDistance(String word1, String word2) { int len1 = word1.length(); @@ -69,7 +71,8 @@ then take the minimum of the various operations(i.e insertion,removal,substituti public static void main(String[] args) { Scanner input = new Scanner(System.in); - String s1, s2; + String s1; + String s2; System.out.println("Enter the First String"); s1 = input.nextLine(); System.out.println("Enter the Second String"); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java b/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java index ef1ff49465f3..be52ab166f18 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/EggDropping.java @@ -3,12 +3,15 @@ /** * DynamicProgramming solution for the Egg Dropping Puzzle */ -public class EggDropping { +public final class EggDropping { + private EggDropping() { + } // min trials with n eggs and m floors public static int minTrials(int n, int m) { int[][] eggFloor = new int[n + 1][m + 1]; - int result, x; + int result; + int x; for (int i = 1; i <= n; i++) { eggFloor[i][0] = 0; // Zero trial for zero floor. @@ -39,7 +42,8 @@ public static int minTrials(int n, int m) { } public static void main(String[] args) { - int n = 2, m = 4; + int n = 2; + int 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 index f2a3b2b8f542..5855030fc65c 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java @@ -7,9 +7,11 @@ /** * @author Varun Upadhyay (https://github.com/varunu28) */ -public class Fibonacci { +public final class Fibonacci { + private Fibonacci() { + } - private static Map<Integer, Integer> map = new HashMap<>(); + private static final Map<Integer, Integer> CACHE = 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, ...] @@ -30,8 +32,8 @@ public static void main(String[] args) { * Outputs the nth fibonacci number */ public static int fibMemo(int n) { - if (map.containsKey(n)) { - return map.get(n); + if (CACHE.containsKey(n)) { + return CACHE.get(n); } int f; @@ -40,7 +42,7 @@ public static int fibMemo(int n) { f = n; } else { f = fibMemo(n - 1) + fibMemo(n - 2); - map.put(n, f); + CACHE.put(n, f); } return f; } @@ -84,7 +86,9 @@ public static int fibOptimized(int n) { if (n == 0) { return 0; } - int prev = 0, res = 1, next; + int prev = 0; + int res = 1; + int next; for (int i = 2; i <= n; i++) { next = prev + res; prev = res; @@ -106,7 +110,6 @@ public static int fibOptimized(int n) { public static int fibBinet(int n) { double squareRootOf5 = Math.sqrt(5); double phi = (1 + squareRootOf5) / 2; - int nthTerm = (int) ((Math.pow(phi, n) - Math.pow(-phi, -n)) / squareRootOf5); - return nthTerm; + return (int) ((Math.pow(phi, n) - Math.pow(-phi, -n)) / squareRootOf5); } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java b/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java index 63ec477c4590..6168ec6ec09f 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/FordFulkerson.java @@ -4,17 +4,20 @@ import java.util.Queue; import java.util.Vector; -public class FordFulkerson { +public final class FordFulkerson { + private FordFulkerson() { + } static final int INF = 987654321; // edges - static int V; - static int[][] capacity, flow; + static int vertexCount; + static int[][] capacity; + static int[][] flow; public static void main(String[] args) { - System.out.println("V : 6"); - V = 6; - capacity = new int[V][V]; + System.out.println("Vertex Count : 6"); + vertexCount = 6; + capacity = new int[vertexCount][vertexCount]; capacity[0][1] = 12; capacity[0][3] = 13; @@ -30,11 +33,11 @@ public static void main(String[] args) { } private static int networkFlow(int source, int sink) { - flow = new int[V][V]; + flow = new int[vertexCount][vertexCount]; int totalFlow = 0; while (true) { - Vector<Integer> parent = new Vector<>(V); - for (int i = 0; i < V; i++) { + Vector<Integer> parent = new Vector<>(vertexCount); + for (int i = 0; i < vertexCount; i++) { parent.add(-1); } Queue<Integer> q = new LinkedList<>(); @@ -43,7 +46,7 @@ private static int networkFlow(int source, int sink) { while (!q.isEmpty() && parent.get(sink) == -1) { int here = q.peek(); q.poll(); - for (int there = 0; there < V; ++there) { + for (int there = 0; there < vertexCount; ++there) { if (capacity[here][there] - flow[here][there] > 0 && parent.get(there) == -1) { q.add(there); parent.set(there, here); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java b/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java index 51cd6e50ea43..de75126044ae 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KadaneAlgorithm.java @@ -6,20 +6,23 @@ /** Program description - To find the maximum subarray sum */ package com.thealgorithms.dynamicprogramming; -public class KadaneAlgorithm { +public final class KadaneAlgorithm { + private KadaneAlgorithm() { + } - public static boolean max_Sum(int[] a, int predicted_answer) { - int sum = a[0], running_sum = 0; + public static boolean maxSum(int[] a, int predictedAnswer) { + int sum = a[0]; + int runningSum = 0; for (int k : a) { - running_sum = running_sum + k; + runningSum = runningSum + k; // running sum of all the indexs are stored - sum = Math.max(sum, running_sum); + sum = Math.max(sum, runningSum); // the max is stored inorder to the get the maximum sum - if (running_sum < 0) running_sum = 0; + if (runningSum < 0) runningSum = 0; // if running sum is negative then it is initialized to zero } // for-each loop is used to iterate over the array and find the maximum subarray sum - return sum == predicted_answer; + return sum == predictedAnswer; // It returns true if sum and predicted answer matches // The predicted answer is the answer itself. So it always return true } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java index 290e98caebae..396efb1a7893 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/KnapsackMemoization.java @@ -40,8 +40,15 @@ int solveKnapsackRecursive(int capacity, int[] weights, int[] profits, int numOf dpTable[numOfItems][capacity] = solveKnapsackRecursive(capacity, weights, profits, numOfItems - 1, dpTable); return dpTable[numOfItems][capacity]; } else { - // Return value of table after storing - return dpTable[numOfItems][capacity] = Math.max((profits[numOfItems - 1] + solveKnapsackRecursive(capacity - weights[numOfItems - 1], weights, profits, numOfItems - 1, dpTable)), solveKnapsackRecursive(capacity, weights, profits, numOfItems - 1, dpTable)); + // case 1. include the item, if it is less than the capacity + final int includeCurrentItem = profits[numOfItems - 1] + solveKnapsackRecursive(capacity - weights[numOfItems - 1], weights, profits, numOfItems - 1, dpTable); + + // case 2. exclude the item if it is more than the capacity + final int excludeCurrentItem = solveKnapsackRecursive(capacity, weights, profits, numOfItems - 1, dpTable); + + // Store the value of function call stack in table and return + dpTable[numOfItems][capacity] = Math.max(includeCurrentItem, excludeCurrentItem); + return dpTable[numOfItems][capacity]; } } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java b/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java index c4c9bbee9a78..119d65dfe365 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LevenshteinDistance.java @@ -1,49 +1,84 @@ package com.thealgorithms.dynamicprogramming; +import java.util.stream.IntStream; + /** - * @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) + * Provides functions to calculate the Levenshtein distance between two strings. + * + * The Levenshtein distance is a measure of the similarity between two strings by calculating the minimum number of single-character + * edits (insertions, deletions, or substitutions) required to change one string into the other. */ -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; - } +public final class LevenshteinDistance { + private LevenshteinDistance() { } - public static int calculateLevenshteinDistance(String str1, String str2) { - int len1 = str1.length() + 1; - int len2 = str2.length() + 1; - int[][] distanceMat = new int[len1][len2]; - for (int i = 0; i < len1; i++) { - distanceMat[i][0] = i; - } - for (int j = 0; j < len2; j++) { - distanceMat[0][j] = j; + /** + * Calculates the Levenshtein distance between two strings using a naive dynamic programming approach. + * + * This function computes the Levenshtein distance by constructing a dynamic programming matrix and iteratively filling it in. + * It follows the standard top-to-bottom, left-to-right approach for filling in the matrix. + * + * @param string1 The first string. + * @param string2 The second string. + * @return The Levenshtein distance between the two input strings. + * + * Time complexity: O(nm), + * Space complexity: O(nm), + * + * where n and m are lengths of `string1` and `string2`. + * + * Note that this implementation uses a straightforward dynamic programming approach without any space optimization. + * It may consume more memory for larger input strings compared to the optimized version. + */ + public static int naiveLevenshteinDistance(final String string1, final String string2) { + int[][] distanceMatrix = IntStream.rangeClosed(0, string1.length()).mapToObj(i -> IntStream.rangeClosed(0, string2.length()).map(j -> (i == 0) ? j : (j == 0) ? i : 0).toArray()).toArray(int[][] ::new); + + IntStream.range(1, string1.length() + 1).forEach(i -> IntStream.range(1, string2.length() + 1).forEach(j -> { + final int cost = (string1.charAt(i - 1) == string2.charAt(j - 1)) ? 0 : 1; + distanceMatrix[i][j] = Math.min(distanceMatrix[i - 1][j - 1] + cost, Math.min(distanceMatrix[i][j - 1] + 1, distanceMatrix[i - 1][j] + 1)); + })); + + return distanceMatrix[string1.length()][string2.length()]; + } + + /** + * Calculates the Levenshtein distance between two strings using an optimized dynamic programming approach. + * + * This edit distance is defined as 1 point per insertion, substitution, or deletion required to make the strings equal. + * + * @param string1 The first string. + * @param string2 The second string. + * @return The Levenshtein distance between the two input strings. + * + * Time complexity: O(nm), + * Space complexity: O(n), + * + * where n and m are lengths of `string1` and `string2`. + * + * Note that this implementation utilizes an optimized dynamic programming approach, significantly reducing the space complexity from O(nm) to O(n), where n and m are the lengths of `string1` and `string2`. + * + * Additionally, it minimizes space usage by leveraging the shortest string horizontally and the longest string vertically in the computation matrix. + */ + public static int optimizedLevenshteinDistance(final String string1, final String string2) { + if (string1.isEmpty()) { + return string2.length(); } - for (int i = 1; i < len1; i++) { - for (int j = 1; j < len2; j++) { - if (str1.charAt(i - 1) == str2.charAt(j - 1)) { - distanceMat[i][j] = distanceMat[i - 1][j - 1]; - } else { - distanceMat[i][j] = 1 + minimum(distanceMat[i - 1][j], distanceMat[i - 1][j - 1], distanceMat[i][j - 1]); - } + + int[] previousDistance = IntStream.rangeClosed(0, string1.length()).toArray(); + + for (int j = 1; j <= string2.length(); j++) { + int prevSubstitutionCost = previousDistance[0]; + previousDistance[0] = j; + + for (int i = 1; i <= string1.length(); i++) { + final int deletionCost = previousDistance[i] + 1; + final int insertionCost = previousDistance[i - 1] + 1; + final int substitutionCost = (string1.charAt(i - 1) == string2.charAt(j - 1)) ? prevSubstitutionCost : prevSubstitutionCost + 1; + prevSubstitutionCost = previousDistance[i]; + previousDistance[i] = Math.min(deletionCost, Math.min(insertionCost, substitutionCost)); } } - return distanceMat[len1 - 1][len2 - 1]; - } - - public static void main(String[] args) { - String str1 = ""; // enter your string here - String str2 = ""; // enter your string here - System.out.print("Levenshtein distance between " + str1 + " and " + str2 + " is: "); - System.out.println(calculateLevenshteinDistance(str1, str2)); + return previousDistance[string1.length()]; } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java index 5b508e036ae3..d6f9b2acf768 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestAlternatingSubsequence.java @@ -11,10 +11,12 @@ x1 < x2 > x3 < x4 > x5 < …. xn or x1 > x2 < x3 > x4 < x5 > …. xn */ -public class LongestAlternatingSubsequence { +public final class LongestAlternatingSubsequence { + private LongestAlternatingSubsequence() { + } /* Function to return longest alternating subsequence length*/ - static int AlternatingLength(int[] arr, int n) { + static int alternatingLength(int[] arr, int n) { /* las[i][0] = Length of the longest @@ -32,7 +34,8 @@ static int AlternatingLength(int[] arr, int n) { int[][] las = new int[n][2]; // las = LongestAlternatingSubsequence for (int i = 0; i < n; i++) { - las[i][0] = las[i][1] = 1; + las[i][0] = 1; + las[i][1] = 1; } int result = 1; // Initialize result @@ -65,6 +68,6 @@ 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)); + + "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 index 72fbc89397c0..2d1fa1d1153f 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestCommonSubsequence.java @@ -1,6 +1,8 @@ package com.thealgorithms.dynamicprogramming; -class LongestCommonSubsequence { +final class LongestCommonSubsequence { + private LongestCommonSubsequence() { + } public static String getLCS(String str1, String str2) { // At least one string is null @@ -39,7 +41,8 @@ public static String getLCS(String str1, String str2) { public static String lcsString(String str1, String str2, int[][] lcsMatrix) { StringBuilder lcs = new StringBuilder(); - int i = str1.length(), j = str2.length(); + int i = str1.length(); + int j = str2.length(); while (i > 0 && j > 0) { if (str1.charAt(i - 1) == str2.charAt(j - 1)) { lcs.append(str1.charAt(i - 1)); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java index e7a54f213ac1..470833ce9c97 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequence.java @@ -1,24 +1,10 @@ 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(); +public final class LongestIncreasingSubsequence { + private LongestIncreasingSubsequence() { } private static int upperBound(int[] ar, int l, int r, int key) { @@ -34,19 +20,19 @@ private static int upperBound(int[] ar, int l, int r, int key) { return r; } - private static int LIS(int[] array) { - int N = array.length; - if (N == 0) { + public static int lis(int[] array) { + int len = array.length; + if (len == 0) { return 0; } - int[] tail = new int[N]; + int[] tail = new int[len]; // always points empty slot in tail int length = 1; tail[0] = array[0]; - for (int i = 1; i < N; i++) { + for (int i = 1; i < len; i++) { // new smallest value if (array[i] < tail[0]) { tail[0] = array[i]; @@ -71,14 +57,17 @@ else if (array[i] > tail[length - 1]) { */ // A function for finding the length of the LIS algorithm in O(nlogn) complexity. public static int findLISLen(int[] a) { - int size = a.length; + final int size = a.length; + if (size == 0) { + return 0; + } 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]); + int index = binarySearchBetween(arr, lis - 1, a[i]); arr[index] = a[i]; - if (index > lis) { + if (index == lis) { lis++; } } @@ -97,7 +86,7 @@ private static int binarySearchBetween(int[] t, int end, int key) { return end + 1; } while (left < right - 1) { - int middle = (left + right) / 2; + final int middle = (left + right) >>> 1; if (t[middle] < key) { left = middle; } else { diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java index c40d91100f30..0b40d4559341 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubsequence.java @@ -4,20 +4,22 @@ * Algorithm explanation * https://www.educative.io/edpresso/longest-palindromic-subsequence-algorithm */ -public class LongestPalindromicSubsequence { +public final class LongestPalindromicSubsequence { + private LongestPalindromicSubsequence() { + } public static void main(String[] args) { String a = "BBABCBCAB"; String b = "BABCBAB"; - String aLPS = LPS(a); - String bLPS = LPS(b); + 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 { + public static String lps(String original) throws IllegalArgumentException { StringBuilder reverse = new StringBuilder(original); reverse = reverse.reverse(); return recursiveLPS(original, reverse.toString()); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java index 0704272963fd..c6ae55919b82 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestPalindromicSubstring.java @@ -3,25 +3,28 @@ /* * Algorithm explanation https://leetcode.com/problems/longest-palindromic-substring/ */ -public class LongestPalindromicSubstring { +public final class LongestPalindromicSubstring { + private LongestPalindromicSubstring() { + } public static void main(String[] args) { String a = "babad"; String b = "cbbd"; - String aLPS = LPS(a); - String bLPS = LPS(b); + String aLPS = lps(a); + String bLPS = lps(b); System.out.println(a + " => " + aLPS); System.out.println(b + " => " + bLPS); } - private static String LPS(String input) { + 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; + int start = 0; + int end = 0; for (int g = 0; g < input.length(); g++) { for (int i = 0, j = g; j < input.length(); i++, j++) { if (g == 0) { diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java b/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java index 5ceb85c984ca..02696bfca9c2 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/LongestValidParentheses.java @@ -7,7 +7,9 @@ * @author Libin Yang (https://github.com/yanglbme) * @since 2018/10/5 */ -public class LongestValidParentheses { +public final class LongestValidParentheses { + private LongestValidParentheses() { + } public static int getLongestValidParentheses(String s) { if (s == null || s.length() < 2) { diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java index 6dec5b418c50..45568d21f295 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainMultiplication.java @@ -4,10 +4,12 @@ import java.util.Arrays; import java.util.Scanner; -public class MatrixChainMultiplication { +public final class MatrixChainMultiplication { + private MatrixChainMultiplication() { + } - private static Scanner scan = new Scanner(System.in); - private static ArrayList<Matrix> mArray = new ArrayList<>(); + private static final Scanner SCANNER = new Scanner(System.in); + private static final ArrayList<Matrix> MATRICES = new ArrayList<>(); private static int size; private static int[][] m; private static int[][] s; @@ -24,14 +26,14 @@ public static void main(String[] args) { int row = Integer.parseInt(mSize[1]); Matrix matrix = new Matrix(count, col, row); - mArray.add(matrix); + MATRICES.add(matrix); count++; } - for (Matrix m : mArray) { + for (Matrix m : MATRICES) { System.out.format("A(%d) = %2d x %2d%n", m.count(), m.col(), m.row()); } - size = mArray.size(); + size = MATRICES.size(); m = new int[size + 1][size + 1]; s = new int[size + 1][size + 1]; p = new int[size + 1]; @@ -42,7 +44,7 @@ public static void main(String[] args) { } for (int i = 0; i < p.length; i++) { - p[i] = i == 0 ? mArray.get(i).col() : mArray.get(i - 1).row(); + p[i] = i == 0 ? MATRICES.get(i).col() : MATRICES.get(i - 1).row(); } matrixChainOrder(); @@ -109,15 +111,15 @@ private static void matrixChainOrder() { private static String[] input(String string) { System.out.print(string); - return (scan.nextLine().split(" ")); + return (SCANNER.nextLine().split(" ")); } } class Matrix { - private int count; - private int col; - private int row; + private final int count; + private final int col; + private final int row; Matrix(int count, int col, int row) { this.count = count; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java index ed9ccd8c0073..6c1c4cf54ffc 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MatrixChainRecursiveTopDownMemoisation.java @@ -6,9 +6,11 @@ // 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 { +public final class MatrixChainRecursiveTopDownMemoisation { + private MatrixChainRecursiveTopDownMemoisation() { + } - static int Memoized_Matrix_Chain(int[] p) { + static int memoizedMatrixChain(int[] p) { int n = p.length; int[][] m = new int[n][n]; for (int i = 0; i < n; i++) { @@ -16,10 +18,10 @@ static int Memoized_Matrix_Chain(int[] p) { m[i][j] = Integer.MAX_VALUE; } } - return Lookup_Chain(m, p, 1, n - 1); + return lookupChain(m, p, 1, n - 1); } - static int Lookup_Chain(int[][] m, int[] p, int i, int j) { + static int lookupChain(int[][] m, int[] p, int i, int j) { if (i == j) { m[i][j] = 0; return m[i][j]; @@ -28,7 +30,7 @@ static int Lookup_Chain(int[][] m, int[] p, int i, int j) { return m[i][j]; } else { for (int k = i; k < j; k++) { - int q = Lookup_Chain(m, p, i, k) + Lookup_Chain(m, p, k + 1, j) + (p[i - 1] * p[k] * p[j]); + int q = lookupChain(m, p, i, k) + lookupChain(m, p, k + 1, j) + (p[i - 1] * p[k] * p[j]); if (q < m[i][j]) { m[i][j] = q; } @@ -41,6 +43,6 @@ static int Lookup_Chain(int[][] m, int[] p, int i, int j) { // respectively output should be Minimum number of multiplications is 38 public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; - System.out.println("Minimum number of multiplications is " + Memoized_Matrix_Chain(arr)); + System.out.println("Minimum number of multiplications is " + memoizedMatrixChain(arr)); } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java b/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java index 5aa0bf027c02..5d31d40dacdc 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/NewManShanksPrime.java @@ -8,18 +8,21 @@ package com.thealgorithms.dynamicprogramming; -public class NewManShanksPrime { +public final class NewManShanksPrime { + private NewManShanksPrime() { + } - public static boolean nthManShanksPrime(int n, int expected_answer) { + public static boolean nthManShanksPrime(int n, int expectedAnswer) { int[] a = new int[n + 1]; // array of n+1 size is initialized - a[0] = a[1] = 1; + a[0] = 1; + a[1] = 1; // The 0th and 1st index position values are fixed. They are initialized as 1 for (int i = 2; i <= n; i++) { a[i] = 2 * a[i - 1] + a[i - 2]; } // The loop is continued till n - return a[n] == expected_answer; + return a[n] == expectedAnswer; // returns true if calculated answer matches with expected answer } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java b/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java index 5ee3327553d7..0840e08c531c 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/OptimalJobScheduling.java @@ -13,24 +13,24 @@ public class OptimalJobScheduling { private final int numberProcesses; private final int numberMachines; - private final int[][] Run; - private final int[][] Transfer; - private final int[][] Cost; + private final int[][] run; + private final int[][] transfer; + private final int[][] cost; /** * Constructor of the class. * @param numberProcesses ,refers to the number of precedent processes(N) * @param numberMachines ,refers to the number of different machines in our disposal(M) - * @param Run , N*M matrix refers to the cost of running each process to each machine - * @param Transfer ,M*M symmetric matrix refers to the transportation delay for each pair of + * @param run , N*M matrix refers to the cost of running each process to each machine + * @param transfer ,M*M symmetric matrix refers to the transportation delay for each pair of * machines */ - public OptimalJobScheduling(int numberProcesses, int numberMachines, int[][] Run, int[][] Transfer) { + public OptimalJobScheduling(int numberProcesses, int numberMachines, int[][] run, int[][] transfer) { this.numberProcesses = numberProcesses; this.numberMachines = numberMachines; - this.Run = Run; - this.Transfer = Transfer; - this.Cost = new int[numberProcesses][numberMachines]; + this.run = run; + this.transfer = transfer; + this.cost = new int[numberProcesses][numberMachines]; } /** @@ -50,7 +50,7 @@ private void calculateCost() { for (int j = 0; j < numberMachines; j++) { // for each Machine - Cost[i][j] = runningCost(i, j); + cost[i][j] = runningCost(i, j); } } } @@ -71,7 +71,7 @@ private int runningCost(int process, int machine) { if (process == 0) // refers to the first process,which does not require for a previous one // to have been executed - return Run[process][machine]; + return run[process][machine]; else { int[] runningCosts = new int[numberMachines]; // stores the costs of executing our Process depending on @@ -79,7 +79,7 @@ private int runningCost(int process, int machine) { for (int k = 0; k < numberMachines; k++) // computes the cost of executing the previous // process to each and every Machine - runningCosts[k] = Cost[process - 1][k] + Transfer[k][machine] + Run[process][machine]; // transferring the result to our Machine and executing + runningCosts[k] = cost[process - 1][k] + transfer[k][machine] + run[process][machine]; // transferring the result to our Machine and executing // the Process to our Machine return findMin(runningCosts); // returns the minimum running cost @@ -88,19 +88,19 @@ private int runningCost(int process, int machine) { /** * Function used in order to return the minimum Cost. - * @param cost ,an Array of size M which refers to the costs of executing a Process to each + * @param costArr ,an Array of size M which refers to the costs of executing a Process to each * Machine * @return the minimum cost */ - private int findMin(int[] cost) { + private int findMin(int[] costArr) { int min = 0; - for (int i = 1; i < cost.length; i++) { + for (int i = 1; i < costArr.length; i++) { - if (cost[i] < cost[min]) min = i; + if (costArr[i] < costArr[min]) min = i; } - return cost[min]; + return costArr[min]; } /** @@ -111,7 +111,7 @@ private void showResults() { for (int i = 0; i < numberProcesses; i++) { for (int j = 0; j < numberMachines; j++) { - System.out.print(Cost[i][j]); + System.out.print(cost[i][j]); System.out.print(" "); } @@ -124,6 +124,6 @@ private void showResults() { * Getter for the running Cost of i process on j machine. */ public int getCost(int process, int machine) { - return Cost[process][machine]; + return cost[process][machine]; } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java b/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java index 2ef7d61a355d..01fa1d19609a 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/PalindromicPartitioning.java @@ -17,7 +17,9 @@ * "aba | b | bbabb | ababa" * @author [Syed] (https://github.com/roeticvampire) */ -public class PalindromicPartitioning { +public final class PalindromicPartitioning { + private PalindromicPartitioning() { + } public static int minimalpartitions(String word) { int len = word.length(); @@ -29,24 +31,26 @@ public static int minimalpartitions(String word) { int[] minCuts = new int[len]; boolean[][] isPalindrome = new boolean[len][len]; - int i, j, L; // different looping variables + int i; + int j; + int subLen; // 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 + /* subLen 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 + for (subLen = 2; subLen <= len; subLen++) { + // For substring of length subLen, set different possible starting indexes + for (i = 0; i < len - subLen + 1; i++) { + j = i + subLen - 1; // Ending index + // If subLen 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) { + if (subLen == 2) { isPalindrome[i][j] = (word.charAt(i) == word.charAt(j)); } else { isPalindrome[i][j] = (word.charAt(i) == word.charAt(j)) && isPalindrome[i + 1][j - 1]; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java b/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java index efe5cc883daf..49c4a0a3a008 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java @@ -18,7 +18,9 @@ import java.util.Arrays; -public class PartitionProblem { +public final class PartitionProblem { + private PartitionProblem() { + } /** * Test if a set of integers can be partitioned into two subsets such that the sum of elements diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java index cc90e56f1b6d..43427457e307 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/RegexMatching.java @@ -12,7 +12,9 @@ * length of pat * */ -public class RegexMatching { +public final class RegexMatching { + private RegexMatching() { + } // Method 1: Using Recursion // Time Complexity=0(2^(N+M)) Space Complexity=Recursion Extra Space diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java b/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java index 4583aec2e1b4..f56fc4ff5641 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/RodCutting.java @@ -4,7 +4,9 @@ * A Dynamic Programming solution for the Rod cutting problem. * Returns the best obtainable price for a rod of length n and price[] as prices of different pieces. */ -public class RodCutting { +public final class RodCutting { + private RodCutting() { + } /** * This method calculates the maximum obtainable value for cutting a rod of length n diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java b/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java index 78baaa32e1a4..362ed5e252d2 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/ShortestCommonSupersequenceLength.java @@ -1,16 +1,18 @@ package com.thealgorithms.dynamicprogramming; // Java program to find length of the shortest supersequence -class ShortestSuperSequence { +final class ShortestSuperSequence { + private ShortestSuperSequence() { + } // Function to find length of the - // shortest supersequence of X and Y. - static int shortestSuperSequence(String X, String Y) { - int m = X.length(); - int n = Y.length(); + // shortest supersequence of x and 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); + int l = lcs(x, y, m, n); // Result is sum of input string // lengths - length of lcs @@ -18,38 +20,39 @@ static int shortestSuperSequence(String X, String Y) { } // Returns length of LCS - // for X[0..m - 1], Y[0..n - 1] - static int lcs(String X, String Y, int m, int n) { - int[][] L = new int[m + 1][n + 1]; - int i, j; + // for x[0..m - 1], y[0..n - 1] + static int lcs(String x, String y, int m, int n) { + int[][] lN = new int[m + 1][n + 1]; + int i; + int j; - // Following steps build L[m + 1][n + 1] + // Following steps build lN[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] + // lN[i][j] contains length of lNCS + // 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) { - L[i][j] = 0; - } else if (X.charAt(i - 1) == Y.charAt(j - 1)) { - L[i][j] = L[i - 1][j - 1] + 1; + lN[i][j] = 0; + } else if (x.charAt(i - 1) == y.charAt(j - 1)) { + lN[i][j] = lN[i - 1][j - 1] + 1; } else { - L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]); + lN[i][j] = Math.max(lN[i - 1][j], lN[i][j - 1]); } } } - // L[m][n] contains length of LCS - // for X[0..n - 1] and Y[0..m - 1] - return L[m][n]; + // lN[m][n] contains length of LCS + // for x[0..n - 1] and y[0..m - 1] + return lN[m][n]; } // Driver code public static void main(String[] args) { - String X = "AGGTAB"; - String Y = "GXTXAYB"; + String x = "AGGTAB"; + String y = "GXTXAYB"; System.out.println("Length of the shortest " - + "supersequence is " + shortestSuperSequence(X, Y)); + + "supersequence is " + shortestSuperSequence(x, y)); } } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java index ef1c6c8f89f0..af31294f7e0e 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java @@ -6,7 +6,9 @@ * StackOverflow(https://stackoverflow.com/questions/22891076/count-number-of-subsets-with-sum-equal-to-k) * @author Samrat Podder(https://github.com/samratpodder) */ -public class SubsetCount { +public final class SubsetCount { + private SubsetCount() { + } /** * Dynamic Programming Implementation. @@ -16,7 +18,7 @@ public class SubsetCount { * @param target is the sum of each element of the subset taken together * */ - public int getCount(int[] arr, int target) { + public static int getCount(int[] arr, int target) { /** * Base Cases - If target becomes zero, we have reached the required sum for the subset * If we reach the end of the array arr then, either if target==arr[end], then we add one to @@ -46,7 +48,7 @@ public int getCount(int[] arr, int target) { * @param arr is the input array on which subsets are to searched * @param target is the sum of each element of the subset taken together */ - public int getCountSO(int[] arr, int target) { + public static int getCountSO(int[] arr, int target) { int n = arr.length; int[] prev = new int[target + 1]; prev[0] = 1; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java index 33696947c008..087d9ac2c7e7 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java @@ -1,6 +1,8 @@ package com.thealgorithms.dynamicprogramming; -public class SubsetSum { +public final class SubsetSum { + private SubsetSum() { + } /** * Driver Code diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java b/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java index 622f8b146d96..dd48008bd21e 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java @@ -1,17 +1,19 @@ package com.thealgorithms.dynamicprogramming; -public class SumOfSubset { +public final class SumOfSubset { + private SumOfSubset() { + } - public static boolean subsetSum(int[] arr, int num, int Key) { - if (Key == 0) { + public static boolean subsetSum(int[] arr, int num, int key) { + if (key == 0) { return true; } - if (num < 0 || Key < 0) { + if (num < 0 || key < 0) { return false; } - boolean include = subsetSum(arr, num - 1, Key - arr[num]); - boolean exclude = subsetSum(arr, num - 1, Key); + boolean include = subsetSum(arr, num - 1, key - arr[num]); + boolean exclude = subsetSum(arr, num - 1, key); return include || exclude; } diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java b/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java index 99f9029009ab..407566f481a0 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java @@ -4,7 +4,9 @@ * The {@code Tribonacci} class provides a method to compute the n-th number in the Tribonacci sequence. * N-th Tribonacci Number - https://leetcode.com/problems/n-th-tribonacci-number/description/ */ -public class Tribonacci { +public final class Tribonacci { + private Tribonacci() { + } /** * Computes the n-th Tribonacci number. @@ -16,7 +18,9 @@ public static int compute(int n) { if (n == 0) return 0; if (n == 1 || n == 2) return 1; - int first = 0, second = 1, third = 1; + int first = 0; + int second = 1; + int third = 1; for (int i = 3; i <= n; i++) { int next = first + second + third; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java index a938634cdfd2..8e8bf3cc6606 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java @@ -14,7 +14,9 @@ package com.thealgorithms.dynamicprogramming; -public class WildcardMatching { +public final class WildcardMatching { + private WildcardMatching() { + } public static boolean isMatch(String text, String pattern) { int m = text.length(); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java b/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java index b7eb029eaa71..0f5359f4d95e 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java @@ -10,26 +10,28 @@ * shelf. You are not allowed to reorder. You have to find the maximum profit * */ -public class WineProblem { +public final class WineProblem { + private 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) { + 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 start = wpRecursion(arr, si + 1, ei) + arr[si] * year; + int end = wpRecursion(arr, si, ei - 1) + arr[ei] * year; return Math.max(start, end); } // 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) { + 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) { @@ -39,8 +41,8 @@ public static int WPTD(int[] arr, int si, int ei, int[][] strg) { 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 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); @@ -51,7 +53,7 @@ public static int WPTD(int[] arr, int si, int ei, int[][] strg) { // 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) { + public static int wpbu(int[] arr) { int n = arr.length; int[][] strg = new int[n][n]; @@ -74,9 +76,9 @@ public static int WPBU(int[] arr) { 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)); + 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/ diff --git a/src/main/java/com/thealgorithms/geometry/GrahamScan.java b/src/main/java/com/thealgorithms/geometry/GrahamScan.java index 9122c6f6f3cc..4f4aebaed971 100644 --- a/src/main/java/com/thealgorithms/geometry/GrahamScan.java +++ b/src/main/java/com/thealgorithms/geometry/GrahamScan.java @@ -126,7 +126,7 @@ public Comparator<Point> polarOrder() { return new PolarOrder(); } - private class PolarOrder implements Comparator<Point> { + private final class PolarOrder implements Comparator<Point> { public int compare(Point p1, Point p2) { int dx1 = p1.x - x; int dy1 = p1.y - y; diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java b/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java index 0f704dd6ed55..88fbc50129ca 100644 --- a/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java +++ b/src/main/java/com/thealgorithms/greedyalgorithms/ActivitySelection.java @@ -6,11 +6,13 @@ // Problem Link: https://en.wikipedia.org/wiki/Activity_selection_problem -public class ActivitySelection { +public final class ActivitySelection { + private ActivitySelection() { + } // Function to perform activity selection - public static ArrayList<Integer> activitySelection(int startTimes[], int endTimes[]) { + public static ArrayList<Integer> activitySelection(int[] startTimes, int[] endTimes) { int n = startTimes.length; - int activities[][] = new int[n][3]; + int[][] activities = new int[n][3]; // Create a 2D array to store activities and their start/end times. // Each row: [activity index, start time, end time] diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java b/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java index 2109e454fa4d..8054581d21d7 100644 --- a/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java +++ b/src/main/java/com/thealgorithms/greedyalgorithms/CoinChange.java @@ -6,16 +6,17 @@ // Problem Link : https://en.wikipedia.org/wiki/Change-making_problem -public class CoinChange { +public final class CoinChange { + private CoinChange() { + } // Function to solve the coin change problem public static ArrayList<Integer> coinChangeProblem(int amount) { // Define an array of coin denominations in descending order - Integer coins[] = {1, 2, 5, 10, 20, 50, 100, 500, 2000}; + Integer[] coins = {1, 2, 5, 10, 20, 50, 100, 500, 2000}; // Sort the coin denominations in descending order Arrays.sort(coins, Comparator.reverseOrder()); - int count = 0; // Variable to keep track of the total number of coins used ArrayList<Integer> ans = new ArrayList<>(); // List to store selected coins // Iterate through the coin denominations @@ -24,7 +25,6 @@ public static ArrayList<Integer> coinChangeProblem(int amount) { if (coins[i] <= amount) { // Repeatedly subtract the coin denomination from the remaining amount while (coins[i] <= amount) { - count++; // Increment the count of coins used ans.add(coins[i]); // Add the coin to the list of selected coins amount -= coins[i]; // Update the remaining amount } diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java b/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java index f46364fc704b..082bd9c68b32 100644 --- a/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java +++ b/src/main/java/com/thealgorithms/greedyalgorithms/FractionalKnapsack.java @@ -5,11 +5,13 @@ // Problem Link: https://en.wikipedia.org/wiki/Continuous_knapsack_problem -public class FractionalKnapsack { +public final class FractionalKnapsack { + private FractionalKnapsack() { + } // Function to perform fractional knapsack - public static int fractionalKnapsack(int weight[], int value[], int capacity) { + public static int fractionalKnapsack(int[] weight, int[] value, int capacity) { // Create a 2D array to store item indices and their value-to-weight ratios. - double ratio[][] = new double[weight.length][2]; + double[][] ratio = new double[weight.length][2]; // Populate the ratio array with item indices and their value-to-weight ratios. for (int i = 0; i < weight.length; i++) { diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java b/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java index 4d2cf7c95a03..ceb664a31e8a 100644 --- a/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java +++ b/src/main/java/com/thealgorithms/greedyalgorithms/JobSequencing.java @@ -5,7 +5,9 @@ // Problem Link: https://en.wikipedia.org/wiki/Job-shop_scheduling -public class JobSequencing { +public final class JobSequencing { + private JobSequencing() { + } // Define a Job class that implements Comparable for sorting by profit in descending order static class Job implements Comparable<Job> { @@ -19,7 +21,7 @@ public int compareTo(Job otherJob) { return otherJob.profit - this.profit; } - public Job(char id, int deadline, int profit) { + Job(char id, int deadline, int profit) { this.id = id; this.deadline = deadline; this.profit = profit; @@ -29,16 +31,16 @@ public Job(char id, int deadline, int profit) { // Function to print the job sequence public static String findJobSequence(ArrayList<Job> jobs, int size) { Boolean[] slots = new Boolean[size]; - Arrays.fill(slots, false); + Arrays.fill(slots, Boolean.FALSE); - int result[] = new int[size]; + int[] result = new int[size]; // Iterate through jobs to find the optimal job sequence for (int i = 0; i < size; i++) { for (int j = jobs.get(i).deadline - 1; j >= 0; j--) { if (!slots[j]) { result[j] = i; - slots[j] = true; + slots[j] = Boolean.TRUE; break; } } diff --git a/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java b/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java index 938ae79bb625..c7f219ef3eab 100644 --- a/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java +++ b/src/main/java/com/thealgorithms/greedyalgorithms/MinimizingLateness.java @@ -2,7 +2,9 @@ import java.util.Arrays; -public class MinimizingLateness { +public final class MinimizingLateness { + private MinimizingLateness() { + } public static class Job { String jobName; diff --git a/src/main/java/com/thealgorithms/io/BufferedReader.java b/src/main/java/com/thealgorithms/io/BufferedReader.java index 477a52bb5c30..fa0237a48049 100644 --- a/src/main/java/com/thealgorithms/io/BufferedReader.java +++ b/src/main/java/com/thealgorithms/io/BufferedReader.java @@ -27,7 +27,8 @@ public class BufferedReader { /** * posRead -> indicates the next byte to read */ - private int posRead = 0, bufferPos = 0; + private int posRead = 0; + private int bufferPos = 0; private boolean foundEof = false; diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteMax.java b/src/main/java/com/thealgorithms/maths/AbsoluteMax.java index 64338297e399..d0c3db3790a3 100644 --- a/src/main/java/com/thealgorithms/maths/AbsoluteMax.java +++ b/src/main/java/com/thealgorithms/maths/AbsoluteMax.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class AbsoluteMax { +public final class AbsoluteMax { + private AbsoluteMax() { + } /** * Finds the absolute maximum value among the given numbers. diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteMin.java b/src/main/java/com/thealgorithms/maths/AbsoluteMin.java index 97d37dd9294a..1ffe6d2e81bc 100644 --- a/src/main/java/com/thealgorithms/maths/AbsoluteMin.java +++ b/src/main/java/com/thealgorithms/maths/AbsoluteMin.java @@ -2,7 +2,9 @@ import java.util.Arrays; -public class AbsoluteMin { +public final class AbsoluteMin { + private AbsoluteMin() { + } /** * Compares the numbers given as arguments to get the absolute min value. diff --git a/src/main/java/com/thealgorithms/maths/AbsoluteValue.java b/src/main/java/com/thealgorithms/maths/AbsoluteValue.java index 607413641392..b9279d5a244a 100644 --- a/src/main/java/com/thealgorithms/maths/AbsoluteValue.java +++ b/src/main/java/com/thealgorithms/maths/AbsoluteValue.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class AbsoluteValue { +public final class AbsoluteValue { + private AbsoluteValue() { + } /** * Returns the absolute value of a number. diff --git a/src/main/java/com/thealgorithms/maths/AliquotSum.java b/src/main/java/com/thealgorithms/maths/AliquotSum.java index daf02f14749f..5a5555777425 100644 --- a/src/main/java/com/thealgorithms/maths/AliquotSum.java +++ b/src/main/java/com/thealgorithms/maths/AliquotSum.java @@ -9,7 +9,9 @@ * 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 final class AliquotSum { + private AliquotSum() { + } /** * Finds the aliquot sum of an integer number. diff --git a/src/main/java/com/thealgorithms/maths/AmicableNumber.java b/src/main/java/com/thealgorithms/maths/AmicableNumber.java index 23c90888ec5d..b30831bfdc58 100644 --- a/src/main/java/com/thealgorithms/maths/AmicableNumber.java +++ b/src/main/java/com/thealgorithms/maths/AmicableNumber.java @@ -19,7 +19,9 @@ * 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} <-SUM = 220. */ -public class AmicableNumber { +public final class AmicableNumber { + private AmicableNumber() { + } /** * Finds all the amicable numbers in a given range. * diff --git a/src/main/java/com/thealgorithms/maths/Area.java b/src/main/java/com/thealgorithms/maths/Area.java index 43d35eea47b9..7a06fd5e5fa0 100644 --- a/src/main/java/com/thealgorithms/maths/Area.java +++ b/src/main/java/com/thealgorithms/maths/Area.java @@ -3,7 +3,9 @@ /** * Find the area of various geometric shapes */ -public class Area { +public final class Area { + private Area() { + } /** * String of IllegalArgumentException for radius diff --git a/src/main/java/com/thealgorithms/maths/AutoCorrelation.java b/src/main/java/com/thealgorithms/maths/AutoCorrelation.java index 5b38235bcd01..344a1271e11c 100644 --- a/src/main/java/com/thealgorithms/maths/AutoCorrelation.java +++ b/src/main/java/com/thealgorithms/maths/AutoCorrelation.java @@ -7,7 +7,9 @@ * @version 2.0 */ -public class AutoCorrelation { +public final class AutoCorrelation { + private AutoCorrelation() { + } /** * Discrete linear auto-correlation function. diff --git a/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java b/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java index 1e5eb32f6e8b..560ce3aabd1a 100644 --- a/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java +++ b/src/main/java/com/thealgorithms/maths/AutomorphicNumber.java @@ -10,7 +10,9 @@ import java.math.BigInteger; -public class AutomorphicNumber { +public final class AutomorphicNumber { + private AutomorphicNumber() { + } /** * A function to check if a number is Automorphic number or not @@ -22,7 +24,8 @@ public class AutomorphicNumber { public static boolean isAutomorphic(long n) { if (n < 0) return false; long square = n * n; // Calculating square of the number - long t = n, numberOfdigits = 0; + long t = n; + long numberOfdigits = 0; while (t > 0) { numberOfdigits++; // Calculating number of digits in n t /= 10; diff --git a/src/main/java/com/thealgorithms/maths/Average.java b/src/main/java/com/thealgorithms/maths/Average.java index 903afbafe35f..1c632cf0a65e 100644 --- a/src/main/java/com/thealgorithms/maths/Average.java +++ b/src/main/java/com/thealgorithms/maths/Average.java @@ -3,7 +3,9 @@ /** * Calculate average of a list of numbers */ -public class Average { +public final class Average { + private Average() { + } /** * Calculate average of a list of numbers diff --git a/src/main/java/com/thealgorithms/maths/BinaryPow.java b/src/main/java/com/thealgorithms/maths/BinaryPow.java index d431d58b91b1..1550376782b1 100644 --- a/src/main/java/com/thealgorithms/maths/BinaryPow.java +++ b/src/main/java/com/thealgorithms/maths/BinaryPow.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class BinaryPow { +public final class BinaryPow { + private BinaryPow() { + } /** * Calculate a^p using binary exponentiation diff --git a/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java b/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java index 4009b79e5057..faec049b08a7 100644 --- a/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java +++ b/src/main/java/com/thealgorithms/maths/BinomialCoefficient.java @@ -10,7 +10,9 @@ * * */ -public class BinomialCoefficient { +public final class BinomialCoefficient { + private BinomialCoefficient() { + } /** * This method returns the number of ways in which k objects can be chosen from n objects diff --git a/src/main/java/com/thealgorithms/maths/Ceil.java b/src/main/java/com/thealgorithms/maths/Ceil.java index f9b570fca76a..aacb9d969950 100644 --- a/src/main/java/com/thealgorithms/maths/Ceil.java +++ b/src/main/java/com/thealgorithms/maths/Ceil.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class Ceil { +public final class Ceil { + private Ceil() { + } /** * Returns the smallest (closest to negative infinity) diff --git a/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java b/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java index f01e029b42a6..f7010acf452d 100644 --- a/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java +++ b/src/main/java/com/thealgorithms/maths/CircularConvolutionFFT.java @@ -9,7 +9,9 @@ * @author Ioannis Karavitsis * @version 1.0 */ -public class CircularConvolutionFFT { +public final class CircularConvolutionFFT { + private CircularConvolutionFFT() { + } /** * This method pads the signal with zeros until it reaches the new size. diff --git a/src/main/java/com/thealgorithms/maths/Combinations.java b/src/main/java/com/thealgorithms/maths/Combinations.java index 68d653229fa9..2b4a78613190 100644 --- a/src/main/java/com/thealgorithms/maths/Combinations.java +++ b/src/main/java/com/thealgorithms/maths/Combinations.java @@ -3,7 +3,9 @@ /** * @see <a href="https://en.wikipedia.org/wiki/Combination">Combination</a> */ -public class Combinations { +public final class Combinations { + private Combinations() { + } /** * Calculate of factorial diff --git a/src/main/java/com/thealgorithms/maths/Convolution.java b/src/main/java/com/thealgorithms/maths/Convolution.java index cafb36f7a2b1..93e103f8c7cf 100644 --- a/src/main/java/com/thealgorithms/maths/Convolution.java +++ b/src/main/java/com/thealgorithms/maths/Convolution.java @@ -6,19 +6,21 @@ * @author Ioannis Karavitsis * @version 1.0 */ -public class Convolution { +public final class Convolution { + private 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 + * @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]; + 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: @@ -33,10 +35,10 @@ public static double[] convolution(double[] A, double[] B) { */ for (int i = 0; i < convolved.length; i++) { convolved[i] = 0; - int k = Math.max(i - B.length + 1, 0); + int k = Math.max(i - b.length + 1, 0); - while (k < i + 1 && k < A.length) { - convolved[i] += A[k] * B[i - k]; + while (k < i + 1 && k < a.length) { + convolved[i] += a[k] * b[i - k]; k++; } } diff --git a/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java b/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java index b761092ac70f..ce35b02ca13b 100644 --- a/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java +++ b/src/main/java/com/thealgorithms/maths/ConvolutionFFT.java @@ -9,7 +9,9 @@ * @author Ioannis Karavitsis * @version 1.0 */ -public class ConvolutionFFT { +public final class ConvolutionFFT { + private ConvolutionFFT() { + } /** * This method pads the signal with zeros until it reaches the new size. diff --git a/src/main/java/com/thealgorithms/maths/CrossCorrelation.java b/src/main/java/com/thealgorithms/maths/CrossCorrelation.java index 080e4ab7e74b..eeb4d6d1717a 100644 --- a/src/main/java/com/thealgorithms/maths/CrossCorrelation.java +++ b/src/main/java/com/thealgorithms/maths/CrossCorrelation.java @@ -7,7 +7,9 @@ * @version 1.0 */ -public class CrossCorrelation { +public final class CrossCorrelation { + private CrossCorrelation() { + } /** * Discrete linear cross-correlation function. @@ -20,7 +22,7 @@ public class CrossCorrelation { public static double[] crossCorrelation(double[] x, double[] y) { // The result signal's length is the sum of the input signals' lengths minus 1 double[] result = new double[x.length + y.length - 1]; - int N = result.length; + int n = result.length; /* To find the cross-correlation between 2 discrete signals x & y, we start by "placing" the second signal @@ -58,13 +60,13 @@ and for every new position (i++) of the result signal, we shift y signal one pos - To find the result[i] value for each i:0->N-1, the positions of x-signal in which the 2 signals meet + To find the result[i] value for each i:0->n-1, the positions of x-signal in which the 2 signals meet are calculated: kMin<=k<=kMax. The variable 'yStart' indicates the starting index of y in each sum calculation. The variable 'count' increases the index of y-signal by 1, to move to the next value. */ int yStart = y.length; - for (int i = 0; i < N; i++) { + for (int i = 0; i < n; i++) { result[i] = 0; int kMin = Math.max(i - (y.length - 1), 0); diff --git a/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java b/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java index 79b0dafad8f4..a2a327117700 100644 --- a/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java +++ b/src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java @@ -1,17 +1,22 @@ package com.thealgorithms.maths; -import java.util.*; +import java.util.Scanner; /* * @author Ojasva Jain * Determinant of a Matrix Wikipedia link: https://en.wikipedia.org/wiki/Determinant */ -public class DeterminantOfMatrix { +public final class DeterminantOfMatrix { + private 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; + int det = 0; + int sign = 1; + int p = 0; + int q = 0; if (n == 1) { det = a[0][0]; } else { diff --git a/src/main/java/com/thealgorithms/maths/DigitalRoot.java b/src/main/java/com/thealgorithms/maths/DigitalRoot.java index 9eeb4a65f2ae..84b33f34c393 100644 --- a/src/main/java/com/thealgorithms/maths/DigitalRoot.java +++ b/src/main/java/com/thealgorithms/maths/DigitalRoot.java @@ -40,7 +40,9 @@ */ package com.thealgorithms.maths; -class DigitalRoot { +final class DigitalRoot { + private DigitalRoot() { + } public static int digitalRoot(int n) { if (single(n) <= 9) { // If n is already single digit than simply call single method and diff --git a/src/main/java/com/thealgorithms/maths/DistanceFormula.java b/src/main/java/com/thealgorithms/maths/DistanceFormula.java index 6efc2fbdff5d..f7e2c7629551 100644 --- a/src/main/java/com/thealgorithms/maths/DistanceFormula.java +++ b/src/main/java/com/thealgorithms/maths/DistanceFormula.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class DistanceFormula { +public final class DistanceFormula { + private DistanceFormula() { + } public static double euclideanDistance(double x1, double y1, double x2, double y2) { double dX = Math.pow(x2 - x1, 2); diff --git a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java index 3bb56c5ccdb7..acf1e55d49c8 100644 --- a/src/main/java/com/thealgorithms/maths/DudeneyNumber.java +++ b/src/main/java/com/thealgorithms/maths/DudeneyNumber.java @@ -6,31 +6,23 @@ */ package com.thealgorithms.maths; -public class DudeneyNumber { +public final class DudeneyNumber { + private 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) { + public static boolean isDudeney(final int n) { + if (n <= 0) { + throw new IllegalArgumentException("Input must me positive."); + } // Calculating Cube Root - int cube_root = (int) (Math.round((Math.pow(n, 1.0 / 3.0)))); + final int cubeRoot = (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) { + if (cubeRoot * cubeRoot * cubeRoot != n) { return false; } - int sum_of_digits = 0; // Stores the sums of the digits of the entered number - int temp = n; // A temporary variable to store the entered number - // Loop to calculate the sum of the digits. - while (temp > 0) { - // Extracting the Last digit of the number - int rem = temp % 10; - - // Calculating the 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. - return cube_root == sum_of_digits; + return cubeRoot == SumOfDigits.sumOfDigits(n); } } diff --git a/src/main/java/com/thealgorithms/maths/EulerMethod.java b/src/main/java/com/thealgorithms/maths/EulerMethod.java index 40e654626a23..3663b6c534aa 100644 --- a/src/main/java/com/thealgorithms/maths/EulerMethod.java +++ b/src/main/java/com/thealgorithms/maths/EulerMethod.java @@ -15,7 +15,9 @@ * https://en.wikipedia.org/wiki/Euler_method ) (see also: * https://www.geeksforgeeks.org/euler-method-solving-differential-equation/ ) */ -public class EulerMethod { +public final class EulerMethod { + private EulerMethod() { + } /** * Illustrates how the algorithm is used in 3 examples and prints the diff --git a/src/main/java/com/thealgorithms/maths/FFT.java b/src/main/java/com/thealgorithms/maths/FFT.java index f50bec52997b..7ca7543d7985 100644 --- a/src/main/java/com/thealgorithms/maths/FFT.java +++ b/src/main/java/com/thealgorithms/maths/FFT.java @@ -10,7 +10,9 @@ * @author Ioannis Karavitsis * @version 1.0 */ -public class FFT { +public final class FFT { + private FFT() { + } /** * This class represents a complex number and has methods for basic @@ -22,12 +24,13 @@ public class FFT { */ static class Complex { - private double real, img; + private double real; + private double img; /** * Default Constructor. Creates the complex number 0. */ - public Complex() { + Complex() { real = 0; img = 0; } @@ -38,7 +41,7 @@ public Complex() { * @param r The real part of the number. * @param i The imaginary part of the number. */ - public Complex(double r, double i) { + Complex(double r, double i) { real = r; img = i; } @@ -183,16 +186,16 @@ public Complex divide(double n) { public static ArrayList<Complex> fft(ArrayList<Complex> x, boolean inverse) { /* Pad the signal with zeros if necessary */ paddingPowerOfTwo(x); - int N = x.size(); - int log2N = findLog2(N); - x = fftBitReversal(N, log2N, x); + int n = x.size(); + int log2n = findLog2(n); + x = fftBitReversal(n, log2n, x); int direction = inverse ? -1 : 1; /* Main loop of the algorithm */ - for (int len = 2; len <= N; len *= 2) { + 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) { + 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); @@ -203,24 +206,24 @@ public static ArrayList<Complex> fft(ArrayList<Complex> x, boolean inverse) { } } } - x = inverseFFT(N, inverse, x); + x = inverseFFT(n, inverse, x); return x; } - /* Find the log2(N) */ - public static int findLog2(int N) { - int log2N = 0; - while ((1 << log2N) < N) { - log2N++; + /* Find the log2(n) */ + public static int findLog2(int n) { + int log2n = 0; + while ((1 << log2n) < n) { + log2n++; } - return log2N; + return log2n; } /* Swap the values of the signal with bit-reversal method */ - public static ArrayList<Complex> fftBitReversal(int N, int log2N, ArrayList<Complex> x) { + public static ArrayList<Complex> fftBitReversal(int n, int log2n, ArrayList<Complex> x) { int reverse; - for (int i = 0; i < N; i++) { - reverse = reverseBits(i, log2N); + for (int i = 0; i < n; i++) { + reverse = reverseBits(i, log2n); if (i < reverse) { Collections.swap(x, i, reverse); } @@ -228,12 +231,12 @@ public static ArrayList<Complex> fftBitReversal(int N, int log2N, ArrayList<Comp return x; } - /* Divide by N if we want the inverse FFT */ - public static ArrayList<Complex> inverseFFT(int N, boolean inverse, ArrayList<Complex> x) { + /* Divide by n if we want the inverse FFT */ + public static ArrayList<Complex> inverseFFT(int n, boolean inverse, ArrayList<Complex> x) { if (inverse) { for (int i = 0; i < x.size(); i++) { Complex z = x.get(i); - x.set(i, z.divide(N)); + x.set(i, z.divide(n)); } } return x; @@ -244,7 +247,7 @@ public static ArrayList<Complex> inverseFFT(int N, boolean inverse, ArrayList<Co * FFT algorithm. * * <p> - * E.g. num = 13 = 00001101 in binary log2N = 8 Then reversed = 176 = + * E.g. num = 13 = 00001101 in binary log2n = 8 Then reversed = 176 = * 10110000 in binary * * <p> @@ -252,14 +255,14 @@ public static ArrayList<Complex> inverseFFT(int N, boolean inverse, ArrayList<Co * 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. + * @param log2n The number of bits you want to reverse. * @return The reversed number */ - private static int reverseBits(int num, int log2N) { + private static int reverseBits(int num, int log2n) { int reversed = 0; - for (int i = 0; i < log2N; i++) { + for (int i = 0; i < log2n; i++) { if ((num & (1 << i)) != 0) { - reversed |= 1 << (log2N - 1 - i); + reversed |= 1 << (log2n - 1 - i); } } return reversed; diff --git a/src/main/java/com/thealgorithms/maths/FFTBluestein.java b/src/main/java/com/thealgorithms/maths/FFTBluestein.java index cd698b62570a..388de6fed3eb 100644 --- a/src/main/java/com/thealgorithms/maths/FFTBluestein.java +++ b/src/main/java/com/thealgorithms/maths/FFTBluestein.java @@ -9,7 +9,9 @@ * @author Ioannis Karavitsis * @version 1.0 */ -public class FFTBluestein { +public final class FFTBluestein { + private FFTBluestein() { + } /** * Bluestein's FFT Algorithm. @@ -24,8 +26,8 @@ public class FFTBluestein { * @param inverse True if you want to find the inverse FFT. */ public static void fftBluestein(ArrayList<FFT.Complex> x, boolean inverse) { - int N = x.size(); - int bnSize = 2 * N - 1; + int n = x.size(); + int bnSize = 2 * n - 1; int direction = inverse ? -1 : 1; ArrayList<FFT.Complex> an = new ArrayList<>(); ArrayList<FFT.Complex> bn = new ArrayList<>(); @@ -36,32 +38,32 @@ public static void fftBluestein(ArrayList<FFT.Complex> x, boolean inverse) { bn.add(new FFT.Complex()); } - for (int i = 0; i < N; i++) { - double angle = (i - N + 1) * (i - N + 1) * Math.PI / N * direction; + 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; + 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<FFT.Complex> 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; + 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))); + x.set(i, bk.multiply(convolution.get(i + n - 1))); } - /* Divide by N if we want the inverse FFT */ + /* Divide by n if we want the inverse FFT */ if (inverse) { - for (int i = 0; i < N; i++) { + for (int i = 0; i < n; i++) { FFT.Complex z = x.get(i); - x.set(i, z.divide(N)); + x.set(i, z.divide(n)); } } } diff --git a/src/main/java/com/thealgorithms/maths/FactorialRecursion.java b/src/main/java/com/thealgorithms/maths/FactorialRecursion.java index 85e03c4dd1a4..d9bafd1e39e9 100644 --- a/src/main/java/com/thealgorithms/maths/FactorialRecursion.java +++ b/src/main/java/com/thealgorithms/maths/FactorialRecursion.java @@ -1,16 +1,8 @@ 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; +public final class FactorialRecursion { + private FactorialRecursion() { } - /** * Recursive FactorialRecursion Method * diff --git a/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java b/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java index 886337478d01..a0dbfb1f70a4 100644 --- a/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java +++ b/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java @@ -9,7 +9,9 @@ package com.thealgorithms.maths; -public class FastInverseSqrt { +public final class FastInverseSqrt { + private FastInverseSqrt() { + } public static boolean inverseSqrt(float number) { float x = number; diff --git a/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java b/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java index a9663d39a988..72bae57c27b0 100644 --- a/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java +++ b/src/main/java/com/thealgorithms/maths/FibonacciJavaStreams.java @@ -9,7 +9,9 @@ * @author: caos321 * @date: 14 October 2021 (Thursday) */ -public class FibonacciJavaStreams { +public final class FibonacciJavaStreams { + private FibonacciJavaStreams() { + } public static Optional<BigDecimal> calculate(final BigDecimal index) { if (index == null || index.compareTo(BigDecimal.ZERO) < 0) { diff --git a/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java b/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java index 937786546fc3..781275d3130d 100644 --- a/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java +++ b/src/main/java/com/thealgorithms/maths/FibonacciNumberCheck.java @@ -5,7 +5,9 @@ * This code checks Fibonacci Numbers up to 45th number. * Other checks fail because of 'long'-type overflow. */ -public class FibonacciNumberCheck { +public final class FibonacciNumberCheck { + private FibonacciNumberCheck() { + } /** * Check if a number is perfect square number * diff --git a/src/main/java/com/thealgorithms/maths/FindKthNumber.java b/src/main/java/com/thealgorithms/maths/FindKthNumber.java index bcb83b5ee2fc..daea3f96332b 100644 --- a/src/main/java/com/thealgorithms/maths/FindKthNumber.java +++ b/src/main/java/com/thealgorithms/maths/FindKthNumber.java @@ -6,9 +6,11 @@ /** * use quick sort algorithm to get kth largest or kth smallest element in given array */ -public class FindKthNumber { +public final class FindKthNumber { + private FindKthNumber() { + } - private static final Random random = new Random(); + private static final Random RANDOM = new Random(); public static void main(String[] args) { /* generate an array with random size and random elements */ @@ -29,17 +31,18 @@ public static void main(String[] args) { } private static int[] generateArray(int capacity) { - int size = random.nextInt(capacity) + 1; + int size = RANDOM.nextInt(capacity) + 1; int[] array = new int[size]; for (int i = 0; i < size; i++) { - array[i] = random.nextInt() % 100; + array[i] = RANDOM.nextInt() % 100; } return array; } private static int findKthMax(int[] nums, int k) { - int start = 0, end = nums.length; + int start = 0; + int end = nums.length; while (start < end) { int pivot = partition(nums, start, end); if (k == pivot) { diff --git a/src/main/java/com/thealgorithms/maths/FrizzyNumber.java b/src/main/java/com/thealgorithms/maths/FrizzyNumber.java index 3b1ff5fde3b3..3ae5e021df1b 100644 --- a/src/main/java/com/thealgorithms/maths/FrizzyNumber.java +++ b/src/main/java/com/thealgorithms/maths/FrizzyNumber.java @@ -7,7 +7,9 @@ package com.thealgorithms.maths; -public class FrizzyNumber { +public final class FrizzyNumber { + private FrizzyNumber() { + } /** * Returns the n-th number that is a sum of powers diff --git a/src/main/java/com/thealgorithms/maths/GCD.java b/src/main/java/com/thealgorithms/maths/GCD.java index 0f3125bde209..5156e4ac881d 100644 --- a/src/main/java/com/thealgorithms/maths/GCD.java +++ b/src/main/java/com/thealgorithms/maths/GCD.java @@ -6,7 +6,9 @@ * * @author Oskar Enmalm 3/10/17 */ -public class GCD { +public final class GCD { + private GCD() { + } /** * get the greatest common divisor diff --git a/src/main/java/com/thealgorithms/maths/GCDRecursion.java b/src/main/java/com/thealgorithms/maths/GCDRecursion.java index 05e44f941ac7..e95ce97c8a04 100644 --- a/src/main/java/com/thealgorithms/maths/GCDRecursion.java +++ b/src/main/java/com/thealgorithms/maths/GCDRecursion.java @@ -3,7 +3,9 @@ /** * @author https://github.com/shellhub/ */ -public class GCDRecursion { +public final class GCDRecursion { + private GCDRecursion() { + } public static void main(String[] args) { System.out.println(gcd(20, 15)); diff --git a/src/main/java/com/thealgorithms/maths/Gaussian.java b/src/main/java/com/thealgorithms/maths/Gaussian.java index 442c51e9d32d..cefbaea5b9b4 100644 --- a/src/main/java/com/thealgorithms/maths/Gaussian.java +++ b/src/main/java/com/thealgorithms/maths/Gaussian.java @@ -2,35 +2,38 @@ import java.util.ArrayList; -public class Gaussian { +public final class Gaussian { + private Gaussian() { + } - public static ArrayList<Double> gaussian(int mat_size, ArrayList<Double> matrix) { + public static ArrayList<Double> gaussian(int matSize, ArrayList<Double> matrix) { ArrayList<Double> answerArray = new ArrayList<Double>(); - int i, j = 0; + int i; + int j = 0; - double[][] mat = new double[mat_size + 1][mat_size + 1]; - double[][] x = new double[mat_size][mat_size + 1]; + double[][] mat = new double[matSize + 1][matSize + 1]; + double[][] x = new double[matSize][matSize + 1]; // Values from arraylist to matrix - for (i = 0; i < mat_size; i++) { - for (j = 0; j <= mat_size; j++) { + for (i = 0; i < matSize; i++) { + for (j = 0; j <= matSize; j++) { mat[i][j] = matrix.get(i); } } - mat = gaussianElimination(mat_size, i, mat); - answerArray = valueOfGaussian(mat_size, x, mat); + mat = gaussianElimination(matSize, i, mat); + answerArray = valueOfGaussian(matSize, x, mat); return answerArray; } // Perform Gaussian elimination - public static double[][] gaussianElimination(int mat_size, int i, double[][] mat) { + public static double[][] gaussianElimination(int matSize, int i, double[][] mat) { int step = 0; - for (step = 0; step < mat_size - 1; step++) { - for (i = step; i < mat_size - 1; i++) { + for (step = 0; step < matSize - 1; step++) { + for (i = step; i < matSize - 1; i++) { double a = (mat[i + 1][step] / mat[step][step]); - for (int j = step; j <= mat_size; j++) { + for (int j = step; j <= matSize; j++) { mat[i + 1][j] = mat[i + 1][j] - (a * mat[step][j]); } } @@ -39,26 +42,27 @@ public static double[][] gaussianElimination(int mat_size, int i, double[][] mat } // calculate the x_1, x_2, ... values of the gaussian and save it in an arraylist. - public static ArrayList<Double> valueOfGaussian(int mat_size, double[][] x, double[][] mat) { + public static ArrayList<Double> valueOfGaussian(int matSize, double[][] x, double[][] mat) { ArrayList<Double> answerArray = new ArrayList<Double>(); - int i, j; + int i; + int j; - for (i = 0; i < mat_size; i++) { - for (j = 0; j <= mat_size; j++) { + for (i = 0; i < matSize; i++) { + for (j = 0; j <= matSize; j++) { x[i][j] = mat[i][j]; } } - for (i = mat_size - 1; i >= 0; i--) { + for (i = matSize - 1; i >= 0; i--) { double sum = 0; - for (j = mat_size - 1; j > i; j--) { + for (j = matSize - 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]); + x[i][i] = (x[i][matSize] - sum) / (x[i][i]); } answerArray.add(x[i][j]); } diff --git a/src/main/java/com/thealgorithms/maths/HarshadNumber.java b/src/main/java/com/thealgorithms/maths/HarshadNumber.java index 4778dc81b664..0b1ba1285c4d 100644 --- a/src/main/java/com/thealgorithms/maths/HarshadNumber.java +++ b/src/main/java/com/thealgorithms/maths/HarshadNumber.java @@ -2,7 +2,9 @@ // Wikipedia for Harshad Number : https://en.wikipedia.org/wiki/Harshad_number -public class HarshadNumber { +public final class HarshadNumber { + private HarshadNumber() { + } /** * A function to check if a number is Harshad number or not @@ -32,7 +34,7 @@ public static boolean isHarshad(long n) { * {@code false} */ public static boolean isHarshad(String s) { - long n = Long.valueOf(s); + final Long n = Long.valueOf(s); if (n <= 0) return false; int sumOfDigits = 0; diff --git a/src/main/java/com/thealgorithms/maths/JosephusProblem.java b/src/main/java/com/thealgorithms/maths/JosephusProblem.java index b878eff2b291..7d19623b3ed0 100644 --- a/src/main/java/com/thealgorithms/maths/JosephusProblem.java +++ b/src/main/java/com/thealgorithms/maths/JosephusProblem.java @@ -20,7 +20,9 @@ @author Kunal */ -public class JosephusProblem { +public final class JosephusProblem { + private JosephusProblem() { + } /** * Find the Winner of the Circular Game. diff --git a/src/main/java/com/thealgorithms/maths/JugglerSequence.java b/src/main/java/com/thealgorithms/maths/JugglerSequence.java index 216098fc926f..702310a1f295 100644 --- a/src/main/java/com/thealgorithms/maths/JugglerSequence.java +++ b/src/main/java/com/thealgorithms/maths/JugglerSequence.java @@ -11,7 +11,9 @@ * * */ -public class JugglerSequence { +public final class JugglerSequence { + private JugglerSequence() { + } /** * This method prints juggler sequence starting with the number in the parameter diff --git a/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java b/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java index d2283dc10214..f025f86682a2 100644 --- a/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java +++ b/src/main/java/com/thealgorithms/maths/KaprekarNumbers.java @@ -1,9 +1,12 @@ package com.thealgorithms.maths; import java.math.BigInteger; -import java.util.*; +import java.util.ArrayList; +import java.util.List; -public class KaprekarNumbers { +public final class KaprekarNumbers { + private KaprekarNumbers() { + } /* This program demonstrates if a given number is Kaprekar Number or not. Kaprekar Number: A Kaprekar number is an n-digit number which its square can be split into diff --git a/src/main/java/com/thealgorithms/maths/KeithNumber.java b/src/main/java/com/thealgorithms/maths/KeithNumber.java index 1db9f9500ed1..1756cfbae91b 100644 --- a/src/main/java/com/thealgorithms/maths/KeithNumber.java +++ b/src/main/java/com/thealgorithms/maths/KeithNumber.java @@ -1,15 +1,20 @@ package com.thealgorithms.maths; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Scanner; -class KeithNumber { +final class KeithNumber { + private KeithNumber() { + } // user-defined function that checks if the given number is Keith or not static boolean isKeith(int x) { // List stores all the digits of the X - ArrayList<Integer> terms = new ArrayList<Integer>(); + ArrayList<Integer> terms = new ArrayList<>(); // n denotes the number of digits - int temp = x, n = 0; + int temp = x; + int n = 0; // executes until the condition becomes false while (temp > 0) { // determines the last digit of the number and add it to the List @@ -21,23 +26,24 @@ static boolean isKeith(int x) { } // reverse the List Collections.reverse(terms); - int next_term = 0, i = n; + int nextTerm = 0; + int i = n; // finds next term for the series // loop executes until the condition returns true - while (next_term < x) { - next_term = 0; + while (nextTerm < x) { + nextTerm = 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); + nextTerm = nextTerm + terms.get(i - j); } - terms.add(next_term); + terms.add(nextTerm); 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 + // either nextTerm will be equal to x or greater than x // if equal, the given number is Keith, else not - return (next_term == x); + return (nextTerm == x); } // driver code diff --git a/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java b/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java index eacc75c23058..f5ff50337bc7 100644 --- a/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java +++ b/src/main/java/com/thealgorithms/maths/KrishnamurthyNumber.java @@ -5,9 +5,13 @@ 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.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; -public class KrishnamurthyNumber { +public final class KrishnamurthyNumber { + private KrishnamurthyNumber() { + } // returns True if the number is a Krishnamurthy number and False if it is not. diff --git a/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java b/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java index f4f7c94aa3e2..db79340f0a99 100644 --- a/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java +++ b/src/main/java/com/thealgorithms/maths/LeastCommonMultiple.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import java.util.*; +import java.util.Scanner; /** * Is a common mathematics concept to find the smallest value number @@ -9,7 +9,9 @@ * @author LauKinHoong */ -public class LeastCommonMultiple { +public final class LeastCommonMultiple { + private LeastCommonMultiple() { + } /** * Driver Code @@ -28,15 +30,18 @@ public static void main(String[] args) { * get least common multiple from two number */ public static int lcm(int num1, int num2) { - int high, num3; + int high; + int num3; int cmv = 0; /* * value selection for the numerator */ if (num1 > num2) { - high = num3 = num1; + high = num1; + num3 = num1; } else { - high = num3 = num2; + high = num2; + num3 = num2; } while (num1 != 0) { diff --git a/src/main/java/com/thealgorithms/maths/LeonardoNumber.java b/src/main/java/com/thealgorithms/maths/LeonardoNumber.java index 1ca5c8bd0fa6..bbeec052777f 100644 --- a/src/main/java/com/thealgorithms/maths/LeonardoNumber.java +++ b/src/main/java/com/thealgorithms/maths/LeonardoNumber.java @@ -3,7 +3,9 @@ /** * https://en.wikipedia.org/wiki/Leonardo_number */ -public class LeonardoNumber { +public final class LeonardoNumber { + private LeonardoNumber() { + } /** * Calculate nth Leonardo Number (1, 1, 3, 5, 9, 15, 25, 41, 67, 109, 177, ...) diff --git a/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java b/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java index 2d00cc5561e8..a50cfb218283 100644 --- a/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java +++ b/src/main/java/com/thealgorithms/maths/LinearDiophantineEquationsSolver.java @@ -3,6 +3,8 @@ import java.util.Objects; public final class LinearDiophantineEquationsSolver { + private LinearDiophantineEquationsSolver() { + } public static void main(String[] args) { // 3x + 4y = 7 diff --git a/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java b/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java index 89acbf6a14e7..c0f55f5e3485 100644 --- a/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java +++ b/src/main/java/com/thealgorithms/maths/LiouvilleLambdaFunction.java @@ -12,7 +12,9 @@ * * */ -public class LiouvilleLambdaFunction { +public final class LiouvilleLambdaFunction { + private LiouvilleLambdaFunction() { + } /** * This method returns λ(n) of given number n diff --git a/src/main/java/com/thealgorithms/maths/LongDivision.java b/src/main/java/com/thealgorithms/maths/LongDivision.java index b1c7b1901701..45e97b1c14c3 100644 --- a/src/main/java/com/thealgorithms/maths/LongDivision.java +++ b/src/main/java/com/thealgorithms/maths/LongDivision.java @@ -8,61 +8,63 @@ package com.thealgorithms.maths; -public class LongDivision { +public final class LongDivision { + private LongDivision() { + } public static int divide(int dividend, int divisor) { - long new_dividend_1 = dividend; - long new_divisor_1 = divisor; + long newDividend1 = dividend; + long newDivisor1 = divisor; if (divisor == 0) { return 0; } if (dividend < 0) { - new_dividend_1 = new_dividend_1 * -1; + newDividend1 = newDividend1 * -1; } if (divisor < 0) { - new_divisor_1 = new_divisor_1 * -1; + newDivisor1 = newDivisor1 * -1; } - if (dividend == 0 || new_dividend_1 < new_divisor_1) { + if (dividend == 0 || newDividend1 < newDivisor1) { return 0; } StringBuilder answer = new StringBuilder(); - String dividend_string = "" + new_dividend_1; - int last_index = 0; + String dividendString = "" + newDividend1; + int lastIndex = 0; String remainder = ""; - for (int i = 0; i < dividend_string.length(); i++) { - String part_v1 = remainder + "" + dividend_string.substring(last_index, i + 1); - long part_1 = Long.parseLong(part_v1); - if (part_1 > new_divisor_1) { + for (int i = 0; i < dividendString.length(); i++) { + String partV1 = remainder + "" + dividendString.substring(lastIndex, i + 1); + long part1 = Long.parseLong(partV1); + if (part1 > newDivisor1) { int quotient = 0; - while (part_1 >= new_divisor_1) { - part_1 = part_1 - new_divisor_1; + while (part1 >= newDivisor1) { + part1 = part1 - newDivisor1; quotient++; } answer.append(quotient); - } else if (part_1 == new_divisor_1) { + } else if (part1 == newDivisor1) { int quotient = 0; - while (part_1 >= new_divisor_1) { - part_1 = part_1 - new_divisor_1; + while (part1 >= newDivisor1) { + part1 = part1 - newDivisor1; quotient++; } answer.append(quotient); - } else if (part_1 == 0) { + } else if (part1 == 0) { answer.append(0); - } else if (part_1 < new_divisor_1) { + } else if (part1 < newDivisor1) { answer.append(0); } - if (!(part_1 == 0)) { - remainder = String.valueOf(part_1); + if (!(part1 == 0)) { + remainder = String.valueOf(part1); } else { remainder = ""; } - last_index++; + lastIndex++; } if ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)) { diff --git a/src/main/java/com/thealgorithms/maths/LucasSeries.java b/src/main/java/com/thealgorithms/maths/LucasSeries.java index ebeb2715fe2d..e277c511f317 100644 --- a/src/main/java/com/thealgorithms/maths/LucasSeries.java +++ b/src/main/java/com/thealgorithms/maths/LucasSeries.java @@ -3,7 +3,9 @@ /** * https://en.wikipedia.org/wiki/Lucas_number */ -public class LucasSeries { +public final class LucasSeries { + private LucasSeries() { + } /** * Calculate nth number of Lucas Series(2, 1, 3, 4, 7, 11, 18, 29, 47, 76, diff --git a/src/main/java/com/thealgorithms/maths/MagicSquare.java b/src/main/java/com/thealgorithms/maths/MagicSquare.java index 3bcede960346..de0afc148982 100644 --- a/src/main/java/com/thealgorithms/maths/MagicSquare.java +++ b/src/main/java/com/thealgorithms/maths/MagicSquare.java @@ -1,11 +1,13 @@ package com.thealgorithms.maths; -import java.util.*; +import java.util.Scanner; /*A magic square of order n is an arrangement of distinct n^2 integers,in a square, such that the n numbers in all rows, all columns, and both diagonals sum to the same constant. A magic square contains the integers from 1 to n^2.*/ -public class MagicSquare { +public final class MagicSquare { + private MagicSquare() { + } public static void main(String[] args) { Scanner sc = new Scanner(System.in); @@ -16,32 +18,32 @@ public static void main(String[] args) { System.exit(0); } - int[][] magic_square = new int[num][num]; + int[][] magicSquare = new int[num][num]; - int row_num = num / 2; - int col_num = num - 1; - magic_square[row_num][col_num] = 1; + int rowNum = num / 2; + int colNum = num - 1; + magicSquare[rowNum][colNum] = 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; - col_num = (col_num + 1) % num; + if (magicSquare[(rowNum - 1 + num) % num][(colNum + 1) % num] == 0) { + rowNum = (rowNum - 1 + num) % num; + colNum = (colNum + 1) % num; } else { - col_num = (col_num - 1 + num) % num; + colNum = (colNum - 1 + num) % num; } - magic_square[row_num][col_num] = i; + magicSquare[rowNum][colNum] = i; } // print the square for (int i = 0; i < num; i++) { for (int j = 0; j < num; j++) { - if (magic_square[i][j] < 10) { + if (magicSquare[i][j] < 10) { System.out.print(" "); } - if (magic_square[i][j] < 100) { + if (magicSquare[i][j] < 100) { System.out.print(" "); } - System.out.print(magic_square[i][j] + " "); + System.out.print(magicSquare[i][j] + " "); } System.out.println(); } diff --git a/src/main/java/com/thealgorithms/maths/MatrixUtil.java b/src/main/java/com/thealgorithms/maths/MatrixUtil.java index f3d0efeacc45..0759853d61a9 100644 --- a/src/main/java/com/thealgorithms/maths/MatrixUtil.java +++ b/src/main/java/com/thealgorithms/maths/MatrixUtil.java @@ -11,7 +11,9 @@ * @author: caos321 * @date: 31 October 2021 (Sunday) */ -public class MatrixUtil { +public final class MatrixUtil { + private MatrixUtil() { + } public static boolean isValid(final BigDecimal[][] matrix) { return matrix != null && matrix.length > 0 && matrix[0].length > 0; diff --git a/src/main/java/com/thealgorithms/maths/Median.java b/src/main/java/com/thealgorithms/maths/Median.java index 89bc42254d34..e4daec8fc11a 100644 --- a/src/main/java/com/thealgorithms/maths/Median.java +++ b/src/main/java/com/thealgorithms/maths/Median.java @@ -5,7 +5,9 @@ /** * Wikipedia: https://en.wikipedia.org/wiki/Median */ -public class Median { +public final class Median { + private Median() { + } /** * Calculate average median diff --git a/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java b/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java index ed4f325b0710..e25836f713a9 100644 --- a/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java +++ b/src/main/java/com/thealgorithms/maths/MillerRabinPrimalityCheck.java @@ -2,7 +2,9 @@ import java.util.Random; -public class MillerRabinPrimalityCheck { +public final class MillerRabinPrimalityCheck { + private MillerRabinPrimalityCheck() { + } /** * Check whether the given number is prime or not diff --git a/src/main/java/com/thealgorithms/maths/MobiusFunction.java b/src/main/java/com/thealgorithms/maths/MobiusFunction.java index e9ead992d7a7..915d0d9a6dae 100644 --- a/src/main/java/com/thealgorithms/maths/MobiusFunction.java +++ b/src/main/java/com/thealgorithms/maths/MobiusFunction.java @@ -12,7 +12,9 @@ * Author: Akshay Dubey (https://github.com/itsAkshayDubey) * * */ -public class MobiusFunction { +public final class MobiusFunction { + private MobiusFunction() { + } /** * This method returns μ(n) of given number n diff --git a/src/main/java/com/thealgorithms/maths/Mode.java b/src/main/java/com/thealgorithms/maths/Mode.java index 7333380b0a69..a92f404c653a 100644 --- a/src/main/java/com/thealgorithms/maths/Mode.java +++ b/src/main/java/com/thealgorithms/maths/Mode.java @@ -1,7 +1,6 @@ package com.thealgorithms.maths; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -11,15 +10,8 @@ * 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}); +public final class Mode { + private Mode() { } /* @@ -28,7 +20,7 @@ public static void main(String[] args) { * @param numbers array of integers * @return mode of the array */ - public static int[] mode(int[] numbers) { + public static int[] mode(final int[] numbers) { if (numbers.length == 0) { return null; } diff --git a/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java b/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java index 01fdd5a6a5a5..5f1190d67de0 100644 --- a/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java +++ b/src/main/java/com/thealgorithms/maths/NonRepeatingElement.java @@ -7,11 +7,14 @@ * 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 final class NonRepeatingElement { + private NonRepeatingElement() { + } public static void main(String[] args) { try (Scanner sc = new Scanner(System.in)) { - int i, res = 0; + int i; + int res = 0; System.out.println("Enter the number of elements in the array"); int n = sc.nextInt(); if ((n & 1) == 1) { @@ -27,12 +30,6 @@ public static void main(String[] args) { 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]; @@ -40,7 +37,8 @@ public static void main(String[] args) { // Finding the rightmost set bit res = res & (-res); - int num1 = 0, num2 = 0; + int num1 = 0; + int num2 = 0; for (i = 0; i < n; i++) { if ((res & arr[i]) > 0) { // Case 1 explained below @@ -51,7 +49,6 @@ public static void main(String[] args) { } System.out.println("The two non repeating elements are " + num1 + " and " + num2); - sc.close(); } } /* diff --git a/src/main/java/com/thealgorithms/maths/NumberOfDigits.java b/src/main/java/com/thealgorithms/maths/NumberOfDigits.java index 665d8ef5a98c..fc538196c7da 100644 --- a/src/main/java/com/thealgorithms/maths/NumberOfDigits.java +++ b/src/main/java/com/thealgorithms/maths/NumberOfDigits.java @@ -3,35 +3,16 @@ /** * 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; - } +public final class NumberOfDigits { + private NumberOfDigits() { } - /** * 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) { + public static int numberOfDigits(int number) { int digits = 0; do { digits++; @@ -46,7 +27,7 @@ private static int numberOfDigits(int number) { * @param number number to find * @return number of digits of given number */ - private static int numberOfDigitsFast(int number) { + public static int numberOfDigitsFast(int number) { return number == 0 ? 1 : (int) Math.floor(Math.log10(Math.abs(number)) + 1); } @@ -56,7 +37,7 @@ private static int numberOfDigitsFast(int number) { * @param number number to find * @return number of digits of given number */ - private static int numberOfDigitsFaster(int number) { + public static int numberOfDigitsFaster(int number) { return number < 0 ? (-number + "").length() : (number + "").length(); } @@ -66,7 +47,7 @@ private static int numberOfDigitsFaster(int number) { * @param number number to find * @return number of digits of given number */ - private static int numberOfDigitsRecursion(int number) { + public static int numberOfDigitsRecursion(int number) { return number / 10 == 0 ? 1 : 1 + numberOfDigitsRecursion(number / 10); } } diff --git a/src/main/java/com/thealgorithms/maths/PalindromeNumber.java b/src/main/java/com/thealgorithms/maths/PalindromeNumber.java index 5dad99ef30e0..a22d63897b37 100644 --- a/src/main/java/com/thealgorithms/maths/PalindromeNumber.java +++ b/src/main/java/com/thealgorithms/maths/PalindromeNumber.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class PalindromeNumber { +public final class PalindromeNumber { + private PalindromeNumber() { + } /** * Check if {@code n} is palindrome number or not * diff --git a/src/main/java/com/thealgorithms/maths/PascalTriangle.java b/src/main/java/com/thealgorithms/maths/PascalTriangle.java index beb9a1e4937e..ef6aa41d6e53 100644 --- a/src/main/java/com/thealgorithms/maths/PascalTriangle.java +++ b/src/main/java/com/thealgorithms/maths/PascalTriangle.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class PascalTriangle { +public final class PascalTriangle { + private PascalTriangle() { + } /** *In mathematics, Pascal's triangle is a triangular array of the binomial coefficients that diff --git a/src/main/java/com/thealgorithms/maths/PerfectCube.java b/src/main/java/com/thealgorithms/maths/PerfectCube.java index f9ed0558b8d5..4104c6238580 100644 --- a/src/main/java/com/thealgorithms/maths/PerfectCube.java +++ b/src/main/java/com/thealgorithms/maths/PerfectCube.java @@ -3,7 +3,9 @@ /** * https://en.wikipedia.org/wiki/Cube_(algebra) */ -public class PerfectCube { +public final class PerfectCube { + private PerfectCube() { + } /** * Check if a number is perfect cube or not diff --git a/src/main/java/com/thealgorithms/maths/PerfectNumber.java b/src/main/java/com/thealgorithms/maths/PerfectNumber.java index 7d6a045166e5..49afd23f91bf 100644 --- a/src/main/java/com/thealgorithms/maths/PerfectNumber.java +++ b/src/main/java/com/thealgorithms/maths/PerfectNumber.java @@ -8,7 +8,9 @@ * * link:https://en.wikipedia.org/wiki/Perfect_number */ -public class PerfectNumber { +public final class PerfectNumber { + private PerfectNumber() { + } /** * Check if {@code number} is perfect number or not diff --git a/src/main/java/com/thealgorithms/maths/Perimeter.java b/src/main/java/com/thealgorithms/maths/Perimeter.java index e3476afaf0b3..f8aa1876d388 100644 --- a/src/main/java/com/thealgorithms/maths/Perimeter.java +++ b/src/main/java/com/thealgorithms/maths/Perimeter.java @@ -1,7 +1,9 @@ package com.thealgorithms.maths; // Perimeter of different 2D geometrical shapes -public class Perimeter { +public final class Perimeter { + private Perimeter() { + } /** * Calculate the Perimeter of regular polygon (equals sides) diff --git a/src/main/java/com/thealgorithms/maths/PiNilakantha.java b/src/main/java/com/thealgorithms/maths/PiNilakantha.java index d00240317997..6d43f134c94c 100644 --- a/src/main/java/com/thealgorithms/maths/PiNilakantha.java +++ b/src/main/java/com/thealgorithms/maths/PiNilakantha.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class PiNilakantha { +public final class PiNilakantha { + private PiNilakantha() { + } // Calculates Pi using Nilakantha's infinite series // Method 2 in the following link explains the algorithm diff --git a/src/main/java/com/thealgorithms/maths/PollardRho.java b/src/main/java/com/thealgorithms/maths/PollardRho.java index 8ce62336061e..7fa913b21b7e 100644 --- a/src/main/java/com/thealgorithms/maths/PollardRho.java +++ b/src/main/java/com/thealgorithms/maths/PollardRho.java @@ -35,7 +35,9 @@ * Author: Akshay Dubey (https://github.com/itsAkshayDubey) * * */ -public class PollardRho { +public final class PollardRho { + private PollardRho() { + } /** * This method returns a polynomial in x computed modulo n @@ -57,7 +59,9 @@ static int g(int base, int modulus) { * @throws RuntimeException object if GCD of given number cannot be found */ static int pollardRho(int number) { - int x = 2, y = 2, d = 1; + int x = 2; + int y = 2; + int d = 1; while (d == 1) { // tortoise move x = g(x, number); diff --git a/src/main/java/com/thealgorithms/maths/Pow.java b/src/main/java/com/thealgorithms/maths/Pow.java index 1d8ff2931ee0..3f362fe88d30 100644 --- a/src/main/java/com/thealgorithms/maths/Pow.java +++ b/src/main/java/com/thealgorithms/maths/Pow.java @@ -1,7 +1,9 @@ package com.thealgorithms.maths; // POWER (exponentials) Examples (a^b) -public class Pow { +public final class Pow { + private Pow() { + } public static void main(String[] args) { assert pow(2, 0) == Math.pow(2, 0); // == 1 diff --git a/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java b/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java index cbb2d6132366..93c8252ab929 100644 --- a/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java +++ b/src/main/java/com/thealgorithms/maths/PowerUsingRecursion.java @@ -5,7 +5,9 @@ * @author Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -public class PowerUsingRecursion { +public final class PowerUsingRecursion { + private PowerUsingRecursion() { + } public static double power(double base, int exponent) { // Base case: anything raised to the power of 0 is 1 diff --git a/src/main/java/com/thealgorithms/maths/PrimeCheck.java b/src/main/java/com/thealgorithms/maths/PrimeCheck.java index 2c9714f1335b..628a819aeba4 100644 --- a/src/main/java/com/thealgorithms/maths/PrimeCheck.java +++ b/src/main/java/com/thealgorithms/maths/PrimeCheck.java @@ -2,7 +2,9 @@ import java.util.Scanner; -public class PrimeCheck { +public final class PrimeCheck { + private PrimeCheck() { + } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); @@ -54,7 +56,8 @@ public static boolean isPrime(int n) { */ public static boolean fermatPrimeChecking(int n, int iteration) { long a; - int up = n - 2, down = 2; + int up = n - 2; + int down = 2; for (int i = 0; i < iteration; i++) { a = (long) Math.floor(Math.random() * (up - down + 1) + down); if (modPow(a, n - 1, n) != 1) { diff --git a/src/main/java/com/thealgorithms/maths/PrimeFactorization.java b/src/main/java/com/thealgorithms/maths/PrimeFactorization.java index 7e13cc673cd4..9ac50fd9043b 100644 --- a/src/main/java/com/thealgorithms/maths/PrimeFactorization.java +++ b/src/main/java/com/thealgorithms/maths/PrimeFactorization.java @@ -9,7 +9,9 @@ import java.util.ArrayList; import java.util.List; -public class PrimeFactorization { +public final class PrimeFactorization { + private PrimeFactorization() { + } public static List<Integer> pfactors(int n) { List<Integer> primeFactors = new ArrayList<>(); diff --git a/src/main/java/com/thealgorithms/maths/PronicNumber.java b/src/main/java/com/thealgorithms/maths/PronicNumber.java index 312af21ea2ba..4891cf3c63b3 100644 --- a/src/main/java/com/thealgorithms/maths/PronicNumber.java +++ b/src/main/java/com/thealgorithms/maths/PronicNumber.java @@ -10,19 +10,21 @@ * * */ -public class PronicNumber { +public final class PronicNumber { + private PronicNumber() { + } /** * This method checks if the given number is pronic number or non-pronic number * - * @param input_number Integer value which is to be checked if is a pronic number or not + * @param inputNumber Integer value which is to be checked if is a pronic number or not * @return true if input number is a pronic number, false otherwise */ - static boolean isPronic(int input_number) { + static boolean isPronic(int inputNumber) { // Iterating from 0 to input_number - for (int i = 0; i <= input_number; i++) { + for (int i = 0; i <= inputNumber; i++) { // Checking if product of i and (i+1) is equals input_number - if (i * (i + 1) == input_number && i != input_number) { + if (i * (i + 1) == inputNumber && i != inputNumber) { // return true if product of i and (i+1) is equals input_number return true; } diff --git a/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java b/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java index 68932c0b76bd..f535e9e6929b 100644 --- a/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java +++ b/src/main/java/com/thealgorithms/maths/PythagoreanTriple.java @@ -3,7 +3,9 @@ /** * https://en.wikipedia.org/wiki/Pythagorean_triple */ -public class PythagoreanTriple { +public final class PythagoreanTriple { + private PythagoreanTriple() { + } public static void main(String[] args) { assert isPythagTriple(3, 4, 5); diff --git a/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java b/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java index 0caa286231b6..8f5d44dbe146 100644 --- a/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java +++ b/src/main/java/com/thealgorithms/maths/RomanNumeralUtil.java @@ -8,7 +8,9 @@ * @author Sokratis Fotkatzikis * @version 1.0 */ -public class RomanNumeralUtil { +public final class RomanNumeralUtil { + private RomanNumeralUtil() { + } private static final int MIN_VALUE = 1; private static final int MAX_VALUE = 5999; diff --git a/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java b/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java index ef02c5759c03..79bc112902c4 100644 --- a/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java +++ b/src/main/java/com/thealgorithms/maths/SimpsonIntegration.java @@ -19,19 +19,19 @@ public static void main(String[] args) { SimpsonIntegration integration = new SimpsonIntegration(); // Give random data for the example purposes - int N = 16; + int n = 16; double a = 1; double b = 3; - // Check so that N is even - if (N % 2 != 0) { - System.out.println("N must be even number for Simpsons method. Aborted"); + // Check so that n is even + 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 integralEvaluation = integration.simpsonsMethod(N, h, a); + double h = (b - a) / (double) n; + double integralEvaluation = integration.simpsonsMethod(n, h, a); System.out.println("The integral is equal to: " + integralEvaluation); } @@ -45,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<Integer, Double> 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 diff --git a/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java b/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java index c988bb70808c..22e9fee00605 100644 --- a/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java +++ b/src/main/java/com/thealgorithms/maths/SquareFreeInteger.java @@ -14,7 +14,9 @@ import java.util.HashSet; import java.util.List; -public class SquareFreeInteger { +public final class SquareFreeInteger { + private SquareFreeInteger() { + } /** * This method returns whether an integer is square free * diff --git a/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java b/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java index 2f8fa9a83885..2b071307e2bc 100644 --- a/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java +++ b/src/main/java/com/thealgorithms/maths/SquareRootWithBabylonianMethod.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class SquareRootWithBabylonianMethod { +public final class SquareRootWithBabylonianMethod { + private SquareRootWithBabylonianMethod() { + } /** * get the value, return the square root @@ -8,7 +10,7 @@ public class SquareRootWithBabylonianMethod { * @param num contains elements * @return the square root of num */ - public static float square_Root(float num) { + public static float squareRoot(float num) { float a = num; float b = 1; double e = 0.000001; diff --git a/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java b/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java index eb116d21ac36..80d185c93785 100644 --- a/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java +++ b/src/main/java/com/thealgorithms/maths/SquareRootWithNewtonRaphsonMethod.java @@ -14,7 +14,9 @@ * be changed according to the user preference. */ -public class SquareRootWithNewtonRaphsonMethod { +public final class SquareRootWithNewtonRaphsonMethod { + private SquareRootWithNewtonRaphsonMethod() { + } public static double squareRoot(int n) { double x = n; // initially taking a guess that x = n. diff --git a/src/main/java/com/thealgorithms/maths/StandardDeviation.java b/src/main/java/com/thealgorithms/maths/StandardDeviation.java index 84d21f3082f0..a8e88d930a9c 100644 --- a/src/main/java/com/thealgorithms/maths/StandardDeviation.java +++ b/src/main/java/com/thealgorithms/maths/StandardDeviation.java @@ -1,18 +1,20 @@ package com.thealgorithms.maths; -public class StandardDeviation { +public final class StandardDeviation { + private StandardDeviation() { + } public static double stdDev(double[] data) { - double var = 0; + double variance = 0; double avg = 0; for (int i = 0; i < data.length; i++) { avg += data[i]; } avg /= data.length; for (int j = 0; j < data.length; j++) { - var += Math.pow((data[j] - avg), 2); + variance += Math.pow((data[j] - avg), 2); } - var /= data.length; - return Math.sqrt(var); + variance /= data.length; + return Math.sqrt(variance); } } diff --git a/src/main/java/com/thealgorithms/maths/StandardScore.java b/src/main/java/com/thealgorithms/maths/StandardScore.java index dcedf458b09e..22a9f550e114 100644 --- a/src/main/java/com/thealgorithms/maths/StandardScore.java +++ b/src/main/java/com/thealgorithms/maths/StandardScore.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -public class StandardScore { +public final class StandardScore { + private StandardScore() { + } public static double zScore(double num, double mean, double stdDev) { return (num - mean) / stdDev; diff --git a/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java b/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java index 0e2fe9e7a46a..877ef4227afc 100644 --- a/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java +++ b/src/main/java/com/thealgorithms/maths/TrinomialTriangle.java @@ -7,9 +7,11 @@ * * Example Input: n = 4 Output 1 1 1 1 1 2 3 2 1 1 3 6 7 6 3 1 */ -public class TrinomialTriangle { +public final class TrinomialTriangle { + private TrinomialTriangle() { + } - public static int TrinomialValue(int n, int k) { + public static int trinomialValue(int n, int k) { if (n == 0 && k == 0) { return 1; } @@ -18,17 +20,17 @@ public static int TrinomialValue(int n, int k) { return 0; } - return (TrinomialValue(n - 1, k - 1) + TrinomialValue(n - 1, k) + TrinomialValue(n - 1, k + 1)); + return (trinomialValue(n - 1, k - 1) + trinomialValue(n - 1, k) + trinomialValue(n - 1, k + 1)); } public static void printTrinomial(int n) { for (int i = 0; i < n; i++) { for (int j = -i; j <= 0; j++) { - System.out.print(TrinomialValue(i, j) + " "); + System.out.print(trinomialValue(i, j) + " "); } for (int j = 1; j <= i; j++) { - System.out.print(TrinomialValue(i, j) + " "); + System.out.print(trinomialValue(i, j) + " "); } System.out.println(); diff --git a/src/main/java/com/thealgorithms/maths/TwinPrime.java b/src/main/java/com/thealgorithms/maths/TwinPrime.java index 867a1d23f220..81731376b37a 100644 --- a/src/main/java/com/thealgorithms/maths/TwinPrime.java +++ b/src/main/java/com/thealgorithms/maths/TwinPrime.java @@ -9,7 +9,9 @@ * * */ -public class TwinPrime { +public final class TwinPrime { + private TwinPrime() { + } /** * This method returns twin prime of the integer value passed as argument diff --git a/src/main/java/com/thealgorithms/maths/VampireNumber.java b/src/main/java/com/thealgorithms/maths/VampireNumber.java index d9aa4f203550..d64c82c6e68e 100644 --- a/src/main/java/com/thealgorithms/maths/VampireNumber.java +++ b/src/main/java/com/thealgorithms/maths/VampireNumber.java @@ -16,7 +16,9 @@ * * <p> */ -public class VampireNumber { +public final class VampireNumber { + private VampireNumber() { + } public static void main(String[] args) { test(10, 1000); diff --git a/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java b/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java index 8a1bb1488eab..e2769744bcda 100644 --- a/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java +++ b/src/main/java/com/thealgorithms/maths/VectorCrossProduct.java @@ -55,14 +55,14 @@ public class VectorCrossProduct { /** * constructor, initialises Vector with given Direction Ratios * - * @param _x set to x - * @param _y set to y - * @param _z set to z + * @param vectorX set to x + * @param vectorY set to y + * @param vectorZ set to z */ - VectorCrossProduct(int _x, int _y, int _z) { - x = _x; - y = _y; - z = _z; + VectorCrossProduct(int vectorX, int vectorY, int vectorZ) { + x = vectorX; + y = vectorY; + z = vectorZ; } /** @@ -111,15 +111,15 @@ public static void main(String[] args) { static void test() { // Create two vectors - VectorCrossProduct A = new VectorCrossProduct(1, -2, 3); - VectorCrossProduct B = new VectorCrossProduct(2, 0, 3); + VectorCrossProduct a = new VectorCrossProduct(1, -2, 3); + VectorCrossProduct b = new VectorCrossProduct(2, 0, 3); // Determine cross product - VectorCrossProduct crossProd = A.crossProduct(B); + 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); + 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 index edc3575dfda6..4b73f849bb81 100644 --- a/src/main/java/com/thealgorithms/maths/Volume.java +++ b/src/main/java/com/thealgorithms/maths/Volume.java @@ -1,7 +1,9 @@ package com.thealgorithms.maths; /* Calculate the volume of various shapes.*/ -public class Volume { +public final class Volume { + private Volume() { + } /** * Calculate the volume of a cube. diff --git a/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java b/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java index aa255832f47f..afd34933047a 100644 --- a/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java +++ b/src/main/java/com/thealgorithms/matrixexponentiation/Fibonacci.java @@ -7,13 +7,15 @@ * see https://www.geeksforgeeks.org/matrix-exponentiation/ * */ -public class Fibonacci { +public final class Fibonacci { + private Fibonacci() { + } // Exponentiation matrix for Fibonacci sequence - private static final int[][] fibMatrix = {{1, 1}, {1, 0}}; - private static final int[][] identityMatrix = {{1, 0}, {0, 1}}; + private static final int[][] FIB_MATRIX = {{1, 1}, {1, 0}}; + private static final int[][] IDENTITY_MATRIX = {{1, 0}, {0, 1}}; // First 2 fibonacci numbers - private static final int[][] baseFibNumbers = {{1}, {0}}; + private static final int[][] BASE_FIB_NUMBERS = {{1}, {0}}; /** * Performs multiplication of 2 matrices @@ -53,14 +55,14 @@ private static int[][] matrixMultiplication(int[][] matrix1, int[][] matrix2) { */ public static int[][] fib(int n) { if (n == 0) { - return Fibonacci.identityMatrix; + return Fibonacci.IDENTITY_MATRIX; } else { int[][] cachedResult = fib(n / 2); int[][] matrixExpResult = matrixMultiplication(cachedResult, cachedResult); if (n % 2 == 0) { return matrixExpResult; } else { - return matrixMultiplication(Fibonacci.fibMatrix, matrixExpResult); + return matrixMultiplication(Fibonacci.FIB_MATRIX, matrixExpResult); } } } @@ -69,7 +71,7 @@ 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); + int[][] result = matrixMultiplication(fib(n), BASE_FIB_NUMBERS); System.out.println("Fib(" + n + ") = " + result[1][0]); sc.close(); } diff --git a/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java b/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java index 0fb5b6f17b97..5543463e9749 100644 --- a/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java +++ b/src/main/java/com/thealgorithms/misc/InverseOfMatrix.java @@ -11,7 +11,9 @@ * * We can also find the inverse of a matrix */ -public class InverseOfMatrix { +public final class InverseOfMatrix { + private InverseOfMatrix() { + } public static void main(String[] argv) { Scanner input = new Scanner(System.in); diff --git a/src/main/java/com/thealgorithms/misc/MapReduce.java b/src/main/java/com/thealgorithms/misc/MapReduce.java index baf960f8ecef..c076957344f9 100644 --- a/src/main/java/com/thealgorithms/misc/MapReduce.java +++ b/src/main/java/com/thealgorithms/misc/MapReduce.java @@ -15,7 +15,9 @@ * Wikipedia link : https://en.wikipedia.org/wiki/MapReduce */ -public class MapReduce { +public final class MapReduce { + private MapReduce() { + } /* *Counting all the words frequency within a sentence. */ diff --git a/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java b/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java index 4d8b980f2409..d4ddffe8ddd7 100644 --- a/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java +++ b/src/main/java/com/thealgorithms/misc/MedianOfMatrix.java @@ -10,6 +10,8 @@ */ public final class MedianOfMatrix { + private MedianOfMatrix() { + } public static int median(List<List<Integer>> matrix) { // Flatten the matrix into a 1D list diff --git a/src/main/java/com/thealgorithms/misc/PalindromePrime.java b/src/main/java/com/thealgorithms/misc/PalindromePrime.java index 58de938394af..6b01cdced23c 100644 --- a/src/main/java/com/thealgorithms/misc/PalindromePrime.java +++ b/src/main/java/com/thealgorithms/misc/PalindromePrime.java @@ -2,7 +2,9 @@ import java.util.Scanner; -public class PalindromePrime { +public final class PalindromePrime { + private PalindromePrime() { + } public static void main(String[] args) { // Main funtion Scanner in = new Scanner(System.in); diff --git a/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java b/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java index af2ca4dd5324..0dfc8ac32a6f 100644 --- a/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java +++ b/src/main/java/com/thealgorithms/misc/RangeInSortedArray.java @@ -1,8 +1,10 @@ package com.thealgorithms.misc; -import java.util.*; +import java.util.Arrays; -public class RangeInSortedArray { +public final class RangeInSortedArray { + private RangeInSortedArray() { + } public static void main(String[] args) { // Testcases @@ -26,7 +28,7 @@ public static void alteredBinSearch(int[] nums, int key, int left, int right, in if (left > right) { return; } - int mid = (left + right) / 2; + int mid = (left + right) >>> 1; if (nums[mid] > key) { alteredBinSearch(nums, key, left, mid - 1, range, goLeft); } else if (nums[mid] < key) { @@ -52,7 +54,7 @@ public static void alteredBinSearch(int[] nums, int key, int left, int right, in // 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; + final int mid = (left + right) >>> 1; if (nums[mid] > key) { right = mid - 1; } else if (nums[mid] < key) { @@ -84,7 +86,7 @@ public static int getCountLessThan(int[] nums, int key) { public static int getLessThan(int[] nums, int key, int left, int right) { int count = 0; while (left <= right) { - int mid = (left + right) / 2; + final int mid = (left + right) >>> 1; if (nums[mid] > key) { right = mid - 1; } else if (nums[mid] <= key) { diff --git a/src/main/java/com/thealgorithms/misc/Sort012D.java b/src/main/java/com/thealgorithms/misc/Sort012D.java index 2ffe31b9ddd8..febe13f4fec3 100644 --- a/src/main/java/com/thealgorithms/misc/Sort012D.java +++ b/src/main/java/com/thealgorithms/misc/Sort012D.java @@ -1,6 +1,6 @@ package com.thealgorithms.misc; -import java.util.*; +import java.util.Scanner; /** * The array is divided into four sections: a[1..Lo-1] zeroes a[Lo..Mid-1] ones @@ -11,7 +11,9 @@ * For more information on the Dutch national flag algorithm refer * https://en.wikipedia.org/wiki/Dutch_national_flag_problem */ -public class Sort012D { +public final class Sort012D { + private Sort012D() { + } public static void main(String[] args) { Scanner np = new Scanner(System.in); @@ -49,6 +51,9 @@ public static void sort012(int[] a) { h--; break; } + default: { + throw new IllegalArgumentException("Unexpected value: " + a[mid]); + } } } System.out.println("the Sorted array is "); diff --git a/src/main/java/com/thealgorithms/misc/Sparsity.java b/src/main/java/com/thealgorithms/misc/Sparsity.java new file mode 100644 index 000000000000..cae2fbdead94 --- /dev/null +++ b/src/main/java/com/thealgorithms/misc/Sparsity.java @@ -0,0 +1,56 @@ +package com.thealgorithms.misc; + +import java.util.Scanner; + +/* + *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 + */ + +final class Sparsity { + private Sparsity() { + } + + /* + * @return Sparsity of matrix + * + * where sparsity = number of zeroes/total elements in matrix + * + */ + static double sparsity(double[][] mat) { + int zero = 0; + // Traversing the matrix to count number of zeroes + for (int i = 0; i < mat.length; i++) { + for (int j = 0; j < mat[i].length; j++) { + if (mat[i][j] == 0) { + zero++; + } + } + } + // return sparsity + return ((double) zero / (mat.length * mat[1].length)); + } + + // Driver method + public static void main(String[] args) { + Scanner in = new Scanner(System.in); + System.out.println("Enter number of rows in matrix: "); + int n = in.nextInt(); + System.out.println("Enter number of Columns in matrix: "); + int m = in.nextInt(); + + System.out.println("Enter Matrix elements: "); + double[][] mat = new double[n][m]; + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + mat[i][j] = in.nextDouble(); + } + } + System.out.println("Sparsity of matrix is: " + sparsity(mat)); + in.close(); + } +} diff --git a/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java b/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java index a232ad986970..1c5f4a440532 100644 --- a/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java +++ b/src/main/java/com/thealgorithms/misc/ThreeSumProblem.java @@ -1,6 +1,14 @@ package com.thealgorithms.misc; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Scanner; +import java.util.Set; public class ThreeSumProblem { @@ -16,13 +24,13 @@ public static void main(String[] args) { arr[i] = scan.nextInt(); } ThreeSumProblem th = new ThreeSumProblem(); - System.out.println("Brute Force Approach\n" + (th.BruteForce(arr, ts)) + "\n"); - System.out.println("Two Pointer Approach\n" + (th.TwoPointer(arr, ts)) + "\n"); - System.out.println("Hashmap Approach\n" + (th.Hashmap(arr, ts))); + System.out.println("Brute Force Approach\n" + (th.bruteForce(arr, ts)) + "\n"); + System.out.println("Two Pointer Approach\n" + (th.twoPointer(arr, ts)) + "\n"); + System.out.println("Hashmap Approach\n" + (th.hashMap(arr, ts))); scan.close(); } - public List<List<Integer>> BruteForce(int[] nums, int target) { + public List<List<Integer>> bruteForce(int[] nums, int target) { List<List<Integer>> arr = new ArrayList<List<Integer>>(); for (int i = 0; i < nums.length; i++) { @@ -43,7 +51,7 @@ public List<List<Integer>> BruteForce(int[] nums, int target) { return arr; } - public List<List<Integer>> TwoPointer(int[] nums, int target) { + public List<List<Integer>> twoPointer(int[] nums, int target) { Arrays.sort(nums); List<List<Integer>> arr = new ArrayList<List<Integer>>(); int start = 0; @@ -73,7 +81,7 @@ public List<List<Integer>> TwoPointer(int[] nums, int target) { return new ArrayList<List<Integer>>(set); } - public List<List<Integer>> Hashmap(int[] nums, int target) { + public List<List<Integer>> hashMap(int[] nums, int target) { Arrays.sort(nums); Set<List<Integer>> ts = new HashSet<>(); HashMap<Integer, Integer> hm = new HashMap<>(); diff --git a/src/main/java/com/thealgorithms/misc/WordBoggle.java b/src/main/java/com/thealgorithms/misc/WordBoggle.java index 0dfbd89def99..3eb0dc95ffb5 100644 --- a/src/main/java/com/thealgorithms/misc/WordBoggle.java +++ b/src/main/java/com/thealgorithms/misc/WordBoggle.java @@ -1,8 +1,16 @@ package com.thealgorithms.misc; -import java.util.*; - -public class WordBoggle { +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public final class WordBoggle { + private WordBoggle() { + } /** * O(nm * 8^s + ws) time where n = width of boggle board, m = height of @@ -127,7 +135,7 @@ class Trie { TrieNode root; char endSymbol; - public Trie() { + Trie() { this.root = new TrieNode(); this.endSymbol = '*'; } diff --git a/src/main/java/com/thealgorithms/misc/matrixTranspose.java b/src/main/java/com/thealgorithms/misc/matrixTranspose.java index b5ad02184a00..40634f18b5f6 100644 --- a/src/main/java/com/thealgorithms/misc/matrixTranspose.java +++ b/src/main/java/com/thealgorithms/misc/matrixTranspose.java @@ -18,7 +18,9 @@ * @version 11.0.9 * @since 2014-03-31 */ -public class matrixTranspose { +public final class matrixTranspose { + private matrixTranspose() { + } public static void main(String[] args) { /* @@ -29,7 +31,10 @@ public static void main(String[] args) { * @return Nothing. */ Scanner sc = new Scanner(System.in); - int i, j, row, column; + int i; + int j; + int row; + int column; System.out.println("Enter the number of rows in the 2D matrix:"); /* diff --git a/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java b/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java index 4ee54bbdacf8..f43841f1f184 100644 --- a/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java +++ b/src/main/java/com/thealgorithms/others/ArrayLeftRotation.java @@ -8,7 +8,9 @@ * @author sangin-lee */ -public class ArrayLeftRotation { +public final class ArrayLeftRotation { + private ArrayLeftRotation() { + } /* * Returns the result of left rotation of given array arr and integer n diff --git a/src/main/java/com/thealgorithms/others/BFPRT.java b/src/main/java/com/thealgorithms/others/BFPRT.java index 29f47cd68ed6..1a5b44180651 100644 --- a/src/main/java/com/thealgorithms/others/BFPRT.java +++ b/src/main/java/com/thealgorithms/others/BFPRT.java @@ -5,7 +5,9 @@ /** * BFPRT algorithm. */ -public class BFPRT { +public final class BFPRT { + private BFPRT() { + } public static int[] getMinKNumsByBFPRT(int[] arr, int k) { if (k < 1 || k > arr.length) { @@ -32,9 +34,7 @@ public static int getMinKthByBFPRT(int[] arr, int k) { public static int[] copyArray(int[] arr) { int[] copyArr = new int[arr.length]; - for (int i = 0; i < arr.length; i++) { - copyArr[i] = arr[i]; - } + System.arraycopy(arr, 0, copyArr, 0, arr.length); return copyArr; } diff --git a/src/main/java/com/thealgorithms/others/BankersAlgorithm.java b/src/main/java/com/thealgorithms/others/BankersAlgorithm.java index 3fbb4f9fda68..a22d7c737415 100644 --- a/src/main/java/com/thealgorithms/others/BankersAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/BankersAlgorithm.java @@ -20,7 +20,9 @@ */ import java.util.Scanner; -public class BankersAlgorithm { +public final class BankersAlgorithm { + private BankersAlgorithm() { + } /** * This method finds the need of each process @@ -58,10 +60,7 @@ static boolean checkSafeSystem(int[] processes, int[] availableArray, int[][] ma int[] safeSequenceArray = new int[totalProcess]; int[] workArray = new int[totalResources]; - - for (int i = 0; i < totalResources; i++) { - workArray[i] = availableArray[i]; - } + System.arraycopy(availableArray, 0, workArray, 0, totalResources); int count = 0; @@ -111,7 +110,8 @@ static boolean checkSafeSystem(int[] processes, int[] availableArray, int[][] ma * This is main method of Banker's Algorithm */ public static void main(String[] args) { - int numberOfProcesses, numberOfResources; + int numberOfProcesses; + int numberOfResources; Scanner sc = new Scanner(System.in); diff --git a/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java b/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java index a1983feccb2e..b70fffe82c5b 100644 --- a/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/BrianKernighanAlgorithm.java @@ -20,7 +20,9 @@ * <p> * Time Complexity: O(logn) */ -public class BrianKernighanAlgorithm { +public final class BrianKernighanAlgorithm { + private BrianKernighanAlgorithm() { + } /** * @param num: number in which we count the set bits diff --git a/src/main/java/com/thealgorithms/others/CRC16.java b/src/main/java/com/thealgorithms/others/CRC16.java index c5c3b1f35a7d..85e5cd2c13ae 100644 --- a/src/main/java/com/thealgorithms/others/CRC16.java +++ b/src/main/java/com/thealgorithms/others/CRC16.java @@ -3,7 +3,9 @@ /** * Generates a crc16 checksum for a given string */ -public class CRC16 { +public final class CRC16 { + private CRC16() { + } public static void main(String[] args) { System.out.println(crc16("Hello World!")); diff --git a/src/main/java/com/thealgorithms/others/CRC32.java b/src/main/java/com/thealgorithms/others/CRC32.java index 561a33f4dae9..180936ed46c1 100644 --- a/src/main/java/com/thealgorithms/others/CRC32.java +++ b/src/main/java/com/thealgorithms/others/CRC32.java @@ -5,7 +5,9 @@ /** * Generates a crc32 checksum for a given string or byte array */ -public class CRC32 { +public final class CRC32 { + private CRC32() { + } public static void main(String[] args) { System.out.println(Integer.toHexString(crc32("Hello World"))); diff --git a/src/main/java/com/thealgorithms/others/Conway.java b/src/main/java/com/thealgorithms/others/Conway.java index b1d54e61094f..ab39890c9ece 100644 --- a/src/main/java/com/thealgorithms/others/Conway.java +++ b/src/main/java/com/thealgorithms/others/Conway.java @@ -1,8 +1,12 @@ package com.thealgorithms.others; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; -public class Conway { +public final class Conway { + private Conway() { + } /* * This class will generate the conway sequence also known as the look and say sequence. @@ -13,7 +17,7 @@ public class Conway { *1s, two 2s, one 1" or 312211. https://en.wikipedia.org/wiki/Look-and-say_sequence * */ - private static final StringBuilder builder = new StringBuilder(); + private static final StringBuilder BUILDER = new StringBuilder(); protected static List<String> generateList(String originalString, int maxIteration) { List<String> numbers = new ArrayList<>(); @@ -25,9 +29,9 @@ protected static List<String> generateList(String originalString, int maxIterati } public static String generateNextElement(String originalString) { - builder.setLength(0); + BUILDER.setLength(0); String[] stp = originalString.split("(?<=(.))(?!\\1)"); - Arrays.stream(stp).forEach(s -> builder.append(s.length()).append(s.charAt(0))); - return builder.toString(); + Arrays.stream(stp).forEach(s -> BUILDER.append(s.length()).append(s.charAt(0))); + return BUILDER.toString(); } } diff --git a/src/main/java/com/thealgorithms/others/CountChar.java b/src/main/java/com/thealgorithms/others/CountChar.java index 5a78c0c17412..ad858137726b 100644 --- a/src/main/java/com/thealgorithms/others/CountChar.java +++ b/src/main/java/com/thealgorithms/others/CountChar.java @@ -1,6 +1,8 @@ package com.thealgorithms.others; -public class CountChar { +public final class CountChar { + private CountChar() { + } /** * Count non space character in string @@ -9,7 +11,7 @@ public class CountChar { * @return number of character in the specified string */ - public static int CountCharacters(String str) { + public 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 index 1defde2cdd8b..26b9c50d928c 100644 --- a/src/main/java/com/thealgorithms/others/CountWords.java +++ b/src/main/java/com/thealgorithms/others/CountWords.java @@ -3,7 +3,7 @@ /** * @author Marcus */ -final public class CountWords { +public final class CountWords { private CountWords() { } diff --git a/src/main/java/com/thealgorithms/others/Damm.java b/src/main/java/com/thealgorithms/others/Damm.java index a32ae246a2ec..55a4c5b81a89 100644 --- a/src/main/java/com/thealgorithms/others/Damm.java +++ b/src/main/java/com/thealgorithms/others/Damm.java @@ -14,7 +14,9 @@ * @see <a href="https://en.wikipedia.org/wiki/Damm_algorithm">Wiki. Damm * algorithm</a> */ -public class Damm { +public final class Damm { + private Damm() { + } /** * Weakly totally anti-symmetric quasigroup of order 10. This table is not diff --git a/src/main/java/com/thealgorithms/others/Dijkstra.java b/src/main/java/com/thealgorithms/others/Dijkstra.java index 4886dc4ce7a4..e2a778f8d6c3 100644 --- a/src/main/java/com/thealgorithms/others/Dijkstra.java +++ b/src/main/java/com/thealgorithms/others/Dijkstra.java @@ -15,9 +15,14 @@ * https://rosettacode.org/wiki/Dijkstra%27s_algorithm#Java Also most of the * comments are from RosettaCode. */ -import java.util.*; +import java.util.HashMap; +import java.util.Map; +import java.util.NavigableSet; +import java.util.TreeSet; -public class Dijkstra { +public final class Dijkstra { + private Dijkstra() { + } private static final Graph.Edge[] GRAPH = { // Distance from node "a" to node "b" is 7. @@ -58,10 +63,11 @@ class Graph { */ public static class Edge { - public final String v1, v2; + public final String v1; + public final String v2; public final int dist; - public Edge(String v1, String v2, int dist) { + Edge(String v1, String v2, int dist) { this.v1 = v1; this.v2 = v2; this.dist = dist; @@ -79,7 +85,7 @@ public static class Vertex implements Comparable<Vertex> { public Vertex previous = null; public final Map<Vertex, Integer> neighbours = new HashMap<>(); - public Vertex(String name) { + Vertex(String name) { this.name = name; } @@ -147,7 +153,7 @@ public String toString() { /** * Builds a graph from a set of edges */ - public Graph(Edge[] edges) { + Graph(Edge[] edges) { graph = new HashMap<>(edges.length); // one pass to find all vertices @@ -193,7 +199,8 @@ public void dijkstra(String startName) { * Implementation of dijkstra's algorithm using a binary heap. */ private void dijkstra(final NavigableSet<Vertex> q) { - Vertex u, v; + Vertex u; + Vertex v; while (!q.isEmpty()) { // vertex with shortest distance (first iteration will return source) u = q.pollFirst(); diff --git a/src/main/java/com/thealgorithms/others/EulersFunction.java b/src/main/java/com/thealgorithms/others/EulersFunction.java index 27c9aed8b620..f08e5e4fa395 100644 --- a/src/main/java/com/thealgorithms/others/EulersFunction.java +++ b/src/main/java/com/thealgorithms/others/EulersFunction.java @@ -3,7 +3,7 @@ /** * @brief utility class for <a href="https://en.wikipedia.org/wiki/Euler%27s_totient_function">Euler's totient function</a> */ -final public class EulersFunction { +public final class EulersFunction { private EulersFunction() { } diff --git a/src/main/java/com/thealgorithms/others/FibbonaciSeries.java b/src/main/java/com/thealgorithms/others/FibbonaciSeries.java index 103e943743c7..a4815296e547 100644 --- a/src/main/java/com/thealgorithms/others/FibbonaciSeries.java +++ b/src/main/java/com/thealgorithms/others/FibbonaciSeries.java @@ -15,13 +15,16 @@ * Problem Statement: print all Fibonacci numbers that are smaller than your * given input N */ -public class FibbonaciSeries { +public final class FibbonaciSeries { + private 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; + int first = 0; + int second = 1; scan.close(); while (first <= n) { // print first fibo 0 then add second fibo into it while updating second as well diff --git a/src/main/java/com/thealgorithms/others/FloydTriangle.java b/src/main/java/com/thealgorithms/others/FloydTriangle.java index d25ab303e3ed..fbeaec339248 100644 --- a/src/main/java/com/thealgorithms/others/FloydTriangle.java +++ b/src/main/java/com/thealgorithms/others/FloydTriangle.java @@ -2,12 +2,15 @@ import java.util.Scanner; -class FloydTriangle { +final class FloydTriangle { + private 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; + int r = sc.nextInt(); + int n = 0; sc.close(); for (int i = 0; i < r; i++) { for (int j = 0; j <= i; j++) { diff --git a/src/main/java/com/thealgorithms/others/GuassLegendre.java b/src/main/java/com/thealgorithms/others/GuassLegendre.java index 8b15739a6d91..5ecfdf2b84cc 100644 --- a/src/main/java/com/thealgorithms/others/GuassLegendre.java +++ b/src/main/java/com/thealgorithms/others/GuassLegendre.java @@ -6,7 +6,9 @@ * * @author AKS1996 */ -public class GuassLegendre { +public final class GuassLegendre { + private GuassLegendre() { + } public static void main(String[] args) { for (int i = 1; i <= 3; ++i) { @@ -19,7 +21,10 @@ 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; + double a = 1; + double b = Math.pow(2, -0.5); + double t = 0.25; + double p = 1; for (int i = 0; i < l; ++i) { double[] temp = update(a, b, t, p); a = temp[0]; diff --git a/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java b/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java index 57ff204c39b1..0ae1e451bc6a 100644 --- a/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java +++ b/src/main/java/com/thealgorithms/others/HappyNumbersSeq.java @@ -5,7 +5,9 @@ import java.util.Scanner; import java.util.Set; -public class HappyNumbersSeq { +public final class HappyNumbersSeq { + private HappyNumbersSeq() { + } private static final Set<Integer> CYCLE_NUMS = new HashSet<>(Arrays.asList(4, 16, 20, 37, 58, 145)); diff --git a/src/main/java/com/thealgorithms/others/Huffman.java b/src/main/java/com/thealgorithms/others/Huffman.java index cc8c8d09864f..4fdee5d5e70e 100644 --- a/src/main/java/com/thealgorithms/others/Huffman.java +++ b/src/main/java/com/thealgorithms/others/Huffman.java @@ -26,7 +26,9 @@ public int compare(HuffmanNode x, HuffmanNode y) { } } -public class Huffman { +public final class Huffman { + private Huffman() { + } // recursive function to print the // huffman-code through the tree traversal. diff --git a/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java b/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java index 201c0ad2dd80..15093549871b 100644 --- a/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java +++ b/src/main/java/com/thealgorithms/others/InsertDeleteInArray.java @@ -1,8 +1,10 @@ package com.thealgorithms.others; -import java.util.*; +import java.util.Scanner; -public class InsertDeleteInArray { +public final class InsertDeleteInArray { + private InsertDeleteInArray() { + } public static void main(String[] args) { try (Scanner s = new Scanner(System.in)) { @@ -19,33 +21,32 @@ public static void main(String[] args) { // 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(); + int insertPos = 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) { + if (i <= insertPos) { b[i] = a[i]; } else { b[i] = a[i - 1]; } } - b[insert_pos] = ins; + b[insertPos] = 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++) { + int delPos = s.nextInt(); + for (i = delPos; 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 index 7fb5645a2726..73eaf2fc9beb 100644 --- a/src/main/java/com/thealgorithms/others/KMP.java +++ b/src/main/java/com/thealgorithms/others/KMP.java @@ -4,18 +4,20 @@ * Implementation of Knuth–Morris–Pratt algorithm Usage: see the main function * for an example */ -public class KMP { +public final class KMP { + private 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); + 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) { + 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); @@ -37,17 +39,17 @@ public static void KMPmatcher(final String haystack, final String needle) { } // return the prefix function - private static int[] computePrefixFunction(final String P) { - final int n = P.length(); + 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)) { + while (q > 0 && p.charAt(q) != p.charAt(i)) { q = pi[q - 1]; } - if (P.charAt(q) == P.charAt(i)) { + if (p.charAt(q) == p.charAt(i)) { q++; } diff --git a/src/main/java/com/thealgorithms/others/KochSnowflake.java b/src/main/java/com/thealgorithms/others/KochSnowflake.java index 8395b1f486a7..0e2600a7d72f 100644 --- a/src/main/java/com/thealgorithms/others/KochSnowflake.java +++ b/src/main/java/com/thealgorithms/others/KochSnowflake.java @@ -1,6 +1,8 @@ package com.thealgorithms.others; -import java.awt.*; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -22,14 +24,16 @@ * https://natureofcode.com/book/chapter-8-fractals/ * #84-the-koch-curve-and-the-arraylist-technique ). */ -public class KochSnowflake { +public final class KochSnowflake { + private KochSnowflake() { + } public static void main(String[] args) { // Test Iterate-method ArrayList<Vector2> vectors = new ArrayList<Vector2>(); vectors.add(new Vector2(0, 0)); vectors.add(new Vector2(1, 0)); - ArrayList<Vector2> result = Iterate(vectors, 1); + ArrayList<Vector2> result = iterate(vectors, 1); assert result.get(0).x == 0; assert result.get(0).y == 0; @@ -50,7 +54,7 @@ public static void main(String[] args) { int imageWidth = 600; double offsetX = imageWidth / 10.; double offsetY = imageWidth / 3.7; - BufferedImage image = GetKochSnowflake(imageWidth, 5); + BufferedImage image = getKochSnowflake(imageWidth, 5); // The background should be white assert image.getRGB(0, 0) == new Color(255, 255, 255).getRGB(); @@ -76,10 +80,10 @@ public static void main(String[] args) { * @param steps The number of iterations. * @return The transformed vectors after the iteration-steps. */ - public static ArrayList<Vector2> Iterate(ArrayList<Vector2> initialVectors, int steps) { + public static ArrayList<Vector2> iterate(ArrayList<Vector2> initialVectors, int steps) { ArrayList<Vector2> vectors = initialVectors; for (int i = 0; i < steps; i++) { - vectors = IterationStep(vectors); + vectors = iterationStep(vectors); } return vectors; @@ -92,7 +96,7 @@ public static ArrayList<Vector2> Iterate(ArrayList<Vector2> initialVectors, int * @param steps The number of iterations. * @return The image of the rendered Koch snowflake. */ - public static BufferedImage GetKochSnowflake(int imageWidth, int steps) { + public static BufferedImage getKochSnowflake(int imageWidth, int steps) { if (imageWidth <= 0) { throw new IllegalArgumentException("imageWidth should be greater than zero"); } @@ -107,8 +111,8 @@ public static BufferedImage GetKochSnowflake(int imageWidth, int steps) { initialVectors.add(vector2); initialVectors.add(vector3); initialVectors.add(vector1); - ArrayList<Vector2> vectors = Iterate(initialVectors, steps); - return GetImage(vectors, imageWidth, imageWidth); + ArrayList<Vector2> vectors = iterate(initialVectors, steps); + return getImage(vectors, imageWidth, imageWidth); } /** @@ -121,7 +125,7 @@ public static BufferedImage GetKochSnowflake(int imageWidth, int steps) { * applied. * @return The transformed vectors after the iteration-step. */ - private static ArrayList<Vector2> IterationStep(ArrayList<Vector2> vectors) { + private static ArrayList<Vector2> iterationStep(ArrayList<Vector2> vectors) { ArrayList<Vector2> newVectors = new ArrayList<Vector2>(); for (int i = 0; i < vectors.size() - 1; i++) { Vector2 startVector = vectors.get(i); @@ -145,7 +149,7 @@ private static ArrayList<Vector2> IterationStep(ArrayList<Vector2> vectors) { * @param imageHeight The height of the rendered image. * @return The image of the rendered edges. */ - private static BufferedImage GetImage(ArrayList<Vector2> vectors, int imageWidth, int imageHeight) { + private static BufferedImage getImage(ArrayList<Vector2> vectors, int imageWidth, int imageHeight) { BufferedImage image = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); @@ -174,9 +178,10 @@ private static BufferedImage GetImage(ArrayList<Vector2> vectors, int imageWidth */ private static class Vector2 { - double x, y; + double x; + double y; - public Vector2(double x, double y) { + Vector2(double x, double y) { this.x = x; this.y = y; } diff --git a/src/main/java/com/thealgorithms/others/Krishnamurthy.java b/src/main/java/com/thealgorithms/others/Krishnamurthy.java index 1f7cd121933f..8e5ba7c6f1c7 100644 --- a/src/main/java/com/thealgorithms/others/Krishnamurthy.java +++ b/src/main/java/com/thealgorithms/others/Krishnamurthy.java @@ -2,10 +2,13 @@ import java.util.Scanner; -class Krishnamurthy { +final class Krishnamurthy { + private Krishnamurthy() { + } static int fact(int n) { - int i, p = 1; + int i; + int p = 1; for (i = n; i >= 1; i--) { p = p * i; } @@ -14,7 +17,9 @@ static int fact(int n) { public static void main(String[] args) { Scanner sc = new Scanner(System.in); - int a, b, s = 0; + int a; + int b; + int s = 0; System.out.print("Enter the number : "); a = sc.nextInt(); int n = a; diff --git a/src/main/java/com/thealgorithms/others/LineSweep.java b/src/main/java/com/thealgorithms/others/LineSweep.java index 9aa0f6faa8e6..946ba6edb475 100644 --- a/src/main/java/com/thealgorithms/others/LineSweep.java +++ b/src/main/java/com/thealgorithms/others/LineSweep.java @@ -11,14 +11,16 @@ * https://en.wikipedia.org/wiki/Sweep_line_algorithm * https://en.wikipedia.org/wiki/De_Morgan%27s_laws> */ -public class LineSweep { +public final class LineSweep { + private LineSweep() { + } /** * Find Maximum end point * param = ranges : Array of range[start,end] * return Maximum Endpoint */ - public static int FindMaximumEndPoint(int[][] ranges) { + public static int findMaximumEndPoint(int[][] ranges) { Arrays.sort(ranges, Comparator.comparingInt(a -> a[1])); return ranges[ranges.length - 1][1]; } @@ -30,7 +32,7 @@ public static int FindMaximumEndPoint(int[][] ranges) { */ public static boolean isOverlap(int[][] ranges) { - int maximumEndPoint = FindMaximumEndPoint(ranges); + int maximumEndPoint = findMaximumEndPoint(ranges); Arrays.sort(ranges, Comparator.comparingInt(a -> a[0])); int[] numberLine = new int[maximumEndPoint + 2]; for (int[] range : ranges) { diff --git a/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java b/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java index 346ae9f82186..36bcca3edc00 100644 --- a/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java +++ b/src/main/java/com/thealgorithms/others/LinearCongruentialGenerator.java @@ -9,7 +9,10 @@ */ public class LinearCongruentialGenerator { - private double a, c, m, previousValue; + private final double a; + private final double c; + private final double m; + private double previousValue; /** * * diff --git a/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java b/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java index 9bc02535a306..c8328a4ee552 100644 --- a/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java +++ b/src/main/java/com/thealgorithms/others/LowestBasePalindrome.java @@ -6,7 +6,7 @@ * @brief Class for finding the lowest base in which a given integer is a palindrome. cf. https://oeis.org/A016026 */ -final public class LowestBasePalindrome { +public final class LowestBasePalindrome { private LowestBasePalindrome() { } diff --git a/src/main/java/com/thealgorithms/others/Luhn.java b/src/main/java/com/thealgorithms/others/Luhn.java index fd5433ca7b65..600128a7725b 100644 --- a/src/main/java/com/thealgorithms/others/Luhn.java +++ b/src/main/java/com/thealgorithms/others/Luhn.java @@ -38,7 +38,9 @@ * * @see <a href="https://en.wikipedia.org/wiki/Luhn_algorithm">Wiki</a> */ -public class Luhn { +public final class Luhn { + private Luhn() { + } /** * Check input digits array by Luhn algorithm. Initial array doesn't change diff --git a/src/main/java/com/thealgorithms/others/Mandelbrot.java b/src/main/java/com/thealgorithms/others/Mandelbrot.java index e60d5c02ccaf..6d7588090ba8 100644 --- a/src/main/java/com/thealgorithms/others/Mandelbrot.java +++ b/src/main/java/com/thealgorithms/others/Mandelbrot.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import java.awt.*; +import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; @@ -23,7 +23,9 @@ * also https://en.wikipedia.org/wiki/Plotting_algorithms_for_the_Mandelbrot_set * ) */ -public class Mandelbrot { +public final class Mandelbrot { + private Mandelbrot() { + } public static void main(String[] args) { // Test black and white diff --git a/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java b/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java index 3056f14dacfc..0bafc435aa75 100644 --- a/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java +++ b/src/main/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthK.java @@ -8,7 +8,9 @@ * items from the end of the window are removed from consideration while new items from the stream take their place. * @author Swarga-codes (https://github.com/Swarga-codes) */ -public class MaximumSumOfDistinctSubarraysWithLengthK { +public final class MaximumSumOfDistinctSubarraysWithLengthK { + private MaximumSumOfDistinctSubarraysWithLengthK() { + } /* * Returns the maximum sum of subarray of size K consisting of distinct * elements. diff --git a/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java b/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java index 2672dc6f2892..cd2cd02ab908 100644 --- a/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java +++ b/src/main/java/com/thealgorithms/others/MiniMaxAlgorithm.java @@ -55,7 +55,9 @@ public static void main(String[] args) { * @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; + int bestScore; + int score1; + int score2; if (depth == height) { // Leaf node reached. return scores[index]; diff --git a/src/main/java/com/thealgorithms/others/PageRank.java b/src/main/java/com/thealgorithms/others/PageRank.java index fa85e9700d3f..c7be7a9882bc 100644 --- a/src/main/java/com/thealgorithms/others/PageRank.java +++ b/src/main/java/com/thealgorithms/others/PageRank.java @@ -1,11 +1,13 @@ package com.thealgorithms.others; -import java.util.*; +import java.util.Scanner; class PageRank { public static void main(String[] args) { - int nodes, i, j; + int nodes; + int i; + int j; Scanner in = new Scanner(System.in); System.out.print("Enter the Number of WebPages: "); nodes = in.nextInt(); @@ -26,20 +28,20 @@ public static void main(String[] args) { 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; + 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"); + int iterationStep = 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; + this.pagerank[k] = initialPageRank; } System.out.print("\n Initial PageRank Values , 0th Step \n"); @@ -47,40 +49,40 @@ public void calc(double totalNodes) { System.out.printf(" Page Rank of " + k + " is :\t" + this.pagerank[k] + "\n"); } - while (ITERATION_STEP <= 2) { // Iterations + while (iterationStep <= 2) { // Iterations // Store the PageRank for All Nodes in Temporary Array for (k = 1; k <= totalNodes; k++) { - TempPageRank[k] = this.pagerank[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) { + 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 + 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 + 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); + this.pagerank[internalNodeNumber] += tempPageRank[externalNodeNumber] * (1 / outgoingLinks); } } - System.out.printf("\n After " + ITERATION_STEP + "th Step \n"); + System.out.printf("\n After " + iterationStep + "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; + iterationStep = iterationStep + 1; } // Add the Damping Factor to PageRank for (k = 1; k <= totalNodes; k++) { - this.pagerank[k] = (1 - DampingFactor) + DampingFactor * this.pagerank[k]; + this.pagerank[k] = (1 - dampingFactor) + dampingFactor * this.pagerank[k]; } // Display PageRank diff --git a/src/main/java/com/thealgorithms/others/PasswordGen.java b/src/main/java/com/thealgorithms/others/PasswordGen.java index c079d1cbebd2..7d21f112d480 100644 --- a/src/main/java/com/thealgorithms/others/PasswordGen.java +++ b/src/main/java/com/thealgorithms/others/PasswordGen.java @@ -11,14 +11,11 @@ * @author AKS1996 * @date 2017.10.25 */ -class PasswordGen { - - public static void main(String[] args) { - String password = generatePassword(8, 16); - System.out.print("Password: " + password); +final class PasswordGen { + private PasswordGen() { } - static String generatePassword(int min_length, int max_length) { + static String generatePassword(int minLength, int maxLength) { Random random = new Random(); String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -38,7 +35,7 @@ static String generatePassword(int min_length, int max_length) { 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) { + for (int i = random.nextInt(maxLength - minLength) + minLength; i > 0; --i) { password.append(letters.get(random.nextInt(letters.size()))); } diff --git a/src/main/java/com/thealgorithms/others/PerlinNoise.java b/src/main/java/com/thealgorithms/others/PerlinNoise.java index 2f774e16ba90..e6551ed6b9ee 100644 --- a/src/main/java/com/thealgorithms/others/PerlinNoise.java +++ b/src/main/java/com/thealgorithms/others/PerlinNoise.java @@ -7,7 +7,9 @@ * For detailed info and implementation see: <a * href="http://devmag.org.za/2009/04/25/perlin-noise/">Perlin-Noise</a> */ -public class PerlinNoise { +public final class PerlinNoise { + private PerlinNoise() { + } /** * @param width width of noise array diff --git a/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java b/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java index 6b766dc3f5a0..259e108a354d 100644 --- a/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java +++ b/src/main/java/com/thealgorithms/others/QueueUsingTwoStacks.java @@ -25,7 +25,7 @@ class QueueWithStack { /** * Constructor */ - public QueueWithStack() { + QueueWithStack() { this.inStack = new Stack<>(); this.outStack = new Stack<>(); } @@ -112,7 +112,9 @@ public boolean isOutStackEmpty() { * * @author sahilb2 (https://www.github.com/sahilb2) */ -public class QueueUsingTwoStacks { +public final class QueueUsingTwoStacks { + private QueueUsingTwoStacks() { + } /** * Main method diff --git a/src/main/java/com/thealgorithms/others/RabinKarp.java b/src/main/java/com/thealgorithms/others/RabinKarp.java index 8757f03bab4b..f8ca33becad3 100644 --- a/src/main/java/com/thealgorithms/others/RabinKarp.java +++ b/src/main/java/com/thealgorithms/others/RabinKarp.java @@ -7,10 +7,12 @@ // An implementation of Rabin-Karp string matching algorithm // Program will simply end if there is no match -public class RabinKarp { +public final class RabinKarp { + private RabinKarp() { + } public static Scanner scanner = null; - public static final int d = 256; + public static final int ALPHABET_SIZE = 256; public static void main(String[] args) { scanner = new Scanner(System.in); @@ -32,14 +34,14 @@ private static void searchPat(String text, String pattern, int q) { int j = 0; int i = 0; - h = (int) Math.pow(d, m - 1) % q; + h = (int) Math.pow(ALPHABET_SIZE, 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; + p = (ALPHABET_SIZE * p + pattern.charAt(i)) % q; + t = (ALPHABET_SIZE * t + text.charAt(i)) % q; } for (i = 0; i <= n - m; i++) { @@ -67,7 +69,7 @@ private static void searchPat(String text, String pattern, int q) { // value of the next character after the end of the evaluated characters is added to get // the hash value of the next window of characters in the text if (i < n - m) { - t = (d * (t - text.charAt(i) * h) + text.charAt(i + m)) % q; + t = (ALPHABET_SIZE * (t - text.charAt(i) * h) + text.charAt(i + m)) % q; // if hash value becomes less than zero than q is added to make it positive if (t < 0) { diff --git a/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java b/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java index 5e4662b0b052..695a10648b6c 100644 --- a/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java +++ b/src/main/java/com/thealgorithms/others/RemoveDuplicateFromString.java @@ -6,7 +6,9 @@ /** * @author Varun Upadhyay (https://github.com/varunu28) */ -public class RemoveDuplicateFromString { +public final class RemoveDuplicateFromString { + private RemoveDuplicateFromString() { + } public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); diff --git a/src/main/java/com/thealgorithms/others/ReturnSubsequence.java b/src/main/java/com/thealgorithms/others/ReturnSubsequence.java index 0d8cbea0d3b3..ef376c47a8f8 100644 --- a/src/main/java/com/thealgorithms/others/ReturnSubsequence.java +++ b/src/main/java/com/thealgorithms/others/ReturnSubsequence.java @@ -2,7 +2,9 @@ import java.util.Scanner; -public class ReturnSubsequence { +public final class ReturnSubsequence { + private ReturnSubsequence() { + } public static void main(String[] args) { System.out.println("Enter String: "); @@ -28,18 +30,16 @@ private static String[] returnSubsequence(String givenString) { ans[0] = ""; return ans; } - String[] SmallAns = returnSubsequence(givenString.substring(1)); // recursive call to get subsequences of substring starting from index + String[] smallAns = returnSubsequence(givenString.substring(1)); // recursive call to get subsequences of substring starting from index // position=1 - String[] ans = new String[2 * SmallAns.length]; // Our answer will be an array off string of size=2*SmallAns - int i = 0; - for (; i < SmallAns.length; i++) { - ans[i] = SmallAns[i]; // Copying all the strings present in SmallAns to ans string array - } - for (int k = 0; k < SmallAns.length; k++) { - ans[k + SmallAns.length] = givenString.charAt(0) + SmallAns[k]; // Insert character at index=0 of the given + String[] ans = new String[2 * smallAns.length]; // Our answer will be an array off string of size=2*smallAns + System.arraycopy(smallAns, 0, ans, 0, smallAns.length); + + for (int k = 0; k < smallAns.length; k++) { + ans[k + smallAns.length] = givenString.charAt(0) + smallAns[k]; // Insert character at index=0 of the given // substring in front of every string - // in SmallAns + // in smallAns } return ans; } diff --git a/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java b/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java index 7c0fe0b2c6f6..2c26f8eae4dc 100644 --- a/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java +++ b/src/main/java/com/thealgorithms/others/ReverseStackUsingRecursion.java @@ -3,7 +3,9 @@ /* Program to reverse a Stack using Recursion*/ import java.util.Stack; -public class ReverseStackUsingRecursion { +public final class ReverseStackUsingRecursion { + private ReverseStackUsingRecursion() { + } // Stack private static Stack<Integer> stack = new Stack<>(); diff --git a/src/main/java/com/thealgorithms/others/RootPrecision.java b/src/main/java/com/thealgorithms/others/RootPrecision.java index e22db1b99931..bc195ffca5ae 100644 --- a/src/main/java/com/thealgorithms/others/RootPrecision.java +++ b/src/main/java/com/thealgorithms/others/RootPrecision.java @@ -2,33 +2,35 @@ import java.util.Scanner; -public class RootPrecision { +public final class RootPrecision { + private RootPrecision() { + } public static void main(String[] args) { // take input Scanner scn = new Scanner(System.in); - // N is the input number - int N = scn.nextInt(); + // 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)); + // 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) { + public static double squareRoot(int n, int p) { // rv means return value double rv; - double root = Math.pow(N, 0.5); + 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); + 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 */ + so as to have decimal points upto p precision */ rv = (int) root; return rv / precision; diff --git a/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java b/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java new file mode 100644 index 000000000000..2ea3de814d0d --- /dev/null +++ b/src/main/java/com/thealgorithms/others/RotateMatrixBy90Degrees.java @@ -0,0 +1,74 @@ +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.Scanner; + +final class Rotate_by_90_degrees { + private Rotate_by_90_degrees() { + } + + 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.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 + */ +final class Rotate { + private 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; + int 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/SieveOfEratosthenes.java b/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java index d7dcdbd11493..6a3412500d11 100644 --- a/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java +++ b/src/main/java/com/thealgorithms/others/SieveOfEratosthenes.java @@ -5,7 +5,7 @@ /** * @brief utility class implementing <a href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes">Sieve of Eratosthenes</a> */ -final public class SieveOfEratosthenes { +public final class SieveOfEratosthenes { private SieveOfEratosthenes() { } @@ -19,7 +19,8 @@ private static Type[] sievePrimesTill(int n) { checkInput(n); Type[] isPrimeArray = new Type[n + 1]; Arrays.fill(isPrimeArray, Type.PRIME); - isPrimeArray[0] = isPrimeArray[1] = Type.NOT_PRIME; + isPrimeArray[0] = Type.NOT_PRIME; + isPrimeArray[1] = Type.NOT_PRIME; double cap = Math.sqrt(n); for (int i = 2; i <= cap; i++) { diff --git a/src/main/java/com/thealgorithms/others/SkylineProblem.java b/src/main/java/com/thealgorithms/others/SkylineProblem.java index 149adf4349cf..ece398e70405 100644 --- a/src/main/java/com/thealgorithms/others/SkylineProblem.java +++ b/src/main/java/com/thealgorithms/others/SkylineProblem.java @@ -59,7 +59,8 @@ public ArrayList<Skyline> findSkyline(int start, int end) { } public ArrayList<Skyline> mergeSkyline(ArrayList<Skyline> sky1, ArrayList<Skyline> sky2) { - int currentH1 = 0, currentH2 = 0; + int currentH1 = 0; + int currentH2 = 0; ArrayList<Skyline> skyline = new ArrayList<>(); int maxH = 0; diff --git a/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java b/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java index fa3869bc5d2e..22979e59b555 100644 --- a/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java +++ b/src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java @@ -5,11 +5,13 @@ */ import java.util.Scanner; -// An implementaion of string matching using finite automata -public class StringMatchFiniteAutomata { +// An implementation of string matching using finite automata +public final class StringMatchFiniteAutomata { + private StringMatchFiniteAutomata() { + } public static final int CHARS = 256; - public static int[][] FA; + public static int[][] fa; public static Scanner scanner = null; public static void main(String[] args) { @@ -28,13 +30,13 @@ public static void searchPat(String text, String pat) { int m = pat.length(); int n = text.length(); - FA = new int[m + 1][CHARS]; + fa = new int[m + 1][CHARS]; - computeFA(pat, m, FA); + computeFA(pat, m, fa); int state = 0; for (int i = 0; i < n; i++) { - state = FA[state][text.charAt(i)]; + state = fa[state][text.charAt(i)]; if (state == m) { System.out.println("Pattern found at index " + (i - m + 1)); @@ -42,11 +44,11 @@ public static void searchPat(String text, String pat) { } } - // Computes finite automata for the partern - public static void computeFA(String pat, int m, int[][] FA) { + // Computes finite automata for the pattern + 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); + fa[state][x] = getNextState(pat, m, state, x); } } } diff --git a/src/main/java/com/thealgorithms/others/Sudoku.java b/src/main/java/com/thealgorithms/others/Sudoku.java index d2bc1d5c7add..0839a376c5de 100644 --- a/src/main/java/com/thealgorithms/others/Sudoku.java +++ b/src/main/java/com/thealgorithms/others/Sudoku.java @@ -1,6 +1,8 @@ package com.thealgorithms.others; -class Sudoku { +final class Sudoku { + private Sudoku() { + } public static boolean isSafe(int[][] board, int row, int col, int num) { // Row has the unique (row-clash) @@ -84,16 +86,16 @@ public static boolean solveSudoku(int[][] board, int n) { return false; } - public static void print(int[][] board, int N) { + public static void print(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(""); } } @@ -112,11 +114,11 @@ public static void main(String[] args) { {0, 0, 0, 0, 0, 0, 0, 7, 4}, {0, 0, 5, 2, 0, 6, 3, 0, 0}, }; - int N = board.length; + int n = board.length; - if (solveSudoku(board, N)) { + if (solveSudoku(board, n)) { // print solution - print(board, N); + print(board, n); } else { System.out.println("No solution"); } diff --git a/src/main/java/com/thealgorithms/others/TopKWords.java b/src/main/java/com/thealgorithms/others/TopKWords.java deleted file mode 100644 index 664a3ec92eac..000000000000 --- a/src/main/java/com/thealgorithms/others/TopKWords.java +++ /dev/null @@ -1,87 +0,0 @@ -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<String, Integer> getDictionary() { - Map<String, Integer> 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<String, Integer> dictionary = cw.getDictionary(); // get the words dictionary: {word: frequency} - - // we change the map to list for convenient sort - List<Map.Entry<String, Integer>> 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 index c0fb4d75f84d..2216799b987a 100644 --- a/src/main/java/com/thealgorithms/others/TowerOfHanoi.java +++ b/src/main/java/com/thealgorithms/others/TowerOfHanoi.java @@ -2,7 +2,9 @@ import java.util.Scanner; -class TowerOfHanoi { +final class TowerOfHanoi { + private TowerOfHanoi() { + } public static void shift(int n, String startPole, String intermediatePole, String endPole) { // if n becomes zero the program returns thus ending the loop. @@ -10,7 +12,7 @@ public static void shift(int n, String startPole, String intermediatePole, Strin // 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 + 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); diff --git a/src/main/java/com/thealgorithms/others/TwoPointers.java b/src/main/java/com/thealgorithms/others/TwoPointers.java index de44354a6602..01391ec72e78 100644 --- a/src/main/java/com/thealgorithms/others/TwoPointers.java +++ b/src/main/java/com/thealgorithms/others/TwoPointers.java @@ -9,7 +9,9 @@ * <p> * link: https://www.geeksforgeeks.org/two-pointers-technique/ */ -class TwoPointers { +final class TwoPointers { + private TwoPointers() { + } /** * Given a sorted array arr (sorted in ascending order). Find if there diff --git a/src/main/java/com/thealgorithms/others/Verhoeff.java b/src/main/java/com/thealgorithms/others/Verhoeff.java index 2144f373e2a4..9088612aaa43 100644 --- a/src/main/java/com/thealgorithms/others/Verhoeff.java +++ b/src/main/java/com/thealgorithms/others/Verhoeff.java @@ -23,7 +23,9 @@ * @see <a href="https://en.wikipedia.org/wiki/Verhoeff_algorithm">Wiki. * Verhoeff algorithm</a> */ -public class Verhoeff { +public final class Verhoeff { + private Verhoeff() { + } /** * Table {@code d}. Based on multiplication in the dihedral group D5 and is diff --git a/src/main/java/com/thealgorithms/others/cn/HammingDistance.java b/src/main/java/com/thealgorithms/others/cn/HammingDistance.java index 820917a17229..c8239d53d606 100644 --- a/src/main/java/com/thealgorithms/others/cn/HammingDistance.java +++ b/src/main/java/com/thealgorithms/others/cn/HammingDistance.java @@ -1,6 +1,6 @@ package com.thealgorithms.others.cn; -final public class HammingDistance { +public final class HammingDistance { private HammingDistance() { } diff --git a/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java b/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java index e73937f60b48..b22e81fe560e 100644 --- a/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java @@ -40,8 +40,8 @@ private void evaluateWaitingTime() { } private void evaluateTurnAroundTime() { - for (int i = 0; i < processes.size(); i++) { - processes.get(i).setTurnAroundTimeTime(processes.get(i).getBurstTime() + processes.get(i).getWaitingTime()); + for (final var process : processes) { + process.setTurnAroundTimeTime(process.getBurstTime() + process.getWaitingTime()); } } } diff --git a/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java b/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java index 7b058bcee625..9bcd5df81056 100644 --- a/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java @@ -1,6 +1,9 @@ package com.thealgorithms.scheduling; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.PriorityQueue; /** * Preemptive Priority Scheduling Algorithm @@ -13,7 +16,7 @@ class Process { int burstTime; int priority; - public Process(String name, int arrivalTime, int burstTime, int priority) { + Process(String name, int arrivalTime, int burstTime, int priority) { this.name = name; this.arrivalTime = arrivalTime; this.burstTime = burstTime; @@ -21,7 +24,9 @@ public Process(String name, int arrivalTime, int burstTime, int priority) { } } -public class PreemptivePriorityScheduling { +public final class PreemptivePriorityScheduling { + private PreemptivePriorityScheduling() { + } public static List<String> preemptivePriorityScheduling(List<Process> processes) { List<String> ganttChart = new ArrayList<>(); PriorityQueue<Process> readyQueue = new PriorityQueue<>(Comparator.comparingInt(p -> - p.priority)); diff --git a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java index 9968f172b482..991c9a4f6148 100644 --- a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java @@ -95,6 +95,8 @@ private void evaluateTurnAroundTime() { } private void evaluateWaitingTime() { - for (int i = 0; i < processes.size(); i++) processes.get(i).setWaitingTime(processes.get(i).getTurnAroundTimeTime() - processes.get(i).getBurstTime()); + for (final var process : processes) { + process.setWaitingTime(process.getTurnAroundTimeTime() - process.getBurstTime()); + } } } diff --git a/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java b/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java index 2bc5f54ce0dd..ca2144e4924f 100644 --- a/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java @@ -24,7 +24,9 @@ public class SJFScheduling { sortByArrivalTime(); } protected void sortByArrivalTime() { - int size = processes.size(), i, j; + int size = processes.size(); + int i; + int j; ProcessDetails temp; for (i = 0; i < size; i++) { for (j = i + 1; j < size - 1; j++) { @@ -44,8 +46,12 @@ protected void sortByArrivalTime() { public void scheduleProcesses() { ArrayList<ProcessDetails> ready = new ArrayList<>(); - int size = processes.size(), runtime, time = 0; - int executed = 0, j, k = 0; + int size = processes.size(); + int runtime; + int time = 0; + int executed = 0; + int j; + int k = 0; ProcessDetails running; if (size == 0) { @@ -77,25 +83,28 @@ public void scheduleProcesses() { /** * this function evaluates the shortest job of all the ready processes (based on a process * burst time) - * @param ReadyProcesses an array list of ready processes + * @param readyProcesses an array list of ready processes * @return returns the process' with the shortest burst time OR NULL if there are no ready * processes */ - private ProcessDetails findShortestJob(ArrayList<ProcessDetails> ReadyProcesses) { - if (ReadyProcesses.isEmpty()) { + private ProcessDetails findShortestJob(ArrayList<ProcessDetails> readyProcesses) { + if (readyProcesses.isEmpty()) { return null; } - int i, size = ReadyProcesses.size(); - int minBurstTime = ReadyProcesses.get(0).getBurstTime(), temp, positionOfShortestJob = 0; + int i; + int size = readyProcesses.size(); + int minBurstTime = readyProcesses.get(0).getBurstTime(); + int temp; + int positionOfShortestJob = 0; for (i = 1; i < size; i++) { - temp = ReadyProcesses.get(i).getBurstTime(); + temp = readyProcesses.get(i).getBurstTime(); if (minBurstTime > temp) { minBurstTime = temp; positionOfShortestJob = i; } } - return ReadyProcesses.get(positionOfShortestJob); + return readyProcesses.get(positionOfShortestJob); } } diff --git a/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java b/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java index ad8aeabacad8..99214fff20c4 100644 --- a/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java +++ b/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java @@ -31,7 +31,8 @@ public SRTFScheduling(ArrayList<ProcessDetails> processes) { } public void evaluateScheduling() { - int time = 0, cr = 0; // cr=current running process, time= units of time + int time = 0; + int cr = 0; // cr=current running process, time= units of time int n = processes.size(); int[] remainingTime = new int[n]; diff --git a/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java b/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java index e4c0cf9d06a2..40b3cd0c20e3 100644 --- a/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java +++ b/src/main/java/com/thealgorithms/searches/BinarySearch2dArray.java @@ -8,16 +8,21 @@ above it will also be smaller than the target), else that element is greater than the target, then the rows below it are ignored. */ -public class BinarySearch2dArray { +public final class BinarySearch2dArray { + private BinarySearch2dArray() { + } - static int[] BinarySearch(int[][] arr, int target) { - int rowCount = arr.length, colCount = arr[0].length; + static int[] binarySearch(int[][] arr, int target) { + int rowCount = arr.length; + int colCount = arr[0].length; if (rowCount == 1) { return binarySearch(arr, target, 0, 0, colCount); } - int startRow = 0, endRow = rowCount - 1, midCol = colCount / 2; + int startRow = 0; + int endRow = rowCount - 1; + int midCol = colCount / 2; while (startRow < endRow - 1) { int midRow = startRow + (endRow - startRow) / 2; // getting the index of middle row diff --git a/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java b/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java index 77043a03ffa3..debab98c67a8 100644 --- a/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java +++ b/src/main/java/com/thealgorithms/searches/BreadthFirstSearch.java @@ -1,7 +1,11 @@ package com.thealgorithms.searches; import com.thealgorithms.datastructures.Node; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Queue; /** * @author: caos321 diff --git a/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java b/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java index dea0db37b3e5..8e601f9873b3 100644 --- a/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java +++ b/src/main/java/com/thealgorithms/searches/HowManyTimesRotated.java @@ -1,6 +1,6 @@ package com.thealgorithms.searches; -import java.util.*; +import java.util.Scanner; /* Problem Statement: @@ -25,7 +25,9 @@ at the rotated array, to identify the minimum element (say a[i]), we observe tha 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 { +final class HowManyTimesRotated { + private HowManyTimesRotated() { + } public static void main(String[] args) { Scanner sc = new Scanner(System.in); diff --git a/src/main/java/com/thealgorithms/searches/InterpolationSearch.java b/src/main/java/com/thealgorithms/searches/InterpolationSearch.java index 215ecdef7987..aa1ff412b6a7 100644 --- a/src/main/java/com/thealgorithms/searches/InterpolationSearch.java +++ b/src/main/java/com/thealgorithms/searches/InterpolationSearch.java @@ -23,7 +23,8 @@ class InterpolationSearch { */ public int find(int[] array, int key) { // Find indexes of two corners - int start = 0, end = (array.length - 1); + int start = 0; + int end = (array.length - 1); // Since array is sorted, an element present // in array must be in range defined by corner diff --git a/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java b/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java index 324b8f582937..49a86e4e53a8 100644 --- a/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/IterativeBinarySearch.java @@ -32,7 +32,10 @@ public final class IterativeBinarySearch implements SearchAlgorithm { */ @Override public <T extends Comparable<T>> int find(T[] array, T key) { - int l, r, k, cmp; + int l; + int r; + int k; + int cmp; l = 0; r = array.length - 1; diff --git a/src/main/java/com/thealgorithms/searches/KMPSearch.java b/src/main/java/com/thealgorithms/searches/KMPSearch.java index dd728d81bd23..3648a4b08b86 100644 --- a/src/main/java/com/thealgorithms/searches/KMPSearch.java +++ b/src/main/java/com/thealgorithms/searches/KMPSearch.java @@ -2,26 +2,26 @@ class KMPSearch { - int KMPSearch(String pat, String txt) { - int M = pat.length(); - int N = txt.length(); + int kmpSearch(String pat, String txt) { + int m = pat.length(); + int n = txt.length(); // create lps[] that will hold the longest // prefix suffix values for pattern - int[] lps = new int[M]; + int[] lps = new int[m]; int j = 0; // index for pat[] // Preprocess the pattern (calculate lps[] // array) - computeLPSArray(pat, M, lps); + computeLPSArray(pat, m, lps); int i = 0; // index for txt[] - while ((N - i) >= (M - j)) { + while ((n - i) >= (m - j)) { if (pat.charAt(j) == txt.charAt(i)) { j++; i++; } - if (j == M) { + if (j == m) { System.out.println("Found pattern " + "at index " + (i - j)); int index = (i - j); @@ -29,7 +29,7 @@ int KMPSearch(String pat, String txt) { return index; } // mismatch after j matches - else if (i < N && pat.charAt(j) != txt.charAt(i)) { + else if (i < n && pat.charAt(j) != txt.charAt(i)) { // Do not match lps[0..lps[j-1]] characters, // they will match anyway if (j != 0) @@ -42,14 +42,14 @@ else if (i < N && pat.charAt(j) != txt.charAt(i)) { return -1; } - void computeLPSArray(String pat, int M, int[] lps) { + void computeLPSArray(String pat, int m, int[] lps) { // length of the previous longest prefix suffix int len = 0; int i = 1; lps[0] = 0; // lps[0] is always 0 - // the loop calculates lps[i] for i = 1 to M-1 - while (i < M) { + // the loop calculates lps[i] for i = 1 to m-1 + while (i < m) { if (pat.charAt(i) == pat.charAt(len)) { len++; lps[i] = len; diff --git a/src/main/java/com/thealgorithms/searches/LinearSearchThread.java b/src/main/java/com/thealgorithms/searches/LinearSearchThread.java index 6e9d73af6b1f..b354d312d1b3 100644 --- a/src/main/java/com/thealgorithms/searches/LinearSearchThread.java +++ b/src/main/java/com/thealgorithms/searches/LinearSearchThread.java @@ -2,7 +2,9 @@ import java.util.Scanner; -public class LinearSearchThread { +public final class LinearSearchThread { + private LinearSearchThread() { + } public static void main(String[] args) { int[] list = new int[200]; @@ -40,7 +42,8 @@ public static void main(String[] args) { class Searcher extends Thread { private final int[] arr; - private final int left, right; + private final int left; + private final int right; private final int x; private boolean found; diff --git a/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java b/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java index 58afc8dfc00d..268c33cef610 100644 --- a/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java +++ b/src/main/java/com/thealgorithms/searches/MonteCarloTreeSearch.java @@ -78,7 +78,7 @@ public Node monteCarloTreeSearch(Node rootNode) { winnerNode = getWinnerNode(rootNode); printScores(rootNode); - System.out.format("\nThe optimal node is: %02d\n", rootNode.childNodes.indexOf(winnerNode) + 1); + System.out.format("%nThe optimal node is: %02d%n", rootNode.childNodes.indexOf(winnerNode) + 1); return winnerNode; } diff --git a/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java b/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java index 8ae304f6103f..cdd256150871 100644 --- a/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/OrderAgnosticBinarySearch.java @@ -1,46 +1,48 @@ -package com.thealgorithms.searches; - -// URL: https://www.geeksforgeeks.org/order-agnostic-binary-search/ - -/* Order Agnostic Binary Search is an algorithm where we do not know whether the given - sorted array is ascending or descending order. - We declare a boolean variable to find whether the array is ascending order. - In the while loop, we use the two pointer method (start and end) to get the middle element. - if the middle element is equal to our target element, then that is the answer. - If not, then we check if the array is ascending or descending order. - Depending upon the condition, respective statements will be executed and we will get our answer. - */ - -public class OrderAgnosticBinarySearch { - - static int BinSearchAlgo(int[] arr, int start, int end, int target) { - - // Checking whether the given array is ascending order - boolean AscOrd = arr[start] < arr[end]; - - while (start <= end) { - int middle = start + (end - start) / 2; - - // Check if the desired element is present at the middle position - if (arr[middle] == target) return middle; // returns the index of the middle element - - // Ascending order - if (AscOrd) { - if (arr[middle] < target) - start = middle + 1; - else - end = middle - 1; - } - - // Descending order - else { - if (arr[middle] > target) - start = middle + 1; - else - end = middle - 1; - } - } - // Element is not present - return -1; - } -} +package com.thealgorithms.searches; + +// URL: https://www.geeksforgeeks.org/order-agnostic-binary-search/ + +/* Order Agnostic Binary Search is an algorithm where we do not know whether the given + sorted array is ascending or descending order. + We declare a boolean variable to find whether the array is ascending order. + In the while loop, we use the two pointer method (start and end) to get the middle element. + if the middle element is equal to our target element, then that is the answer. + If not, then we check if the array is ascending or descending order. + Depending upon the condition, respective statements will be executed and we will get our answer. + */ + +public final class OrderAgnosticBinarySearch { + private OrderAgnosticBinarySearch() { + } + + static int binSearchAlgo(int[] arr, int start, int end, int target) { + + // Checking whether the given array is ascending order + boolean ascOrd = arr[start] < arr[end]; + + while (start <= end) { + int middle = start + (end - start) / 2; + + // Check if the desired element is present at the middle position + if (arr[middle] == target) return middle; // returns the index of the middle element + + // Ascending order + if (ascOrd) { + if (arr[middle] < target) + start = middle + 1; + else + end = middle - 1; + } + + // Descending order + else { + if (arr[middle] > target) + start = middle + 1; + else + end = middle - 1; + } + } + // Element is not present + return -1; + } +} diff --git a/src/main/java/com/thealgorithms/searches/QuickSelect.java b/src/main/java/com/thealgorithms/searches/QuickSelect.java index 7d3e2e343961..97eab4bb4046 100644 --- a/src/main/java/com/thealgorithms/searches/QuickSelect.java +++ b/src/main/java/com/thealgorithms/searches/QuickSelect.java @@ -1,12 +1,17 @@ package com.thealgorithms.searches; -import java.util.*; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; /** * An implementation of the Quickselect algorithm as described * <a href="https://en.wikipedia.org/wiki/Median_of_medians">here</a>. */ public final class QuickSelect { + private QuickSelect() { + } /** * Selects the {@code n}-th largest element of {@code list}, i.e. the element that would diff --git a/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java b/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java index e774546423f4..cc8387f6c4f3 100644 --- a/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java +++ b/src/main/java/com/thealgorithms/searches/RabinKarpAlgorithm.java @@ -6,8 +6,7 @@ public final class RabinKarpAlgorithm { private RabinKarpAlgorithm() { } - // d is the number of characters in the input alphabet - private static final int d = 256; + private static final int ALPHABET_SIZE = 256; public static int search(String pattern, String text, int primeNumber) { @@ -19,13 +18,13 @@ public static int search(String pattern, String text, int primeNumber) { int h = 1; // The value of h would be "pow(d, patternLength-1)%primeNumber" - for (int i = 0; i < patternLength - 1; i++) h = (h * d) % primeNumber; + for (int i = 0; i < patternLength - 1; i++) h = (h * ALPHABET_SIZE) % primeNumber; // Calculate the hash value of pattern and first // window of text for (int i = 0; i < patternLength; i++) { - hashForPattern = (d * hashForPattern + pattern.charAt(i)) % primeNumber; - hashForText = (d * hashForText + text.charAt(i)) % primeNumber; + hashForPattern = (ALPHABET_SIZE * hashForPattern + pattern.charAt(i)) % primeNumber; + hashForText = (ALPHABET_SIZE * hashForText + text.charAt(i)) % primeNumber; } // Slide the pattern over text one by one @@ -51,7 +50,7 @@ public static int search(String pattern, String text, int primeNumber) { // Calculate hash value for next window of text: Remove // leading digit, add trailing digit if (i < textLength - patternLength) { - hashForText = (d * (hashForText - text.charAt(i) * h) + text.charAt(i + patternLength)) % primeNumber; + hashForText = (ALPHABET_SIZE * (hashForText - text.charAt(i) * h) + text.charAt(i + patternLength)) % primeNumber; // handling negative hashForText if (hashForText < 0) hashForText = (hashForText + primeNumber); diff --git a/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java b/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java index 8860f3380e31..6c6284e28019 100644 --- a/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/RecursiveBinarySearch.java @@ -4,7 +4,7 @@ // Explanation:- https://www.tutorialspoint.com/java-program-for-binary-search-recursive package com.thealgorithms.searches; -import java.util.*; +import java.util.Scanner; // Create a SearchAlgorithm class with a generic type abstract class SearchAlgorithm<T extends Comparable<T>> { diff --git a/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java b/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java index 4e5939d6b2b8..5c7a914e3bf2 100644 --- a/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java +++ b/src/main/java/com/thealgorithms/searches/SaddlebackSearch.java @@ -16,7 +16,9 @@ * * @author Nishita Aggarwal */ -public class SaddlebackSearch { +public final class SaddlebackSearch { + private SaddlebackSearch() { + } /** * This method performs Saddleback Search @@ -55,7 +57,10 @@ 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(); + int i; + int j; + int rows = sc.nextInt(); + int col = sc.nextInt(); arr = new int[rows][col]; for (i = 0; i < rows; i++) { for (j = 0; j < col; j++) { diff --git a/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java b/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java index afd5c194f7c4..c00bfc9da6f5 100644 --- a/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/SquareRootBinarySearch.java @@ -14,7 +14,9 @@ * * @author sahil */ -public class SquareRootBinarySearch { +public final class SquareRootBinarySearch { + private SquareRootBinarySearch() { + } /** * This is the driver method. diff --git a/src/main/java/com/thealgorithms/searches/UnionFind.java b/src/main/java/com/thealgorithms/searches/UnionFind.java index 4dfece0e6381..2effdf37bea5 100644 --- a/src/main/java/com/thealgorithms/searches/UnionFind.java +++ b/src/main/java/com/thealgorithms/searches/UnionFind.java @@ -1,11 +1,13 @@ package com.thealgorithms.searches; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class UnionFind { - private int[] p; - private int[] r; + private final int[] p; + private final int[] r; public UnionFind(int n) { p = new int[n]; @@ -23,7 +25,10 @@ public int find(int i) { return i; } - return p[i] = find(parent); + final int result = find(parent); + p[i] = result; + + return result; } public void union(int x, int y) { diff --git a/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java b/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java index 817d9b355450..acb9fb5cb3cd 100644 --- a/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java +++ b/src/main/java/com/thealgorithms/searches/sortOrderAgnosticBinarySearch.java @@ -1,5 +1,7 @@ package com.thealgorithms.searches; -public class sortOrderAgnosticBinarySearch { +public final class sortOrderAgnosticBinarySearch { + private sortOrderAgnosticBinarySearch() { + } public static int find(int[] arr, int key) { int start = 0; int end = arr.length - 1; diff --git a/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java b/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java index 1c2dce65c953..13076c617c76 100644 --- a/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java +++ b/src/main/java/com/thealgorithms/sorts/BinaryInsertionSort.java @@ -10,7 +10,7 @@ public int[] binaryInsertSort(int[] array) { int high = i - 1; while (low <= high) { - int mid = (low + high) / 2; + final int mid = (low + high) >>> 1; if (temp < array[mid]) { high = mid - 1; } else { diff --git a/src/main/java/com/thealgorithms/sorts/BitonicSort.java b/src/main/java/com/thealgorithms/sorts/BitonicSort.java index 346d860508ca..b4b26299562f 100644 --- a/src/main/java/com/thealgorithms/sorts/BitonicSort.java +++ b/src/main/java/com/thealgorithms/sorts/BitonicSort.java @@ -55,8 +55,8 @@ void bitonicSort(int[] a, int low, int cnt, int 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); + void sort(int[] a, int n, int up) { + bitonicSort(a, 0, n, up); } /* A utility function to print array of size n */ diff --git a/src/main/java/com/thealgorithms/sorts/BogoSort.java b/src/main/java/com/thealgorithms/sorts/BogoSort.java index 75f1e84367c3..7a1f7b216437 100644 --- a/src/main/java/com/thealgorithms/sorts/BogoSort.java +++ b/src/main/java/com/thealgorithms/sorts/BogoSort.java @@ -8,7 +8,7 @@ */ public class BogoSort implements SortAlgorithm { - private static final Random random = new Random(); + private static final Random RANDOM = new Random(); private static <T extends Comparable<T>> boolean isSorted(T[] array) { for (int i = 0; i < array.length - 1; i++) { @@ -24,7 +24,7 @@ private static <T> void nextPermutation(T[] array) { int length = array.length; for (int i = 0; i < array.length; i++) { - int randomIndex = i + random.nextInt(length - i); + int randomIndex = i + RANDOM.nextInt(length - i); SortUtils.swap(array, randomIndex, i); } } diff --git a/src/main/java/com/thealgorithms/sorts/BubbleSort.java b/src/main/java/com/thealgorithms/sorts/BubbleSort.java index 46f30291d346..6823c68d0a74 100644 --- a/src/main/java/com/thealgorithms/sorts/BubbleSort.java +++ b/src/main/java/com/thealgorithms/sorts/BubbleSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - /** * @author Varun Upadhyay (https://github.com/varunu28) * @author Podshivalov Nikita (https://github.com/nikitap492) @@ -21,8 +19,8 @@ public <T extends Comparable<T>> 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); + if (SortUtils.greater(array[j], array[j + 1])) { + SortUtils.swap(array, j, j + 1); swapped = true; } } diff --git a/src/main/java/com/thealgorithms/sorts/BucketSort.java b/src/main/java/com/thealgorithms/sorts/BucketSort.java index 184e36f04db6..2a48cca0f433 100644 --- a/src/main/java/com/thealgorithms/sorts/BucketSort.java +++ b/src/main/java/com/thealgorithms/sorts/BucketSort.java @@ -8,7 +8,9 @@ /** * Wikipedia: https://en.wikipedia.org/wiki/Bucket_sort */ -public class BucketSort { +public final class BucketSort { + private BucketSort() { + } public static void main(String[] args) { int[] arr = new int[10]; diff --git a/src/main/java/com/thealgorithms/sorts/CircleSort.java b/src/main/java/com/thealgorithms/sorts/CircleSort.java index 74b3fc62125d..25c308b16e3c 100644 --- a/src/main/java/com/thealgorithms/sorts/CircleSort.java +++ b/src/main/java/com/thealgorithms/sorts/CircleSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - public class CircleSort implements SortAlgorithm { /* This method implements the circle sort @@ -10,8 +8,11 @@ public class CircleSort implements SortAlgorithm { @Override public <T extends Comparable<T>> T[] sort(T[] array) { int n = array.length; - while (doSort(array, 0, n - 1)) - ; + if (n == 0) { + return array; + } + while (doSort(array, 0, n - 1)) { + } return array; } @@ -24,7 +25,7 @@ private <T extends Comparable<T>> Boolean doSort(T[] array, int left, int right) boolean swapped = false; if (left == right) { - return false; + return Boolean.FALSE; } int low = left; @@ -32,7 +33,7 @@ private <T extends Comparable<T>> Boolean doSort(T[] array, int left, int right) while (low < high) { if (array[low].compareTo(array[high]) > 0) { - swap(array, low, high); + SortUtils.swap(array, low, high); swapped = true; } low++; @@ -40,7 +41,7 @@ private <T extends Comparable<T>> Boolean doSort(T[] array, int left, int right) } if (low == high && array[low].compareTo(array[high + 1]) > 0) { - swap(array, low, high + 1); + SortUtils.swap(array, low, high + 1); swapped = true; } @@ -50,21 +51,4 @@ private <T extends Comparable<T>> Boolean doSort(T[] array, int left, int right) return swapped || leftHalf || rightHalf; } - - /* Driver code*/ - public static void main(String[] args) { - CircleSort CSort = new CircleSort(); - - 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]; - } - - 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; - } - } } diff --git a/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java b/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java index dc3a9a100fa0..c88c7bd099f6 100644 --- a/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java +++ b/src/main/java/com/thealgorithms/sorts/CocktailShakerSort.java @@ -16,7 +16,8 @@ public <T extends Comparable<T>> T[] sort(T[] array) { int length = array.length; int left = 0; int right = length - 1; - int swappedLeft, swappedRight; + int swappedLeft; + int swappedRight; while (left < right) { // front swappedRight = 0; diff --git a/src/main/java/com/thealgorithms/sorts/CombSort.java b/src/main/java/com/thealgorithms/sorts/CombSort.java index 2341ac652e83..edf09a2eb3f8 100644 --- a/src/main/java/com/thealgorithms/sorts/CombSort.java +++ b/src/main/java/com/thealgorithms/sorts/CombSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - /** * Comb Sort algorithm implementation * @@ -52,9 +50,9 @@ public <T extends Comparable<T>> T[] sort(T[] arr) { // Compare all elements with current gap for (int i = 0; i < size - gap; i++) { - if (less(arr[i + gap], arr[i])) { + if (SortUtils.less(arr[i + gap], arr[i])) { // Swap arr[i] and arr[i+gap] - swap(arr, i, i + gap); + SortUtils.swap(arr, i, i + gap); swapped = true; } } @@ -88,6 +86,6 @@ public static void main(String[] args) { ob.sort(arr); System.out.println("sorted array"); - print(arr); + SortUtils.print(arr); } } diff --git a/src/main/java/com/thealgorithms/sorts/CountingSort.java b/src/main/java/com/thealgorithms/sorts/CountingSort.java index 9a9b076b22e0..e83271d9ee67 100644 --- a/src/main/java/com/thealgorithms/sorts/CountingSort.java +++ b/src/main/java/com/thealgorithms/sorts/CountingSort.java @@ -4,7 +4,11 @@ import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; import java.util.stream.IntStream; import java.util.stream.Stream; diff --git a/src/main/java/com/thealgorithms/sorts/DNFSort.java b/src/main/java/com/thealgorithms/sorts/DNFSort.java index 7e18b657973f..50ba8c89715b 100644 --- a/src/main/java/com/thealgorithms/sorts/DNFSort.java +++ b/src/main/java/com/thealgorithms/sorts/DNFSort.java @@ -1,13 +1,16 @@ package com.thealgorithms.sorts; -public class DNFSort { +public final class DNFSort { + private DNFSort() { + } // Sort the input array, the array is assumed to // have values in {0, 1, 2} - static void sort012(int[] a, int arr_size) { + static void sort012(int[] a, int arrSize) { int low = 0; - int high = arr_size - 1; - int mid = 0, temp = 0; + int high = arrSize - 1; + int mid = 0; + int temp; while (mid <= high) { switch (a[mid]) { case 0: { @@ -28,24 +31,26 @@ static void sort012(int[] a, int arr_size) { high--; break; } + default: + throw new IllegalArgumentException("Unexpected value: " + a[mid]); } } } /* Utility function to print array arr[] */ - static void printArray(int[] arr, int arr_size) { - for (int i = 0; i < arr_size; i++) { + static void printArray(int[] arr, int arrSize) { + for (int i = 0; i < arrSize; i++) { System.out.print(arr[i] + " "); } - System.out.println(""); + 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_size = arr.length; - sort012(arr, arr_size); + int arrSize = arr.length; + sort012(arr, arrSize); System.out.println("Array after seggregation "); - printArray(arr, arr_size); + printArray(arr, arrSize); } } diff --git a/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java b/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java index 7a3cdfa317f6..20b8f0ba1abc 100644 --- a/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java +++ b/src/main/java/com/thealgorithms/sorts/DutchNationalFlagSort.java @@ -13,14 +13,14 @@ public class DutchNationalFlagSort implements SortAlgorithm { @Override public <T extends Comparable<T>> T[] sort(T[] unsorted) { - return dutch_national_flag_sort(unsorted, unsorted[(int) Math.ceil((unsorted.length) / 2.0) - 1]); + return dutchNationalFlagSort(unsorted, unsorted[(int) Math.ceil((unsorted.length) / 2.0) - 1]); } public <T extends Comparable<T>> T[] sort(T[] unsorted, T intendedMiddle) { - return dutch_national_flag_sort(unsorted, intendedMiddle); + return dutchNationalFlagSort(unsorted, intendedMiddle); } - private <T extends Comparable<T>> T[] dutch_national_flag_sort(T[] arr, T intendedMiddle) { + private <T extends Comparable<T>> T[] dutchNationalFlagSort(T[] arr, T intendedMiddle) { int i = 0; int j = 0; int k = arr.length - 1; diff --git a/src/main/java/com/thealgorithms/sorts/GnomeSort.java b/src/main/java/com/thealgorithms/sorts/GnomeSort.java index 33a13d5bb2d4..9bef6a2837b5 100644 --- a/src/main/java/com/thealgorithms/sorts/GnomeSort.java +++ b/src/main/java/com/thealgorithms/sorts/GnomeSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - /** * Implementation of gnome sort * @@ -15,10 +13,10 @@ public <T extends Comparable<T>> T[] sort(T[] arr) { int i = 1; int j = 2; while (i < arr.length) { - if (less(arr[i - 1], arr[i])) { + if (SortUtils.less(arr[i - 1], arr[i])) { i = j++; } else { - swap(arr, i - 1, i); + SortUtils.swap(arr, i - 1, i); if (--i == 0) { i = j++; } @@ -67,7 +65,7 @@ public static void main(String[] args) { gnomeSort.sort(strings); System.out.println("After sort : "); - print(integers); - print(strings); + SortUtils.print(integers); + SortUtils.print(strings); } } diff --git a/src/main/java/com/thealgorithms/sorts/InsertionSort.java b/src/main/java/com/thealgorithms/sorts/InsertionSort.java index cd160866ae15..3b8c286515bc 100644 --- a/src/main/java/com/thealgorithms/sorts/InsertionSort.java +++ b/src/main/java/com/thealgorithms/sorts/InsertionSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - import java.util.function.Function; class InsertionSort implements SortAlgorithm { @@ -20,8 +18,8 @@ public <T extends Comparable<T>> T[] sort(T[] array) { public <T extends Comparable<T>> T[] sort(T[] array, int lo, int hi) { for (int i = lo; i < hi; i++) { - for (int j = i; j > lo && less(array[j], array[j - 1]); j--) { - swap(array, j, j - 1); + for (int j = i; j > lo && SortUtils.less(array[j], array[j - 1]); j--) { + SortUtils.swap(array, j, j - 1); } } return array; @@ -45,13 +43,13 @@ public <T extends Comparable<T>> T[] sentinelSort(T[] array) { // put the smallest element to the 0 position as a sentinel, which will allow us to avoid // redundant comparisons like `j > 0` further for (int i = 1; i < n; i++) - if (less(array[i], array[minElemIndex])) minElemIndex = i; - swap(array, 0, minElemIndex); + if (SortUtils.less(array[i], array[minElemIndex])) minElemIndex = i; + SortUtils.swap(array, 0, minElemIndex); for (int i = 2; i < n; i++) { int j = i; T currentValue = array[i]; - while (less(currentValue, array[j - 1])) { + while (SortUtils.less(currentValue, array[j - 1])) { array[j] = array[j - 1]; j--; } @@ -73,13 +71,13 @@ public static void main(String[] args) { InsertionSort insertionSort = new InsertionSort(); double insertionTime = measureApproxExecTime(insertionSort::sort, randomArray); - System.out.printf("Original insertion time: %5.2f sec.\n", insertionTime); + System.out.printf("Original insertion time: %5.2f sec.%n", insertionTime); double insertionSentinelTime = measureApproxExecTime(insertionSort::sentinelSort, copyRandomArray); - System.out.printf("Sentinel insertion time: %5.2f sec.\n", insertionSentinelTime); + System.out.printf("Sentinel insertion time: %5.2f sec.%n", insertionSentinelTime); // ~ 1.5 time sentinel sort is faster, then classical Insertion sort implementation. - System.out.printf("Sentinel insertion is %f3.2 time faster than Original insertion sort\n", insertionTime / insertionSentinelTime); + System.out.printf("Sentinel insertion is %f3.2 time faster than Original insertion sort%n", insertionTime / insertionSentinelTime); } private static double measureApproxExecTime(Function<Double[], Double[]> sortAlgorithm, Double[] randomArray) { diff --git a/src/main/java/com/thealgorithms/sorts/LinkListSort.java b/src/main/java/com/thealgorithms/sorts/LinkListSort.java index e679fa9f03e7..fdbfe3130e41 100644 --- a/src/main/java/com/thealgorithms/sorts/LinkListSort.java +++ b/src/main/java/com/thealgorithms/sorts/LinkListSort.java @@ -7,13 +7,11 @@ package com.thealgorithms.sorts; -import java.util.*; +import java.util.Arrays; public class LinkListSort { public static boolean isSorted(int[] p, int option) { - try (Scanner sc = new Scanner(System.in)) { - } int[] a = p; // Array is taken as input from test class int[] b = p; @@ -24,7 +22,10 @@ public static boolean isSorted(int[] p, int option) { switch (ch) { case 1: Task nm = new Task(); - Node start = null, prev = null, fresh, ptr; + Node start = null; + Node prev = null; + Node fresh; + Node ptr; for (int i = 0; i < a.length; i++) { // New nodes are created and values are added fresh = new Node(); // Node class is called @@ -49,7 +50,10 @@ public static boolean isSorted(int[] p, int option) { // The given array and the expected array is checked if both are same then true // is displayed else false is displayed case 2: - Node start1 = null, prev1 = null, fresh1, ptr1; + Node start1 = null; + Node prev1 = null; + Node fresh1; + Node ptr1; for (int i1 = 0; i1 < a.length; i1++) { // New nodes are created and values are added fresh1 = new Node(); // New node is created @@ -75,7 +79,10 @@ public static boolean isSorted(int[] p, int option) { // is displayed else false is displayed case 3: Task2 mm = new Task2(); - Node start2 = null, prev2 = null, fresh2, ptr2; + Node start2 = null; + Node prev2 = null; + Node fresh2; + Node ptr2; for (int i2 = 0; i2 < a.length; i2++) { // New nodes are created and values are added fresh2 = new Node(); // Node class is created @@ -137,7 +144,7 @@ class Node { class Task { - static int[] a; + private int[] a; public Node sortByMergeSort(Node head) { if (head == null || head.next == null) return head; @@ -181,7 +188,9 @@ void task(int[] n, int i, int j) { } void task1(int[] n, int s, int m, int e) { - int i = s, k = 0, j = m + 1; + int i = s; + int k = 0; + int j = m + 1; int[] b = new int[e - s + 1]; while (i <= m && j <= e) { if (n[j] >= n[i]) @@ -245,7 +254,7 @@ static int count(Node head) { class Task2 { - static int[] a; + private int[] a; public Node sortByHeapSort(Node head) { if (head == null || head.next == null) return head; diff --git a/src/main/java/com/thealgorithms/sorts/MergeSort.java b/src/main/java/com/thealgorithms/sorts/MergeSort.java index 0950b46891ce..9949783ca21b 100644 --- a/src/main/java/com/thealgorithms/sorts/MergeSort.java +++ b/src/main/java/com/thealgorithms/sorts/MergeSort.java @@ -9,7 +9,7 @@ */ class MergeSort implements SortAlgorithm { - @SuppressWarnings("rawtypes") private static Comparable[] aux; + private Comparable[] aux; /** * Generic merge sort algorithm implements. @@ -30,7 +30,7 @@ public <T extends Comparable<T>> T[] sort(T[] unsorted) { * @param left the first index of the array. * @param right the last index of the array. */ - private static <T extends Comparable<T>> void doSort(T[] arr, int left, int right) { + private <T extends Comparable<T>> void doSort(T[] arr, int left, int right) { if (left < right) { int mid = (left + right) >>> 1; doSort(arr, left, mid); @@ -49,8 +49,9 @@ private static <T extends Comparable<T>> void doSort(T[] arr, int left, int righ * increasing order. */ @SuppressWarnings("unchecked") - private static <T extends Comparable<T>> void merge(T[] arr, int left, int mid, int right) { - int i = left, j = mid + 1; + private <T extends Comparable<T>> void merge(T[] arr, int left, int mid, int right) { + int i = left; + int j = mid + 1; System.arraycopy(arr, left, aux, left, right + 1 - left); for (int k = left; k <= right; k++) { diff --git a/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java b/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java index b9551523bb8d..290c2df59c3d 100644 --- a/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java +++ b/src/main/java/com/thealgorithms/sorts/MergeSortNoExtraSpace.java @@ -1,28 +1,30 @@ package com.thealgorithms.sorts; -import java.util.*; import java.util.Arrays; +import java.util.Scanner; /*This code implements the mergeSort algorithm without extra space For understanding about mergesort visit :https://www.geeksforgeeks.org/merge-sort/ */ -public class MergeSortNoExtraSpace { +public final class MergeSortNoExtraSpace { + private MergeSortNoExtraSpace() { + } - public static void call_merge_sort(int[] a, int n) { + public static void callMergeSort(int[] a, int n) { int maxele = Arrays.stream(a).max().getAsInt() + 1; - merge_sort(a, 0, n - 1, maxele); + mergeSort(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 + public static void mergeSort(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); + mergeSort(a, start, mid, maxele); + mergeSort(a, mid + 1, end, maxele); + implementMergeSort(a, start, mid, end, maxele); } } - public static void implement_merge_sort(int[] a, int start, int mid, int end, + public static void implementMergeSort(int[] a, int start, int mid, int end, int maxele) { // implementation of mergesort int i = start; int j = mid + 1; @@ -62,7 +64,7 @@ public static void main(String[] args) { for (int i = 0; i < n; i++) { a[i] = inp.nextInt(); } - call_merge_sort(a, n); + callMergeSort(a, n); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); } diff --git a/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java b/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java index f9d12a2aae38..f67ba631be0e 100644 --- a/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java +++ b/src/main/java/com/thealgorithms/sorts/MergeSortRecursive.java @@ -1,7 +1,6 @@ package com.thealgorithms.sorts; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class MergeSortRecursive { @@ -59,11 +58,3 @@ private static List<Integer> sort(List<Integer> unsortedA, List<Integer> unsorte } } } - -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(); - } -} diff --git a/src/main/java/com/thealgorithms/sorts/OddEvenSort.java b/src/main/java/com/thealgorithms/sorts/OddEvenSort.java index b5213792d12d..fb6e4d2649cb 100644 --- a/src/main/java/com/thealgorithms/sorts/OddEvenSort.java +++ b/src/main/java/com/thealgorithms/sorts/OddEvenSort.java @@ -3,7 +3,9 @@ import java.util.Random; // https://en.wikipedia.org/wiki/Odd%E2%80%93even_sort -public class OddEvenSort { +public final class OddEvenSort { + private OddEvenSort() { + } public static void main(String[] args) { int[] arr = new int[100]; diff --git a/src/main/java/com/thealgorithms/sorts/PancakeSort.java b/src/main/java/com/thealgorithms/sorts/PancakeSort.java index c5e59a0215b7..cd3e89307238 100644 --- a/src/main/java/com/thealgorithms/sorts/PancakeSort.java +++ b/src/main/java/com/thealgorithms/sorts/PancakeSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - /** * Implementation of pancake sort * @@ -18,12 +16,12 @@ public <T extends Comparable<T>> T[] sort(T[] array) { T max = array[0]; int index = 0; for (int j = 0; j < size - i; j++) { - if (less(max, array[j])) { + if (SortUtils.less(max, array[j])) { max = array[j]; index = j; } } - flip(array, index, array.length - 1 - i); + SortUtils.flip(array, index, array.length - 1 - i); } return array; } @@ -62,6 +60,6 @@ public static void main(String[] args) { PancakeSort pancakeSort = new PancakeSort(); System.out.println("After sorting:"); pancakeSort.sort(arr); - print(arr); + SortUtils.print(arr); } } diff --git a/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java b/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java index cd399fb701cb..9c0ab45b6a3c 100644 --- a/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java +++ b/src/main/java/com/thealgorithms/sorts/PigeonholeSort.java @@ -1,8 +1,6 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - -import java.util.*; +import java.util.ArrayList; public class PigeonholeSort { @@ -42,7 +40,7 @@ public static void main(String[] args) { Integer[] arr = {8, 3, 2, 7, 4, 6, 8}; System.out.print("Unsorted order is : "); - print(arr); + SortUtils.print(arr); pigeonholeSort.sort(arr); @@ -50,6 +48,6 @@ public static void main(String[] args) { for (int i = 0; i < arr.length; i++) { assert (arr[i]) <= (arr[i + 1]); } - print(arr); + SortUtils.print(arr); } } diff --git a/src/main/java/com/thealgorithms/sorts/QuickSort.java b/src/main/java/com/thealgorithms/sorts/QuickSort.java index 2842b08a975c..3ebdd96ce938 100644 --- a/src/main/java/com/thealgorithms/sorts/QuickSort.java +++ b/src/main/java/com/thealgorithms/sorts/QuickSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - /** * @author Varun Upadhyay (https://github.com/varunu28) * @author Podshivalov Nikita (https://github.com/nikitap492) @@ -45,7 +43,7 @@ private static <T extends Comparable<T>> void doSort(T[] array, int left, int ri */ private static <T extends Comparable<T>> int randomPartition(T[] array, int left, int right) { int randomIndex = left + (int) (Math.random() * (right - left + 1)); - swap(array, randomIndex, right); + SortUtils.swap(array, randomIndex, right); return partition(array, left, right); } @@ -62,14 +60,14 @@ private static <T extends Comparable<T>> int partition(T[] array, int left, int T pivot = array[mid]; while (left <= right) { - while (less(array[left], pivot)) { + while (SortUtils.less(array[left], pivot)) { ++left; } - while (less(pivot, array[right])) { + while (SortUtils.less(pivot, array[right])) { --right; } if (left <= right) { - swap(array, left, right); + SortUtils.swap(array, left, right); ++left; --right; } diff --git a/src/main/java/com/thealgorithms/sorts/RadixSort.java b/src/main/java/com/thealgorithms/sorts/RadixSort.java index d2090bf86646..a87097bf6e9d 100644 --- a/src/main/java/com/thealgorithms/sorts/RadixSort.java +++ b/src/main/java/com/thealgorithms/sorts/RadixSort.java @@ -2,7 +2,9 @@ import java.util.Arrays; -class RadixSort { +final class RadixSort { + private RadixSort() { + } private static int getMax(int[] arr, int n) { int mx = arr[0]; @@ -33,9 +35,7 @@ private static void countSort(int[] arr, int n, int exp) { count[(arr[i] / exp) % 10]--; } - for (i = 0; i < n; i++) { - arr[i] = output[i]; - } + System.arraycopy(output, 0, arr, 0, n); } private static void radixsort(int[] arr, int n) { diff --git a/src/main/java/com/thealgorithms/sorts/ShellSort.java b/src/main/java/com/thealgorithms/sorts/ShellSort.java index 5f41a5440388..37a50e855698 100644 --- a/src/main/java/com/thealgorithms/sorts/ShellSort.java +++ b/src/main/java/com/thealgorithms/sorts/ShellSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - public class ShellSort implements SortAlgorithm { /** @@ -25,7 +23,7 @@ public <T extends Comparable<T>> T[] sort(T[] array) { 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) { + for (j = i; j >= gap && SortUtils.less(temp, array[j - gap]); j -= gap) { array[j] = array[j - gap]; } array[j] = temp; @@ -43,6 +41,6 @@ public static void main(String[] args) { for (int i = 0; i < toSort.length - 1; ++i) { assert toSort[i] <= toSort[i + 1]; } - print(toSort); + SortUtils.print(toSort); } } diff --git a/src/main/java/com/thealgorithms/sorts/SimpleSort.java b/src/main/java/com/thealgorithms/sorts/SimpleSort.java index 138ebb62937d..7aab7c784b92 100644 --- a/src/main/java/com/thealgorithms/sorts/SimpleSort.java +++ b/src/main/java/com/thealgorithms/sorts/SimpleSort.java @@ -1,16 +1,14 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - public class SimpleSort implements SortAlgorithm { @Override public <T extends Comparable<T>> T[] sort(T[] array) { - final int LENGTH = array.length; + final int length = array.length; - for (int i = 0; i < LENGTH; i++) { - for (int j = i + 1; j < LENGTH; j++) { - if (less(array[j], array[i])) { + for (int i = 0; i < length; i++) { + for (int j = i + 1; j < length; j++) { + if (SortUtils.less(array[j], array[i])) { T element = array[j]; array[j] = array[i]; array[i] = element; @@ -25,12 +23,12 @@ public static void main(String[] args) { // ==== Int ======= Integer[] a = {3, 7, 45, 1, 33, 5, 2, 9}; System.out.print("unsorted: "); - print(a); + SortUtils.print(a); System.out.println(); new SimpleSort().sort(a); System.out.print("sorted: "); - print(a); + SortUtils.print(a); System.out.println(); // ==== String ======= @@ -45,11 +43,11 @@ public static void main(String[] args) { "pineapple", }; System.out.print("unsorted: "); - print(b); + SortUtils.print(b); System.out.println(); new SimpleSort().sort(b); System.out.print("sorted: "); - print(b); + SortUtils.print(b); } } diff --git a/src/main/java/com/thealgorithms/sorts/SlowSort.java b/src/main/java/com/thealgorithms/sorts/SlowSort.java index 1ab8ceea4fdf..dcd426b31c0d 100644 --- a/src/main/java/com/thealgorithms/sorts/SlowSort.java +++ b/src/main/java/com/thealgorithms/sorts/SlowSort.java @@ -16,7 +16,7 @@ private <T extends Comparable<T>> void sort(T[] array, int i, int j) { if (SortUtils.greaterOrEqual(i, j)) { return; } - int m = (i + j) / 2; + final int m = (i + j) >>> 1; sort(array, i, m); sort(array, m + 1, j); if (SortUtils.less(array[j], array[m])) { diff --git a/src/main/java/com/thealgorithms/sorts/SortUtils.java b/src/main/java/com/thealgorithms/sorts/SortUtils.java index 9e114b2084fc..fda1975189ec 100644 --- a/src/main/java/com/thealgorithms/sorts/SortUtils.java +++ b/src/main/java/com/thealgorithms/sorts/SortUtils.java @@ -5,6 +5,8 @@ import java.util.stream.Collectors; final class SortUtils { + private SortUtils() { + } /** * Swaps two elements at the given positions in an array. diff --git a/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java b/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java index e75b8e1e6f04..b048d0245b64 100644 --- a/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java +++ b/src/main/java/com/thealgorithms/sorts/SortUtilsRandomGenerator.java @@ -2,14 +2,16 @@ import java.util.Random; -public class SortUtilsRandomGenerator { +public final class SortUtilsRandomGenerator { + private SortUtilsRandomGenerator() { + } - private static final Random random; - private static final long seed; + private static final Random RANDOM; + private static final long SEED; static { - seed = System.currentTimeMillis(); - random = new Random(seed); + SEED = System.currentTimeMillis(); + RANDOM = new Random(SEED); } /** @@ -30,7 +32,7 @@ public static Double[] generateArray(int size) { * @return Double value [0, 1) */ public static Double generateDouble() { - return random.nextDouble(); + return RANDOM.nextDouble(); } /** @@ -39,6 +41,6 @@ public static Double generateDouble() { * @return int value [0, n) */ public static int generateInt(int n) { - return random.nextInt(n); + return RANDOM.nextInt(n); } } diff --git a/src/main/java/com/thealgorithms/sorts/StrandSort.java b/src/main/java/com/thealgorithms/sorts/StrandSort.java index 2d8411faca4f..7e2251d70640 100644 --- a/src/main/java/com/thealgorithms/sorts/StrandSort.java +++ b/src/main/java/com/thealgorithms/sorts/StrandSort.java @@ -3,7 +3,9 @@ import java.util.Iterator; import java.util.LinkedList; -public class StrandSort { +public final class StrandSort { + private StrandSort() { + } // note: the input list is destroyed public static <E extends Comparable<? super E>> LinkedList<E> strandSort(LinkedList<E> list) { diff --git a/src/main/java/com/thealgorithms/sorts/SwapSort.java b/src/main/java/com/thealgorithms/sorts/SwapSort.java index a626e511bb10..08ce988578f3 100644 --- a/src/main/java/com/thealgorithms/sorts/SwapSort.java +++ b/src/main/java/com/thealgorithms/sorts/SwapSort.java @@ -1,7 +1,5 @@ package com.thealgorithms.sorts; -import static com.thealgorithms.sorts.SortUtils.*; - /** * The idea of Swap-Sort is to count the number m of smaller values (that are in * A) from each element of an array A(1...n) and then swap the element with the @@ -13,10 +11,10 @@ public class SwapSort implements SortAlgorithm { @Override public <T extends Comparable<T>> T[] sort(T[] array) { - int LENGTH = array.length; + int len = array.length; int index = 0; - while (index < LENGTH - 1) { + while (index < len - 1) { int amountSmallerElements = this.getSmallerElementCount(array, index); if (amountSmallerElements > 0 && index != amountSmallerElements) { @@ -34,7 +32,7 @@ public <T extends Comparable<T>> T[] sort(T[] array) { private <T extends Comparable<T>> int getSmallerElementCount(T[] array, int index) { int counter = 0; for (int i = 0; i < array.length; i++) { - if (less(array[i], array[index])) { + if (SortUtils.less(array[i], array[index])) { counter++; } } @@ -46,12 +44,12 @@ public static void main(String[] args) { // ==== Int ======= Integer[] a = {3, 7, 45, 1, 33, 5, 2, 9}; System.out.print("unsorted: "); - print(a); + SortUtils.print(a); System.out.println(); new SwapSort().sort(a); System.out.print("sorted: "); - print(a); + SortUtils.print(a); System.out.println(); // ==== String ======= @@ -66,11 +64,11 @@ public static void main(String[] args) { "pineapple", }; System.out.print("unsorted: "); - print(b); + SortUtils.print(b); System.out.println(); new SwapSort().sort(b); System.out.print("sorted: "); - print(b); + SortUtils.print(b); } } diff --git a/src/main/java/com/thealgorithms/sorts/TimSort.java b/src/main/java/com/thealgorithms/sorts/TimSort.java index be7eaa275c91..85e16636c6ae 100644 --- a/src/main/java/com/thealgorithms/sorts/TimSort.java +++ b/src/main/java/com/thealgorithms/sorts/TimSort.java @@ -9,7 +9,7 @@ */ class TimSort implements SortAlgorithm { private static final int SUB_ARRAY_SIZE = 32; - @SuppressWarnings("rawtypes") private static Comparable[] aux; + private Comparable[] aux; @Override public <T extends Comparable<T>> T[] sort(T[] a) { @@ -30,9 +30,9 @@ public <T extends Comparable<T>> T[] sort(T[] a) { return a; } - @SuppressWarnings("unchecked") - private static <T extends Comparable<T>> void merge(T[] a, int lo, int mid, int hi) { - int i = lo, j = mid + 1; + private <T extends Comparable<T>> void merge(T[] a, int lo, int mid, int hi) { + int i = lo; + int j = mid + 1; System.arraycopy(a, lo, aux, lo, hi + 1 - lo); for (int k = lo; k <= hi; k++) { diff --git a/src/main/java/com/thealgorithms/sorts/TopologicalSort.java b/src/main/java/com/thealgorithms/sorts/TopologicalSort.java index 76d527ce756d..dd3a763bb197 100644 --- a/src/main/java/com/thealgorithms/sorts/TopologicalSort.java +++ b/src/main/java/com/thealgorithms/sorts/TopologicalSort.java @@ -1,6 +1,10 @@ package com.thealgorithms.sorts; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; /** * The Topological Sorting algorithm linearly orders a DAG or Directed Acyclic Graph into @@ -12,7 +16,9 @@ * @author Jonathan Taylor (https://github.com/Jtmonument) * Based on Introduction to Algorithms 3rd Edition */ -public class TopologicalSort { +public final class TopologicalSort { + private TopologicalSort() { + } /* * Enum to represent the colors for the depth first search @@ -43,7 +49,7 @@ private static class Vertex { * */ public final ArrayList<String> next = new ArrayList<>(); - public Vertex(String label) { + Vertex(String label) { this.label = label; } } @@ -67,13 +73,6 @@ public void addEdge(String label, String... next) { } } - static class BackEdgeException extends RuntimeException { - - public BackEdgeException(String backEdge) { - super("This graph contains a cycle. No linear ordering is possible. " + backEdge); - } - } - /* * Depth First Search * @@ -125,7 +124,7 @@ private static String sort(Graph graph, Vertex u, LinkedList<String> list) { * * In many cases, we will not know u.f, but v.color denotes the type of edge * */ - throw new BackEdgeException("Back edge: " + u.label + " -> " + label); + throw new RuntimeException("This graph contains a cycle. No linear ordering is possible. Back edge: " + u.label + " -> " + label); } }); u.color = Color.BLACK; diff --git a/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java b/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java index a73697a7df21..a8f5254b22c5 100644 --- a/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java +++ b/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java @@ -16,7 +16,9 @@ * @author <a href="https://github.com/khalil2535">khalil2535<a> * @author shellhub */ -class BalancedBrackets { +final class BalancedBrackets { + private BalancedBrackets() { + } /** * Check if {@code leftBracket} and {@code rightBracket} is paired or not diff --git a/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java b/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java index 0a206a8ba1e9..41d1c6408ee5 100644 --- a/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java +++ b/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java @@ -2,7 +2,9 @@ import java.util.Stack; -public class DecimalToAnyUsingStack { +public final class DecimalToAnyUsingStack { + private DecimalToAnyUsingStack() { + } public static void main(String[] args) { assert convert(0, 2).equals("0"); diff --git a/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java b/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java index 7daf2e060e22..2fb03de77de5 100644 --- a/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java +++ b/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java @@ -8,9 +8,12 @@ // e.g.' // ((a + b) + (c + d)) -> false // (a + b) + ((c + d)) -> true -import java.util.*; +import java.util.Scanner; +import java.util.Stack; -public class DuplicateBrackets { +public final class DuplicateBrackets { + private DuplicateBrackets() { + } public static boolean check(String str) { Stack<Character> st = new Stack<>(); diff --git a/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java index 2cafdc940650..e3519978c6e5 100644 --- a/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java +++ b/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java @@ -2,7 +2,9 @@ import java.util.Stack; -public class InfixToPostfix { +public final class InfixToPostfix { + private InfixToPostfix() { + } public static void main(String[] args) throws Exception { assert "32+".equals(infix2PostFix("3+2")); diff --git a/src/main/java/com/thealgorithms/stacks/LargestRectangle.java b/src/main/java/com/thealgorithms/stacks/LargestRectangle.java index 63f1d0b4f30d..0404d9c99508 100644 --- a/src/main/java/com/thealgorithms/stacks/LargestRectangle.java +++ b/src/main/java/com/thealgorithms/stacks/LargestRectangle.java @@ -7,10 +7,13 @@ * @author mohd rameez github.com/rameez471 */ -public class LargestRectangle { +public final class LargestRectangle { + private LargestRectangle() { + } public static String largestRectanglehistogram(int[] heights) { - int n = heights.length, maxArea = 0; + int n = heights.length; + int maxArea = 0; Stack<int[]> st = new Stack<>(); for (int i = 0; i < n; i++) { int start = i; diff --git a/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java b/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java index 5eb895d945e5..d76122b16632 100644 --- a/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java +++ b/src/main/java/com/thealgorithms/stacks/MaximumMinimumWindow.java @@ -27,7 +27,9 @@ * * @author sahil */ -public class MaximumMinimumWindow { +public final class MaximumMinimumWindow { + private MaximumMinimumWindow() { + } /** * This function contains the logic of finding maximum of minimum for every diff --git a/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java b/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java index d681e41fbfc3..f7cbea714eb0 100644 --- a/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java +++ b/src/main/java/com/thealgorithms/stacks/NextGreaterElement.java @@ -41,7 +41,9 @@ Next greater element between (6 to n) is -1 -1. */ -public class NextGreaterElement { +public final class NextGreaterElement { + private NextGreaterElement() { + } public static int[] findNextGreaterElements(int[] array) { if (array == null) { diff --git a/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java b/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java index 84263d986508..4d37da0e7c31 100644 --- a/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java +++ b/src/main/java/com/thealgorithms/stacks/NextSmallerElement.java @@ -37,7 +37,9 @@ Next smaller element between (0 , 5) is 6 answer is -1 */ -public class NextSmallerElement { +public final class NextSmallerElement { + private NextSmallerElement() { + } public static int[] findNextSmallerElements(int[] array) { // base case diff --git a/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java b/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java index 0c674ec02a1e..c69a511c2c17 100644 --- a/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java +++ b/src/main/java/com/thealgorithms/stacks/PostfixToInfix.java @@ -16,7 +16,9 @@ * */ -public class PostfixToInfix { +public final class PostfixToInfix { + private PostfixToInfix() { + } public static boolean isOperator(char token) { switch (token) { @@ -26,9 +28,9 @@ public static boolean isOperator(char token) { case '*': case '^': return true; + default: + return false; } - - return false; } public static boolean isValidPostfixExpression(String postfix) { @@ -88,7 +90,8 @@ public static String getPostfixToInfix(String postfix) { Stack<String> stack = new Stack<>(); StringBuilder valueString = new StringBuilder(); - String operandA, operandB; + String operandA; + String operandB; char operator; for (int index = 0; index < postfix.length(); index++) { diff --git a/src/main/java/com/thealgorithms/strings/Alphabetical.java b/src/main/java/com/thealgorithms/strings/Alphabetical.java index fde17c883917..de07dde2d510 100644 --- a/src/main/java/com/thealgorithms/strings/Alphabetical.java +++ b/src/main/java/com/thealgorithms/strings/Alphabetical.java @@ -5,7 +5,9 @@ * based on the position of the characters in the conventional ordering of an * alphabet. Wikipedia: https://en.wikipedia.org/wiki/Alphabetical_order */ -class Alphabetical { +final class Alphabetical { + private Alphabetical() { + } public static void main(String[] args) { assert !isAlphabetical("123abc"); diff --git a/src/main/java/com/thealgorithms/strings/CharactersSame.java b/src/main/java/com/thealgorithms/strings/CharactersSame.java index e0243fa8edef..78ccbbea4898 100644 --- a/src/main/java/com/thealgorithms/strings/CharactersSame.java +++ b/src/main/java/com/thealgorithms/strings/CharactersSame.java @@ -1,6 +1,8 @@ package com.thealgorithms.strings; -public class CharactersSame { +public final class CharactersSame { + private CharactersSame() { + } /** * Driver Code diff --git a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java b/src/main/java/com/thealgorithms/strings/CheckAnagrams.java index a20e8b4ad418..7bf7cd9a7c66 100644 --- a/src/main/java/com/thealgorithms/strings/CheckAnagrams.java +++ b/src/main/java/com/thealgorithms/strings/CheckAnagrams.java @@ -7,7 +7,9 @@ * Two strings are anagrams if they are made of the same letters arranged * differently (ignoring the case). */ -public class CheckAnagrams { +public final class CheckAnagrams { + private CheckAnagrams() { + } /** * Check if two strings are anagrams or not * diff --git a/src/main/java/com/thealgorithms/strings/CheckVowels.java b/src/main/java/com/thealgorithms/strings/CheckVowels.java index 7b4fca3d54ce..44965cc9282c 100644 --- a/src/main/java/com/thealgorithms/strings/CheckVowels.java +++ b/src/main/java/com/thealgorithms/strings/CheckVowels.java @@ -9,7 +9,9 @@ * on the position of the characters in the conventional ordering of an * alphabet. Wikipedia: https://en.wikipedia.org/wiki/Alphabetical_order */ -public class CheckVowels { +public final class CheckVowels { + private CheckVowels() { + } private static final Set<Character> VOWELS = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u')); diff --git a/src/main/java/com/thealgorithms/strings/HammingDistance.java b/src/main/java/com/thealgorithms/strings/HammingDistance.java index bfa3114b1c03..95c523ccd411 100644 --- a/src/main/java/com/thealgorithms/strings/HammingDistance.java +++ b/src/main/java/com/thealgorithms/strings/HammingDistance.java @@ -4,7 +4,9 @@ is the number of positions at which the corresponding symbols are different. https://en.wikipedia.org/wiki/Hamming_distance */ -public class HammingDistance { +public final class HammingDistance { + private HammingDistance() { + } /** * calculate the hamming distance between two strings of equal length diff --git a/src/main/java/com/thealgorithms/strings/HorspoolSearch.java b/src/main/java/com/thealgorithms/strings/HorspoolSearch.java index 99ba2399c42f..d9187cbf66c4 100644 --- a/src/main/java/com/thealgorithms/strings/HorspoolSearch.java +++ b/src/main/java/com/thealgorithms/strings/HorspoolSearch.java @@ -44,7 +44,9 @@ * recommend checking out the wikipedia page and professor Anany Levitin's book: * Introduction To The Design And Analysis Of Algorithms. */ -public class HorspoolSearch { +public final class HorspoolSearch { + private HorspoolSearch() { + } private static HashMap<Character, Integer> shiftValues; // bad symbol table private static Integer patternLength; diff --git a/src/main/java/com/thealgorithms/strings/Isomorphic.java b/src/main/java/com/thealgorithms/strings/Isomorphic.java index 7a355dcafa06..088addc6ea45 100644 --- a/src/main/java/com/thealgorithms/strings/Isomorphic.java +++ b/src/main/java/com/thealgorithms/strings/Isomorphic.java @@ -1,8 +1,13 @@ package com.thealgorithms.strings; -import java.util.*; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; -public class Isomorphic { +public final class Isomorphic { + private Isomorphic() { + } public static boolean checkStrings(String s, String t) { if (s.length() != t.length()) { diff --git a/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java b/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java index 7ad9971eb56b..2e3ee25fb6ea 100644 --- a/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java +++ b/src/main/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumber.java @@ -1,8 +1,12 @@ package com.thealgorithms.strings; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; -public class LetterCombinationsOfPhoneNumber { +public final class LetterCombinationsOfPhoneNumber { + private LetterCombinationsOfPhoneNumber() { + } static Character[][] numberToCharMap; diff --git a/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java b/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java index a74a10aa05c0..fa9171133a15 100644 --- a/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java +++ b/src/main/java/com/thealgorithms/strings/LongestPalindromicSubstring.java @@ -3,7 +3,9 @@ // Longest Palindromic Substring import java.util.Scanner; -class LongestPalindromicSubstring { +final class LongestPalindromicSubstring { + private LongestPalindromicSubstring() { + } public static void main(String[] args) { Solution s = new Solution(); diff --git a/src/main/java/com/thealgorithms/strings/Lower.java b/src/main/java/com/thealgorithms/strings/Lower.java index ef3902b15df3..e20cc5f0f2f7 100644 --- a/src/main/java/com/thealgorithms/strings/Lower.java +++ b/src/main/java/com/thealgorithms/strings/Lower.java @@ -1,6 +1,8 @@ package com.thealgorithms.strings; -public class Lower { +public final class Lower { + private Lower() { + } /** * Driver Code diff --git a/src/main/java/com/thealgorithms/strings/MyAtoi.java b/src/main/java/com/thealgorithms/strings/MyAtoi.java index a8669273a3cd..0aed13f936a7 100644 --- a/src/main/java/com/thealgorithms/strings/MyAtoi.java +++ b/src/main/java/com/thealgorithms/strings/MyAtoi.java @@ -3,16 +3,18 @@ package com.thealgorithms.strings; -public class MyAtoi { +public final class MyAtoi { + private MyAtoi() { + } public static int myAtoi(String s) { s = s.trim(); - char[] char_1 = s.toCharArray(); + char[] char1 = s.toCharArray(); String number = ""; boolean negative = false; boolean zero = false; boolean isDigit = false; - for (char ch : char_1) { + for (char ch : char1) { if (Character.isDigit(ch)) { if (number.length() > 1 && !isDigit) { number = "0"; diff --git a/src/main/java/com/thealgorithms/strings/Palindrome.java b/src/main/java/com/thealgorithms/strings/Palindrome.java index c0cab91bb7c6..3567a371d70e 100644 --- a/src/main/java/com/thealgorithms/strings/Palindrome.java +++ b/src/main/java/com/thealgorithms/strings/Palindrome.java @@ -3,7 +3,9 @@ /** * Wikipedia: https://en.wikipedia.org/wiki/Palindrome */ -class Palindrome { +final class Palindrome { + private Palindrome() { + } /** * Check if a string is palindrome string or not using String Builder diff --git a/src/main/java/com/thealgorithms/strings/Pangram.java b/src/main/java/com/thealgorithms/strings/Pangram.java index 9d734579406c..e0989ce86715 100644 --- a/src/main/java/com/thealgorithms/strings/Pangram.java +++ b/src/main/java/com/thealgorithms/strings/Pangram.java @@ -5,7 +5,9 @@ /** * Wikipedia: https://en.wikipedia.org/wiki/Pangram */ -public class Pangram { +public final class Pangram { + private Pangram() { + } /** * Test code @@ -25,12 +27,11 @@ public static void main(String[] args) { */ // alternative approach using Java Collection Framework public static boolean isPangramUsingSet(String s) { - HashSet<Character> alpha = new HashSet<Character>(); + HashSet<Character> alpha = new HashSet<>(); s = s.trim().toLowerCase(); for (int i = 0; i < s.length(); i++) if (s.charAt(i) != ' ') alpha.add(s.charAt(i)); - if (alpha.size() == 26) return true; - return false; + return alpha.size() == 26; } /** diff --git a/src/main/java/com/thealgorithms/strings/PermuteString.java b/src/main/java/com/thealgorithms/strings/PermuteString.java index d4abb67440b4..f263292eb7bd 100644 --- a/src/main/java/com/thealgorithms/strings/PermuteString.java +++ b/src/main/java/com/thealgorithms/strings/PermuteString.java @@ -11,7 +11,9 @@ 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 final class PermuteString { + private PermuteString() { + } // Function for swapping the characters at position I with character at position j public static String swapString(String a, int i, int j) { diff --git a/src/main/java/com/thealgorithms/strings/ReverseString.java b/src/main/java/com/thealgorithms/strings/ReverseString.java index c5f54f745470..b47a77e9226c 100644 --- a/src/main/java/com/thealgorithms/strings/ReverseString.java +++ b/src/main/java/com/thealgorithms/strings/ReverseString.java @@ -3,7 +3,9 @@ /** * Reverse String using different version */ -public class ReverseString { +public final class ReverseString { + private ReverseString() { + } public static void main(String[] args) { assert reverse("abc123").equals("321cba"); diff --git a/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java b/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java index 0cd2a971b225..e180f6c3991b 100644 --- a/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java +++ b/src/main/java/com/thealgorithms/strings/ReverseStringRecursive.java @@ -4,7 +4,9 @@ * Reverse String using Recursion */ -public class ReverseStringRecursive { +public final class ReverseStringRecursive { + private ReverseStringRecursive() { + } /** * @param str string to be reversed * @return reversed string diff --git a/src/main/java/com/thealgorithms/strings/Rotation.java b/src/main/java/com/thealgorithms/strings/Rotation.java index c82ae5c32758..e1352f1197b1 100644 --- a/src/main/java/com/thealgorithms/strings/Rotation.java +++ b/src/main/java/com/thealgorithms/strings/Rotation.java @@ -6,7 +6,9 @@ * the string "abcdef" to the end of the string, so that the original string * becomes the string "cdefab" */ -public class Rotation { +public final class Rotation { + private Rotation() { + } public static void main(String[] args) { assert rotation("abcdef", 2).equals("cdefab"); diff --git a/src/main/java/com/thealgorithms/strings/StringCompression.java b/src/main/java/com/thealgorithms/strings/StringCompression.java index 28a3df743fc6..131bd4165493 100644 --- a/src/main/java/com/thealgorithms/strings/StringCompression.java +++ b/src/main/java/com/thealgorithms/strings/StringCompression.java @@ -4,7 +4,9 @@ * string * @author Swarga-codes (https://github.com/Swarga-codes) */ -public class StringCompression { +public final class StringCompression { + private StringCompression() { + } /** * Returns the compressed or encoded string * diff --git a/src/main/java/com/thealgorithms/strings/Upper.java b/src/main/java/com/thealgorithms/strings/Upper.java index 8f306a20e8f0..0fc87a9da318 100644 --- a/src/main/java/com/thealgorithms/strings/Upper.java +++ b/src/main/java/com/thealgorithms/strings/Upper.java @@ -1,6 +1,8 @@ package com.thealgorithms.strings; -public class Upper { +public final class Upper { + private Upper() { + } /** * Driver Code diff --git a/src/main/java/com/thealgorithms/strings/ValidParentheses.java b/src/main/java/com/thealgorithms/strings/ValidParentheses.java index 5d3738522d44..947a39da4bde 100644 --- a/src/main/java/com/thealgorithms/strings/ValidParentheses.java +++ b/src/main/java/com/thealgorithms/strings/ValidParentheses.java @@ -4,7 +4,9 @@ // the same type of brackets. Open brackets must be closed in the correct order. Every close // bracket has a corresponding open bracket of the same type. -public class ValidParentheses { +public final class ValidParentheses { + private ValidParentheses() { + } public static boolean isValid(String s) { char[] stack = new char[s.length()]; int head = 0; @@ -24,6 +26,8 @@ public static boolean isValid(String s) { case ']': if (head == 0 || stack[--head] != '[') return false; break; + default: + throw new IllegalArgumentException("Unexpected character: " + c); } } return head == 0; diff --git a/src/main/java/com/thealgorithms/strings/WordLadder.java b/src/main/java/com/thealgorithms/strings/WordLadder.java index e88acbd18586..16d4e0a02452 100644 --- a/src/main/java/com/thealgorithms/strings/WordLadder.java +++ b/src/main/java/com/thealgorithms/strings/WordLadder.java @@ -38,7 +38,9 @@ All the words in wordList are unique. */ -class WordLadder { +final class WordLadder { + private WordLadder() { + } /** * This function finds the ladderLength @@ -65,24 +67,24 @@ public static int ladderLength(String beginWord, String endWord, List<String> wo int size = queue.size(); 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++) { - char original_chars = words_chars[j]; + char[] wordsChars = curr.toCharArray(); + for (int j = 0; j < wordsChars.length; j++) { + char originalChars = wordsChars[j]; for (char c = 'a'; c <= 'z'; c++) { - if (words_chars[j] == c) { + if (wordsChars[j] == c) { continue; } - words_chars[j] = c; - String new_word = String.valueOf(words_chars); - if (new_word.equals(endWord)) { + wordsChars[j] = c; + String newWord = String.valueOf(wordsChars); + if (newWord.equals(endWord)) { return level + 1; } - if (set.contains(new_word)) { - set.remove(new_word); - queue.offer(new_word); + if (set.contains(newWord)) { + set.remove(newWord); + queue.offer(newWord); } } - words_chars[j] = original_chars; + wordsChars[j] = originalChars; } } level++; diff --git a/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java b/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java index 252517dc80cc..99154542955f 100644 --- a/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java +++ b/src/main/java/com/thealgorithms/strings/longestNonRepeativeSubstring.java @@ -2,10 +2,14 @@ import java.util.HashMap; -class longestNonRepeativeSubstring { +final class longestNonRepeativeSubstring { + private longestNonRepeativeSubstring() { + } public static int lengthOfLongestSubstring(String s) { - int max = 0, start = 0, i = 0; + int max = 0; + int start = 0; + int i = 0; HashMap<Character, Integer> map = new HashMap<>(); while (i < s.length()) { diff --git a/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java b/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java index 75ab883386f5..2dfcf3909b8f 100644 --- a/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java +++ b/src/main/java/com/thealgorithms/strings/zigZagPattern/zigZagPattern.java @@ -1,25 +1,32 @@ package com.thealgorithms.strings.zigZagPattern; -class zigZagPattern { +final class zigZagPattern { + private zigZagPattern() { + } public static String encode(String s, int numRows) { if (numRows < 2 || s.length() < numRows) return s; - int start = 0, index = 0, height = 1, depth = numRows; + int start = 0; + int index = 0; + int height = 1; + int depth = numRows; char[] zigZagedArray = new char[s.length()]; while (depth != 0) { - int pointer = start, height_space = 2 + ((height - 2) * 2), depth_space = 2 + ((depth - 2) * 2); + int pointer = start; + int heightSpace = 2 + ((height - 2) * 2); + int depthSpace = 2 + ((depth - 2) * 2); boolean bool = true; while (pointer < s.length()) { zigZagedArray[index++] = s.charAt(pointer); - if (height_space == 0) - pointer += depth_space; - else if (depth_space == 0) - pointer += height_space; + if (heightSpace == 0) + pointer += depthSpace; + else if (depthSpace == 0) + pointer += heightSpace; else if (bool) { - pointer += depth_space; + pointer += depthSpace; bool = false; } else { - pointer += height_space; + pointer += heightSpace; bool = true; } } diff --git a/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java b/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java index cf702ccadecd..177163b09ca1 100644 --- a/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java +++ b/src/test/java/com/thealgorithms/backtracking/AllPathsFromSourceToTargetTest.java @@ -1,8 +1,8 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; -import java.util.*; +import java.util.List; import org.junit.jupiter.api.Test; public class AllPathsFromSourceToTargetTest { diff --git a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java index 02527257ccc6..23fa5d54574c 100644 --- a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java +++ b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import java.util.List; import java.util.TreeSet; diff --git a/src/test/java/com/thealgorithms/backtracking/CombinationTest.java b/src/test/java/com/thealgorithms/backtracking/CombinationTest.java index ed6148271d91..44edc3077fd5 100644 --- a/src/test/java/com/thealgorithms/backtracking/CombinationTest.java +++ b/src/test/java/com/thealgorithms/backtracking/CombinationTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import java.util.TreeSet; diff --git a/src/test/java/com/thealgorithms/backtracking/MColoringTest.java b/src/test/java/com/thealgorithms/backtracking/MColoringTest.java index 606193b05197..8b505abbc046 100644 --- a/src/test/java/com/thealgorithms/backtracking/MColoringTest.java +++ b/src/test/java/com/thealgorithms/backtracking/MColoringTest.java @@ -1,8 +1,8 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.*; +import java.util.ArrayList; import org.junit.jupiter.api.Test; /** diff --git a/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java b/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java index 1464c5221bff..edaca14af067 100644 --- a/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java +++ b/src/test/java/com/thealgorithms/backtracking/MazeRecursionTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java b/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java new file mode 100644 index 000000000000..9da16061d8f4 --- /dev/null +++ b/src/test/java/com/thealgorithms/backtracking/ParenthesesGeneratorTest.java @@ -0,0 +1,33 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class ParenthesesGeneratorTest { + @ParameterizedTest + @MethodSource("regularInputStream") + void regularInputTests(int input, List<String> expected) { + assertEquals(expected, ParenthesesGenerator.generateParentheses(input)); + } + + @ParameterizedTest + @MethodSource("negativeInputStream") + void throwsForNegativeInputTests(int input) { + assertThrows(IllegalArgumentException.class, () -> ParenthesesGenerator.generateParentheses(input)); + } + + private static Stream<Arguments> regularInputStream() { + return Stream.of(Arguments.of(0, List.of("")), Arguments.of(1, List.of("()")), Arguments.of(2, List.of("(())", "()()")), Arguments.of(3, List.of("((()))", "(()())", "(())()", "()(())", "()()()")), + Arguments.of(4, List.of("(((())))", "((()()))", "((())())", "((()))()", "(()(()))", "(()()())", "(()())()", "(())(())", "(())()()", "()((()))", "()(()())", "()(())()", "()()(())", "()()()()"))); + } + + private static Stream<Arguments> negativeInputStream() { + return Stream.of(Arguments.of(-1), Arguments.of(-5), Arguments.of(-10)); + } +} diff --git a/src/test/java/com/thealgorithms/backtracking/PermutationTest.java b/src/test/java/com/thealgorithms/backtracking/PermutationTest.java index b6c0400c623f..76a714829109 100644 --- a/src/test/java/com/thealgorithms/backtracking/PermutationTest.java +++ b/src/test/java/com/thealgorithms/backtracking/PermutationTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.backtracking; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java b/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java new file mode 100644 index 000000000000..dac2e2675674 --- /dev/null +++ b/src/test/java/com/thealgorithms/backtracking/SubsequenceFinderTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.backtracking; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +public class SubsequenceFinderTest { + + @ParameterizedTest + @MethodSource("getTestCases") + void testGenerateAll(TestCase testData) { + final var actual = SubsequenceFinder.generateAll(testData.input()); + assertIterableEquals(testData.expected(), actual); + } + + static Stream<TestCase> getTestCases() { + return Stream.of(new TestCase(new ArrayList<>(), List.of(List.of())), new TestCase(List.of(1, 2), List.of(List.of(), List.of(2), List.of(1), List.of(1, 2))), + new TestCase(List.of("A", "B", "C"), List.of(List.of(), List.of("C"), List.of("B"), List.of("B", "C"), List.of("A"), List.of("A", "C"), List.of("A", "B"), List.of("A", "B", "C"))), + new TestCase(List.of(1, 2, 3), List.of(List.of(), List.of(3), List.of(2), List.of(2, 3), List.of(1), List.of(1, 3), List.of(1, 2), List.of(1, 2, 3))), new TestCase(List.of(2, 2), List.of(List.of(), List.of(2), List.of(2), List.of(2, 2)))); + } + + record TestCase(List<Object> input, List<List<Object>> expected) { + } +} diff --git a/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java b/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java index 8dc61ae4fa9d..532f06f79ab3 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/HighestSetBitTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.bitmanipulation; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java b/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java index 56e9108cbc4b..9bf804373438 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/IndexOfRightMostSetBitTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.bitmanipulation; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java b/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java index 2e33539fe4a7..0b2bfb0bb065 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/IsEvenTest.java @@ -1,14 +1,17 @@ package com.thealgorithms.bitmanipulation; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; class IsEvenTest { @Test void testIsEven() { - assertEquals(true, IsEven.isEven(2)); - assertEquals(true, IsEven.isEven(-12)); - assertEquals(false, IsEven.isEven(21)); + assertTrue(IsEven.isEven(0)); + assertTrue(IsEven.isEven(2)); + assertTrue(IsEven.isEven(-12)); + assertFalse(IsEven.isEven(21)); + assertFalse(IsEven.isEven(-1)); } } diff --git a/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java b/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java index 6954619806f6..27bc93c31ae4 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/IsPowerTwoTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.bitmanipulation; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java b/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java index f0f7353a3365..1addde057181 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/NonRepeatingNumberFinderTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.bitmanipulation; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; @@ -13,11 +13,11 @@ class NonRepeatingNumberFinderTest { @Test void testNonRepeatingNumberFinder() { - int arr[] = {1, 2, 1, 2, 6}; + int[] arr = {1, 2, 1, 2, 6}; assertEquals(6, NonRepeatingNumberFinder.findNonRepeatingNumber(arr)); - int arr1[] = {1, 2, 1, 2}; + int[] arr1 = {1, 2, 1, 2}; assertEquals(0, NonRepeatingNumberFinder.findNonRepeatingNumber(arr1)); - int arr2[] = {12}; + int[] arr2 = {12}; assertEquals(12, NonRepeatingNumberFinder.findNonRepeatingNumber(arr2)); } } diff --git a/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java b/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java index 31ab24826783..13761ac23e44 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/NumbersDifferentSignsTest.java @@ -5,7 +5,8 @@ * @author Bama Charan Chhandogi */ -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java b/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java index 730e345686b6..967a89a1ee97 100644 --- a/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java +++ b/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.bitmanipulation; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java b/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java index e143850e1669..ef5e634f781b 100644 --- a/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java +++ b/src/test/java/com/thealgorithms/ciphers/BlowfishTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.ciphers; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/ciphers/CaesarTest.java b/src/test/java/com/thealgorithms/ciphers/CaesarTest.java index 5fa81f95fa49..7aa41c4cf423 100644 --- a/src/test/java/com/thealgorithms/ciphers/CaesarTest.java +++ b/src/test/java/com/thealgorithms/ciphers/CaesarTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.ciphers; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/ciphers/DESTest.java b/src/test/java/com/thealgorithms/ciphers/DESTest.java index e652c028d5dd..ddc643a6eb35 100644 --- a/src/test/java/com/thealgorithms/ciphers/DESTest.java +++ b/src/test/java/com/thealgorithms/ciphers/DESTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.ciphers; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -45,7 +45,6 @@ void testDecrypt() { + "001101001101001001101011001000011100000011001000011011001110101010010111101111000111" + "101010011010110000100100110011000001010001010110010011011010001010011111000001110011001010011"; String expectedOutput = "Your lips are smoother than vaseline\r\n"; - ; // when String plainText = des.decrypt(cipherText); diff --git a/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java b/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java index 5562241b48db..fa497e4682e8 100644 --- a/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java +++ b/src/test/java/com/thealgorithms/ciphers/PlayfairTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.ciphers; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java b/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java index 9e7f9f697c2a..5cbdf39acb27 100644 --- a/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java +++ b/src/test/java/com/thealgorithms/conversions/BinaryToHexadecimalTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java b/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java index 39a7f67024f1..c7018daecf23 100644 --- a/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java +++ b/src/test/java/com/thealgorithms/conversions/BinaryToOctalTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java b/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java index de2cb7e25ccd..1105f457504e 100644 --- a/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java +++ b/src/test/java/com/thealgorithms/conversions/DecimalToHexaDecimalTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/HexToOctTest.java b/src/test/java/com/thealgorithms/conversions/HexToOctTest.java index d6a9b6092628..5924aa31854b 100644 --- a/src/test/java/com/thealgorithms/conversions/HexToOctTest.java +++ b/src/test/java/com/thealgorithms/conversions/HexToOctTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java b/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java index a5abcb95cb8d..72a0a0174a93 100644 --- a/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java +++ b/src/test/java/com/thealgorithms/conversions/HexaDecimalToBinaryTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java b/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java index 046b00754c4c..04768d034b93 100644 --- a/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java +++ b/src/test/java/com/thealgorithms/conversions/IntegerToRomanTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java b/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java index 6c7fe8702b68..86cf692c5258 100644 --- a/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java +++ b/src/test/java/com/thealgorithms/conversions/OctalToBinaryTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java b/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java index 4a4c6d84b053..6e17ea14efc8 100644 --- a/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java +++ b/src/test/java/com/thealgorithms/conversions/OctalToDecimalTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java b/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java index 347f0eb86fb5..f71732b27d51 100644 --- a/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java +++ b/src/test/java/com/thealgorithms/conversions/OctalToHexadecimalTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.conversions; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java b/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java index 9158d0e12b5d..9bc3b89ced9e 100644 --- a/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java +++ b/src/test/java/com/thealgorithms/datastructures/buffers/CircularBufferTest.java @@ -1,11 +1,18 @@ package com.thealgorithms.datastructures.buffers; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Comparator; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicIntegerArray; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.RepeatedTest; diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java index f931e602383c..eb48c7d9e8d6 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/GCounterTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.datastructures.crdt; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java index 74250ede1f23..b4566aa9b1d8 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/GSetTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.datastructures.crdt; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java index 6fb227bd80c5..36593d6669f8 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/LWWElementSetTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.datastructures.crdt; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java index f12c38f174dc..f6d19a3e7b20 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/ORSetTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.datastructures.crdt; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Set; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java index 46c22a6edcb7..4081b8ae01d8 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/PNCounterTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.datastructures.crdt; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java b/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java index d81362e854d0..dfe392a0d616 100644 --- a/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java +++ b/src/test/java/com/thealgorithms/datastructures/crdt/TwoPSetTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.datastructures.crdt; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java index b5f75f5e831e..579e236699b3 100644 --- a/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.datastructures.graphs; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.datastructures.graphs.BoruvkaAlgorithm.Graph; import java.util.ArrayList; diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java index 9890463de3ff..ed7c886d784e 100644 --- a/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java +++ b/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.datastructures.graphs; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java b/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java index 851432006123..14bddeae1c91 100644 --- a/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java +++ b/src/test/java/com/thealgorithms/datastructures/hashmap/HashMapCuckooHashingTest.java @@ -1,6 +1,9 @@ package com.thealgorithms.datastructures.hashmap; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import com.thealgorithms.datastructures.hashmap.hashing.HashMapCuckooHashing; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java index 621b353b85df..37e43d2aada3 100644 --- a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java +++ b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayListTest.java @@ -1,6 +1,9 @@ package com.thealgorithms.datastructures.hashmap.hashing; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java index b4443da153b4..483e43bb5cb3 100644 --- a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java +++ b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/GenericHashMapUsingArrayTest.java @@ -1,6 +1,9 @@ package com.thealgorithms.datastructures.hashmap.hashing; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java index df014510e8cd..49133ba5ffb5 100644 --- a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java +++ b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MajorityElementTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.datastructures.hashmap.hashing; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Collections; diff --git a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java index ea6595cc803c..44551a8adac6 100644 --- a/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/hashmap/hashing/MapTest.java @@ -1,6 +1,9 @@ package com.thealgorithms.datastructures.hashmap.hashing; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Random; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java b/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java index dfaba3911d0c..f4c4c548ffbf 100644 --- a/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java +++ b/src/test/java/com/thealgorithms/datastructures/heaps/LeftistHeapTest.java @@ -14,14 +14,14 @@ void testLeftistHeap() { heap.insert(2); heap.insert(3); heap.insert(1); - heap.in_order(); - Assertions.assertTrue(heap.in_order().toString().equals("[6, 2, 3, 1]")); - Assertions.assertTrue(heap.extract_min() == 1); - Assertions.assertTrue(heap.in_order().toString().equals("[6, 2, 3]")); + heap.inOrder(); + Assertions.assertTrue(heap.inOrder().toString().equals("[6, 2, 3, 1]")); + Assertions.assertTrue(heap.extractMin() == 1); + Assertions.assertTrue(heap.inOrder().toString().equals("[6, 2, 3]")); heap.insert(8); heap.insert(12); heap.insert(4); - Assertions.assertTrue(heap.in_order().toString().equals("[8, 3, 12, 2, 6, 4]")); + Assertions.assertTrue(heap.inOrder().toString().equals("[8, 3, 12, 2, 6, 4]")); heap.clear(); Assertions.assertTrue(heap.isEmpty()); } diff --git a/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java b/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java index f4bcfd7fc40d..c4113b787de9 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/QuickSortLinkedListTest.java @@ -6,7 +6,8 @@ * GitHub: https://github.com/Prabhat-Kumar-42 */ -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java b/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java index 8273b890e6ae..c03f5b14c641 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/ReverseKGroupTest.java @@ -5,7 +5,8 @@ * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java b/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java index 23780758b664..d3c020f8881b 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/RotateSinglyLinkedListsTest.java @@ -5,7 +5,8 @@ * Author: Bama Charan Chhandogi (https://github.com/BamaCharanChhandogi) */ -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java b/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java index bef02e62a929..a47434083cdb 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/SinglyLinkedListTest.java @@ -1,6 +1,9 @@ package com.thealgorithms.datastructures.lists; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.Arrays; @@ -163,7 +166,7 @@ void reverseListTest() { } // This is Recursive Reverse List Test // Test to check whether the method reverseListRec() works fine - void RecursiveReverseList() { + void recursiveReverseList() { // Create a linked list: 1 -> 2 -> 3 -> 4 -> 5 SinglyLinkedList list = createSampleList(5); @@ -179,7 +182,7 @@ void RecursiveReverseList() { } @Test - void RecursiveReverseListNullPointer() { + void recursiveReverseListNullPointer() { // Create an empty linked list SinglyLinkedList list = new SinglyLinkedList(); Node first = list.getHead(); @@ -192,7 +195,7 @@ void RecursiveReverseListNullPointer() { } @Test - void RecursiveReverseListTest() { + void recursiveReverseListTest() { // Create a linked list with values from 1 to 20 SinglyLinkedList list = createSampleList(20); diff --git a/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java b/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java index 794b38d1502e..c572739ffbbf 100644 --- a/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java +++ b/src/test/java/com/thealgorithms/datastructures/lists/SkipListTest.java @@ -1,8 +1,10 @@ package com.thealgorithms.datastructures.lists; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.*; +import java.util.Arrays; import java.util.stream.IntStream; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java b/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java index 6df221280f86..e8294a323463 100644 --- a/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java +++ b/src/test/java/com/thealgorithms/datastructures/trees/LazySegmentTreeTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.datastructures.trees; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java b/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java index 3bd197bf8bf8..9628e86b9bff 100644 --- a/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java +++ b/src/test/java/com/thealgorithms/datastructures/trees/TreeTestUtils.java @@ -4,7 +4,9 @@ import java.util.LinkedList; import java.util.Queue; -public class TreeTestUtils { +public final class TreeTestUtils { + private TreeTestUtils() { + } /** * Creates a binary tree with given values diff --git a/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java b/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java index bf1a60e84e77..ccada6e061e1 100644 --- a/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java +++ b/src/test/java/com/thealgorithms/divideandconquer/BinaryExponentiationTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.divideandconquer; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java b/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java index 8331d8823486..1ec45a863e1a 100644 --- a/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java +++ b/src/test/java/com/thealgorithms/divideandconquer/StrassenMatrixMultiplicationTest.java @@ -1,40 +1,41 @@ package com.thealgorithms.divideandconquer; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; class StrassenMatrixMultiplicationTest { - StrassenMatrixMultiplication SMM = new StrassenMatrixMultiplication(); + StrassenMatrixMultiplication smm = new StrassenMatrixMultiplication(); // Strassen Matrix Multiplication can only be allplied to matrices of size 2^n // and has to be a Square Matrix @Test - public void StrassenMatrixMultiplicationTest2x2() { - int[][] A = {{1, 2}, {3, 4}}; - int[][] B = {{5, 6}, {7, 8}}; + public void strassenMatrixMultiplicationTest2x2() { + int[][] a = {{1, 2}, {3, 4}}; + int[][] b = {{5, 6}, {7, 8}}; int[][] expResult = {{19, 22}, {43, 50}}; - int[][] actResult = SMM.multiply(A, B); + int[][] actResult = smm.multiply(a, b); assertArrayEquals(expResult, actResult); } @Test - void StrassenMatrixMultiplicationTest4x4() { - int[][] A = {{1, 2, 5, 4}, {9, 3, 0, 6}, {4, 6, 3, 1}, {0, 2, 0, 6}}; - int[][] B = {{1, 0, 4, 1}, {1, 2, 0, 2}, {0, 3, 1, 3}, {1, 8, 1, 2}}; + void strassenMatrixMultiplicationTest4x4() { + int[][] a = {{1, 2, 5, 4}, {9, 3, 0, 6}, {4, 6, 3, 1}, {0, 2, 0, 6}}; + int[][] b = {{1, 0, 4, 1}, {1, 2, 0, 2}, {0, 3, 1, 3}, {1, 8, 1, 2}}; int[][] expResult = {{7, 51, 13, 28}, {18, 54, 42, 27}, {11, 29, 20, 27}, {8, 52, 6, 16}}; - int[][] actResult = SMM.multiply(A, B); + int[][] actResult = smm.multiply(a, b); assertArrayEquals(expResult, actResult); } @Test - void StrassenMatrixMultiplicationTestNegetiveNumber4x4() { - int[][] A = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; - int[][] B = {{1, -2, -3, 4}, {4, -3, -2, 1}, {5, -6, -7, 8}, {8, -7, -6, -5}}; + + void strassenMatrixMultiplicationTestNegetiveNumber4x4() { + int[][] a = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}; + int[][] b = {{1, -2, -3, 4}, {4, -3, -2, 1}, {5, -6, -7, 8}, {8, -7, -6, -5}}; int[][] expResult = {{56, -54, -52, 10}, {128, -126, -124, 42}, {200, -198, -196, 74}, {272, -270, -268, 106}}; - int[][] actResult = SMM.multiply(A, B); + int[][] actResult = smm.multiply(a, b); assertArrayEquals(expResult, actResult); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java index 8fbed8528bee..a065bb8c2a10 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/CatalanNumberTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java index b68e72931e71..d220a2bb512e 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; @@ -9,7 +9,7 @@ public class KnapsackMemoizationTest { KnapsackMemoization knapsackMemoization = new KnapsackMemoization(); @Test - void Test1() { + void test1() { int[] weight = {1, 3, 4, 5}; int[] value = {1, 4, 5, 7}; int capacity = 10; @@ -17,7 +17,7 @@ void Test1() { } @Test - void Test2() { + void test2() { int[] weight = {95, 4, 60, 32, 23, 72, 80, 62, 65, 46}; int[] value = {55, 10, 47, 5, 4, 50, 8, 61, 85, 87}; int capacity = 269; @@ -25,7 +25,7 @@ void Test2() { } @Test - void Test3() { + void test3() { int[] weight = {10, 20, 30}; int[] value = {60, 100, 120}; int capacity = 50; diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java b/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java index a22bf3fea30c..ad4c4c7c53e0 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java @@ -2,15 +2,44 @@ import static org.junit.jupiter.api.Assertions.assertEquals; +import java.util.Arrays; +import java.util.List; +import java.util.function.ToIntBiFunction; +import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class LevenshteinDistanceTests { @ParameterizedTest - @CsvSource({"dog,cat,3", "sunday,saturday,3", "cat,cats,1", "rain,train,1"}) - void levenshteinDistanceTest(String str1, String str2, int distance) { - int result = LevenshteinDistance.calculateLevenshteinDistance(str1, str2); - assertEquals(distance, result); + @MethodSource("testCases") + public void testLevenshteinDistance(final int expected, final String str1, final String str2, final ToIntBiFunction<String, String> dist) { + assertEquals(expected, dist.applyAsInt(str1, str2)); + assertEquals(expected, dist.applyAsInt(str2, str1)); + assertEquals(0, dist.applyAsInt(str1, str1)); + assertEquals(0, dist.applyAsInt(str2, str2)); + } + + private static Stream<Arguments> testCases() { + final Object[][] testData = { + {0, "", ""}, + {0, "Hello, World!", "Hello, World!"}, + {4, "", "Rust"}, + {3, "horse", "ros"}, + {6, "tan", "elephant"}, + {8, "execute", "intention"}, + {1, "a", "b"}, + {1, "a", "aa"}, + {1, "a", ""}, + {1, "a", "ab"}, + {1, "a", "ba"}, + {2, "a", "bc"}, + {2, "a", "cb"}, + }; + + final List<ToIntBiFunction<String, String>> methods = Arrays.asList(LevenshteinDistance::naiveLevenshteinDistance, LevenshteinDistance::optimizedLevenshteinDistance); + + return Stream.of(testData).flatMap(input -> methods.stream().map(method -> Arguments.of(input[0], input[1], input[2], method))); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java b/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java new file mode 100644 index 000000000000..5135105592a5 --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/LongestIncreasingSubsequenceTests.java @@ -0,0 +1,49 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class LongestIncreasingSubsequenceTests { + @FunctionalInterface + public interface IntArrayToInt { + int apply(int[] array); + } + + @ParameterizedTest + @MethodSource("testCases") + public void testLongestIncreasingSubsequence(final int expected, final int[] input, final IntArrayToInt method) { + assertEquals(expected, method.apply(input)); + } + + private static Stream<Arguments> testCases() { + final Object[][] testData = { + {0, new int[] {}}, + {1, new int[] {1}}, + {1, new int[] {2, 2}}, + {1, new int[] {3, 3, 3}}, + {1, new int[] {4, 4, 4, 4}}, + {1, new int[] {5, 5, 5, 5, 5}}, + {2, new int[] {1, 2}}, + {2, new int[] {1, 2, 2, 2, 2}}, + {2, new int[] {1, 0, 2}}, + {3, new int[] {1, 10, 2, 30}}, + {3, new int[] {5, 8, 3, 7, 9, 1}}, + {6, new int[] {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15}}, + {4, new int[] {10, 9, 2, 5, 3, 7, 101, 18}}, + {4, new int[] {10, 10, 9, 9, 2, 2, 5, 5, 3, 3, 7, 7, 101, 101, 18, 18}}, + {4, new int[] {0, 1, 0, 3, 2, 3}}, + {2, new int[] {1, 1, 2, 2, 2}}, + {3, new int[] {1, 1, 2, 2, 2, 3, 3, 3, 3}}, + }; + + final List<IntArrayToInt> methods = Arrays.asList(LongestIncreasingSubsequence::lis, LongestIncreasingSubsequence::findLISLen); + + return Stream.of(testData).flatMap(input -> methods.stream().map(method -> Arguments.of(input[0], input[1], method))); + } +} diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java index 72e1d660028c..173ed00488d0 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/OptimalJobSchedulingTest.java @@ -15,11 +15,11 @@ public void testOptimalJobScheduling1() { int numberProcesses = 5; int numberMachines = 4; - int[][] Run = {{5, 1, 3, 2}, {4, 2, 1, 3}, {1, 5, 2, 1}, {2, 3, 4, 2}, {1, 1, 3, 1}}; + int[][] run = {{5, 1, 3, 2}, {4, 2, 1, 3}, {1, 5, 2, 1}, {2, 3, 4, 2}, {1, 1, 3, 1}}; - int[][] Transfer = {{0, 1, 2, 4}, {1, 0, 2, 3}, {2, 2, 0, 1}, {4, 3, 1, 0}}; + int[][] transfer = {{0, 1, 2, 4}, {1, 0, 2, 3}, {2, 2, 0, 1}, {4, 3, 1, 0}}; - OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, Run, Transfer); + OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, run, transfer); opt.execute(); @@ -40,11 +40,11 @@ public void testOptimalJobScheduling2() { int numberProcesses = 3; int numberMachines = 3; - int[][] Run = {{5, 1, 3}, {4, 2, 1}, {1, 5, 2}}; + int[][] run = {{5, 1, 3}, {4, 2, 1}, {1, 5, 2}}; - int[][] Transfer = {{0, 1, 2}, {1, 0, 2}, {2, 2, 0}}; + int[][] transfer = {{0, 1, 2}, {1, 0, 2}, {2, 2, 0}}; - OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, Run, Transfer); + OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, run, transfer); opt.execute(); @@ -65,7 +65,7 @@ public void testOptimalJobScheduling3() { int numberProcesses = 6; int numberMachines = 4; - int[][] Run = { + int[][] run = { {5, 1, 3, 2}, {4, 2, 1, 1}, {1, 5, 2, 6}, @@ -74,14 +74,14 @@ public void testOptimalJobScheduling3() { {3, 2, 2, 3}, }; - int[][] Transfer = { + int[][] transfer = { {0, 1, 2, 1}, {1, 0, 2, 3}, {2, 2, 0, 2}, {1, 3, 2, 0}, }; - OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, Run, Transfer); + OptimalJobScheduling opt = new OptimalJobScheduling(numberProcesses, numberMachines, run, transfer); opt.execute(); diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java index d63c634c3969..098893f41771 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/PartitionProblemTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java index 13f7b6f9c408..c76f89deb600 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/SubsetCountTest.java @@ -5,27 +5,25 @@ import org.junit.jupiter.api.Test; public class SubsetCountTest { - public static SubsetCount obj = new SubsetCount(); - @Test void hasMultipleSubset() { int[] arr = new int[] {1, 2, 3, 3}; - assertEquals(3, obj.getCount(arr, 6)); + assertEquals(3, SubsetCount.getCount(arr, 6)); } @Test void singleElementSubset() { int[] arr = new int[] {1, 1, 1, 1}; - assertEquals(4, obj.getCount(arr, 1)); + assertEquals(4, SubsetCount.getCount(arr, 1)); } @Test void hasMultipleSubsetSO() { int[] arr = new int[] {1, 2, 3, 3}; - assertEquals(3, obj.getCountSO(arr, 6)); + assertEquals(3, SubsetCount.getCountSO(arr, 6)); } @Test void singleSubsetSO() { int[] arr = new int[] {1, 1, 1, 1}; - assertEquals(1, obj.getCountSO(arr, 4)); + assertEquals(1, SubsetCount.getCountSO(arr, 4)); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java index 53c34937cbab..9df35447eefa 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -8,10 +9,10 @@ class SumOfSubsetTest { @Test void basicCheck() { - assertEquals(false, SumOfSubset.subsetSum(new int[] {1, 2, 7, 10, 9}, 4, 14)); - assertEquals(false, SumOfSubset.subsetSum(new int[] {2, 15, 1, 6, 7}, 4, 4)); - assertEquals(true, SumOfSubset.subsetSum(new int[] {7, 3, 2, 5, 8}, 4, 14)); - assertEquals(true, SumOfSubset.subsetSum(new int[] {4, 3, 2, 1}, 3, 5)); - assertEquals(true, SumOfSubset.subsetSum(new int[] {1, 7, 2, 9, 10}, 4, 13)); + assertFalse(SumOfSubset.subsetSum(new int[] {1, 2, 7, 10, 9}, 4, 14)); + assertFalse(SumOfSubset.subsetSum(new int[] {2, 15, 1, 6, 7}, 4, 4)); + assertTrue(SumOfSubset.subsetSum(new int[] {7, 3, 2, 5, 8}, 4, 14)); + assertTrue(SumOfSubset.subsetSum(new int[] {4, 3, 2, 1}, 3, 5)); + assertTrue(SumOfSubset.subsetSum(new int[] {1, 7, 2, 9, 10}, 4, 13)); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java b/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java index f6a86e72ad9c..386938d28ec9 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java @@ -1,58 +1,59 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; public class UniquePathsTests { @Test - public void testUniquePaths_3x3() { + public void testUniquePaths3x3() { assertEquals(6, UniquePaths.uniquePaths(3, 3)); } @Test - public void testUniquePaths_1x1() { + public void testUniquePaths1x1() { assertEquals(1, UniquePaths.uniquePaths(1, 1)); } @Test - public void testUniquePaths_3x7() { + public void testUniquePaths3x7() { assertEquals(28, UniquePaths.uniquePaths(3, 7)); } @Test - public void testUniquePaths_7x3() { + public void testUniquePaths7x3() { assertEquals(28, UniquePaths.uniquePaths(7, 3)); } @Test - public void testUniquePaths_100x100() { + public void testUniquePaths100x100() { assertThrows(ArithmeticException.class, () -> UniquePaths.uniquePaths(100, 100)); } @Test - public void testUniquePaths2_3x3() { + public void testUniquePathsII3x3() { assertEquals(6, UniquePaths.uniquePaths2(3, 3)); } @Test - public void testUniquePaths2_1x1() { + public void testUniquePathsII1x1() { assertEquals(1, UniquePaths.uniquePaths2(1, 1)); } @Test - public void testUniquePaths2_3x7() { + public void testUniquePathsII3x7() { assertEquals(28, UniquePaths.uniquePaths2(3, 7)); } @Test - public void testUniquePaths2_7x3() { + public void testUniquePathsII7x3() { assertEquals(28, UniquePaths.uniquePaths2(7, 3)); } @Test - public void testUniquePaths2_100x100() { + public void testUniquePathsII100x100() { assertThrows(ArithmeticException.class, () -> UniquePaths.uniquePaths2(100, 100)); } } diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java index 8d91af663ec5..56cd4ffe7d44 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java @@ -1,5 +1,6 @@ package com.thealgorithms.dynamicprogramming; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java index 42263ac1de8a..a997c198a39b 100644 --- a/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java +++ b/src/test/java/com/thealgorithms/greedyalgorithms/ActivitySelectionTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.greedyalgorithms; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; @@ -9,8 +9,8 @@ public class ActivitySelectionTest { @Test public void testActivitySelection() { - int start[] = {1, 3, 0, 5, 8, 5}; - int end[] = {2, 4, 6, 7, 9, 9}; + int[] start = {1, 3, 0, 5, 8, 5}; + int[] end = {2, 4, 6, 7, 9, 9}; ArrayList<Integer> result = ActivitySelection.activitySelection(start, end); ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0, 1, 3, 4)); @@ -20,8 +20,8 @@ public void testActivitySelection() { @Test public void testSingleActivity() { - int start[] = {1}; - int end[] = {2}; + int[] start = {1}; + int[] end = {2}; ArrayList<Integer> result = ActivitySelection.activitySelection(start, end); ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0)); @@ -31,8 +31,8 @@ public void testSingleActivity() { @Test public void testNoOverlap() { - int start[] = {1, 2, 3}; - int end[] = {2, 3, 4}; + int[] start = {1, 2, 3}; + int[] end = {2, 3, 4}; ArrayList<Integer> result = ActivitySelection.activitySelection(start, end); ArrayList<Integer> expected = new ArrayList<>(Arrays.asList(0, 1, 2)); diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java index edbf0a09bcbd..34ec354ba6f0 100644 --- a/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java +++ b/src/test/java/com/thealgorithms/greedyalgorithms/FractionalKnapsackTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.greedyalgorithms; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; @@ -8,24 +8,24 @@ public class FractionalKnapsackTest { @Test public void testFractionalKnapsackWithExampleCase() { - int weight[] = {10, 20, 30}; - int value[] = {60, 100, 120}; + int[] weight = {10, 20, 30}; + int[] value = {60, 100, 120}; int capacity = 50; assertEquals(240, FractionalKnapsack.fractionalKnapsack(weight, value, capacity)); } @Test public void testFractionalKnapsackWithZeroCapacity() { - int weight[] = {10, 20, 30}; - int value[] = {60, 100, 120}; + int[] weight = {10, 20, 30}; + int[] value = {60, 100, 120}; int capacity = 0; assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity)); } @Test public void testFractionalKnapsackWithEmptyItems() { - int weight[] = {}; - int value[] = {}; + int[] weight = {}; + int[] value = {}; int capacity = 50; assertEquals(0, FractionalKnapsack.fractionalKnapsack(weight, value, capacity)); } diff --git a/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java b/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java index 8dd42bc7c5ec..b679121689a1 100644 --- a/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java +++ b/src/test/java/com/thealgorithms/greedyalgorithms/JobSequencingTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.greedyalgorithms; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Collections; diff --git a/src/test/java/com/thealgorithms/io/BufferedReaderTest.java b/src/test/java/com/thealgorithms/io/BufferedReaderTest.java index c9872980c3b7..baccf319d15e 100644 --- a/src/test/java/com/thealgorithms/io/BufferedReaderTest.java +++ b/src/test/java/com/thealgorithms/io/BufferedReaderTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.io; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/src/test/java/com/thealgorithms/maths/AreaTest.java b/src/test/java/com/thealgorithms/maths/AreaTest.java index 91fd03748163..b28afb85fbc3 100644 --- a/src/test/java/com/thealgorithms/maths/AreaTest.java +++ b/src/test/java/com/thealgorithms/maths/AreaTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java b/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java index 9571efff1a42..0a366cd1adbe 100644 --- a/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java +++ b/src/test/java/com/thealgorithms/maths/AutomorphicNumberTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/AverageTest.java b/src/test/java/com/thealgorithms/maths/AverageTest.java index 2008232c3b18..c5c751938f5d 100644 --- a/src/test/java/com/thealgorithms/maths/AverageTest.java +++ b/src/test/java/com/thealgorithms/maths/AverageTest.java @@ -8,25 +8,25 @@ public class AverageTest { private static final double SMALL_VALUE = 0.00001d; @Test - public void testAverage_double_12() { + public void testAverageDouble12() { double[] numbers = {3d, 6d, 9d, 12d, 15d, 18d, 21d}; Assertions.assertEquals(12d, Average.average(numbers), SMALL_VALUE); } @Test - public void testAverage_double_20() { + public void testAverageDouble20() { double[] numbers = {5d, 10d, 15d, 20d, 25d, 30d, 35d}; Assertions.assertEquals(20d, Average.average(numbers), SMALL_VALUE); } @Test - public void testAverage_double_4_5() { + public void testAverageDouble() { double[] numbers = {1d, 2d, 3d, 4d, 5d, 6d, 7d, 8d}; Assertions.assertEquals(4.5d, Average.average(numbers), SMALL_VALUE); } @Test - public void testAverage_int_5() { + public void testAverageInt() { int[] numbers = {2, 4, 10}; Assertions.assertEquals(5, Average.average(numbers)); } diff --git a/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java b/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java index 118e8db8726d..4e88d1e91bac 100644 --- a/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java +++ b/src/test/java/com/thealgorithms/maths/CollatzConjectureTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.List; import org.junit.jupiter.api.BeforeAll; diff --git a/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java b/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java index 09c8c4b1cc94..cd93edfae61d 100644 --- a/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java +++ b/src/test/java/com/thealgorithms/maths/DudeneyNumberTest.java @@ -1,17 +1,28 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; class DudeneyNumberTest { + @ParameterizedTest + @CsvSource({"1", "512", "4913", "5832", "17576", "19683"}) + void positiveDudeneyBase10Power3(final int n) { + assertTrue(DudeneyNumber.isDudeney(n)); + } - @Test - void isDudeney() { - final int validDudeneyNumber = 512; - final int invalidDudeneyNumber = 125; + @ParameterizedTest + @CsvSource({"2", "19", "21", "125", "27", "343", "729", "19682", "19684"}) + void negativeDudeneyBase10Power3(final int n) { + assertFalse(DudeneyNumber.isDudeney(n)); + } - assertTrue(() -> DudeneyNumber.isDudeney(validDudeneyNumber)); - assertFalse(() -> DudeneyNumber.isDudeney(invalidDudeneyNumber)); + @ParameterizedTest + @CsvSource({"0", "-1"}) + void throwsInputLessThanOne(final int n) { + assertThrows(IllegalArgumentException.class, () -> DudeneyNumber.isDudeney(n)); } } diff --git a/src/test/java/com/thealgorithms/maths/FFTTest.java b/src/test/java/com/thealgorithms/maths/FFTTest.java index dfb9ea532dee..696ab5a24732 100644 --- a/src/test/java/com/thealgorithms/maths/FFTTest.java +++ b/src/test/java/com/thealgorithms/maths/FFTTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import java.util.ArrayList; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java b/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java new file mode 100644 index 000000000000..db18b46356b4 --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java @@ -0,0 +1,27 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class FactorialRecursionTest { + @ParameterizedTest + @MethodSource("inputStream") + void testFactorialRecursion(long expected, int number) { + assertEquals(expected, FactorialRecursion.factorial(number)); + } + + private static Stream<Arguments> inputStream() { + return Stream.of(Arguments.of(1, 0), Arguments.of(1, 1), Arguments.of(2, 2), Arguments.of(6, 3), Arguments.of(120, 5)); + } + + @Test + void testThrowsForNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> FactorialRecursion.factorial(-1)); + } +} diff --git a/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java b/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java index 6e664f54307f..a3416a6bc871 100644 --- a/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java +++ b/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java b/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java index bea4e0a63d1f..af1c459f3d7f 100644 --- a/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java +++ b/src/test/java/com/thealgorithms/maths/HarshadNumberTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java b/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java index 52322e5558a9..05e58cf88e22 100644 --- a/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java +++ b/src/test/java/com/thealgorithms/maths/KaprekarNumbersTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java b/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java index a2be8a4c4954..a2763047acf0 100644 --- a/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java +++ b/src/test/java/com/thealgorithms/maths/LiouvilleLambdaFunctionTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/LongDivisionTest.java b/src/test/java/com/thealgorithms/maths/LongDivisionTest.java index f0d702efa127..24f757f8f3ad 100644 --- a/src/test/java/com/thealgorithms/maths/LongDivisionTest.java +++ b/src/test/java/com/thealgorithms/maths/LongDivisionTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/MeansTest.java b/src/test/java/com/thealgorithms/maths/MeansTest.java index fa17cea68f7c..a1c07e25bea3 100644 --- a/src/test/java/com/thealgorithms/maths/MeansTest.java +++ b/src/test/java/com/thealgorithms/maths/MeansTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.ArrayList; import java.util.LinkedHashSet; diff --git a/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java b/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java index 6e6fd491b989..d547cecf24cd 100644 --- a/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java +++ b/src/test/java/com/thealgorithms/maths/MillerRabinPrimalityCheckTest.java @@ -1,30 +1,30 @@ package com.thealgorithms.maths; -import static com.thealgorithms.maths.MillerRabinPrimalityCheck.*; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; class MillerRabinPrimalityCheckTest { @Test void testDeterministicMillerRabinForPrimes() { - assertTrue(deterministicMillerRabin(2)); - assertTrue(deterministicMillerRabin(37)); - assertTrue(deterministicMillerRabin(123457)); - assertTrue(deterministicMillerRabin(6472601713L)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(2)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(37)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(123457)); + assertTrue(MillerRabinPrimalityCheck.deterministicMillerRabin(6472601713L)); } @Test void testDeterministicMillerRabinForNotPrimes() { - assertFalse(deterministicMillerRabin(1)); - assertFalse(deterministicMillerRabin(35)); - assertFalse(deterministicMillerRabin(123453)); - assertFalse(deterministicMillerRabin(647260175)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(1)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(35)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(123453)); + assertFalse(MillerRabinPrimalityCheck.deterministicMillerRabin(647260175)); } @Test void testMillerRabinForPrimes() { - assertTrue(millerRabin(11, 5)); - assertTrue(millerRabin(97, 5)); - assertTrue(millerRabin(6720589, 5)); - assertTrue(millerRabin(9549401549L, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(11, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(97, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(6720589, 5)); + assertTrue(MillerRabinPrimalityCheck.millerRabin(9549401549L, 5)); } } diff --git a/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java b/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java index ddfac15d8200..f3a6514ce633 100644 --- a/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java +++ b/src/test/java/com/thealgorithms/maths/MobiusFunctionTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/ModeTest.java b/src/test/java/com/thealgorithms/maths/ModeTest.java new file mode 100644 index 000000000000..629fd8bd580a --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/ModeTest.java @@ -0,0 +1,21 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class ModeTest { + @ParameterizedTest + @MethodSource("tcStream") + void basicTest(final int[] expected, final int[] numbers) { + assertArrayEquals(expected, Mode.mode(numbers)); + } + + private static Stream<Arguments> tcStream() { + return Stream.of(Arguments.of(null, new int[] {}), Arguments.of(new int[] {5}, new int[] {5}), Arguments.of(new int[] {1, 2, 3, 4, 5}, new int[] {1, 2, 3, 4, 5}), Arguments.of(new int[] {1, 2, 3, 4, 5}, new int[] {5, 4, 3, 2, 1}), + Arguments.of(new int[] {7}, new int[] {7, 9, 9, 4, 5, 6, 7, 7, 8}), Arguments.of(new int[] {7, 9}, new int[] {7, 9, 9, 4, 5, 6, 7, 7, 9})); + } +} diff --git a/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java b/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java new file mode 100644 index 000000000000..799052b22d83 --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/NumberOfDigitsTest.java @@ -0,0 +1,39 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.function.IntFunction; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +public class NumberOfDigitsTest { + + @ParameterizedTest + @MethodSource("testCases") + void testNumberOfDigits(final int expected, final int number, final IntFunction<Integer> methodUnderTest) { + assertEquals(expected, methodUnderTest.apply(number)); + assertEquals(expected, methodUnderTest.apply(-number)); + } + + private static Stream<Arguments> testCases() { + final Integer[][] inputs = new Integer[][] { + {3, 100}, + {1, 0}, + {2, 12}, + {3, 123}, + {4, 1234}, + {5, 12345}, + {6, 123456}, + {7, 1234567}, + {8, 12345678}, + {9, 123456789}, + {9, 987654321}, + }; + + final IntFunction<Integer>[] methods = new IntFunction[] {NumberOfDigits::numberOfDigits, NumberOfDigits::numberOfDigitsFast, NumberOfDigits::numberOfDigitsFaster, NumberOfDigits::numberOfDigitsRecursion}; + + return Stream.of(inputs).flatMap(input -> Stream.of(methods).map(method -> Arguments.of(input[0], input[1], method))); + } +} diff --git a/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java b/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java index 4f5ec4cef095..a1512aacb30d 100644 --- a/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java +++ b/src/test/java/com/thealgorithms/maths/PascalTriangleTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java b/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java index 4dc7c8ce53ad..0433ba80cfa4 100644 --- a/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java +++ b/src/test/java/com/thealgorithms/maths/PerfectNumberTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java b/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java index 14574ab3c1eb..705cc6672818 100644 --- a/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java +++ b/src/test/java/com/thealgorithms/maths/PowerUsingRecursionTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java b/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java index edc684481c2f..abe6068c2022 100644 --- a/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java +++ b/src/test/java/com/thealgorithms/maths/PrimeFactorizationTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/PronicNumberTest.java b/src/test/java/com/thealgorithms/maths/PronicNumberTest.java index e4ca04fd0403..5a31981bed5c 100644 --- a/src/test/java/com/thealgorithms/maths/PronicNumberTest.java +++ b/src/test/java/com/thealgorithms/maths/PronicNumberTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java b/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java index 2dc2643c5878..13ea58155dec 100644 --- a/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java +++ b/src/test/java/com/thealgorithms/maths/PythagoreanTripleTest.java @@ -1,21 +1,22 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class PythagoreanTripleTest { @Test - public void Testpythagoreantriple() { - assertEquals(true, PythagoreanTriple.isPythagTriple(3, 4, 5)); - assertEquals(true, PythagoreanTriple.isPythagTriple(6, 8, 10)); - assertEquals(true, PythagoreanTriple.isPythagTriple(9, 12, 15)); - assertEquals(true, PythagoreanTriple.isPythagTriple(12, 16, 20)); - assertEquals(true, PythagoreanTriple.isPythagTriple(15, 20, 25)); - assertEquals(true, PythagoreanTriple.isPythagTriple(18, 24, 30)); - assertEquals(false, PythagoreanTriple.isPythagTriple(5, 20, 30)); - assertEquals(false, PythagoreanTriple.isPythagTriple(6, 8, 100)); - assertEquals(false, PythagoreanTriple.isPythagTriple(-2, -2, 2)); + public void testPythagoreanTriple() { + assertTrue(PythagoreanTriple.isPythagTriple(3, 4, 5)); + assertTrue(PythagoreanTriple.isPythagTriple(6, 8, 10)); + assertTrue(PythagoreanTriple.isPythagTriple(9, 12, 15)); + assertTrue(PythagoreanTriple.isPythagTriple(12, 16, 20)); + assertTrue(PythagoreanTriple.isPythagTriple(15, 20, 25)); + assertTrue(PythagoreanTriple.isPythagTriple(18, 24, 30)); + assertFalse(PythagoreanTriple.isPythagTriple(5, 20, 30)); + assertFalse(PythagoreanTriple.isPythagTriple(6, 8, 100)); + assertFalse(PythagoreanTriple.isPythagTriple(-2, -2, 2)); } } diff --git a/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java b/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java index 3d13e43665af..77446d30df32 100644 --- a/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java +++ b/src/test/java/com/thealgorithms/maths/SquareRootwithBabylonianMethodTest.java @@ -7,21 +7,21 @@ public class SquareRootwithBabylonianMethodTest { @Test void testfor4() { - Assertions.assertEquals(2, SquareRootWithBabylonianMethod.square_Root(4)); + Assertions.assertEquals(2, SquareRootWithBabylonianMethod.squareRoot(4)); } @Test void testfor1() { - Assertions.assertEquals(1, SquareRootWithBabylonianMethod.square_Root(1)); + Assertions.assertEquals(1, SquareRootWithBabylonianMethod.squareRoot(1)); } @Test void testfor2() { - Assertions.assertEquals(1.4142135381698608, SquareRootWithBabylonianMethod.square_Root(2)); + Assertions.assertEquals(1.4142135381698608, SquareRootWithBabylonianMethod.squareRoot(2)); } @Test void testfor625() { - Assertions.assertEquals(25, SquareRootWithBabylonianMethod.square_Root(625)); + Assertions.assertEquals(25, SquareRootWithBabylonianMethod.squareRoot(625)); } } diff --git a/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java b/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java index 63f53bc6e0ba..1eab73c67642 100644 --- a/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java +++ b/src/test/java/com/thealgorithms/maths/SumWithoutArithmeticOperatorsTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/maths/VolumeTest.java b/src/test/java/com/thealgorithms/maths/VolumeTest.java index 9692246b6a91..1bdb3ae80040 100644 --- a/src/test/java/com/thealgorithms/maths/VolumeTest.java +++ b/src/test/java/com/thealgorithms/maths/VolumeTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.maths; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/misc/MapReduceTest.java b/src/test/java/com/thealgorithms/misc/MapReduceTest.java index 213acad9743b..c79c40701cc1 100644 --- a/src/test/java/com/thealgorithms/misc/MapReduceTest.java +++ b/src/test/java/com/thealgorithms/misc/MapReduceTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.misc; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java b/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java index c1fa30d6a1cd..ec3a84b86c5b 100644 --- a/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java +++ b/src/test/java/com/thealgorithms/misc/MedianOfMatrixtest.java @@ -1,6 +1,6 @@ package com.thealgorithms.misc; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java b/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java index 431d8daa2bab..355f107ddb61 100644 --- a/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java +++ b/src/test/java/com/thealgorithms/others/ArrayLeftRotationTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/others/ArrayRightRotation.java b/src/test/java/com/thealgorithms/others/ArrayRightRotation.java index a78ef81f32a4..11e4f44500b1 100644 --- a/src/test/java/com/thealgorithms/others/ArrayRightRotation.java +++ b/src/test/java/com/thealgorithms/others/ArrayRightRotation.java @@ -1,6 +1,8 @@ package com.thealgorithms.others; -public class ArrayRightRotation { +public final class ArrayRightRotation { + private ArrayRightRotation() { + } public static int[] rotateRight(int[] arr, int k) { if (arr == null || arr.length == 0 || k < 0) { throw new IllegalArgumentException("Invalid input"); diff --git a/src/test/java/com/thealgorithms/others/BestFitCPUTest.java b/src/test/java/com/thealgorithms/others/BestFitCPUTest.java index 0a82ebdf011f..296cf1ca1c04 100644 --- a/src/test/java/com/thealgorithms/others/BestFitCPUTest.java +++ b/src/test/java/com/thealgorithms/others/BestFitCPUTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/thealgorithms/others/CRC16Test.java b/src/test/java/com/thealgorithms/others/CRC16Test.java index 54e82f69aa88..bf309928bbf4 100644 --- a/src/test/java/com/thealgorithms/others/CRC16Test.java +++ b/src/test/java/com/thealgorithms/others/CRC16Test.java @@ -5,9 +5,6 @@ import org.junit.jupiter.api.Test; class CRC16Test { - - CRC16 crc = new CRC16(); - @Test void testCRC16() { // given diff --git a/src/test/java/com/thealgorithms/others/CountCharTest.java b/src/test/java/com/thealgorithms/others/CountCharTest.java index 55e55b8d52f4..382ba4246400 100644 --- a/src/test/java/com/thealgorithms/others/CountCharTest.java +++ b/src/test/java/com/thealgorithms/others/CountCharTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; @@ -11,6 +11,6 @@ void testCountCharacters() { String input = "12345"; int expectedValue = 5; - assertEquals(expectedValue, CountChar.CountCharacters(input)); + assertEquals(expectedValue, CountChar.countCharacters(input)); } } diff --git a/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java b/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java index 070812f114d8..f2e6944c06d2 100644 --- a/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java +++ b/src/test/java/com/thealgorithms/others/CountFriendsPairingTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.dynamicprogramming.CountFriendsPairing; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java b/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java index b726a746d5ac..57b6e189b116 100644 --- a/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java +++ b/src/test/java/com/thealgorithms/others/FirstFitCPUTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java b/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java index ac2aa9648c07..25b211657c5d 100644 --- a/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java +++ b/src/test/java/com/thealgorithms/others/KadaneAlogrithmTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.dynamicprogramming.KadaneAlgorithm; import org.junit.jupiter.api.Test; @@ -10,48 +10,48 @@ public class KadaneAlogrithmTest { @Test void testForOneElement() { int[] a = {-1}; - assertTrue(KadaneAlgorithm.max_Sum(a, -1)); + assertTrue(KadaneAlgorithm.maxSum(a, -1)); } @Test void testForTwoElements() { int[] a = {-2, 1}; - assertTrue(KadaneAlgorithm.max_Sum(a, 1)); + assertTrue(KadaneAlgorithm.maxSum(a, 1)); } @Test void testForThreeElements() { int[] a = {5, 3, 12}; - assertTrue(KadaneAlgorithm.max_Sum(a, 20)); + assertTrue(KadaneAlgorithm.maxSum(a, 20)); } @Test void testForFourElements() { int[] a = {-1, -3, -7, -4}; - assertTrue(KadaneAlgorithm.max_Sum(a, -1)); + assertTrue(KadaneAlgorithm.maxSum(a, -1)); } @Test void testForFiveElements() { int[] a = {4, 5, 3, 0, 2}; - assertTrue(KadaneAlgorithm.max_Sum(a, 14)); + assertTrue(KadaneAlgorithm.maxSum(a, 14)); } @Test void testForSixElements() { int[] a = {-43, -45, 47, 12, 87, -13}; - assertTrue(KadaneAlgorithm.max_Sum(a, 146)); + assertTrue(KadaneAlgorithm.maxSum(a, 146)); } @Test void testForSevenElements() { int[] a = {9, 8, 2, 23, 13, 6, 7}; - assertTrue(KadaneAlgorithm.max_Sum(a, 68)); + assertTrue(KadaneAlgorithm.maxSum(a, 68)); } @Test void testForEightElements() { int[] a = {9, -5, -5, -2, 4, 5, 0, 1}; - assertTrue(KadaneAlgorithm.max_Sum(a, 10)); + assertTrue(KadaneAlgorithm.maxSum(a, 10)); } } diff --git a/src/test/java/com/thealgorithms/others/LineSweepTest.java b/src/test/java/com/thealgorithms/others/LineSweepTest.java index 20cf1cd75153..6bf6ef5b3002 100644 --- a/src/test/java/com/thealgorithms/others/LineSweepTest.java +++ b/src/test/java/com/thealgorithms/others/LineSweepTest.java @@ -1,5 +1,7 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; public class LineSweepTest { @@ -23,6 +25,6 @@ void testForOverlapWhenEndAEqualsStartBAndViceVersa() { @Test void testForMaximumEndPoint() { int[][] arr = {{10, 20}, {1, 100}, {14, 16}, {1, 8}}; - assertEquals(100, LineSweep.FindMaximumEndPoint(arr)); + assertEquals(100, LineSweep.findMaximumEndPoint(arr)); } } diff --git a/src/test/java/com/thealgorithms/others/LinkListSortTest.java b/src/test/java/com/thealgorithms/others/LinkListSortTest.java index e0e258aacd69..100593b1f756 100644 --- a/src/test/java/com/thealgorithms/others/LinkListSortTest.java +++ b/src/test/java/com/thealgorithms/others/LinkListSortTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.sorts.LinkListSort; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java b/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java index 49855161ec90..a8e168ffa13a 100644 --- a/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java +++ b/src/test/java/com/thealgorithms/others/MaximumSumOfDistinctSubarraysWithLengthKTest.java @@ -1,32 +1,32 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; public class MaximumSumOfDistinctSubarraysWithLengthKTest { @Test - public void SampleTestCase1() { + public void sampleTestCase1() { assertEquals(15, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(3, 1, 5, 4, 2, 9, 9, 9)); } @Test - public void SampleTestCase2() { + public void sampleTestCase2() { assertEquals(0, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(3, 4, 4, 4)); } @Test - public void SampleTestCase3() { + public void sampleTestCase3() { assertEquals(12, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(3, 9, 9, 9, 1, 2, 3)); } @Test - public void EdgeCase1() { + public void edgeCase1() { assertEquals(0, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(0, 9, 9, 9)); } @Test - public void EdgeCase2() { + public void edgeCase2() { assertEquals(0, MaximumSumOfDistinctSubarraysWithLengthK.maximumSubarraySum(5, 9, 9, 9)); } } diff --git a/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java b/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java index 660562a5506e..3b657e441b1c 100644 --- a/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java +++ b/src/test/java/com/thealgorithms/others/NewManShanksPrimeTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.dynamicprogramming.NewManShanksPrime; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/others/NextFitTest.java b/src/test/java/com/thealgorithms/others/NextFitTest.java index 2de6b411080c..75fb3ab7c261 100644 --- a/src/test/java/com/thealgorithms/others/NextFitTest.java +++ b/src/test/java/com/thealgorithms/others/NextFitTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/thealgorithms/others/PasswordGenTest.java b/src/test/java/com/thealgorithms/others/PasswordGenTest.java index aa5303ada239..57de329c8f09 100644 --- a/src/test/java/com/thealgorithms/others/PasswordGenTest.java +++ b/src/test/java/com/thealgorithms/others/PasswordGenTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java b/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java index 6cc653670a21..986e72ea45b5 100644 --- a/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java +++ b/src/test/java/com/thealgorithms/others/TestPrintMatrixInSpiralOrder.java @@ -1,26 +1,26 @@ -package com.thealgorithms.others; - -import static org.junit.jupiter.api.Assertions.*; - -import java.util.List; -import org.junit.jupiter.api.Test; - -public class TestPrintMatrixInSpiralOrder { - @Test - public void testOne() { - int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; - var printClass = new PrintAMatrixInSpiralOrder(); - List<Integer> res = printClass.print(matrix, matrix.length, matrix[0].length); - List<Integer> list = List.of(3, 4, 5, 6, 7, 12, 18, 27, 34, 33, 32, 31, 30, 23, 14, 8, 9, 10, 11, 17, 26, 25, 24, 15, 16); - assertIterableEquals(res, list); - } - - @Test - public void testTwo() { - int[][] matrix = {{2, 2}}; - var printClass = new PrintAMatrixInSpiralOrder(); - List<Integer> res = printClass.print(matrix, matrix.length, matrix[0].length); - List<Integer> list = List.of(2, 2); - assertIterableEquals(res, list); - } -} +package com.thealgorithms.others; + +import static org.junit.jupiter.api.Assertions.assertIterableEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public class TestPrintMatrixInSpiralOrder { + @Test + public void testOne() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + var printClass = new PrintAMatrixInSpiralOrder(); + List<Integer> res = printClass.print(matrix, matrix.length, matrix[0].length); + List<Integer> list = List.of(3, 4, 5, 6, 7, 12, 18, 27, 34, 33, 32, 31, 30, 23, 14, 8, 9, 10, 11, 17, 26, 25, 24, 15, 16); + assertIterableEquals(res, list); + } + + @Test + public void testTwo() { + int[][] matrix = {{2, 2}}; + var printClass = new PrintAMatrixInSpiralOrder(); + List<Integer> res = printClass.print(matrix, matrix.length, matrix[0].length); + List<Integer> list = List.of(2, 2); + assertIterableEquals(res, list); + } +} diff --git a/src/test/java/com/thealgorithms/others/TwoPointersTest.java b/src/test/java/com/thealgorithms/others/TwoPointersTest.java index 8cadb031111b..e8fe41b0bdaf 100644 --- a/src/test/java/com/thealgorithms/others/TwoPointersTest.java +++ b/src/test/java/com/thealgorithms/others/TwoPointersTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -10,34 +11,34 @@ public class TwoPointersTest { void twoPointersFirstTestCase() { int[] arr = {2, 6, 9, 22, 121}; int key = 28; - assertEquals(true, TwoPointers.isPairedSum(arr, key)); + assertTrue(TwoPointers.isPairedSum(arr, key)); } @Test void twoPointersSecondTestCase() { int[] arr = {-1, -12, 12, 0, 8}; int key = 0; - assertEquals(true, TwoPointers.isPairedSum(arr, key)); + assertTrue(TwoPointers.isPairedSum(arr, key)); } @Test void twoPointersThirdTestCase() { int[] arr = {12, 35, 12, 152, 0}; int key = 13; - assertEquals(false, TwoPointers.isPairedSum(arr, key)); + assertFalse(TwoPointers.isPairedSum(arr, key)); } @Test void twoPointersFourthTestCase() { int[] arr = {-2, 5, -1, 52, 31}; int key = -3; - assertEquals(true, TwoPointers.isPairedSum(arr, key)); + assertTrue(TwoPointers.isPairedSum(arr, key)); } @Test void twoPointersFiftiethTestCase() { int[] arr = {25, 1, 0, 61, 21}; int key = 12; - assertEquals(false, TwoPointers.isPairedSum(arr, key)); + assertFalse(TwoPointers.isPairedSum(arr, key)); } } diff --git a/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java b/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java index 6f2a53b3dfe7..eb69f6056132 100644 --- a/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java +++ b/src/test/java/com/thealgorithms/others/WorstFitCPUTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.others; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java index 5cb3c624db42..61e2a2ac2690 100644 --- a/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java @@ -5,9 +5,11 @@ * @author [Bama Charan Chhandogi](https://www.github.com/BamaCharanChhandogi) */ -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.Test; class PreemptivePrioritySchedulingTest { diff --git a/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java index 700a174f328c..3da526601f5f 100644 --- a/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.scheduling; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import com.thealgorithms.devutils.entities.ProcessDetails; import java.util.ArrayList; diff --git a/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java index ae31feb9a6b4..aab5c64c847f 100644 --- a/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.scheduling; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.devutils.entities.ProcessDetails; import java.util.ArrayList; @@ -73,7 +74,7 @@ void scheduling() { } @Test - void schedulingOf_TwoProcesses() { + void schedulingOfTwoProcesses() { initialisation0(); SJFScheduling a = new SJFScheduling(process); a.scheduleProcesses(); @@ -82,7 +83,7 @@ void schedulingOf_TwoProcesses() { } @Test - void schedulingOfA_ShortestJobArrivingLast() { + void schedulingOfAShortestJobArrivingLast() { initialisation2(); SJFScheduling a = new SJFScheduling(process); a.scheduleProcesses(); @@ -91,7 +92,7 @@ void schedulingOfA_ShortestJobArrivingLast() { assertEquals("2", a.schedule.get(2)); } @Test - void scheduling_WithProcessesNotComingBackToBack() { + void schedulingWithProcessesNotComingBackToBack() { initialisation3(); SJFScheduling a = new SJFScheduling(process); a.scheduleProcesses(); @@ -100,7 +101,7 @@ void scheduling_WithProcessesNotComingBackToBack() { assertEquals("3", a.schedule.get(2)); } @Test - void schedulingOf_nothing() { + void schedulingOfNothing() { process = new ArrayList<>(); SJFScheduling a = new SJFScheduling(process); a.scheduleProcesses(); diff --git a/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java index 0cfe3d34f0ec..9cec31130164 100644 --- a/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java +++ b/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java @@ -19,7 +19,7 @@ public void initialization() { } @Test - public void Constructor() { + public void constructor() { initialization(); SRTFScheduling s = new SRTFScheduling(processes); assertEquals(3, s.processes.get(0).getBurstTime()); diff --git a/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java b/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java index e5db2f74f446..18f0afc6a0a6 100644 --- a/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java +++ b/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java @@ -3,18 +3,18 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.util.*; +import java.util.Arrays; import org.junit.jupiter.api.Test; public class BinarySearch2dArrayTest { @Test // valid test case - public void BinarySearch2dArrayTestMiddle() { + public void binarySearch2dArrayTestMiddle() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 6; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(1, ans[0]); assertEquals(1, ans[1]); @@ -22,11 +22,11 @@ public void BinarySearch2dArrayTestMiddle() { @Test // valid test case - public void BinarySearch2dArrayTestMiddleSide() { + public void binarySearch2dArrayTestMiddleSide() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 8; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(1, ans[0]); assertEquals(3, ans[1]); @@ -34,11 +34,11 @@ public void BinarySearch2dArrayTestMiddleSide() { @Test // valid test case - public void BinarySearch2dArrayTestUpper() { + public void binarySearch2dArrayTestUpper() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 2; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(0, ans[0]); assertEquals(1, ans[1]); @@ -46,11 +46,11 @@ public void BinarySearch2dArrayTestUpper() { @Test // valid test case - public void BinarySearch2dArrayTestUpperSide() { + public void binarySearch2dArrayTestUpperSide() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 1; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(0, ans[0]); assertEquals(0, ans[1]); @@ -58,11 +58,11 @@ public void BinarySearch2dArrayTestUpperSide() { @Test // valid test case - public void BinarySearch2dArrayTestLower() { + public void binarySearch2dArrayTestLower() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 10; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(2, ans[0]); assertEquals(1, ans[1]); @@ -70,11 +70,11 @@ public void BinarySearch2dArrayTestLower() { @Test // valid test case - public void BinarySearch2dArrayTestLowerSide() { + public void binarySearch2dArrayTestLowerSide() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 11; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(2, ans[0]); assertEquals(2, ans[1]); @@ -82,11 +82,11 @@ public void BinarySearch2dArrayTestLowerSide() { @Test // valid test case - public void BinarySearch2dArrayTestNotFound() { + public void binarySearch2dArrayTestNotFound() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 101; - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(-1, ans[0]); assertEquals(-1, ans[1]); @@ -96,13 +96,13 @@ public void BinarySearch2dArrayTestNotFound() { * Test if the method works with input arrays consisting only of one row. */ @Test - public void BinarySearch2dArrayTestOneRow() { + public void binarySearch2dArrayTestOneRow() { int[][] arr = {{1, 2, 3, 4}}; int target = 2; // Assert that the requirement, that the array only has one row, is fulfilled. assertEquals(arr.length, 1); - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(0, ans[0]); assertEquals(1, ans[1]); @@ -112,13 +112,13 @@ public void BinarySearch2dArrayTestOneRow() { * Test if the method works with the target in the middle of the input. */ @Test - public void BinarySearch2dArrayTestTargetInMiddle() { + public void binarySearch2dArrayTestTargetInMiddle() { int[][] arr = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12, 13, 14, 15}}; int target = 8; // Assert that the requirement, that the target is in the middle row and middle column, is // fulfilled. assertEquals(arr[arr.length / 2][arr[0].length / 2], target); - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(1, ans[0]); assertEquals(2, ans[1]); @@ -129,7 +129,7 @@ public void BinarySearch2dArrayTestTargetInMiddle() { * in the row above the middle row. */ @Test - public void BinarySearch2dArrayTestTargetAboveMiddleRowInMiddleColumn() { + public void binarySearch2dArrayTestTargetAboveMiddleRowInMiddleColumn() { int[][] arr = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}; int target = 3; @@ -137,7 +137,7 @@ public void BinarySearch2dArrayTestTargetAboveMiddleRowInMiddleColumn() { // in an array with an even number of columns, and on the row "above" the middle row. assertEquals(arr[0].length % 2, 0); assertEquals(arr[arr.length / 2 - 1][arr[0].length / 2], target); - int[] ans = BinarySearch2dArray.BinarySearch(arr, target); + int[] ans = BinarySearch2dArray.binarySearch(arr, target); System.out.println(Arrays.toString(ans)); assertEquals(0, ans[0]); assertEquals(2, ans[1]); @@ -147,11 +147,11 @@ public void BinarySearch2dArrayTestTargetAboveMiddleRowInMiddleColumn() { * Test if the method works with an empty array. */ @Test - public void BinarySearch2dArrayTestEmptyArray() { + public void binarySearch2dArrayTestEmptyArray() { int[][] arr = {}; int target = 5; // Assert that an empty array is not valid input for the method. - assertThrows(ArrayIndexOutOfBoundsException.class, () -> BinarySearch2dArray.BinarySearch(arr, target)); + assertThrows(ArrayIndexOutOfBoundsException.class, () -> BinarySearch2dArray.binarySearch(arr, target)); } } diff --git a/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java b/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java index 77562ecdb87d..2a32a4ddb46c 100644 --- a/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/BreadthFirstSearchTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.datastructures.Node; import java.util.List; diff --git a/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java b/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java index f85e94090d3f..af21b570fd7c 100644 --- a/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/DepthFirstSearchTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import com.thealgorithms.datastructures.Node; import java.util.List; diff --git a/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java b/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java index ac731b0f5dea..7d52e9fb4eca 100644 --- a/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java +++ b/src/test/java/com/thealgorithms/searches/HowManyTimesRotatedTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/searches/KMPSearchTest.java b/src/test/java/com/thealgorithms/searches/KMPSearchTest.java index a0250ba34f5a..cb804ac6a6a3 100644 --- a/src/test/java/com/thealgorithms/searches/KMPSearchTest.java +++ b/src/test/java/com/thealgorithms/searches/KMPSearchTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; @@ -8,55 +8,55 @@ class KMPSearchTest { @Test // valid test case - public void KMPSearchTestLast() { + public void kmpSearchTestLast() { String txt = "ABABDABACDABABCABAB"; String pat = "ABABCABAB"; KMPSearch kmpSearch = new KMPSearch(); - int value = kmpSearch.KMPSearch(pat, txt); + int value = kmpSearch.kmpSearch(pat, txt); System.out.println(value); assertEquals(value, 10); } @Test // valid test case - public void KMPSearchTestFront() { + public void kmpSearchTestFront() { String txt = "AAAAABAAABA"; String pat = "AAAA"; KMPSearch kmpSearch = new KMPSearch(); - int value = kmpSearch.KMPSearch(pat, txt); + int value = kmpSearch.kmpSearch(pat, txt); System.out.println(value); assertEquals(value, 0); } @Test // valid test case - public void KMPSearchTestMiddle() { + public void kmpSearchTestMiddle() { String txt = "AAACAAAAAC"; String pat = "AAAA"; KMPSearch kmpSearch = new KMPSearch(); - int value = kmpSearch.KMPSearch(pat, txt); + int value = kmpSearch.kmpSearch(pat, txt); System.out.println(value); assertEquals(value, 4); } @Test // valid test case - public void KMPSearchTestNotFound() { + public void kmpSearchTestNotFound() { String txt = "AAABAAAA"; String pat = "AAAA"; KMPSearch kmpSearch = new KMPSearch(); - int value = kmpSearch.KMPSearch(pat, txt); + int value = kmpSearch.kmpSearch(pat, txt); System.out.println(value); assertEquals(value, 4); } @Test // not valid test case - public void KMPSearchTest4() { + public void kmpSearchTest4() { String txt = "AABAAA"; String pat = "AAAA"; KMPSearch kmpSearch = new KMPSearch(); - int value = kmpSearch.KMPSearch(pat, txt); + int value = kmpSearch.kmpSearch(pat, txt); System.out.println(value); assertEquals(value, -1); } diff --git a/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java index c19adaa1260c..03502eec00d1 100644 --- a/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java +++ b/src/test/java/com/thealgorithms/searches/OrderAgnosticBinarySearchTest.java @@ -7,9 +7,9 @@ public class OrderAgnosticBinarySearchTest { @Test // valid Test Case - public void ElementInMiddle() { + public void elementInMiddle() { int[] arr = {10, 20, 30, 40, 50}; - int answer = OrderAgnosticBinarySearch.BinSearchAlgo(arr, 0, arr.length - 1, 30); + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 30); System.out.println(answer); int expected = 2; assertEquals(expected, answer); @@ -17,9 +17,9 @@ public void ElementInMiddle() { @Test // valid Test Case - public void RightHalfDescOrder() { + public void rightHalfDescOrder() { int[] arr = {50, 40, 30, 20, 10}; - int answer = OrderAgnosticBinarySearch.BinSearchAlgo(arr, 0, arr.length - 1, 10); + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 10); System.out.println(answer); int expected = 4; assertEquals(expected, answer); @@ -27,9 +27,9 @@ public void RightHalfDescOrder() { @Test // valid test case - public void LeftHalfDescOrder() { + public void leftHalfDescOrder() { int[] arr = {50, 40, 30, 20, 10}; - int answer = OrderAgnosticBinarySearch.BinSearchAlgo(arr, 0, arr.length - 1, 50); + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 50); System.out.println(answer); int expected = 0; assertEquals(expected, answer); @@ -37,9 +37,9 @@ public void LeftHalfDescOrder() { @Test // valid test case - public void RightHalfAscOrder() { + public void rightHalfAscOrder() { int[] arr = {10, 20, 30, 40, 50}; - int answer = OrderAgnosticBinarySearch.BinSearchAlgo(arr, 0, arr.length - 1, 50); + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 50); System.out.println(answer); int expected = 4; assertEquals(expected, answer); @@ -47,9 +47,9 @@ public void RightHalfAscOrder() { @Test // valid test case - public void LeftHalfAscOrder() { + public void leftHalfAscOrder() { int[] arr = {10, 20, 30, 40, 50}; - int answer = OrderAgnosticBinarySearch.BinSearchAlgo(arr, 0, arr.length - 1, 10); + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 10); System.out.println(answer); int expected = 0; assertEquals(expected, answer); @@ -57,9 +57,9 @@ public void LeftHalfAscOrder() { @Test // valid test case - public void ElementNotFound() { + public void elementNotFound() { int[] arr = {10, 20, 30, 40, 50}; - int answer = OrderAgnosticBinarySearch.BinSearchAlgo(arr, 0, arr.length - 1, 100); + int answer = OrderAgnosticBinarySearch.binSearchAlgo(arr, 0, arr.length - 1, 100); System.out.println(answer); int expected = -1; assertEquals(expected, answer); diff --git a/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java index ca5829c54495..6eab20f45467 100644 --- a/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java +++ b/src/test/java/com/thealgorithms/searches/PerfectBinarySearchTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/searches/QuickSelectTest.java b/src/test/java/com/thealgorithms/searches/QuickSelectTest.java index 405135ecad0d..dd04c85b76ae 100644 --- a/src/test/java/com/thealgorithms/searches/QuickSelectTest.java +++ b/src/test/java/com/thealgorithms/searches/QuickSelectTest.java @@ -1,8 +1,13 @@ package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; - -import java.util.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Random; import java.util.stream.Collectors; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java index a8dc96e91998..40e1acce9c3a 100644 --- a/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/searches/RabinKarpAlgorithmTest.java @@ -9,7 +9,7 @@ class RabinKarpAlgorithmTest { @ParameterizedTest @CsvSource({"This is an example for rabin karp algorithmn, algorithmn, 101", "AAABBDDG, AAA, 137", "AAABBCCBB, BBCC, 101", "AAABBCCBB, BBCC, 131", "AAAABBBBCCC, CCC, 41", "ABCBCBCAAB, AADB, 293", "Algorithm The Algorithm, Algorithm, 101"}) - void RabinKarpAlgorithmTestExample(String txt, String pat, int q) { + void rabinKarpAlgorithmTestExample(String txt, String pat, int q) { int indexFromOurAlgorithm = RabinKarpAlgorithm.search(pat, txt, q); int indexFromLinearSearch = txt.indexOf(pat); assertEquals(indexFromOurAlgorithm, indexFromLinearSearch); diff --git a/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java index 4144efa5e89b..0a2794f9e8d7 100644 --- a/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java +++ b/src/test/java/com/thealgorithms/searches/RecursiveBinarySearchTest.java @@ -3,7 +3,7 @@ // Test file updated with JUnit tests package com.thealgorithms.searches; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; // Import the JUnit 5 Test annotation diff --git a/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java b/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java index e706a58fafbe..39ac5bf037ea 100644 --- a/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java +++ b/src/test/java/com/thealgorithms/searches/RowColumnWiseSorted2dArrayBinarySearchTest.java @@ -37,7 +37,7 @@ public void rowColumnSorted2dArrayBinarySearchTestSide() { } @Test - public void rowColumnSorted2dArray_BinarySearchTestUpper() { + public void rowColumnSorted2dArrayBinarySearchTestUpper() { Integer[][] arr = { {10, 20, 30, 40}, {15, 25, 35, 45}, @@ -52,7 +52,7 @@ public void rowColumnSorted2dArray_BinarySearchTestUpper() { } @Test - public void rowColumnSorted2dArray_BinarySearchTestUpperSide() { + public void rowColumnSorted2dArrayBinarySearchTestUpperSide() { Integer[][] arr = { {10, 20, 30, 40}, {15, 25, 35, 45}, @@ -67,7 +67,7 @@ public void rowColumnSorted2dArray_BinarySearchTestUpperSide() { } @Test - public void rowColumnSorted2dArray_BinarySearchTestLower() { + public void rowColumnSorted2dArrayBinarySearchTestLower() { Integer[][] arr = { {10, 20, 30, 40}, {15, 25, 35, 45}, @@ -82,7 +82,7 @@ public void rowColumnSorted2dArray_BinarySearchTestLower() { } @Test - public void rowColumnSorted2dArray_BinarySearchTestLowerSide() { + public void rowColumnSorted2dArrayBinarySearchTestLowerSide() { Integer[][] arr = { {10, 20, 30, 40}, {15, 25, 35, 45}, @@ -97,7 +97,7 @@ public void rowColumnSorted2dArray_BinarySearchTestLowerSide() { } @Test - public void rowColumnSorted2dArray_BinarySearchTestNotFound() { + public void rowColumnSorted2dArrayBinarySearchTestNotFound() { Integer[][] arr = { {10, 20, 30, 40}, {15, 25, 35, 45}, diff --git a/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java b/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java index 83e6562122ff..014fb4bd24af 100644 --- a/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java +++ b/src/test/java/com/thealgorithms/searches/TestSearchInARowAndColWiseSortedMatrix.java @@ -1,27 +1,27 @@ -package com.thealgorithms.searches; - -import static org.junit.jupiter.api.Assertions.*; - -import org.junit.jupiter.api.Test; - -public class TestSearchInARowAndColWiseSortedMatrix { - @Test - public void searchItem() { - int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; - - var test = new SearchInARowAndColWiseSortedMatrix(); - int[] res = test.search(matrix, 16); - int[] expectedResult = {2, 2}; - assertArrayEquals(expectedResult, res); - } - - @Test - public void notFound() { - int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; - - var test = new SearchInARowAndColWiseSortedMatrix(); - int[] res = test.search(matrix, 96); - int[] expectedResult = {-1, -1}; - assertArrayEquals(expectedResult, res); - } -} +package com.thealgorithms.searches; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import org.junit.jupiter.api.Test; + +public class TestSearchInARowAndColWiseSortedMatrix { + @Test + public void searchItem() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + + var test = new SearchInARowAndColWiseSortedMatrix(); + int[] res = test.search(matrix, 16); + int[] expectedResult = {2, 2}; + assertArrayEquals(expectedResult, res); + } + + @Test + public void notFound() { + int[][] matrix = {{3, 4, 5, 6, 7}, {8, 9, 10, 11, 12}, {14, 15, 16, 17, 18}, {23, 24, 25, 26, 27}, {30, 31, 32, 33, 34}}; + + var test = new SearchInARowAndColWiseSortedMatrix(); + int[] res = test.search(matrix, 96); + int[] expectedResult = {-1, -1}; + assertArrayEquals(expectedResult, res); + } +} diff --git a/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java b/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java index 5261d6c64785..bdd0702942a2 100644 --- a/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/BinaryInsertionSortTest.java @@ -1,27 +1,27 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; class BinaryInsertionSortTest { - BinaryInsertionSort BIS = new BinaryInsertionSort(); + BinaryInsertionSort bis = new BinaryInsertionSort(); @Test // valid test case - public void BinaryInsertionSortTestNonDuplicate() { + public void binaryInsertionSortTestNonDuplicate() { int[] array = {1, 0, 2, 5, 3, 4, 9, 8, 10, 6, 7}; int[] expResult = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; - int[] actResult = BIS.binaryInsertSort(array); + int[] actResult = bis.binaryInsertSort(array); assertArrayEquals(expResult, actResult); } @Test - public void BinaryInsertionSortTestDuplicate() { + public void binaryInsertionSortTestDuplicate() { int[] array = {1, 1, 1, 5, 9, 8, 7, 2, 6}; int[] expResult = {1, 1, 1, 2, 5, 6, 7, 8, 9}; - int[] actResult = BIS.binaryInsertSort(array); + int[] actResult = bis.binaryInsertSort(array); assertArrayEquals(expResult, actResult); } } diff --git a/src/test/java/com/thealgorithms/sorts/CircleSortTest.java b/src/test/java/com/thealgorithms/sorts/CircleSortTest.java new file mode 100644 index 000000000000..d113473272b7 --- /dev/null +++ b/src/test/java/com/thealgorithms/sorts/CircleSortTest.java @@ -0,0 +1,8 @@ +package com.thealgorithms.sorts; + +class CircleSortTest extends SortingAlgorithmTest { + @Override + SortAlgorithm getSortAlgorithm() { + return new CircleSort(); + } +} diff --git a/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java b/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java index 7c81aefc6d04..c7581e7c8f7b 100644 --- a/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/DutchNationalFlagSortTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; @@ -11,7 +11,7 @@ public class DutchNationalFlagSortTest { 1 will be used as intended middle. Partitions on the result array: [ smaller than 1 , equal 1, greater than 1] */ - void DNFSTestOdd() { + void testOddDnfs() { Integer[] integers = {1, 3, 1, 4, 0}; Integer[] integersResult = {0, 1, 1, 4, 3}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -24,7 +24,7 @@ void DNFSTestOdd() { 3 will be used as intended middle. Partitions on the result array: [ smaller than 3 , equal 3, greater than 3] */ - void DNFSTestEven() { + void testEvenDnfs() { Integer[] integers = {8, 1, 3, 1, 4, 0}; Integer[] integersResult = {0, 1, 1, 3, 4, 8}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -37,7 +37,7 @@ void DNFSTestEven() { "b" will be used as intended middle. Partitions on the result array: [ smaller than b , equal b, greater than b] */ - void DNFSTestEvenStrings() { + void testEvenStringsDnfs() { String[] strings = {"a", "d", "b", "s", "e", "e"}; String[] stringsResult = {"a", "b", "s", "e", "e", "d"}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -50,7 +50,7 @@ void DNFSTestEvenStrings() { "b" will be used as intended middle. Partitions on the result array: [ smaller than b , equal b, greater than b] */ - void DNFSTestOddStrings() { + void testOddStringsDnfs() { String[] strings = {"a", "d", "b", "s", "e"}; String[] stringsResult = {"a", "b", "s", "e", "d"}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -63,7 +63,7 @@ void DNFSTestOddStrings() { 0 will be used as intended middle. Partitions on the result array: [ smaller than 0 , equal 0, greater than 0] */ - void DNFSTestOddMidGiven() { + void testOddMidGivenDnfs() { Integer[] integers = {1, 3, 1, 4, 0}; Integer[] integersResult = {0, 1, 4, 3, 1}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -76,7 +76,7 @@ void DNFSTestOddMidGiven() { 4 will be used as intended middle. Partitions on the result array: [ smaller than 4 , equal 4, greater than 4] */ - void DNFSTestEvenMidGiven() { + void testEvenMidGivenDnfs() { Integer[] integers = {8, 1, 3, 1, 4, 0}; Integer[] integersResult = {0, 1, 3, 1, 4, 8}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -89,7 +89,7 @@ void DNFSTestEvenMidGiven() { "s" will be used as intended middle. Partitions on the result array: [ smaller than s , equal s, greater than s] */ - void DNFSTestEvenStringsMidGiven() { + void testEvenStringsMidGivenDnfs() { String[] strings = {"a", "d", "b", "s", "e", "e"}; String[] stringsResult = {"a", "d", "b", "e", "e", "s"}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); @@ -102,7 +102,7 @@ void DNFSTestEvenStringsMidGiven() { "e" will be used as intended middle. Partitions on the result array: [ smaller than e , equal e, greater than e] */ - void DNFSTestOddStringsMidGiven() { + void testOddStringsMidGivenDnfs() { String[] strings = {"a", "d", "b", "s", "e"}; String[] stringsResult = {"a", "d", "b", "e", "s"}; DutchNationalFlagSort dutchNationalFlagSort = new DutchNationalFlagSort(); diff --git a/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java b/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java index 87a2c73384c3..78744973355d 100644 --- a/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/InsertionSortTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.function.Function; import org.junit.jupiter.api.BeforeEach; diff --git a/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java b/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java index 54179e12049c..a5c6905f7514 100644 --- a/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/IntrospectiveSortTest.java @@ -8,7 +8,7 @@ public class IntrospectiveSortTest { @Test // valid test case - public void StrandSortNonDuplicateTest() { + public void strandSortNonDuplicateTest() { Integer[] expectedArray = {1, 2, 3, 4, 5}; Integer[] actualList = new IntrospectiveSort().sort(expectedArray); assertArrayEquals(expectedArray, actualList); @@ -16,7 +16,7 @@ public void StrandSortNonDuplicateTest() { @Test // valid test case - public void StrandSortDuplicateTest() { + public void strandSortDuplicateTest() { Integer[] expectedArray = {2, 2, 2, 5, 7}; Integer[] actualList = new IntrospectiveSort().sort(expectedArray); assertArrayEquals(expectedArray, actualList); @@ -24,7 +24,7 @@ public void StrandSortDuplicateTest() { @Test // valid test case - public void StrandSortEmptyTest() { + public void strandSortEmptyTest() { Integer[] expectedArray = {}; Integer[] actualList = new IntrospectiveSort().sort(expectedArray); assertArrayEquals(expectedArray, actualList); @@ -32,14 +32,14 @@ public void StrandSortEmptyTest() { @Test // valid test case - public void StrandSortNullTest() { + public void strandSortNullTest() { Integer[] expectedArray = null; assertThrows(NullPointerException.class, () -> { new IntrospectiveSort().sort(expectedArray); }); } @Test // valid test case - public void StrandSortNegativeTest() { + public void strandSortNegativeTest() { Integer[] expectedArray = {-1, -2, -3, -4, -5}; Integer[] actualList = new IntrospectiveSort().sort(expectedArray); assertArrayEquals(expectedArray, actualList); @@ -47,7 +47,7 @@ public void StrandSortNegativeTest() { @Test // valid test case - public void StrandSortNegativeAndPositiveTest() { + public void strandSortNegativeAndPositiveTest() { Integer[] expectedArray = {-1, -2, -3, 4, 5}; Integer[] actualList = new IntrospectiveSort().sort(expectedArray); assertArrayEquals(expectedArray, actualList); diff --git a/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java b/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java index 36470f86451d..83fbd1ece909 100644 --- a/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/SelectionSortTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import org.junit.jupiter.api.Test; @@ -8,7 +8,7 @@ class SelectionSortTest { @Test // valid test case - void IntegerArrTest() { + void integerArrTest() { Integer[] arr = {4, 23, 6, 78, 1, 54, 231, 9, 12}; SelectionSort selectionSort = new SelectionSort(); @@ -17,7 +17,7 @@ void IntegerArrTest() { @Test // valid test case - void StringArrTest() { + void stringArrTest() { String[] arr = {"c", "a", "e", "b", "d"}; SelectionSort selectionSort = new SelectionSort(); diff --git a/src/test/java/com/thealgorithms/sorts/ShellSortTest.java b/src/test/java/com/thealgorithms/sorts/ShellSortTest.java index cecc8d8bd581..73be91b397bd 100644 --- a/src/test/java/com/thealgorithms/sorts/ShellSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/ShellSortTest.java @@ -9,7 +9,7 @@ public class ShellSortTest { private ShellSort shellSort = new ShellSort(); @Test - public void ShellSortEmptyArray() { + public void shellSortEmptyArray() { Integer[] inputArray = {}; Integer[] outputArray = shellSort.sort(inputArray); Integer[] expectedOutput = {}; @@ -17,7 +17,7 @@ public void ShellSortEmptyArray() { } @Test - public void ShellSortSingleIntegerArray() { + public void shellSortSingleIntegerArray() { Integer[] inputArray = {4}; Integer[] outputArray = shellSort.sort(inputArray); Integer[] expectedOutput = {4}; @@ -25,7 +25,7 @@ public void ShellSortSingleIntegerArray() { } @Test - public void ShellSortSingleStringArray() { + public void shellSortSingleStringArray() { String[] inputArray = {"s"}; String[] outputArray = shellSort.sort(inputArray); String[] expectedOutput = {"s"}; @@ -33,7 +33,7 @@ public void ShellSortSingleStringArray() { } @Test - public void ShellSortNonDuplicateIntegerArray() { + public void shellSortNonDuplicateIntegerArray() { Integer[] inputArray = {6, -1, 99, 27, -15, 23, -36}; Integer[] outputArray = shellSort.sort(inputArray); Integer[] expectedOutput = {-36, -15, -1, 6, 23, 27, 99}; @@ -41,7 +41,7 @@ public void ShellSortNonDuplicateIntegerArray() { } @Test - public void ShellSortDuplicateIntegerArray() { + public void shellSortDuplicateIntegerArray() { Integer[] inputArray = {6, -1, 27, -15, 23, 27, -36, 23}; Integer[] outputArray = shellSort.sort(inputArray); Integer[] expectedOutput = {-36, -15, -1, 6, 23, 23, 27, 27}; @@ -49,7 +49,7 @@ public void ShellSortDuplicateIntegerArray() { } @Test - public void ShellSortNonDuplicateStringArray() { + public void shellSortNonDuplicateStringArray() { String[] inputArray = {"s", "b", "k", "a", "d", "c", "h"}; String[] outputArray = shellSort.sort(inputArray); String[] expectedOutput = {"a", "b", "c", "d", "h", "k", "s"}; @@ -57,7 +57,7 @@ public void ShellSortNonDuplicateStringArray() { } @Test - public void ShellSortDuplicateStringArray() { + public void shellSortDuplicateStringArray() { String[] inputArray = {"s", "b", "d", "a", "d", "c", "h", "b"}; String[] outputArray = shellSort.sort(inputArray); String[] expectedOutput = {"a", "b", "b", "c", "d", "d", "h", "s"}; diff --git a/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java b/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java index 34a6b00dd9a8..591b53891ee7 100644 --- a/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java +++ b/src/test/java/com/thealgorithms/sorts/SortUtilsTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.List; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java b/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java index 92e743cf220c..113bff2b5b0d 100644 --- a/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/sorts/SortingAlgorithmTest.java @@ -1,6 +1,8 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.List; diff --git a/src/test/java/com/thealgorithms/sorts/StrandSortTest.java b/src/test/java/com/thealgorithms/sorts/StrandSortTest.java index 679a1131f53f..91e85c81e5ec 100644 --- a/src/test/java/com/thealgorithms/sorts/StrandSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/StrandSortTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; import java.util.Arrays; import java.util.LinkedList; @@ -10,7 +10,7 @@ class StrandSortTest { @Test // valid test case - public void StrandSortNonDuplicateTest() { + public void strandSortNonDuplicateTest() { int[] expectedArray = {1, 2, 3, 4, 5}; LinkedList<Integer> actualList = StrandSort.strandSort(new LinkedList<Integer>(Arrays.asList(3, 1, 2, 4, 5))); int[] actualArray = new int[actualList.size()]; @@ -22,7 +22,7 @@ public void StrandSortNonDuplicateTest() { @Test // valid test case - public void StrandSortDuplicateTest() { + public void strandSortDuplicateTest() { int[] expectedArray = {2, 2, 2, 5, 7}; LinkedList<Integer> actualList = StrandSort.strandSort(new LinkedList<Integer>(Arrays.asList(7, 2, 2, 2, 5))); int[] actualArray = new int[actualList.size()]; diff --git a/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java b/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java index e299dad1276a..de115b458fe7 100644 --- a/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/TopologicalSortTest.java @@ -1,8 +1,9 @@ package com.thealgorithms.sorts; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertIterableEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; -import com.thealgorithms.sorts.TopologicalSort.BackEdgeException; import com.thealgorithms.sorts.TopologicalSort.Graph; import java.util.LinkedList; import org.junit.jupiter.api.Test; @@ -53,7 +54,7 @@ public void failureTest() { graph.addEdge("6", "2"); graph.addEdge("7", ""); graph.addEdge("8", ""); - Exception exception = assertThrows(BackEdgeException.class, () -> TopologicalSort.sort(graph)); + Exception exception = assertThrows(RuntimeException.class, () -> TopologicalSort.sort(graph)); String expected = "This graph contains a cycle. No linear ordering is possible. " + "Back edge: 6 -> 2"; assertEquals(exception.getMessage(), expected); diff --git a/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java b/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java index 449c8c11ba78..c5d57d63cf38 100644 --- a/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java +++ b/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java @@ -8,7 +8,7 @@ public class WiggleSortTest { @Test - void WiggleTestNumbersEven() { + void wiggleTestNumbersEven() { WiggleSort wiggleSort = new WiggleSort(); Integer[] values = {1, 2, 3, 4}; Integer[] result = {1, 4, 2, 3}; @@ -17,7 +17,7 @@ void WiggleTestNumbersEven() { } @Test - void WiggleTestNumbersOdd() { + void wiggleTestNumbersOdd() { WiggleSort wiggleSort = new WiggleSort(); Integer[] values = {1, 2, 3, 4, 5}; Integer[] result = {3, 5, 1, 4, 2}; @@ -26,7 +26,7 @@ void WiggleTestNumbersOdd() { } @Test - void WiggleTestNumbersOddDuplicates() { + void wiggleTestNumbersOddDuplicates() { WiggleSort wiggleSort = new WiggleSort(); Integer[] values = {7, 2, 2, 2, 5}; Integer[] result = {2, 7, 2, 5, 2}; @@ -35,7 +35,7 @@ void WiggleTestNumbersOddDuplicates() { } @Test - void WiggleTestNumbersOddMultipleDuplicates() { + void wiggleTestNumbersOddMultipleDuplicates() { WiggleSort wiggleSort = new WiggleSort(); Integer[] values = {1, 1, 2, 2, 5}; Integer[] result = {2, 5, 1, 2, 1}; @@ -44,7 +44,7 @@ void WiggleTestNumbersOddMultipleDuplicates() { } @Test - void WiggleTestNumbersEvenMultipleDuplicates() { + void wiggleTestNumbersEvenMultipleDuplicates() { WiggleSort wiggleSort = new WiggleSort(); Integer[] values = {1, 1, 2, 2, 2, 5}; Integer[] result = {2, 5, 1, 2, 1, 2}; @@ -54,7 +54,7 @@ void WiggleTestNumbersEvenMultipleDuplicates() { } @Test - void WiggleTestNumbersEvenDuplicates() { + void wiggleTestNumbersEvenDuplicates() { WiggleSort wiggleSort = new WiggleSort(); Integer[] values = {1, 2, 4, 4}; Integer[] result = {1, 4, 2, 4}; @@ -63,7 +63,7 @@ void WiggleTestNumbersEvenDuplicates() { } @Test - void WiggleTestStrings() { + void wiggleTestStrings() { WiggleSort wiggleSort = new WiggleSort(); String[] values = {"a", "b", "d", "c"}; String[] result = {"a", "d", "b", "c"}; diff --git a/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java b/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java index 4857529e49a5..a8d8e0d3d9dc 100644 --- a/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java +++ b/src/test/java/com/thealgorithms/stacks/StackPostfixNotationTest.java @@ -1,7 +1,8 @@ package com.thealgorithms.stacks; import static java.util.Map.entry; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.util.Map; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java b/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java index 3d240f2c2bed..083239152ec2 100644 --- a/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java +++ b/src/test/java/com/thealgorithms/strings/AlphabeticalTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/AnagramsTest.java b/src/test/java/com/thealgorithms/strings/AnagramsTest.java index 2b56ef0172f9..ba530cffb017 100644 --- a/src/test/java/com/thealgorithms/strings/AnagramsTest.java +++ b/src/test/java/com/thealgorithms/strings/AnagramsTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/CharacterSameTest.java b/src/test/java/com/thealgorithms/strings/CharacterSameTest.java index e4faee25e84f..d91b5f2f55e9 100644 --- a/src/test/java/com/thealgorithms/strings/CharacterSameTest.java +++ b/src/test/java/com/thealgorithms/strings/CharacterSameTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java b/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java index 74918929f3c8..713b53f0b634 100644 --- a/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java +++ b/src/test/java/com/thealgorithms/strings/CheckVowelsTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java b/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java index f2faf49cfd3e..9649a89a3325 100644 --- a/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java +++ b/src/test/java/com/thealgorithms/strings/HorspoolSearchTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/IsomorphicTest.java b/src/test/java/com/thealgorithms/strings/IsomorphicTest.java index a51b0fe9caa9..0dac47551868 100644 --- a/src/test/java/com/thealgorithms/strings/IsomorphicTest.java +++ b/src/test/java/com/thealgorithms/strings/IsomorphicTest.java @@ -1,10 +1,13 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -public class IsomorphicTest { +public final class IsomorphicTest { + private IsomorphicTest() { + } @Test public static void main(String[] args) { diff --git a/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java b/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java index c9b890f4d502..4ffbddcb44a8 100644 --- a/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java +++ b/src/test/java/com/thealgorithms/strings/LetterCombinationsOfPhoneNumberTest.java @@ -1,8 +1,9 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertTrue; -import java.util.*; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.Test; public class LetterCombinationsOfPhoneNumberTest { diff --git a/src/test/java/com/thealgorithms/strings/LowerTest.java b/src/test/java/com/thealgorithms/strings/LowerTest.java index ebc72f3c7bfd..e0abb921a593 100644 --- a/src/test/java/com/thealgorithms/strings/LowerTest.java +++ b/src/test/java/com/thealgorithms/strings/LowerTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/MyAtoiTest.java b/src/test/java/com/thealgorithms/strings/MyAtoiTest.java index 6d27a8acb415..45f9158571e9 100644 --- a/src/test/java/com/thealgorithms/strings/MyAtoiTest.java +++ b/src/test/java/com/thealgorithms/strings/MyAtoiTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/PangramTest.java b/src/test/java/com/thealgorithms/strings/PangramTest.java index 7ad79b203b45..00ecb909b2de 100644 --- a/src/test/java/com/thealgorithms/strings/PangramTest.java +++ b/src/test/java/com/thealgorithms/strings/PangramTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java b/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java index af8d20ab9b7e..b33037f37cfd 100644 --- a/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java +++ b/src/test/java/com/thealgorithms/strings/ReverseStringRecursiveTest.java @@ -5,8 +5,6 @@ import org.junit.jupiter.api.Test; public class ReverseStringRecursiveTest { - ReverseStringRecursive stringRecursive = new ReverseStringRecursive(); - @Test void shouldAcceptWhenEmptyStringIsPassed() { String expected = ""; diff --git a/src/test/java/com/thealgorithms/strings/ReverseStringTest.java b/src/test/java/com/thealgorithms/strings/ReverseStringTest.java index 137ec7a949ab..e73f7afce8eb 100644 --- a/src/test/java/com/thealgorithms/strings/ReverseStringTest.java +++ b/src/test/java/com/thealgorithms/strings/ReverseStringTest.java @@ -7,7 +7,7 @@ public class ReverseStringTest { @Test - public void ReverseStringTest() { + public void testReverseString() { String input1 = "Hello World"; String input2 = "helloworld"; String input3 = "123456789"; diff --git a/src/test/java/com/thealgorithms/strings/RotationTest.java b/src/test/java/com/thealgorithms/strings/RotationTest.java index 239366df92b2..911ff87d29ad 100644 --- a/src/test/java/com/thealgorithms/strings/RotationTest.java +++ b/src/test/java/com/thealgorithms/strings/RotationTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/StringCompressionTest.java b/src/test/java/com/thealgorithms/strings/StringCompressionTest.java index 4194cad0b754..bbd56c19dc23 100644 --- a/src/test/java/com/thealgorithms/strings/StringCompressionTest.java +++ b/src/test/java/com/thealgorithms/strings/StringCompressionTest.java @@ -1,5 +1,5 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; diff --git a/src/test/java/com/thealgorithms/strings/UpperTest.java b/src/test/java/com/thealgorithms/strings/UpperTest.java index 5c030efdc740..5413c77b913a 100644 --- a/src/test/java/com/thealgorithms/strings/UpperTest.java +++ b/src/test/java/com/thealgorithms/strings/UpperTest.java @@ -1,6 +1,6 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java b/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java index 13909e636f5c..22deb4b14d3c 100644 --- a/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java +++ b/src/test/java/com/thealgorithms/strings/ValidParenthesesTest.java @@ -1,6 +1,7 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; @@ -8,16 +9,16 @@ public class ValidParenthesesTest { @Test void testOne() { - assertEquals(true, ValidParentheses.isValid("()")); + assertTrue(ValidParentheses.isValid("()")); } @Test void testTwo() { - assertEquals(true, ValidParentheses.isValid("()[]{}")); + assertTrue(ValidParentheses.isValid("()[]{}")); } @Test void testThree() { - assertEquals(false, ValidParentheses.isValid("(]")); + assertFalse(ValidParentheses.isValid("(]")); } } diff --git a/src/test/java/com/thealgorithms/strings/WordLadderTest.java b/src/test/java/com/thealgorithms/strings/WordLadderTest.java index 5b40df8b4d17..4f1d07ebdc4a 100644 --- a/src/test/java/com/thealgorithms/strings/WordLadderTest.java +++ b/src/test/java/com/thealgorithms/strings/WordLadderTest.java @@ -1,8 +1,9 @@ package com.thealgorithms.strings; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; -import java.util.*; +import java.util.Arrays; +import java.util.List; import org.junit.jupiter.api.Test; public class WordLadderTest {