在基本文本文件中创建特定行的每个组合的文本文件

时间:2010-06-18 20:33:45

标签: c# file text permutation combinations

好的,所以希望我能够足够详细地解释一下这个人能够帮助我..我正在用C#编写一个程序,它应该采用一个文本文件并替换特定的文本,这些文本恰好是文件,并为给定文件名的每个组合打印一个新的文本文件。更改文件名文本的特定位置有自己的一组可能的文件名,列为下面描述的数组。无论每个位置可用的文件名数量以及文件名的总位置数,该程序都应该运行。如果你真的想让它变得很棒,可以稍微优化它,因为知道在任何单个文本文件中都不应该复制任何文件名。

text是一系列行,构成了整个文件的基础。

lineNum包含文件名条目的行位置数组。

previousFiles是以前使用的文件名数组,从文件中已有的文件名开始。

files是一个可能的文件名的锯齿状二维数组,其中files[1]是第二个位置的所有可能文件名的数组

下面是一个示例,说明如何使用3个单独的文件名位置,第一个给出3个可能的文件名,第二个给出8个可能的文件名,第三个给出3个可能的文件名。

哦,假设buildNewFile有效。

        int iterator = 0;
        for (int a = 0; a < 3; a++)
        {
            for (int b = 0; b < 8; b++)
            {
                for (int c = 0; c < 3; c++)
                {
                    iterator++;
                    text[lineNums[0]] = text[lineNums[0]].Replace(previousFiles[0], files[0][a]);
                    text[lineNums[1]] = text[lineNums[1]].Replace(previousFiles[0], files[0][a]);
                    text[lineNums[2]] = text[lineNums[2]].Replace(previousFiles[1], files[1][b]);
                    text[lineNums[3]] = text[lineNums[3]].Replace(previousFiles[1], files[1][b]);
                    text[lineNums[4]] = text[lineNums[4]].Replace(previousFiles[2], files[2][c]);
                    text[lineNums[5]] = text[lineNums[5]].Replace(previousFiles[2], files[2][c]);
                    previousFiles = new string[] { files[0][a], files[1][b], files[2][c] };
                    buildNewFile(text, Info.baseFolder + "networks\\" + Info.dsnFilename + iterator + ".dsn");
                }
            }
        }

如果你们可以帮助我,非常感谢你,我无法弄清楚如何以递归或其他方式做到这一点。如果您有任何问题,我会回答并编辑,以反映这一点。

1 个答案:

答案 0 :(得分:1)

我花了一点时间才弄清楚你真正想做什么。这个问题可以在没有递归的情况下解决,诀窍是查看你拥有的数据并将其变为更有用的格式。

您的“文件”数组是最不方便的数组。诀窍是将数据转换为可用的排列。为此,我建议利用yield并使用返回IEnumerable的方法。它的代码在这里:

public IEnumerable<string[]> GenerateFileNameStream(string[][] files)
{
    int[] current_indices = new int[files.Length];
    current_indices.Initialize();
    List<string> file_names = new List<string>();

    while (current_indices[0] < files[0].Length)
    {
        file_names.Clear();

        for (var index_index = 0; index_index < current_indices.Length; index_index++)
        {
            file_names.Add(files[index_index][current_indices[index_index]]);
        }

        yield return file_names.ToArray();

        // increment the indices, trickle down as needed
        for (var check_index = 0; check_index < current_indices.Length; check_index++)
        {
            current_indices[check_index]++;

            // if the index hasn't rolled over, we're done here
            if (current_indices[check_index] < files[check_index].Length) break;

            // if the last location rolls over, then we are totally done
            if (check_index == current_indices.Length - 1) yield break;

            // reset this index, increment the next one in the next iteration
            current_indices[check_index] = 0;
        }
    }
}

基本上,它会跟踪files 2D数组的每一行的当前索引,并返回每个当前索引处的文件名。然后它递增第一个索引。如果第一个索引翻转,则它将重置为0并改为增加下一个索引。这样我们就可以遍历文件名的每个排列。

现在,看一下lineNumfiles之间的关系,我假设文件中的每个位置都被复制到两行。其余的代码在这里:

public void MakeItWork(string[][] files, int[] lineNum, string[] text, string[] previousFiles)
{
    var iterator = 0;
    var filenames = GenerateFileNameStream(files);

    // work a copy of the text, assume the "previousFiles" are in this text
    var text_copy = new string[text.Length];

    foreach (var filenameset in filenames)
    {
        iterator++;
        Array.Copy(text, text_copy, text.Length);

        for (var line_index = 0; line_index < lineNum.Length; line_index++)
        {
            var line_number = lineNum[line_index];
            text[line_number] = text[line_number].Replace(previousFiles[line_index], filenameset[line_index / 2]);
        }

        buildNewFile(text_copy, Info.baseFolder + "networks\\" + Info.dsnFilename + iterator + ".dsn");
    }
}

此代码只获取枚举器的结果并为您生成文件。基于示例代码的假设是每个文件位置每个文件使用两次(因为lineNum数组的长度是files位置数的两倍。

我还没有完全测试所有代码,但算法的关键在那里。关键是将数据转换为更有用的形式,然后进行处理。我在这里提出问题时的另一个建议是将问题更多地描述为“问题”而不是当前解决方案。如果您详细说明了您尝试实现的目标而不是显示代码,则可以更深入地了解问题。