开发者

Algorithm to take a number and output its English word

I want to make a program in C which will ask the user to input a number and then it will print that number in English.

For example:

if(INPUT == 1) then print ONE
if(INPUT == 2) then print TWO

and so on. It can be made using switch-case and if else but it makes the code lengthy. For few numbers it's 开发者_如何学Pythonfine but if we have to write up to 100 then it will be lengthy.

Is there a short algorithm or idea for this?


You can use the below, but this prints only upto thousands. I did this to solve some particular programming problem. Thats why i did not extend beyond thousands. But its not hard to extend for bigger number. Also, this program can be still optimized or made more clearer.

#include <stdio.h>
#include <string.h>

void print(int num) {
    char digit [21][10] = { "", "one", "two", "three", "four", "five", "six", "seven",
                          "eight", "nine", "ten", "eleven", "twelve", "thirteen", 
                          "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                          "nineteen"};
    char tens [11][10] = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", 
                         "seventy", "eighty", "ninety"};
    char str[1000] = {0};
    int prev=0, div=1000;
    strcpy(str, "");

    while(div) {

        if ((num / div) % 10 > 0 || (div == 10 && (num%100) > 0)) { 

            if (prev) {
                strcat(str, "and");
                prev = 0;
            }

            switch(div) {
            case 1000:
                strcat(str, digit[(num / div) % 10]);     
                strcat(str, "thousand");
                prev = 1;
                break;
            case 100:
                strcat(str, digit[(num / div) % 10]);     
                strcat(str, "hundred");
                prev = 1;
                break;
            case 10:
                if ( (num%100) >= 10 && (num%100) <= 19)
                    strcat(str, digit[num%100]);
                else {
                    strcat(str, tens[(num%100)/10]);
                    strcat(str, digit[num%10]);
                }
                break;
            }
        }

        div /= 10;
    }
    printf("%d %s\n", num, str);

}
int main(int argc, char **argv) {

    long sum = 0;
    int count = 0;

    if (argc <= 1) {
        fprintf(stderr, "wrong number of arguments\n");
        return -1;
    }

    print(atoi(argv[1]));

    return 0;
}


You can use this it can be used to convert upto first 99 integers to words. and its a bit simple. have a look:

void main()
{
int n,m,j;
clrscr();
printf("Enter any number between 1 to 99 : ");
scanf("%d",&n);
printf("You entered ");
if(n>0&&n<=10)
goto one;
else if (n>10&&n<20)
{
m=n%10;
goto two;
}
else if(n>20&&n<100)
{
j=n/10;
n=n%10;
goto three;
}
two:
switch(m)
{
case 1:printf("eleven ");
break;
case 2:printf("twelve ");
break;
case 3:printf("thirteen ");
break;
case 4:printf("fourteen ");
break;
case 5:printf("fifteen ");
break;
case 6:printf("sixteen ");
break;
case 7:printf("seventeen ");
break;
case 8:printf("eighteen ");
break;
case 9:printf("nineteen ");
break;
}
three:
switch(j)
{
case 2:printf("twenty ");
goto one;
case 3:printf("thirty ");
goto one;
case 4:printf("fourty ");
goto one;
case 5:printf("fifty ");
goto one;
case 6:printf("sixty ");
goto one;
case 7:printf("seventy ");
goto one;
case 8:printf("eighty ");
goto one;
case 9:printf("ninety ");
goto one;
}
one:
switch(n)
{
case 1:printf("one ");
break;
case 2:printf("two ");
break;
case 3:printf("three ");
break;
case 4:printf("four ");
break;
case 5:printf("five ");
break;
case 6:printf("six ");
break;
case 7:printf("seven ");
break;
case 8:printf("eight ");
break;
case 9:printf("nine ");
break;
case 10:printf("ten ");
break;
}
getch();
}

Hope this helps.


Just use recursion . I dont have enough time to test it, so this code might be buggy, but you can easily extend it.

