Levenshtein distance in java outputting the wrong number - java

For my university assignment in java I have been asked to provide "extra analytics functions" I decided to use Levenshtein distance but I have an issue where the number outputted to the console is one less than the actual answer. So the distance between "cat" and "hat" should be 1 but it's displaying as 0
public class Levenshtein {
public Levenshtein(String first, String second) {
char [] s = first.toCharArray();
char [] t = second .toCharArray();
int Subcost = 0;
int[][] array = new int[first.length()][second.length()];
for (int i = 0; i < array[0].length; i++)
{
array[0][i] = i;
}
for (int j = 0; j < array.length; j++)
{
array [j][0]= j;
}
for (int i = 1; i < second.length(); i++)
{
for (int j = 1; j < first.length(); j++)
{
if (s[j] == t [i])
{
Subcost = 0;
}
else
{
Subcost = 1;
}
array [j][i] = Math.min(array [j-1][i] +1,
Math.min(array [j][i-1] +1,
array [j-1][i-1] + Subcost) );
}
}
UI.output("The Levenshtein distance is -> " + array[first.length()-1][second.length()-1]);
}
}

Apparently you're using the following algorithm:
https://en.wikipedia.org/wiki/Levenshtein_distance#Iterative_with_full_matrix
I think you were not too accurate with indices. I'm not sure where exactly the problem is, but here is a working version:
public int calculateLevenshteinDistance(String first, String second) {
char[] s = first.toCharArray();
char[] t = second.toCharArray();
int substitutionCost = 0;
int m = first.length();
int n = second.length();
int[][] array = new int[m + 1][n + 1];
for (int i = 1; i <= m; i++) {
array[i][0] = i;
}
for (int j = 1; j <= n; j++) {
array[0][j] = j;
}
for (int j = 1; j <= n; j++) {
for (int i = 1; i <= m; i++) {
if (s[i - 1] == t[j - 1]) {
substitutionCost = 0;
} else {
substitutionCost = 1;
}
int deletion = array[i - 1][j] + 1;
int insertion = array[i][j - 1] + 1;
int substitution = array[i - 1][j - 1] + substitutionCost;
int cost = Math.min(
deletion,
Math.min(
insertion,
substitution));
array[i][j] = cost;
}
}
return array[m][n];
}

Related

finding length of union array

I am trying to find length of an array formed by union of two arrays. I can print out the union elements like this, but have no idea how to get length of my union array. Any ideas?
Can it be count variable length of my union array?
int[] array1={1,3,2,5};
int[] array2={4,5,1,3,2};
int m = array1.length, n = array2.length, k = array1.length, i = 0, flag = 0;
int c[] = new int[m + n];
int d[] = new int[m];
for (i = 0; i < m; i++) {
c[i] = array1[i];
}
for (i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (array2[i] != array1[j]) {
flag = 1;
} else {
flag = 0;
break;
}
}
if (flag == 1) {
c[k] = array2[i];
k++;
}
}
int count = 1;
for (i = 0; i < k - 1; i++) {
count++;
}
int p = 0;
for (i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (array2[i] == array1[j]) {
flag = 1;
break;
} else {
flag = 0;
}
}
if (flag == 1) {
d[p] = array2[i];
p++;
}
}
System.out.println("The length of the union array is: " + count);
The count should be k + m and not k. So just replace:
for (i = 0; i < k - 1; i++)
with
for (i = 0; i < k + m - 1; i++)
Better solution would be to assign k + m to count and print it. Something like this:
count = k + m;
System.out.println("count is " + count);
If you want a unique count then use Set:
Set<Integer> set = new HashSet<>();
set.addAll(Arrays.asList(array1));
set.addAll(Arrays.asList(array2));
count = set.size();

How can I find a local minimum in a 2D array?

public static void main(String[] args) {
// TODO code application logic here
int numRows = 5;
int numCols = numRows;
int[][] twoDimArray = new int[numRows][numCols];
Random randGen = new Random();
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
int randIndex = randGen.nextInt(4);
int value = randGen.nextInt(100);
twoDimArray[i][j] = value;
}
}
System.out.println("\nThe two-dimensional array: ");
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
System.out.print(twoDimArray[i][j] + " ");
}
System.out.println();
}
}
}
I want to find a local minimum using a "brute force" approach. I know with a one dimensional array I would use a for-loop to compare all the elements in the array until I found a local minimum, but I don't know how to do that here.
Edit: Could I use binary search instead? Find the middle row and search there and if one isn't found, I search one of the halves.
The brute force method would be very similar to that of a 1D array, just with an extra loop, and a few more checks:
public int[] findLocalMinimum(int[][] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
int current = arr[i][j];
if (i + 1 < arr.length && current >= arr[i + 1][j] ||
i - 1 >= 0 && current >= arr[i - 1][j] ||
j + 1 < arr[i].length && current >= arr[i][j + 1] ||
j - 1 >= 0 && current >= arr[i][j - 1]) {
continue;
} else {
return new int[] { i, j };
}
}
}
return new int[] { -1, -1 };
}

ArrayIndexOutOfBounds in binomial cofficient dynamic programming

I am trying to create a method that calculates (N choose R) using dynamic programming but I get an array out of bounds exception:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 7
at BinomialCoefficients.method5(BinomialCoefficients.java:127)
at BinomialCoefficients.main(BinomialCoefficients.java:50)
I am using a 2 dimensional array. Here is my code,
protected static long method5(long lN, long lR)
{
long lArray[][] = new long[(int) (lN+1)][(int) (lR+1)];
for(int i = 0; i <= lN; i++)
{
lArray[i][0] = 1;
}
for(int i = 0; i <= lN; i++)
{
lArray[i][i] = 1;
}
for(int i = 0; i <= lN; i++)
{
for(int j = i; j <= i; j++)
{
lArray[i][j] = lArray[i-1][j-1] + lArray[i-1][j];
}
}
/*for(int i = 0; i <= lN; i++)
{
for(int j = 0; j <= i; j++)
{
System.out.print(String.format("%5d", lArray[i][j]));
}
System.out.println();
}*/
return lArray[(int) lN][(int) lR];
}
Can somebody tell me what is wrong with it?
This code looks suspicious
for(int i = 0; i <= lN; i++)
{
lArray[i][i] = 1;
}
considering lArray was initialized using two potentially different values:
long lArray[][] = new long[(int) (lN+1)][(int) (lR+1)];
I think you should have an inner loop here, such as:
for(int i = 0; i <= lN; i++) {
for (int j=0; j<=lR; j++) {
lArray[i][j] = 1;
}
}
I see the indexing error has already been corrected. But will point out that you're allocating a square array when you only need one row. You're also not taking advantage of symmetry. Consider something like this:
public class Binomial {
public static long n_choose_r(int n, int r) {
r = Math.min(r, n - r);
long [] a = new long[r + 1];
a[0] = 1;
for (int i = 1; i <= n; ++i) {
if (i <= r) {
a[i] = 1;
}
for (int j = Math.min(r, i - 1); j > 0; --j) {
a[j] += a[j - 1];
}
}
return a[r];
}
public static void main(String [] args) {
System.out.println(n_choose_r(6, 4));
}
}

Java - Selection Sort - only switching once

So the first switch definitely occurs between the lowest value 3, and 5, but it doesn't keep going after that. This makes me think there is something wrong with one of the for loops?
public class SelectionSort
{
public static void main (String[] args)
{
int [] list;
list = new int[5];
list[0] = 4;
list[1] = 5;
list[2] = 12;
list[3] = 9;
list[4] = 3;
for (int i = 0; i < list.length-1; ++i) {
int index = i;
for (int j = 1; j < list.length; ++j) {
if (list[j] < list[index]) {
int temp = list[j];
list[j] = list[index];
list[index] = temp;
}
}
}
for (int k = 0; k < list.length; ++k) {
System.out.print(list[k] + ", ");
}
}
}
Short versiĆ³n:
for (int i = 0; i < list.length-1; i++)
for (int j = i+1; j < list.length; j++)
if (list[j] < list[i]) {
int temp = list[j];
list[j] = list[i];
list[i] = temp;
}
for (int k = 0; k < list.length; k++) {
System.out.print(list[k] + ", ");
}
after if (list[j] < list[index]) {, you have to update index if boolean statement gets satisfied so you need to index = j and do the swap after
see follwing :
public class MySelectionSort {
public static int[] doSelectionSort(int[] arr){
for (int i = 0; i < arr.length - 1; i++)
{
int index = i;
for (int j = i + 1; j < arr.length; j++)
if (arr[j] < arr[index])
index = j;
int smallerNumber = arr[index];
arr[index] = arr[i];
arr[i] = smallerNumber;
}
return arr;
}
for (int i = 0; i < list.length; ++i) {
int index = i;
for (int j = i + 1; j < list.length; ++j) {
if (list[j] < list[index]) {
index = j; }}
if (index != i) {
int temp = list[i];
list[i] = list[index];
list[index] = i; }}
To cut down on the number of swaps, the loop on j should only be looking the best item to swap with item i. There should be at most one swap for each value of i. (That's what makes it a Selection sort. If you do multiple swaps for each i, you might as well be doing Bubble Sort.
But that's for efficiency. The reason your code isn't working is that you start the loop on j at j = 1 instead of j = i + 1.

sorting arrays only sorts a few

I`ve been trying to bubble sort an array in java for some time now, but every time it just does a few and then it follows the array list.
public void mysort() {
Random randomNumbers = new Random();
int randomArray[] = new int[20];
for (int j = 0; j <= 19; j++) {
randomArray[j] = randomNumbers.nextInt(200 + 1);
for (int k = 1; k < 20; k++) {
if (randomArray[k - 1] < randomArray[k]) {
int hjelp = randomArray[k - 1];
randomArray[k - 1] = randomArray[k];
randomArray[k] = hjelp;
}
}
}
for (int i = 0; i <= 19; i++) {
System.out.println(randomArray[i]);
}
}
How do I make my bubble sort work properly?
You should populate the array first, and THEN call the sort. You're "sorting" the array 20 times, while it's still incomplete.
public void mysort() {
Random randomNumbers = new Random();
int randomArray[] = new int[20];
for (int j = 0; j < randomArray.length; j++) {
randomArray[j] = randomNumbers.nextInt(200) + 1;
}
for (int i = 0; i < randomArray.length; i++) {
for (int k = 1; k < randomArray.length; k++) {
if (randomArray[k - 1] < randomArray[k]) {
int hjelp = randomArray[k - 1];
randomArray[k - 1] = randomArray[k];
randomArray[k] = hjelp;
}
}
}
for (int i = 0; i < randomArray.length; i++) {
System.out.println(randomArray[i]);
}
}
You need to populate array first.
You are trying to populate and sort at the same time.
Populate :
for (int j = 0; j <= 19; j++ ){
randomArray[j] = randomNumbers.nextInt(200+1);
}
Sort :
BubleSort();
You code should have been like this :
Random randomNumbers = new Random();
int randomArray[] = new int[20];
for (int j = 0; j <= 19; j++) {
randomArray[j] = randomNumbers.nextInt(200 + 1);
}
for(int j=0;j<20;j++) {
for (int k = 1; k < 20; k++) {
if (randomArray[k - 1] < randomArray[k]) {
int hjelp = randomArray[k - 1];
randomArray[k - 1] = randomArray[k];
randomArray[k] = hjelp;
}
}
}
for (int i = 0; i <= 19; i++) {
System.out.println(randomArray[i]);
}
Note you are doing this in descending order. if you want to do it in ascending order change
if (randomArray[k - 1] < randomArray[k])
to
if (randomArray[k - 1] > randomArray[k])

Categories

Resources