Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 需要减少程序的运行时间吗_Python_String - Fatal编程技术网

Python 需要减少程序的运行时间吗

Python 需要减少程序的运行时间吗,python,string,Python,String,我有一个问题,我必须找到字符串的连续子字符串,条件是子字符串的第一个字母和最后一个字母必须相同。我试过这样做,但是运行时超过了几个测试用例的提问时间限制。我尝试对for循环使用map,但不知道如何处理嵌套的for循环。谁能帮我减少这个程序的运行时间 n = int(raw_input()) string = str(raw_input()) def get_substrings(string): length = len(string) list = [] for i in rang

我有一个问题,我必须找到字符串的连续子字符串,条件是子字符串的第一个字母和最后一个字母必须相同。我试过这样做,但是运行时超过了几个测试用例的提问时间限制。我尝试对for循环使用map,但不知道如何处理嵌套的for循环。谁能帮我减少这个程序的运行时间

n = int(raw_input())
string = str(raw_input())
def get_substrings(string):
  length = len(string)
  list = []
  for i in range(length):
    for j in range(i,length):
      list.append(string[i:j + 1]) 
  return list
substrings = get_substrings(string)
contiguous = filter(lambda x: (x[0] == x[len(x) - 1]), substrings)
print len(contiguous)

如果我正确理解了问题,请让我知道如果不是这样,请尝试以下方法:

不确定这是否会加快运行时的速度,但我相信这种算法可能特别适用于较长的字符串(消除嵌套循环)。在字符串中迭代一次,将每个字符的索引(位置)存储在具有恒定时间查找的数据结构中(hashmap或数组,如果设置正确)。完成后,您应该有一个数据结构来存储每个字符的所有不同位置。使用此选项可以轻松检索子字符串

例如:

编码很有趣

以字母i为例,在做了我上面所说的之后,在hashmap中查找它,发现它出现在索引3和索引6处。这意味着您可以执行类似子字符串(3,6)的操作来获得它

虽然不是最好的代码,但它似乎是一个合理的起点……您可以通过一些创造性思维消除循环:

import string
import itertools

my_string = 'helloilovetocode'

mappings = dict()

for index, char in enumerate(my_string):
    if not mappings.has_key(char):
        mappings[char] = list()

    mappings[char].append(index)
    print char

for char in mappings:
    if len(mappings[char]) > 1:
        for subset in itertools.combinations(mappings[char], 2):
            print my_string[subset[0]:(subset[1]+1)]

问题是,就算法复杂性而言,您的代码效率太低

这里有一个替代方案(我相信是索利曼的更干净但稍慢的版本)


解决方案的算法问题在于,当您可以轻松确定单个线性时间过程中的实际对时,盲目地检查每个可能的子串。如果您只需要长度为N和M的唯一字符的字符串的计数,这可以在O(MN)时间内轻松确定(给定字符的出现次数,您可以从数学上计算出有多少子字符串)。当然,在最坏的情况下(所有字符都相同),您的代码的复杂性将与我们的代码相同,但在平均情况下,您的代码的复杂性要差得多,因为您有一个嵌套的for循环(n^2次)

谢谢您的帮助。你能举个例子吗?我是python新手,完全理解hashmaps。字符串中的单个字母怎么样?它们不也是子字符串吗?这种方法可以用于打印单个字母表,即子字符串吗?这是一个简单的修改,在第一个for循环中,在将每个字符添加到字典映射后打印每个字符。我检查了这种方法的计时。它比我的代码花费了更多的时间(大约多0.2秒)。不过,谢谢你的方法。它工作,我喜欢它!如果有更多的方法来减少运行时间,我会很高兴。删除了第一个for循环,这是不必要的。如果您找到更好的方法来获取最终数组中的所有索引组合,则可以消除末尾的嵌套for循环。递归解决方案可能适用于此问题
import collections
def index_str(s):
    """
    returns the indices characters show up at
    """
    indices = collections.defaultdict(list)
    for index, char in enumerate(s):
        indices[char].append(index)
    return indices

def get_substrings(s):
    indices = index_str(s)
    for key, index_lst in indices.items():
        num_indices = len(index_lst)
        for i in range(num_indices):
            for j in range(i, num_indices):
                yield s[index_lst[i]: index_lst[j] + 1]