你好,
我试图找到一个公式来计算字母在序列中连续重复的最高次数。 我附上了一个示例,其中我尝试为 Poly Ts 列编写公式,它将连续生成序列中的 Ts 计数。

谢谢你,
普拉蒂什
本着“其他解决方案”的精神,这是另一个强力解决方案:
NamesDefaultToHere(1);
// Given a string and a single character, finds the longest sequence of that character
// and returns the length and starting position of that sequence. If the sequence
// occurs more than once, only the first is identified
findLongestRepeatedCharacter =
Function({str, char}, {Default Local},
n = Length(str);
count = 0;
currentCount = 1;
// Traverse the string except for the last character
for (i = 1, i <= n-1, i++,
thisChar = Substr(str, i, 1);
nextChar = Substr(str, i+1, 1);
// If the current character and the next are both 'char' ...
if((thisChar == char & nextChar == char),
// ... increment 'currentCount'
currentCount++,
// ... else if they're not ...
if(currentCount > count,
// ... record 'currentCount' if it's bigger than we've seen so far
count = currentCount;
);
// ... and reset 'currentCount'
currentCount = 1;
);
);
// Build the sequence we've found
seq = Repeat(char, count);
// Find where it occurs
pos = Munger(str, 1, seq);
// Return the results
if (pos == 0,
EvalList({0, pos}),
EvalList({count, pos})
);
);
// Try it out
str = "(N1:25252525)AACCAA(N1)GACGTTAACAGTTCTTTG";
Print(findLongestRepeatedCharacter(str, "T"));
Print(findLongestRepeatedCharacter(str, "A"));
Print(findLongestRepeatedCharacter(str, "X"));使用 ShortestEditScript() 的表公式在本应是序列的公式部分中使用了 s2。 附有修正后的功能表。
这是一个简单的暴力方法;不确定相对于的性能@gzmorgan0的方法。
s2 = "(N1:25252525)AACCAA(N1)GACGTTAACAGTTCTTTG";
len = length(s2);
tstring = repeat("T", len);
maxlen = 0;
for (i = len, i >= 1, i--,
if (contains(s2, tstring),
maxlen = i;
break();
,
tstring = substr(tstring, 2);
);
);
show(maxlen);正则表达式专家可能有一个很好的模式来扫描和查找所有匹配项,但这超出了我的正则表达式技能范围。
我提供了两种可以使用列公式完成的解决方案。 两者可能都需要一些解释。
第一个使用嵌套字符函数,第二个使用 ShortestEditScript() 函数。 顺便说一句,您没有指定是否计算 (N1) 之前的 T 序列,两者都使用整个字符串。 附上示例表,解释如下

假设 s2 = "(N1:25252525)AACCAA(N1)GACGTTAACAGTTCTTTG";
字符函数:Words()、Sort List()、Reverse()、list[n]、Length()
Length(Reverse(Sort List(words(s2,"ACGN():0123456789")))[1]);
这是各个函数的日志输出
//:*/
words(s2,"ACGN():0123456789")
/*:
{"TT", "TT", "TTT"}
//:*/
Reverse(Sort List(words(s2,"ACGN():0123456789")))
/*:
{"TTT", "TT", "TT"}
//:*/
Reverse(Sort List(words(s2,"ACGN():0123456789")))[1]
/*:
"TTT"
//:*/
Length(Reverse(Sort List(words(s2,"ACGN():0123456789")))[1]);
/*:
3ShortestEditScript() 是一个有趣的函数。 脚本9_Extra_ShortestEditDistance.jsl写给JSL Companion,JMP 脚本语言的应用程序第二版记录了使用这一强大而有用的功能的 4 种不同方法。对于此示例,我使用 Sequnces() 并请求矩阵输出。 在这个论坛中完整地记录这一点需要太多的空间,所以我将只展示结果并添加一些评论。
msed = Shortest Edit Script( Strings(s2, Repeat("T",length(s2)),matrix(1)) );
maximum(msed[loc(msed[0,1]==0),4]);被比较的两个字符串是 s2 和由函数 Repeat("T", length(s2) ) 创建的所有 T 的字符串。
msed = Shortest Edit Script( Strings(s2, Repeat("T",length(s2)),matrix(1)) );
/*:
[-1 1 . 27,
0 28 1 2,
-1 30 . 5,
0 35 3 2,
-1 37 . 1,
0 38 5 3,
-1 41 . 1,
1 . 8 34]
/* The matrix output n x 4 where n = nrow(msed)
Column1: -1 | 1| 0 -1-->remove, 1-->insert, 0-->common
Column2: position in the 1st string .-->missing / not found
Column3: position in the 2nd string .-->missing / not found
Column4: length
*/所以现在需要找到矩阵第一列中 0 的位置(匹配/公共/T),这可以使用 loc() 函数来完成。 那么匹配序列的长度就在第4列,所以只要找到最大值就可以了。注意 msed[0,1] 代表矩阵 msed 的第一列。
loc(msed[0,1]==0)<BR />/*:<BR />[2, 4, 6] <BR />//:*/<BR />msed[loc(msed[0,1]==0),4]<BR />/*:<BR />[2, 2, 3]<BR />//:*/<BR /> maximum(msed[loc(msed[0,1]==0),4]);<BR />/*:<BR />3
看到其他解决方案将会很有趣。