C++ 子字符串 - 指向字符串范围的指针(加载大文件)
C++ substring - a pointer to a range of a string (loading a big file)
我有这样一个文件:
- ACCCTCGGCTACTACGACTAC
- GCTAGTCAGACTGAGCATGTCAGTC
- TAGCTAGCTGACTGACTACATCGAC
- GCTAGATGCTAGCGTATAGTCTGCTGAGTCTGAGT
- GTCAGTCATGTGACTGACGTATGCTATTA
以上文件有点大,它有 9000 行,长度为 100-200 个字符。
我需要将这些行的 5 个范围内的子字符串插入地图(整个文件必须在同一个地图中)。
第一行是:ACCCTCGGCTACTACGACTAC 所以我需要加载到地图:
- ACCCTCGGCTACTACGACTAC 下一个
- ACCCTCGGCTACTACGACTAC 下一个
- ACCCTCGGCTACTACGACTAC 下一个
- ...
- ACCCTCGGCTACTACGACTAC
在此之后我们加载第二行,第三行,直到 eof。
所以。我的第一个想法是:
map<string, set<string>> sequences;
int SEQLEN = 74; // cause we load 74 long substrings
while (getline(in, name) && getline(in, chain)) {
for (int i = 0; i + SEQLEN < chain.size(); i++) {
string subchain = chain.substr(i, SEQLEN);
sequences[subchain].insert(name);
}
}
但在此之后我们有一张地图,它消耗 4.5 GB 的 RAM,这是不可接受的,因为它应该工作的 PC 只有 2 GB 的 :C
我听说过某种“指向字符串字符的指针”。如果存在这样的东西,我可以加载所有行并为这些子字符串保存指向 'start char' 和 'end char' 的指针,然后通过提供此 'range'.[=11= 来加载它们]
你怎么看,是否有类似“指向字符串的特定字符的指针”之类的东西?
如果有人有任何想法,我将不胜感激:)
由于您的字符串编码核碱基,并且您关心节省内存,最好的方法是完全摆脱字符串。
你的字母表中有四个核碱基字符,只有 45 或 1024 个可能的 sub-strings 长度为 5。你可以将它们中的每一个编码为 short
整数通过查找,然后通过反向查找将其解码输出。
这种方法将为您节省大量内存:一个包含 1024 个字符串的数组和一个查找所需的 std::map<std::string,short>
将占用大约 50K 的内存。存储每个单独的 5 个字符的子字符串将花费您两个字节,而不是 32 位系统上的 14 个字节或 64 位系统上的 22 个字节。您的整个文件可以存储在不到 1 MB 的内存中。
我有这样一个文件:
- ACCCTCGGCTACTACGACTAC
- GCTAGTCAGACTGAGCATGTCAGTC
- TAGCTAGCTGACTGACTACATCGAC
- GCTAGATGCTAGCGTATAGTCTGCTGAGTCTGAGT
- GTCAGTCATGTGACTGACGTATGCTATTA
以上文件有点大,它有 9000 行,长度为 100-200 个字符。
我需要将这些行的 5 个范围内的子字符串插入地图(整个文件必须在同一个地图中)。
第一行是:ACCCTCGGCTACTACGACTAC 所以我需要加载到地图:
- ACCCTCGGCTACTACGACTAC 下一个
- ACCCTCGGCTACTACGACTAC 下一个
- ACCCTCGGCTACTACGACTAC 下一个
- ...
- ACCCTCGGCTACTACGACTAC
在此之后我们加载第二行,第三行,直到 eof。
所以。我的第一个想法是:
map<string, set<string>> sequences;
int SEQLEN = 74; // cause we load 74 long substrings
while (getline(in, name) && getline(in, chain)) {
for (int i = 0; i + SEQLEN < chain.size(); i++) {
string subchain = chain.substr(i, SEQLEN);
sequences[subchain].insert(name);
}
}
但在此之后我们有一张地图,它消耗 4.5 GB 的 RAM,这是不可接受的,因为它应该工作的 PC 只有 2 GB 的 :C
我听说过某种“指向字符串字符的指针”。如果存在这样的东西,我可以加载所有行并为这些子字符串保存指向 'start char' 和 'end char' 的指针,然后通过提供此 'range'.[=11= 来加载它们]
你怎么看,是否有类似“指向字符串的特定字符的指针”之类的东西?
如果有人有任何想法,我将不胜感激:)
由于您的字符串编码核碱基,并且您关心节省内存,最好的方法是完全摆脱字符串。
你的字母表中有四个核碱基字符,只有 45 或 1024 个可能的 sub-strings 长度为 5。你可以将它们中的每一个编码为 short
整数通过查找,然后通过反向查找将其解码输出。
这种方法将为您节省大量内存:一个包含 1024 个字符串的数组和一个查找所需的 std::map<std::string,short>
将占用大约 50K 的内存。存储每个单独的 5 个字符的子字符串将花费您两个字节,而不是 32 位系统上的 14 个字节或 64 位系统上的 22 个字节。您的整个文件可以存储在不到 1 MB 的内存中。