В приведенном ниже коде у меня есть ряд строк (последовательностей ДНК), которые я сохраняю в векторе. У меня есть struct
, read_tag
, которые я использую для идентификации каждой строки; read_tag.read_id
— идентификатор строки. Я беру 30-символьные подстроки каждой строки и использую их как ключ в unordered_multimap
с read_tag
в качестве значения; цель состоит в том, чтобы сгруппировать строки, которые имеют общую последовательность из 30 символов. Естественно, идентичная строка будет хэшироваться до одного и того же значения и попадет в одно и то же ведро на мультикарте. Смещение используется для указания «сдвига» от нулевого индекса 30-символьного тега.
Однако, когда я запускаю этот код, перебирая каждое ведро; Я обнаружил, что в одном и том же ведре есть несколько разных последовательностей. Я думал, что коллизии были разрешены в unordered_mutlimap
, и поэтому в ведре их должен быть только один ключ (строка). Я понимаю, что может произойти столкновение, но я думал, что в unordered_mutlimap
реализовано либо цепочка, либо зондирование и т.д. Вы должны иметь возможность запустить и проверить вывод, чтобы увидеть, где я запутался.
Я также std::hash
каждый ключ, один в ведре, и я обнаружил, что ключи в "столкновениях" имеют другое значение хеш-функции.
Итак, как будто происходят коллизии, в результате чего получаются значения с diff. keys в одном и том же сегменте, но, наоборот, ключи хэшируются в разные значения. Это способ избежать этого и различать значения на основе ключей внутри сегментов? Или мне нужно реализовать это?
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
#include <functional>
using namespace std;
int main() {
vector<string> reads;
reads.push_back("CCAGCTGCTCTCACCCTGGGCAGGGTCCCTGCACACACTGTATCTTTTGAGGTCCCTTCAGGACCCCGGTTTGCTGCCTC");
reads.push_back("CCAGCTGCTCTCACCCTGGGCAGGGTCCCTGCACACACTGTATCTTTTGAGGTCCCTTCAGGACCCCGGTTTGCTGCCTC");
reads.push_back("GGCAGGGTCATACCCGATTAACTTGTTATAGAGTATGGGGCATCAACTTGGGCAGCAATGGGGAACGGTGTCTCTGGAAG");
reads.push_back("CCAGCTGCTCTCACCCTGGGCAGGGTCCCTGCACACACTGTATCTTTTGAGGTCCCTTCAGGACCCCGGTTTGCTGCCTC");
reads.push_back("GGCAGGGTCATACCCGATTAACTTGTTATAGAGTATGGGGCATCAACTTGGGCAGCAATGGGGAACGGTGTCTCTGGAAG");
reads.push_back("GGCAGGGTCATACCCGATTAACTTGTTATAGAGTATGGGGCATCAACTTGGGCAGCAATGGGGAACGGTGTCTCTGGAAG");
reads.push_back("GGCAGGGTCATACCCGATTAACTTGTTATAGAGTATGGGGCATCAACTTGGGCAGCAATGGGGAACGGTGTCTCTGGAAG");
reads.push_back("CCGGGCGTGGTGGCGTGCACCTGTAATCCCAGCTACTTGGGATGTTCAGGCAGGAGACTCGCTTGATCCCCGGGGACGGA");
reads.push_back("CCGGGCGTGGTGGCGTGCACCTGTAATCCCAGCTACTTGGGATGTTCAGGCAGGAGACTCGCTTGATCCCCGGGGACGGA");
reads.push_back("CCGGGCGTGGTGGCGTGCACCTGTAATCCCAGCTACTTGGGATGTTCAGGCAGGAGACTCGCTTGATCCCCGGGGACGGA");
reads.push_back("CCGGGCGTGGTGGCGTGCACCTGTAATCCCAGCTACTTGGGATGTTCAGGCAGGAGACTCGCTTGATCCCCGGGGACGGA");
reads.push_back("CCAGCTGCTCTCACCCTGGGCAGGGTCCCTGCACACACTGTATCTTTTGAGGTCCCTTCAGGACCCCGGTTTGCTGCCTC");
struct read_tag{
unsigned int read_id; // unique string identifier
int offset; // shift of 30 character substring represented by tag
};
unordered_multimap<string, read_tag> mutation_grouper;
for(int read_id=0; read_id < reads.size(); read_id++) {
string read = reads[read_id];
for(int i=0; i < read.size()-30; i++) {
string sub_read = read.substr(i, 30);
read_tag next_tag;
pair<string, read_tag> key_val;
next_tag.read_id = read_id;
next_tag.offset = i;
key_val.first = sub_read;
key_val.second = next_tag;
mutation_grouper.insert(key_val);
}
}
cout << "mutation_grouper buckets" << endl;
std::hash<std::string> hash_er;
for(unsigned int bucket = 0; bucket < mutation_grouper.bucket_count(); bucket++) {
cout << "Bucket: " << bucket << endl;
for( auto local_it = mutation_grouper.begin(bucket);
local_it != mutation_grouper.end(bucket); ++local_it) {
cout << local_it->first << " : " << local_it->second.read_id
<< ", " << local_it->second.offset << ", " << endl;
cout << "hash value: " << local_it->first <<"::: " << hash_er(local_it->first) << endl;
}
cout << endl << endl;
}
}
read.size()
, но переменнойread
нет (вы имели в видуreads
?). Вы также дважды используете.orientation
в коде, который нигде не определен. И с этими двумя исправлениями программа все равно вылетает, из-за строкиread.substr(i, 30)
. - person Jakube   schedule 23.07.2016