Well, this is giving me a real headache. I'm building a matrix determinant function to compute NxN determinant, and I'm using recursion.
The logic is working right but I'm not able to get the final value computed correctly.
Here is my code for Matrix Determinant:
public static double determinant(double[,]array){
double det=0;
double total = 0;
double[,] tempArr = new double[array.GetLength(0) - 1, array.GetLength(1) - 1];
if(array.GetLength(0)==2)
{
det = array[0, 0] * array[1, 1] - array[0, 1] * array[1, 0];
}
else {
for (int i = 0; i <1; i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
if (j % 2 != 0) array[i, j] = array[i, j] * -1;
tempArr= fillNewArr(array, i, j);
det+=determinant(tempArr);
total =total + (det * array[i, j]);
}
}
}
return det;
}
and about fillNewArr method it's just a method to trim the array, method is as follow:
p
ublic static double[,] fillNewArr(double[,] originalArr, int row, int col)
{
double[,] tempArray = new double[originalArr.GetLength(0) - 1, originalArr.GetLength(1) - 1];
for (int i = 0, newRow = 0; i < originalArr.GetLength(0); i++)
{
if (i == row)
continue;
for (int j = 0, newCol=0; j < originalArr.GetLength(1); j++)
{
if ( j == col) continue;
tempArray[newRow, newCol] = originalArr[i, j];
newCol++;
}
newRow++;
}
return tempArray;
}
The method is working as it supposed to "I assume" but the final result is not computed in the right way, why would that be?!
4x4 Array Example:
{2 6 6 2}
{2 7 3 6}
{1 5 0 1}
{3 7 0 7}
Final result should be -168, while mine is 104!
This bit
if (j % 2 != 0) array[i, j] = array[i, j] * -1;
tempArr= fillNewArr(array, i, j);
det+=determinant(tempArr);
total =total + (det * array[i, j]);
uses a variable total that is never used again. It should probably be something like
double subdet = determinant(fillNewArr(array, i, j));
if (j % 2 != 0) subdet *= -1;
det += array[i, j] * subdet;
Related
I don't know what to do, my program is not working
I need to sort a two-dimensional array by the first elements of a row in descending order by rearranging the rows
(need to sort string without sort item)
Let's say I'm given an array:
1 2 3
4 5 6
7 8 9
As a result of the program, I need to get:
7 8 9
4 5 6
1 2 3
`
using System;
namespace BubbleSort
{
internal class Program
{
static void Main(string[] args)
{
//Объявление массива и его размерности
const int n = 3;
int bubble;
int[,] A =
{
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 },
};
//Алгоритм пузырьковой сортировки
for (int i = 0; i < n; i++)
{
for(int j = 0; j < n - 1; j++)
{
if (A[i, 0] < A[i++, 0])
{
for(j = 0; j < n-1; j++)
{
bubble = A[i, j];
A[i, j] = A[i, j+1];
A[i, j+1] = bubble;
}
}
}
}
//Вывод массива
for (int y = 0; y < n; y++)
{
for (int x = 0; x < n; x++)
{
Console.Write(A[y, x] + " ");
}
Console.WriteLine();
}
}
}
}
`
From the code in your comments, I'm not sure why you have a nested loop for swapping the values since a single loop will do. I've removed that here.
If you refer to the pseudocode implementation on Wikipedia, you'll see that you need to keep running multiple passes across the array until everything is sorted. You can do this like so:
bool swapped;
do
{
swapped = false; // reset swapped
for (int i = 0; i < n - 1; i++) // loop through all but the last row
{
if (A[i, 0] < A[i + 1, 0]) // determine if this row needs to be swapped with the next row
{
swapped = true; // mark swapped
for (int j = 0; j < n; j++) // swap each item in row i with each item in row i+1
{
int tmp = A[i, j];
A[i, j] = A[i + 1, j];
A[i + 1, j] = tmp;
}
}
}
}
while (swapped); // if we swapped anything, we need to make another pass to ensure the array is sorted
We can also do away with the need for n by using .GetUpperBound(dimension) which returns a value between 0 and n - 1 (where n is the count of items in the array in that dimension). Because the result is effectively n - 1, I've modified the loop conditions slightly:
bool swapped;
do
{
swapped = false;
for (int i = 0; i < A.GetUpperBound(0); i++)
{
if (A[i, 0] < A[i + 1, 0])
{
swapped = true;
for (int j = 0; j <= A.GetUpperBound(1); j++)
{
int tmp = A[i, j];
A[i, j] = A[i + 1, j];
A[i + 1, j] = tmp;
}
}
}
}
while (swapped);
We can also refer to the "Optimizing bubble sort" section of the Wikipedia page and implement that instead, which will make our code run more optimally:
int n = A.GetUpperBound(0); // get the initial value of n
do
{
int newn = 0; // default newn to 0, so if no items are visited, it will remain 0 and the loop will exit
for (int i = 0; i < n; i++)
{
if (A[i, 0] < A[i + 1, 0])
{
for (int j = 0; j <= A.GetUpperBound(1); j++)
{
int tmp = A[i, j];
A[i, j] = A[i + 1, j];
A[i + 1, j] = tmp;
}
newn = i; // store the current (highest) value of i swapped
}
}
n = newn; // set the value of n to the highest value of i swapped
}
while (n > 0); // loop until n == 0
The logic here (as explained on Wikipedia) is that by the end of the first pass, the last item is in the correct position. By the end of the second pass, the second-to-last and last items are in the correct position, and so on. So each time, we can visit one less item. When we have 0 items to visit, we have 0 items to swap, and the sort is complete.
You can see this optimised version in this YouTube visualisation.
I think the line
if (A[i, 0] < A[i++, 0])
should read
if (A[i, 0] < A[i+ 1, 0])
Im having trouble with code, I get
System.IndexOutOfRangeException
in the first loop in the find() method. Could you guys help me? I cant figure out whats wrong.
I've found this code for java and changed a little bit for C#. In java code there was int[][] A, Ive changed it to int[,]. P.S on java, code works.
class Program
{
static void Main(string[] args)
{
int[,] A = { { 1, 7, 9, 2 }, { 8, 6, 3, 2 }, { 1, 6, 7, 8 },
{ 2, 9, 8, 2 } };
Console.WriteLine("{0}", find(A));
}
public static int find(int[,] A)
{
int[,] solution = new int[A.Length + 1, A.Length + 1];
solution[0, 0] = A[0, 0];
for(int i = 1; i < A.Length; i++)
{
solution[0, i] = A[0, i] + solution[0, i - 1]; //IndexOutOfRangeException
}
for(int i = 1; i < A.Length; i++)
{
solution[i, 0] = A[i, 0] + solution[i - 1, 0];
}
for(int i = 1; i < A.Length; i++)
{
for(int j = 1; j < A.Length; j++)
{
solution[i, j] = A[i, j]
+ Math.Min(solution[i - 1, j], solution[i, j - 1]);
}
}
return solution[A.Length - 1, A.Length - 1];
}
}
The problem is that in a jagged array ([,]) the property Length will give you the overall amount of elements, in your case A.Length == 16 but you want only one dimension. The solution would be to use GetLength.
for (int i = 1; i < A.GetLength(1); i++)
you need to use 0 for the X-Dimension and 1 for the Y-Dimenstion ( [X,Y]) see the documenation for details.
This is how your method should look like:
public static int find(int[,] A)
{
int[,] solution = new int[A.GetLength(0) + 1, A.GetLength(1)+ 1];
solution[0, 0] = A[0, 0];
for (int i = 1; i < A.GetLength(1); i++)
{
solution[0, i] = A[0, i] + solution[0, i - 1];
}
for (int i = 1; i < A.GetLength(0); i++)
{
solution[i, 0] = A[i, 0] + solution[i - 1, 0];
}
for (int i = 1; i < A.GetLength(0); i++)
{
for (int j = 1; j < A.GetLength(1); j++)
{
solution[i, j] = A[i, j]
+ Math.Min(solution[i - 1, j], solution[i, j - 1]);
}
}
return solution[A.GetLength(0) - 1, A.GetLength(1) - 1];
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I get this performance issue from visual studio (Prefer jagged arrays over multidimensional).
The code to be replaced is "//matrix".
How can i do this with my code?
public static int LevenshteinDistance(string s, string t)
{
int n = s.Length; //length of s
int m = t.Length; //length of t
int[,] d = new int[n + 1, m + 1]; // matrix
int cost; // cost
// Step 1
if (n == 0) return m;
if (m == 0) return n;
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++) ;
for (int j = 0; j <= m; d[0, j] = j++) ;
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
cost = (t.Substring(j - 1, 1) == s.Substring(i - 1, 1) ? 0 : 1);
// Step 6
d[i, j] = System.Math.Min(System.Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
Here's a version which uses only a single dimensional array.
public static int LevenshteinDistance(string s, string t)
{
int n = s.Length; //length of s
int m = t.Length; //length of t
int stride = m+1;
int[] d = new int[(n + 1)*stride];
// note, d[i*m + i + j] holds (i,j)
int cost;
// Step 1
if (n == 0) return m;
if (m == 0) return n;
// Step 2, adjusted to skip (0,0)
for (int i = 0, k = stride; k < d.Length; k += stride) d[k] = ++i;
for (int j = 1; j < stride; ++j) d[j] = j;
// Step 3
int newrow = stride * 2;
char si = s[0];
for (int i=0, j=0, k = stride + 1; k < d.Length; ++k)
{
// don't overwrite d[i,0]
if (k == newrow) {
newrow += stride;
j=0;
si=s[++i];
continue;
}
// Step 5
cost = (t[j] == si ? 0 : 1);
// Step 6
d[k] = System.Math.Min(System.Math.Min(
d[k-stride] + 1, /* up one row */
d[k-1] + 1 /* left one */ ),
d[k-stride-1] + cost /* diagonal */ );
}
// Step 7
return d[d.Length-1];
}
This should improve performance 3 ways:
No string comparison and no one-character string garbage for the GC to clean up
Changed memory layout to match iteration order, improving cache behavior
Used single dimensional array and optimizer-friendly idioms, which should reduce bounds-checking
However, I'm pretty sure that applying mike z's suggestion of using two vectors will make for even clearer code.
I am trying to create a matrix of Random numbers using Polar Rejection method with the code below. I don't see any error but the console does not show any results. My code is below:
class Program
{
static void Main(string[] args)
{
Program.GenerateRandom();
}
public static void GenerateRandom()
{
Console.WriteLine("Please enter newtrials.");
int newTrials=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter Steps.");
int newSteps = Convert.ToInt32(Console.ReadLine());
int i = 0;
int j = 0;
double[,] v = new double[newTrials,newSteps];
double[,] d = new double[newTrials, newSteps];
double[,] l = new double[newTrials, newSteps];
double[,] Z = new double[newTrials, newSteps];
for (i = 0; i < newTrials; ++j)
{
for (j = 0; j < newSteps; ++i)
{
do
{
Random rnd = new Random();
v[i, j] = 2 * rnd.NextDouble() - 1;
d[i, j] = 2 * rnd.NextDouble() - 1; ;
l[i, j] = Math.Pow(v[i, j], 2) + Math.Pow(d[i, j], 2);
}
while (l[i, j] >= 1.0);
}
Z[i, j] = Math.Sqrt(-2 * Math.Log(l[i, j]) / l[i, j]) * v[i, j];
}
Console.WriteLine("values are:{0},{1}",Z[0,0],Z[0,1]);
Console.ReadLine();
}
}
}
I see two things that are I believe are errors in this code:
for (i = 0; i < newTrials; ++j) and for (j = 0; j < newSteps; ++i). You're incrementing the counter for the j loop in i and the counter for i loop in j. This is causing a "System.IndexOutOfRangeException" when I run your code because the j loop isn't getting incremented in the j loop and thus the loop isn't stopping.
Z[i, j] = Math.Sqrt(-2 * Math.Log(l[i, j]) / l[i, j]) * v[i, j]; at this point in the program's execution the loops have reached the bounds of the arrays you declared above. So if the user input 10 and 10 this code is calling Z[10, 10]. Since arrays are zero based Z only has upper bounds of Z[9,9] this is throwing a "System.IndexOutOfRangeException" as well.
The other consequence of the 2nd issue is that you're only writing an answer to the last index of the second dimension of the Z array. Meaning, if we use our 10 and 10 example again, results will only be written to Z[0, 9], Z[1, 9], Z[2, 9], Z[3, 9], Z[4, 9], Z[5, 9], Z[6, 9], Z[7, 9], Z[8, 9], and Z[9, 9]. I'm not sure what you're intending to do with this code but I think you have some logic errors.
I think you want something like the following:
Console.WriteLine("Please enter newtrials.");
int newTrials = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter Steps.");
int newSteps = Convert.ToInt32(Console.ReadLine());
int i = 0;
int j = 0;
double[,] v = new double[newTrials, newSteps];
double[,] d = new double[newTrials, newSteps];
double[,] l = new double[newTrials, newSteps];
double[,] Z = new double[newTrials, newSteps];
Random rnd = new Random();
for (i = 0; i < newTrials; i++)
{
for (j = 0; j < newSteps; j++)
{
do
{
v[i, j] = 2.0 * rnd.NextDouble() - 1.0;
d[i, j] = 2.0 * rnd.NextDouble() - 1.0;
l[i, j] = Math.Pow(v[i, j], 2.0) + Math.Pow(d[i, j], 2.0);
}
while (l[i, j] >= 1.0);
Z[i, j] = Math.Sqrt(-2 * Math.Log(l[i, j]) / l[i, j]) * v[i, j];
}
}
for (i = 0; i < newTrials; i++)
{
Console.Write("[");
for (j = 0; j < newSteps; j++)
{
Console.Write("{0}, ", Z[i, j]);
}
Console.Write("]\n");
}
Console.ReadLine();
Hi i'm using the levenshtein algorithm to calculate the difference between two strings, using the below code. It currently provides the total number of changes which need to be made to get from 'answer' to 'target', but i'd like to split these up into the types of errors being made. So classifying an error as a deletion, substitution or insertion.
I've tried adding a simple count but i'm new at this and don't really understand how the code works so not sure how to go about it.
static class LevenshteinDistance
{
/// <summary>
/// Compute the distance between two strings.
/// </summary>
public static int Compute(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
// Step 1
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
// Step 2
for (int i = 0; i <= n; d[i, 0] = i++)
{
}
for (int j = 0; j <= m; d[0, j] = j++)
{
}
// Step 3
for (int i = 1; i <= n; i++)
{
//Step 4
for (int j = 1; j <= m; j++)
{
// Step 5
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
// Step 6
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
// Step 7
return d[n, m];
}
}
Thanks in advance.