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;

  // http://www.spoj.pl/problems/IKEYB/

  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。

版权声明:本文为博主http://www.zuiniusn.com原创文章,未经博主允许不得转载。

时间: 2024-08-03 07:14:28

C# I/O 助手类的相关文章

WorldWind源码剖析系列:代理助手类ProxyHelper

代理助手类ProxyHelper通过平台调用的互操作技术封送了若干Win32结构体和函数.该类类图如下. 提供的主要处理方法基本上都是静态函数,简要描述如下: 内嵌类型WINHTTP_AUTOPROXY_OPTIONS代表自动代理选项的Win32结构体. 内嵌类型WINHTTP_PROXY_INFO代表被WinHTTP互操作返回的代理信息结构体. static extern IntPtr WinHttpOpen()封送Win32动态链接库中的打开Windows Http服务函数. static

WorldWind源码剖析系列:图像助手类ImageHelper

图像助手类ImageHelper封装了对各种图像的操作.该类类图如下. 提供的主要处理方法基本上都是静态函数,简要描述如下: public static bool IsGdiSupportedImageFormat(string imageFileName) 静态函数用给定的图像文件名称来判断该图像是否是Windows GDI+支持的图像. public static Texture LoadTexture(string textureFileName) 静态函数从指定的图像文件路径加载并返回纹

C# SQL数据库助手类2.0(自用)

1 using System; 2 using System.Collections.Generic; 3 using System.Configuration; 4 using System.Data; 5 using System.Data.SqlClient; 6 using System.Text; 7 8 namespace YcTools 9 { 10 /// <summary>C# SQL数据库助手类2.0</summary> 11 public class YSql

Yii2 数组助手类arrayHelper

数组助手类 ArrayHelper 1.什么是数组助手类 Yii 数组助手类提供了额外的静态方法,让你更高效的处理数组. a.获取值(getValue) class User { public $name = 'Alex'; } $array = [ 'foo' => [ 'bar' => new User(),ddd ] ] 获取 name 的值 PHP 方法: $value = isset($array['foo']['bar']->name) ? $array['foo']['na

AES加密解密 助手类 CBC加密模式

string str = "2018"; string result1 = AESHelper.AesEncrypt(str); string result2 = AESHelper.AesDecrypt(result1); namespace Demo { /// <summary> /// AES加密解密 助手类 /// CBC加密模式 /// </summary> public class AESHelper { /// <summary> /

加解密总结(附助手类)

对称加密算法:DES.AES.IDEA.RC2.RC4.SKIPJACK……加解密使用相同密钥,这个是对称加密.对称加密优点是速度快 非对称加密算法:RSA.DSA.DH.ECC.EL GAMAL……公钥加密数据,然后私钥解密的情况被称为加密解密:因为公钥加密的数据只有它相对应的私钥可以解开,所以你可以把公钥给人和人,让他加密他想要传送给你的数据,这个数据只有到了有私钥的你这里,才可以解开成有用的数据,其他人就是得到了,也看懂内容实际应用中,一般都是和对方交换公钥,然后你要发给对方的数据,用他的

考勤助手类图的设计

以上为类图1.0版本,其中在“教务老师”与“信箱”的关系处争议较大,但是从调用关系上来分析我认为这样的设计是没有错误的,所以这个问题大家最终达成一致.至于学生和出勤表之间的联系的确是我的考虑不周,所以是应该做修改的.再有就是一张考勤表应该匹配一张出勤表,所以组合的数量关系上是有错误的,以下是修改后的版本: 根据以上仅考虑重要逻辑部分的类的关系,以及时序图的设计,我将uml类图进行了进一步的补充设计:

Yii的数组助手类

获取值 用原生PHP从一个对象.数组.或者包含这两者的一个复杂数据结构中获取数据是非常繁琐的. 你首先得使用isset 检查 key 是否存在, 然后如果存在你就获取它,如果不存在, 则提供一个默认返回值: Yii 提供了一个非常方便的方法来做这件事: 方法的第一个参数是我们从哪里获取值.第二个参数指定了如何获取数据, 它可以是下述几种类型中的一个: 数组键名或者欲从中取值的对象的属性名称: 以点号分割的数组键名或者对象属性名称组成的字符串,上例中使用的参数类型就是该类型: 返回一个值的回调函数

数据库助手类 DBHelper

using System; using System.Collections.Generic; using System.Text; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Reflection; /// <summary> /// 数据库助手 /// @浅时光 /// #[email protected] /// </summary> name