C# 是否在字符串中找到重复内容?
您将如何解决以下问题: 我有一个半大的文本文件(大约10页),我想在这个文本中找到重复的内容。更具体地说,给定一个字符串,找出两个相同的最长字符串 我一直在研究最长的公共子序列: 但这些实现采用两个字符串作为输入 也许已经有服务在做这个了?试试这个C# 是否在字符串中找到重复内容?,c#,algorithm,string,seo,C#,Algorithm,String,Seo,您将如何解决以下问题: 我有一个半大的文本文件(大约10页),我想在这个文本中找到重复的内容。更具体地说,给定一个字符串,找出两个相同的最长字符串 我一直在研究最长的公共子序列: 但这些实现采用两个字符串作为输入 也许已经有服务在做这个了?试试这个 public static string FindLargestDuplicateString( string text) { var largest = string.Empty; for
public static string FindLargestDuplicateString(
string text)
{
var largest = string.Empty;
for (var i = '!'; i <= '}'; i++)
{
var l = FindLargestDuplicateStringImpl(
text, i.ToString());
if (l.Length > largest.Length)
largest = l;
}
return largest;
}
private static string FindLargestDuplicateStringImpl(
string text, string currentLargest)
{
bool found = false;
for (var i = '!'; i <= '}'; i++)
{
var comp = currentLargest + i;
var last = text.LastIndexOf(comp);
var first = text.IndexOf(comp, 0);
if (first == -1 || last == -1 || first == last)
continue;
currentLargest = comp;
found = true;
}
return !found ? currentLargest :
FindLargestDuplicateStringImpl(text, currentLargest);
}
公共静态字符串FindLargestDuplicateString(
字符串(文本)
{
var=string.Empty;
for(变量i='!';i最大.Length)
最大=l;
}
回报最大;
}
私有静态字符串FindLargestDuplicateStringImpl(
字符串文本,字符串(最大)
{
bool-found=false;
对于(var i='!';i您可以这样做
public static ArrayList<String> split(String line){
line+=" ";
Pattern pattern = Pattern.compile("\\w*\\s");
Matcher matcher = pattern.matcher(line);
ArrayList<String> list = new ArrayList<String>();
while (matcher.find()){
list.add(matcher.group());
}
return list;
}
下面是一个简单(但效率低下)的算法:循环所有可能的子字符串长度,从最大值到1。对于每个长度,将该长度的所有子字符串放入字典。如果发现重复的子字符串,请停止。它必须是最大的子字符串。下面是相应的C代码:
公共静态字符串FindDuplicateSubstring(字符串s)
{
对于(int len=s.Length-1;len>0;len--){
var dict=新字典();
对于(int i=0;i,“最长公共子序列”算法不要求匹配是连续的子字符串。例如,对于字符串“computer”和“houseboat”,子序列是“out”。这是您想要的吗
如果希望匹配项是连续的子字符串,则称为。该链接描述了使用后缀树的线性时间和空间算法
如果您想要简短的内容,这里有一种基于LCS算法的方法,但没有表。其思想是在所需子字符串及其副本之间循环所有可能的整数移位。对于每个移位,通过扫描字符串一次,找到最大的连续匹配。如果输入字符串的长度为n,则有O(n)可能的移位和检查每个移位需要O(n)个时间,因此总成本是O(n^2),只有一个固定的空间量。(与我的简单字典答案相比,它需要O(n^3)个时间和O(n^2)个空间。)如果您不希望重叠匹配(即,您希望“bbbbbb”返回“bb”而不是“bbb”),然后在检查每个班次时,如果最大匹配超过班次,则停止。以下是C代码:
公共静态字符串findDuplicateString(字符串s,
bool allowOverlap=错误)
{
int matchPos=0,maxLength=0;
对于(int-shift=1;shift最大长度){
maxLength=匹配计数;
matchPos=i-matchCount+1;
}
如果(!allowOverlap&&(matchCount==shift)){
//我们找到了允许的最大匹配项
//为了这次换班。
打破
}
}else匹配计数=0;
}
}
如果(maxLength>0)返回s.Substring(matchPos,maxLength);
否则返回null;
}
我已经用我的字典答案对此进行了测试,它给出了相同的结果。但是对于长度为3000的随机字符串,字典需要15秒,而上述方法需要60毫秒(并且内存要少得多)。您是否只需要“整字”搜索?在这种情况下,只需将文本拆分为单词,然后使用列表或字典即可。。
public static void duplicatedWords(String s, int n){
ArrayList<String> splitted = split(s);
System.out.println(splitted);
HashMap<String, Integer> map = new HashMap<String, Integer>();
PriorityQueue<String> pq = new PriorityQueue<String>(splitted.size(), new myComp());
for(int i = 0; i<splitted.size(); i++){
if(map.get(splitted.get(i)) == null){
map.put(splitted.get(i), 1);
}
else if(map.get(splitted.get(i)) == 1) {
map.put(splitted.get(i), map.get(splitted.get(i))+1);
pq.add(splitted.get(i));
}
}
int size = pq.size();
for(int i = 0; i<size; i++){
if(i <n)
System.out.println(pq.remove());
else
break;
}
}
public static class myComp implements Comparator{
@Override
public int compare(Object arg0, Object arg1) {
String s1 = (String)arg0;
String s2 = (String)arg1;
return s2.length()-s1.length();
}
}
public static string FindDuplicateSubstring(string s)
{
for (int len = s.Length-1; len > 0; len--) {
var dict = new Dictionary<string, int>();
for (int i = 0; i <= s.Length - len; i++) {
string sub = s.Substring(i, len);
if (dict.ContainsKey(sub)) return sub;
else dict[sub] = i;
}
}
return null;
}
public static string FindDuplicateSubstring(string s,
bool allowOverlap = false)
{
int matchPos = 0, maxLength = 0;
for (int shift = 1; shift < s.Length; shift++) {
int matchCount = 0;
for (int i = 0; i < s.Length - shift; i++) {
if (s[i] == s[i+shift]) {
matchCount++;
if (matchCount > maxLength) {
maxLength = matchCount;
matchPos = i-matchCount+1;
}
if (!allowOverlap && (matchCount == shift)) {
// we have found the largest allowable match
// for this shift.
break;
}
} else matchCount = 0;
}
}
if (maxLength > 0) return s.Substring(matchPos, maxLength);
else return null;
}