Как реализовать Java HashMap.equals (HashMap) в JavaScript - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь написать функцию, которая принимает две строки и возвращает, имеют ли они одинаковую частоту букв. Предполагается, что ни одна строка не является нулевой.

Вот моя реализация 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 возвращает true, что является правильным. Однако функции JS возвращают false.

Есть ли способ вернуть, что две карты равны в JS, если они имеют одинаковые ключи и значения, но в другом порядке?

Ответы [ 2 ]

0 голосов
/ 28 сентября 2018

Вот код, который я создал, который работает:

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.log(perm(s1, s1));

То, что произошло, я использовал неправильный синтаксис для Map (). Вместо этого я использовал скобочные обозначения для создания моих пар ключ-значение или методов Map.prototype.

См. Этот пример кода:

let m = new Map();
m.set(1, "a");
m[2] = "b";
console.log(m);
//Output: Map { 1 => 'a', 2: 'b' }

Использование методов Map.get и Map.set работает для меня.

0 голосов
/ 28 июня 2018

Проблема с вашим кодом в том, как вы сравниваете два объекта карты. В 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;

...