use*_*513 20 php numbers cpu-word
我试图将写成单词的数值转换为整数.例如,"iPhone有二十三万七千八百三个应用程序"将成为"iPhone为230783应用程序"
在开始编码之前,我想知道是否存在此转换的任何函数/代码.
Joh*_*ica 22
有很多页面讨论从数字到单词的转换.反方向并没有那么多.我能找到的最好的是Ask Yahoo上的一些伪代码.有关一个不错的算法,请参见http://answers.yahoo.com/question/index?qid=20090216103754AAONnDz:
好吧,总的来说,你做了两件事:找到令牌(翻译成数字的单词)和应用语法.简而言之,您正在为非常有限的语言构建解析器.
您需要的令牌是:
力量:千万,百万,百万
:百
:十,二十,三十......九十
单元:一,二,三,......九,
特别:十,十一,十二,......十九(删除任何"和",因为它们毫无意义.将连字符分成两个标记.这是六十五个应该被处理为"六十""五")
一旦你对你的字符串进行了标记,就从右移到左边.
从右边抓住所有的标记,直到你击中POWER或整个弦.
在这些模式的停止点之后解析标记:
SPECIAL
TEN
UNIT
十个单位
UNIT一百
UNIT一百特殊
UNIT百个十个
单位一百UNIT
UNIT百十个单位(这假定在这个语法中不允许"一千七百")
这将为您提供数字的最后三位数字.
如果你停在整个字符串,你就完成了.
如果您停在电源上,请在步骤1重新开始,直到达到更高的POWER或整个琴弦.
El *_*obo 21
老问题,但是对于遇到这个问题的其他人来说,我今天必须写出一个解决方案.以下采用与John Kugelman描述的算法模糊相似的方法,但不适用于严格的语法; 因此,它将允许一些奇怪的排序,例如"十万和一百万"仍将产生相同的"一百万十万"(1,100,000).无效位(例如拼写错误的数字)将被忽略,因此将无效字符串的输出视为未定义.
根据user132513对joebert答案的评论,我使用了Pear的Number_Words来生成测试系列.以下代码在0到5,000,000之间的数字上获得100%得分,然后在0到10,000,000之间的100,000个数字的随机样本上获得100%(在整个100亿个系列中运行需要很长时间).
/**
* Convert a string such as "one hundred thousand" to 100000.00.
*
* @param string $data The numeric string.
*
* @return float or false on error
*/
function wordsToNumber($data) {
// Replace all number words with an equivalent numeric value
$data = strtr(
$data,
array(
'zero' => '0',
'a' => '1',
'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',
'fourty' => '40', // common misspelling
'fifty' => '50',
'sixty' => '60',
'seventy' => '70',
'eighty' => '80',
'ninety' => '90',
'hundred' => '100',
'thousand' => '1000',
'million' => '1000000',
'billion' => '1000000000',
'and' => '',
)
);
// Coerce all tokens to numbers
$parts = array_map(
function ($val) {
return floatval($val);
},
preg_split('/[\s-]+/', $data)
);
$stack = new SplStack; // Current work stack
$sum = 0; // Running total
$last = null;
foreach ($parts as $part) {
if (!$stack->isEmpty()) {
// We're part way through a phrase
if ($stack->top() > $part) {
// Decreasing step, e.g. from hundreds to ones
if ($last >= 1000) {
// If we drop from more than 1000 then we've finished the phrase
$sum += $stack->pop();
// This is the first element of a new phrase
$stack->push($part);
} else {
// Drop down from less than 1000, just addition
// e.g. "seventy one" -> "70 1" -> "70 + 1"
$stack->push($stack->pop() + $part);
}
} else {
// Increasing step, e.g ones to hundreds
$stack->push($stack->pop() * $part);
}
} else {
// This is the first element of a new phrase
$stack->push($part);
}
// Store the last processed part
$last = $part;
}
return $sum + $stack->pop();
}
Run Code Online (Sandbox Code Playgroud)