Как найти анаграмму в тексте

Поиск анаграмм и сабанаграмм во всех словах языка

Время на прочтение
2 мин

Количество просмотров 8K

Решение задач с анаграммами натолкнуло на мысль:

Сколько останется слов, если удалить все анаграммы и сабанграммы из словаря русского языка

В найденном словаре больше 1,5 млн слов в различных формах

Можно сравнить каждое слово с каждым, но для 1,5 млн записей это долго и неоптимально.
В мире с бесконечной памятью можно сгенерировать подстроки всех перестановок каждого слова и проверить наш словарь на них

Но есть ли решение получше?

Начнем с терминологии:

Анаграмма — слово, получаемое перестановкой букв
Пример: ракета и карета

Сабанаграмма — слово, которое можно составить из букв другого слова
Пример: арка — сабанаграмма слова ракета

Задача

:

Допустим наш словарь состоит из пяти хитрых слов:

ракета, карета, арка, кот, мокрота

Добавляем словарь в префиксное дерево (Trie)
Каждый узел дерева содержит пару: буква + ее количество в слове
Узлы отсортированы по алфавиту и частоте буквы в слове

Алгоритм (в упрощенной форме):

Берем слово, н.р. кот:

Ищем узлы, начинающиеся на минимальную букву слова («к»)

(На рисунке такие узлы отмечены сиреневым)

Как только мы нашли такой узел, ищем в поддереве путь, содержащий оставшиеся буквы в нужном количестве

В слове мокрота ниже узла K-1 есть O-2 и Т-1, что для нашего слова кот достаточно

Преимущество такой структуры данных в том, что мы можем быстро выходить из поддерева, если буква узла > чем искомая буква

Проверив наш словарь, мы выяснили, что только мокрота не является анаграммой или сабанаграммой другого слова

