Проверка строк друг против друга (анаграммы)

назначение состоит в том, чтобы написать программу, которая принимает две группы слов от пользователя, а затем печатает оператор "True", если эти две анаграммы (или, по крайней мере, если все буквы одного присутствуют в другом) и оператор "False", если нет.

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

s1 = input("Please enter a word:")
s2 = input("Please enter another word:")

for i in range(0, len(s1), 1):
    if i in range (0, len(s2), 1):
        print("The letters in your first word are present in your second word.")

14 ответов


вам нужно подумать над своей условной логикой немного больше. Цикл находится на правильном пути, но если в s1 есть буква, которая не находится в s2, вы должны break из этого цикла и распечатайте оператор "False". Рассмотрите возможность использования переменной типа all_s1_in_s2 = True а затем установите значение false, если вы найдете букву, которая не соответствует.

несколько советов:

  • for l in s1 будет петля через строку s1, давая вам доступ к каждой букве в последовательности, как l - вы не нужны range или len на всех

  • на if .. in оператор может помочь проверить, существует ли буква в строке, например if letter in mystring: является действительным заявлением, и это может помочь вам много, снова не нуждаясь range или len

  • вы должны избегать использования чисел в именах переменных, где это возможно-лучше было бы word_one и word_two, например


почему бы просто не отсортировать строки?

>>> sorted('anagram')
['a', 'a', 'a', 'g', 'm', 'n', 'r']
>>> sorted('nagaram')
['a', 'a', 'a', 'g', 'm', 'n', 'r']
>>> sorted('anagram') == sorted('nagaram')
True

вы можете использовать магию счетчик С коллекции библиотека. Из документации:

это неупорядоченная коллекция, в которой элементы хранятся как ключи словаря, а их количество хранится как значения словаря

таким образом, Вы можете инициализировать объект счетчика строкой (итерацией) и сравнить с другим счетчиком из строки

from collections import Counter

def is_anagram(str1, str2):
   return Counter(str1) == Counter(str2)

def is_anagram(w1, w2):
    w1, w2 = list(w1.upper()), list(w2.upper())
    w2.sort()
    w1.sort()
    return w1 == w2

>>> s1 = 'vivid'
>>> s2 = 'dvivi'
>>> s3 = 'vivid'
>>> def is_anagram(s1, s2):
...     if s1.lower() == s2.lower():
...         return False
...     return sorted(s1.lower()) == sorted(s2.lower())
...
>>> is_anagram(s1, s2)
True
>>> is_anagram(s1, s3)
False
>>> s2 = 'dvivii'
>>> is_anagram(s1, s2)
False
>>> s2 = 'evivi'
>>> is_anagram(s1, s2)
False
>>> 

это сработало для меня

str1="abcd"
str2="bcad"
word1=[]
word2=[]
for x in range(len(str1)):
    word1.append(str1[x])
for x in range(len(str2)):
    word2.append(str2[x])
if(len(word1)==len(word2)):
    for letter in word1:
        if letter in word2:
            word2.remove(letter)

if len(word2)==0:
    print "anagram"
else:
    print "not anagram"

чтобы проверить, являются ли две строки анаграммами друг друга, используя словари: Примечание: четное число, специальные символы могут быть использованы в качестве входных

def anagram(s):
    string_list = []
    for ch in s.lower():
        string_list.append(ch)

    string_dict = {}
    for ch in string_list:
        if ch not in string_dict:
            string_dict[ch] = 1
        else:
            string_dict[ch] = string_dict[ch] + 1

    return string_dict



s1 = "master"
s2 = "stream"

a = anagram(s1)
b = anagram(s2)

if a == b:
    print "Anagram"
else:
    print "Not Anagram"

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

text = input('Enter a string: ')
text1 = input('Enter a string: ')
text,text1 = text.lower(),text1.lower()
count = 0
count1=0
for i in range(97,123):
    if chr(i) in text and chr(i) in text1:
    count1+=1
        if text.count(chr(i)) == text1.count(chr(i)):
             count +=1
if len(text) >= len(text1):
    num1 = len(text)
else:
    num1 = len(text1)
if count == count1:
    print("they are anagrams")
else :
    print("they are not anagrams")

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

создайте словарь, используя понимание и сравните словари двух слов с простым == оператора.

def isanagram2(wrd1, wrd2):

    wrd1_dict = {k: 0 for k in wrd1}
    wrd2_dict = {k: 0 for k in wrd2}

    for c1, c2 in zip(wrd1, wrd2):
        wrd1_dict[c1] += 1
        wrd2_dict[c2] += 1

    if wrd1_dict == wrd2_dict:
        return True
    return False

просто мысль:

def check_(arg):
        mark = hash(str(set(sorted(arg))))
        return mark

def ana(s1, s2):
        if check_(s1) != check_(s2):
                pass
        elif len(s1) != len(s2):
                pass
        else:
             print("{0} could be anagram of  {1}".format(s1, s2))

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

