Ошибка компиляции при сравнении двух анаграмм при использовании hashmap - PullRequest
0 голосов
/ 28 августа 2018

Мне нужно найти способ проверить две строки, если они анаграммы. Если они есть, метод должен возвращать true и false в противном случае. Так как я не мог придумать правильный способ сделать это самостоятельно, я нашел еще один фрагмент кода Родни Шагулиана (Github: github.com/RodneyShag, HackerRank: hackerrank.com/RodneyShag), который должен работать:

import java.io.*;
import java.util.*;

public class Solution {

    static boolean isAnagram(String a, String b) {
        if (a == null || b == null || a.length() != b.length()) {
            return false;
        }
        a = a.toLowerCase();
        b = b.toLowerCase();
        HashMap<Character, Integer> map = new HashMap<>();

        /* Fill HashMap with 1st String */
        for (int i = 0; i < a.length(); i++) {
            char ch = a.charAt(i);
            map.merge(ch, 1, Integer::sum);
        }

        /* Compare 2nd String to 1st String's HashMap */
        for (int i = 0; i < b.length(); i++) {
            char ch = b.charAt(i);
            if (map.containsKey(ch) && map.get(ch) > 0) {
                map.put(ch, map.get(ch) - 1);
            } else {
            return false;
        }
    }
    return true;
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String a = scan.next();
        String b = scan.next();
        scan.close();
        boolean ret = isAnagram(a, b);
        System.out.println( (ret) ? "Anagrams" : "Not Anagrams" );
    }
} 

Я просто скопировал и вставил его в собственную IDE, но в строке 18 получил три ошибки компиляции:

map.merge(ch, 1, Integer::sum);

Сказать, что

')' expected,   
illegal start of expression,   
error: ';' expected.

Что я не понимаю, так как не вижу скобок или чего-то пропущенного. Код также явно работал для автора. Может кто-нибудь помочь мне увидеть проблему?

Кроме того, есть ли способ сравнить две строки, чтобы увидеть, являются ли они анаграммами без использования hashmap? Возможно, с помощью метода string to char [] и для циклов? (Это был оригинальный способ, которым я придумал, я совсем не знаком с хэш-картами.)

1 Ответ

0 голосов
/ 28 августа 2018

Прежде всего, этот код не является проблемой и хорошо работает в моей среде, и вы можете проверить свою версию JDK, используя java -version

Вот моя версия JDK

$ java -version
java version "1.8.0_101"
Java(TM) SE Runtime Environment (build 1.8.0_101-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.101-b13, mixed mode)

Лямбда-выражения Integer::sum - это функции, поддерживаемые JDK8 и более поздними версиями, если вы используете версию JDK до 1.8, вы не можете успешно скомпилировать;

тогда давайте поговорим об анаграммах:

Мы можем использовать массив, который является индексом символа, а затем подсчитать количество вхождений каждого символа в строке. В первой строке каждый появляющийся символ добавляется в соответствующую позицию массива. Во второй строке каждый появляющийся символ вычитается из соответствующей позиции массива. Итак, что мы делаем, мы проходим первую строку, проходим вторую строку, и единственный способ, которым обе эти строки будут анаграммами, это если этот массив все еще будет равным 0. Это означает, что один из двух строк имеет одинаковое количество символов.

  1. Создать 256-битный целочисленный массив k
  2. Для каждого символа x в первой строке sFirst целочисленное значение x равно y, добавляя k [y] к 1
  3. Для каждого символа x во второй строке sSecond целочисленное значение для x равно y, минус k [y] на 1
  4. Если массив k все еще равен нулю, то строки sFirst и sSecond являются анаграммами

-

public class CustomStringUtil {
    public static boolean secondIsAnagram(String sFirst, String sSecond) {
        if (sFirst.length() != sSecond.length()) {
            return false;
        }
        int[] asciiChars = new int[256];
        for (int i = sFirst.length() - 1; i >= 0; --i) {
            ++asciiChars[sFirst.charAt(i)];
        }
        for (int i = sFirst.length() - 1; i >= 0; --i) {
            char currChar = sSecond.charAt(i);
            if (asciiChars[currChar] == 0) {
                return false;
            }
            --asciiChars[currChar];
        }
        return true;
    }
}
...