C# I/O 助手类

在使用 C# 语言解 ACM 题的时候,如果能够有一个 ReadInt32 方法直接从标准输入读取整数比较方便的。下面就是一个 I/O 助手类 IOHelper:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
namespace  Skyiv
{
   using  System;
   using  System.IO;
   using  System.Text;
 
   sealed  class  IOHelper : IDisposable
   {
     static  readonly  Encoding Encoding = Encoding.ASCII;  // or UTF8 ?
     static  readonly  byte [] EOLS = Encoding.GetBytes(Environment.NewLine);
     static  readonly  byte [] BLANKS = { 9, 10, 13, 32 };  // tab,lf,cr,space
     static  readonly  byte  EOF = 0;  // assume '\0' not in input file
     
     byte [] buf =  new  byte [32];  // for Write(int n)
     byte [] buffer =  new  byte [64 * 1024];
     int  current = 0;
     int  count = 0;
     BinaryReader reader;
     BinaryWriter writer;
     
     public  IOHelper()
       this (Console.OpenStandardInput(), Console.OpenStandardOutput())
     {}
     
     public  IOHelper(Stream reader, Stream writer)
     {
       this .reader =  new  BinaryReader(reader);
       this .writer =  new  BinaryWriter(writer);
     }
     
     byte  ReadByte()
     {
       if  (current >= count)
       {
         count = reader.Read(buffer, current = 0, buffer.Length);
         if  (count == 0)  return  EOF;
       }
       return  buffer[current++];
     }
     
     public  static  byte [] GetBytes( string  str)
     {
       return  Encoding.GetBytes(str);
     }
     
     public  int  ReadInt32()
     {
       var  n = 0;
       var  ok =  false ;
       for  ( byte  b; (b = ReadByte()) != EOF; )
       {
         if  (Array.IndexOf(BLANKS, b) >= 0)
           if  (ok)  break ;
           else  continue ;
         n = n * 10 + (b -  '0' );
         ok =  true ;
       }
       return  n;
     }
     
     public  int  ReadLine( byte [] buffer)
     {
       var  n = 0;
       while  (n < buffer.Length)
       {
         var  b = ReadByte();
         if  (b == EOLS[0])
         {
           if  (EOLS.Length == 2 && ReadByte() != EOLS[1])
             throw  new  InvalidDataException( "Invalid EOL" );
           break ;
         }
         buffer[n++] = b;
       }
       return  n;
     }
 
     public  void  Write( int  n)
     {
       if  (n == 0) { writer.Write(( byte ) '0' );  return ; }
       var  i = buf.Length;
       for  (; n > 0; n /= 10) buf[--i] = ( byte )((n % 10) +  '0' );
       Write(buf, i, buf.Length - i);
     }
     
     public  void  Write( byte [] buffer,  int  index,  int  count)
     {
       writer.Write(buffer, index, count);
     }
     
     public  void  Write( string  str)
     {
       var  buffer = Encoding.GetBytes(str);
       writer.Write(buffer, 0, buffer.Length);
     }
     
     public  void  WriteSpace()
     {
       writer.Write(BLANKS, 3, 1);
     }
     
     public  void  WriteLine()
     {
       writer.Write(EOLS, 0, EOLS.Length);
     }
     
     public  void  Dispose()
     {
       if  (reader !=  null ) reader.Close();
       if  (writer !=  null ) writer.Close();
     }
   }
}

此外,IOHelper 类还提供以下方法用于处理字符串:

  • public int ReadLine(byte[] buffer)
  • public void Write(byte[] buffer, int index, int count)

类似于 C/C++ 语言,这两个方法仅仅把字符串当作字节数组处理,使用 ASCII 码。而不是象 C# 语言中字符串是使用 Unicode 进行编码。

下面是一个使用示例,题目来源请参见“I-Keyboard”这篇随笔。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
namespace  Skyiv.Ben.Acm
{
   using  System;
 
   sealed  class  Ikeyb
   {
     const  int  MAX = 90;
     
     static  int [,] cost =  new  int [MAX + 1, MAX + 1];
     static  int [,] price =  new  int [MAX + 1, MAX + 1];
     static  int [,] index =  new  int [MAX + 1, MAX + 1];
     static  int [] F =  new  int [MAX];
     static  byte [] keys =  new  byte [MAX];
     static  byte [] letters =  new  byte [MAX];
     static  byte [] message1 = IOHelper.GetBytes( "Keypad #" );
     static  byte [] message2 = IOHelper.GetBytes( ": " );
     
     static  IOHelper helper;
 
     static  void  Main()
     {
       using  (helper =  new  IOHelper())
       {
         var  runner =  new  Ikeyb();
         var  T = helper.ReadInt32();
         for  ( var  n = 1; n <= T; n++) runner.Run(n);
       }
     }
 
     void  Run( int  n)
     {
       var  K = helper.ReadInt32();
       var  L = helper.ReadInt32();
       helper.ReadLine(keys);
       helper.ReadLine(letters);
       for  ( var  i = 0; i < L; i++) F[i] = helper.ReadInt32();
       Initialize(K, L);
       Compute(K, L);
       helper.Write(message1, 0, message1.Length);
       helper.Write(n);
       helper.Write(message2, 0, 1);
       helper.WriteLine();
       Output(K, L);
       helper.WriteLine();
     }
     
     void  Initialize( int  K,  int  L)
     {
       for  ( var  i = 0; i <= K; i++)
         for  ( var  j = 1; j <= L; j++)
           price[i, j] =  int .MaxValue / 2;
       for  ( var  i = 1; i <= L; i++)
         for  ( var  j = i; j <= L; j++)
           cost[i, j] = cost[i, j - 1] + (j - i + 1) * F[j - 1];
     }
     
     void  Compute( int  K,  int  L)
     {
       for  ( var  i = 1; i <= K; i++)
         for  ( var  j = i; j <= L; j++)
           for  ( var  n = 1; n <= j - i + 1; n++)
           {
             var  sum = price[i - 1, j - n] + cost[j - n + 1, j];
             if  (sum <= price[i, j])
             {
               price[i, j] = sum;
               index[i, j] = n;
             }
           }
     }
 
     void  Output( int  K,  int  L)
     {
       if  (K == 0)  return ;
       var  n = index[K--, L];
       Output(K, L - n);
       helper.Write(keys, K, 1);
       helper.Write(message2, 0, message2.Length);
       helper.Write(letters, L - n, n);
       helper.WriteLine();
     }
   }
}

如果给出以下输入:

1
2 5
*#
ABCDE
1024
32768
2147483647
987
654321

上述程序将产生以下输出:

Keypad #1:
*: ABCD
#: E

注意上述输出其实是有问题的,正确的输出应该分为 AB 和 CDE 两组。但是程序本身是没有问题的,而是输入数据有问题。因为原来的题目中限定各个字母出现的频率不能超过 100000。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值