NLV
NLV

Reputation: 21657

Generate a unique string based on a pair of strings

I've two strings StringA, StringB. I want to generate a unique string to denote this pair.

i.e.

f(x, y) should be unique for every x, y and f(x, y) = f(y, x) where x, y are strings.

Any ideas?

Upvotes: 2

Views: 3303

Answers (9)

user159088
user159088

Reputation:

Compute a message digest of both strings and XOR the values

MD5(x) ^ MD5(Y)

The message digest gives you unique value for each string and the XOR makes it possible for f(x, y) to be equal to f(y, x).

EDIT: As @Phil H observed, you have to treat the case in which you receive two equal strings as input, which would generate 0 after the XOR. You could return something like an MD5(x+y) if x and y are the same, and MD5(x) ^ MD5(y) for the rest of values.

Upvotes: 5

Phil H
Phil H

Reputation: 20151

Just find a unique way of ordering them and concatenate with a separator.

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

For arbitrarily long lists of strings, either sort the list or generate a set, then concatenate with a separator:

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

Preferably, if the strings are long or the separator choice is a problem, use the hashes and hash the result:

def uniqueStr(sep,strList):
    return hash(''.join([hash(str) for str in Set(strList)]))

Upvotes: 2

Jessu
Jessu

Reputation: 2089

public static String getUniqString(String x,String y){
    return (x.compareTo(y)<0)?(x+y):(y+x);
}

Upvotes: 0

HuBeZa
HuBeZa

Reputation: 4761

Just create a new class and override 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();
    }
}

Upvotes: 3

SWeko
SWeko

Reputation: 30932

You could just sort them and concatenate them, along with, lets, say the lenght of the first word.

That way f("one","two") = "onetwo3", f("two","one") = "onetwo3", and no other combination would produce that unique string as , e,g, "onet", "wo" would yield "onetwo4"

However, this will be a abysmal solution for reasonably long strings.

You could also do some sort of hash code calculcation, like this

first.GetHashCode() ^ second.GetHashCode()

that would be reasonably unique, however, you can't guarantee uniqueness.

It would be nice if the OP provided a little more context, because this does not sound like a sound solution to any problem.

Upvotes: 0

&#216;yvind Br&#229;then
&#216;yvind Br&#229;then

Reputation: 60744

What about StringC = StringA + StringB;.

That is guaranteed to be unique for any combination of StringA or StringB. Or did you have some other considerations for the string also?

You can for example combine the strings and take the MD5 hash of it. Then you will get a string that is probably "unique enough" for your needs, but you cannot reverse the hash back into the strings again, but you can take the same strings and be sure that the generated hash will be the same the next time.

EDIT

I saw your edit now, but I feel it's only a matter of sorting the strings first in that case. So something like

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

Upvotes: 0

Alex Hope O&#39;Connor
Alex Hope O&#39;Connor

Reputation: 9724

Well take into consideration the first letter of each string before combining them? So if it is alphabetically ordered f(x, y) = f(y, x) will be true.

if(x > y) c = x + y; else c = y + x;

Upvotes: 0

Marc Climent
Marc Climent

Reputation: 9484

You can use x.GetHashCode(). That not ensures that this will be unique, but quite. See more information in this question.

For example:

public int GetUniqueValue(string x, string y)
{
    unchecked {
        var result = x.GetHashCode() * x.GetHashCode();
        return result;
    }
}

Upvotes: 0

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239824

I think the following should yield unique strings:

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

(That is, there's only one place in the string where a single "@" sign can appear, and we don't have to worry about a run of "@"s at the end of StringA being confused with a run of "@"s at the start of StringB.

Upvotes: 1

Related Questions