harin04
harin04

Reputation: 281

Extracting values from string input

I am trying an efficient way to split up a string. I have a string in the below format which represents a value.

string input = "1A2B3C4D5DC";

i have to fetch the numeric value next to each character , so that i can compute the final value. Currently im doing this, This works fine, Can you suggest me a better approach.

    public double GetValue(string input)
    {
        string value;
        int beginIndex = 0, endIndex = 0, unit1 = 0, unit2 = 0, unit3 = 0, unit4 = 0, unit5 = 0;
        input = input.Replace("cd", "zz");
        if (input.ToLower().Contains("a"))
        {
            endIndex = input.ToLower().IndexOf('a');
            value = input.Substring(beginIndex, endIndex - beginIndex);
            int.TryParse(value, out unit1);
            beginIndex = endIndex + 1;
        }

        if (input.ToLower().Contains("b"))
        {
            endIndex = input.ToLower().IndexOf('b');
            value = input.Substring(beginIndex, endIndex - beginIndex);
            int.TryParse(value, out unit2);
            beginIndex = endIndex + 1;
        }

        if (input.ToLower().Contains("c") )
        {
            endIndex = input.ToLower().IndexOf('b');
            value = input.Substring(beginIndex, endIndex - beginIndex);
            int.TryParse(value, out unit3);
            beginIndex = endIndex + 1;
        }

        if (input.ToLower().Contains("d"))
        {
            endIndex = input.ToLower().IndexOf('d');
            value = input.Substring(beginIndex, endIndex - beginIndex);
            int.TryParse(value, out unit4);
            beginIndex = endIndex + 1;
        }

        if (input.Length > beginIndex + 2)
        {
            value = input.Substring(beginIndex, input.Length - beginIndex - 2);
            int.TryParse(value, out unit5);
        }

        return (unit1 * 10 + unit2 * 20 + unit3 * 30 + unit4 * 40 + unit5 * 50); //some calculation
    }

Possible inputs can be : 21A34DC , 4C, 2BDC, 2B. basically they all are optional but if present it has to be in the same sequence

Upvotes: 1

Views: 93

Answers (5)

John Alexiou
John Alexiou

Reputation: 29274

Tell me if this produces the expected output:

    static void Main(string[] args)
    {
        int sum = GetValue("1A2B3C4D5DC");
        // {1,2,3,4,5} = 10*(1+2*2+3*3+4*4+5*5) = 550
    }

    public static int GetValue(string input)
    {
        // make input all lowercase
        input = input.ToLower();
        // replace terminator dc with next letter to
        // avoid failing the search;
        input = input.Replace("dc", "e");

        // initialize all unit values to zero
        const string tokens = "abcde";
        int[] units = new int[tokens.Length];

        // keep track of position of last parsed number
        int start = 0;
        for (int index = 0; index < tokens.Length; index++)
        {
            // fetch next letter
            char token = tokens[index];
            // find letter in input
            int position = input.IndexOf(token, start);
            // if found
            if (position>start)
            {
                // extract string before letter
                string temp = input.Substring(start, position-start);
                // and convert to integer
                int.TryParse(temp, out units[index]);
            }
            // update last parsed number
            start = position+1;
        }
        // add unit values, each one worth +10 more than the
        // previous one. 
        //
        // {x,y,z} = 10*x + 20*y + 30*z
        int sum = 0;
        for (int i = 0; i < units.Length; i++)
        {
            sum += 10*(i+1)*units[i];
        }
        return sum;
    }

}

Please add some test cases in the question with the expected results just to make sure our answers are correct.

"1A2B3C4D5DC" => 550
???

Upvotes: 0

harin04
harin04

Reputation: 281

Following code for me ,

public double GetValue(string input)
{
    input)= input)();
    string value;
    int aValue = 0, bValue = 0, cValue = 0, dvalue = 0, cdValue = 0;

    if (match.Groups[5].Success && !string.IsNullOrEmpty(match.Groups[5].Value))
        {
            string val = match.Groups[5].Value;
            if (!int.TryParse(val.Substring(0, val.Length - 2), out cdValue))
            {
                return -1;
            }
        }
        if (match.Groups[4].Success && !string.IsNullOrEmpty(match.Groups[4].Value))
        {
            string val = match.Groups[4].Value;
            if (!int.TryParse(val.Substring(0, val.Length - 1), out dvalue))
            {
                return -1;
            }
        }
        if (match.Groups[3].Success && !string.IsNullOrEmpty(match.Groups[3].Value))
        {
            string val = match.Groups[3].Value;
            if (!int.TryParse(val.Substring(0, val.Length - 1), out cValue))
            {
                return -1;
            }
        }
        if (match.Groups[2].Success && !string.IsNullOrEmpty(match.Groups[2].Value))
        {
            string val = match.Groups[2].Value;
            if (!int.TryParse(val.Substring(0, val.Length - 1), out bValue))
            {
                return -1;
            }
        }
        if (match.Groups[1].Success && !string.IsNullOrEmpty(match.Groups[1].Value))
        {
            string val = match.Groups[1].Value;
            if (!int.TryParse(val.Substring(0, val.Length - 1), out aValue))
            {
                return -1;
            }
        }
        return (aValue  * 10 + bValue * 20 + cValue * 30 + dvalue * 40 + cdValue * 50); //some calculation
}

Upvotes: 0

fkerrigan
fkerrigan

Reputation: 300

Just looking at your code there is a lot of repeating code, so refactoring it "as is" and using a mapping dictionary is likely good solurtion

Something like this

   public static  double GetValue(string input)
    {
        var map = new Dictionary<string, int>()
        {
             {"a", 10 }, {"b", 20}, {"c", 30}, {"d", 40}
        };
        int result = 0;
        foreach(var i in map)
        {
            int endIndex, outValue;
            string value;
            endIndex = input.ToLower().IndexOf(i.Key);
            value = input.Substring(endIndex -1,  1);
            int.TryParse(value, out outValue);

            result += (i.Value * outValue);
        }

        return result;
    }

Upvotes: 0

StepUp
StepUp

Reputation: 38209

If you want to extract just numbers from string, then use Regular Expressions:

string input = "1A2B3C4D5DC";           
var resultString = Regex.Replace(input, @"[^0-9]+", "");

Or linq way:

string input = "1A2B3C4D5DC";            
var  resultString = new String(input.Where(Char.IsDigit).ToArray());

Upvotes: 1

ASh
ASh

Reputation: 35730

you can find all numbers within string with a regular expression:

string input = "1A2B3C4D5DC";
Regex rx = new Regex(@"\d+");
// Regex rx = new Regex(@"-?\d+"); // this one includes negative integers
var matches = rx.Matches(input);

int[] numbers = matches.OfType<Match>()
                       .Select(m => Convert.ToInt32(m.Value))
                       .ToArray();

make necessary computations with resulting array.

Upvotes: 1

Related Questions