Я пытаюсь написать функцию, которая принимает две строки и возвращает, имеют ли они одинаковую частоту букв. Предполагается, что ни одна строка не является пустой.
Вот моя реализация на Java:
public void addToMap(HashMap<String, Integer> map, String s){
if (map.get(s) == null){
map.put(s, 1);
} else{
map.put(s, map.get(s)+1);
}
}
public boolean perm(String a, String b){
if (a.length() != b.length()){
return false;
}
HashMap<String, Integer> aMap = new HashMap<>();
HashMap<String, Integer> bMap = new HashMap<>();
for(int i = 0; i < a.length(); i++){
addToMap(aMap, a.substring(i,i+1));
addToMap(bMap, b.substring(i,i+1));
}
return aMap.equals(bMap);
}
Я пытаюсь воспроизвести это в JavaScript:
const addToMap = (map, s) => {
if (map[s] == null){
map[s] = 1;
} else{
map[s] = map[s]+1;
}
}
const perm = (a,b) => {
if (a.length != b.length){
return false;
}
let aMap = new Map();
let bMap = new Map();
for(let i = 0; i < a.length; i++){
addToMap(aMap, a.substring(i,i+1));
addToMap(bMap, b.substring(i,i+1));
}
return aMap === bMap;
}
Я тестировал perm («abca», «bcaa») для обеих реализаций. Код Java возвращает истину, что верно. Однако функции JS возвращают false.
Есть ли способ вернуть, что две карты равны в JS, если у них одинаковые ключи и значения, но в другом порядке?
Проблема в том, как вы объединяете оба объекта Map() в Javascript. Я настоятельно рекомендую вам проверить этот stackoverflow.com/questions/35948335/…



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема с вашим кодом заключается в том, как вы сравниваете два объекта карты. В Java вы используете equels, но если вы используете ==, вы всегда получите такой же ложный результат. В js вы можете сравнивать два объекта по циклу по ключам и сравнивать каждый ключ и значение, или для короче, но с небольшими накладными расходами, просто выполните JSON.stringify (aMap) === JSON.stringify (bMap) вместо aMap == bMap
Обновлять Как вы упомянули, JSON.stringify не работает. (Обычно, когда вы перебираете ключи, они будут идти в алфавитном порядке, но это зависит от браузера, поскольку объект в js обычно не является упорядоченными свойствами ключ-значение).
Поэтому, когда я упоминаю, вам просто нужно сравнить две карты. Например:
const isSubMap = function(mapA, mapB) {
for (let key in mapA) {
if (!mapB[key] || mapA[key] !== mapB[key]) {
return false;
}
}
return true;
}
Но что касается меня, я бы выбрал другой подход к решению этой проблемы: 1) Суммируйте коды для всех символов из строки A и строки B, а затем сравните sumA == sumB; 2) Просто создайте карту различий. Таким образом, символы из строки A добавят ключ к карте со значением 1 и / или увеличат счетчик, а символы из строки B будут уменьшать счетчик, если значение свойства больше 1, или создать новый со значением -1 (если значение === 0, то удалить ключевое свойство из объекта). В конце проверьте, имеет ли объект нулевые свойства с помощью Object.keys (obj) .length === 0;
Он по-прежнему возвращает false. Это не удается: console.info (perm ("abca", "bcaa")); Сравнивались строки: Карта {a: 2, b: 1, c: 1} Карта {b: 1, c: 1, a: 2} Я не понимаю, почему они пройдут.
Однако это работает, добавление этого в мой код заставит меня пройти всю строку и карту, чего я бы предпочел не делать. Я нашел решение вопроса о перестановке: stackoverflow.com/questions/35948335/… Объект Map в JS просто не сравнивается. stackoverflow.com/q/37049306/7066218 Но для моей проблемы с картой JS кажется, что
Вот созданный мной код, который работает:
const addToMap = (map, s) => {
if (map.has(s)){
map.set(s, map.get(s)+1);
} else{ map.set(s, 1);}
}
const perm = (a, b) => {
if (a.length != b.length){ return false; }
let aMap = new Map();
let bMap = new Map();
for(let i = 0; i < a.length; i++){
addToMap(aMap, a.substring(i, i+1));
addToMap(bMap, b.substring(i, i+1));
}
return aMap.toString() == bMap.toString();
}
const s1 = "abcda";
const s2 = "cdbaa";
console.info(perm(s1, s1));
Произошло то, что я использовал неправильный синтаксис для Map (). Я использовал скобки для создания пар ключей и значений вместо методов Map.prototype.
См. Этот пример кода:
let m = new Map();
m.set(1, "a");
m[2] = "b";
console.info(m);
//Output: Map { 1 => 'a', 2: 'b' }
Мне подходят методы Map.get и Map.set.
Если ваш код работает, подумайте об этом в Проверка кода