Python 相互检查字符串(字谜)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14990725/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:01:28  来源:igfitidea点击:

Checking strings against each other (Anagrams)

pythonanagram

提问by Kyle

The assignment is to write a program that accepts two groups of words from the user and then prints a "True" statement if the two are anagrams (or at least if all the letters of one are present in the other) and a "False" statement if not.

作业是编写一个程序,接受来自用户的两组单词,然后如果这两组单词是字谜(或者至少如果一个单词的所有字母都出现在另一个单词中)和一个“False”语句,则打印“True”语句如果不是,则声明。

Being very new to programming as a whole, I don't know how to move beyond just indexing a string and comparing all of the pieces of one to another. I stress that I am a beginner; I've read many of the other posts tagged with Python and Anagram, and they are uniformly above my head and reference things I have not been taught. So the simpler the better. Here is my non-working code so far:

作为一个整体编程的新手,我不知道如何超越仅仅索引一个字符串并将一个字符串的所有部分相互比较。我强调我是初学者;我已经阅读了许多其他用 Python 和 Anagram 标记的帖子,它们都在我的头顶之上,并且引用了我没有学过的东西。所以越简单越好。到目前为止,这是我的非工作代码:

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.")

采纳答案by John Lyon

You need to think through your conditional logic a bit more. The loop is on the right track, but if there is a letter in s1 that is NOT in s2, you should breakout of this loop and print the "False" statement. Consider using a variable like all_s1_in_s2 = Trueand then setting that to false if you find a letter that doesn't match.

您需要多考虑一下您的条件逻辑。循环在正确的轨道上,但是如果 s1 中有一个break不在s2 中的字母,则您应该退出该循环并打印“False”语句。all_s1_in_s2 = True如果发现不匹配的字母,请考虑使用变量 like然后将其设置为 false。

Some other tips:

其他一些提示:

  • for l in s1will loop through string s1 giving you access to each letter in sequence as l- you don't need rangeor lenat all

  • The if .. instatement can help test whether a letter exists in a string, e.g. if letter in mystring:is a valid statement and this could help you a lot, again not needing rangeor len

  • You should avoid using numbers in variable names where possible - better would be word_oneand word_two, as an example

  • for l in s1通过串S1将循环让您访问的每个字母顺序l-你不需要rangelen根本

  • if .. in语句可以帮助测试字符串中是否存在一个字母,例如if letter in mystring:是一个有效的语句,这可以帮助你很多,同样不需要rangelen

  • 您应该尽可能避免在变量名称中使用数字 - 最好是word_oneand word_two,例如

回答by Blender

Why not just sort the strings?

为什么不只是对字符串进行排序?

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

回答by ProB

Anagrams are the two different words formed with same characters: For eg: EAT and TEA likewise there can be numerous examples.

字谜是由相同字符构成的两个不同单词:例如:EAT 和 TEA 同样可以有很多例子。

One good way to see if give two words or sentences are anagrams is to set a counter array of size 256, and initially set all the values to 0. (This can be a good option if the input is bigger, at least than a few words) Now start reading the first string(word or a sentence), and increment its corresponding ASCII location in the array by one. Repeat this for the complete string. Now start reading the second string and keep decreasing the corresponding ASCII counter of each letter in the array. Finally, parse the array; if all the values are zero then the inputs were anagrams otherwise not. Following is the commented code for the better understanding.

查看给出两个单词或句子是否为字谜的一种好方法是设置一个大小为 256 的计数器数组,并将所有值初始设置为 0。(如果输入更大,至少是几个单词)现在开始读取第一个字符串(单词或句子),并将其在数组中对应的 ASCII 位置增加 1。对完整的字符串重复此操作。现在开始读取第二个字符串并不断减少数组中每个字母对应的 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;
}

回答by James Sapam

Just another solution without using 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: this works only for alphabet not numerals

注意:这仅适用于字母而不适用于数字

回答by Shan Valleru

>>> 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
>>> 

回答by Schopenhauer

Just a thought:

只是一个想法:

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))

回答by Niruhan Viswarupan

This worked for me

这对我有用

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"

回答by lborgav

You can use the magic Counterfrom collectionslibrary. From documentation:

您可以使用魔法计数器收藏库。从文档:

It is an unordered collection where elements are stored as dictionary keys and their counts are stored as dictionary values

它是一个无序集合,其中元素存储为字典键,它们的计数存储为字典值

So, you can initialize a Counter object with a string (a iterable) and compare with another Counter from a string

因此,您可以使用字符串(可迭代对象)初始化 Counter 对象并与字符串中的另一个 Counter 进行比较

from collections import Counter

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

回答by kumar22

To check if two strings are anagrams of each other using dictionaries: Note : Even Number, special characters can be used as an input

使用字典检查两个字符串是否互为字谜: 注意:偶数,特殊字符可用作输入

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"

回答by АСTPOHOMOC

    #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