在代码大战中工作我试图解决这个问题:
在这个kata中我们想要将字符串转换为整数。字符串只代表单词中的数字。
示例:
=============================================== ===================================
我想出了下面的代码来做到这一点。 On jsfiddle for you convience.
我遇到的问题是“七十万”给你10700。
我花了一天时间环顾四周,试图解决这个问题,但我只是陷入困境。该计划采取的步骤是:
因此,乘数不会变为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;
}
答案 0 :(得分:4)
也许你不需要正则表达式
function parse(numbersInString){
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 },
mult = { hundred: 100, thousand: 1000, million: 1000000 },
strNums = numbersInString.split(' ').reverse(),
number = 0,
multiplier = 1;
for(i in strNums){
if( mult[strNums[i]] != undefined ) {
if(mult[strNums[i]]==100) {
multiplier*=mult[strNums[i]]
}else{
multiplier=mult[strNums[i]]
}
} else {
if (!isNaN(parseFloat(strNums[i]))) {
number += parseFloat(strNums[i]) * multiplier;
} else {
var nums = strNums[i].split('-');
number += ((ref[nums[0]]||0) + (ref[nums[1]]||0)) * multiplier;
}
}
}
return number;
}
答案 1 :(得分:1)
感觉mult.exec
应该在while
块中,以便将所有乘数放在一起。
这个小片段
while( a = find.exec(number) ) {
if( m = mult.exec(a[0]) ) {
while(m) {
multiplier *= ref[m[0]];
m = mult.exec(a[0]);
}
}
else {
value += ref[a[0]] * multiplier;
}
}
让事情为七十万工作,但随后为这个庞大的数字而破产。尽管我找不到确切的解决方案,但是number
数组和multiplier
数组中的数百可能是问题的根源。
有趣的小问题。也许有了这个线索,你可以得到其余的想法。
答案 2 :(得分:1)
非常有趣的问题。我认为非常重要的是观察到,当字符串中出现数百,数百万,等等时,它可能是它之前的所有数字,或数字本身。如果它是百,那可能是这甚至不是结束。我们可能不得不在之后成倍增加,比如“十万”。
因此,我将总计算分为3个变量:totalOfUnits
,totalOfHundreds
和totalOfMultitudes
。然后按顺序修改所有数字:
totalOfUnits
totalOfUnit
s == 0,请将100添加到totalOfHundreds
totalOfUnits
> 0,向totalOfHundreds
添加100 *单位,并将totalOfUnits
设为0 totalOfUnits
== 0且数百= = 0,请将众多本身添加到totalOfMultitudes totalOfUnits
> 0或totalOfHundreds
> 0,将多次(totalOfUnits
+ totalOfHundreds
)添加到totalOfMultitudes并将totalOfUnits
和totalOfHundreds
设置为0。最后,返回totalOfUnits
+ totalOfHundreds
+ totalOfMultitudes
。代码适用于所有给定的示例,如下所示:
function parseNumber(num){
var units = {
zero:0, 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
};
var hundreds = {
hundred: 100
};
var multitudes = {
hundred: 100,
thousand: 1000,
million: 1000000
};
var parts = num.split(/[ -]/);
totalOfUnits = 0;
totalOfHundreds = 0;
totalOfMultitudes = 0;
var result = undefined;
for(var i = 0; i < parts.length; i++){
if(units[parts[i]]){
//Add unit
totalOfUnits = totalOfUnits + units[parts[i]];
}else if(hundreds[parts[i]]){
totalOfHundreds += hundreds[parts[i]] * (totalOfUnits || 1);
totalOfUnits = 0;
}else if(multitudes[parts[i]]){
totalOfMultitudes += multitudes[parts[i]] * (((totalOfUnits || 0) + (totalOfHundreds || 0)) || 1);
totalOfUnits = totalOfHundreds = 0;
}
}
return totalOfUnits + totalOfHundreds + totalOfMultitudes;
}
答案 3 :(得分:-1)
这不是一个答案,但我喜欢稍微评论一下这个方法,因为我看不出你怎么可能用你当前的算法解析这些单词。你可以让它适用于一个特定的实例或范围,但它永远不会适用于所有单词的变化。
如果您在数据结构中单独计算所有类型的单位,那将会更容易,也更容易预测,例如
var data = {
millions:3,
hundredThousands:2,
tenThousands:6,
thousands:6,
hundreds:0,
tens:8,
ones:9
};
在计数之后,您可以简单地将所有结果(包括零)串起来以构成整数值。
var value = [
data.millions,
data.hundredThousands,
data.tenThousands,
data.thousands,
data.hundreds,
data.tens,
data.ones
].join('');
return parseInt(value); // 3266089