首页 / 知识

关于算法:使人类易于理解的整数表示形式

2023-04-12 05:31:00

关于算法:使人类易于理解的整数表示形式

Making human readable representations of an Integer

对于那些喜欢这种东西的人来说,这是一个编码问题。 让我们看看您的函数的实现(当然,使用您选择的语言),该函数返回人类可读的指定Integer的String表示形式。 例如:

  • humanReadable(1)返回"一个"。

  • humanReadable(53)返回"五十三个"。

  • humanReadable(723603)返回"七十二万三千六百三十三"。

  • humanReadable(1456376562)返回"十亿,四亿五千六百万,三十六万七千六,五百六十二"。

奖励积分,可提供特别巧妙/优雅的解决方案!

这似乎是没有意义的练习,但是这种算法在现实世界中有很多应用(尽管支持多达十亿个这样的算法可能是过大的了:-)


已经有一个关于这个的问题:
将整数转换为书面数字

答案是C#,但我认为您可以弄清楚。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import math

def encodeOnesDigit(num):
   return ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'][num]

def encodeTensDigit(num):
   return ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'][num-2]

def encodeTeens(num):
   if num < 10:
      return encodeOnesDigit(num)
   else:
      return ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'][num-10]

def encodeTriplet(num):
   if num == 0: return ''
   str = ''
   if num >= 100:
      str = encodeOnesDigit(num / 100) + ' hundred'
   tens = num % 100
   if tens >= 20:
      if str != '': str += ' '
      str += encodeTensDigit(tens / 10)
      if tens % 10 > 0:
         str += '-' + encodeOnesDigit(tens % 10)
   elif tens != 0:
      if str != '': str += ' '
      str += encodeTeens(tens)
   return str

def zipNumbers(numList):
   if len(numList) == 1:
      return numList[0]
   strList = ['', ' thousand', ' million', ' billion'] # Add more as needed
   strList = strList[:len(numList)]
   strList.reverse()
   joinedList = zip(numList, strList)
   joinedList = [item for item in joinedList if item[0] != '']
   return ', '.join(''.join(item) for item in joinedList)

def humanReadable(num):
   if num == 0: return 'zero'
   negative = False
   if num < 0:
      num *= -1
      negative = True
   numString = str(num)
   tripletCount = int(math.ceil(len(numString) / 3.0))
   numString = numString.zfill(tripletCount * 3)
   tripletList = [int(numString[i*3:i*3+3]) for i in range(tripletCount)]
   readableList = [encodeTriplet(num) for num in tripletList]
   readableStr = zipNumbers(readableList)
   return 'negative ' + readableStr if negative else readableStr


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System;

namespace HumanReadable
{
    public static class HumanReadableExt
    {
        private static readonly string[] _digits = {
                                                      "","one","two","three","four","five",
                                                      "six","seven","eight","nine","eleven","twelve",
                                                      "thirteen","fourteen","fifteen","sixteen","seventeen",
                                                      "eighteen","nineteen"
                                                   };

        private static readonly string[] _teens = {
                                                     "","","twenty","thirty","forty","fifty",
                                                     "sixty","seventy","eighty","ninety"
                                                  };

        private static readonly string[] _illions = {
                                                       "","thousand","million","billion","trillion"
                                                    };

        private static string Seg(int number)
        {
            var work = string.Empty;

            if (number >= 100)
                work += _digits[number / 100] +" hundred";

            if ((number % 100) < 20)
                work += _digits[number % 100];
            else
                work += _teens[(number % 100) / 10] +"-" + _digits[number % 10];

            return work;
        }

        public static string HumanReadable(this int number)
        {
            if (number == 0)
                return"zero";
            var work = string.Empty;

            var parts = new string[_illions.Length];

            for (var ind = 0; ind < parts.Length; ind++)
                parts[ind] = Seg((int) (number % Math.Pow(1000, ind + 1) / Math.Pow(1000, ind)));

            for (var ind = 0; ind < parts.Length; ind++)
                if (!string.IsNullOrEmpty(parts[ind]))
                    work = parts[ind] +"" + _illions[ind] +"," + work;

            work = work.TrimEnd(',', ' ');

            var lastSpace = work.LastIndexOf(' ');
            if (lastSpace >= 0)
                work = work.Substring(0, lastSpace) +" and" + work.Substring(lastSpace);

            return work;
        }
    }

    class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine(1.HumanReadable());
            Console.WriteLine(53.HumanReadable());
            Console.WriteLine(723603.HumanReadable());
            Console.WriteLine(1456376562.HumanReadable());
            Console.ReadLine();
        }
    }
}

支持多达999百万,但没有负数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
String humanReadable(int inputNumber) {
  if (inputNumber == -1) {
    return"";
  }
  int remainder;
  int quotient;
  quotient = inputNumber / 1000000;
  remainder = inputNumber % 1000000;
  if (quotient > 0) {
    return humanReadable(quotient) +" million," + humanReadable(remainder);
  }
  quotient = inputNumber / 1000;
  remainder = inputNumber % 1000;
  if (quotient > 0) {
    return humanReadable(quotient) +" thousand," + humanReadable(remainder);
  }
  quotient = inputNumber / 100;
  remainder = inputNumber % 100;
  if (quotient > 0) {
    return humanReadable(quotient) +" hundred," + humanReadable(remainder);
  }
  quotient = inputNumber / 10;
  remainder = inputNumber % 10;
  if (remainder == 0) {
    //hackish way to flag the algorithm to not output something like"twenty zero"
    remainder = -1;
  }
  if (quotient == 1) {
    switch(inputNumber) {
    case 10:
      return"ten";
    case 11:
      return"eleven";
    case 12:
      return"twelve";
    case 13:
      return"thirteen";
    case 14:
      return"fourteen";
    case 15:
      return"fifteen";
    case 16:
      return"sixteen";
    case 17:
      return"seventeen";
    case 18:
      return"eighteen";
    case 19:
      return"nineteen";
    }
  }
  switch(quotient) {
  case 2:
    return"twenty" + humanReadable(remainder);
  case 3:
    return"thirty" + humanReadable(remainder);
  case 4:
    return"forty" + humanReadable(remainder);
  case 5:
    return"fifty" + humanReadable(remainder);
  case 6:
    return"sixty" + humanReadable(remainder);
  case 7:
    return"seventy" + humanReadable(remainder);
  case 8:
    return"eighty" + humanReadable(remainder);
  case 9:
    return"ninety" + humanReadable(remainder);
  }
  switch(inputNumber) {
  case 0:
    return"zero";
  case 1:
    return"one";
  case 2:
    return"two";
  case 3:
    return"three";
  case 4:
    return"four";
  case 5:
    return"five";
  case 6:
    return"six";
  case 7:
    return"seven";
  case 8:
    return"eight";
  case 9:
    return"nine";
  }
}

同意在现实世界中有许多应用。
因此,已经有许多实际的实现。

自从几乎永远以来,它就一直是bsdgames的一部分...

1
> man number

此功能实现存在一个巨大的问题。这是未来的本地化。该功能由说英语的人编写,很可能不适用于英语以外的任何其他语言。除非您确实需要保持通用性,否则几乎不可能为世界上的任何人类语言编写通用的易于本地化的功能。实际上,在现实世界中,您不需要使用巨大的整数进行运算,因此您只需将所有数字保存在一个大(甚至不是那么大)的字符串数组中即可。


算法函数编码问题语言

最新内容

相关内容

热门文章

推荐文章

标签云

猜你喜欢