非常棘手/复杂的文本格式:如何将字符串[] []作为表格输出?

时间:2015-11-24 06:43:35

标签: c# .net string algorithm

诺贝尔奖可以帮助我弄清楚我是否完全错了。所以我要做的是获取一个字符串数组的数组,以打印为表格,例如

{ {"abcdefg", "hij"}, {"klm", "nopqrstuvwxyz"} }

----------------->

 ====================
  abcdefg | hij
 --------------------
  klm     | nopqrstu
          | vwxyz
 ====================

其中有一个常量确定表的宽度(以字符为单位)。

所以我的代码是一个完整的怪物,不起作用:

    public static void PrintTable ( string[][] cells )
    {
        // Outputs content in cells matrix like 

        // =========================================
        //  cells[0][0]   | cells[0][1]
        // -----------------------------------------
        //  cells[1][0]   | cells[1][1]
        // -----------------------------------------
        //  cells[2][0]   | cells[2][1]
        //                .
        //                .
        // -----------------------------------------
        //  cells[n-1][0] | cells[n-1][1]
        //  ========================================

        // Each cell must be able to hold at least 1 character inside 
        // 1 space of padding on the left and right

        int linelen = OutputFormatter.OutputMaxLength; // copy of width (in characters) of lines being formatted
        // Calculate widths of columns 1 and 2 (excluding the single space of padding on the 
        // left and right side of each):
        int w1 = Math.Max(cells.Max(c => c[0].Length), linelen - 5);
        int w2 = linelen - w1 - 1;
        OutputFormatter.PrintChars('='); // prints a line of equals signs for the top border of the table

        // print out rows:
        foreach ( string[] row in cells )
        {
            // Make the strings corresponding to the first and second column have equal
            // length by adding whitespace to the end of the shorter one:
            int m1 = row[0].Length, m2 = row[1].Length;
            String padding = new String(' ', Math.Abs(m1 - m2));
            if ( m1 > m2 ) row[1] += padding;
            else row[0] += padding;

            // Print out content of row
            for ( int i = 0, j = 0, n = row[0].Length; i < n && j < n; i += w1, j += w2 )
            {
                Console.WriteLine(" {0} | {1} ",
                                    row[0].Substring(i,w1),
                                    row[1].Substring(j,w2));
            }
            OutputFormatter.PrintChars('-'); // prints a line of dashes to separate rows
        }

        OutputFormatter.PrintChars('='); // prints a line of equals signs to form bottom border of table
    }

任何人都有这方面的1行解决方案吗? ;)

我已经完成了调试,但是在点击

之后会抛出异常
                Console.WriteLine(" {0} | {1} ",
                                    row[0].Substring(i,w1),
                                    row[1].Substring(j,w2));

当我用输入字符串

进行测试时
{
   new string[] {"CompareLastTwo","Shows difference between friends lists of last two Facebook data files in repository"},
   new string[] {"AddFriendList <DataFolderPath>", "blah blah blah"}
};

所有打印的内容都是

enter image description here

有人可以帮我弄清楚我在这里犯的逻辑错误吗?有没有一种方法可以更好地利用.NET库来实现这种优雅,紧凑,高效,聪明和可读?

2 个答案:

答案 0 :(得分:1)

首先,最好将格式化逻辑保留在OutputFormatter类中,而不是仅使用常量值。

以下代码应该适合您。

    exist  
identical  README.rdoc
identical  Rakefile
identical  config.ru
identical  .gitignore
identical  Gemfile
    exist  app
identical  app/assets/javascripts/application.js
identical  app/assets/stylesheets/application.css
identical  app/controllers/application_controller.rb
identical  app/helpers/application_helper.rb
identical  app/views/layouts/application.html.erb
identical  app/assets/images/.keep
identical  app/mailers/.keep
identical  app/models/.keep
identical  app/controllers/concerns/.keep
identical  app/models/concerns/.keep
    exist  bin
identical  bin/bundle
identical  bin/rails
identical  bin/rake
identical  bin/setup
    exist  config
identical  config/routes.rb
identical  config/application.rb
identical  config/environment.rb
conflict  config/secrets.yml

答案 1 :(得分:0)

这是一种稍微不同的方法,它允许不同的列宽:

class Program
{
    static void Main(string[] args)
    {
        string[][] sampleInput = {
            new string[] { "Column 1 Head", "Column 2 Header" },
            new string[] { "klm", "nopqrstuvwxyz" },
            new string[] { "klm dksfj sldkf sdlk", "nalsdk als dkasopqrstuvwxyz" }
        };

        PrintJaggedArrayWithWrappedLines(sampleInput, 15, 12);

        Console.ReadLine();
    }

    public static void PrintJaggedArrayWithWrappedLines(string[][] jaggedArray, int leftColumnMaxWidth, int rightColumnMaxWidth)
    {
        for (int j = 0; j < jaggedArray.Length; j++)
        {
            string[] aRow = jaggedArray[j];
            int leftColumnNumLines = (int)Math.Ceiling((double)aRow[0].Length / (double)leftColumnMaxWidth);
            int rightColumnNumLines = (int)Math.Ceiling((double)aRow[1].Length / (double)rightColumnMaxWidth);
            int numberLines = Math.Max(leftColumnNumLines, rightColumnNumLines);

            string leftColumn = aRow[0].PadRight(numberLines * leftColumnMaxWidth, ' ');
            string rightColumn = aRow[1].PadRight(numberLines * rightColumnMaxWidth, ' ');

            for (int i = 0; i < numberLines; i++)
            {
                Console.WriteLine(" {0} | {1} ", leftColumn.Substring(i * leftColumnMaxWidth, leftColumnMaxWidth), rightColumn.Substring(i * rightColumnMaxWidth, rightColumnMaxWidth));
            }
            if (j == 0)
            {
                Console.WriteLine(new String('-', leftColumnMaxWidth + rightColumnMaxWidth + 4));
            }
        }
    }
}

在样本输入上,结果为:

 Column 1 Head   | Column 2 Hea
                 | der
-------------------------------
 klm             | nopqrstuvwxy
                 | z
 klm dksfj sldkf | nalsdk als d
  sdlk           | kasopqrstuvw
                 | xyz