Algorithm to take a number and output its English word

依然范特西╮ 提交于 2019-12-23 17:33:54

问题


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 fine but if we have to write up to 100 then it will be lengthy.

Is there a short algorithm or idea for this?


回答1:


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;
}



回答2:


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.




回答3:


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);



回答4:


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...




回答5:


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;
}



回答6:


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.




回答7:


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");
    }
}

}




回答8:


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);

}



回答9:


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 


来源:https://stackoverflow.com/questions/6951913/algorithm-to-take-a-number-and-output-its-english-word

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!