在 java 中跟踪转换字符串的原始位置
Track original position of transformed string in java
我正在研究一个源代码抄袭算法(winnowing algorithm)的实现,遇到问题需要帮助。
示例:
我有一个字符串
String test="blahello,,,,/blatestbla7234///§"§$%"%$\n\n23344)§()(§$blablayeahbla";
并将此字符串转换为
test="blahelloblatestblablablayeahbla"
然后根据这个字符串我构建了千克,例如 5 克
blahe lahel ahell hello ellob llobl .... ahbla
我将 kgrams 保存在一个字符串列表中,但也想保存每个 kgram 的原始文本的开始和结束位置,所以我可以在最后引用每个 kgram 回到它们的原始文本位置。
编辑:
所以我的问题是如何得到一个千克的开始和结束位置
有人可以帮我吗?你有什么主意吗?
提前致谢。
如果你想从原始字符串中得到位置,你不能先去除非字母,否则信息会丢失。您要么需要直接在原始字符串中找到 kgrams(更多 CPU 时间),要么将每个字母的原始位置与修改后的字符串一起存储(更多内存 space)。
这是后者的一个实现:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class KGram {
public final String str;
public final int start;
public final int end;
public KGram(String str, int start, int end) {
this.str = str;
this.start = start;
this.end = end;
}
@Override
public String toString() {
return "KGram[\"" + str + "\":" + start + "," + end + "]";
}
public static List<KGram> extractFrom(String input, int size) {
char[] chars = new char[input.length()];
int[] indexes = new int[input.length()];
int len = 0;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (!Character.isLetter(c)) continue;
chars[len] = c;
indexes[len] = i;
len++;
}
List<KGram> kgrams = new ArrayList<>();
for (int i = 0, j = size - 1; j < len; i++, j++) {
String str = new String(Arrays.copyOfRange(chars, i, j + 1));
kgrams.add(new KGram(str, indexes[i], indexes[j]));
}
return kgrams;
}
}
示例:
String test = "blahello,,,,/blatestbla7234///§\"§$%\"%$\n\n23344)§()(§$blablayeahbla";
List<KGram> kgrams = KGram.extractFrom(test, 5);
System.out.println(kgrams.get(4)); // prints KGram["ellob":4,13]
System.out.println(kgrams.get(26)); // prints KGram["ahbla":60,64]
我正在研究一个源代码抄袭算法(winnowing algorithm)的实现,遇到问题需要帮助。
示例: 我有一个字符串
String test="blahello,,,,/blatestbla7234///§"§$%"%$\n\n23344)§()(§$blablayeahbla";
并将此字符串转换为
test="blahelloblatestblablablayeahbla"
然后根据这个字符串我构建了千克,例如 5 克
blahe lahel ahell hello ellob llobl .... ahbla
我将 kgrams 保存在一个字符串列表中,但也想保存每个 kgram 的原始文本的开始和结束位置,所以我可以在最后引用每个 kgram 回到它们的原始文本位置。
编辑:
所以我的问题是如何得到一个千克的开始和结束位置 有人可以帮我吗?你有什么主意吗? 提前致谢。
如果你想从原始字符串中得到位置,你不能先去除非字母,否则信息会丢失。您要么需要直接在原始字符串中找到 kgrams(更多 CPU 时间),要么将每个字母的原始位置与修改后的字符串一起存储(更多内存 space)。
这是后者的一个实现:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class KGram {
public final String str;
public final int start;
public final int end;
public KGram(String str, int start, int end) {
this.str = str;
this.start = start;
this.end = end;
}
@Override
public String toString() {
return "KGram[\"" + str + "\":" + start + "," + end + "]";
}
public static List<KGram> extractFrom(String input, int size) {
char[] chars = new char[input.length()];
int[] indexes = new int[input.length()];
int len = 0;
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (!Character.isLetter(c)) continue;
chars[len] = c;
indexes[len] = i;
len++;
}
List<KGram> kgrams = new ArrayList<>();
for (int i = 0, j = size - 1; j < len; i++, j++) {
String str = new String(Arrays.copyOfRange(chars, i, j + 1));
kgrams.add(new KGram(str, indexes[i], indexes[j]));
}
return kgrams;
}
}
示例:
String test = "blahello,,,,/blatestbla7234///§\"§$%\"%$\n\n23344)§()(§$blablayeahbla";
List<KGram> kgrams = KGram.extractFrom(test, 5);
System.out.println(kgrams.get(4)); // prints KGram["ellob":4,13]
System.out.println(kgrams.get(26)); // prints KGram["ahbla":60,64]