简体   繁体   中英

Finding the unique string within an list of strings

I have managed to solve this exercise from the codewars website using the following code

def find_uniq(arr):
    diff = None
    first = None
    for s in arr:
        if first is None:
            first = s
            continue

        if (len(first) in [0, 1]) and (len(s) in [0, 1]):
            if arr.count(first) == 1:
                return first
            elif arr.count(s) == 1:
                return s

        temp = set(first.lower()).difference(set(s.lower()))
        if temp:
            diff = s

        if diff is not None:
            temp = set(diff.lower()).difference(set(s.lower()))
            return first if temp else diff

My code passes all their unit tests but problem is when I try it using the following custom unit test, it fails

test.assert_equals(['foo', 'abc', 'acb', 'bac', 'bca', 'cab', 'cba dab'], 'foo')  # fails, returns 'abc'

The exercise is a follows:

There is an array / list of strings. All strings contains similar letters except one. Try to find it!

and rules are:

  • Strings may contain spaces. Spaces is not significant, only non-spaces symbols matters. Eg string that contains only spaces is like empty string.

  • It's guaranteed that array / list contains more than 3 strings.

Any suggestions on how this can be improved to handle such cases or even just general improvement of the function overall.

Thank you.

Calling the list.count method in a loop is inefficient. You can instead use a dict keep track of the unique sets of characters you have iterated through so far. Make the set of characters the string minus the space the key of the dict, the string itself the value. If the current key is already in the dict, you would then know that the key is not unique. The task then becomes to find the key that is different from this common key. If there already is a different key in the dict, then return the value of that different key. If not, keep iterating until you get a key that's different from the known common key:

def find_uniq(arr):
    seen = {}
    common = None
    for string in arr:
        key = frozenset(set(string.lower()).difference(' '))
        if key in seen:
            common = key
        if common is not None:
            if key != common:
                return string
            if len(seen) > 1:
                del seen[common]
                return next(iter(seen.values()))
        seen[key] = string

so that the following expressions will all be True :

find_uniq(['foo', 'abc', 'acb ']) == 'foo'
find_uniq(['abbc', 'foo', 'acb ']) == 'foo'
find_uniq(['abc', 'acb ', 'foo']) == 'foo'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM