Reputation: 21657
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
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
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
Reputation: 2089
public static String getUniqString(String x,String y){
return (x.compareTo(y)<0)?(x+y):(y+x);
}
Upvotes: 0
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
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
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
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
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
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