我有三個字串
String a = Hello, how are you doing?
String b = Can I as you something?
String c = Hello, how are you doing? Can I ask you something?
我的目標是評估字串 c 是否是字串 a 和 b 的合并。請注意,字串 b 中有一個拼寫錯誤,其中“as”應該是“ask”。
當前的邏輯是(偽代碼):
if
String c contains String a AND String b
then
merge = true
我遇到的問題是,如果在合并程序中字串 c 有細微的變化,則 String.contains() 不再有效,因為它在檢查字串 b 時回傳 false。
是否有可能/想法使用替代且有效的我的示例?
我正在嘗試使用字串相似度(Jaccard 等),但這些都不起作用,因為 a、b 和 c 的大小可能會有所不同,因此很容易/可能獲得正確的相似度百分比。
uj5u.com熱心網友回復:
沒有任何內置函式(我發現)可以做到這一點,但我想出了一些希望適合您需要的東西。你顯然可以改變這個(我試圖讓它盡可能干凈)
第一步:我們需要一個函式,它接受兩個字串并回傳兩者之間的差異數。我想出了這個非常簡單的函式:
public static int getNumberDifferences(String a, String b)
{
int maxLength = Math.max(a.length(), b.length());
int minLength = Math.min(a.length(), b.length());
int result = maxLength - minLength;//the difference in length between the two
for(int i = 0; i < minLength; i )
{
if(a.charAt(i) != b.charAt(i)) //If the characters are different
result ; //Add one to the result
}
return result;
}
所以簡而言之,我們遍歷字串并在每次遇到差異時將差異數量加一。(請注意,一開始我取了兩個字串的長度差,所以這也計算了大小的差異)
第 2 步:我們需要另一個函式來接收每個單詞(在一個陣列中)并回傳它遇到的每個差異。為此,我想出了另一個超級簡單的函式:
public static int getNumberDifferences(String[] a, String[] b)
{
int result = 0;
for(int i = 0; i < Math.min(a.length, b.length); i )
{
result = getNumberDifferences(a[i], b[i]);
}
return result;
}
在這個函式中,我們簡單地添加了字串中每個單詞之間的所有差異。
最后,我們顯示:
public static void main(String[] args)
{
String a = "Hello, how are you doing?" ;
String b = "Can I ask you something?";
String c = "Hello, how are you doing? Can I ask you something?";
int differences = getNumberDifferences(
(a " " b) //Join the two strings with a space in the middle
.split(" "), //Split them to take every word
c.split(" ")); //Split c as well
System.out.println(differences);
}
所以最終的代碼是這樣的:
public class Main {
public static void main(String[] args)
{
String a = "Hello, how are you doing?" ;
String b = "Can I ask you something?";
String c = "Hello, how are you doing? Can I ask you something?";
int differences = getNumberDifferences(
(a " " b) //Join the two strings with a space in the middle
.split(" "), //Split them to take every word
c.split(" ")); //Split c as well
System.out.println(differences);
}
public static int getNumberDifferences(String[] a, String[] b)
{
int result = 0;
for(int i = 0; i < Math.min(a.length, b.length); i )
{
result = getNumberDifferences(a[i], b[i]);
}
return result;
}
public static int getNumberDifferences(String a, String b)
{
int maxLength = Math.max(a.length(), b.length());
int minLength = Math.min(a.length(), b.length());
int result = maxLength - minLength; //the difference in length between the two
for(int i = 0; i < minLength; i )
{
if(a.charAt(i) != b.charAt(i)) //If the characters are different
result ; //Add one to the result
}
return result;
}
}
如果這有幫助,請告訴我:)
uj5u.com熱心網友回復:
如何正確標記注釋,您必須與Levenshtein distance.
您想使用相似度百分比來比較 2 個字串,因此我們可以將此百分比關聯為字串之間的關系距離與參考字串的長度。所以,如果我們需要 100% 的相似性,我們的字串必須絕對相等,并且字串之間的距離為 0。相反:如果我們需要 100% 的相似性,我們的字串必須完全不同,我們的距離幾乎是作為參考字串的長度(或更多)。
我被命名為相似度百分比,allowedDiscrepancy因為它提供了更多資訊。因此,我的代碼具有distance計算參考字串與另一個和compareWithDiscrepancy方法之間距離的方法,以及相關性。檢查這個,它的作業原理。
public class StringUtils {
public static void main(String[] args) {
final String a = "Hello, how are you doing?";
final String b = "Can I as you something?";
final String c = "Hello, how are you doing? Can I ass you something?";
// allowedDiscrepancy = 1.0 (100%) - strings might be absolutely different
//So, we have 2 strings with little difference, so it must be return "true"
assertTrue(compareWithDiscrepancy(c, String.format("%s %s", a, b), 1.0));
// allowedDiscrepancy = 0.0 (0%) - strings must be absolutely equals
//So, we have 2 strings with little difference, but more than 0, so it must be return "false"
assertFalse(compareWithDiscrepancy(c, String.format("%s %s", a, b), 0.0));
final String sameA = "Hello.";
final String sameB = "How are you?";
final String sameC = String.format("%s %s", sameA, sameB);
// allowedDiscrepancy = 1.0 (100%) - strings might be absolutely different
//So, we have 2 strings absolutely equals, so it must be return "true"
assertTrue(compareWithDiscrepancy(sameA, String.format("%s %s", sameA, sameB), 1));
// allowedDiscrepancy = 0.0 (0%) - strings must be absolutely equals
//So, we have 2 strings absolutely equals, so it must be return "true" too
assertTrue(compareWithDiscrepancy(sameC, String.format("%s %s", sameA, sameB), 0));
final String differentA = "Part 1.";
final String differentB = "Part 2.";
final String differentC = "Absolutely different string";
// allowedDiscrepancy = 1.0 (100%) - strings might be absolutely different
//So, we have 2 absolutely different strings, so it must be return "true"
assertTrue(compareWithDiscrepancy(differentC, String.format("%s %s", differentA, differentB), 1));
// allowedDiscrepancy = 0.0 (0%) - strings must be absolutely equals
//So, we have 2 absolutely different strings, so it must be return "false" too
assertFalse(compareWithDiscrepancy(differentC, String.format("%s %s", differentA, differentB), 0));
System.out.println("Done!");
}
public static boolean compareWithDiscrepancy(final String referenceString, final String testedString, double allowedDiscrepancy) {
if (allowedDiscrepancy < 0) allowedDiscrepancy = 0;
if (allowedDiscrepancy > 1) allowedDiscrepancy = 1;
int distance = distance(referenceString, testedString);
double realDiscrepancy = distance * 1.0 / referenceString.length();
if (realDiscrepancy > 1) realDiscrepancy = 1;
return allowedDiscrepancy >= realDiscrepancy;
}
static int distance(String x, String y) {
int[][] dp = new int[x.length() 1][y.length() 1];
for (int i = 0; i <= x.length(); i ) {
for (int j = 0; j <= y.length(); j ) {
if (i == 0) {
dp[i][j] = j;
} else if (j == 0) {
dp[i][j] = i;
} else {
dp[i][j] = min(dp[i - 1][j - 1]
cost(x.charAt(i - 1), y.charAt(j - 1)),
dp[i - 1][j] 1,
dp[i][j - 1] 1);
}
}
}
return dp[x.length()][y.length()];
}
public static int cost(char a, char b) {
return a == b ? 0 : 1;
}
public static int min(int... numbers) {
return Arrays.stream(numbers)
.min().orElse(Integer.MAX_VALUE);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/368302.html
