我的任務是做一個有組織的洗牌,從源頭上看,所有的奇數將被放在左邊,偶數將被放在右邊。
我已經做了很多類似的作業,對于正常的情況來說,它是很好的:
我已經做了很多類似的作業。
public static string ShuffleChars(string source, int count)?
{
if (string.IsNullOrWhiteSpace(source) || source.Length == 0)
{
throw new ArgumentException(null)。
}
if (count < 0)
{
throw new ArgumentException(null)。
}
for (int i = 0; i < count; i )
{
source = string.Concat(source.Where((item, index) => index % 2 == 0)
string.Concat(source.Where((item, index) => index % 2 !=0))。
}
return源。
}
現在的問題是,如果count是int.MaxValue或其他以百萬為單位的巨大數字,它將大量地回圈。我怎樣才能在速度和資源消耗方面優化代碼呢?
uj5u.com熱心網友回復:
你應該能夠通過字串的長度來確定在它回到原來的排序順序之前需要多少次迭代。 然后取迭代次數和輸入次數的模數,并且只迭代該次數。
例如,一個三個字符的字串將在2迭代中回到它的原始排序順序。如果輸入計數是做11迭代,我們知道11 % 2 == 1,所以我們只需要迭代一次。
一旦你確定了一個公式,即對于任何長度的字串,需要多少次迭代才能達到原始排序順序,你總是可以將迭代次數減少到這個數字或更少。
然而,得出一個公式將是很棘手的。一個有14個字符的字串需要12次迭代,直到它與自己匹配,但是一個有15個字符的字串只需要4次。
因此,一個捷徑可能是簡單地開始迭代直到我們找到一個匹配(或者直到我們達到指定的計數)。如果我們首先達到計數,那么我們將回傳該答案。否則,我們可以通過第一段中的想法來確定答案--獲取輸入計數和迭代計數的模數,并回傳該答案。
這可能需要我們將迭代的值存盤在一個字典中,這樣我們就可以檢索到一個特定的過去的值了。
例如:
public static string ShuffleChars(string source, int count)?
{
string s = source;
var results = new Dictionary<int, string>()。
for (int i = 0; i < count; i )
{
s = string.Concat(s.Where((item, index) => index % 2 == 0)
string.Concat(s.Where((item, index) => index % 2 != 0))。
//如果我們重復了我們的原始字串,回傳保存的。
//當前迭代的輸入計數模數的值。
if (s == source)
{
return results[count % (i 1) - 1] 。
}
//否則,為以后保存數值。
else
{
results[i] = s;
}
}
// If we get here it means we hit the requested count before
//曾經回傳到輸入的原始排序順序。
return s。
}
uj5u.com熱心網友回復:
與其在每個回圈中創建新的不可變的字串,你可以使用一個可變的字符陣列(char[]),并在不同地方交換字符。就記憶體消耗而言,這將是最有效的,但在一個陣列上進行交換可能相當棘手。使用兩個陣列要容易得多,因為你只需將字符從一個陣列復制到另一個陣列,并在每個回圈結束時交換這兩個陣列。
你還可以做的一個優化是使用char陣列的indices,而不是其值。我不確定這在實踐中是否會有什么不同,因為在現代的64位機器中,char和int型別都占用了8個位元組(AFAIK)。但在32位機器上,它肯定會有區別。下面是一個實作,所有這些想法都放在一起:
public static string ShuffleChars(string source, int count)?
{
if (source == null) throw new ArgumentNullException(nameof(source))。
if (count < 0) throw new ArgumentOutOfRangeException(nameof(count))。
//將兩個陣列實體化。
int[] indices = new int[source.Length]。
int[] temp = new int[source.Length];
//用遞增的數字初始化索引陣列。
for (int i = 0; i < indices.Length; i )
indices[i] = i;
for (int k = 0; k < count; k )
{
//將賠率復制到臨時陣列中。
for (int i = 0, j = 0; j < indices. 長度; i = 1, j = 2)
temp[i] = indices[j];
//將偶數復制到temp陣列中。
int lastEven = (indices.Length >> 1 << 1) - 1;
for (int i = indices. 長度 - 1, j = lastEven; j >= 0; i -= 1, j -= 2)
temp[i] = indices[j];
//互換兩個陣列,使用值圖元。
(indices, temp) = (temp, indices);
}
//將索引映射到源字串的字符上。
return String.Concat(indices.Select(i => source[i]))。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/326837.html
標籤:
下一篇:laravel錯誤"ArgumentCountErrorToofewargumentstofunctionAppHttpControllersUserController::magesend
