我被分配了一项任务,以编写一种算法来检测给定的字符串数组是否包含水平,垂直或对角线的4个重复字母的多个序列。他们还问我最有效的方法。
一个输入示例将是这样的:
String[] input = {"ATGCGA","CAGTGC","TTATGT","AGAAGG","CCCCTA","TCACTG"};
但是你们可以在这里像桌子一样清楚地看到它:
A T G C G A
C A G T G C
T T A T G T
A G A A G G
C C C C T A
T C A C T G
此数组包含3个重复字母的序列:
对角线发现AAAA CCCC水平找到 垂直找到GGGG
因此,由于在此输入示例中找到了多个序列,因此输出应为true。
我有一个解决此问题的想法,但是我的主要问题是处理对角线,特别是使用一种有效的方法来解决这个问题,因为他们希望在高并发环境中使用此功能。
对于提供的任何帮助,我将不胜感激。可以,但不能写代码,但至少要有一些想法才能找到解决此问题的正确方法。
我已经很感激!
答案 0 :(得分:1)
我认为您最好的选择是首先分析问题。
确定什么是对角线。在这种情况下,当遍历对角线时,行索引和列索引都增加1。
接下来,您必须执行一些规则。基于对角线长度4,有一个最大的行/列位置,任何对角线都可以从该位置开始。为了提高效率,您只应遍历可能导致匹配的索引。
为了直观地说明这一点,矩阵中所有这些X位置都可能是重复序列的开始:
X X X O O O
X X X O O O
X X X O O O
O O O O O O
O O O O O O
O O O O O O
因此,对于具有36个字符的6x6矩阵,我们最多只看9条长度为4的对角线。
现在我们只是满足长度要求的对角线,下一步就是简单地沿着对角线走,然后将每个下一个值与起始值进行比较。为了进一步提高效率,我们可以在对角线不再匹配起始字符后立即停止对其进行检查。
这是它可能在代码中播放的一种方式:
public static void main(String ... args) {
// Find diagonal duplicates (AAAA) starting at (0, 0)
String[] input = {"ATGCGA","CAGTGC","TTATGT","AGAAGG","CCCCTA","TCACTG"};
findSequences(input);
// Find diagonal duplicates (AAAA) starting at (2,2)
String[] input2 = {"BTGCGA","CCGTGC","TTATGT","AGAAGG","CCCCAA","TCACTA"};
findSequences(input2);
// Find diagonal duplicates (ZZZZ) starting at (1,2)
String[] input3 = {"BTGCGA","CCZTGC","TTCZGT","AGAAZG","CCCCAZ","TCACTA"};
findSequences(input3);
}
private static void findSequences(String ...input) {
// sought-after length of repeated characters
int repeatLength = 4;
// max row a diagonal of length 'repeatLength' could start at
int maxStartRow = input.length - repeatLength;
// max column a diagonal could start at... assumes all rows have same length.
int maxStartColumn = input[0].length() - repeatLength;
for (int i = 0; i <= maxStartRow; i++) {
for (int j = 0; j <= maxStartColumn; j++) {
boolean allMatch = true;
char[] sequence = new char[repeatLength];
// Capture the starting character
sequence[0] = input[i].charAt(j);
// Walk down the diagonal from the starting character
// ceasing when the characters no longer match or we exceed the length
for (int diagonalCounter = 1; diagonalCounter < repeatLength && allMatch; diagonalCounter++) {
sequence[diagonalCounter]= input[i+diagonalCounter].charAt(j+diagonalCounter);
allMatch &= (sequence[0] == sequence[diagonalCounter]);
}
if (allMatch) {
System.out.println("Match " + String.valueOf(sequence) + " found, starting at (" + i + ", " + j + ")");
}
}
}
}
打印:
Match AAAA found, starting at (0, 0)
Match AAAA found, starting at (2, 2)
Match ZZZZ found, starting at (1, 2)