我需要读取包含矩阵数据的文件并在我的程序中创建矩阵。 Matrix 文件格式类似于:
# Matrix made by matblas from blosum62.iij
# * column uses minimum score
# BLOSUM Clustered Scoring Matrix in 1/2 Bit Units
# Blocks Database = /data/blocks_5.0/blocks.dat
# Cluster Percentage: >= 62
# Entropy = 0.6979, Expected = -0.5209
A R N D C Q E G H I L K M F P S T W Y V B Z X *
A 4 -1 -2 -2 0 -1 -1 0 -2 -1 -1 -1 -1 -2 -1 1 0 -3 -2 0 -2 -1 0 -4
R -1 5 0 -2 -3 1 0 -2 0 -3 -2 2 -1 -3 -2 -1 -1 -3 -2 -3 -1 0 -1 -4
N -2 0 6 1 -3 0 0 0 1 -3 -3 0 -2 -3 -2 1 0 -4 -2 -3 3 0 -1 -4
D -2 -2 1 6 -3 0 2 -1 -1 -3 -4 -1 -3 -3 -1 0 -1 -4 -3 -3 4 1 -1 -4
C 0 -3 -3 -3 9 -3 -4 -3 -3 -1 -1 -3 -1 -2 -3 -1 -1 -2 -2 -1 -3 -3 -2 -4
Q -1 1 0 0 -3 5 2 -2 0 -3 -2 1 0 -3 -1 0 -1 -2 -1 -2 0 3 -1 -4
E -1 0 0 2 -4 2 5 -2 0 -3 -3 1 -2 -3 -1 0 -1 -3 -2 -2 1 4 -1 -4
G 0 -2 0 -1 -3 -2 -2 6 -2 -4 -4 -2 -3 -3 -2 0 -2 -2 -3 -3 -1 -2 -1 -4
H -2 0 1 -1 -3 0 0 -2 8 -3 -3 -1 -2 -1 -2 -1 -2 -2 2 -3 0 0 -1 -4
I -1 -3 -3 -3 -1 -3 -3 -4 -3 4 2 -3 1 0 -3 -2 -1 -3 -1 3 -3 -3 -1 -4
L -1 -2 -3 -4 -1 -2 -3 -4 -3 2 4 -2 2 0 -3 -2 -1 -2 -1 1 -4 -3 -1 -4
K -1 2 0 -1 -3 1 1 -2 -1 -3 -2 5 -1 -3 -1 0 -1 -3 -2 -2 0 1 -1 -4
M -1 -1 -2 -3 -1 0 -2 -3 -2 1 2 -1 5 0 -2 -1 -1 -1 -1 1 -3 -1 -1 -4
F -2 -3 -3 -3 -2 -3 -3 -3 -1 0 0 -3 0 6 -4 -2 -2 1 3 -1 -3 -3 -1 -4
P -1 -2 -2 -1 -3 -1 -1 -2 -2 -3 -3 -1 -2 -4 7 -1 -1 -4 -3 -2 -2 -1 -2 -4
S 1 -1 1 0 -1 0 0 0 -1 -2 -2 0 -1 -2 -1 4 1 -3 -2 -2 0 0 0 -4
T 0 -1 0 -1 -1 -1 -1 -2 -2 -1 -1 -1 -1 -2 -1 1 5 -2 -2 0 -1 -1 0 -4
W -3 -3 -4 -4 -2 -2 -3 -2 -2 -3 -2 -3 -1 1 -4 -3 -2 11 2 -3 -4 -3 -2 -4
Y -2 -2 -2 -3 -2 -1 -2 -3 2 -1 -1 -2 -1 3 -3 -2 -2 2 7 -1 -3 -2 -1 -4
V 0 -3 -3 -3 -1 -2 -2 -3 -3 3 1 -2 1 -1 -2 -2 0 -3 -1 4 -3 -2 -1 -4
B -2 -1 3 4 -3 0 1 -1 0 -3 -4 0 -3 -3 -2 0 -1 -4 -3 -3 4 1 -1 -4
Z -1 0 0 1 -3 3 4 -2 0 -3 -3 1 -1 -3 -1 0 -1 -3 -2 -2 1 4 -1 -4
X 0 -1 -1 -1 -2 -1 -1 -1 -1 -1 -1 -1 -1 -1 -2 0 0 -2 -1 -1 -1 -1 -1 -4
* -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4 1
字母具有恒定的位置,因此由于我只对其中四个感兴趣,所以我可以在程序中分配x
和y
。我需要的只是一个包含值的矩阵,我可以通过给出函数“GetValue”“x”和“y”来搜索值。
这是我的代码。它只是头文件中定义的类的一部分,其中包含并通过矩阵搜索值。也许这不是优雅的方式,但我没有那么多时间,所以现在我想快速完成。稍后我会有更多时间,所以我会做得更好。
/*
* algorytm.cpp
* implementacja algorytmu
*
* Autor: Mateusz
*
*/
#include <cstdlib>
#include <iostream>
#include <string>
#include <stdio.h>
#include <fstream>
#include <vector>
#include "matryca_sub.h"
#include <sstream>
#include <istream>
#include <sstream>
using namespace std;
int ScoreMatrix::MainMatrix(char *mat_file, int x, int y)
{
cout << "Main matrix function start" << endl;
CreateMatrix(30);
ReadMatrix(mat_file);
int val;
val=GetValue(x, y);
return val;
cout << "Main matrix function end" << endl;
}
void ScoreMatrix::CreateMatrix(int edge)
{
cout << "Creating sub matrix start" << endl;
//int** scores = new int* [*edge-1];
//for (int i=0; i<=23; i++) scores[i] = new int[*edge-1];
if( scores != 0 ) delete [] scores;
scores = new int [edge*edge];
cols = edge;
cout << "Sub matrix created" << endl;
}
void ScoreMatrix::SetValue(int x, int y, int val)
{
cout << "write to sub matrix start" << endl;
//scores[x][y] = val;
scores[(cols* y) + x] = val;
cout << "write to sub matrix end" << endl;
}
int ScoreMatrix::GetValue(int x, int y)
{
//cout << "GetValue start" << endl;
//return scores[x][y];
return scores[(cols * x) + y];
cout << "GetValue end" << endl;
}
void ScoreMatrix::ReadMatrix(char *mat_file)
{
cout << "start reading matrix from file" << endl;
int row=0;
ifstream mfile;
mfile.open(mat_file);
mfile.precision(2);
mfile.setf(ios::fixed, ios::showpoint);
while(!mfile.eof())
{
for (row=0; row<=23; row++)
{
string line;
getline( mfile, line);
istringstream iss(line);
if (line[0] !='#' && line[0] != ' ')
{
int s;
iss >> s;
for (int i=1; !iss.eof(); i++)
{
iss >> s;
SetValue(i, row, s);
}
}
}
}
cout << "end reading matrix from file" << endl;
}
包含头文件:
/*
* File: mat_sub.h
* Author: mateusz
*
* Created on 6 luty 2011, 14:44
*/
#ifndef MAT_SUB_H
#define MAT_SUB_H
#include <cstdlib>
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
class ScoreMatrix
{
public:
ScoreMatrix():
cols (0)
,scores (0)
{}
char mat_file;
int MainMatrix(char *mat_file, int x, int y);
int GetValue(int x, int y);
private:
int cols, rows;
int* scores;
void CreateMatrix(int edge);
void SetValue(int x, int y, int val);
void ReadMatrix(char *mat_file);
};
#endif /* MAT_SUB_H */
在seagfoult函数打印许多开始从文件读取矩阵之一
之前。
最佳答案
天哪。如果我听起来很刺耳,希望您能原谅我,但是这段代码有很多问题,从基本设计一直到细节,例如您使用的循环从文件中读取数据。
首先,在我看来,您的“矩阵”类需要应用适量的“单一责任”。我会将其简化为二维矩阵,仅此而已。
其次,我将摆脱您自己处理内存管理的麻烦。您真正需要的只是一个 std::vector
,以及足够的前端来提供 2D 寻址。
第三,我会摆脱“getValue”/“setValue”,并像自 20 世纪 50 年代科学程序员从汇编语言转换为 Fortran 以来的每一个精心设计的矩阵一样使用下标。
考虑到这些,我们得到一个简化的矩阵类,如下所示:
template <class T>
class matrix {
std::vector<T> data;
size_t cols;
public:
matrix(int x, int y) : cols(x), data(x*y) {}
T &operator()(int x, int y) {
return data[cols * y + x];
}
};
请注意,为简单起见,当您为其添加下标时,您将大致像在 Fortran 或 BASIC 中一样使用 ()
,而不是像通常那样使用 []
C 或 C++。您可以支持后者,但这需要更多(而且更难看)code 。另请注意,您不想要cols * (y+x)
,如果您坚持使用,则需要(cols * y) + x
括号(尽管认为这很愚蠢,因为乘法和加法的相对优先级是众所周知的。最后,我将其作为模板,只是因为这样做很容易 - 如果您想直接指定类型,那就是显然很容易做到。
最后,我将把文件中的数据读取到矩阵中作为一个自由函数。这样做时,我会摆脱所有 while (!whatever.eof())
,因为它们几乎肯定会错误地工作。
template <class T>
void read_matrix(std::string const &filename, matrix<T> &m) {
std::ifstream infile(filename);
std::string line;
int x = 0, y=0;
while (std::getline(infile, line)) {
if (line[0] == '#' || line[0] == ' ')
continue;
int value;
std::istringinstream converter(&line[1]); // &line[1] to skip leading letter
while (converter >> value)
m(x++, y) = value;
++y;
}
}
从技术上讲,&line[1]
不能保证在 C++03 上工作,但 C++11 确实可以保证它,主要是因为它可以与所有已知的实现一起工作。
关于c++ - 从文件加载矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4914654/