public static void convertNum(int number) {

    String[] digit = { "", "one", "two", "three", "four", "five", "six",
            "seven", "eight", "nine", "ten", "eleven", "twelve",
            "thirteen", "fourteen", "fifteen", "sixteen", "seventeen",
            "eighteen", "nineteen" };
    String[] tens = { "", "", "twenty", "thirty", "forty", "fifty",
            "sixty", "seventy", "eighty", "ninety" };

    if (number > 0 && number < 20)
        System.out.print(digit[number]);

    else if (number / 1000000 > 0) {

        convertNum(number / 1000000);
        System.out.print(" million ");
        convertNum(number % 1000000);

    }

    else if (number / 100000 > 0) {

        convertNum(number / 100000);
        System.out.print(" lukh ");
        convertNum(number % 100000);

    }

    else if (number / 1000 > 0) {

        convertNum(number / 1000);
        System.out.print(" thousand ");
        convertNum(number % 1000);

    }

    else if (number / 100 > 0) {

        convertNum(number / 100);
        System.out.print(" hundred ");
        convertNum(number % 100);

    }

    else if (number / 10 >= 2) {

        System.out.print(" " + tens[number / 10] + " ");
        convertNum(number % 10);

    }

}   

convertNum (9191197);


What you need is a recursive function which calls itself after ones,tens,hundreth and thousand digits.

For eg.

num_to_string(num = 344384)
{
    if( haslakh())
    num_to_string(3);print("lakh");
    if( hasthou())
    num_to_string(44);print("thousand");
    if( hashundrer())
    num_to_string(38);print("hundred");
    num_to_string(4);
    if( num is from 1 to 9 ) print one..nine;
    if( num if from 10 to 90 ) print ten to ninty;
}


I would be surprised if the humanity didn't implement it a thousands (sorry: 1000) already.

So I checked on Github and a found at least a few.

I haven't contributed any of them.


I'm having trouble thinking of a good way to automate this and still make it short. If you know the end point (i.e you want to go 1-100), then you could do something like this:

char* numberArray[101] = {'Zero', 'One', 'Two' ... , 'One Hundred'};

And then when you receive input, simply use the number to access that array index, and it will spit out your answer:

int input;
cin >> input; // input = 5
cout << numberArray[input]; // outputs: Five

I apologize if my syntax is wrong, I've been doing PHP and javaScript for so long now I don't remember C syntax all that well...


This is what I wrote, this is very easily extensible to any size. I've not cleaned up some things which I could but the logic works very fine

import java.util.Arrays; import java.util.Scanner;

