我需要一个函数将一个字符串数组转换为一个字符串,该字符串可以按照与排序输入相同的顺序排序(排序第一个输入参数,如果等于排序第二个等等......)
在本机代码中,用\ 0分隔字符串会有,但不知何故
(“a”+ char.MinValue +“2”)。CompareTo(“a1”)等于1!
发生了什么,是否可以创建这样的功能?
public static string StringsToKey(params string[] values)
编辑:这是我想要成功的测试:
Assert.IsTrue(MiscUtils.StringsToKey("a", "2").CompareTo(MiscUtils.StringsToKey("a1")) < 0);
我想避免使用CompareOrdinal,因为我并不总是控制密钥的排序方式。此外,序数可能会在国际集上产生错误的排序顺序......
答案 0 :(得分:5)
public static string StringsToKey(params string[] values)
{
return string.Join(char.MinValue.ToString(), values);
}
用法应该有效:
var s1 = StringsToKey("abc", "def", "1234");
var s2 = StringsToKey("ab", "cde", "f1234");
var comparisonResult = string.Compare(s1, s2, StringComparison.Ordinal);
修改强>
var s1 = StringsToKey("a", "2");
var s2 = StringsToKey("a1");
var r = string.Compare(s1, s2, StringComparison.Ordinal);
返回负值(-49
)。
编辑II:
正如Joe在评论中提到的那样,如果字符串包含'\0'
(如果tab用作分隔符,则为'\t'
),这将不起作用。因此,没有这样的分隔符适用于所有情况。所以,我重写了该函数,但现在它有2个参数,但仍然使用CompareTo
方法进行比较:
public static int CompareStringSequences(
IEnumerable<string> first,
IEnumerable<string> second)
{
var x = Enumerable.Zip(first, second, (s1, s2) => s1.CompareTo(s2))
.FirstOrDefault(i => i != 0);
return x == 0 ?
x1.Length - x2.Length :
x;
}
答案 1 :(得分:1)
String.CompareTo()方法返回一个int,将两个值与最短字符串的长度进行比较。假设'\ 0'是“小于”字符'1',它以正常的字符串顺序跟随它。您可以使用String.Split()方法拆分任何字符。包括'\ 0'。然后,您可以使用Array.Sort()方法对字符串进行排序。
答案 2 :(得分:1)
基本上,如果使用“序数排序”,您想要的操作就是简单地连接所有字符串。为了说明,我们采用两个字符串数组:
a={"My", "dog", "is", "black"}
b={"My", "cat", "sleeps", "often"}
比较这些数组中的每个字符串,直到找到不同的字符串:
a={"My", "dog", "is", "black"}
b={"My", "cat", "sleeps", "often"}
^
first difference: b is "less than" a
...完全等于比较连接的字符串:
a="Mydogisblack"
b="Mycatsleepsoften"
^
First difference; again, b < a
您方法的代码就是:
public static string StringsToKey(params string[] values)
{
var builder = new StringBuilder();
foreach(var s in values)
builder.Append(s + "\0"); //the \0 is ASCII 0, used to delimit words
return builder;
}
答案 3 :(得分:1)
此代码似乎适用于输入不包含标签的情况:
public static string StringsToKey(params string[] values)
{
return values.Aggregate("", (current, value) => current + value + '\t');
}
答案 4 :(得分:1)
与以null结尾的C样式字符串不同,.NET字符串可能包含空字符,因此在一般情况下,没有分隔符可以保证排序低于字符串中的任何有效字符。
当然,如果您确定您的字符串不包含空值并且顺序排序正常,则已发布的某些解决方案将起作用。
但我会说甚至不尝试。为字符串数组编写比较器将更有效(避免创建临时字符串)并更好地表达您的意图。有很多方法可以做到这一点,包括以下内容(比较IList&lt; string&gt;而不是string []以获得更大的灵活性,并支持文化敏感的比较):
public class StringListComparer : IComparer<IList<string>>
{
private StringComparer comparer;
public StringListComparer()
: this(StringComparer.Ordinal)
{
}
public StringListComparer(StringComparer comparer)
{
if (comparer == null) throw new ArgumentNullException("comparer");
this.comparer = comparer;
}
public int Compare(IList<string> x, IList<string> y)
{
int result;
for (int i = 0; i < Math.Min(x.Count, y.Count); i++)
{
result = comparer.Compare(x[i], y[i]);
if (result != 0) return result;
}
return x.Count.CompareTo(y.Count);
}
}
以上代码未经测试且可能有错误,但我相信你明白了。