我的任务是使用程序参数中提供的表(.txt文件)实现散列连接算法。
表格文件可能如下所示:
c1:int,c2:int,c3:string,c4:long
1,1,asd,11
2,3,asdqwe,11
标题行,包含列的名称和列的类型,然后是由","分隔的行。 列数和列类型是可变的。
因此应该存储列名和类型,我必须将它们存储在2D数组或矩阵中。
我必须读取类型并为指定类型的列创建一个容器。 我还必须将所有列存储在异构数组或结构中。
我不知道C ++ 11下面的任何STL容器是异质的。
如何确定列的类型,从其类型创建容器并以异构方式存储所有列数组?
我的努力:
class Table {
public:
struct Column {
std::string name;
std::string type;
Column(std::string name, std::string type) : name(name), type(type) {}
};
//enum for switch-case
static enum typeValue {
INT,
STRING,
LONG,
CHAR,
DOUBLE,
SHORT
};
private:
std::string filePath;
std::ifstream file;
std::vector<Column> columns;
int rowNumber;
std::vector<std::array> tableData;
public:
Table(std::string filePath) {
this->filePath = filePath;
rowNumber = 0;
open();
loadTableData();
}
bool open() {
file.open(filePath);
std::string line;
std::string delimiter = ",";
size_t pos = 0;
std::string token;
getline(file, line);
while ((pos = line.find(delimiter)) != std::string::npos) { //parse the columns
token = line.substr(0, pos);
size_t posT = 0;
posT = token.find(":");
columns.push_back(Column(token.substr(0, posT), token.substr(posT + delimiter.length())));
line.erase(0, pos + delimiter.length());
}
size_t posT = 0;
posT = line.find(":");
columns.push_back(Column(line.substr(0, posT), line.substr(posT + delimiter.length())));
while (std::getline(file, line)) //count the rows
++rowNumber;
for (int i = 0; i < columns.size(); ++i) {
switch (hashIt(columns[i].type)) {
case INT:
std::vector<int> *tempI = new std::vector<int>();
tableData[i] = tempI;
break;
case STRING:
std::vector<std::string> *tempS = new std::vector<std::string>();
tableData[i] = tempS;
break;
case LONG:
std::vector<long> *tempL = new std::vector<long>();
tableData[i] = tempL;
break;
case CHAR:
std::vector<char> *tempC = new std::vector<char>();
tableData[i] = tempC;
break;
case DOUBLE:
std::vector<double> *tempD = new std::vector<double>();
tableData[i] = tempD;
break;
case SHORT:
std::vector<short> *tempSh = new std::vector<short>();
tableData[i] = tempSh;
break;
default:
std::cerr << "Error: Unsupported column type.";
}
}
//file.close();
std::cout << "Table " << filePath << " has " << columns.size() << " columns." << std::endl;
return true;
}
bool loadTableData() {
file.seekg(0, file.beg);
std::string line;
getline(file, line); //discarding the column headers
while (std::getline(file, line)) {
++rowNumber; //count the rows
for (int i = 0; i < columns.size(); ++i) {
std::string delimiter = ",";
size_t pos = line.find(delimiter);
std::string token = line.substr(0, pos);
tableData[i].push_back(token);
}
}
}
template<typename T>
T **createColumnData(int colNum) {
T *data = new T[rowNumber]();
tableData.insert(colNum, data);
}
typeValue hashIt(std::string const &inString) {
if (inString == "int") return INT;
if (inString == "string") return STRING;
if (inString == "long") return LONG;
if (inString == "char") return CHAR;
if (inString == "double") return DOUBLE;
if (inString == "short") return SHORT;
std::cerr << "Error: Unsupported column type.";
return NULL;
}
};
谢谢!
答案 0 :(得分:0)
IMO,您应该将行建模为结构:
struct Row
{
int column1;
int column2;
std::string name;
int column3;
};
下一步是重载operator>>
以读入结构。
std::istream& operator>>(std::istream& inp, Row& r)
{
char comma;
inp >> r.column1;
inp >> comma;
inp >> r.column2;
inp >> comma;
std::getline(inp, r.name, ',');
inp >> r.column3;
inp.ignore(100000, '\n');
return inp;
}
然后你可以阅读记录:
std::vector<Row> database;
Row r;
while (input_file >> r)
{
database.push_back(r);
}
也许你的下一步是创建索引表。这样可以更快地搜索您的数据库:
std::map<int, int> index_by_column1;
std::map<std::string, int> index_by_name;
该对的第二个值是相关记录的数据库的索引。
查找包含name
&#34; Fred&#34;:
std::map<std::string, int>::const_iterator iter;
iter = index_by_name.find("Fred");
Record r;
if (iter != index_by_name.end())
{
int database_index = (*iter).second;
r = database[database_index];
}
您可以使用将索引返回到数据库的哈希表,而不是使用std::map
。