我们的字符串Seq
的大小为N
,并且包含z
字母{A,B,C ......}。
我必须执行一个函数来计算字母i
的出现次数,该字母用l
字母(间隙)与字母j
分隔:
例如:
I=A, j=T and gap=10
That have to find the number of occurrence of AT,A-T,A--T,A---T,A----T,,,A---------T(- is any alphabet)
我将此代码用于DNA序列(字母z
= 4)并假设为N(L * N)
复杂性:
inline const short int V (const char x){
switch(x){
case 'A':case 'a':
return 0;
break;
case 'C':case 'c':
return 1;
break;
case 'G':case 'g':
return 2;
break;
default:
return 3;
break;
}
}
// [[Rcpp::export]]
IntegerVector basem(std::string seq ,int gap ,int N){
IntegerVector res(16);
short int x=0;
short int y=0;
for(int i=0;i<N-gap;i++){
x=V(seq[i]);
y=V(seq[i+gap]);
res[4*x+y]++;
}
return res;
}
// [[Rcpp::export]]
List basegap (std::string sequence,int x){
int n=sequence.size();
List result ;
for(int j=1;j<x;j++) {
result.push_back(basem(sequence,j,n));
}
return result;
}
basem:计算间隙的出现次数
basegap:计算从1到X
的间隙的出现次数
运行示例:
a
[1] "atgccatcactcagtaaagaagcggccctggttcatgaagcgttagttgcgcgaggactggaaacaccgctgcgcccgcccgtgcatgaaatggataacgaaacgccgaaaagccttattgctggtcatatgaccgaaatcatgcagctgctgaatctcgacctggctgatgacagtttgatggaaacgcggcatcgcatcgctaaaatgtatgtcgatgaaattttctccggtctggattacgccaatttcccgaaaatcaccctcattgaaaacaaaatgaaggtcgatgaaatggtcaccgtccgcgatatcactctgaccagcacctgtgaacaccattttgttaccatcgatggcaaagcgacggtggcctatatcccgaaagattcggtgatcggtctgtcaaaaattaaccgcattgtgcagttctttgcccagcgtccgcaggtgcaggaacgtctgacgcagcaaattcttgttgccgcgctacaaacgctgctgggcaccaataacgtggctgtctcgatcgacgcggtgcattactgcgtgaaggcgcgtggcatccgcgatgcaaccagtgccacgacaacgtcctctcttggtggattgttcaaatccagtcagaatacgcgccacgagtttctgcgcgctgtgcgtcatcacaactga"
basem(a,5,nchar(a))
[1] 40 50 42 37 47 46 36 49 45 39 44 39 38 42 45 28
x<-basegap(a,10)
[[1]]
[1] 61 38 23 48 48 39 57 35 44 58 28 38 17 44 60 33
[[2]]
[1] 42 47 43 38 42 49 53 35 44 44 35 44 42 39 37 36
[[3]]
[1] 50 39 44 37 35 53 44 47 46 41 47 33 39 46 32 36
[[4]]
[1] 42 54 36 38 54 36 52 36 43 49 41 34 31 39 38 45
[[5]]
[1] 40 50 42 37 47 46 36 49 45 39 44 39 38 42 45 28
[[6]]
[1] 42 44 40 42 45 44 44 45 38 44 47 38 44 45 36 28
[[7]]
[1] 38 44 44 42 44 49 42 42 40 44 42 41 47 40 39 27
[[8]]
[1] 34 48 47 38 46 49 41 41 47 39 39 42 42 40 40 31
[[9]]
[1] 43 37 45 42 40 46 56 34 45 57 33 32 40 36 33 44
m<-matrix(unlist(x),nrow=16)
m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 61 42 50 42 40 42 38 34 43
[2,] 38 47 39 54 50 44 44 48 37
[3,] 23 43 44 36 42 40 44 47 45
[4,] 48 38 37 38 37 42 42 38 42
[5,] 48 42 35 54 47 45 44 46 40
[6,] 39 49 53 36 46 44 49 49 46
[7,] 57 53 44 52 36 44 42 41 56
[8,] 35 35 47 36 49 45 42 41 34
[9,] 44 44 46 43 45 38 40 47 45
[10,] 58 44 41 49 39 44 44 39 57
[11,] 28 35 47 41 44 47 42 39 33
[12,] 38 44 33 34 39 38 41 42 32
[13,] 17 42 39 31 38 44 47 42 40
[14,] 44 39 46 39 42 45 40 40 36
[15,] 60 37 32 38 45 36 39 40 33
[16,] 33 36 36 45 28 28 27 31 44
我的问题是:
答案 0 :(得分:0)
这可以在O(N log N).
中完成。算法如下:
以排序方式存储每个字母i
的索引。 O(N)
对于每个带有字母j
的索引,二进制搜索范围中字母i
的索引数。 O(N log N)
在C ++中,这可以通过减去迭代器来完成。例如,在1次迭代中:
vector<int> indices; <- Store indices of letter i
int index; <- Index of a letter j
vector<int>:iterator it1 = upper_bound(indices.begin(),indices.end(),index+L); <- Position just above the last index
vector<int>:iterator it2 = lower_bound(indices.begin(),indices.end(),index-L); <- Position at or below the first index
int num = it1 - it2; <- number of indices with the letter i in the range
对于其他语言,可能还有其他方法可以做到这一点,但由于我不熟悉不同的编程语言,我只能给出一个C ++示例。基本上你想用较小的索引减去较大的索引。
您可能还想查找binary search的其他一些应用程序。
答案 1 :(得分:0)
你可以使用队列数据结构在O(N)时间内找到这样的对的数量(在范围&lt;间隙中的A之后的T)
Run through you string.
When you meet A, add it's position to queue
When you meet T, add queue size to result
If queue head <= current_position - gap
remove head