Код на Java

 public boolean isAnagramOrSubAnagram(Word word) {
        Character minCharacter = word.getMinCharacter();

        Stack<TrieNode> stack = new Stack<>();
        stack.add(root);

        while (!stack.isEmpty()) {
            TrieNode node = stack.pop();

            for (Entry<TrieKey, TrieNode> entry : node.getChildren().entrySet()) {
                char character = entry.getKey().getCharacter();
                if (character < minCharacter) {
                    stack.add(entry.getValue());
                } else if (character > minCharacter) {
                    break;
                } else if (entry.getKey().getCount() >= word.getCharacterCount(minCharacter)) {
                    if (doesMinWordCharacterNodeContainAnagram(entry, word)) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

→ Полная версия кода с двумя словарями и тестами

P.S.

Для русского словаря от 1.5 млн. осталось 242399 слов за 13 минут
Для английского словаря от 416 тыс. осталось 49251 за 45 секунд

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

В этом руководстве мы узнаем, как определить, являются ли данные строки анаграммой. Но сначала мы должны познакомиться с концепцией анаграммы.

Что такое анаграмма?

Анаграмма – это состояние, при котором одна строка или число переставляются таким образом; каждый символ измененной строки или числа должен быть частью другой строки или числа. Другими словами, строка называется анаграммой другой, если вторая является простой перестановкой первой строки. Например: Python и yphton являются анаграммами; Java и avaJ также являются анаграммами.

Давайте разберемся с описанием проблемы определения анаграммы:

  • Получите строковые входные данные от пользователя и сохраните их в отдельных переменных.
  • Используйте метод sort() для сортировки обеих строк в списки.
  • Проверьте оба списка, образуют ли они анаграмму или нет.
  • Распечатайте результат.
  • Выход.

Программа –

 
def anagramCheck2(str1,str2): 
    # Convert string into lists 
    list1 = list(str1) 
    list2 = list(str2) 
    # Sort the list value 
    list1.sort() 
    list2.sort() 
 
    position = 0 
    matches = True 
 
    while position < len(str1) and matches: 
        if list1[position]==list2[position]: 
            position = position + 1 
        else: 
            matches = False 
 
    return matches 
 
print(anagramCheck2('python','ythonp')) 

Выход:

True 

Объяснение –

В приведенном выше коде мы объявили метод anagramCheck(), который принимает в качестве аргумента две строки. Эти строки преобразуются в список для сортировки. Затем мы определили переменную позиции и присвоили ей ноль. На каждой итерации цикла while длина строки сравнивается со значением позиции. Каждый элемент обоих списков сравнивал друг друга и увеличивал значение позиции на единицу. Как только значение позиции станет больше, чем длина строки, цикл будет завершен и вернет истину; в противном случае он вернет false.

Есть несколько методов и примеров, которые мы можем использовать для поиска анаграммы в Python. Эти методы приведены ниже.

1. Техника подсчета

В этом методе мы вычисляем количество каждого символа в обеих заданных строках. Если количество данной строки соответствует другой строке, то соответствующее слово является анаграммой другого слова.

Давайте разберем на примере.

 
from collections import Counter, defaultdict 
def checking_anagram(keywords): 
    agrms = defaultdict(list) 
    for i in keywords: 
        hist = tuple(Counter(i).items()) 
        agrms[hist].append(i) 
    return list(agrms.values()) 
keywords =("python","yphotn") 
print(checking_anagram(keywords)) 

Выход:

[['python'], ['yphotn']] 

Объяснение –

Мы импортировали модуль коллекции и его методы Count и defaultdict, чтобы проверить анаграмму строки в приведенном выше коде. Мы определили метод check_anagram() для подсчета и записи каждого символа с помощью функции счетчика. Каждый счет преобразуется в список и отслеживается. Этот процесс выполняется для всех символов в первой строке, кроме второй. Если количество обеих строк совпадает, это означает, что обе строки являются анаграммами.

2. Метод сортировки

В этом методе обе строки сортируются и проверяют, соответствуют ли оба значения друг другу. Давайте разберемся в следующем примере.

Пример –

 
def Anogram_check(str1, str2): 
    # Strings are sorted and check whether both are matching or not 
    if(sorted(str1)== sorted(str2)): 
        print("Both strings are an Anagram.") 
    else: 
        print("Both strings are not an Anagram.") 
        
string1 ="python" 
string2 ="ythopn" 
print( "String value1 : ", str1 ) 
print( "String value2 : ", str2 ) 
Anogram_check(string1, str2) 

Выход:

String value1 :  python 
String value2 :  ythopn 
Both strings are an Anagram. 

Объяснение –

В приведенном выше коде мы определили метод check_anagram() и передали две строки. В методе check_anagram() мы сохранили строку в определенных переменных. Мы сравнили каждую строку после сортировки. Если сравнение между строками совпало, данная строка формируется как анаграмма; в противном случае они вернулись как Обе строки не являются анаграммами. Этот метод относительно простой и эффективный. Это значительно снижает сложность кода.

3. Обратная проверка анаграммы

Мы можем применить эту технику следующим образом.

Пример –

 
words_list = ["cat", "tac", "Play", "ay"] 
anagrams = {} 
for w in words_list: 
    reverse_word=w[::-1] 
    if reverse_word in words_list: 
         anagrams[w] =(words_list.pop(words_list.index(reverse_word))) 
         print(anagrams) 

Выход:

{'cat': 'tac'} 

Объяснение –

В приведенном выше коде мы использовали этот метод для сравнения анаграмм среди перевернутой строки. Здесь мы сформировали две разные строки. Этот метод похож на палиндромы, где мы перевернули одну строку и проверили ее с другими строками. Если они совпадают, струны образуют анаграмму; если они не совпадают, они не определяются как анаграммы.

4. Методика проверки положения

В этом методе уровень позиции сравнивается с проверкой анаграммы. Мы можем добиться этого, сверяя позиционный символ первой строки с каждой позиционной символьной строкой в другой строке. Если первая строка совпадает с другой строкой, она объявляется анаграммой.

Пример –

 
def checking_anagram(str1,str2): 
    chk_var = True 
    if len(str1) != len(str2): 
        chk_var = False 
        list1 = list(str2) 
    pos_string1 = 0 
    while pos_string1 < len(str1) and chk_var: 
        pos_string2 = 0 
        found = False 
    while pos_string2 < len(list1) and not found: 
        if str1[pos_string1] == list1[pos_string2]: 
            found = True 
        else: 
            pos_string2 = pos_string2 + 1 
    if found: 
        list1[pos_string2] = None 
    else: 
        chk_var = False 
        pos_string1 = pos_string1 + 1 
    return chk_var 
 
 
str1 = "ythopn" 
str2 = "python" 
print("String value1 : " , str1) 
print("String value2 : " , str2) 
Boolean_out = checking_anagram('ythopn','python') 
if Boolean_out: 
    print( "Both words are Alogram " ) 
else: 
    print( "Both words are not Alogram " ) 

Выход:

String value1 :  ythopn 
String value2 :  python 

Объяснение:

В этом еще одна техника получения анаграммы двух строк. Здесь мы также использовали сравнение. Во вложенном цикле while мы передаем строку в эти циклы для процесса проверки.

Внешний цикл while используется для обработки одной из строк, а внутренний цикл – для другой строки. Символ одной строки сравнивается с другой строкой каждого символа, и этот процесс продолжается для каждой буквы в первой строке. Если все символы первой строки совпадают с другой строкой, то обе строки должны быть анаграммой. Этот метод – очень стабильный процесс, потому что он работает по алгоритму, точно оценивая строки.

Изучаю Python вместе с вами, читаю, собираю и записываю информацию опытных программистов.


Download Article


Download Article

You can create an anagram by taking the letters from a phrase of word and rearranging them to form new phrases and words. Anagrams can be a random combination of letters or can resemble a real word. Your job is to use the letters available, without adding or subtracting, to uncover the hidden word or phrase.

  1. Image titled Solve Anagrams Effectively Step 1

    1

    Break up the anagram. First, write down all of the letters in a different pattern. You won’t be able to find a new phrase or word if you keep staring at the same one that’s already in front of you. The letters are already in a jumbled mess, but reorganizing them into a recognizable pattern or shape will help.

    • Draw a shape and write the letters around it. This makes it easier for your eye to pick up combinations since there’s no order to the letters- they’re each equally important.
    • The most commonly used shape is a circle. You can spin your paper or notebook any which way to get a new perspective.
    • Constantly rearranging your letters is important because it gives your mind new ways to look at various groupings of the same letters. Sometimes you need a fresh viewpoint if you’ve been staring at the same thing for some time.
  2. Image titled Solve Anagrams Effectively Step 2

    2

    Put letters together in common pairings. After you break up the anagram, start putting together pairs of letters. For example, you may notice that you have an “H” and that it normally follows a consonant like “P” or “S” to make words that contain “PH” or “SH.”[1]

    • In addition, “H” usually is found after “P,” “S,” “T,” “W,” and “G” unless it’s at the beginning of a word.
    • Unusual letter pairings like “QU” or common ones like “TH” are easy to build words from.
    • Once you start isolating smaller pairings, you have fewer letters to unscramble.

    Advertisement

  3. Image titled Solve Anagrams Effectively Step 3

    3

    Separate vowels and consonants. Write out all of the consonants from your anagram in one column and the vowels in a separate one. Start with the consonants and write out each different way that they can be ordered. Then, insert the vowels into each combination to see how many new words you can make.[2]

    • If you have a lot of vowels, first find the consonant pairs since there are fewer variations to be had.
    • Also, if you have mostly consonants, pair the vowels that can go together. For example, “IE,” “EA,” ot “OU.”
    • Triple vowel combos like “beautiful” or “silhouette” are rare but taking the time to memorize them will help you solve anagrams faster. [3]
  4. Image titled Solve Anagrams Effectively Step 4

    4

    Pick out prefixes and suffixes. Many words in the English language are built off of prefixes and suffixes, which are pairings of letters at the beginning or end of a word to indicate grammar. For anagrams, they can be helpful to find because all you need to do is find the pairings and build a word from the remaining letters.[4]

    • Some common prefixes include: un-, dis-, sub-, re-, de-, in-, ab-, ad-, and ex-.
    • Suffixes you may find could be: -ing, -ness, -ly, -ed, -er, -ry, -ous, -ment, and -tion.
    • Switch around pre- and suffixes to create more word options. For example, “paint-er” can become “re-paint” by using the same letters in a new way.
  5. Advertisement

  1. Image titled Solve Anagrams Effectively Step 5

    1

    Separate all of the letters. Take out a new sheet of paper and rewrite the anagram at the top of the paper. You always want to keep the original anagram handy so that you have a reference and can check that you’re using the correct letters.

  2. Image titled Solve Anagrams Effectively Step 6

    2

    Put the letters in alphabetic order. Start with the first letter you have that’s closest to “A” and write all of the remaining letters after it in the order that they appear in the alphabet. This will help you see what kinds of letters you have or isolate an abundance of vowels or any rare letters like “Q”s or “Z”s.

    • Some letters may repeat but you should still write down any duplicates. Remember, you need to use every letter that exists in the original anagram.
  3. Image titled Solve Anagrams Effectively Step 7

    3

    Use the alphabetized anagram to solve the puzzle. Just by rearranging an anagram into a jumbled yet ordered list, you can begin to see prefixes, suffixes, or even small, simple words. Once the letters are in an organized set, you can then also begin to memorize the combinations since alphabetizing is a consistent method of organizing any grouping of letters.

  4. Advertisement

  1. Image titled Solve Anagrams Effectively Step 8

    1

    Organize the letters based on a pattern. Take an anagram and reorganize it. Use a standard such as alphabetizing to create a ‘base set’ of letters from the anagram. Alphabetizing an anagram makes a base set of letters because regardless of how the letters are scrambled, they can always be put back in the same order based on that “A-Z” standard.

  2. Image titled Solve Anagrams Effectively Step 9

    2

    Solve as many anagrams as possible based on the base set. You can have anagrams that appear to be different, but if you alphabetize “drife” and “ifred,” you get “defir” as a base set for both. From the base set of letters “defir,” you can create “fried” and “fired.” Memorize the alphabetized base sets and the different words you can make from it.[5]

    • If you play word games like Scrabble or Words With Friends, then you might see familiar combinations of letters over time.
    • Memorizing anagram combinations will train you to see patterns in random letter combinations. It will help you solve crossword puzzles or word games faster.
  3. Image titled Solve Anagrams Effectively Step 10

    3

    Revisit the same anagrams often. You want to be able to recognize basic combinations of letters anywhere. Make flashcards or reread your notebook full of anagrams to commit to memory the ones you’ve solved. Practice often to get into the habit of unscrambling anagrams so that you become more efficient at solving them in the future.

  4. Advertisement

Add New Question

  • Question

    What is the opposite of an anagram?

    Daphthecat

    Daphthecat

    Community Answer

    A kangaroo word, a word that contains other words within it without rearranging letters (but being able to ignore letters). For example, encourage contains the words courage, age, cur, enrage, etc.

  • Question

    What is an anagram of «raced»?

    Donagan

    CARED, CEDAR, and ARCED. (The latter is one spelling of the past-tense of «arc.»)

  • Question

    Where did the word anagram stem from?

    Donagan

    «Ana» (or «backwards») + «gram» (or «letter»).

See more answers

Ask a Question

200 characters left

Include your email address to get a message when this question is answered.

Submit

Advertisement

Video

  • When you’re really stumped on an anagram, there are several websites that can help unscramble things for you. Sometimes you need to see the answer so that you can work backwards.[6]

  • Purchase a book of anagrams for more practice. These should be available at your local bookstore or online.[7]

  • You can explore new anagrams and expand your knowledge by using foreign languages.

Show More Tips

Thanks for submitting a tip for review!

Advertisement

Things You’ll Need

  • pencil or pen
  • notebook
  • a dictionary or thesaurus

References

About This Article

Article SummaryX

To solve anagrams, rearrange the given letters to uncover hidden words or phrases. Try reorganizing the letters into a recognizable pattern or rearrange them into new groupings to give you a fresh perspective. For example, draw a shape, like a circle, and write the letters around it. You can also try putting letters into common pairings. For instance, the letter “H” is usually found at the beginning of a word or after the letters “S,” “T,” or “W.” Picking out prefixes and suffixes can also help you isolate pairings, so look for common pairings like “un,” “dis,” “ly,” or “ment.” Another way to solve anagrams is to put the letters into alphabetical order to help you see small, simple words, prefixes, or suffixes. To learn how to memorize anagram combinations, keep reading!

Did this summary help you?

Thanks to all authors for creating a page that has been read 210,404 times.

Reader Success Stories

  • Xavier Goh

    «I was wondering how to solve anagrams after reading The Da Vinci Code. Thanks.»

Did this article help you?

# list of words
words = ["ROOPA","TABU","OOPAR","BUTA","BUAT" , "PAROO","Soudipta",
        "Kheyali Park", "Tollygaunge", "AROOP","Love","AOORP",
         "Protijayi","Paikpara","dipSouta","Shyambazaar",
        "jayiProti", "North Calcutta", "Sovabazaar"]

#Method 1
A = [''.join(sorted(word)) for word in words]

dict ={}

for indexofsamewords,samewords in enumerate(A):
    dict.setdefault(samewords, []).append(indexofsamewords)
    
print(dict)
#{'AOOPR': [0, 2, 5, 9, 11], 'ABTU': [1, 3, 4], 'Sadioptu': [6, 14], ' KPaaehiklry': [7], 'Taeggllnouy': [8], 'Leov': [10], 'Paiijorty': [12, 16], 'Paaaikpr': [13], 'Saaaabhmryz': [15], ' CNaachlortttu': [17], 'Saaaaborvz': [18]}

for index in dict.values(): 
    print( [words[i] for i in index ] )
    

The Output :

['ROOPA', 'OOPAR', 'PAROO', 'AROOP', 'AOORP']
['TABU', 'BUTA', 'BUAT']
['Soudipta', 'dipSouta']
['Kheyali Park']
['Tollygaunge']
['Love']
['Protijayi', 'jayiProti']
['Paikpara']
['Shyambazaar']
['North Calcutta']
['Sovabazaar']

На этот раз будем изучать задачу «Проверка анаграмм» («Verify Anagrams»).

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

Анаграмма — это игра со словами, когда в результате перестановки букв слова или фразы получаем другое слово или фразу. Два слова являются анаграммами, если мы можем получить одно из другого переставляя буквы местами. Даны два слова или фразы, и ваша задача — проверить, являются ли они анаграммами.

Считаем буквы

Итак, нам нужно сравнить две фразы. Для начала нам нужно их «обработать»: выбрать только буквы и перевести их в нижний регистр. Также, на этом шаге мы можем преобразовать строку в массив. Вынесем эту процедуру в отдельную функцию.

def sanitize(text):
    return [ch.lower() for ch in text if ch.isalpha()]

Или, если вы бережете память и предпочитаете генераторы:

def sanitize(text):
    yield from (ch.lower() for ch in text.lower() if ch.isalpha())

Или любите функциональный стиль программирования:

sanitize = lambda t: map(str.lower, filter(str.isalpha, text))

Далее нам нужно сосчитать каждую букву в тексте, и, если количественные характеристики проверяемых слов/фраз совпадают, то они анаграммы. Предположим, что мы используем только английские буквы. Тогда мы можем использовать массив из 26 элементов для ведения счета.

def count_letters(text):
    counter = [0] * 26
    for ch in text:
        counter[ord(ch) - ord("a")] += 1
    return counter

Честно говоря, это выглядит как код написанный на С, но никак не на Python. Кроме того, мы привязаны жестко к английскому алфавиту. Давайте заменим список на словарь (dictionary).

def count_letters(text):
    counter = {}
    for ch in text:
        counter[ch] = counter.get(ch, 0) + 1
    return counter

Уже лучше, но известный девиз Python гласит — «Батарейки прилагаются». И класс Counter дает возможность просто подсчитать буквы в тексте.

from collections import Counter

def count_letters(text):
    return Counter(text)

Думаю, вы и сами видите, что наша отдельная функция count_letters уже не так уж и нужна, и итоговое решение можно записать так:

from collections import Counter

def sanitize(text):
    yield from (ch.lower() for ch in text.lower() if ch.isalpha())

def verify_anagrams(first, second):
    return Counter(sanitize(first)) == Counter(sanitize(second))

Сортируем все подряд

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

def verify_anagrams(first, second):
    return "".join(sorted(first.lower())).strip() == "".join(sorted(second.lower())).strip()

Как можно заметить, мы одним движением руки можем преобразовать эту функцию в однострочник (забавы ради):

verify_anagrams=lambda f,s,p=lambda x: "".join(sorted(x.lower())).strip():p(f)==p(s)

Вот такая вот история об анаграммах.

Спасибо CheckiO за интересную задачу.

Понравилась статья? Поделить с друзьями:
  • Как найти медиану цены
  • Как исправить затяжку на трикотаже
  • Как составить цифры в головоломки
  • Как найти влажность воздуха физика 8 класс
  • Как найти все хобби