0

可能重复:
对来自流式阅读器的过滤数据执行小计

数据集:“file.dat”中的数百行数据,每行长度为 80-500 个 ASCII 字符。

位于每个字符串中的特定位置(固定宽度不定界)有 4 条相关信息。

1) -NUMBERS- 始终位于每个字符串的前 3 个字符,是一个数字,表示该字符串是否与我相关。如果它包含 210,310 或 410 中的任何一个,那么我想处理这一行,否则我想忽略它。

2)-字母-此信息的位置取决于前 3 位数字是 210、310 还是 410。如果是 210,那么我希望算法查看位置 406-409 中包含的值(始终为字母)。如果前 3 位数字是 310,那么我需要 322-325 的值,如果是 410,那么我需要的是 478-481。

3 & 4) -NUMBERS- 最后两条信息是数字,其中一条永远为0,另一条> 0。鉴于我不知道哪个是非零,我希望将它们加在一起. 这些号码位于以下位置:

       第一个号码位置 第二个号码位置             

210:……………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………12 ..142-153

310:…………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………………113-124 ...126-137

410:..................113-124.................................. ...126-137

我需要做的是为 2) 中的每个字母组合提供小计。2) 的值范围只有大约 4-5 种不同的字母排列方式(ABCD、AAAA、BBBB、CCCC、DDDD),所以我的最终输出是:

210 AAAA “总数”

210 BBBB “总数”

.

.

.

410 DDDD “总数”

410 ABCD “总数”

等。对于数字和字母的所有组合(最多 15 个)。

我希望这很清楚,在此先感谢。

编辑:当前代码:

我目前正在尝试使用一系列 if 和许多 var 来解决它,希望这段代码粘贴:

class Program
{
    static void Main()
    {
        // Read in a file line-by-line, and store in a List.
        List<string> list = new List<string>();
        using (StreamReader reader = new StreamReader("file.dat"))
        {
            string line;
            while ((line = reader.ReadLine()) != null)
            {
                var beginning = line.Substring(0, 3);
                // building this up atm
                // var letters210 = line.Substring(129,11);
                if (beginning != "210" && beginning != "310" && beginning != "410")
                    continue;

                list.Add(line); // Add to list.
                Console.WriteLine(line); // Write to console.
            }
        }
    }
}
4

1 回答 1

0

I'd write a class whose job is handling a particular type of line and aggregating all the sums:

public class LineHandler
{
    // Start indices and lengths for string and two numbers
    int si, sl, n1i, n1l, n2i, n2l;
    Dictionary<string, int> sums;

    public LineHandler(int si, int sl, int n1i, int n1l, int n2i, int n2l)
    {
        this.si = si; this.sl = sl; this.n1i = n1i;
        this.n1l = n1l; this.n2i = n2i; this.n2l = n2l;
        sums = new Dictionary<string,int>();
    }

    public void HandleString(string s)
    {
        string key = s.Substring(si, sl);
        int sum = int.Parse(s.Substring(n1i, n1l)) + int.Parse(s.Substring(n2i, n2l));
        if (sums.ContainsKey(key))
            sums[key] += sum;
        else
            sums[key] = sum;
    }

    public Dictionary<string, int> Sums { get { return sums; } }
}

Then you can create a dictionary of these to help select the right one for each line (double-check I've got the lengths right):

    Dictionary<string, LineHandler> handlers = new Dictionary<string, LineHandler> {
        { "210", new LineHandler(406, 3, 129, 11, 142, 11) },
        { "310", new LineHandler(322, 3, 113, 11, 126, 11) },
        { "410", new LineHandler(478, 3, 113, 11, 126, 11) } };
    public Dictionary<string, int> Sums { get { return sums; } }
}

Then you can just loop over your lines and "handle" each line if there's a handler for it:

while ((line = reader.ReadLine()) != null)
{
    string key = line.Substring(0, 3);
    if (handlers.ContainsKey(key))
        handlers[key].HandleString(line);
}

Then you can access the values:

foreach(string key in handlers.Keys)
{
    LineHandler handler = handlers[key];
    foreach (string s in handler.Sums.Keys)
        Console.WriteLine("{0} {1} {2}", key, s, handler.Sums[s]);
}
于 2012-11-30T10:32:53.560 回答