問題:給定一個包含整數的陣列(長度至少為 3,但可能非常大)。陣列要么完全由奇陣列成,要么完全由偶陣列成,除了單個整數 N。撰寫一個將陣列作為引數并回傳這個“例外值”N 的方法。
示例 [2, 4, 0, 100, 4, 11, 2602, 36] 應該回傳:11(唯一的奇數)
[160, 3, 1719, 19, 11, 13, -21] 應該回傳:160(唯一的偶數)
問題:我可以找到目標號碼。在本例中為“6”。但是當我嘗試寫它時,它被寫了3次。我不明白為什么不寫一次。
namespace sayitoplamlar?
{
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] {1,3,5,6};
int even = 0;
int odd = 0;
foreach (var num in integers)
{
if (num%2==0)
{
even = 1;
}
else
{
odd = 1;
}
if (even>1)
{
foreach (var item in integers)
{
if (item%2!=0)
{
Console.WriteLine(item);
}
}
}
else if (odd>1)
{
foreach (var item in integers)
{
if (item%2==0)
{
Console.WriteLine(item);
}
}
}
}
}
}
}```
uj5u.com熱心網友回復:
因為我們做這個作業是為了取得好成績:)
我們真的不需要同時計算奇數和偶數元素,并且可以只計算一次奇數,因為它更方便 - 只需將所有余數相加(奇數 % 2 = 1,偶數 % 2 = 0)。如果我們需要偶數個元素,那就是array.Length - countOdd.
int countOdd = 0;
for (int i = 0; i < array.Length; i ) // or foreach
{
countOdd = array[i] % 2;
}
如果您覺得計數技巧太復雜并且只需要在分配上的 A 標記而不是原始代碼的變體就可以了:
int countOdd = 0;
foreach (int element in array)
{
if (element % 2 == 1)
countOdd ; // which is exactly countOdd = 1, just shorter.
}
現在是第二部分 - 尋找例外值。我們甚至不需要知道它是奇數還是偶數,而只是來自“%2”的提醒。我們現在知道有多少奇數元素 - 可能是 1(比期望的余數是 1 - 我們正在尋找奇數元素)或多于一個(然后期望的余數是 0,因為我們正在尋找偶數元素)。
int desiredRemainder = countOdd == 1 ? 1 : 0;
現在剩下的就是檢查哪個元素具有所需的余數并從我們的方法回傳:
foreach (int element in array)
{
if (element % 2 == desiredRemainder)
{
return element;
}
}
請注意,作業要求“回傳”而不是“列印”。與回傳值不同,列印值不允許方法呼叫者使用它。使用提前回傳還可以節省一些時間來迭代陣列的其余部分。
完整代碼:
int FindOutlier(int[] array)
{
int desiredReminder = array.Sum(x => x % 2) == 1 ? 1 : 0;
return array.First(x => x % 2 == desiredReminder);
}
另一種解決方案是只迭代陣列一次——因為一旦我們確定哪個重復與嵌套 foreach 的嘗試相似,我們就需要回傳第一個奇數或第一個偶數。注意,因為我們保證存在例外值并且只是我們不需要嘗試記住第一個數字的例外值 - 只是當前是可以的。
int FindOutlier(int[] array)
{
int? odd = null; // you can use separate int bool instead
int? even = null;
int countOdd = 0;
int countEven = 0;
foreach (int element in array)
{
bool isEven = element % 2 == 0;
if (isEven)
{
countEven ;
even = element;
}
else
{
countOdd ;
odd = element;
}
if (countEven > 1 && odd.HasValue)
return odd.Value;
if (countOdd > 1 && even.HasValue)
return even.Value;
}
throw new Exception("Value must be found before");
}
而且,如果您可以始終迭代整個串列代碼將很簡單,因為我們只需要跟蹤奇數(或偶數,僅一種)的計數,并且 return 不需要檢查我們是否找到了該值我們知道這兩種型別的數字都出現在串列中:
int FindOutlier(int[] array)
{
int odd = 0;
int even = 0;
int countEven = 0;
foreach (int element in array)
{
if (element % 2 == 0)
{
countEven ;
even= element;
}
else
{
odd = element;
}
}
return countEven > 1 ? odd : even;
}
uj5u.com熱心網友回復:
您將所有內容混合到一個演算法中。在大多數情況下,最好有單獨的步驟。在您的情況下,步驟可能是:
- 計算賠率和偶數
- 找出例外值
- 列印結果
這樣,您可以確保輸出不會干擾回圈。
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] {1,3,5,6};
int even = 0;
int odd = 0;
// Count odds and evens
foreach (var num in integers)
{
if (num%2==0)
{
even = 1;
}
else
{
odd = 1;
}
}
// Find the outlier
var outlier = 0;
foreach (var item in integers)
{
if (even == 1 && item%2==0)
{
outlier = item;
break;
}
if (odd == 1 && item%2!=0)
{
outlier = item;
break;
}
}
// Print the result
Console.WriteLine(outlier);
}
}
你甚至可以制作這個單獨的方法。由于 SoC(關注點分離)以及如果您想實作可測驗性(單元測驗),這也是有意義的。
無論如何,您都想要一個方法并使用該return陳述句,如作業中所述
撰寫一個將陣列作為引數并回傳此“例外值”N 的方法。
也許您想檢查以下代碼,它使用單獨的方法:
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] { 1, 3, 5, 6 };
var outlier = FindOutlier(integers);
Console.WriteLine(outlier);
}
private static int FindOutlier(int[] integers)
{
if (integers.Length < 3) throw new ArgumentException("Need at least 3 elements.");
bool isEvenOutlier = IsEvenOutlier(integers);
var outlier = FindOutlier(integers, isEvenOutlier ? 0:1);
return outlier;
}
static bool IsEvenOutlier(int[] integers)
{
// Count odds and evens
int even = 0;
int odd = 0;
foreach (var num in integers)
{
if (num % 2 == 0)
{
even = 1;
}
else
{
odd = 1;
}
}
// Check which one occurs only once
if (even == 1) return true;
if (odd == 1) return false;
throw new ArgumentException("No outlier in data.", nameof(integers));
}
private static int FindOutlier(int[] integers, int remainder)
{
foreach (var item in integers)
{
if (item % 2 == remainder)
{
return item;
}
}
throw new ArgumentException("No outlier in argument.", nameof(integers));
}
}
uj5u.com熱心網友回復:
它列印 '6' 3 次的原因是因為您在回圈內迭代整數,在該回圈中迭代整數。一次num又一次item。
考慮一下當你對 [1,3,5,6] 運行它時會發生什么。
num=1,你得到奇數=1,偶數=0。兩個 if 條件都不成立,所以我們進入下一次迭代。num=3, 你得到奇數 = 2 和偶數 = 0。奇數 > 1 所以我們再次遍歷整數(帶有專案)并列印 '6' whenitem=6。num=5,你得到奇數=3,偶數=0。同樣,這將在item=6.num=6,你得到奇數=3,偶數=1。即使我們增加了偶數計數,我們仍然有奇數 > 3,因此將列印 '6' whenitem=6。
最好對這些值進行一次迭代,并將最后一個偶數和最后一個奇數與計數一起存盤(它的性能也更高)。
然后,如果偶數 > 0,則可以列印最后一個奇數(因為只有一個奇數,這將是最后一個),如果奇數 > 0,則可以列印最后一個偶數。
IE
namespace sayitoplamlar?
{
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] { 1, 3, 5, 6 };
int even = 0;
int? lastEven = null;
int odd = 0;
int? lastOdd = null;
foreach (var num in integers)
{
if (num % 2 == 0)
{
even = 1;
lastEven = num;
}
else
{
odd = 1;
lastOdd = num;
}
}
if (even > 1)
{
Console.WriteLine(lastOdd);
}
else if (odd > 1)
{
Console.WriteLine(lastEven);
}
}
}
}
uj5u.com熱心網友回復:
因為您在列印之前沒有關閉第一個 foreach 回圈......
namespace sayitoplamlar?
{
class Program
{
static void Main(string[] args)
{
int[] integers;
integers = new int[] {1,3,5,6};
int even = 0;
int odd = 0;
foreach (var num in integers)
{
if (num%2==0)
{
even = 1;
}
else
{
odd = 1;
}//you need to close it here
if (even>1)
{
foreach (var item in integers)
{
if (item%2!=0)
{
Console.WriteLine(item);
}
}
}
else if (odd>1)
{
foreach (var item in integers)
{
if (item%2==0)
{
Console.WriteLine(item);
}
}
}
}
}//not here
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/444760.html
