Не могу понять логику решения этой проблемы анаграммы - PullRequest
0 голосов
/ 29 июня 2019

Учитывая две строки, a и b, которые могут иметь или не иметь одинаковую длину, определяют минимальное количество удалений символов, необходимое для создания анаграмм a и b. Любые символы могут быть удалены из любой строки.

Я впервые готовлюсь к конкурентному программированию, и мне сложно понять логику двух циклов for.

String str1 = s.next();               
String str2 = s.next();
char []c1 = str1.toCharArray();
char []c2 = str2.toCharArray();
int []cnt1 = new int[26];
int []cnt2 = new int[26];

int len1 = str1.length();
for (int i = 0; i < len1; i++) {
    cnt1[c1[i] - 97]++;
}

int len2 = str2.length();
for (int i = 0; i < len2; i++) {
    cnt2[c2[i] - 97]++;
}

int cnt = 0;
for (int i = 0; i < 26; i++) {
    cnt += Math.abs(cnt2[i] - cnt1[i]);
}

System.out.println(cnt);

Ответы [ 2 ]

1 голос
/ 29 июня 2019

Этот фрагмент проходит по каждой строке и подсчитывает количество вхождений каждой буквы в нем (и сохраняет счетчики в массиве для повышения производительности).

Затем он проходит по двум массивам счетчиков и для каждой буквы вычитает счетчики для обеих строк (в абсолютном значении).Разница заключается в количестве того символа, который должен быть удален.Эти различия суммируются, и в результате получается ответ.

0 голосов
/ 29 июня 2019

Хорошо, это то, что программа делает с двумя циклами for.

Представьте «cnt1» как английский алфавит от «A» до «Z», написанный на бумаге слева направо, как и «cnt2». Во-первых, цикл for помечает букву на бумаге, если она найдена в «string1», и второй - «string2».

Теперь у вас есть две бумаги с буквами от «А» до «Z», написанные слева направо, и после выполнения двух «для циклов» каждая бумага имеет метки на тех буквах, которые присутствовали в соответствующие строковые входы.

Теперь, если буква отмечена галочкой на обеих бумагах, оставьте ее в покое, и если вы обнаружите какую-либо букву, отмеченную галочкой на одном листе (то есть в массиве), и не отмечен галочкой в ​​другом массиве, то посчитайте ее как письмо, которое будет удалено.

К тому времени, когда вы отсканируете обе бумаги, подобные этой, слева направо, у вас будет количество букв, которые необходимо полностью удалить из обеих бумаг.

Посмотрим, как это реализовано в коде. Начальные значения по умолчанию для массива примитивов - все нули, и действие «пометить галочкой» букву на бумаге достигается путем изменения этого конкретного индекса на «1».

Таким образом, к моменту окончания первых двух циклов for каждый из массивов 'cnt1' и 'cnt2' будет содержать '1' в случайном порядке. Если оба массива имеют «1» или «0» для данного индекса, вам не нужно их считать, если они будут разными, т.е. разница этого конкретного индекса для обоих массивов равна «1» (вот почему вы видите Math. abs используется), то это буква, которая будет удалена из первой строки или второй.

edit: Для конкурсных экзаменов вы должны сначала иметь возможность визуализировать решение, а затем найти оптимальное. Компьютеры только добавляют скорость к найденному решению. Они не думают, мы заставляем их думать :)

Надеюсь, вы могли бы сначала визуализировать решение и все еще привыкать к программированию. Всего наилучшего!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...