我有两个字符串StringA,StringB。我想生成一个唯一的字符串来表示这对。基于一对字符串生成一个唯一的字符串
即
F(X,Y)应该为每个x,y和F(X,Y)= F是唯一的(Y,X),其中x,y是字符串。
任何想法?
我有两个字符串StringA,StringB。我想生成一个唯一的字符串来表示这对。基于一对字符串生成一个唯一的字符串
即
F(X,Y)应该为每个x,y和F(X,Y)= F是唯一的(Y,X),其中x,y是字符串。
任何想法?
计算两个字符串的消息摘要和XOR的值
MD5(x)^MD5(Y)
消息摘要为每个字符串提供唯一值,XOR使f(x,y)等于f(y,x)成为可能。
编辑:正如@Phil H所观察到的,您必须将收到两个相等的字符串作为输入的情况,这会在异或之后生成0。如果x和y相同,您可以返回类似于MD5(x+y)
的东西,对于其余值,可以返回MD5(x)^MD5(y)
。
+1,这不是很美,但很实用。 – 2011-02-24 09:11:19
这是相当独特的,并不是真正独特的,因为根据定义,任何散列算法都可以为不同的输入产生相同的输出。 – SWeko 2011-02-24 09:12:01
唯一的问题是MD5(x)^ MD5(x)= 0 - 因此您可以得到任何匹配字符串对的相同结果。 – 2011-02-24 09:17:22
StringC = StringA + StringB;
怎么样。
这对于StringA或StringB的任何组合都是唯一的。或者您是否还有其他一些关于字符串的注意事项?
例如,您可以合并字符串并获取它的MD5哈希值。然后,您将得到一个可能“足够独特”的字符串以满足您的需求,但不能再次将哈希反转回字符串中,但可以采用相同的字符串并确保下次生成的哈希值相同。
编辑
我现在看到你的编辑,但我觉得这只是在这种情况下,第一个排序字符串的问题。因此,像
StringC = StringA.CompareTo(StringB) < 0 ? StringA + StringB : StringB + StringA;
你可以只对它们进行排序和将它们连接起来,伴随着,让,说的第一个字的lenght。
这样f("one","two") = "onetwo3"
,f("two","one") = "onetwo3"
,并没有其他的组合将产生独一无二的字符串作为,E,G,"onet", "wo"
会产生"onetwo4"
然而,这将是相当长的字符串一个糟糕的解决方案。
你也可以做一些散列码calculcation的,像这样的
first.GetHashCode()^second.GetHashCode()
,这将是相当独特的,但是,你不能保证唯一性。
如果OP提供了更多的上下文,那就太好了,因为这听起来不像任何问题的完美解决方案。
只需找到一种独特的排序方式,并与分隔符连接即可。
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)]))
' “onesep”,“two”与“one”,“septwo”一样产生相同的结果 – SWeko 2011-02-24 09:05:20
必须选择分隔符,以便它不是字符串中的有效字符。 – 2011-02-24 09:11:33
@SWeko:添加了哈希连接版本以消除对分隔符的需要,并返回一个固定大小的字符串。 – 2011-02-24 09:22:58
我认为有以下应该产生唯一的字符串:
String f = Replace(StringA<StringB?StringA:StringB,"@","@@") + "}@{" + Replace(StringA<StringB?StringB:StringA,"@","@@")
(也就是说,只有一个在一个单一的“@”符号可以出现在字符串中的地方,我们不必担心在StringA的结尾处运行“@”与在StringB的开始处运行的“@”s相混淆
您可以使用x.GetHashCode()。不能确保这将是唯一的,但相当。查看更多信息in this question。
例如:
public int GetUniqueValue(string x, string y)
{
unchecked {
var result = x.GetHashCode() * x.GetHashCode();
return result;
}
}
那么考虑到每个字符串在组合之前的第一个字母?因此,如果它按字母顺序排列,f(x,y)= f(y,x)将为真。
if(x> y) c = x + y; else c = y + x;
只需创建一个新的类并覆盖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();
}
}
对于组合多个哈希码,“*”通常是一个糟糕的选择 - 如果一个字符串的代码为0,则其他字符串的内容无关紧要,因此所有这些对都会发生冲突。另外,您还需要将其封装在“未选中”的块中,以防止溢出。见例如这个问题的答案:http://stackoverflow.com/questions/263400/what-is-the-best-algorithm-for-an-overridden-system-object-gethashcode – 2011-02-24 09:32:53
@Damien_The_Unbeliever:一般来说,你是对的,但是:(1)字符串散列方法不可能产生0.(2)您必须使用像+或*这样的命令不可知的运算符(您是否有更好的运算符?)。 (3)诅咒你需要将其预处理为'unchecked',并检查空引用(在所有字符串是对象之后)并使用比'StringA'更好的名称,但是我想为NLV留下一些工作。否则,他应该怎样处理他剩余的一天:) – HuBeZa 2011-02-24 09:45:22
我意识到没有完美的解决方案来为一对产生独特的字符串,并且这里提供的所有解决方案都接近完美。正如Sweko所说,这对于任何问题都不是一个好的解决方案(方法),我已经将解决方案的逻辑更改为我的问题以避免出现此问题:)。 – NLV 2011-02-24 11:05:25
public static String getUniqString(String x,String y){
return (x.compareTo(y)<0)?(x+y):(y+x);
}
对不起!我没有阅读所有答案。不幸的是,我的答案是@Phil H的答案副本。 – Jessu 2011-02-24 09:26:44
你能举个例子吗?你到目前为止做了什么? – 2011-02-24 09:03:43
我不是一个建立一个逻辑来获得这样一个独特的价值。我想f('ABC','DEF')='someuniquevalue'= f('DEF','ABC'),我想现在定义f。 – NLV 2011-02-24 09:05:57
你打算在.NET之外使用这个'someuniquevalue'(即作为数据库PK)吗?否则,我认为我的答案是最简单直接的。 – HuBeZa 2011-02-24 09:21:19