" "
. When FindBugs warns you about problems with calculating the absolute value of the hashcode equal to Integer.MIN_VALUE, it gives examples of lines that have such a hashcode - "polygenelubricants"
or "DESIGNING WORKHOUSES"
. Where did these examples come from? How to make a beautiful string with the specified hashcode?"<___> [</>] <___>"
21715 2 1 1 2 1 7 ...
List<String> words = Files.readAllLines(Paths.get("litf-win.txt"), Charset.forName("cp1251")).stream() .map(s -> s.substring(0, s.indexOf(' '))) .filter(s -> s.length() > 2) .collect(Collectors.toList());
String[] preps = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" };
List<String> infixes = Stream.concat(Stream.of(" "), Arrays.stream(preps).map(p -> ' '+p+' ')) .collect(Collectors.toList());
words.stream().flatMap(s -> infixes.stream().map((String infix) -> infix+s))
Map<Integer, Map<Integer, List<String>>> lenHashSuffix = words.stream() .flatMap(s -> infixes.stream().map((String infix) -> infix+s)) .collect(Collectors.groupingBy(String::length, Collectors.groupingBy(String::hashCode)));
words.stream().map(s -> Character.toTitleCase(s.charAt(0)) + s.substring(1))
flatMap
. It remains to lenHashSuffix
over all lengths from lenHashSuffix
, calculate the appropriate hashcode for s 2, and extract the lines with this hashcode. Here the question arises: how for a given len length to calculate h ( s 1 ) · 31 len ? The Math.pow
method does not work: it works with fractional numbers. It would be possible to write a for
loop, but this is inconsistent! Fortunately, we have reduce! int hash = IntStream.range(0, len).reduce(s.hashCode(), (a, i) -> a*31);
entry
from lenHashSuffix
stream of the s 2 rows that satisfy us can be obtained as follows: entry.getValue().getOrDefault( target - IntStream.range(0, entry.getKey()).reduce(s.hashCode(), (a, i) -> a*31), Collections.emptyList()).stream()
words.stream() .map(s -> Character.toTitleCase(s.charAt(0)) + s.substring(1)) .flatMap(s -> lenHashSuffix.entrySet().stream() .flatMap(entry -> entry.getValue().getOrDefault( target - IntStream.range(0, entry.getKey()).reduce(s.hashCode(), (a, i) -> a*31), Collections.emptyList()).stream().map(suffix -> s+suffix))) .sorted().forEach(System.out::println);
import java.nio.charset.Charset; import java.nio.file.*; import java.util.*; import java.util.stream.*; public class PhraseHashCode { public static void main(String[] args) throws Exception { int target = Integer.MIN_VALUE; String[] preps = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" }; List<String> infixes = Stream.concat(Stream.of(" "), Arrays.stream(preps).map(p -> ' '+p+' ')) .collect(Collectors.toList()); List<String> words = Files.readAllLines(Paths.get("litf-win.txt"), Charset.forName("cp1251")).stream() .map(s -> s.substring(0, s.indexOf(' '))) .filter(s -> s.length() > 2) .collect(Collectors.toList()); Map<Integer, Map<Integer, List<String>>> lenHashSuffix = words.stream() .flatMap(s -> infixes.stream().map((String infix) -> infix+s)) .collect(Collectors.groupingBy(String::length, Collectors.groupingBy(String::hashCode))); words.stream() .map(s -> Character.toTitleCase(s.charAt(0)) + s.substring(1)) .flatMap(s -> lenHashSuffix.entrySet().stream() .flatMap(entry -> entry.getValue().getOrDefault( target - IntStream.range(0, entry.getKey()).reduce(s.hashCode(), (a, i) -> a*31), Collections.emptyList()).stream().map(suffix -> s+suffix))) .sorted().forEach(System.out::println); } }
" " " " " " " " " " " "
Math.abs
from the hashcode, you will need the following lines (target = Integer.MIN_VALUE): " " " " " " " " " "
Source: https://habr.com/ru/post/252671/
All Articles