假设我有一个非常大的A-D字符序列,确切地说是40亿。我的目标是找到在该大字符序列中设置为长度为30的几个新字母序列的索引。当您要查找的序列有一个小错误(字母错误)时,问题也会增加。我该如何解决这个问题?
琐碎的方法是在整个4亿个文本文件中一次迭代一个字母,但这将永远耗尽内存耗尽。
我被告知要使用散列图,但我不确定要使用什么作为我的键值对。使用正则表达式的想法也出现了,但我不完全确定它是否适用于我的问题。任何方向方面的帮助将不胜感激。谢谢!
以下是我要问的问题:
答案 0 :(得分:4)
这是一个典型的问题,称为longest common subsequence(LCS)。有许多算法可以解决它。基因组计划经常进行这种搜索。提供的wiki链接有很多例子。您的错误阈值将是一个特例。
你在做基因测序吗?我问的只是因为你只提到了4个变量:)
答案 1 :(得分:3)
通过以字符编码,您每2次使用就会浪费14位。你可以只用一个字节编码四个核苷酸字母,那么你只需要半个千兆字节。至于算法,您可以在java.lang.String.indexOf
和Boyer-Moore algorithm上的维基百科页面中学习代码。
答案 2 :(得分:1)
这是一个快速简单的代码来处理表示。
public static enum Nucleotide {
A,B,C,D;
}
public static int setbit(int val, int pos, boolean on) {
if (on) {
// set bit
return val | (1 << (8-pos-1));
}
else {
// unset bit
return val & ~(1 << (8-pos-1));
}
}
public static int set2bits(int val, int pos, int bits) {
// set/unset the first bit
val = setbit(val, pos, (bits & 2) > 0);
// set/unset the second bit
val = setbit(val, pos+1, (bits & 1) > 0);
return val;
}
public static int setNucleotide(int sequence, int pos, Nucleotide tide) {
// set both bits based on the ordinal position in the enum
return set2bits(sequence, pos*2, tide.ordinal());
}
public static void setNucleotide(int [] sequence, int pos, Nucleotide tide) {
// figure out which element in the array to work with
int intpos = pos/4;
// figure out which of the 4 bit pairs to work with.
int bitpos = pos%4;
sequence[intpos] = setNucleotide(sequence[intpos], bitpos, tide);
}
public static Nucleotide getNucleotide(int [] sequence, int pos) {
int intpos = pos/4;
int bitpos = pos%4;
int val = sequence[intpos];
// get the bits for the requested on, and shift them
// down into the least significant bits so we can
// convert batch to the enum.
int shift = (8-(bitpos+1)*2);
int tide = (val & (3 << shift)) >> shift;
return Nucleotide.values()[tide];
}
public static void main(String args[]) {
int sequence[] = new int[4];
setNucleotide(sequence, 4, Nucleotide.C);
System.out.println(getNucleotide(sequence, 4));
}
显然有很多比特转换正在进行,但是少量评论应该对正在发生的事情有意义。
当然,这种表示的缺点是你正在以4个为一组进行工作。如果你想要10个核苷酸,你必须在计数的某个地方保留另一个变量,以便你知道序列中的最后2个核苷酸没用。
如果没有别的话,可以用蛮力完成模糊匹配。您将采用一系列N个核苷酸,然后从0开始,检查核苷酸0:N-1并查看多少匹配。然后你从1:N然后2:N + 1等等......