大家好,我正在完成一个在线练习,我必须创建一个读取多个文本段落的程序。所有数字(以文本形式写入)必须相加,总和显示在最后。
我有几个问题,如果你们不介意回答的话,因为我对此进行了很多研究。
这只是所使用文本的示例:
例如,请记住,您正站在十二点钟的平台上,并且有 五列火车每小时在九条轨道上运行。火车最快可以行驶两百英里 一小时。数百万亿之一...
我正在使用 StringTokenizer,因此每个单词都是单独读取的。
通过研究,我学会了创建代表每个单词的数组(请参阅代码示例),这样单词就可以轻松地表示为整数。虽然我也为每个数字创建了变量,但这可能不是必需的,尽管我不明白Java如何将一个单词表示为它的有效数字。 (再次请参阅代码)。
虽然我最大的问题是如何使用循环组合诸如 2081 = 281 这样的单词。
任何建议将不胜感激,我知道这段代码远非完美,因为我正在继续通过在线 Material 和书籍学习。
class wordsToNumberAdder
{
public static void main()
{
String str = "Just remember that you're standing on a platform at twelve o'clock and there are
five trains that run every hour on nine tracks. A train can go as fast as two hundred miles
an hour. One of millions of billions... ";
StringTokenizer st = new StringTokenizer(str);
String[] digits = {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
String[] tens = {"twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
String[] teens = {"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"};
String[] power = {"hundred","thousand","million","billion"};
int one = 1, two = 2, three = 3, four = 4, five = 5, six = 6, seven = 7, eight = 8, nine = 9;
int twenty = 20, thirty = 30, forty = 40, fifty = 50, sixty = 60, seventy = 70, eighty = 80, ninety = 90;
int ten = 10, eleven = 11, twelve = 12, thirteen = 13, forteen = 14, fifthteen = 15, sixteen = 16;
int eighteen = 18, nineteen = 19, thirty = 30, hundred = 100, thousand = 1000;
long billion = 1000000000;
double result = 0;
double group = 0;
while (set.hasMoreTokens()) {
String word = set.nextToken();
for (int x = 0; x < power.length; i += 3) {
if (word.equals(power[i])) {
group = group * Math.pow(10, i);
result = result + group;
group = 0;
}
}
最佳答案
对我来说,这里有两个子问题:将输入解析为数字短语的集合(“2004”等),并将这些数字短语转换为实际值进行求和。
没有理由不使用映射来进行单词到值的解析。因此,不要尝试所有这些字段,而是尝试一下:
private static final Map<String, Long> NUMBER_MAP;
static {
final Map<String, Long> map = new HashMap<String, Long>();
map.put("one", 1L);
map.put("two", 2L);
map.put("three", 3L);
...
map.put("hundred", 100L);
map.put("hundreds", 100L);
...
map.put("billion", 1000000000L);
map.put("billions", 1000000000L);
NUMBER_MAP = Collections.unmodifiableMap(map);
}
关于此的一些事情:首先,它是不可变的,因此这些映射都不能更改,并且最好尽量减少代码中的可变性。我还添加了几个单词的复数形式以方便解析。可能有一种更优雅的方式来处理这些复数,但我保持简单。我也拥有渴望简单的一切。
现在,进行解析。使用 StringTokenizer 是一个好的开始,但是您并没有用它做太多事情。这是我实现解析的方法:
public static void main(final String[] args) {
final StringTokenizer tokenizer = new StringTokenizer(paragraph.replace(".", " ").toLowerCase());
final StringBuilder phrase = new StringBuilder();
final Set<String> numberSet = NUMBER_MAP.keySet();
while (tokenizer.hasMoreTokens()) {
final String token = tokenizer.nextToken();
if (numberSet.contains(token)) {
if (phrase.length() > 0) {
phrase.append(" ");
}
phrase.append(token);
} else if (!IGNORED_WORDS.contains(token)) {
processPhrase(phrase.toString());
phrase.setLength(0);
}
}
processPhrase(phrase.toString());
}
那么我在这里做了什么?首先,我正在清理输入字符串以处理句点和大写字母。这样我们就可以解析像“一百”这样的句子。然后我使用 StringBuilder 来有效地构建数字短语。如果下一个标记(单词)位于我们的数字的键集中(例如“十八”或“一百”),我会将其添加到当前短语中,如果它不是短语中的第一个单词,则前面加一个空格。 IGNORED_WORDS 是一个(不可变)集合,仅包含字符串“and”。例如,这让我们可以解析“一百一十”。
那么短语到数字的转换怎么样呢?您上面写的循环对我来说没有多大意义。什么是i
?什么是x
?这是什么错别字?我使用的一般方法是一次考虑两个单词。如果只有一个,那就很简单了,我们就完成了。但如果有两个,我们就必须考虑它们的顺序。以“九百”为例。由于第二个值 (100) 大于第一个值 (9),因此我们将它们相乘并将它们添加到总和中。如果之前计算的值大于当前的值,我们只需将它们相加。这样,解析“12200”看起来像:
12 < 1000 : current sum = 12 * 1000 = 12000
2 < 100 : current sum += 2 * 100 = 12000 + 200 = 12200
我没有测试太多,but you can see my implementation of it here .
附录
map 在任何编程语言中都非常酷。映射是一对一(双射)函数:Java 映射中的键是函数的域,键映射到的值是范围。您可以使用 map.keySet()
提取所有键的集合,并使用 map.values()
提取值(其中 map
是一个实例化 Map 变量)。更强大的功能如下:
for (Map.Entry<K, V> entry : map.entrySet()) {
// loop over all entries in the map
}
这实际上是映射中每个映射的迭代器,您可以在每次迭代中获取键和值。
无论如何,如果我们有一个映射变量,然后执行map.keySet()
,我们就会得到该映射中所有键的 Java Set。在这篇文章的实例中,这个集合将包括字符串“一”,“二”,...“十亿”。换句话说,如果我有一个语句“A 映射到 B”的集合,并请求 keySet,我将获得这些语句中的所有“A”。
因此,将 NUMBER_MAP 视为从英文数字(键)到数学数字(值)的映射。从段落中的英文数字开始,我想得到数学数字。为此,我将段落中的值与 map 中的键进行了比较。
关于java - 使用 for 循环将文本中的书面数字转换为总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17381391/