Its been bugging me for hours because it is always returning 0 at numbers[i] and I cant figure out the problem. code worked for a different program but I had to change it so it could have a custom array size and that's when everything went wrong.
any help would be great.
Thanks in advance.
int[] numbers = new int[Convert.ToInt16(TxtArray.Text)];
int j = 0;
for (j = numbers.Length; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 1; i++)
{
string NumbersInput = Microsoft.VisualBasic.Interaction.InputBox("Enter Numbers to be sorted",
"Numbers Input", "", -1, -1);
numbers[i] = Convert.ToInt16(NumbersInput);
//returns 0 in if statement
if (numbers[i] < numbers[i + 1])
{
int intTemp = 0;
intTemp = numbers[i];
numbers[i] = numbers[i + 1];
numbers[i + 1] = intTemp;
}
}
}
for (int i = 0; i < numbers.Length; i++)
{
LstNumbers.Items.Add(numbers[i]);
}
private void button1_Click(object sender, EventArgs e)
{
int sizeOfArrayInt = Convert.ToInt32(arraySize.Text);
int[] array = new int[sizeOfArrayInt];
string numbers = arrayValues.Text;
string[] numbersSplit = numbers.Split(',');
int count = 0;
foreach (string character in numbersSplit)
{
int value;
bool parse = Int32.TryParse(character, out value);
if (value != null)
{
array[count] = value;
}
count++;
}
array = this.SortArray(array);
foreach (int item in array)
{
this.listBox.Items.Add(item);
}
}
private int[] SortArray(int[] arrayToSort)
{
//int[] sortedArray = new int[arrayToSort.Length];
int count = arrayToSort.Length;
for (int j = count; j >= 0; j--)
{
int i = 0;
for (i = 0; i <= j - 2; i++)
{
if (arrayToSort[i] < arrayToSort[i + 1])
{
int intTemp = 0;
intTemp = arrayToSort[i];
arrayToSort[i] = arrayToSort[i + 1];
arrayToSort[i + 1] = intTemp;
}
}
}
return arrayToSort;
}
strong text
This I got to work as a Windows Form and the output displays in the list box as each array item or individual i iteration over the array. Of course there is no error checking. Hope that helps.
Setting aside the strangeness of how you are working with text boxes, your problem with throwing an exception would happen even without them because it lies here, in your inner loop:
for (i = 0; i <= j - 1; i++)
Suppose that numbers.Length == 2. This means that j == 2. So on the first time through the outer loop, you hit the inner loop with these conditions. The first time through, i == 0. You get to the if statement:
if (numbers[i] < numbers[i + 1])
numbers[0] exists, and numbers[1] exists, so this iteration goes through fine and i is incremented.
Now i == 1. Now the loop checks its boundary condition. i <= j - 1 == true, so the loop continues. Now when you hit that if statement, it tries to access numbers[i + 1], i.e., numbers[2], which does not exist, throwing an IndexOutOfRangeException.
Edit: Came back and realized that I left out the solution (to the exception, anyway). For the bubble sort to work, your inner loop's boundary condition should be i <= j - 2, because j's initial value is == numbers.Length, which is not zero-based, while array indexes are.
Second Edit: Note that just using a List won't actually solve this problem. You have to use the right boundary condition. Trying to access list[list.Count()] will throw an ArgumentOutOfRangeException. Just because a List will dynamically resize doesn't mean that it will somehow let you access items that don't exist. You should always take time to check your boundary conditions, no matter what data structure you use.
Related
I've read the CLRS and tried to implement the recursive merge sort algorithm . cant see what the error is but everytime i run it gives me an "Index out of bounds error "
i've been trying for 5h now
static public void MergeSort(int[] input, int IndexStanga, int IndexDreapta)
{
if (IndexStanga < IndexDreapta)
{
int IndexMijloc = (IndexDreapta + IndexStanga) / 2;
MergeSort(input, IndexStanga, IndexMijloc);
MergeSort(input, IndexMijloc + 1, IndexDreapta);
Merge(input, IndexStanga, IndexDreapta, IndexMijloc);
}
}
static public void Merge(int[] input, int stanga, int dreapta, int mijloc)
{
int lungDR = 0;
int lunST = 0;
lungDR = dreapta - mijloc;
lunST = mijloc - stanga + 1;
int[] valDreapta = new int[lungDR + 1];
int[] valStanga = new int[lunST + 1];
valDreapta[valDreapta.Length - 1] = int.MaxValue;
valStanga[valStanga.Length - 1] = int.MaxValue;
int i = 0;
int j = 0;
for (i = stanga; i <= mijloc; i++) valStanga[i] = input[i];
for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }
i = 0;
j = 0;
for (int k = 0; k < input.Length; k++)
{
if (valStanga[i] <= valDreapta[j]) //error out of bounds
{
input[k] = valStanga[i];
i++;
}
else
{
input[k] = valDreapta[j];
j++;
}
}
}
Fixes noted in comments below. First fix for moving data from input to valStanga. Second fix for the range on merging back to input. The parameters for merge are in an unusual order, first, last, middle. Normally the order is first, middle, last.
Comments: The program will have issues if the array to be sorted contains elements equal to max integer. It would be more efficient to do a one time allocation of a working array, rather than allocate new sub-arrays on every call to merge. The copy operations can be avoided by changing the direction of merge with each level of recursion.
int i = 0;
int j = 0;
for (i = 0; i < lungDR; i++) { valDreapta[i] = input[i + mijloc + 1]; }
for (i = 0; i < lunST; i++) { valStanga[i] = input[i + stanga]; } // fix
i = 0;
j = 0;
for (int k = stanga; k <= dreapta; k++) // fix
{
if (valStanga[i] <= valDreapta[j])
I have the following Bubble sort Algorithm:
public void BubbleSort(int[] arr, int start, int end)
{
int instructions = 0;
bool swapped = true;
while (swapped)
{
swapped = false;
for (int i = 0; i < arr.Length - 1; i++)
{
//instructions++;
for (int j = i + 1; j < arr.Length; j++)
{
instructions++;
if (arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
swapped = true;
}
}
}
}
Console.WriteLine("instructions++ " + instructions);
}
if you print instructions you will see it is exactly: (n^2) - n
So why do we disregard -n?
Is it considered constant even though it is variable to the input size(it would be weird buy hey..)?
Time compelxity works as such. For large n values in this case, linear n does not matter. For eg if we are talking about 10 million numbers the value (10^6)^2 is far greater than 10^6. So even though it exists the other factor dwarfs it for large n so it makes it easier to disregard it.
Hi this is my code for longest common subsequence for 2 strings in c# . I need help in backtracking . I need to find out the subsequence : GTCGT
String str1 = "GTCGTTCG";
String str2 = "ACCGGTCGAGTG";
int[,] l = new int[str1.Length, str2.Length]; // String 1 length and string 2 length storing it in a 2-dimensional array
int lcs = -1;
string substr = string.Empty;
int end = -1;
for (int i = 0; i <str1.Length ; i++) // Looping based on string1 length
{
for (int j = 0; j < str2.Length; j++) // Looping based on string2 Length
{
if (str1[i] == str2[j]) // if match found
{
if (i == 0 || j == 0) // i is first element or j is first elemnt then array [i,j] = 1
{
l[i, j] = 1;
}
else
{
l[i, j] = l[i - 1, j - 1] + 1; // fetch the upper value and increment by 1
}
if (l[i, j] > lcs)
{
lcs = l[i, j]; // store lcs value - how many time lcs is found
end = i; // index on longest continuous string
}
}
else // if match not found store zero initialze the array value by zero
{
l[i, j] = 0;
}
}
Your function needs to return a collection of strings. There might be several longest common sub-sequence with same length.
public List<string> LCS(string firstString, string secondString)
{
// to create the lcs table easier which has first row and column empty.
string firstStringTemp = " " + firstString;
string secondStringTemp = " " + secondString;
// create the table
List<string>[,] temp = new List<string>[firstStringTemp.Length, secondStringTemp.Length];
// loop over all items in the table.
for (int i = 0; i < firstStringTemp.Length; i++)
{
for (int j = 0; j < secondStringTemp.Length; j++)
{
temp[i, j] = new List<string>();
if (i == 0 || j == 0) continue;
if (firstStringTemp[i] == secondStringTemp[j])
{
var a = firstStringTemp[i].ToString();
if (temp[i - 1, j - 1].Count == 0)
{
temp[i, j].Add(a);
}
else
{
foreach (string s in temp[i - 1, j - 1])
{
temp[i, j].Add(s + a);
}
}
}
else
{
List<string> b = temp[i - 1, j].Concat(temp[i, j - 1]).Distinct().ToList();
if (b.Count == 0) continue;
int max = b.Max(p => p.Length);
b = b.Where(p => p.Length == max).ToList();
temp[i, j] = b;
}
}
}
return temp[firstStringTemp.Length - 1, secondStringTemp.Length - 1];
}
You need to have a collection set in each entry of table. So you can still keep different strings with the same length in each cell of table.
As far as I've understood your question, I think you want to know the subsequence value i.e. that string. So, to get the subsequence, I've learnt a little bit differently. First, I calculate the table the one we do in standard Longest Common Subsequence (LCS) problem. Then I traverse the table to get the subsequence value. Sorry, I'm not familiar with C#, so, I will give you CPP code. Please have a look and let me know if you face any problem.
#include<iostream>
#include<vector>
#include<string>
using namespace std;
string printLongestCommonSubsequence(vector<vector<int> >& dp, int m, int n, string text1, string text2){
int i = m, j = n;
string lcs = "";
while(i > 0 && j > 0){
if(text1[i-1] == text2[j-1]){
lcs.push_back(text1[i-1]);
i--; j--;
}
else{
if(dp[i][j-1] > dp[i-1][j]) j--;
else i--;
}
}
reverse(lcs.begin(), lcs.end());
return lcs;
}
string longestCommonSubsequence(string text1, string text2){
int m = text1.size();
int n = text2.size();
vector<vector<int> > dp(m+1, vector<int>(n+1));
//initialization
for(int i=0; i<m+1; i++){
for(int j=0; j<n+1; j++){
if(i == 0 || j == 0) dp[i][j] = 0;
}
}
//solving the subproblems to solve the bigger problems
for(int i=1; i<m+1; i++){
for(int j=1; j<n+1; j++){
if(text1[i-1] == text2[j-1])
dp[i][j] = 1 + dp[i-1][j-1];
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
}
return printLongestCommonSubsequence(dp, m, n, text1, text2);
}
int main(){
string text1, text2;
cout<<"Enter the first string: ";
cin>>text1;
cout<<"\nEnter the second string: ";
cin>>text2;
string lcs = longestCommonSubsequence(text1, text2);
cout<<"Longest Common Subsequence is: "<<lcs<<endl;
return(0);
}
Please have a look at the diagram.
With respect to printing the LCS,
The basic idea is:
When the characters are equal of both the strings then move towards diagonal.
When the characters are not equal of both the strings then move towards the maximum of both the directions.
I hope this helps 🙂
Happy Learning
Thanks
I want to browse a matrix like these one :
I want browse the first row, get the smallest number, then browse the row matching with the precedent smallest number.
Ex : I browse the A row : I browse the cell A,A , I get 0. I don't keep it (because it's 0) I browse the cell A,D I get 5. I keep it. I browse the cell A,G I get 8 but i don't keep it because it is superior to 5. I browse cell A,K and I get 4 I keep it (< 5).
For the moment it's ok, a simple loop is sufficient to do this. Then I want to browse the row K and if possible don't browse the cell K,A because I already browsed it when I browsed the row A.
You need to loop through an upper/lower half of the matrix? I assume a matrix is an array of int arrays.
var matrix = new int[][]{ ... };
int smallest = 0;
for(int i = 0; i < matrix.Length; i++)
{
for(int j = 0; j < matrix.Length; j++)
{
int number = matrix[i][j];
if (number != 0 && number < smallest)
smallest = number;
}
}
Although, I didn't quite get
then browse the row matching with the precedent smallest number
part.
Here the solution I found :
private static IEnumerable<int> ComputeMatrix(int[,] matrix)
{
// check args
if (matrix.Rank != 2) { throw new ArgumentException("matrix should have a rank of 2"); }
if (matrix.GetUpperBound(0) != matrix.GetUpperBound(1)) { throw new ArgumentException("matrix should have the same size");}
// indice treated
List<int> treatedIndex = new List<int>();
for (int i = 0; i <= matrix.GetUpperBound(0); i++)
{
if (treatedIndex.Count == matrix.GetUpperBound(0))
break;
// distance minimum between 2 points
int distanceMin = Int32.MaxValue;
// next iteration of index
int nextI = i;
// add the index to ignore in the next iteration
int nextJ = -1;
for (int j = 0; j <= matrix.GetUpperBound(1); j++)
{
if (treatedIndex.IndexOf(j) == -1)
{
if (matrix[i, j] != 0 && matrix[i, j] < distanceMin)
{
distanceMin = matrix[i, j];
nextI = j;
nextJ = i;
}
}
}
i = nextI - 1;
treatedIndex.Add(nextJ);
yield return distanceMin;
}
}
This code is buggy but can't figure out why ... want to populate an array with 7 unique random integers without using arraylists or linq! I know the logic is not okay...
class Program
{
static void Main(string[] args)
{ int current;
int[] numbers = new int[7]; // size of that array
Random rNumber = new Random();
current = rNumber.Next(1, 50);
numbers[0] = current;
Console.WriteLine("current number is {0}", current);
for (int i=1;i<7;i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < numbers.Length; j++)
{
do
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
}
else
{
numbers[j++] = current;
break;
}
}while (current == numbers[j]);
}//inner for
}//outer for
for (int l = 0; l < 7; l++) // DISPLAY NUMBERS
{
Console.WriteLine(numbers[l]);
}
}// main
}//class
want to populate an array with 7 unique integers without using
arraylists or linq!
int[] list = new int[7];
for (int i = 0; i < list.Length; i++)
{
list[i] = i;
}
EDIT
I changed your inner loop, if the random number is already in the array; create a new random and reset j to 0.
for (int i = 1; i < 7; i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < numbers.Length; j++)
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
j = 0; // reset the index iterator
}
}//inner for
numbers[i] = current; // Store the unique random integer
}//outer for
I presume you are looking for random numbers, so the other answer is not what you are looking for.
There are a couple of issues here.
The inner loop is testing for duplicates. However, it is looking from 0 through the end of the array since it is using numbers.length. This should probably be i, to compare with already set values. numbers.length is always 7 regardless of whether or not you set any of the elements.
the assignment is using j, so presuming the first element is not a duplicate, it will be overwritten each time. That should be numbers[i] = current;. No ++ necessary as the for is handling the incrementing.
if you determine that a number is a duplicate, j should be reset to zer to check against the entire list again rather than having the while in the middle.
Without a complete rewrite, the changes will look something like this:
for (int i=1;i<7;i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < i; j++) //----------------- loop through set values
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
j = 0; // -----------------------reset the counter to start over
}
}//inner for
// if we got here there is no duplicate --------------------------------
numbers[i] = current;
}//outer for
(Please note that I have not tested this code, just added the changes)
you keep overwriting the same indexes in the else, and also checking too many indices causing the first to show up as a duplicate at all times which was false...
change it to:
for (int i=1;i<7;i++)
{
current = rNumber.Next(1, 50);
for (int j = 0; j < i; j++) ///< change to j < i. no need to check the others
{
do
{
if (current == numbers[j])
{
Console.WriteLine("Duplicate Found");
current = rNumber.Next(1, 50);
}
else
{
numbers[i] = current; ///< not j++ but i to prevent writing at the same locations over and over again
break;
}
}while (current == numbers[j]);
}//inner for
}//outer for
What about this?
int[] list = new int[7];
var rn = new Random(Environment.TickCount);
for (int i = 0; i < 7; i++)
{
var next = rn.Next(1, 50);
while(Contains(list, next))
{
next = rn.Next(1, 50);
}
list[i] = next;
}
private bool Contains(IEnumerable<int> ints, int num)
{
foreach(var i in ints)
{
if(i = num) return true;
}
return false;
}