MCPcopy Create free account
hub / github.com/TheAlgorithms/Java / compress

Method compress

src/main/java/com/thealgorithms/compression/LZ77.java:54–124  ·  view source on GitHub ↗

Compresses the input text using the LZ77 algorithm. @param text The input string to compress. Must not be null. @param windowSize The size of the sliding window (search buffer). Must be positive. @param lookaheadBufferSize The size of the lookahead buffer. Must be positive. @return A list of {@link

(String text, int windowSize, int lookaheadBufferSize)

Source from the content-addressed store, hash-verified

52 * @throws IllegalArgumentException if windowSize or lookaheadBufferSize are not positive.
53 */
54 public static List<Token> compress(String text, int windowSize, int lookaheadBufferSize) {
55 if (text == null) {
56 return new ArrayList<>();
57 }
58 if (windowSize <= 0 || lookaheadBufferSize <= 0) {
59 throw new IllegalArgumentException("Window size and lookahead buffer size must be positive.");
60 }
61
62 List<Token> compressedOutput = new ArrayList<>();
63 int currentPosition = 0;
64
65 while (currentPosition < text.length()) {
66 int bestMatchDistance = 0;
67 int bestMatchLength = 0;
68
69 // Define the start of the search window
70 int searchBufferStart = Math.max(0, currentPosition - windowSize);
71 // Define the end of the lookahead buffer (don't go past text length)
72 int lookaheadEnd = Math.min(currentPosition + lookaheadBufferSize, text.length());
73
74 // Search for the longest match in the window
75 for (int i = searchBufferStart; i < currentPosition; i++) {
76 int currentMatchLength = 0;
77
78 // Check how far the match extends into the lookahead buffer
79 // This allows for overlapping matches (e.g., "aaa" can match with offset 1)
80 while (currentPosition + currentMatchLength < lookaheadEnd) {
81 int sourceIndex = i + currentMatchLength;
82
83 // Handle overlapping matches (run-length encoding within LZ77)
84 // When we've matched beyond our starting position, wrap around using modulo
85 if (sourceIndex >= currentPosition) {
86 int offset = currentPosition - i;
87 sourceIndex = i + (currentMatchLength % offset);
88 }
89
90 if (text.charAt(sourceIndex) == text.charAt(currentPosition + currentMatchLength)) {
91 currentMatchLength++;
92 } else {
93 break;
94 }
95 }
96
97 // If this match is longer than the best found so far
98 if (currentMatchLength > bestMatchLength) {
99 bestMatchLength = currentMatchLength;
100 bestMatchDistance = currentPosition - i; // Calculate offset from current position
101 }
102 }
103
104 char nextChar;
105 if (currentPosition + bestMatchLength < text.length()) {
106 nextChar = text.charAt(currentPosition + bestMatchLength);
107 } else {
108 nextChar = END_OF_STREAM;
109 }
110
111 // Add the token to the output

Callers 15

testNoInitialRepeatsMethod · 0.95
testLongerExampleMethod · 0.95
testEmptyStringMethod · 0.95
testAllSameCharactersMethod · 0.95
testSingleCharacterMethod · 0.95
testMatchToEndMethod · 0.95
testSmallWindowSizeMethod · 0.95

Calls 4

lengthMethod · 0.80
maxMethod · 0.45
minMethod · 0.45
addMethod · 0.45

Tested by 15

testNoInitialRepeatsMethod · 0.76
testLongerExampleMethod · 0.76
testEmptyStringMethod · 0.76
testAllSameCharactersMethod · 0.76
testSingleCharacterMethod · 0.76
testMatchToEndMethod · 0.76
testSmallWindowSizeMethod · 0.76