Я пробовал два пути: A сортирует символы обеих строк в алфавитном порядке и сравнивает результаты, B подсчитывает каждый символ в обеих строках и сравнивает подсчеты. Я бы предпочел A over B относительно удобочитаемости.
public boolean isAnagramA(String a, String b) {
if (a.length() != b.length()) {
return false;
}
char[] aAsArray = a.toUpperCase().toCharArray();
char[] bAsArray = b.toUpperCase().toCharArray();
Arrays.sort(aAsArray);
Arrays.sort(bAsArray);
return Arrays.equals(aAsArray, bAsArray);
}
public int numberOf(char needle, char[] haystack) {
int count = 0;
for (int i = 0; i < haystack.length; i++) {
if (haystack[i] == needle) {
count++;
}
}
return count;
}
public boolean isAnagramB(String a, String b) {
if (a.length() != b.length()) {
return false;
}
char[] aAsArray = a.toUpperCase().toCharArray();
char[] bAsArray = b.toUpperCase().toCharArray();
for (int i = 0; i < aAsArray.length; i++) {
if (numberOf(aAsArray[i], aAsArray) != numberOf(aAsArray[i], bAsArray)) {
return false;
}
}
return true;
}
public void run() {
{
long start = System.nanoTime();
System.out.println(isAnagramA("OTTO", "TOT"));
System.out.println(isAnagramA("OTTO", "TOTO"));
System.out.println(isAnagramA("LOTTO", "TOLLO"));
System.out.println(isAnagramA("yarm", "army"));
System.out.println(isAnagramA("Yarm", "Army"));
System.out.println(isAnagramA("SMAISMRMILMEPOETALEVMIBVNENVGTTAVIRAS",
"AltissimvmPlanetamTergeminvmObservavi"));
System.out.println((System.nanoTime() - start) + " ns for 6 x A");
}
{
long start = System.nanoTime();
System.out.println(isAnagramB("OTTO", "TOT"));
System.out.println(isAnagramB("OTTO", "TOTO"));
System.out.println(isAnagramB("LOTTO", "TOLLO"));
System.out.println(isAnagramB("yarm", "army"));
System.out.println(isAnagramB("Yarm", "Army"));
System.out.println(isAnagramB("SMAISMRMILMEPOETALEVMIBVNENVGTTAVIRAS",
"AltissimvmPlanetamTergeminvmObservavi"));
System.out.println((System.nanoTime() - start) + " ns for 6 x B");
}
{
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
isAnagramA("SMAISMRMILMEPOETALEVMIBVNENVGTTAVIRAS", "AltissimvmPlanetamTergeminvmObservavi");
}
System.out.println((System.currentTimeMillis() - start) + " ms for 1000000 x A");
}
{
long start = System.currentTimeMillis();
for (int i = 0; i < 1000000; i++) {
isAnagramB("SMAISMRMILMEPOETALEVMIBVNENVGTTAVIRAS", "AltissimvmPlanetamTergeminvmObservavi");
}
System.out.println((System.currentTimeMillis() - start) + " ms for 1000000 x B");
}
}
Метод запуска() используется для проверки, работает ли он (а не JUnit, только выход) и какие пути быстрее, это выход:
false
true
false
true
true
true
579384 ns for 6 x A
false
true
false
true
true
true
252453 ns for 6 x B
1310 ms for 1000000 x A
1333 ms for 1000000 x B
сначала, кажется, два раз медленнее, но цикл 1000000 раз по сравнению с анаграммой Galileo Galilei показывает практически отсутствие разницы в производительности (надеюсь, это не из-за оптимизации компилятора).
Я согласен с другими комментаторами в отношении правильности и удобочитаемости в первую очередь и оптимизации исследований только в том случае, если и где есть настоящая потребность в нем.
Сначала я бы позаботился о правильности кода, прежде чем думать о производительности: этот код явно не работает ни на что, кроме 4-символьных строк, которые уже не содержат обратную косую черту; и даже тогда это не сработает. –
Не сделал бы это 'APPLE' и' LAAPE' анаграммой? Я думаю, вы должны просто подсчитать сумму, которую каждый символ «char» появляется в каждой строке и сравнивать оба массива, или «Карта» – SomeJavaGuy
Почему бы вам не проверить производительность самостоятельно? Производительность может варьироваться в зависимости от используемого оборудования. –