Thread: Numbers to Text revisited

  1. #1
    Registered User
    Join Date
    Sep 2010
    Posts
    42

    Numbers to Text revisited

    I appologize for screwing up the initial thread Bubba. No excuses. I am reposting my changed code and hope everyone is still willing to help a newbie.

    I have my code working but for the life of me I can't get is to write the results to the console. I'm sure its something simple. I just cant seem to get Console.Writeline to show it too me.

    Main
    Code:
     class Program
        {
            static void Main(string[] args)
            {
                NumberString Demo = new NumberString();  //creating a new NumberString object
                Demo.Number = 1234;
                string NumberText = Demo.Text;
                Demo.Text = "one million four hundred seventy five thousand fifteen";
                int n = Demo.Number;
    
                NumberString.numbervalue(Demo.Number);  //calling my method "numbervalue"
    
                Console.WriteLine();
                Console.Read();
            }
    My new class
    Code:
    class NumberString
        {
            public int Number //"Number" is a property of class "NumberString"
            { get; set; }
    
            public string Text  //"Text" is a property of class "NumberString"
            { get; set; }
    
    
            private static string[] undertwenty = new string[]  //Numbers less than twenty
                {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven",
                "twelve", "thirteen", "fourteen", "fifteen", "sixten", "seventeen", "eighteen", "nineteen"};
    
            private static string[] tens = new string[] //two digit numbers twenty and over
                { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninty" };
    
            private static string[] bigs = new string[]  //for numbers 3 digits and over
                { "hundred", "thousand", "million" };
    
            public static string numbervalue(int Number)
            {
    
                if (Number == 0)
                    return undertwenty[0];
    
                int[] groupdigits = new int[4];
    
                int positive = Math.Abs(Number);
    
                for (int i = 0; i < 4; i++)  //seperate into groups
                {
                    groupdigits[i] = positive % 1000;
                    positive /= 1000;
                }
    
                string[] grouptext = new string[4];
                for (int i = 0; i < 4; i++)
                    grouptext[i] = digitstowords(groupdigits[i]);
    
                string combined = grouptext[0];
                bool add_and;
    
                add_and = (groupdigits[0] > 0) && (groupdigits[0] < 100);
    
                for (int i = 1; i < 4; i++)
                {
                    if (groupdigits[i] != 0)
                    {
                        string prefix = grouptext[i] + " " + bigs[i];
                        if (combined.Length != 0)
                            prefix += add_and ? " and " : "' ";
    
                        add_and = false;
    
                        combined = prefix + combined;
                    }
                }
    
                if (Number < 0)
                    combined = "Negative " + combined;
    
                return combined;
            }
    
            private static string digitstowords(int three_digits)
            {
                string grouptext = "";
                int hundreds = three_digits / 100;
                int Tens = three_digits % 100;
    
                if (hundreds != 0)
                {
                    grouptext += undertwenty[hundreds] + " Hundred";
                    if (Tens != 0)
                        grouptext += " and ";
                }
    
                int ten = Tens / 10;
                int ones = Tens % 10;
    
                if (ten >= 2)
                {
                    grouptext += tens[ten];
                    if (ones != 0)
                        grouptext += " " + undertwenty[ones];
                }
                else if (Tens != 0)
                    grouptext += undertwenty[Tens];
    
                return grouptext;
            }
    
        }
    }

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Your numberValue method takes care to return a string object. Your main function should take as much care to not promptly throw that string object straight into the trash.

    Also,
    Code:
    Console.WriteLine(Hey did you want to print something? Where did it go?)

  3. #3
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Thanks tabstop. Watching the debugger I have my converted text in my string "combined"

    "Your main function should take as much care to not promptly throw that string object straight into the trash."

    How do I keep my returned string in main so I can write it to the console?

    Thanks for your help, obviously new at this but trying to learn!

  4. #4
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    You might consider, you know, assigning it to a variable?

  5. #5
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by d2rover View Post
    How do I keep my returned string in main so I can write it to the console?

    Thanks for your help, obviously new at this but trying to learn!
    There's a couple of ways you can do this. You can either save a reference to the string or just put your method call directly in the WriteLine() call:

    Option 1:
    Code:
                string str = NumberString.numbervalue(Demo.Number);
    
                Console.WriteLine(str);
    Option 2:
    Code:
                Console.WriteLine(NumberString.numbervalue(Demo.Number));
    If you understand what you're doing, you're not learning anything.

  6. #6
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Let me see if I am understanding this correctly.
    In option 2 I am telling it to write to the console the return value of my method? Then option 1 is just setting the return value to a string variable then have it write that variable to the console?

    Option 2 looks cleaner but setting it to a variable might be useful if you wanted to manipulate it elsewhere?

    Thank you very much for taking time to help me learn this!

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Yeah, sorry. I wasn't paying attention and didn't realize NumberString.Number was an int. Option 1 should have been:
    Code:
                int num = NumberString.numbervalue(Demo.Number);
    
                Console.WriteLine(num);
    Anyway, you have the concept down. Sometimes it's nice to split it up into 2 lines just to make it easier to read. If you start nesting a bunch of method calls it can get pretty difficult to go back and read it. You could also do manipulation right there too. For instance, if you wanted to show the number multiplied by 2, these all end up printing the same thing:
    Code:
                int num = NumberString.numbervalue(Demo.Number) * 2;
                Console.WriteLine(num);
    Code:
                int num = NumberString.numbervalue(Demo.Number);
                Console.WriteLine(num * 2);
    Code:
                Console.WriteLine(NumberString.numbervalue(Demo.Number) * 2);
    If you understand what you're doing, you're not learning anything.

  8. #8
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Very helpful! Thank you!

    If you were doing this professionally and wanted to go the other way and convert text to a number should it be written in its own class or would you write them both in the same class?

    I am assuming that will take about another 100 lines of code to do the opposite.

    Thanks!!!

  9. #9
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I would put it in the same class. I can see having two constructors, one that takes an int and one that takes a string. Then you could call it like:
    Code:
    NumberString ns1 = new NumberString(12);
    NumberString ns2 = new NumberString("twelve");
    If you understand what you're doing, you're not learning anything.

  10. #10
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    I'm working on going the other way and converting words to numerals. I have it splitting the words up, setting up a List collection, and going into a switch. Its setting each element of the list to the correct numeral. Now I am struggling with the logic/math to put the numerals back together in the correct format. I think I need to start with the "million" then "thousand" ect.

    Can anyone point me the right direction?

    Code:
      public static int digitvalue(string Text)
            {
                string TextToLow = Text.ToLower();                  //set string to lower case
                string[] array = TextToLow.Split(',', ' ');         //take out commas and spaces and put into an array
                List<int> list = new List<int>();                  //set up a list collection of ints
    
                for (int i = 0; i < array.Length; i++)            //loop through my array 
                {
                    string number;
                    number = array[i];
    
                    switch (number)
                    {
                        case "zero":                  //under twentys 0-19
                            list.Add(0);
                            break;
                        case "one":
                            list.Add(1);
                            break;
                        case "two":
                            list.Add(2);
                            break;
                        case "three":
                            list.Add(3);
                            break;
                        case "four":
                            list.Add(4);
                            break;
                        case "five":
                            list.Add(5);
                            break;
                        case "six":
                            list.Add(6); ;
                            break;
                        case "seven":
                            list.Add(7);
                            break;
                        case "eight":
                            list.Add(8);
                            break;
                        case "nine":
                            list.Add(9);
                            break;
                        case "ten":
                            list.Add(10);
                            break;
                        case "eleven":
                            list.Add(11);
                            break;
                        case "twelve":
                            list.Add(12);
                            break;
                        case "thirteen":
                            list.Add(13);
                            break;
                        case "fourteen":
                            list.Add(14);
                            break;
                        case "fifteen":
                            list.Add(15);
                            break;
                        case "sixteen":
                            list.Add(16);
                            break;
                        case "seventeen":
                            list.Add(17);
                            break;
                        case "eighteen":
                            list.Add(18);
                            break;
                        case "nineteen":
                            list.Add(19);
                            break;
                        case "twenty":              //twenty to ninty the "ty's"
                            list.Add(20);
                            break;
                        case "thirty":
                            list.Add(30);
                            break;
                        case "forty":
                            list.Add(40);
                            break;
                        case "fifty":
                            list.Add(50);
                            break;
                        case "sixty":
                            list.Add(60);
                            break;
                        case "seventy":
                            list.Add(70);
                            break;
                        case "eighty":
                            list.Add(80);
                            break;
                        case "ninty":
                            list.Add(90);
                            break;
                        case "hundred":                   //bigs 100's, 1000's, 1000000's 
                            list.Add(100);
                            break;
                        case "thousand":
                            list.Add(1000);
                            break;
                        case "million":
                            list.Add(1000000);
                            break;
                        default:
                            break;
                    }
    
                    
                }
                Console.WriteLine(list.Count);  //list.count gives # of items in "list"
    
                return list[0];
            }
    
        }
    }

  11. #11
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Why not just add them all together?
    Code:
    int sum = 0;
    foreach(int num in list)
      sum += num;
    Or simply:
    Code:
    int sum = list.Sum();
    In fact, you can skip having a List at all and just add to the sum in the switch.
    If you understand what you're doing, you're not learning anything.

  12. #12
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Yes I understand adding up the items in the list. Its the logic part that has me stumped. Say you have the text: "two million four hundred thirty thousand one hundred twenty three"

    If I just add up the list you get: 1001260

    Somehow I've got to grab the million, mutiply it by two and set it aside.

    Then grab the thousand, mutiply it by four hundred thirty and set it aside.

    Grab the hundred multiply it by one then add the twenty and the three.

    Lastly add those three groups together to get 2430123.

    I think this is the way to do it but maybe I'm making it over complicated

  13. #13
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Yes, it is not that simple.
    You can try and work sequentially. For example

    So for example if you have "two million four hundred thirty thousand one hundred twenty three"
    the you would first read "two". Give it a label
    a) Multiplier (i.e. two thousands)


    Then you read a "million". This gain can be
    b) Value to be multiplied

    So you will look at previous and multiply it. If the previous end up being "two hundred" then you can safely multiple 200 x 1000,000. Now at this point MULT = 200 and after this point MULT = 0. So if you read "six" afterwards then you would set MULT=6 and so on.

    There are some special cases, from 11-99. Since you don't say "nine tens" for 90 for example. These are still
    a) Multipliers
    and you just have to add the rule that "if you have two multipliers you just add them up". So if you have "ninety nine" you just have MULT=90+9=99

    Now lets go to the end of the algorithm. Lets see the line "one hundred twenty three". You should have (MULT = 0, SUM = 0)
    Code:
    one -> MULT += 1 = 1
    hundred -> SUM += MULT * 100 = 100; MULT = 0
    twenty -> MULT+= 20
    three -> MULT += 3 = 23
    END -> SUM += MULT = 123
    so basically when you reach the end you just add the multiplier as a value. You would do the same if you reach a b) Value to be multiplied. So for "two million four hundred"
    Code:
    two -> MULT+= 2 = 2
    million -> SUM += MULT * 1000,000 = 2,000,000; MULT = 0
    four -> MULT += 4 = 4
    hundred -> SUM += MULT * 100 = 2,000,400; MULT = 0
    etc etc

    Then you have to the exceptions part!
    What if somebody says "a" hundred rather than one. Or just "hundred". That is not hard to solve. You just have to have a case like
    Code:
    if (MULT == 0) MULT = 1;
    so if the "hundred two" will be equal to "one hundred two" since the MULT=0 will become MULT=1.
    Then just take card the "and" for example "two hundred and two". Probably you just have to emit "and" since it is not really useful at all.

    Don't know if there are other weird cases, there shouldn't be actually. The only thing left is to make this an actual code

  14. #14
    Registered User
    Join Date
    Sep 2010
    Posts
    42
    Thanks for the help. I got the logic working as follows:
    Code:
    foreach (int a in list)
                {
                    int temp;
                    temp = a;
    
                    if (a <= 90)
                        Current += temp;
    
                    if (a == 100)
                        Current *= temp;
    
                    if (a == 1000 || a == 1000000 || a == 1000000000)
                    {
                        Current *= temp;
                        Result += Current;
                        Current = 0;
                    }
                }
                Result += Current;
    
                return Result;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting numbers from a text file with C
    By Help_with_C in forum C Programming
    Replies: 2
    Last Post: 10-19-2010, 04:37 PM
  2. Numbers in Text Format
    By deb_cal2 in forum C Programming
    Replies: 14
    Last Post: 01-24-2008, 04:23 AM
  3. Removing text between /* */ in a file
    By 0rion in forum C Programming
    Replies: 2
    Last Post: 04-05-2004, 08:54 AM
  4. Small HTML question
    By Thantos in forum Tech Board
    Replies: 4
    Last Post: 12-29-2003, 12:37 AM
  5. Ok, Structs, I need help I am not familiar with them
    By incognito in forum C++ Programming
    Replies: 7
    Last Post: 06-29-2002, 09:45 PM