【问题标题】:String number approximation字符串数近似
【发布时间】:2014-01-30 15:49:31
【问题描述】:

我在想一个“数字逼近”函数,它接受一个整数并返回一个字符串,类似于以下内容:

45 => "some"
100 => "1 hundred"
150 => "over 1 hundred"
1,386 => "over 1 thousand"
15,235,742 => "over 15 million"
797,356,264,255 => "over 700 billion"

我希望将它用于,例如,以近似的方式表示数据库表中有多少行。

我想不出如何描述这样的东西,所以搜索它有点棘手。

是否有人知道执行此操作的现有函数(最好在 PHP 中),或者任何人都可以描述/指向一个算法以让我开始自己动手?

【问题讨论】:

  • 最好的方法就是做简单的数学运算。获取大小字符串的位数和更精确的前几位数字。您的实施取决于您想要获得的确切原因。有用的是round()abs()do ... while

标签: php integer approximation


【解决方案1】:

看看这个包:http://pear.php.net/package-info.php?package=Numbers_Words

在 cmets 中解释的以下代码可以做到这一点

我给出了两种选择。一个只有文字。您在答案中确切地说的第二个。第一个更容易,因为您不需要再次将单词预先转换为数字。

<?php
require_once "Numbers/Words.php";
$number = new Numbers_Words();
$input = "797,356,264,255";
$input = str_replace(',', '',$input); // removing the comas
$output = $input[0]; // take first char (7)
$output2 = $input[0].'00'; //7 + appended 00 = 700 (for displaying 700 instead of 'seven hundred')
for ($i = 1; $i<strlen($input); $i++) {
    $output .= '0';
}
$words =  $number->toWords($output); //seven hundred billion
$output3 = explode(' ', $words);
$word = $output3[count($output3)-1]; // billion

echo "Over ". $words; // Over seven hundred billion
#####################
echo "Over " . $output2 . ' ' . $word; // Over 700 billion

【讨论】:

    【解决方案2】:

    你想做什么是如此主观。这就是为什么你找不到任何功能来做到这一点。

    对于您的算法,您可以定义一些与模式匹配的字符串。例如:over ** million 匹配 8 位数字。您可以找到前 2 位数字并替换字符串中的 **

    然后你可以使用roundfloorceil等数学函数(这取决于你想要什么),并找到与你的模式对应的字符串。

    【讨论】:

      【解决方案3】:

      经过一番折腾,我想出了这个:

      function numberEstimate($number) {
      // Check for some special cases.
      if ($number < 1) {
          return "zero";
      } else if ($number< 1000) {
          return "less than 1 thousand";
      }
      
      // Define the string suffixes.
      $sz = array("thousand", "million", "billion", "trillion", "gazillion");
      
      // Calculate.
      $factor = floor((strlen($number) - 1) / 3);
      $number = floor(($number / pow(1000, $factor)));
      $number = floor(($number / pow(10, strlen($number) - 1))) * pow(10, strlen($number) - 1);
      return "over ".$number." ".@$sz[$factor - 1];
      }
      

      输出如下内容:

      0 => "zero"
      1 => "less than 1 thousand"
      10 => "less than 1 thousand"
      11 => "less than 1 thousand"
      56 => "less than 1 thousand"
      99 => "less than 1 thousand"
      100 => "less than 1 thousand"
      101 => "less than 1 thousand"
      465 => "less than 1 thousand"
      890 => "less than 1 thousand"
      999 => "less than 1 thousand"
      1,000 => "over 1 thousand"
      1,001 => "over 1 thousand"
      1,956 => "over 1 thousand"
      56,123 => "over 50 thousand"
      99,213 => "over 90 thousand"
      168,000 => "over 100 thousand"
      796,274 => "over 700 thousand"
      999,999 => "over 900 thousand"
      1,000,000 => "over 1 million"
      1,000,001 => "over 1 million"
      5,683,886 => "over 5 million"
      56,973,083 => "over 50 million"
      964,289,851 => "over 900 million"
      769,767,890,753 => "over 700 billion"
      7,687,647,652,973,863 => "over 7 gazillion"
      

      这可能不是最漂亮的解决方案,也不是最优雅的解决方案,但它似乎工作并且做得很好,所以我可能会同意这个。

      感谢大家的指点和建议!

      【讨论】:

        猜你喜欢
        • 2011-05-11
        • 2013-07-10
        • 1970-01-01
        • 2010-09-08
        • 2016-03-28
        • 1970-01-01
        • 2015-02-07
        • 2013-04-15
        • 1970-01-01
        相关资源
        最近更新 更多