我有一个包含字符串的数组。我想将当前字符串与数组中的所有字符串进行比较,然后按字母顺序排列。 我该怎么做?
澄清:字符串不按任何顺序排列。我想知道哪个索引具有下一个字母顺序的下一个字符串。例如,如果我有String" Bananas"我想要的下一个字符串" Apple" "桔子" "香蕉"将是" Oranges"。
给出数组
var fruit = new[] { "Apple", "Oranges", "Bananas" }
我想要一个能通过这个测试的函数
Assert.AreEqual(1, NextGreatestIndex(fruit, 2))
因为在"Oranges"
之后"Bananas"
接下来是{{1}}。
答案 0 :(得分:5)
答案 1 :(得分:1)
字符串不以任何顺序排列。我想知道哪个索引有 下一个字符串,具有下一个字母顺序。例如,如果我 有字符串“香蕉”我想要的“Apple”下一个字符串 “橘子”“香蕉”将是“橘子”
使用LINQ很容易:
string[] fruits = {"Apple", "Oranges", "Bananas"};
string fruit = "Bananas";
string next = fruits.OrderBy(s => s).FirstOrDefault(f => string.Compare(f, fruit) > 0);
如果next
后面没有水果,则为null
。
也许您希望为将来的查找保留已排序的集合,以避免一直重新排序。
您可以使用SortedSet<string>
及其GetViewBetween
方法:
var sortedFruits = new SortedSet<string>(fruits);
next = sortedFruits.GetViewBetween(fruit, sortedFruits.Max).Skip(1).FirstOrDefault();
请注意,即使您添加新项目,该集也会保持订购。它也会跳过重复项,但在这种情况下这应该不是问题,因为您只想按字母顺序获取下一个项目。
答案 2 :(得分:0)
你能做的最简单的事情是:
var strings = new[]{"apples","oranges","bananas"};
var sample = "apples";
var next = strings.OrderBy(i=>i).SkipWhile(i=>!i.Equals(sample)).Skip(1).Take(1).SingleOrDefault();
最高效的方法是使用BinarySearch,这样操作就是O(log(N))(你需要存储重复使用的排序列表)。
var sorted = strings.OrderBy(i=>i).ToList();
var sample = "bananas";
var index = sorted.BinarySearch(sample);
var next = index < 0 ? null : index >= sorted.Count - 1 ? null : sorted[index + 1];
答案 3 :(得分:0)
编辑现在反映了明确的问题。
适用于包含字符串数组的任何IList<T>
的通用实现。
int NextGreaterIndex<T>(
IList<T> list,
int currentIndex,
Comparer<T> comparer = null)
{
if (comparer == null)
{
comparer = Comparer<T>.Default;
}
var result = -1;
var best = default(T);
var found = false;
var current = list[currentIndex];
for (var i = 0; i < list.Count; i++)
{
if (i == currentIndex)
{
continue;
}
var t = list[i];
if (comparer.Compare(current, t) >= 0)
{
continue;
}
if (found && comparer.Compare(t, best) >= 0)
{
continue;
}
best = t;
result = i;
found = true;
}
return result;
}
用法:
var fruit = new[] { "Apple", "Oranges", "Bananas" }
var answer = NextGreaterIndex(fruit, 2);
// answer == 1