2011-12-19 3 views
0

Мне нужен способ преобразования коллекции строк в уникальную строку. Это означает, что мне нужно иметь другую строку, если какая-либо из строк внутри коллекции изменилась.Как сгенерировать уникальную строку из коллекции строк?

Я работаю над большим решением, поэтому я, возможно, не смогу работать с лучшими идеями. Необходимая уникальная строка будет использоваться для сравнения двух коллекций, поэтому разные строки означают разные коллекции. Я не могу сравнивать строки внутри одного за одним, потому что порядок может измениться, плюс решение уже построено для возврата результата, основанного на сравнении двух строк. Это надстройка. Сгенерированная строка будет передана как параметр для этого сравнения.

Спасибо!

+4

{ «а»,» b "," c "}! = {" a "," c "," b "} или порядок не имеет значения? во-первых, вы должны определить, что представляет собой другая коллекция здесь –

+0

Использовать хэш-алгоритм? MD5, SHA-1 ... –

+1

Если ваша цель - сравнить коллекции, посмотрите на реализацию IEquatable. Erix

ответ

1

Они оба работают, решив использовать разделительный символ «:», а также используя escape-символ, чтобы он стал понятным, когда мы обозначаем что-то другое символом разделителя. Поэтому нам просто нужно избегать всех наших строк, прежде чем конкатенировать их с нашим разделителем между ними. Это дает нам уникальные строки для каждой коллекции. Все, что нам нужно сделать, если мы хотим сделать коллекции одинаковыми независимо от того, нужно ли сортировать нашу коллекцию, прежде чем мы что-нибудь сделаем. Я должен добавить, что мой пример использует LINQ и, таким образом, предполагает сбор реализует IEnumerable<string> и что у вас есть с использованием декларации на System.LINQ

Вы можете обернуть, что в функции следующим образом

string GetUniqueString(IEnumerable<string> Collection, bool OrderMatters = true, string Escape = "/", string Separator = ":") 
{ 
    if(Escape == Separator) 
     throw new Exception("Escape character should never equal separator character because it fails in the case of empty strings"); 
    if(!OrderMatters) 
     Collection = Collection.OrderBy(v=>v);//Sorting fixes ordering issues. 
    return Collection 
     .Select(v=>v.Replace(Escape, Escape + Escape).Replace(Separator,Escape + Separator))//Escape String 
     .Aggregate((a,b)=>a+Separator+b); 
} 
1

Как насчет использования hash function?

+0

хеш-функция не возвращает уникальные строки –

+1

@MoslemBenDhaou Криптографическая хэш-функция почти наверняка вернет уникальные строки. Если вы найдете две строки, которые хеш-то же самое, это будет большой новостью. – BenH

+0

«Ea» и «FB», это просто зависит от простого числа, используемого для хэширования строк. с 32-битным sdk, часто это простое число 31. Это просто разница между «a» и «B». –

0

Под «сборной строкой» вы подразумеваете «набор строк»?

Вот наивный (но рабочий) подход: сортируйте коллекцию (чтобы исключить зависимость от порядка), примирите их и возьмите хэш этого (например, MD5).

Тривиальный для реализации, но не очень умный по производительности.

+0

Да, но функции хэша не возвращают уникальные строки –

+0

MD5 (например) - это 128-битное число. Это целая чертова много разных ценностей. Другие хеши еще больше. Я бы не слишком серьезно относился к столкновениям. –

+0

Реальная проблема с этим решением (как и при использовании многих предложенных решений) является краевым случаем сравнения {«AB», «C»} с {«A», «BC»}. Хеширующая часть действительно хороша (но не нужна) – ForbesLindesay

0

Вы говорите, что вам нужно закодировать строковую коллекцию в виде строки. Например, коллекция {"abc", "def"} может быть закодирована как "sDFSDFSDFSD", но {"a", "b"} может быть закодирована как "SDFeg". Если это так, и вам не нужны уникальные ключи, вы можете использовать что-то вроде SHA или MD5.

+0

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

+0

@Moslem Большинство хеш-функций можно считать уникальными, если размер выборки не огромен, и я имею в виду абсолютно огромный, но если вы не заботитесь о размере результата, вы можете просто конкатенировать их. – ForbesLindesay

1

Учитывая вам ограничение, использовать разделители подхода:

выбрать разделитель и способ побега. , например. использование; и избежать его bwithin строки у \ ;, также избежать \ по \\

Так это список строк ...

"A;bc" 
"D\ef;" 

... становится "A\;bc;D\\ef\;"

Это не очень, но, учитывая что это должна быть строка, тогда старые добрые пути csv и его собратьев не так уж плохи.

Смежные вопросы