public class NumReader {

static final String[] units = {"", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
static final String[] tens = {"", null, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
static final String[] teens = {"ten", "eleven", "twelve", "thrirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
static final String hundredSuffix = "hundred";
static final String[] suffixes = {"", "thousand", "million", "billion"};

static boolean isValid(int num) {
    return (num <= 1000000000 && num >= 0);
}
static String numToString(int inpNum) {
    return numToString(inpNum, String.valueOf(inpNum).toCharArray());
}
static String numToString(int inpNum, char[] digits) {
    return numToString(inpNum, digits, false);
}
static String numToString(int inpNum, char[] digits, boolean firstCall) {
    StringBuilder b = new StringBuilder();
    if (inpNum == 0 && firstCall) {
        return "zero";
    } else if (inpNum < 10) {
        return units[inpNum];
    } else if (inpNum < 20) {
        return teens[inpNum - 10];
    } else if (inpNum < 100) {
        b.append(tens[digits[0] - '0']).append(" ").append(units[digits[1] - '0']);
        return b.toString();
    } else if (digits.length == 3) {
        String sub = new String(Arrays.copyOfRange(digits, 1, 3));
        b.append(units[digits[0] - '0']).append(" ")
                .append(hundredSuffix);
        sub = numToString(Integer.parseInt(sub), Arrays.copyOfRange(digits, 1, 3));
        if (sub.equals("")) {
            b.append(sub);
        } else {
            b.append(" and ").append(sub);
        }
        return b.toString();
    } else if (digits.length > 3) {
        int numSuffixes = digits.length / 3;
        int initCut = digits.length % 3;
        int i;
        String sub, opt = "";
        for (i = 0; i < numSuffixes; i++) {
            int end = digits.length - 3 * i;
            sub = new String(Arrays.copyOfRange(digits, end - 3, end));
            sub = numToString(Integer.parseInt(sub));
            opt = (sub.equals("")) ? opt : (sub + " " + suffixes[i] + " " + opt);
        }
        if (initCut != 0) {
            sub = new String(Arrays.copyOfRange(digits, 0, initCut));
            opt = numToString(Integer.parseInt(sub)) + " " + suffixes[i] + " " + opt;
        }
        return opt;
    }
    return "";
}

public static void main(String[] args) {

    Scanner s = new Scanner(System.in);
    int num = s.nextInt();
    if (isValid(num)) {
        System.out.println(numToString(num, String.valueOf(num).toCharArray(), true));
    } else {
        System.out.println("Not a valid input, num <= 1000000000");
    }
}

}


I want to improve kalyan answers. There are 2 errors:

  • There is no space between word. For example: 100 will get result onehundred (no space)
  • In English hundred and thousand need plural form with s. For example 200 -> two hundreds (It needs 's' in result)

Modify code like this will resolve those errors:

void print(int num) {
    char digit [21][10] = { "", "one", "two", "three", "four", "five", "six", "seven",
                      "eight", "nine", "ten", "eleven", "twelve", "thirteen", 
                      "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
                      "nineteen"};
    char tens [11][10] = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", 
                     "seventy", "eighty", "ninety"};
    char str[1000] = {0};
    int prev=0, div=1000;
    strcpy(str, "");

    while(div) {

    if ((num / div) % 10 > 0 || (div == 10 && (num%100) > 0)) {

        if (prev) {
            strcat(str, " and");
            prev = 0;
        }

        switch(div) {
            case 1000:
                if (strlen(str) > 0 && str[strlen(str) - 1] != ' ')
                    strcat(str, " ");
                strcat(str, digit[(num / div) % 10]);

                if (((num / div) % 10) > 1)
                    strcat(str, " thousands");
                else
                    strcat(str, " thousand");
                prev = 1;
                break;
            case 100:
                if (strlen(str) > 0 && str[strlen(str) - 1] != ' ')
                    strcat(str, " ");

                strcat(str, digit[(num / div) % 10]);

                if (((num / div) % 10) > 1)
                    strcat(str, " hundreds");
                else
                    strcat(str, " hundred");

                prev = 1;
                break;
            case 10:
                if ( (num%100) >= 10 && (num%100) <= 19)
                {
                    if (strlen(str) > 0 && str[strlen(str) - 1] != ' ')
                        strcat(str, " ");

                    strcat(str, digit[num%100]);
                }
                else {
                    if (strlen(str) > 0 && str[strlen(str) - 1] != ' ')
                        strcat(str, " ");
                    strcat(str, tens[(num%100)/10]);

                    if (strlen(str) > 0 && str[strlen(str) - 1] != ' ')
                        strcat(str, " ");

                    strcat(str, digit[num%10]);
                }
                break;
            }
        }

        div /= 10;
    }
    printf("%d %s\n", num, str);

}


Here's another way. Not sure of the merits efficiency vs. memory vs. speed, but It is easy to add code to handle more digits.

/* File : num_to_words_int.c
*
*  Descr: Prints the equivalent number in words. '1' to 'one', etc.
*     This version takes the input and converts it to a numeric vs.
*     a string value. 345 vs. "345". Then uses modulus division to
*     count the number of digits. The count represents the places;
*     i.e. count=5 ==> 10,000 ,, 1,000 ,, 100 ,, 10 ,, 1 are the
*     words that will be needed.
* 
*     300  => count=3 ==>three hundred
*     30   => count=2 ==>thirtey
*     3    => count=1 ==>three
*     13   => count=2 ==>thirteen
*     3456 => count=4 ==>three thousand four hundred fifty six
*     
*     [345], [34 5], [3 4], [3, [0]
*
*  Debugging Option:
*    <run> num_to_words_int.exe number option_mask
*
*          001 - print init   remainder array
*          010 - print filled remainder array
*          100 - print count, index, remainder value
*
*  Author: Gene Bradshaw
*  Date:   09-16-2016     
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math>

void main(int argc, char *argv[])
{
  const int HUNDREDS=0, THOUSANDS=1, MILLIONS=2, BILLIONS=3;
  int i, count, total, remainder[12]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  long number=0, orignum=0;
  char *ones[]  = {"zero","one","two","three","four","five","six","seven","eight","nine"};
  char *teens[] = {"ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
  char *tens[] = {"ten","ten","twenty","thirty","forty","fifty","sixty","seventy","eighty","ninety"};
  char *places[] = {"hundred","thousand","million","billion"};  // place values; 10's, 100'2, etc.


  // ERRORS ARGUMENTS
  if(argc < 2)
  {
    printf("\na number is required as input!\n\n");
    exit(1);
  }
  else if(argc > 3)
  {
    printf("\nonly one number and optionally a flag are required as input!\n\n");
    exit(1);
  }
    else  printf("\n");

    // CONVERT TO WORDS
    if(!(number = atol(argv[1])))   // zero
    {
        printf("number: %d\n%s\n\n", number, ones[0]);
        exit(0);
    }


  // Debugging
  if(argv[2] && (atoi(argv[2]) & 0x01))
    {
    for(i=11; i>-1; i--)    printf("%d %d, ", i, remainder[i]);
    printf("\n\n");
    }

  // GET DIGITS
    if(number < 0)  // Remeber if negative, then make positive
    {
        orignum = number;       number *= -1;
    }

   count=0;
  do{
    remainder[count++] = number%10;
    number/=10;
  }while(number); // int type var converts to '0' when # < 0

  // ERROR DIGIT COUNT
  if (count > 12) 
  {
    printf("\ntoo many digits; up to 12 digits supported!\n\n");
    exit(1);
  }

    // Debugging
  if(argv[2] && (atoi(argv[2]) & 0x02))
  {
        for(i=11; i>-1 ; i--)    printf("%d %d, ", i, remainder[i]);
    printf("\n\n");
    }


    // DISPLAY REMAINDERS
    printf("number: ");  // This if for displaying the reverse remainder[].
    if (orignum < 0) printf("-");

    for(i=count-1; i>-1; i--)
  {
    if(!(i%3) && i)  printf("%d,", remainder[i]);
    else    printf("%d", remainder[i]);
  }
  printf("\n");

    // FIND AND PRINT WORDS
  total = count; i = count-1;                          // counting rules
    if(orignum < 0)     printf("negative ");
  while(count)
  { 
    if(argv[2] && (atoi(argv[2]) & 0x04))              // Debugging
            printf("\nC: %d, i: %d and R: %d\n", count, i, remainder[i]);

    switch(count)
    {
      case 1: 
        // print if not teens or 0
        if(remainder[i+1] != 1 && remainder[i])
          printf("%s ", ones[remainder[i]]);
        break;
      case 2: 
        // teens when 2nd digit is a '1'
        if(remainder[i] == 1)
          printf("%s ", teens[remainder[i-1]]);

        // ones when 1st digit is not a '0'
        else if(remainder[i])
          printf("%s ", tens[remainder[i]]);

        break;
      case 3: // d
        if(remainder[i]){
          printf("%s ", ones[remainder[i]]);
          printf("%s ", places[count-3]);
        }
        break;
      case 4: // k
        if(remainder[i])
          printf("%s ", ones[remainder[i]]);

                if(remainder[i] || (total > 4 && total < 7))
          printf("%s ", places[count-3]);

                break;
      // 10,000   100,000  1,000,000
      // ten tho  hun tho  one million
      case  5: // 10 k
      case  8: // 10 M
      case 11: // 10 B
        if(remainder[i]){  printf("%s ", tens[remainder[i]]); }
        break;
      case  6: // 100 k
      case  9: // 100 M
      case 12: // 100 B
        if(remainder[i]){
          printf("%s ", ones[remainder[i]]); 
          printf("%s ", places[HUNDREDS]);
        }
        break;
      case  7: // M
       if(remainder[i])
          printf("%s ", ones[remainder[i]]);

       if(remainder[i] || (total > 7 && total < 10))
          printf("%s ", places[MILLIONS]);
              break;
      case 10: // B
       if(remainder[i])
          printf("%s ", ones[remainder[i]]);

       if(remainder[i] || (total > 10 && total < 13))
          printf("%s ", places[BILLIONS]);
        break;

            // Add cases to increase digit count supported
            //case 13: //T /*- add code here -*/ break;

            default: break;
    }
    count--; i--;
  }  
  printf("\n\n");
}

Examples:

    $>./num_to_words.exe -1000000
    $>number: -1,000,000
    $>negative one million 

    $>./num_to_words.exe 123456789011
    $>number: 123,456,789,011
    $>one hundred twenty three billion four hundred fifty six million seven hundred eighty nine thousand eleven 

    $>./num_to_words.exe 123456789012
    $>number: 123,456,789,012
    $>one hundred twenty three billion four hundred fifty six million seven hundred eighty nine thousand twelve 

    $>./num_to_words.exe -123456789012
    $>number: -123,456,789,012
    $>negative one hundred twenty three billion four hundred fifty six million seven hundred eighty nine thousand twelve 

    $>./num_to_words.exe 0
    $>number: 0
    $>zero

    $>./num_to_words.exe 1
    $>number: 1
    $>one 
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