例如我们得到了字符串" Number"长度为5(n = 5),由1到a的所有数字组成(数字可以重复,但是从1到a的所有数字必须包含在字符串中,字符串的长度必须为n)。让我们说a = 2并用先前给定的条件生成示例性数字(或者更确切的数字序列),让它成为" 12211"长度为5,由一个和两个组成。现在让我们假设我们需要找到一个算法,它将在我们的字符串中找到所有可能的数字序列" Number"其中每个序列都是" Number"的子串,每个序列具有不同的长度,可能只包含一个任何数字的出现。
对于我们的例子" 12211"我们可以说有7个序列:
1. "1"
2. "12"
3. "2"
4. "2"
5. "21"
6. "1"
7. "1"
结果将是" 7"。
另一个清晰的例子:" Number" =" 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"。
你对快速算法有什么想法吗?我提出的那个太慢了(比较每一个数字)。
答案 0 :(得分:1)
将布尔表设为一个集合(在第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;
}
你应该添加任何间隔的大小,因为你只需在末尾添加新元素,所有子字符串都是正确的(没有2个相同的字符),并且所有子字符串都没有考虑。它是seq [0:q]中最大的唯一子串,带有seq [q],所以它是正确的。
答案 1 :(得分:0)
查看Longest common subsequence problem,查看“阅读所有LCS”部分,并巧妙地使用矩阵,您将获得所需的一切。
答案 2 :(得分:0)
int count(std::string seq, int len) {
int sum = 0;
bool elem[256] = {0};
int i = 0, j = 0;
while ( i < len ) {
while ( !elem[seq[j]] && j < len) {
elem[seq[j]] = true;
j++;
}
sum += j - i;
elem[seq[i]] = false;
i++;
}
return sum;
}
我无法想到比这更有效的解决方案。祝你好运。