'Converting words to numbers

I have problem converting words into numbers like

Input:

Five Thousand Six Hundred Thirty two

Output:

5632

How can I do this?



Solution 1:[1]

Here, i did it in python, it will help you or someone else from algorithmic perspective.

#!/usr/bin/python

__author__ = 'tomcat'

all = {
        "one" : 1,
        "two" : 2,
        "three" : 3,
        "four" : 4,
        "five" : 5,
        "six" : 6,
        "seven" : 7,
        "eight" : 8,
        "nine" : 9,
        "ten" : 10,
        "eleven": 11,
        "twelve": 12,
        "thirteen": 13,
        "fourteen": 14,
        "fifteen": 15,
        "sixteen": 16,
        "seventeen": 17,
        "eighteen": 18,
        "nineteen": 19,
        "twenty" : 20,
        "thirty" : 30,
        "forty" : 40,
        "fifty" : 50,
        "sixty" : 60,
        "seventy" : 70,
        "eighty" : 80,
        "ninety" : 90,
        "hundred" : 100,
        "thousand" : 1000,
        "million" : 1000000,
        "billion" : 1000000000,
        "trillion" : 1000000000000,
        "quadrillion" : 1000000000000000,
        "quintillion" : 1000000000000000000,
        "sextillion" : 1000000000000000000000,
        "septillion" : 1000000000000000000000000,
        "octillion" : 1000000000000000000000000000,
        "nonillion" : 1000000000000000000000000000000
        };


spliter = {
        "thousand" : 1000,
        "million" : 1000000,
        "billion" : 1000000000,
        "trillion" : 1000000000000,
        "quadrillion" : 1000000000000000,
        "quintillion" : 1000000000000000000,
        "sextillion" : 1000000000000000000000,
        "septillion" : 1000000000000000000000000,
        "octillion" : 1000000000000000000000000000,
        "nonillion" : 1000000000000000000000000000000
        };

inputnumber = raw_input("Please enter string number : ");

tokens = inputnumber.split(" ");

result = 0;
partial_result = 0;
for index in range(len(tokens)):
    if tokens[index] in spliter :
        if partial_result == 0:
            partial_result = 1;
        partial_result *= all[tokens[index]];
        result += partial_result;
        partial_result = 0;
    else:
        if tokens[index] == "hundred" :
            if partial_result == 0:
                partial_result = 1;
            partial_result *= all[tokens[index]];

        else:
            partial_result += all[tokens[index]];


result += partial_result;

print result;

Solution 2:[2]

How would you do this, in general if you didn't have to code it up?? In this example your collection of words is:

Five Thousand Six Hundred Thirty two

We could convert each of those to numbers to get the following collection:

5 1000 6 100 30 2

Starting from 5 (hint: 5 < 1000 is to the left of 1000. This suggests...!??) what steps would you follow in getting to the number 5632?

What if the number was

Six hundred thirty three billion fifty four million two hundred twenty three thousand four?

Can you figure out some sort of rule (or better, an algorithm)?

Once you have broken the big problem down into a collection of little problems then the next battle is to find the correct way of coding something that correctly solves each little problem

Solution 3:[3]

Hope this gives you some start:-

#include <iostream>
#include <string>
#include <map>
using namespace std;

map<string, int> reference;

string ones[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};

void storeOnes(){
    for(int i = 0; i < 11; i++){
        reference[ones[i]] = i;
    }
}

int main(){
    //set up
    storeOnes();
    string test = "onetwothreetwofour";
    string buffer;


    for(int i = 0; i < test.length(); i++){
        buffer.push_back(test.at(i));
        map<string, int>::iterator it = reference.find(buffer);
        if(it != reference.end()){
            cout << (*it).second;
            buffer = "";
        }
    }
    cout << endl << endl;
    system("pause");
    return 0;
}

Solution 4:[4]

Consider using map. Say five thousand six hundred three ten two.

#include<iostream>
#include<map>
using namespace std;

int main()
{
    map<string,int> digits;
    digits["one"] = 1;
    digits["two"] = 2;
    digits["three"] = 3;
    digits["four"] = 4;
    digits["five"] = 5;
    digits["six"] = 6;
    digits["seven"] = 7;
    digits["eight"] = 8;
    digits["nine"] = 9;
    digits["ten"] = 10; 
    digits["hundred"] = 10; 
    digits["thousand"] = 1000;

    const int num_len = 7;
    string num_str[num_len]={"five", "thousand", "six", "hundred", "three", "ten", "two"}; 

    int number = digits[num_str[0]]*digits[num_str[1]] + 
                 digits[num_str[2]]*digits[num_str[3]] +
                 digits[num_str[4]]*digits[num_str[5]] +
                 digits[num_str[6]];

    cout << number;    
}

Solution 5:[5]

Another way to do this is by recursion as is done here (in java and c++)

https://github.com/jman27182818/words_to_numbers

Most of that code is about parsing the string in order to obtain a string vector which can be acted upon recursively. Essentially the algorithms is

