如何正确编写C#helper类以从单行读取多个整数?

时间:2018-02-07 13:14:39

标签: java c#

我试图从Java切换到C#并且还在练习竞争性编程问题,但是我发现C#没有方便的方法从控制台读取单个int,例如{{1 }}。现在公平地说,我也不会在Java中使用这种方法,而是使用辅助类来做类似的事情:

(这是一个静态的内部类):

Scanner.nextInt()

我尝试在C#中重写相同内容,结果如下:

static class InputReader {
    public String[] input;
    public BufferedReader reader;
    ublic int current;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        input = null;
        current = 0;
    }

    public String next() {
    while (input == null || current == input.length) {
        try {
            current = 0;
            input = reader.readLine().split("\\s");
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }

        return input[current++];
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
}

但是当我从问题陈述中粘贴这个序列时,我得到了一个异常(NumberFormatException):

internal static class InputHelper
{
    private static int current;
    private static string[] buffer;

    public static string next()
    {
        while (buffer == null || current == buffer.Length)
        {
            current = 0;
            buffer = Console.ReadLine()?.Split();
        }

        return buffer[current++];
    }

    public static int NextInt()
    {
        return int.Parse(next());
    }
}
编辑:我怀疑是因为Windows Linux上使用了不同的换行符而引发异常,但这可能是完全错误的。

其他时间例如:

3
5 1
3
3 3
1 2 3
4 1
1 

它运作得很好。关于它为什么会出错的任何想法?

2 个答案:

答案 0 :(得分:1)

我不知道你为什么不行,但你可以试试这个:

public static class ConsoleHelper
{
    private static string[] input = new string[0];
    private static int inputIndex;

    public static void ReadNextInput()
    {
        input = Console.ReadLine().Split();
        inputIndex = 0;
    }
    public static int GetNextInt()
    {
        return int.Parse(ReadNextWord());
    }
    public static string GetNextWord()
    {
        return ReadNextWord();
    }

    private static string ReadNextWord()
    {
        if (inputIndex >= input.Length)
        {
            ReadNextInput();
        }

        return input[inputIndex++];
    }
}

我一直在比赛中使用它,直到现在,我从未失败过。

编辑:

你可以尝试这种分割:Split(' ', StringSplitOptions.RemoveEmptyEntries); 这会自动删除输出数组中的空元素。

答案 1 :(得分:1)

  

然而,当我从问题陈述中粘贴这个序列时,我得到了一个异常(NumberFormatException)。

我怀疑这是因为输入上有尾随空格。默认情况下,Split会在遇到不是后跟非分隔符的分隔符时发出空条目。

例如,给定输入1 2(带有两个空格),结果将是["1", "", "2"],因为第一个空格后跟另一个分隔符。类似地,输入1 2 (带有尾随空格)将产生["1", "2", ""],因为最终分隔符没有任何东西。

这通常是一个混乱点,Split的文档并没有很好地告知您:

  

返回:一个数组,其元素包含此实例中由 separator 中的一个或多个字符分隔的子字符串。 [强调我的]

对我来说,这句话意味着连续的分隔符将会被压缩'成为一体,但根本不是它的工作方式。

要避免此行为,请使用接受String.Split的{​​{1}}重载,并指定StringSplitOptions