1

how can I make it better? is there any algorithm/method to make it better and shorter?

def sub_string_finder(string):
    given_string = string.upper()
    substring_of = []
    length = len(given_string)
    # find all substring and put it in substring array
    for i in range(length):
        for j in range(i + 1, length + 1):
            substring_of.append(given_string[i:j])
    return substring_of


s = input("Enter a string: ")
print(f"Number of substring: {len(sub_string_finder(s))}")
print(sub_string_finder(s))

Output for "developer":

Number of substring: 45
['D', 'DE', 'DEV', 'DEVE', 'DEVEL', 'DEVELO', 'DEVELOP', 'DEVELOPE', 'DEVELOPER', 'E', 'EV', 'EVE', 'EVEL', 'EVELO', 'EVELOP', 'EVELOPE', 'EVELOPER', 'V', 'VE', 'VEL', 'VELO', 'VELOP', 'VELOPE', 'VELOPER', 'E', 'EL', 'ELO', 'ELOP', 'ELOPE', 'ELOPER', 'L', 'LO', 'LOP', 'LOPE', 'LOPER', 'O', 'OP', 'OPE', 'OPER', 'P', 'PE', 'PER', 'E', 'ER', 'R']

Update

This is the final answer until now using itertools and combinations, Thanks to the respondents. To increase readability we can use line break. Remember that Python allows line breaks between brackets and braces.

from itertools import combinations


def sub_string_finder(string):
    substring_of = [
    string.upper()[i:j] 
    for i, j in combinations(range(len(string) + 1), r=2)
]
    return substring_of

If you are interested in learning about Python List Comprehensions, you can chek this.

Farshad
  • 337
  • 2
  • 9
  • 1
    As for alghorithm itself you might read https://stackoverflow.com/questions/2560262/generate-all-unique-substrings-for-given-string though note that is about bit different task (finding all *unique* substrings of string) – Daweo Dec 15 '19 at 09:53
  • What should be the output for input `aaaa`? – norok2 Dec 15 '19 at 09:55
  • input == "aaaa", output == ['A', 'AA', 'AAA', 'AAAA', 'A', 'AA', 'AAA', 'A', 'AA', 'A'] – Farshad Dec 15 '19 at 10:37

2 Answers2

1

You can write the nested loop as one line. You can also skip the check != "" if you start the second inner from i + 1

def sub_string_finder(string):
    given_string = string.upper()
    length = len(given_string)
    substring_of = [given_string[i:j] for i in range(length) for j in range(i + 1, length + 1)]

    return substring_of

Or using combinations from itertools

substring_of = [given_string[i:j] for i, j in combinations(range(len(given_string) + 1), r=2) if given_string[i:j] != ""]
Guy
  • 46,488
  • 10
  • 44
  • 88
1

A little bit shorter, based on the @Guy suggestion (without itertools):

def sub_string_finder(string):
    substring_of = [string.upper()[i:j] for i in range(len(string)) for j in range(i + 1, len(string) + 1)]
    return substring_of
timanix
  • 94
  • 1
  • 3