我需要阅读矩阵数据,并在我的prrogram中创建矩阵。 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函数之前打印许多start reading matrix from file
之一。
答案 0 :(得分:3)
哦,我的。如果我听起来很苛刻,我希望你能原谅我,但是这段代码有很多很多的问题,一直从基本设计一直到你使用的循环之类的细节从文件中读取数据。
首先,在我看来,你的“矩阵”课程需要健康的“单一责任”。我把它拆成二维矩阵,没别的。
其次,我将摆脱自己处理内存管理的问题。你真正需要的只是一个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确实能够保证它,主要是因为它适用于所有已知的实现。
答案 1 :(得分:1)
此:
scores = new int[[*edge] [*edge]];
是无效的C ++语法。你是说这个吗?:
scores = new int[*edge * *edge];
同样,当您尝试访问scores
的元素时,您应该执行以下操作:
scores[(cols * y) + x] = val;
顺便说一句,如果您不打算修改原始值,则无法通过指针将int
传递给函数。我会将CreateMatrix()
重写为:
void ScoreMatrix::CreateMatrix(int edge)
{
scores = new int[edge*edge];
cols = edge;
}
答案 2 :(得分:1)
(如果您的代码不起作用)读取此(仅限于此)格式的C代码:
int base2num(char b)
// just a numbering scheme for the input characters. This indexing will be used
// in the matrix into which it is read
{
switch (b)
{
case 'A': case 'a': return 0; break;
case 'C': case 'c': return 1; break;
case 'G': case 'g': return 2; break;
case 'T': case 't': return 3; break;
case 'P': case 'p': return 4; break;
case 'V': case 'v': return 5; break;
case 'L': case 'l': return 6; break;
case 'I': case 'i': return 7; break;
case 'M': case 'm': return 8; break;
case 'F': case 'f': return 9; break;
case 'Y': case 'y': return 10; break;
case 'W': case 'w': return 11; break;
case 'H': case 'h': return 12; break;
case 'K': case 'k': return 13; break;
case 'R': case 'r': return 14; break;
case 'Q': case 'q': return 15; break;
case 'N': case 'n': return 16; break;
case 'E': case 'e': return 17; break;
case 'D': case 'd': return 18; break;
case 'S': case 's': return 19; break;
default: return -1;
}
}
void str2int(char *line, int i, int *mat, char *arr)
{
int m,k;
char * endptr;
endptr=line+1;
for (m=0;m<23;m++)
{
k=base2num(arr[m]);
if (k==-1)
continue;
mat[i*20+k]=strtol(endptr,&endptr,0);
}
}
void parseinp(FILE *fp, int *mat)
{
int i,j;
char line[256];
char arr[23];
while (fgets(line,256,fp)!=NULL)
{
if (line[0]=='#')
continue;
i=3;
j=0;
if (base2num(line[3])!=-1)
//assumption: the first character is
//part of the 20 bases
{
while(line[i]!='*')
// this is the first line of the table,
// that which contains A R N D etc.
// store the chars in arr
{
arr[j]=line[i];
j++;
i+=3;
}
continue;
}
i=base2num(line[0]);
if (i<0) // not one of the 20 core bases
{
continue;
}
else
{
// printf("%d\n",i);
str2int(line,i,mat,arr);
}
}
}
int * get_blosum()
{
FILE *fp;
int *mat;
int n,m;
mat=(double *) calloc(400, sizeof(double));
fp =fopen("BLOSUM62","r");
if (fp==NULL)
{
perror("failed to open protein matrix file!");
}
parseinp(fp, mat);
fclose(fp);
return mat;
}
答案 3 :(得分:0)
您似乎错误地使用了[]
语法。我想你想改变以下几行:
scores = new int[[*edge] [*edge]];
scores[cols *[y + x]] = val;
return *scores[cols *[x + y]];
到
scores = new int[(*edge) * (*edge)];
scores[cols * (y + x)] = val;
return *scores[cols * (x + y)];
请注意使用括号()
代替[]
。
答案 4 :(得分:0)
要在其他人之前评估某些内容,请不要使用[]
,而应使用括号。它应该是这样的:
void ScoreMatrix::CreateMatrix(int *edge)
{
scores = new int[(*edge) * (*edge)];
cols = *edge;
}
void ScoreMatrix::SetValue(int x, int y, int val)
{
scores[cols * (y + x)] = val;
}
int ScoreMatrix::GetValue(int x, int y)
{
return *scores[cols * (x + y)];
}