嗯,你没有很好地解释你的问题,但这是我的尝试。
首先,你的代码到处都是,即使是这么小的程序,任何人都很难阅读任何内容,我会编辑它以使其可读,但我不确定我是否被允许。
无论如何,二元组=字母、单词或音节对(根据谷歌的说法)。您正在寻找它的相似度值吗?
好吧,我对此做了一些研究,看来您需要的算法就是这个。
现在,让我们开始充实这一点。 OP,如果我误解了你的问题,请纠正我。您正在通过将单词分解为二元组并找到它们各自的相似度值来寻找单词之间的相似性,是吗?如果是这样,让我们在开始使用这个公式之前对其进行分解,因为它肯定是您需要的。
现在,我们有两个词:法国和法语。如果将它们分解为二元组,我们希望找到它们的相似度值。
对于法国,我们有 {FR, RA, AN, NC, CE}
对于法语,我们有 {FR、RE、EN、NC、CH}
France 和 French 旨在表示第一个方程中的 s1 和 s2。接下来,我们获取他们在两个二元组中的匹配。我的意思是,在这两个单词中都可以找到哪些二元组或字母对?在这种情况下,答案是 FR 和 NC。
由于我们找到了 2 对,因此顶部的值变为 4,因为公式规定,2 乘以匹配的二元组的数量。所以我们在顶部有 4 个,没有其他的。
现在,下半部分是通过将您正在比较的每个单词可以组成的二元组数量相加来解决的,即 5 个代表 FRANCE,5 个代表 FRENCH。所以分母是 10
那么现在,我们有什么?我们有 4/10,即 0.4。THAT是我们的相似度值,这就是你在制作程序时需要找到的值。
让我们尝试另一个例子,将其根植于我们的头脑中,比方说
s1 =“歌利亚”
s2 =“守门员”
因此,使用二元组,我们想出了字符串数组......
{"GO","OL","LI","IA","AT","TH"}
{"GO","OA","AL","LI","IE"}
现在,比赛的数量。这两个单词中有多少个匹配的二元组?答案 - 2、GO 和 LI
所以,分子将有
2 x {2 场比赛} = 4
现在,分母是,歌利亚有 6 个二元组,守门员有 5 个二元组。请记住,我们必须根据原始公式将这 2 个值相加,因此我们的分母为 11。
那么,这让我们在哪里?
S(歌利亚, 守门员) = 4/11 ~ .364
我在此链接下找到了公式(以及基本上我刚刚学到的所有内容),这确实使事情变得容易理解。
http://www.catalysoft.com/articles/StrikeAMatch.html http://www.catalysoft.com/articles/StrikeAMatch.html
我将编辑此评论,因为我需要一段时间才能为您的班级提出一个方法,但只是为了快速回复,如果您正在寻找有关如何操作的更多帮助,该链接是一个很好的地方开始。
EDIT****
好的,刚刚为其构建了方法,就在这里。
public class BiGram
{
/*
here are your imports
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
import java.io.FileNotFoundException;
*/
//you'll have to forgive the lack of order or common sense, I threw it
//together fast I could cuz it sounded like you were in a rush
public String[][] bigramizedWords = new String[2][100];
public String[] words = new String[2];
public File file1 = new File("file1.txt");
public File file2 = new File("file2.txt");
public int tracker = 0;
public double matches = 0;
public double denominator = 0; //This will hold the sum of the bigrams of the 2 words
public double results;
public Scanner a;
public PrintWriter pw1;
public BiGram()
{
initialize();
bigramize();
results = matches/denominator;
pw1.println("\n\nThe Bigram Similarity value between " + words[0] + " and " + words[1] + " is " + results + ".");
pw1.close();
}
public static void main(String[] args)
{
BiGram b = new BiGram();
}
public void initialize()
{
try
{
a = new Scanner(file1);
pw1 = new PrintWriter(file2);
while (a.hasNext())
{
//System.out.println("Enter 2 words delimited by a space to calculate their similarity values based off of bigrams.");
//^^^ I was going to use the above line, but I see you are using File and PrintWriter,
//I assume you will have the files yourself with the words to be compared
String gram = a.next();
//pw1.println(gram); -----you had this originally, we don't need this
int line = gram.length();
for(int x=0;x<=line-2;x++)
{
bigramizedWords[tracker][x] = gram.substring(x, x+2);
pw1.println(gram.substring(x, x+2) + "");
}
pw1.println("");
words[tracker] = gram;
tracker++;
}
}
catch(FileNotFoundException e)
{
System.err.format("FileNotExist");
}
}
public void bigramize()
{
denominator = (words[0].length() - 1) + (words[1].length() - 1);
//^^ Let me explain this, basically, for every word you have, let's say BABY and BALL,
//the denominator is gonna be the sum of number of bigrams. In this case, BABY has {BA,AB,BY} or 3
//bigrams, same for BALL, {BA,AL,LL} or 3. And the length of the word BABY is 4 letters, same
//with Ball. So basically, just subtract their respective lengths by 1 and add them together, and
//you get the number of bigrams combined from both words, or 6
for(int k = 0; k < bigramizedWords[0].length; k++)
{
if(bigramizedWords[0][k] != null)
{
for(int i = 0; i < bigramizedWords[1].length; i++)
{
///////////////////////////////////////////
if(bigramizedWords[1][i] != null)
{
if(bigramizedWords[0][k].equals(bigramizedWords[1][i]))
{
matches++;
}
}
}
}
}
matches*=2;
}
}