2010-06-18 44 views
0

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

text是构成整个文件基础的一行数组。

lineNum保存文件名条目行位置的数组。

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

files是可能的文件名的锯齿状的2维阵列,其中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

我花了一段时间才弄清楚你真的想做什么。这个问题可以在不递归的情况下解决,诀窍是查看您拥有的数据并将其转换为更有用的格式。您的“files”数组是最不方便的数组。诀窍是将数据转换为可用的排列。为此,我建议利用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的两倍。

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

相关问题