【C# for OJ/ACM做题】适用于各种OJ的2种C#输入输出辅助类(IOHelper)

来源:互联网 发布:三国志11公孙瓒数据 编辑:程序博客网 时间:2024/05/01 10:31

好像还没见过有人总结出来在各种Online Judge(以下简称OJ)上使用C#时的读写辅助类吧

(用C#做题,读写标准输入输出流的麻烦大家懂的啊,读进来要自行切割后转化,输出,不一定都想去记C#那么特色的字符串格式化标记法)


下面给出2种输入输出类的实现(用来提交一些题目通过,但并没有特别系统的测试)

先说思路

1、读一整行string进来,然后Split()分割开,再按需Parse

2、根据需要的类型(整数还是小数还是别的字符串等),一个个字符读入,并且直接拼接到数中(不再搞成string再转化了)。

方案1的时间效率相对来讲很高(反正轻松虐爆Java就对了,和C的scanf的效率差估计10%吧),但是内存非常浪费,相当于输入文件整体导入到内存里还复制了2遍(string整串1遍,spilt开又是1遍),而且C#催促GC实在是没什么效果你懂的。

方案2的时间效率就比方案1差不少了,但是因为中间避免了string的使用,内存上就没有那么铺张浪费了

具体还请各位看具体题目情况选择。如果内存比较富裕,请选择方案1,如果时间有不小的富裕但内存卡得有点太小了,那请选择方案2


方案1:

(来源:某CF上C#的紫名用户,反正不是我自己+自行修改一些实现细节)

using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.IO;  using System.Numerics;  using E = System.Linq.Enumerable;    namespace CodeForces549H {      class Program {          protected IOHelper io;            public Program(string inputFile, string outputFile) {              io = new IOHelper(inputFile, outputFile, Encoding.Default);                //TODO:在这里实现你的代码            //使用方法:            //读入:io.NextInt()/io.NextDouble()            //输出:io.Write(其他对象)/io.Write(小数类型值,需要的精度)            io.Dispose();          }            static void Main(string[] args) {              Program myProgram = new Program(null, null);          }      }        class IOHelper : IDisposable {          public StreamReader reader;          public StreamWriter writer;            public IOHelper(string inputFile, string outputFile, Encoding encoding) {              if (inputFile == null)                  reader = new StreamReader(Console.OpenStandardInput(), encoding);              else                  reader = new StreamReader(inputFile, encoding);                if (outputFile == null)                  writer = new StreamWriter(Console.OpenStandardOutput(), encoding);              else                  writer = new StreamWriter(outputFile, false, encoding);                curLine = new string[] { };              curTokenIdx = 0;          }            string[] curLine;          int curTokenIdx;            char[] whiteSpaces = new char[] { ' ', '\t', '\r', '\n' };            public bool hasNext() {              if (curTokenIdx >= curLine.Length) {                  //Read next line                  string line = reader.ReadLine();                  if (line != null)                      curLine = line.Split(whiteSpaces, StringSplitOptions.RemoveEmptyEntries);                  else                      curLine = new string[] { };                  curTokenIdx = 0;              }                return curTokenIdx < curLine.Length;          }            public string NextToken() {              return hasNext() ? curLine[curTokenIdx++] : null;          }            public int NextInt() {              return int.Parse(NextToken());          }            public double NextDouble() {              string tkn = NextToken();              return double.Parse(tkn, System.Globalization.CultureInfo.InvariantCulture);          }            public Decimal NextDecimal() {              string tkn = NextToken();              return Decimal.Parse(tkn, System.Globalization.CultureInfo.InvariantCulture);          }            public void Write(double val, int precision) {              writer.Write(val.ToString("F" + precision, System.Globalization.CultureInfo.InvariantCulture));          }          public void Write(Decimal val, int precision) {              writer.Write(val.ToString("F" + precision, System.Globalization.CultureInfo.InvariantCulture));          }            public void Write(object stringToWrite) {              writer.Write(stringToWrite);          }            public void WriteLine(Decimal val, int precision) {              writer.WriteLine(val.ToString("F" + precision, System.Globalization.CultureInfo.InvariantCulture));          }            public void WriteLine(double val, int precision) {              writer.WriteLine(val.ToString("F" + precision, System.Globalization.CultureInfo.InvariantCulture));          }            public void WriteLine(object stringToWrite) {              writer.WriteLine(stringToWrite);          }            public void Dispose() {              try {                  if (reader != null) {                      reader.Dispose();                  }                  if (writer != null) {                      writer.Flush();                      writer.Dispose();                  }              } catch { };          }              public void Flush() {              if (writer != null) {                  writer.Flush();              }          }      }  }  


方案二:

基于夏天的风的C++输入挂修改(http://blog.csdn.net/shahdza/article/details/6317011)

不过C#的泛型和C++的模板类差别有点大,写法完全直接移植臣妾做不到啊555……如果有大神能做到请告诉我

using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.IO;  using System.Numerics;  using E = System.Linq.Enumerable;using InputDataType = System.Double;namespace LowMemReader {    class Program {        static void Main(string[] args) {            //TODO:直接在这里写代码吧,或者你可以在这个类的构造函数里写也没关系            //使用方法:            //1、修改InputDataType为你想要的数据类型,比如System.Int32/System.Int64/System.Double等            //或者你直接把实现里的InputDataType换掉也没关系            //2、int x;            //readPosInt(x);            //返回false表示碰到了EOF,返回True表示读到了数            //readPosInt()读入非负整数            //readInt()读入整数(可正可负)            //readFloat()读入小数(可正可负)            //readString()并没有写,感觉如果延续这个一个个字符读进来并拼接的思路,更加费内存了        }                static bool readPosInt(out InputDataType x){            int c = Console.Read(); x = 0;            for (;c<'0'||c>'9';c = Console.Read())                if (c == -1) return false;            while ('0' <= c && c <= '9') {                x =x * 10 + c - '0';                c = Console.Read();            }            return true;        }        static bool readInt(out InputDataType x){            int c = Console.Read(); x = 0;            for (;c!='-'&&( c < '0' || c > '9'); c = Console.Read()) {                if (c == -1) return false;            }            int sgn = (c == '-') ? -1 : 1;            x = (c == '-') ? 0 : c - '0';            while ((c = Console.Read())>='0' && c <= '9') {                x = x * 10 + c - '0';            }            x *= sgn;            return true;        }        static bool readFloat(out InputDataType x) {            int c = Console.Read(); x = 0; double bit = 0.1;            for (; c != '-' &&c!='.'&& (c < '0' || c > '9'); c = Console.Read()) {                if (c == -1) return false;            }            int sgn = (c == '-') ? -1 : 1;            x = (c == '-') ? 0 : c - '0';            if (c != '.') {                while ((c = Console.Read()) >= '0' && c <= '9') {                    x = x * 10 + c - '0';                }            }            if (c == ' ' || c == '\r' || c == '\n' || c == '\t') { x *= sgn; return true; }            while ((c = Console.Read()) >= '0' && c <= '9') {                x = x + (InputDataType)((c - '0') * bit); bit /= 10;            }            x *= sgn;            return true;        }    }}


0 0
原创粉丝点击