Создание набора строк из строки 0 и 1, где изменяются только два символа (python) - PullRequest
2 голосов
/ 16 апреля 2020

Предположим, у меня есть следующая строка: '0000'

Я хочу создать набор строк, в которых изменяются только два числа (в данном случае от 0 до 1)

Для пример из строки '0000' я получу результат: {'0011', '0101', '0110', '1001', '1010', '1100'}

Вот мой код:

def shift_two(string):
  shift_2 = set()
  for i in range(len(string)):
    if i == len(string) - 1:
      break

    str_temp = list(string)
    if str_temp[i] == '1':
      str_temp[i] = '0'
    else:
      str_temp[i] = '1'

    #copy a string, because list is mutable
    for j in range(i+1,len(string)):
      copy_str = str_temp.copy()

      if copy_str[j] == '1':
        copy_str[j] = '0'
        shift_2.add(''.join(copy_str))
      else:
        copy_str[j] = '1'
        shift_2.add(''.join(copy_str))

  return shift_2

Но, возможно, есть более эффективные способы (и более читабельные) для завершения это задание?

Ответы [ 3 ]

1 голос
/ 16 апреля 2020

Я думаю, что нашел более читаемое (и, вероятно, также более эффективное) решение вашей проблемы:

def flip(letter):
    if letter == '0':
        return '1'
    elif letter == '1':
        return '0'

def shift_two(string):
    permutations = []

    for ind_1 in range(len(string)):
        for ind_2 in range(ind_1+1, len(string)):
            string_list = list(string)
            string_list[ind_1] = flip(string[ind_1])
            string_list[ind_2] = flip(string[ind_2])

            permutations.append(string_list)

    return permutations

и

string = '0000'
shift_two(string)

возвращает список всех требуемых перестановок.

1 голос
/ 16 апреля 2020

Вот вариант, который использует [Python 3.Docs]: itertools - Функции создания итераторов для эффективного зацикливания .

code00.py :

#!/usr/bin/env python

import sys
import itertools as it


def replace(s, replacements):
    if len(s) < len(replacements):
        return s
    base = s[:-len(replacements)] + "".join(replacements)
    return sorted(set("".join(i) for i in it.permutations(base, len(base))))


def main(*argv):
    s = "0000"
    repls = ("1", "1")
    l = list(replace(s, repls))
    print(l)


if __name__ == "__main__":
    print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    main(*sys.argv[1:])
    print("\nDone.")

Выход :

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q061258915]> "e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32

['0011', '0101', '0110', '1001', '1010', '1100']

Done.
1 голос
/ 16 апреля 2020

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

def shift_two(string, index, shiftSet):
    string = list(string)
    if (string.count('1') < 2 and index < len(string)):
        shift_two("".join(string), index + 1, shiftSet)
        string[index] = "1"
        shift_two("".join(string), index + 1, shiftSet)
    else:
        if (string.count('1') == 2):
            shiftSet.add("".join(string))

shiftSet = set()
shift_two("0000", 0, shiftSet)
print(shiftSet)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...