what is the native logic work behind public static void Reverse(Array array, int index, int length);
You can use .NET Reflector for that:
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Reverse(Array array, int index, int length)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
if ((index < array.GetLowerBound(0)) || (length < 0))
{
throw new ArgumentOutOfRangeException((index < 0) ? "index" : "length", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
}
if ((array.Length - (index - array.GetLowerBound(0))) < length)
{
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
}
if (array.Rank != 1)
{
throw new RankException(Environment.GetResourceString("Rank_MultiDimNotSupported"));
}
if (!TrySZReverse(array, index, length))
{
int num = index;
int num2 = (index + length) - 1;
object[] objArray = array as object[];
if (objArray == null)
{
while (num < num2)
{
object obj3 = array.GetValue(num);
array.SetValue(array.GetValue(num2), num);
array.SetValue(obj3, num2);
num++;
num2--;
}
}
else
{
while (num < num2)
{
object obj2 = objArray[num];
objArray[num] = objArray[num2];
objArray[num2] = obj2;
num++;
num2--;
}
}
}
}
TrySZReverse is a native method that can sometimes do the same thing only faster.
Loop from the starting point, index, to the middle of the range, index + length/2, swapping each array[i] with array[index + length - i - 1].
Some details about the native method "TrySZReverse"
from the related codes from coreclr([1][2]), TrySZReverse handles the array of primitive types, and the reverse algorithm is the same as Array.Reverse :
codes quotation
static void Reverse(KIND array[], UINT32 index, UINT32 count) {
LIMITED_METHOD_CONTRACT;
_ASSERTE(array != NULL);
if (count == 0) {
return;
}
UINT32 i = index;
UINT32 j = index + count - 1;
while(i < j) {
KIND temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
and the prefix "SZ" seems stands for "single-dimension zero-terminated".
Related
Im trying to write a quicksort algorithm in C#, and I've been getting System.StackOverflowExceptions for the last while and can't figure out why.
Here is my Class:
class quicksort : sortalgorithm
{
int pivotIndex = -1;
int pivotSwapped = 0;
Random rand = new Random();
public quicksort(int[] arr)
{
if (arr.Length < 5)
{
throw new Exception("Array has too few Entries");
}
toSort = arr;
}
protected override int sort()
{
if (pivotIndex == -1) getPivot();
int indexL = getIndexLeft();
int indexR = getIndexRight();
if (indexR != -1 && indexL != -1 && indexL != toSort.Length-1)
{
swap(indexL, indexR);
}
if (indexL > indexR)
{
Console.WriteLine("Index thingy");
swap(toSort.Length - 1, indexL);
pivotSwapped++;
if (pivotSwapped == toSort.Length - 1)
{
return 1;
}
else
{
Console.WriteLine("new piv");
pivotSwapped++;
getPivot();
sort();
return -1;
}
}
else
{
sort();
return -1;
}
}
private void swap(int i, int j)
{
int temp = toSort[i];
toSort[i] = toSort[j];
toSort[j] = temp;
}
private void getPivot()
{
pivotIndex = rand.Next(0, toSort.Length - 1);
swap(toSort.Length - 1, pivotIndex);
}
private int getIndexLeft() // Larger then Pivot Starting: Left
{ //Error Here
int itemFromLeft = -1;
for (int i = 0; i < toSort.Length - 1; i++)
{
if (toSort[i] >= toSort[toSort.Length - 1])
{
itemFromLeft = i;
i = toSort.Length + 1;
}
}
//Console.WriteLine(itemFromLeft);
return itemFromLeft;
}
private int getIndexRight()// Smaller then Pivot Starting: Right
{
int itemFromRight = -1;
for (int i = toSort.Length - 1; i >= 0; i--)
{
if (toSort[i] < toSort[toSort.Length - 1])
{
itemFromRight = i;
i = -1;
}
}
//Console.WriteLine(itemFromRight);
return itemFromRight;
}
}
I hope that someone can help me.
P.S. the class sortalgorithm in this case only has the the array toSort.
My Console output always looks a bit like this:
[4, 28, 62, 33, 11] // The unsorted array
Index thingy
new piv
Index thingy
new piv
Index thingy
new piv
Process is terminated due to `StackOverflowException`.
a stack overflow error usually happens when you have a error in your recursion , ie a function keeps calling itself until there is no room left in the stack to hold all the references,
the only obvious candidate is
**sort();**
return -1;
}
}
else
{
**sort();**
return -1;
}
so either one or the other recursive calls is probably incorrect and needs removing and i suspect the issue will be resolved
EDIT:
as you are unable to debug your code
this is what a quick sort should look like
public int sort()
{
qsort(0, toSort.Length - 1);
return 0;
}
private void qsort( int left, int right)
{
if (left < right)
{
int pivot = Partition( left, right);
if (pivot > 1)
{
qsort( left, pivot - 1);
}
if (pivot + 1 < right)
{
qsort( pivot + 1, right);
}
}
}
private int Partition( int left, int right)
{
int pivot = toSort[left];
while (true)
{
while (toSort[left] < pivot)
{
left++;
}
while (toSort[right] > pivot)
{
right--;
}
if (left < right)
{
if (toSort[left] == toSort[right]) return right;
int temp = toSort[left];
toSort[left] = toSort[right];
toSort[right] = temp;
}
else
{
return right;
}
}
}
Note that if left >= right do nothing
This simple implementation of Hoare partition scheme demonstrates how to avoid stack overflow by recursing on the smaller partition, and looping back for the larger partition, an idea used in the original quicksort. Stack space complexity is limited to O(log2(n)), but worst case time complexity is still O(n^2).
static public void Quicksort(int [] a, int lo, int hi)
{
while(lo < hi){ // while partition size > 1
int p = a[(lo + hi) / 2];
int i = lo, j = hi;
i--; // Hoare partition
j++;
while (true)
{
while (a[++i] < p) ;
while (a[--j] > p) ;
if (i >= j)
break;
int t = a[i];
a[i] = a[j];
a[j] = t;
}
i = j++; // i = last left, j = first right
if((i - lo) <= (hi - j)){ // if size(left) <= size(right)
Quicksort(a, lo, i); // recurse on smaller partition
lo = j; // and loop on larger partition
} else {
Quicksort(a, j, hi); // recurse on smaller partition
hi = i; // and loop on larger partition
}
}
}
This is program consumes 36.50 MB of memory but I want it to be less than 32 MB
public static void CreateText(string text)
{
if (Convert.ToInt32(text.Length) <= 80)
{
int n;
string str = "";
string count = "";
char[] mas = text.ToCharArray();
for (int i = 0; i < Convert.ToInt32(mas.Length); i++)
{
if (int.TryParse(mas[i].ToString(), out n))
{
count += mas[i].ToString();
}
else
{
if (String.IsNullOrEmpty(count))
{
str += mas[i].ToString();
}
else
{
for (int j = 0; j < Convert.ToInt32(count); j++)
{
str += mas[i].ToString();
}
count = "";
}
}
}
Console.WriteLine(str);
} else {
Console.WriteLine("Error");
}
}
To reduce memory footprint you need to get read of temporary string objects generated by applying operation += against a string. String is immutable object in C#, so += creates new string. StringBuilder is mutable, so use it instead of string. You also need to have count as an int, not string or StringBuilder.
public static void CreateText(string mas)
{
if (mas.Length <= 80)
{
StringBuilder str;
int count;
for (int i = 0; i < mas.Length; i++)
{
if (mas[i] >= '0' && mas[i] <= '9')
count = count * 10 + mas[i] - '0';
else
{
if (count == 0)
str.Append(mas[i]);
else
{
for (int j = 0; j < count; j++)
str.Append(mas[i]);
count = 0;
}
}
}
Console.WriteLine(str.ToString());
}
else
Console.WriteLine("Error");
}
This probably isn't possible. Most of the RAM in a 36MB program is just core framework libraries. 36MB is nothing.
But I do see some potential improvements, the biggest of which are maintaining count as an integer rather than a string and using a string constructor and StringBuilder instead of appending to a string all the time:
public static void CreateText(string text)
{
if (text != null && text.Length <= 80)
{
int n; int count = 0;
StringBuilder result = new StringBuilder();
char[] mas = text.ToCharArray();
foreach(char c in text)
{
if (int.TryParse(c.ToString(), out n))
{
count = (count * 10) + n;
}
else
{
if (count == 0)
{
result.Append(c);
}
else
{
result.Append(new string(c, count));
count = 0;
}
}
}
Console.WriteLine(result.ToString());
} else {
Console.WriteLine("Error");
}
}
There is a potential bug there if you want to be able to explicitly set 0 repetition in the input string. If that's the case, we'll need something that is slightly less efficient, but should still have a big improvement over the original:
public static void CreateText(string text)
{
if (text != null && text.Length <= 80)
{
int n; int count = -1;
StringBuilder result = new StringBuilder();
char[] mas = text.ToCharArray();
foreach(char c in text)
{
if (int.TryParse(c.ToString(), out n))
{
if (count == -1) count = 0;
count = (count * 10) + n;
}
else
{
if (count == -1)
{
result.Append(c);
}
else
{
result.Append(new string(c, count));
count = -1;
}
}
}
Console.WriteLine(result.ToString());
} else {
Console.WriteLine("Error");
}
}
Try this:
public static void CreateText(string text)
{
if (text.Length <= 80)
{
var str = new StringBuilder();
var count = new StringBuilder();
for (int i = 0; i < text.Length; i++)
{
int n;
if (int.TryParse(text[i].ToString(), out n))
{
count.Append(text[i]);
}
else
{
if (String.IsNullOrEmpty(count.ToString()))
{
str.Append(text[i]);
}
else
{
for (int j = 0; j < Convert.ToInt32(count.ToString()); j++)
{
str.Append(text[i].ToString());
}
count.Clear();
}
}
}
Console.WriteLine(str);
}
else
{
Console.WriteLine("Error");
}
}
What I did was:
Remove the string contetantions (since they are immutable) and used a StringBuilder instead.
No need to convert to a char[] since your can treat a String as one (it implements the indexer)
Moved the n closed to used to it's only allocated if needed
I was trying to implement an Enumerable that replicates what LINQ OrderBy does. To do so, I used two approaches:
I used Mono's Linq/Enumerable.cs as base and replicated the OrderBy code in my Enumerable.
I used a decompiler to get an impression of .NET's version and replicated that code.
When benchmarking the LINQ version versus both options (I used .Take(10) to print less output), the linq version is significantly faster (1900ms vs 3700ms). The source data was List<MyObject>, sorted by char member. Optimized build flag was on.
Could someone please explain me where this difference could come from?
Edit:
I will outline the code for 2. below:
Here, Buffer<TElement> is a copy of System.Linq.Buffer<TElement> (copied from ILSpy as it is internal) and Sort is (mostly) copied in the same way from System.Linq.EnumerableSorter<TElement>.
public class Query2F
{
private Func<Lineitem, char> keySelector;
private char[] keys;
private IComparer<char> comparer;
private bool descending;
public Query2F(Func<Lineitem, char> keySelector, bool descending)
{
this.keySelector = keySelector;
this.descending = descending;
this.comparer = Comparer<char>.Default;
}
public static IEnumerable<Lineitem> Execute(List<Lineitem> lineitem)
{
Buffer<Lineitem> buffer = new Buffer<Lineitem>(lineitem);
if (buffer.count > 0)
{
Query2F q2f = new Query2F((s => s.returnflag), false);
int[] array = q2f.Sort(buffer.items, buffer.count);
q2f = null;
for (int i = 0; i < buffer.count; i++)
{
yield return buffer.items[array[i]];
}
}
yield break;
}
private void ComputeKeys(Lineitem[] elements, int count)
{
this.keys = new char[count];
for (int i = 0; i < count; i++)
{
//this.keys[i] = this.keySelector(elements[i]);
this.keys[i] = elements[i].returnflag;
}
}
private int CompareKeys(int index1, int index2)
{
int num = this.comparer.Compare(this.keys[index1], this.keys[index2]);
if (num == 0)
{
return index1 - index2;
}
else
{
if (!this.descending)
{
return num;
}
return -num;
}
}
internal int[] Sort(Lineitem[] elements, int count)
{
this.ComputeKeys(elements, count);
int[] array = new int[count];
for (int i = 0; i < count; i++)
{
array[i] = i;
}
this.QuickSort(array, 0, count - 1);
return array;
}
private void QuickSort(int[] map, int left, int right)
{
do
{
int num = left;
int num2 = right;
int index = map[num + (num2 - num >> 1)];
do
{
if (num < map.Length)
{
if (this.CompareKeys(index, map[num]) > 0)
{
num++;
continue;
}
}
while (num2 >= 0 && this.CompareKeys(index, map[num2]) < 0)
{
num2--;
}
if (num > num2)
{
break;
}
if (num < num2)
{
int num3 = map[num];
map[num] = map[num2];
map[num2] = num3;
}
num++;
num2--;
}
while (num <= num2);
if (num2 - left <= right - num)
{
if (left < num2)
{
this.QuickSort(map, left, num2);
}
left = num;
}
else
{
if (num < right)
{
this.QuickSort(map, num, right);
}
right = num2;
}
}
while (left < right);
}
}
internal struct Buffer<TElement>
{
internal TElement[] items;
internal int count;
internal Buffer(IEnumerable<TElement> source)
{
TElement[] array = null;
int num = 0;
ICollection<TElement> collection = source as ICollection<TElement>;
if (collection != null)
{
num = collection.Count;
if (num > 0)
{
array = new TElement[num];
collection.CopyTo(array, 0);
}
}
else
{
foreach (TElement current in source)
{
if (array == null)
{
array = new TElement[4];
}
else
{
if (array.Length == num)
{
TElement[] array2 = new TElement[checked(num * 2)];
Array.Copy(array, 0, array2, 0, num);
array = array2;
}
}
array[num] = current;
num++;
}
}
this.items = array;
this.count = num;
}
internal TElement[] ToArray()
{
if (this.count == 0)
{
return new TElement[0];
}
if (this.items.Length == this.count)
{
return this.items;
}
TElement[] array = new TElement[this.count];
Array.Copy(this.items, 0, array, 0, this.count);
return array;
}
}
Problem solved.Thanks to Mike for pointing me to the solution.
The reason for the discrepancies in the execution time were merely that I executed the wrong build (which was not a Release build).
I was given 30 minutes to complete the following task in an interview for an entry level C# developer role, the closest I could get to was to find out if the characters in both sides of the current index matched each other.
Construct an array which takes in an string and determines if at index
(i) the substring to
the left of (i) when reversed, equals to the substring to the right of
(i).
example: "racecar"
at index(3) the left substring is "rac" and when reversed equals to
the right substring "car".
return (i) if met with such condition, eslse return -1.
if string length is under 3, return 0;
if (str.Length < 3)
return -1;
for (int i = 0; i < str.Length - 1; i++)
{
if(str[i-1] == str [i+1])
return i;
}
return -1;
If i != n/2 you should return false, so just check for i==n/2:
int n = str.Length;
for (int i=0;i<=n/2;i++)
{
if (str[i] != str[n-i-1])
return -1;
}
return n/2;
I came up with this, but I really hope you were sitting in front of Visual Studio when they asked this...
using System.Linq;
class Program {
// New version: in fact, we are only looking for palindromes
// of odd length
static int FancyQuestion2(string value) {
if (value.Length % 2 == 0) {
return -1;
}
string reversed = new string(value.ToCharArray().Reverse().ToArray());
if (reversed.Equals(value, StringComparison.InvariantCultureIgnoreCase)) {
return (int)(value.Length / 2);
}
return -1;
}
static void Main(string[] args) {
int i1 = FancyQuestion2("noon"); // -1 (even length)
int i2 = FancyQuestion2("racecar"); // 3
int i3 = FancyQuestion2("WasItACatISaw"); // 6
}
}
public static int check(string str)
{
if(str.Length < 3)
return 0;
int n = str.Length;
int right = str.Length-1;
int left = 0;
while (left < right)
{
if (str[left] != str[right])
return -1;
left++;
right--;
}
return n / 2;
}
public static bool check(string s, int index)
{
if (s.Length < 3)
return false;
string left = s.Substring(0, index);
Char[] rightChars = s.Substring(index + 1).ToCharArray();
Array.Reverse(rightChars);
string right =new string (rightChars);
return left.Equals(right);
}
try this
static void Main(string[] args)
{
string theword = Console.ReadLine();
char[] arrSplit = theword.ToCharArray();
bool status = false;
for (int i = 0; i < arrSplit.Length; i++)
{
if (i < theword.Length)
{
string leftWord = theword.Substring(0, i);
char[] arrLeft = leftWord.ToCharArray();
Array.Reverse(arrLeft);
leftWord = new string(arrLeft);
string rightWord = theword.Substring(i + 1, theword.Length - (i + 1));
if (leftWord == rightWord)
{
status = true;
break;
}
}
}
Console.Write(status);
Console.ReadLine();
}
Your approach is correct, but the implementation is wrong. You need a different loop variable than i, as that contains the index of the (supposedly) center character in the string.
Also, you can't return the index from inside the loop, then you will only check one pair of character. You have to loop through the string, then check the result.
int checkPalindrome(string str, int i) {
// check that the index is at the center of the string
if (i != str.Length - i - 1) {
return -1;
}
// a variable to keep track of the state
bool cont = true;
// loop from 1 until you reach the first and last characters
for (int j = 1; cont && i - j >= 0; j++) {
// update the status
cont &= str[i - j] == str[i + j];
}
// check if the status is still true
if (cont) {
return i;
} else {
return -1;
}
}
This is the shortest I can think of:
using System;
public class Test
{
public static void Main()
{
string example = "racecar";
bool isPal = IsBothEndsPalindrome(example, 3);
Console.WriteLine(isPal);
}
static bool IsBothEndsPalindrome(string s, int i) {
while(i-- > 0) {
if(s[i] != s[s.Length - i - 1]) return false;
}
return true;
}
}
How it operates: http://ideone.com/2ae3j
Another approach, test for -1 upon return, the shortestz I can think of:
using System;
public class Test
{
public static void Main()
{
TestPal( "Michael", 3 );
TestPal( "racecar", 3 );
TestPal( "xacecar", 3 );
TestPal( "katutak", 3 );
TestPal( "able was i ere i saw elba", 7 );
TestPal( "radar", 2 );
TestPal( "radars", 2 );
// This is false, space is not ignored ;-)
TestPal( "a man a plan a canal panama", 9 );
}
static void TestPal(string s, int count) {
Console.WriteLine( "{0} : {1}", s, IsBothEndsPalindrome(s, count) );
}
static bool IsBothEndsPalindrome(string s, int count) {
while(--count >= 0 && s[count] == s[s.Length - count - 1]);
return count == -1;
}
}
Output:
Michael : False
racecar : True
xacecar : False
katutak : True
able was i ere i saw elba : True
radar : True
radars : False
a man a plan a canal panama : False
Note: The last one is False, the space is not ignored by code
Pure C, but hope the workflow helps you getting there. Thanks for sharing this.
int is_palindrome (const char str[], unsigned int index)
{
int len = strlen(str);
int result = index;
//index not valid?
if (index >= len)
return -1;
int i;
for (i = 0; ((index+i) < len && (index - i) >= 0); ++i) {
if(str[index-i] != str[index+i])
return -1;
else
continue;
}
return result;
}
In this following code i am receiving and out of range exception.
private void btnRoll_Click(object sender, EventArgs e)
{
int success4 = 0;
int success6 = 0;
int success8 = 0;
int success10 = 0;
int success20 = 0;
int botch4 = 0;
int botch6 = 0;
int botch8 = 0;
int botch10 = 0;
int botch20 = 0;
if (cbnd4.SelectedIndex != 0)
{
int value = 4;
int arraySize = (int)cbnd4.SelectedIndex;
int[] refArray = randomNumber(value, arraySize);
foreach (int i in refArray)
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= 2)
{
success4++;
}
if (refArray[i] == 1)
{
botch4++;
}
}
if (cbGame.SelectedIndex == 2)
{
if(refArray[i] >= 2)
{
success4++;
}
if (refArray[i] == 1)
{
botch4++;
}
}
}
}
/* if (cbmd4.SelectedIndex != 0)
{
}
*/
if (cbnd6.SelectedIndex != 0)
{
int value = 6;
int arrySize = (int)cbnd6.SelectedIndex;
int[] refArray = randomNumber(value, arrySize);
foreach (int i in refArray)
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= 4)
{
success6++;
} if (refArray[i] == 1)
{
botch6++;
}
}
if (cbGame.SelectedIndex == 2)
{
if (refArray[i] >= 4)
{
success6++;
}
if (refArray[i] == 1)
{
botch6++;
}
}
}
}
if (cbnd8.SelectedIndex != 0)
{
int value = 8;
int arrySize = (int)cbnd8.SelectedIndex;
int[] refArray = randomNumber(value, arrySize);
foreach (int i in refArray)
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= 5)
{
success4++;
}
if (refArray[i] == 1)
{
botch8++;
}
}
if (cbGame.SelectedIndex == 2)
{
if (refArray[i] >= 5)
{
success4++;
}
if (refArray[i] == 1)
{
botch8++;
}
}
}
}
if (cbnd10.SelectedIndex != 0)
{
int value = 10;
int arrySize = (int)cbnd10.SelectedIndex;
int[] refArray = randomNumber(value, arrySize);
foreach (int i in refArray)
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= 7)
{
success10++;
}
if (refArray[i] == 1)
{
botch10++;
}
}
if (cbGame.SelectedIndex == 2)
{
if (refArray[i] >= 7)
{
success10++;
}
if (refArray[i] == 1)
{
botch10++;
}
}
}
}
if (cbnd20.SelectedIndex != 0)
{
int value = 20;
int arrySize = (int)cbnd20.SelectedIndex;
int[] refArray = randomNumber(value, arrySize);
foreach (int i in refArray)
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= 16)
{
success20++;
}
if (refArray[i] == 1)
{
botch20++;
}
}
if (cbGame.SelectedIndex == 2)
{
if (refArray[i] >= 7)
{
success20++;
}
if (refArray[i] == 1)
{
botch20++;
}
}
}
}
lBotch_Result.Text = Convert.ToString(botch4 + botch6 + botch8 + botch10 + botch20);
lSuccess_Result.Text = Convert.ToString(success4 + success6 + success8 + success10 + success20);
MessageBox.Show("d4 successes: " +
success4.ToString() +
"\r\nd6 Successes: " +
success6.ToString() +
"\r\nd8 Successes: " +
success8.ToString() +
"\r\nd10 Successes: " +
success10.ToString() +
"\r\nd20 Successes: " +
success20.ToString() +
"\r\nd4 Botches: " +
botch4.ToString() +
"\r\nd6 Botches: " +
botch6.ToString() +
"\r\nd8 Botches: " +
botch8.ToString() +
"\r\nd10 Botches: " +
botch10.ToString() +
"\r\nd20 Botches: " +
botch20.ToString());
}
The Out of ranged exception occurs when if(refArray[i] >= 7) and the refArray.Length contains an odd int value.
here is the Exception Output:
System.IndexOutOfRangeException was
unhandled
Message="IndexOutOfRangeException"
StackTrace:
at Table_Top_Game_Dice.Form1.btnRoll_Click(Object
sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs
e)
at System.Windows.Forms.Button.OnClick(EventArgs
e)
at System.Windows.Forms.ButtonBase.WnProc(WM
wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM
wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr
hwnMain)
at System.Windows.Forms.Application.Run(Form
fm)
at Table_Top_Game_Dice.Program.Main()
any advice here would be greatly appreciated. i have been pounding my head against the wall for 5 hours trying to fix this.
oh, the refArray gets it values from the following function: (if it helps)
private int[] randomNumber(int value, int arraySize)
{
int[] randArray = new int[arraySize];
maxValue = value;
Random rand = new Random();
for (int i = 0; i < arraySize; i++)
{
randArray[i] = rand.Next(minValue, maxValue);
}
return randArray;
}
You are obviously trying to access an array element beyond the end of the array.
The randomNumber()method generates an array of random numbers where the size of the array and the maximum value are independent. Therefore it might return { 1, 7, 13 } if called with arraySize 3 and value 20.
Then you iterate over the array using foreach (int i in refArray). In consequence there will be three iterations with i set to 1, then 7, and finally 13.
So if you access the array using refArray[i] you try to access the array elements and indexes 1, 7, and 13 and therefore get an IndexOutOfRangeException in the second iteration because you try to access the element at index 7 while the array contains only 3 elements.
Did you intend for (int i = 0; i < refArray.Length; i++) instead of the foreach loop?
Isn't this piece of code able to produce an int that is equal to the size of the array and subsequently cause an outofrange exception when reading that item from the array by i.
int[] refArray = randomNumber(value, arraySize);
foreach (int i in refArray)
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= 2)
{
success4++;
}
if (refArray[i] == 1)
{
botch4++;
}
}
I didn't found the error, but you are repeating a lot of code. Try to encapsulate all these code inside of each "if (cbndXX.SelectedIndex != YY) inside a function.
Something like this:
private void RefactorizedFunction(ComboBox cmb, ComboBox cbGame, ref int success, ref int botch, int value, int maxsuxcess)
{
var arraySize = (int)cmb.SelectedIndex;
int[] refArray = randomNumber(value, arraySize);
foreach (int i in refArray) //WARNING HERE...
{
if (cbGame.SelectedIndex == 1)
{
if (refArray[i] >= maxsuxcess)
{
success++;
}
if (refArray[i] == 1)
{
botch++;
}
}
if (cbGame.SelectedIndex != 2) continue;
if (refArray[i] >= maxsuxcess)
{
success++;
}
if (refArray[i] == 1)
{
botch++;
}
}
}
It is not tested, and it will not solve your problem, but I'm sure your code will be easier to debug. There is other ways to improve your code, like using a dictionary or arrays instead of all these successXX and botchXX vars but... step by step.