我正在设计一个系统,用于确定给定文本的人类语言。它的工作原理是为每种感兴趣的语言存储一个字典,然后评估用户输入是否与字典中存储的任何单词相对应。字典中点击率最高的语言就是赢家。
我猜为了让这两个条目,用户的单词和来自"单词列表"文件的单词匹配编码必须是相同的,这就是我想要修复的。
我从这个网站上取了单词列表。
当我在我的代码中使用来自"ASCII"的代码时,一切都工作,但是当我使用来自"Unicode"的代码时,没有任何工作。
这让我感到不安,因为我不希望程序得到一些以错误方式编码的输入(以与我的单词列表数据结构冲突的方式),然后失败。
由于这个原因,我想用一种特定的编码来标准化所有的输入。我认为"Unicode"会更好,因为这是一个确定文本自然语言的系统,我可能会得到一些希腊、俄罗斯或中国字符,而根据我的理解,"ASCII"是高度非标准化的。我目前使用Eclipse的控制台来编写输入。
我是这样读取文件的:
//BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream( dir.toString() ), "UTF-8") );
BufferedReader br = new BufferedReader( new FileReader( dir.toString() ) );
String line = null;
BloomFilter<String> bloomFilter;
if (word_holding_directory_path.toLowerCase().contains("/de/"))
{
bloomFilter = de_bloomFilter;
}
我是这样读取用户输入的:
//Scanner in = new Scanner( System.in , "UTF-8");
Scanner in = new Scanner(System.in);
System.out.println("Please enter a sentence: ");
String[] input_text = in.nextLine().split("\s");
正如您所看到的,我试图强制编码为UTF-8(这与Unicode是一样的,不是吗?),但由于它不起作用,我将其注释掉了。
我是这样比较这两个词的:
for (String word : input_text)
{
String normalized = word.trim().toLowerCase();
if (words.contains(normalized))
{
++count;
}
}
完整的程序在这里github,它很短,相当明确的注释。
您链接的字典似乎是UTF-16LE格式,而不是UTF-8格式。您应该相应地修复InputStreamReader
实例化中的encoding参数。
Unicode和UTF-8最强调的是不是是一回事;事实上,说文本是"Unicode"而不提及编码是不够精确的。1
(您应该能够猜出几年前的ZIP文件可能使用UTF-16LE,这仍然是Windows上的默认设置。新资源通常是UTF-8,即使在Windows上也是如此。
从UTF-16文件中读取一个字符串,从控制台读取另一个包含相同文本的字符串,使用正确的控制台编码将产生两个相等的Java字符串。另一方面,如果其中一个输入流上的编码不正确,那么在字符串中最终得到的内容将基本上是随机伪造的。(在"火车残骸"场景中,您在两个输入上有不同的编码错误,并且碰巧得到两个相等的字符串,而实际上这两个字符串应该包含不同的文本。)
(不确定UTF-8对于控制台是否通常是正确的,或者可能特别在您的环境中—我不是Java程序员。)
1简单地说,抽象的Unicode字符串
U+0066 U+00F6 U+0072
(代表瑞典语för)将被表示为
0x66 0xC3 0xB7 0x72
UTF-8中的(注意普通ASCII字符如何映射到标识表示),以及
0x66 0x00 0xF6 0x00 0x72 0x00
在UTF-16LE(其中每对字节是一个16位序列,MSB设置为零,而LSB容纳整个表示的有效部分)。
在纯ASCII中,此字符串无法表示;很久以前,它会被写成
0x66 0x7C 0x72
,其中0x7C是正确的管道字符|
,它在本地映射到硬件中的字形ö
。(相应地,如果您使用的是应该包含适当管道字符的英语资源,那么也将被呈现为ö
;因此,Unix管道行grep cat food | xxd
将显示为grep cat food ö xxd
。)
稍后,ISO-8859-1开始流行,这个字符串将被表示为
0x66 0xFC 0x72
那当然既简单又有效。为什么Unicode不也这样表示它呢?因为在8位编码中只有256个字符,而Unicode要大得多。你不能代表上海市或машина。