0

.txt 以我不关心的可变长度字符串开始每一行,然后是空格分隔的 ID:

somegarbage 34532 2034 203 4 30403


garbage 2 45 2342 23 33503434
garbagethird 2 

第 2 行和第 3 行是空的。

数据文件的一行上的所有 ID 应该是

  1. 推入一个数学集合(即{.},其中元素的顺序无关紧要)
  2. 分配给 V[行号]。

读入后的示例查询:

V[5]
  -> {2}
V[2]
  -> {}

我需要什么函数和数据结构?

如果 MATLAB 没有设置的数据结构,是否有任何接近的东西,或者我必须求助于二​​维数组?

4

2 回答 2

1

有两个函数非常适合此目的:textreadtextscan. 它们都接收一个格式字符串,该字符串指定输入文本文件的每一行中的参数模式。

解决方案textread

textread需要输出变量的数量与每行中读取的参数数量相匹配,因此您可以按照以下方式执行操作:

[col1, col2, col3, col4, col5, col6] = textread('myfile.txt', '%s %d %d %d %d');
V = [col2, col3, col4, col5, col6]

这产生:

V =
    34532        2034         203           4         30403
        2          45        2342          23      33503434

本质上,您拥有的是一个矩阵数组的数组),其中每一行对应于输入文本文件中的一行。要访问这样的行之一,您只需执行以下操作V(row_index, :),例如:

V(1, :) =
    34532        2034         203           4         30403

解决方案textscan

textscan需要手动打开文件。它返回一个元胞数组(它实际上是一种特殊类型的数组,可以在同一个集合中保存多种类型的变量,例如带有数字的字符串)。为了获得与 相同的矩阵textread,我们使用逗号分隔的列表和简单的连接,如下所示:

fid = fopen('myfile.txt');
C = textscan(fid, '%s %d %d %d %d %d')
V = [C{2:6}]
fclose(fid);

现在V应该包含与第一个示例相同的元素。

如果解析参数的数量未知,最好将整行读取为一个完整的字符串,然后使用以下代码进行解析regexp

fid = fopen('myfile.txt');
C = textscan(fid, '%s', 'Delimiter', '');
V = C{1};
for i = 1:numel(V)
    V{i} = cellfun(@str2num, regexp(V{i}, '\d*', 'match'));
end
fclose(fid);

在这种情况下,输出V将是一个元胞数组(因为矩阵需要每个元素的数量是固定的)。元胞数组中的每个元胞将是一个数字数组(向量),可能具有不同的长度。对于您的示例,结果将是一个 3×1 元胞数组(忽略空行):

V = 
    [34532        2034         203           4       30403]
    [    2          45        2342          23    33503434]
    [    2]

在这里,您可以使用花括号 ( {}) 访问每行的元素,例如V{2}

ans =
    [    2          45        2342          23    33503434]

忠告:格式模式和正则表达式极大地简化了字符串解析,并且通常在 MATLAB 中优于使用循环遍历标记的直接方法for。它还使解决方案更加优雅,并且不那么繁琐。

于 2012-12-02T13:17:34.517 回答
1

根据您打算如何处理数据,这可能是方法:

V=importdata('A.txt')
V = 

      data: [2x6 double]
  textdata: {2x1 cell}
rowheaders: {2x1 cell}

V 将是一个结构,其字段数据将包含您所有的“ID”。然后你可以使用V.data(linenumber,:)来获取你想要弄乱的行。

V.data(1,:)
ans =

   34532        2034         203           4       30403        3333

并且行的长度可以不等:

V.data(2,:)

ans =

       2          45        2342          23    33503434         NaN

改进的解决方案:

fid = fopen('A.txt');
tline = fgets(fid);
counter=1;
while ischar(tline)
v{counter} = strread(char(tline),'%s','delimiter',' ');
if ~isempty(v{counter})
    v{counter}=v{counter}(2:end);
else
    v{counter}={};
end
tline = fgets(fid);
V{counter}=cellfun(@str2double, v{counter}');
counter=counter+1;
end
fclose(fid);

此解决方案保留空行:

V{1}

ans =

   34532        2034         203           4       30403

V{2}

ans =

 []
于 2012-12-02T05:35:51.283 回答