A[] = String array //example {"three","hundred"}
Integer converter(A){
    if(length(A) <= 4)
        handle_base_case; 
        //either A only has small values or is of the form 
        //{"three","billion"}  

    //if length is greater than 4 the array must have a large value
    index = find_first_value_greater_than_100(A);
    arrayl = A[1:index-1];
    arrayr = A[index+1:A.end()];
    return (convert_hundreds(arrayl) * Value_of(A[index])+ converter(arrayr) );
    }

where "convert_hundreds" takes an array with strings whose values are no large than 100 each (or 1,000 for spanish) and returns the numerical value. This algorithm is more memory intensive than the previous one but I like it because it seems to generalize to other languages better.

Solution 6:[6]

Here's a process in C++

input : nine thousand nine hundred ninety nine

output: 9999

vector 'talika' looks like this: 9 1000 9 100 9 10 9 1

#include <iostream>
#include <bits/stdc++.h>

using namespace std;

bool endswith(string a, string b)
{
    //To check if the word ends with ty eg. thirty, forty

    int len = a.length();
    string last_two = a.substr(len-2, len-1); //ty

    if((last_two.compare(b)) == 0)return true;

    return false;
}

int main() {

    int t,i,j;
    int n,cnt, num;

    cin >> t;
    getchar();

    map<string, int>conv;
    vector<int>talika;

    conv["one"] = 1;
    conv["two"] = 2;
    conv["three"] = 3;
    conv["four"] = 4;
    conv["five"] = 5;
    conv["six"] = 6;
    conv["seven"] = 7;
    conv["eight"] = 8;
    conv["nine"] = 9;
    conv["ten"] = 10;

    conv["eleven"] = 11;
    conv["twelve"] = 12;
    conv["thirteen"] = 13;
    conv["fourteen"] = 14;
    conv["fifteen"] = 15;
    conv["sixteen"] = 16;
    conv["seventeen"] = 17;
    conv["eighteen"] = 18;
    conv["ninteen"] = 19;


    conv["thousand"] = 1000;
    conv["hundred"] = 100;

    conv["twenty"] = 20;
    conv["thirty"] = 30;
    conv["forty"] = 40;
    conv["fifty"] = 50;
    conv["sixty"] = 60;
    conv["seventy"] = 70;
    conv["eighty"] = 80;
    conv["ninety"] = 90;

    while(t--)
    {
        string num_in_word, ongsho;
        getline(cin,num_in_word);//get the number in words
        stringstream x(num_in_word);

        bool sheshe_ty = false;

        while(getline(x,ongsho, ' '))
        {
            num = conv[ongsho];
            if(endswith(ongsho,"ty"))
            {
                talika.push_back(num/10);
                talika.push_back(10);
                sheshe_ty = true;
                continue;
            }

            talika.push_back(num);
            sheshe_ty = false;
        }

        if(conv[ongsho] != 1000 && conv[ongsho] != 100 && sheshe_ty == false){
            talika.push_back(1);
        }


        num = 0;

        for(i=0;i < talika.size();i++)
        {
            num += talika[i] * talika[i+1];
            i++;
        }

        cout << "The Number: " << num << endl;

        talika.clear();

    }
    return 0;
}

Solution 7:[7]

This may help :

#include <bits/stdc++.h>

using namespace std;

/*
 * Complete the 'getPhoneNumber' function below.
 *
 * The function is expected to return a STRING.
 * The function accepts STRING s as parameter.
 */

string wordsToNumber(string s)
{
    vector<string> allStringNums{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
    vector<string> operations{"double", "triple"};

    string search;
    string ans = "";
    int op = 0;

    for (int i = 0; i < s.length(); i++)
    {
        if (i == s.length() - 1)
        {
            search.push_back(s.at(i));
        }
        if (isspace(s[i]) || i == s.length() - 1)
        {
            // cout << search << endl;
            auto it = find(allStringNums.begin(), allStringNums.end(), search);

            if (it != allStringNums.end())
            {
                if (op > 0)
                {

                    for (int j = 0; j < op; j++)
                    {
                        ans += to_string(it - allStringNums.begin());
                    }

                    op = 0;
                }
                else
                {
                    ans += to_string(it - allStringNums.begin());
                }
            }
            else
            {
                it = find(operations.begin(), operations.end(), search);
                if (it != operations.end())
                {
                    op = (it - operations.begin()) + 2;
                }
                // cout << it - operations.begin() << " " << op << endl;
            }

            search = "";
        }
        else
        {
            search.push_back(s.at(i));
        }
    }
    cout << ans << endl;

    return ans;
}

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    string s;
    getline(cin, s);

    string result = wordsToNumber(s);

    fout << result << "\n";

    fout.close();

    return 0;
}
  • Input Will Be Like one two three four nine five three one or something like one two double three five six triple four six nine

  • Their Outputs Will Be 12349531 and 123356444469

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 KKK
Solution 2
Solution 3 Rahul Tripathi
Solution 4 cpp
Solution 5 jman
Solution 6 Ramisa Anjum Aditi
Solution 7 PIYUSH PUNIYA