один хороший способ увидеть, являются ли два слова или предложения анаграммами, - установить массив счетчиков размером 256 и изначально установить все значения в 0. (Это может быть хорошим вариантом, если вход больше, по крайней мере, чем несколько слов) теперь начните читать первую строку (слово или предложение) и увеличьте ее соответствующее местоположение ASCII в массиве на единицу. Повторите это для полной строки. Теперь начните читать вторую строку и продолжайте уменьшать соответствующий счетчик ASCII каждой буквы в массиве. Наконец, проанализируйте массив; если все значения равны нулю, то входы были анаграммами, иначе нет. Ниже приведен код с комментариями для лучшего понимания.

#include<iostream>
#include<string>

using namespace std;

bool is_anagram(string s1, string s2)
{
    //Following statement chechs the base condition; if either of the strings is empty,                                  
    //return False
    if(s1.length() == 0 || s2.length() == 0)
        return false;

    //initializing the counter array and setting it's values to 0
    int counter[256] = {0};

    //Calculating the lengths of both the strings
    int len1 = s1.length();
    int len2 = s2.length();

    //Following is also a base condition that checks whether the strings are equal in 
    //length, if not we return False
    if(len1 != len2)
        return false;

    //Following for loop increments the values of the counter array for the first  
    //string
    for(int i = 0; i < len1; i++)
    {
        counter[s1[i]]++;
    }

    //This for loop decrements the values of the counter array for the second string
    for(int i = 0; i < len2; i--)
    {
        counter[s2[i]]--;
    }
    //Now we check whether the counter array is empty/(or as it was initialized); if               
    //yes then the two strings are anagrams
    for(int i = 0; i < 256; i++)
    {
        if(counter[i] != 0)
            return false;
    }

    return true;
}

    #An anagram is the result of rearranging the letters of a word to produce a new word. Anagrams are case insensitive
    #Examples:
    # foefet is an anagram of toffee
    # Buckethead is an anagram of DeathCubeK

    # The shortest my function style *************************************** 
    def is_anagram1(test, original):
        """Сhecks 'test' is anagram of 'original' strings based on:
        1. length of the both string and length of the sets made from the strings is equivalent
        2. then checks equivalents of sorted lists created from test and original strings

        >>> is_anagram1('Same','same')
        False
        >>> is_anagram1('toffee','foeftt')
        False
        >>> is_anagram1('foefet','toffee')
        True
        >>> is_anagram1("Buuckk",'kkkcuB')
        False
        >>> is_anagram1('Buckethead','DeathCubeK')
        True
        >>> is_anagram1('DeathCubeK','Buckethead')
        True
        """
        # check the length of the both string
        if len(test) != len(original):
            return False

        # check is the strings are the same
        t,o = test.lower(), original.lower()
        if t == o:
            return False

        # check the sorted lists
        return sorted(t) == sorted(o)


    # The final my one line code **************************************
    def is_anagram(test, original):
        """Сhecks 'test' is anagram of 'original' in one line of code

        >>> is_anagram('Same','same')
        False
        >>> is_anagram('toffee','foeftt')
        False
        >>> is_anagram('foefet','toffee')
        True
        >>> is_anagram("Buuckk",'kkkcuB')
        False
        >>> is_anagram('Buckethead','DeathCubeK')
        True
        >>> is_anagram('DeathCubeK','Buckethead')
        True
        """
        return False if len(test) != len(original) or test.lower() == original.lower() else sorted(test.lower()) == sorted(original.lower())

    if __name__ == "__main__":
        import doctest
        doctest.testmod(verbose=True)


### 2 items passed all tests:
### 6 tests in __main__.is_anagram
### 6 tests in __main__.is_anagram1
### 12 tests in 3 items.
### 12 passed and 0 failed.
### Test passed

просто другое решение без использования sort:

s1 = "aaabbbccc"
s2 = "abcabcabc"

def are_anagram1(s1, s2):
   return [False, True][sum([ord(x) for x in s1]) == sum([ord(x) for x in s2])]

print are_anagram1(s1,s2)

NB: это работает только для алфавита, а не цифр


Return True отвечает на вопрос "Является ли w2 анаграммой подпоследовательности w1"

объяснение: в приведенном ниже коде мы можем ответить на два вопроса: 1) являются ли две строки анаграммами,2) Если w2 является анаграммой подпоследовательности w1. Мы используем O (1) пространство(константа) и O (n) время. Словарь d0 может быть расширен, чтобы включить любые символы, и мы остаемся в пределах O (1) пространства.

def anagrams(w1,w2):
       d0={chr(i):0 for i in range(ord('a'),ord('z'))}
       for char in w1:
           d0[char]+=1
       for char in w2:
           if d0[char]==0:
               return False
           else:
               d0[char]-=1
    return sum([d0[x] for x in d0])==0 #return True (for subseqence anagram)