开发者

How to extgract an integer and a two dimensional integer array from a combination of both in C#

I have an input as

2:{{2,10},{6,4}} 

I am reading this as

string input = Console.ReadLine();

Next this input has to be passed to a function

GetCount(int count开发者_如何学Go, int[,] arr)
{

}

How can I do so using C#?

Thanks


You could use RegularExpressions for extracting in an easy way each token of your input string. In the following example, support for extra spaces is included also (the \s* in the regular expressions).

Remember that always is a great idea to give a class the responsibility of parsing (in this example) rather than taking an procedural approach.

All the relevant lines are commented for better understanding.

Finally, i tested this and worked with the provided sample input strings.

using System;
using System.Text.RegularExpressions;

namespace IntPairArrayParserDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            var input = "2:{{2,10},{6,4}}";
            ParseAndPrintArray(input);

            var anotherInput = "2  : { { 2 , 10 } , { 6 , 4 } }";
            ParseAndPrintArray(anotherInput);
        }

        private static void ParseAndPrintArray(string input)
        {
            Console.WriteLine("Parsing array {0}...", input);

            var array = IntPairArrayParser.Parse(input);

            var pairCount = array.GetLength(0);
            for (var i = 0; i < pairCount; i++)
            {
                Console.WriteLine("Pair found: {0},{1}", array[i, 0], array[i, 1]);
            }
            Console.WriteLine();
        }
    }

    internal static class IntPairArrayParser
    {
        public static int[,] Parse(string input)
        {
            if (string.IsNullOrWhiteSpace(input)) throw new ArgumentOutOfRangeException("input");

            // parse array length from string
            var length = ParseLength(input);

            // create the array that will hold all the parsed elements
            var result = new int[length, 2];

            // parse array elements from input
            ParseAndStoreElements(input, result);

            return result;
        }

        private static void ParseAndStoreElements(string input, int[,] array)
        {
            // get the length of the first dimension of the array
            var expectedElementCount = array.GetLength(0);

            // parse array elements
            var elementMatches = Regex.Matches(input, @"{\s*(\d+)\s*,\s*(\d+)\s*}");

            // validate that the number of elements present in input is corrent
            if (expectedElementCount != elementMatches.Count)
            {
                var errorMessage = string.Format("Array should have {0} elements. It actually has {1} elements.", expectedElementCount, elementMatches.Count);
                throw new ArgumentException(errorMessage, "input");
            }

            // parse array elements from input into array
            for (var elementIndex = 0; elementIndex < expectedElementCount; elementIndex++)
            {
                ParseAndStoreElement(elementMatches[elementIndex], elementIndex, array);
            }
        }

        private static void ParseAndStoreElement(Match match, int index, int[,] array)
        {
            // parse first and second element values from the match found
            var first = int.Parse(match.Groups[1].Value);
            var second = int.Parse(match.Groups[2].Value);

            array[index, 0] = first;
            array[index, 1] = second;
        }

        private static int ParseLength(string input)
        {
            // get the length from input and parse it as int
            var lengthMatch = Regex.Match(input, @"(\d+)\s*:");
            return int.Parse(lengthMatch.Groups[1].Value);
        }
    }
}


Not to do your work for you, you will first have to parse the whole string to find the individual integers, either using regular expressions or, as I would do it myself, the string.Split method. Then parse the substrings representing the individual integers with the int.Parse or the int.TryParse methods.


I doubt you're going to get a serious parsing answer for your custom format. If you NEED to have the value inputted that way, I'd look up some info on regular expressions. If that's not powerful enough for you, there are some fairly convienient parser-generators you can use.

Alternatively, the much more realistic idea would be something like this:

(NOTE: Haven't tried this at all... didn't even put it in VS... but this is the idea...)

int rows = 0;
string rowsInput = "";
do {
    Console.Write("Number of rows:");
    rowsInput = Console.ReadLine();
} while (!Int32.TryParse(rowsInput, out rows);

int columns = 0;
string columnsInput = "";
do {
    Console.Write("Number of columns:");
    string columnsInput = Console.ReadLine();
} while (!Int32.TryParse(columnsInput, out columns);

List<List<int>> values = new List<List<int>>();

for (int i = 0; i < rows; i++)
{
    bool validInput = false;
    do {
        Console.Write(String.Format("Enter comma-delimited integers for row #{0}:", i.ToString()));
        string row = Console.ReadLine();
        string[] items = row.split(',');
        int temp;
        validInput = (items.Length == columns) && (from item in items where  !Int32.TryParse(item, out temp) select item).count() == 0;
        if (validInput)
        {
            values.add(
                    (from item in items select Convert.ToInt32(item)).ToList()
            );
        }
    } while (!validInput);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