如何从嵌套的for循环中分离顺序打印语句?

时间:2015-02-04 18:51:48

标签: c# for-loop code-separation

我有以下方法打印出给定数组的所有连续子集。我希望能够将在for循环中交织的丑陋的print语句分离出来并转换为新的函数。这可行吗?

    // Example:  
    // Input: char[] input = new char[] { 'a', 'b', 'c' };
    // Output: 
    //        (a) (a b) (a b c)
    //        (b) (b c)
    //        (c)  

    static void  PrintContSubArrays(char[] arr)
    {
        int len = arr.Length;
        StringBuilder sb1 = new StringBuilder();
        StringBuilder sb2 = new StringBuilder();

        for (int i = 0; i < len; i++)
        {
            for (int j = 1; j <= len; j++)
            {
                sb2.AppendFormat("(");

                for (int k = i; k < j; k++)
                {
                    sb2.AppendFormat("{0} ", arr[k]);
                }

                sb2.Remove(sb2.Length - 1, 1);
                sb2.Append(") ");

                if (sb2.Length > 3) sb1.Append(sb2);
                sb2.Clear();
            }
            sb1.Append(System.Environment.NewLine);
        }

        Console.WriteLine(sb1.ToString());
        Console.ReadLine();
    }

4 个答案:

答案 0 :(得分:2)

根据@usr

的建议实现此目的
  

而不是进行字符串处理内联提取子数组   char[]并使用yield return返回它们。那样的来电者   接收一组子数组。他可以处理,格式化和打印它们   他想要的。

这就是我所拥有的。但这并不能转化为您的确切输出格式。由于丢失了上下文,某些格式会丢失。如果您愿意将原始数组长度传递给print方法,则可以通过调整print方法中的for循环来获得所需的内容。

    // Input: int[] input = new int[] { 1, 2, 3};
    // Call: Console.WriteLine(PrintContSubArrays(GetContSubArrays(input)));
    // Output: 
    //       (1)
    //       (1 2)
    //       (1 2 3)
    //       (2)
    //       (2 3)
    //       (3)

    // Generate subsets
    static IEnumerable<int[]> GetContSubArrays(int[] arr)
    {
        int len = arr.Length;

        for (int i = 0; i < len; i++)
        {
            for (int j = 1; j <= len; j++)
            {
                int[] placeholder = new int[j - i < 0 ? 0 : j - i];
                bool isPlaceholderEmpty = true;

                for (int k = i; k < j; k++)
                {
                    placeholder[k - i] = arr[k];
                    isPlaceholderEmpty = false;
                }
                if (!isPlaceholderEmpty) yield return placeholder;
            }
        }
    }

    // Print
    static string PrintContSubArrays(IEnumerable<int[]> input)
    {
        StringBuilder sb1 = new StringBuilder();

        foreach (int[] intarr in input)
        {
            if (intarr != null)
            {
                sb1.Append("(");
                foreach (int intsingle in intarr)
                {
                    sb1.AppendFormat("{0} ", intsingle);
                }
                sb1.Remove(sb1.Length - 1, 1);
                sb1.Append(")");
            }
            sb1.AppendFormat(Environment.NewLine);
        }

        return sb1.ToString();
    }

答案 1 :(得分:1)

不使用内联字符串处理,而是将子数组提取为char[],并使用yield return返回它们。这样调用者就会收到一组子数组。他可以随意处理,格式化和打印它们。

答案 2 :(得分:1)

这是简化事情的一种方法:

static void PrintContiguousSubArrays( char[] input )
{
  if ( input == null ) throw new ArgumentNullException("input") ;
  if ( input.Length == 0 ) return ;

  for ( int offset = 0 ; offset < input.Length ; ++offset )
  {
    string separator = "" ;

    for ( int length = 1 ; offset+length <= input.Length ; ++length )
    {
      Console.Write( "{0}[{1}]" ,
        separator ,
        string.Join("," , input.Skip(offset).Take(length).Select( c => new string(c,1) ) )
        );
      separator = " ";
    }
    Console.WriteLine();

  }

  return ;
}

这是另一种方式:

static IEnumerable<IEnumerable<char>> ContiguousSubArraysOf( char[] input )
{
  if ( input == null ) throw new ArgumentNullException("input") ;

  for ( int offset = 0 ; offset < input.Length ; ++offset )
  {
    for ( int length = 1 ; offset+length <= input.Length ; ++length )
    {
      yield return input.Skip(offset).Take(length) ;
    }
  }

}

这会让你说出这样的话:

char[] input = "abc".ToCharArray();

foreach( var item in ContiguousSubArraysOf(input) )
{
  Console.WriteLine( "[{0}]" ,
    string.Join( "," , item.Select( c => new string(c,1) ) )
  ) ;
}

答案 3 :(得分:1)

这样做怎么样?

static void PrintContSubArrays(char[] arr)
{
    Console.WriteLine(String.Join(Environment.NewLine,
            from n1 in Enumerable.Range(0, arr.Length)
            select String.Join(" ",
                from n2 in Enumerable.Range(1, arr.Length - n1)
                select String.Format("({0})", String.Join(" ", arr.Skip(n1).Take(n2))))));
    Console.ReadLine();
}

这样你就可以摆脱所有丑陋的循环。