2010-09-24 2 views
6

У меня есть две строки, содержащие буквы и цифры, разделенные пробелами. ex «elza7ma wa2fa fel matab» и «2ana ba7eb el za7ma 2awy 2awy»C# сравнить две строки для совпадающих слов

Что является самым быстрым способом сравнить эти две строки, чтобы узнать, есть ли у них общее слово?

Я попытался разбить один из них с помощью string.split и использовать string.compare для всего массива слов. но это очень медленно, так как я буду сравнивать множество строк.

+0

кажется, что indexOf будет работать быстрее, чем регулярное выражение, однако не знаю, если он быстрее, чем string.compare :). Вы можете попробовать – Danil

+1

Вы действительно хотите * быстрее всего? Вы можете работать буквально * лет * по этой проблеме. Я подозреваю, что вы хотите * достаточно быстро *, и в этом случае вы не дали достаточно информации для решения проблемы. * Какое у вас оборудование, каков ваш бюджет времени и какая проблема типичного размера? * –

+3

Кроме того, что такое «много строк»? Ваши комментарии ниже показывают, что «много» - сотни. Я считаю, что сотни - это невероятно крошечное количество строк *. Это точно? Я бы назвал «много» миллионами или миллиардами строк - как и в, Bing индексирует много строк. Не имея хорошей идеи о размере проблемы, трудно дать вам хороший ответ. –

ответ

14

LINQ решение

"elza7ma wa2fa fel matab".Split() 
         .Intersect("2ana ba7eb el za7ma 2awy 2awy".Split()) 
         .Any(); 

// as a string extension method 
public static class StringExtensions 
{ 
    public static bool OneWordMatches(this string theString, string otherString) 
    { 
     return theString.Split().Intersect(otherString.Split()).Any(); 
    } 
} 

// returns true 
"elza7ma wa2fa fel matab 2ana".OneWordMatches("2ana ba7eb el za7ma 2awy 2awy"); 
+0

Перегрузка 'Split' не берет ни одного символа' char'. Вероятно, лучше всего также указать 'RemoveEmptyEntries' – JaredPar

+0

Вы можете использовать' Split() 'без каких-либо параметров. В этом случае он будет использовать пробелы, вкладки и новые строки в качестве разделителя. – Oliver

+0

Действительно ли это происходит быстрее, или Intersect() также проходит через оба массива? – Sjoerd

5

Я думаю, что самый простой способ разбить строки в слова и использовать набор структуры как HashSet<string> для проверки дубликатов. Например,

public bool HasMatchingWord(string left, string right) { 
    var hashSet = new HashSet<string>(
    left.Split(" ", StringSplitOptions.RemoveEmptyEntries)); 
    return right 
    .Split(" ", StringSplitOptions.RemoveEmptyEntries) 
    .Any(x => hashSet.Contains(x)); 
} 
+1

Можете также добавить проверку равенства, чтобы обрабатывать конфликты (если они есть). –

+0

Является ли кто-нибудь уверенным, что это лучший способ работы? – Marwan

1

Вы можете разделить две строки по слову и построить два хэш-таблиц/словарей. Затем пройдите через оба и добавьте ключи, увеличивающие int в третьем словаре (Dictionary<string, int>). Если какой-либо ключ в третьем словаре имеет число более одного, это слово находится в обеих исходных строках.

Я бы подумал, что любой алгоритм для решения этой проблемы будет «медленным» - особенно для больших входных строк/множества слов.

+0

Добавление всех слов в один и тот же HashSet и проверка возвращаемого значения Add() проще. – Sjoerd

+0

Я перечитываю оригинальный вопрос - да было бы намного проще. Он просто спрашивает, есть ли какие-либо слова, которые представлены в обеих строках, а не то, а не сколько случаев. – mbanzon

0

Я бы, вероятно, взял начальный удар производительности и разделил строку, а затем упорядочил по алфавиту и по длине слова. Если вам просто нужно выяснить, совпадает ли одно слово, перерыв, как только вы его найдете. Как только у вас есть массивы разделенных строк, упорядоченные по алфавиту и по длине, это ограничивает количество сравнений, которые вам нужно будет делать.

0
  • Самый простой способ - сравнить все слова с любым другим словом. Это простое решение, но медленное.
  • Другим способом является сортировка обоих списков, а затем сравнение двух верхних позиций. Как mergesort, но с целью найти равные слова.
  • Другой способ состоит в том, чтобы скомпилировать список слов в дерево и сопоставить слова с этим деревом. Регулярное выражение может сделать это, или вы можете сделать это самостоятельно. В вашем примере первая буква должна быть 2, b, e или z. Таким образом, каждое слово проверяется только один раз и проверяется наименьшее количество символов.
Смежные вопросы