Генерация уникальной строки на основе пары строк - PullRequest
2 голосов
/ 24 февраля 2011

У меня есть две строки StringA, StringB. Я хочу создать уникальную строку для обозначения этой пары.

т.е.

f (x, y) должно быть уникальным для каждого x, y и f (x, y) = f (y, x), где x, y - строки

Есть идеи?

Ответы [ 9 ]

4 голосов
/ 24 февраля 2011

Вычислить дайджест сообщения для обеих строк и значения XOR

MD5(x) ^ MD5(Y)

Дайджест сообщения дает вам уникальное значение для каждой строки, а XOR позволяет f (x, y) быть равным f (y, x).

РЕДАКТИРОВАТЬ: Как заметил @Phil H, вы должны обработать случай, в котором вы получите две одинаковые строки в качестве ввода, которое будет генерировать 0 после XOR. Вы можете вернуть что-то вроде MD5(x+y), если x и y одинаковы, и MD5(x) ^ MD5(y) для остальных значений.

3 голосов
/ 24 февраля 2011

Просто создайте новый класс и переопределите Equals & GetHashCode:

class StringTuple
{
    public string StringA { get; set; }
    public string StringB { get; set; }

    public override bool Equals(object obj)
    {
        var stringTuple = obj as StringTuple;
        if (stringTuple == null)
            return false;

        return (StringA.Equals(stringTuple.StringA) && StringB.Equals(stringTuple.StringB)) ||
            (StringA.Equals(stringTuple.StringB) && StringB.Equals(stringTuple.StringA));
    }

    public override int GetHashCode()
    {
        // Order of operands is irrelevant when using *
        return StringA.GetHashCode() * StringB.GetHashCode();
    }
}
2 голосов
/ 24 февраля 2011

Просто найдите уникальный способ упорядочить их и объединить с разделителем.

def uniqueStr(strA,strB,sep):
    if strA <= strB:
        return strA+sep+strB
    else:
        return strB+sep+strA

Для произвольно длинных списков строк, либо отсортируйте список, либо сгенерируйте набор, затем объедините с разделителем:

def uniqueStr(sep,strList):
    return sep.join(Set(strList));

Предпочтительно, если строки длинные или выбор разделителя является проблемой, используйте хэши и хэшируйте результат:

def uniqueStr(sep,strList):
    return hash(''.join([hash(str) for str in Set(strList)]))
1 голос
/ 24 февраля 2011

Я думаю, что следующее должно привести к уникальным строкам:

String f = Replace(StringA<StringB?StringA:StringB,"@","@@") + "}@{" + Replace(StringA<StringB?StringB:StringA,"@","@@")

(то есть в строке есть только одно место, где может появиться один знак "@", и нам не о чем беспокоитьсяо том, что символ @ в конце StringA путают с символом @ в начале StringB.

0 голосов
/ 24 февраля 2011
public static String getUniqString(String x,String y){
    return (x.compareTo(y)<0)?(x+y):(y+x);
}
0 голосов
/ 24 февраля 2011

Хорошо, примите во внимание первую букву каждой строки, прежде чем объединять их?Таким образом, если это в алфавитном порядке, f (x, y) = f (y, x) будет истинным.

if (x> y) c = x + y;иначе с = у + х;

0 голосов
/ 24 февраля 2011

Вы можете использовать x.GetHashCode (). Это не гарантирует, что это будет уникальным, но вполне. Подробнее в этом вопросе .

Например:

public int GetUniqueValue(string x, string y)
{
    unchecked {
        var result = x.GetHashCode() * x.GetHashCode();
        return result;
    }
}
0 голосов
/ 24 февраля 2011

Вы можете просто отсортировать их и объединить их, скажем, скажем, длина первого слова.

Таким образом f("one","two") = "onetwo3", f("two","one") = "onetwo3", и никакая другая комбинация не выдаст эту уникальную строкутак как, e, g, "onet", "wo" даст "onetwo4"

Тем не менее, это будет ужасное решение для разумно длинных строк.

Вы также можете сделать какую-то калькуляцию хеш-кода,как этот

first.GetHashCode() ^ second.GetHashCode()

, который был бы достаточно уникальным, однако вы не можете гарантировать уникальность.

Было бы неплохо, если бы ОП предоставил немного больше контекста, потому что это не звучиткак разумное решение любой проблемы.

0 голосов
/ 24 февраля 2011

А как насчет StringC = StringA + StringB;.

Это гарантированно будет уникальным для любой комбинации StringA или StringB.Или у вас были и другие соображения относительно строки?

Вы можете, например, объединить строки и взять их хэш MD5.Затем вы получите строку, которая, вероятно, является «достаточно уникальной» для ваших нужд, но вы не можете снова вернуть хеш обратно в строки, но вы можете взять те же строки и быть уверенными, что сгенерированный хеш будет таким же в следующий раз.

РЕДАКТИРОВАТЬ

Я видел ваше редактирование сейчас, но я чувствую, что в этом случае нужно только сначала отсортировать строки.Так что-то вроде

StringC = StringA.CompareTo(StringB) < 0 ? StringA + StringB : StringB + StringA;
...