【发布时间】:2013-11-09 20:41:23
【问题描述】:
在 codewars 上工作我试图解决这个问题:
在这个 kata 中,我们要将字符串转换为整数。字符串仅表示单词中的数字。
例子:
- “一”=> 1
- “二十”=> 20
- "246" => 246
- “七十八万三千九百一十九” => 783919
================================================ ====================================
我想出了下面的代码来做到这一点。 On jsfiddle for you convience.
我遇到的一个问题是“七十万”给你 10700。
我花了一天的时间环顾四周并试图弄清楚这一点,但我只是卡住了。程序采取的步骤是:
- 字符串变为“千百七” - 好
- 第一个 while 循环找到“千”并将乘数设置为 1000 - 好
- 第二个 while 循环找到 'hundred' 但随后 mult.exec(a[0]) if 语句解析为 null。 - 该死的
所以乘数不是变成 100000,而是值变成了 100000,我们注定会得到错误的答案。
在尝试调试时,我尝试在 jsfiddle 的 while 中创建第二个循环期间使用的数组。在那里它起作用并等同于“一百”而不是空值。有谁知道为什么会发生这种情况?
function parseInt(number) {
// reference array for english -> integer
var ref = { 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, fifty: 50, sixty: 60, seventy: 70, eighty: 80, ninety:90, hundred: 100, thousand: 1000, million: 1000000 };
// regex to find number values from the string
var find = new RegExp( "(one|t(wo|hree|en|welve|hirteen|wenty|hirty)|f(our|ive|ourteen|iftenn|orty|ifty)|s(ixteen|ixty|eventy|ix|even|eventeen|teen)|eigh(ty|t|teen)|nin(ety|e|eteen)|zero|hundred|thousand|million)", "gi" );
// hundred/thousand/million etc. act as multipliers in this solution and need a seperate search
var mult = new RegExp( "(hundred|thousand|million)", "gi" );
// reversing the string allows us to add largest digits first
number = number.split(' ').reverse().join(" ");
// while there is a number in string number
// if that number is a multiplier
// if that number is 100 -> multiplier = multiplier * 100;
// else multiplier = reference value;
// else value = value + reference value * multiplier
// end while
value = 0; multiplier = 1;
while( a = find.exec(number) ) {
if( m = mult.exec(a[0]) ) {
if( m[0] == 'hundred' ) { multiplier *= 100; }
else { multiplier = ref[m[0]]; }
}
else {
value += ref[a[0]] * multiplier;
}
}
return value;
}
【问题讨论】:
-
这是您正在研究的一个有趣的问题,我不能说我完全理解您的代码。但是,其中有一些陷阱与您的问题没有直接关系。 1) 您可能希望避免与内置的 'parseInt' 函数发生名称冲突。它可能不会影响您的代码行为,但使用这样的内置名称可能是一种不好的做法。
-
2) 您的
find正则表达式没有正确防止匹配正确的前缀 - 在您的示例 JS fiddle 中,当它应该匹配“十七”时,它似乎匹配“七”作为正确的前缀。您需要在正则表达式字符串中包含空格保护以强制进行全字匹配。 -
好主意,我将把它合并到我的法语词法分析器中,当数字变得太大时,建议用数字(int)表示代替单词(字符串)表示。虽然同意@MikeEdwards - 有些情况您可能需要注意:
7将是seven和seventeen的结果,因为RegEx 在找到第一个有效片段时停止匹配(seven)。4在four和fourteen也是另一个例子。您需要一种解决方法,就像他建议的那样。另外,英文中的每个数字都可以分解成30个左右的部分,这不是很有趣吗? -
我应该澄清一下——“这个”并不是指你的代码。我的意思是将法语文字数字表示解析为整数表示的想法,以便在文字表示在文本中“太长”时给出建议。我回头一看,发现我的措辞有点不对劲,我错过了编辑截止日期:)
-
在 JavaScript 中,您应该始终使用正则表达式文字,除非您的正则表达式是动态的。这些似乎不是……
标签: javascript