你好,
我試圖找到一個公式來計算字母在序列中連續重複的最高次數。 我附上了一個示例,其中我嘗試為 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
看到其他解決方案將會很有趣。