1

假设我们有一个 Octave/Matlab 矩阵,其中填充了以字符串形式提供给我们的数据,如下所示:

N =

 Columns 1 through 6:

  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000
  0.0000e+000  0.0000e+000  2.3423e+008  1.0809e+009  1.6893e+010  6.5398e+008

 Columns 7 through 12:

  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000  0.0000e+000
  3.3553e+009  6.9347e+010  3.5653e+010  2.7392e+011  2.1380e+008  7.9962e+009

 Columns 13 and 14:

  9.0266e+015  2.6575e+007
  9.0265e+015  1.2970e-008

所以每个 Columns 都会有它的值列表(这里每个 Column 都2可以有更多的行,我们不知道有多少,在我们得到那个字符串之前我们知道列的总数)

list<list<double> >如何在运行时(从给定的字符串)将这样的野兽解析成 C# ?

4

1 回答 1

1

您应该首先将矩阵写入文件(在 Octave/Matlab 中)。这些文件具有一致的格式,允许您从中提取数据。

并且不会知道,我有一些代码可以将 Octave 矩阵解析为 .NET!别介意幕后的待办事项。这是一个更大的课程的一部分,但这应该是大部分;如果缺少任何重要的东西,请添加评论,我会挖掘它。

Dictionary<string, object> variables;

private bool ReadAllVariablesFromDataFile(string[] lines)
{
    int i = 0;

    while (i < lines.Length)
    {
        string line = lines[i];
        int oldI = i;
        i = ReadSingleVariable(i, lines);
    }

    return true;
}

private static bool IsDefinitionLine(string line)
{
    return (line != null && line.TrimStart().StartsWith("#"));
}

private int ReadSingleVariable(int startIndex, string[] lines)
{
    // TODO: Types other than matrix.
    OctaveVariable variable = new OctaveVariable();

    while (IsDefinitionLine(lines[startIndex]))
    {
        ProcessDefinitionLine(variable, lines[startIndex]);
        startIndex++;
    }

    if (!variable.IsInitialized)
    {
        return startIndex;
    }

    for (int i = 0; i < variable.Rows; i++)
    {
        ProcessDataLine(variable, lines[startIndex + i], i);
    }

    this.variables.Add(variable.Name, variable.Value);

    return startIndex + variable.Rows;
}

private static void ProcessDefinitionLine(OctaveVariable variable, string line)
{
    string value = GetLineValue(line);

    switch (GetLineId(line))
    {
        case "name":
            variable.Name = value;
            variable.IsInitialized = true;
            break;
        case "rows":
            variable.Rows = int.Parse(value);
            break;
        case "columns":
            variable.Columns = int.Parse(value);
            break;
        default:
            break;
    }
}

private static void ProcessDataLine(OctaveVariable variable, string line, int rowIndex)
{
    string[] values = line.Trim().Split(' ');
    double[] row = new double[variable.Columns];

    for (int i = 0; i < variable.Columns; i++)
    {
        variable.Value[rowIndex, i] = double.Parse(values[i]);
    }
}

private static string GetLineId(string line)
{
    return line.Split(':').First().TrimStart('#').Trim().ToLowerInvariant();
}

private static string GetLineValue(string line)
{
    string[] pair = line.Split(':');
    if (pair.Length < 2)
    {
        throw new ArgumentException("Invalid def line");
    }

    return pair[1].Trim();
}
于 2013-03-21T23:47:18.910 回答