Skip to content

Latest commit

 

History

History
77 lines (52 loc) · 6.81 KB

Exploring Anagram Detection and Solutions in JavaScript.hy.md

File metadata and controls

77 lines (52 loc) · 6.81 KB

Ի՞նչ է անագրամը: Ստեղծել ֆունկցիա, որը կստուգի թե տրված երկու բառերն արդյո՞ք անագրամ են:

Անագրամա, երբեմն անվանում են նաև շրջագրում (հունարեն՝ αναγράμμα - «տառերի տեղափոխում»)։ Այն գրական հնարանք է, որն օգտագործվում է բառի նույն տառերի տարբեր դասավորությամբ նոր բառեր ստանալու նպատակով։ Օրինակ «երգ» բառի անագրամ կարող է հանդիսանալ «գեր» բառը։

Պահանջվում է գրել ֆունկցիա, որը որպես արգումենտ կստանա երկու բառ, և կպարզի թե արդյո՞ք մեկը մյուսի անագրամն է։ Նաև պետք է անտեսել տառերի մեծատառ կամ փոքրատառ լինելը։

const isAnagram = (a, b) =>
  [...a.toLowerCase()].sort().toString() ===
  [...b.toLowerCase()].sort().toString();

isAnagram("friend", "fiNder"); // true
isAnagram("hello", "hi"); // false

Ֆունկցիան ընդունում է երկու արգումենտ՝ a և b: Սկզբից առաջին արգումենտով ստացած բառի վրա կանչում է toLowerCase մեթոդը, որպեսզի այն սարքի ամբողջովին փոքրատառ։ Ապա սփրեդ (...) օպերատորի օգնությամբ այդ բառը վերածում է տառերի զանգվածի։ Կատարվում է զանգվածի լեքսիկոգրաֆիկ տեսակավորում, և տառերը դասավորվում են ըստ Unicode-ի աղյուսակում ունեցած հերթական համարների, որը մեր պարագայում համընկնում է տառերի այբբենական հերթականության հետ։ Իսկ հետո այդ զանգվածը կրկին վերածվում է տողի, toString մեթոդի օգնությամբ։

Նույն հերթականությամբ այդ բոլոր գործողությունները կատարվում են նաև երկրորդ արգումենտի նկատմամբ, ապա խիստ հավասարության օպերատորի օգնությամբ ստուգում ենք արտահայտության աջ և ձախ մասերի հավասարությունը։ Եթե նրանք հավասար են, ապա մի բառը մյուսի անագրամն է, և ֆունկցիան վերադարձնում է true:

Մենք կարող ենք մի քիչ էլ բարդացնել խնդիրը, օրինակ ի՞նչպես անել, որ ֆունկցիան բացի մեծատառ-փոքրատառից, հաշվի չառնի նաև բացատների առկայությունը։

Շատ հեշտ դա կարող ենք անել regular expression-ի և trim մեթոդի օգնությամբ։

const sort = (str) =>
  str.replace(/\s+/g, "").toLowerCase().split("").sort().join("");

const isAnagram = (original, test) =>
  original.trim() === test.trim() ? false : sort(original) === sort(test);

Սկզբում ստեղծում ենք «օգնական» ֆունկցիան։ Այն նախ regular expression-ի օգնությամբ մաքրում է բոլոր բացատները։ Ովքեր երբեք չեն օգտագործել regular expression, ասեմ որ /\s+/g արտահայտությունը տողի մեջ ուղղակի գլոբալ որոնում է բոլոր բացատները և replace մեթոդի օգնությամբ փոխարինում դրանք դատարկ տողով, այսինքն կարելի է ասել մաքրում է տողը բոլոր բացատներից։

Ապա toLowerCase մեթոդի օգնությամբ տողի բոլոր տառերը վերածվում են փոքրատառի։ split մեթոդը այդ տողը վերածում է տառերի զանգվածի, ապա նրա վրա կանչելով sort մեթոդը, կատարում է տառերի տեսակավորում։ Եվ վերջապես join մեթոդը կատարում է արդեն բացատներից մաքրված, ամբողջովին փոքրատառերի վերածված և զանգվածի մեջ այբբենական կարգով դասավորված տառերի միավորումը տողի մեջ։

Բուն ֆունկցիան, որը պետք է ստուգի թե բառերն արդյոք անագրամ են՝ ստանում է երկու պարամետր, ապա trim մեթոդի օգնությամբ մաքրում է բառի սկզբում կամ վերջում եղած բացատները, և համեմատում։ Եթե նրանք բացարձակապես նույնն են, և թերնարի օպերատորը վերադարձնում է true, մենք այնտեղ վերագրում ենք false արժեք։ Այս մի քիչ «հակատրամաբանական» քայլը արվում է, որպեսզի բացառվի երկու բացարձակապես նույն բառերի դիտարկումը որպես անագրամներ։ Գրածս առաջին տարբերակում այդ ստուգումը չէր կատարվում, և օրինակ isAnagram("hello", "hello") կանչը վերադարձնում էր true, ինչը իրականում այնքան էլ ճիշտ չէ, նրանք բացարձակապես նույնն են, ոչ թե մեկը մյուսի անագրամը։

Երբ պարամետրերը ամբողջությամբ նույնը չեն լինում, ապա «օգնական» ֆունկցիայի կանչի միջոցով կատարվում է պարամետրերի համեմատություն, և ստացված բուլյան արժեքն էլ դառնում է ֆունկցիայի վերադարձվող արժեք։

isAnagram("f rie nd", "fiNdeR"); // true
isAnagram(" hello ", "hello"); // false
isAnagram("friend", "hello"); // false

Ի դեպ օգտագործելով ES6-ում ավելացված Map տվյալների կառուցվածքը՝ կարելի է ստեղծել բառերի անագրամ լինելը ստուգող արագ և մաքուր ֆունկցիա՝

const isAnagram = (str1, str2) => {
  if (str1.length !== str2.length) return false;

  const map = new Map();

  for (const char of str1) {
    const count = map.has(char) ? map.get(char) + 1 : 1;
    map.set(char, count);
  }

  for (const char of str2) {
    if (!map.has(char)) return false;

    const count = map.get(char) - 1;

    if (count === 0) {
      map.delete(char);
      continue;
    }

    map.set(char, count);
  }

  return map.size === 0;
};

Map տվյալների կառուցվածքի մասին մանրամասն կարդացեք այստեղ