简体   繁体   中英

Multiple numbers from strings with-out regex

I am building a console calculator that take as input number as string.

Ex :

string inputNumber = "190+154+114"
double[] number = new double[5];

I would like that string to be converted to an array of number, Example:

number[0] = 190;
number[1] = 154;
number[2] = 114;

I know that there is a library do to it but I want to understand how to read the sign and then put the number into the array.

So far all I could think of is to read the string as a single character then find the '+' characters, I then read the numbers as a character until the character!="null" || character=='+' character!="null" || character=='+' . But the problem is I don't know how to transform into code.

====================================================================== EDIT

I read the answer and I found them really interesting. However, how do I make a new string when a operator sign is inserted?

Ex:

string inputNumber = string.Empty;
string[] number = new string[20];
//Input number
Console.WriteLine("enter a number"); //190+155+220
inputNumber = Console.ReadLine();

so how do get string when an operator is entered, so the new string has to be like this :

number[0] = "190";
number[1] = "155";
number[2] = "220";

This works for me:

string inputNumber = "190+154+114";
double[] number = inputNumber.Split('+').Select(x => double.Parse(x)).ToArray();

I get this:

数字

Of course this gets more complicated when you require other mathematical operation, particularly - with negative numbers, and parenthesis.

What you really need is a way to parse a mathematical expression and produce an expression tree.

My original answer was just to split on the '+' character, but it sounds like you're also going to need to store the operators, and then do some math if you're building a calculator. If that's the case, then here's another way to do it.

First, create an array of the known operators you will work with. Then, we will break up the string by searching for these operators. Each time we find one, we grab the string starting from the previous operator to the current one and store it in our 'numbers' List<double> , then we grab the current operator and store it in our 'operators' List<char> . Finally, we grab the last number (the rest of the string after the last operator).

After you have the numbers in one array and the operators in another, you can verify that there is one more number than operators (because if there's a mismatch, then we may have a bad output). Assuming the string is in a good format, you can store the first number as result , read the next operator and the next number, and do the operation on the result . I'll leave it to you to implement some kind of operator precedence!

Maybe the code is easier to read than all those words:

static void Main()
{
    var knownOperators = new[] { '+', '-', '*', '/' };

    // Get input string from user
    Console.Write("Please input a math string: ");
    string inputNumber = Console.ReadLine(); // "190+154+114";

    var numbers = new List<double>();
    var operators = new List<char>();
    double tmp = 0;

    // We will break up the string by searching for operators. Each time we find
    // one, we grab the string from the previous operator to the current one and
    // store it in 'numbers' as a double, then we grab the current operator and
    // store it in 'operators' as a char. At the very end, we grab the last number.
    var previousOperatorIndex = 0;
    var operatorIndex = inputNumber.IndexOfAny(knownOperators, previousOperatorIndex);
    while (operatorIndex > -1)
    {
        // Add the number part - the string from the previous operator to this one
        if (double.TryParse(inputNumber.Substring(previousOperatorIndex, 
            operatorIndex - previousOperatorIndex), out tmp))
        {
            numbers.Add(tmp);
        }

        operators.Add(inputNumber[operatorIndex]);
        previousOperatorIndex = operatorIndex + 1;
        operatorIndex = inputNumber.IndexOfAny(knownOperators, previousOperatorIndex);
    }
    // Add the last number (after the last operator)
    if (double.TryParse(inputNumber.Substring(previousOperatorIndex), out tmp))
    {
        numbers.Add(tmp);
    }

    // Validate we have one more number than operator
    if (numbers.Count < (operators.Count + 1))
    {
        Console.WriteLine("Error: there were too many operators!");
    }
    else if (numbers.Count > (operators.Count + 1))
    {
        Console.WriteLine("Error: there were too many numbers!");
    }
    else
    {
        // Do the math!
        double result = numbers[0];

        for (int i = 1; i < numbers.Count; i++)
        {
            switch (operators[i - 1])
            {
                case '+':
                    result += numbers[i];
                    break;
                case '-':
                    result -= numbers[i];
                    break;
                case '*':
                    result *= numbers[i];
                    break;
                case '/':
                    result /= numbers[i];
                    break;
                default:
                    break;
            }
        }

        Console.WriteLine("The result is: {0}", result);
    }

    Console.Write("\nDone!\nPress any key to exit...");
    Console.ReadKey();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM