例如,我们得到长度为5(n=5)的字符串“number”,它由从1到a的所有数字组成(数字可以重复,但从1到a的所有数字必须包含在字符串中,并且字符串的长度必须为n)。假设a=2,并用先前给定的条件生成示例数字(或者更确切地说是数字序列),设其为“12211”,长度为5,由1和2组成现在假设我们需要找到一个算法,在字符串“Number”中找到所有可能的数字序列,其中每个序列都是“Number”的子串,每个序列的长度不同,可能只包含任何数字的一次出现。
对于我们的示例“12211”,我们可以说有7个序列:

1.    "1"
2.    "12"
3.    "2"
4.    "2"
5.    "21"
6.    "1"
7.    "1"

结果将是“7”。
另一个清晰的例子是:对于“数字”=“123452”和B=5(数字是1,2,3,4,5),可能的序列是:
1.    "12345"
2.    "1234"
3.    "123"
4.    "12"
5.    "1"
6.    "2345"
7.    "234"
8.    "23"
9.    "2"
10.   "3452"
11.   "345"
12.   "34"
13.   "3"
14.   "452"
15.   "45"
16.   "4"
17.   "52"
18.   "5"
19.   "2"

结果将是“19”。
你对快速算法有什么想法吗?我想到的那个太慢了(比较每个数字)。

最佳答案

将布尔表设为集合(在第n个元素中为true表示n在实际间隔中)
现在很容易了。您只需遍历数组并扩展间隔,当您找到重复的元素时,只需移动间隔的开始部分,直到达到唯一的序列。
一些更好的解释代码:

unsigned long long number_of_seq(string seq) {
  set<char> in_use; //Can be some O(1) set, pointless
  unsigned long long result = 0ULL;
  //p - begin of actual interval
  //q - end of this interval
  for(size_t p = 0, q = 0; q < seq.size();) {
       while(in_use.count(seq[q]) != 0) { //While: add seq[q] makes interval not unique
            in_use.erase(seq[p]);
            ++p; //move begin of interval
        }
       in_use.insert(seq[q]);
       ++q;
       result += q - p; //add size of interval
   }
  return result;
 }

您应该添加任何间隔的大小,因为您只需在末尾添加新元素,所有子字符串都是正确的(没有两个相同的字符),并且考虑所有没有新字符的子字符串它是seq[0:q]和seq[q]中最大的唯一子串,所以它是正确的。

10-08 08:27
查看更多