Dynamic edit distance - java

I tried to make a dynamic algorithm to calculate the distance between two strings. For example, if I have "casa" and "cara", the output should be 2 (1 insert + 1 deletion), but I get 1. This is the algorithm:
public static int distance(String word1, String word2) {
int dp[][] = new int[m+1][n+1];
for (int i=0; i<=m; i++) {
for (int j=0; j<=n; j++) {
if (i==0)
dp[i][j] = j;
else if (j==0)
dp[i][j] = i;
else if (str1.charAt(i-1) == str2.charAt(j-1))
dp[i][j] = dp[i-1][j-1];
else {
int rep=dp[i-1][j-1];
int ins=dp[i][j-1];
int del=dp[i-1][j];
dp[i][j] = 1 + Math.min(rep, Math.min(ins, del));
}
}
}
return dp[m][n];
}
Could you please find me which code causes the bug?
Why the output of this algorithm is 1 instead of 2 using the strings "casa" and "cara"?

Related

Creating an array from the values of another array?

New to java and I am working on a RLE encoder. A method I am working on right now requires to convert an array of example:
{13,13,13,4,4,4,4,4,4}
to
{3,13,6,4}.
It checks the numbers that appear in consecutive order and then prints that into index[i], then prints the actual number value in index[i+1].
My current issue is that if a number is repeated more than 15 times, I have to start a new "run". So {13,13,13,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,} (there are 20 4's in succession here) will print {3,13,15,4,5,4}. My code currently prints {3,15,20,4}.
import java.util.Arrays;
public class testing {
public static void main(String[] args) {
byte [] flatdata = {15,15,15,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4};
int count = 1;
for (int i = 0; i < flatdata.length - 1; i++) {
if (flatdata[i] != flatdata[i + 1]) {
count++; }
}
byte numLength = 1;
byte indexNum = 0;
int newArraySize = count * 2;
byte[] newArray = new byte[newArraySize];
byte[] arrayWithTotalIndexes = new byte[newArraySize];
int i;
for (i = 0; i < flatdata.length - 1; i++) {
if (flatdata[i] != flatdata[i + 1]) {
newArray[indexNum] = numLength;
newArray[indexNum + 1] = flatdata[i];
indexNum = (byte) (indexNum + 2);
numLength = 1;
} else {
numLength++;
}
}
if (flatdata[i - 1] == flatdata[i]) {
newArray[indexNum] = numLength;
newArray[indexNum + 1] = flatdata[i];
} else {
newArray[indexNum] = numLength;
newArray[indexNum + 1] = flatdata[i];
}
System.out.println(Arrays.toString(flatdata));
System.out.println(Arrays.toString(newArray));
System.out.println("countRuns: " + count);
System.out.println(Arrays.toString(arrayWithTotalIndexes));
byte[] desiredArray = {3,15,15,4,5,4};
System.out.println("Desired Array: " + Arrays.toString(desiredArray));
}
I know my first step has to be to adjust the size of the new array to include the extra entries of the array.
public static void main(String [] args){
byte [] arr = {15,15,15,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,};
for (int i = 0; i < arr.length; i++) {
int count1 = 0;
for (int j = 0; j < arr.length; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
if (count1 > 15) {
System.out.println("true");
break;
}
System.out.println("false");
}
}
I thought about running a separate loop to check if a number is repeated more than 15 times to change the size of the new array but it has been to no avail.
Here is a link to a previous question I asked regarding the same method in case it makes things more clear.
Creating an array from another array?
Would appreciate any tips or ideas on how to tackle this.
Expand the test for starting a new result pair by changing:
if (flatdata[i] != flatdata[i + 1])
to:
if (flatdata[i] != flatdata[i + 1] || numLength == 15)

how to determine if a number is a smart number in java?

I have this question I am trying to solve. I have tried coding for the past 4 hours.
An integer is defined to be a Smart number if it is an element in the infinite sequence
1, 2, 4, 7, 11, 16 …
Note that 2-1=1, 4-2=2, 7-4=3, 11-7=4, 16-11=5 so for k>1, the kth element of the sequence is equal to the k-1th element + k-1. For example, for k=6, 16 is the kth element and is equal to 11 (the k-1th element) + 5 ( k-1).
Write function named isSmart that returns 1 if its argument is a Smart number, otherwise it returns 0. So isSmart(11) returns 1, isSmart(22) returns 1 and isSmart(8) returns 0
I have tried the following code to
import java.util.Arrays;
public class IsSmart {
public static void main(String[] args) {
// TODO Auto-generated method stub
int x = isSmart(11);
System.out.println(x);
}
public static int isSmart(int n) {
int[] y = new int[n];
int j = 0;
for (int i = 1; i <= n; i++) {
y[j] = i;
j++;
}
System.out.println(Arrays.toString(y));
for (int i = 0; i <= y.length; i++) {
int diff = 0;
y[j] = y[i+1] - y[i] ;
y[i] = diff;
}
System.out.println(Arrays.toString(y));
for (int i = 0; i < y.length; i++) {
if(n == y[i])
return 1;
}
return 0;
}
}
When I test it with 11 it is giving me 0 but it shouldn't. Any idea how to correct my mistakes?
It can be done in a simpler way as follows
import java.util.Arrays;
public class IsSmart {
public static void main(String[] args) {
int x = isSmart(11);
System.out.println("Ans: "+x);
}
public static int isSmart(int n) {
//------------ CHECK THIS LOGIC ------------//
int[] y = new int[n];
int diff = 1;
for (int i = 1; i < n; i++) {
y[0] =1;
y[i] = diff + y[i-1];
diff++;
}
//------------ CHECK THIS LOGIC ------------//
System.out.println(Arrays.toString(y));
for (int i = 0; i < y.length; i++) {
if(n == y[i])
return 1;
}
return 0;
}
}
One of the problems is the way that your populating your array.
The array can be populated as such
for(int i = 0; i < n; i++) {
y[i] = (i == 0) ? 1 : y[i - 1] + i;
}
The overall application of the function isSmart can be simplified to:
public static int isSmart(int n) {
int[] array = new int[n];
for(int i = 0; i < n; i++) {
array[i] = (i == 0) ? 1 : array[i - 1] + i;
}
for (int i = 0; i < array.length; i++) {
if (array[i] == n) return 1;
}
return 0;
}
Note that you don't need to build an array:
public static int isSmart(int n) {
int smart = 1;
for (int i = 1; smart < n; i++) {
smart = smart + i;
}
return smart == n ? 1 : 0;
}
Here is a naive way to think of it to get you started - you need to fill out the while() loop. The important thing to notice is that:
The next value of the sequence will be the number of items in the sequence + the last item in the sequence.
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
System.out.println(isSmart(11));
}
public static int isSmart(int n) {
ArrayList<Integer> sequence = new ArrayList<Integer>();
// Start with 1 in the ArrayList
sequence.add(1);
// You need to keep track of the index, as well as
// the next value you're going to add to your list
int index = 1; // or number of elements in the sequence
int nextVal = 1;
while (nextVal < n) {
// Three things need to happen in here:
// 1) set nextVal equal to the sum of the current index + the value at the *previous* index
// 2) add nextVal to the ArrayList
// 3) incriment index by 1
}
// Now you can check to see if your ArrayList contains n (is Smart)
if (sequence.contains(n)) { return 1; }
return 0;
}
}
First think of a mathematical solution.
Smart numbers form a sequence:
a0 = 1
an+1 = n + an
This gives a function for smart numbers:
f(x) = ax² + bx + c
f(x + 1) = f(x) + x = ...
So the problem is to find for a given y a matching x.
You can do this by a binary search.
int isSmart(int n) {
int xlow = 1;
int xhigh = n; // Exclusive. For n == 0 return 1.
while (xlow < xhigh) {
int x = (xlow + xhigh)/2;
int y = f(x);
if (y == n) {
return 1;
}
if (y < n) {
xlow = x + 1;
} else {
xhigh = x;
}
}
return 0;
}
Yet smarter would be to use the solution for x and look whether it is an integer:
ax² + bx + c' = 0 where c' = c - n
x = ...
I was playing around with this and I noticed something. The smart numbers are
1 2 4 7 11 16 22 29 ...
If you subtract one you get
0 1 3 6 10 15 21 28 ...
0 1 2 3 4 5 6 7 ...
The above sequence happens to be the sum of the first n numbers starting with 0 which is n*(n+1)/2. So add 1 to that and you get a smart number.
Since n and n+1 are next door to each other you can derive them by reversing the process.
Take 29, subtract 1 = 28, * 2 = 56. The sqrt(56) rounded up is 8. So the 8th smart number (counting from 0) is 29.
Using that information you can detect a smart number without a loop by simply reversing the process.
public static int isSmart(int v) {
int vv = (v-1)*2;
int sq = (int)Math.sqrt(vv);
int chk = (sq*(sq+1))/2 + 1;
return (chk == v) ? 1 : 0;
}
Using a version which supports longs have verified this against the iterative process from 1 to 10,000,000,000.

Java Bubble Sorting Array Wrong Output

just to preface, I am very new to coding in Java, or coding in general to be exact.
Here is what I am trying to accomplish. It is a project, where we take a input file of numbers, one integer being a competitor number, the next being their weight for a fish they caught, (Looking like this 3 26.7 (new line per two numbers) 2 2.6.. so on and so on), put them in a array, then sort them in one way or another. Now, I will post the whole code, but it is only the last method, "sort", that I am having difficulties right now.
The method is a bubble sorting method. The way I am approaching it is so that it will take the first array, compare it with the second array to see if it is less than, then swap the two competitor numbers if the logic is correct so that I can print the competitor numbers in the main method, and call the appropriate weight for the competitor (which is previously compiled in past if/then loop). Note, I do not have it currently trying to print the competitor weight.
I believe I am on the right track for this, but for some reason, the numbers printed, after calling the sort method, are not correct. If you could tell me what I am doing wrong, that would be greatly helpful. Thanks.
import java.io.*;
import java.util.Scanner;
public class Project8
{
public static void main(String[] args)
throws FileNotFoundException
{
Scanner inF = new Scanner(new File("data7.txt"));
PrintWriter outF = new PrintWriter(new File("pro7out.txt"));
int [] arrayNum = new int[7];
int [] sortedNum = new int[7];
double [] arrayWeight = new double[7];
int place, firstplace, lastplace;
double weight;
String line;
String entries[];
outF.printf("My name - Project 7: 4/10/18%nResults of the Rocking JR Fishing Contest%n");
outF.printf("Competitor Total%n Number Weight%n");
for (int m = 0; m < 7; m++)
{
arrayNum[m] = m + 1;
}
while (inF.hasNextLine())
{
line = inF.nextLine();
entries = line.split(" +");
place = Integer.parseInt(entries[0]);
weight = Double.parseDouble(entries[1]);
if (place == 1)
arrayWeight[0] += weight;
else if (place == 2)
arrayWeight[1] += weight;
else if (place == 3)
arrayWeight[2] += weight;
else if (place == 4)
arrayWeight[3] += weight;
else if (place == 5)
arrayWeight[4] += weight;
else if (place == 6)
arrayWeight[5] += weight;
else
arrayWeight[6] += weight;
}
for (int k = 0; k < 7; k++)
outF.printf("%5d %15.2f%n", arrayNum[k], arrayWeight[k]);
firstplace = first(arrayNum, arrayWeight);
lastplace = last(arrayNum, arrayWeight);
sortedNum = sort(arrayNum, arrayWeight);
outF.printf(" Winner is%n %d %3.2f%n", firstplace, arrayWeight[firstplace-1]);
outF.printf(" Not as successful%n %d %3.2f%n", lastplace, arrayWeight[lastplace-1]);
for (int k = 0; k < 7; k++)
outF.printf("%d", sortedNum[k]);
outF.printf(" Contest Over%n");
inF.close();
outF.close();
}
public static int first(int number[], double weight[])
{
int firstplace=0;
double max=0;
for (int k = 0; k < 7; k++)
{
if (weight[k] > max)
{
max = weight[k];
firstplace = number[k];
}
}
return firstplace;
}
public static int last(int number[], double weight[])
{
int lastplace=0;
double minimum=weight[0];
for (int k = 0; k < 7; k++)
{
if (weight[k] < minimum)
{
minimum = weight[k];
lastplace = number[k];
}
}
return lastplace;
}
public static int[] sort(int number[], double weight[])
{
int n = number.length;
int tempNum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 1; j < (n-1); j++)
{
if (weight[j - 1] < weight[j])
{
tempNum = number[j - 1];
number[j - 1] = number[j];
number[j] = tempNum;
}
}
}
return number;
}
}

How can i use a nested loops to help identify if i have 2 different matching pairs of dices

So I just had a lesson on loops and nested loops. My professor said that nested loops can help us do tasks such as knowing if we rolled 2 different matching pairs with 4 dices (4242) I'm a bit confused on how that would work.
So I started to work it out and this is what I was able to create.
public boolean 4matchDice(String dice){
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
}
}
I used boolean as the return as it will tell us whether or not we have 2 different matching pairs.
Thing is, what do I put in the the loops? That's what's confusing me the most.
Here's a solution I came up with, seems to be returning the correct outcome for all the test cases I ran.
public static boolean matchDice(String dice) {
char[] diceArray = dice.toCharArray();
int pairs = 0;
for (int i = 0; i < 4; i++) {
for (int j = i + 1; j < dice.length(); j++) {
if (diceArray[i] == diceArray[j]) {
diceArray[i] = 'X';
diceArray[j] = 'Y';
pairs++;
}
}
}
return (pairs > 1);
}
If you're only comparing two sets with two dice each, this is enough:
public boolean match4Dice(int first, int second, int third, int fourth) {
if ((first == third && second == fourth) || (first == fourth && second == third)) {
return true;
}
return false;
}
But if you're comparing 2 sets with any number of dice, the following algorithm would suit you better.
public boolean matchDice(String firstDiceSet, String secondDiceSet) {
// validate input, string must contain numbers from 1 - 6 only.
// lenghts of strings firstDiceSet & secondDiceSet must be equal
// works for any number of dice in each set.
// The dice only match if all numbers in the firstDiceSet all present in the secondDiceSet also.
// Let us count the matching numbers to check if this true.
int numberOfMatches = 0;
for (int i = 0; i < firstDiceSet.length(); i++) {
for (int j = 0; j < secondDiceSet.length(); j++) {
if (firstDiceSet[i] == secondDiceSet[j]) { // and not used
// increment number of matches
// mark secondDiceSet[j] as used, so that you do not count the same match twice.
// account for cases where firstDiceSet = "33" and the secondDiceSet = "35"
}
}
}
// your dice set match if the following condition is true
return (numberOfMatches == secondDiceSet.length());
}
Hi I just coded up a solution that will take "4242" as an input, although sindhu_sp's method is more practical i believe. I just wanted to show you another example to help your learning of java!
public static boolean fourMatchDice(String dice){
int match = 0;
for (int i = 0; i < dice.length(); i++){
for (int j = i+1; j < dice.length(); j++){
if (dice.toCharArray()[i] == dice.toCharArray()[j]){
System.out.println("does " + dice.toCharArray()[i] + " = " + dice.toCharArray()[j]);
match ++;
}
}
}
if(match == 2) *EDIT* //Change to (match >= 2) if 4 of the same pair is allowed.
return true;
return false;
}
public static void main(String[] args) {
System.out.println(fourMatchDice("4242"));
}
output:
does 4 = 4
does 2 = 2
true

an alternative to all and any from python to Java?

I'm tryin' to code how to find out a determinant in a matrix with Java 8. There are some particular cases for that work. For instance, when a matrix is an upper triangular. I coded this work with Python 3.6 using this code:
def is_upper_triangular(a, order):
for i in range(1, order):
if all(a[i][j] == 0 for j in range(order)):
return True
return False
This is very easy and clean code, so I've thought to code with Java, but I don't find any "all" method with Java to use it. I've found some information about that in this web page with negative solution. Is there any alternative to solve my problem.
Here's my java code for now:
public static double detMatrix(double[][] matriz) {
if(matriz.length == 1)
return matriz[0][0];
if(matriz.length == 2)
return matriz[0][0] * matriz[1][1] - matriz[1][0] * matriz[0][1];
double det = 0;
for(int i=0; i<matriz.length; i++){
double[][] nm = new double[matriz.length-1][matriz.length-1];
for(int j=0; j<matriz.length; j++){
if(j != i){
for(int k=1; k<matriz.length; k++){
int indice = -1;
if(j<i)
indice = j;
else if(j>i)
indice = j - 1;
nm[indice][k-1] = matriz[j][k];
}
}
}
if(i % 2 == 0)
det += matriz[i][0] * detMatrix(nm);
else
det -= matriz[i][0] * detMatrix(nm);
}
return det;
}
Thanks
I know you are asking for a specific keyword feature in Java, but different programming languages afford different approaches.
For example, instead of an all operator, why not simply use Arrays.fill(...)? The python that looks like
for i in range(1, order):
if all(a[i][j] == 0 for j in range(order))
would look like
for (int i = 0; i < a.length, i++) {
Arrays.fill(a[i], i+1, a[i].length, 0);
}
Likewise, the any operation in Python might look like it is doing more with less, but really it collapses down to
for (Element element : allElements() {
if (element satisifies condition) {
... statements ...
}
}
With Java, the above loop can work, but it makes the inefficiency apparent. If you really don't like to see what your code is doing, you can hide this in a method.
public List<int> findFives(int[][] a) {
...
}
Well, it seems java works with Streams, but Streams is a hard option beause, it seems, it converts any matrix in an Array 1D, and this is very difficult when i want to search all 0's under main diagonal matrix. I suppose some people know to solve it but i don't know about that.
Other problem with that is we have to load some java packages. So i've found another solution without to load extra java packages. Here is:
public static double [][] transMatrix(double [][] mat) {
double[][] matrizT = new double[mat[0].length][mat.length];
for(int i=0; i<mat.length; i++)
for (int j = 0; j<mat[i].length; j++)
matrizT[j][i] = mat[i][j];
return matrizT;
}
public static boolean isUpper(double[][] mat) {
int p = 0;
for(int i=0;i<mat.length;i++)
{
for(int j=0;j<i;j++)
{
if(mat[i][j]!=0)
p = 1; break;
}
}
return p == 0;
}
public static double productDiag(double[][] mat) {
double prod;
prod = 1.;
for(int i=0;i<mat.length;i++)
for(int j=0; j<mat[0].length;j++)
if(i==j)
prod *= mat[i][j];
return prod;
}
public static double detMatrix(double[][] matrix) {
if(matrix.length == 1)
return matrix[0][0];
if(matrix.length == 2)
return matrix[0][0] * matrix[1][1] - matrix[1][0] * matrix[0][1];
if(isUpper(matrix) || isUpper(transMatrix(matrix))
|| (isUpper(matrix) && isUpper(transMatrix(matrix)))){
return productDiag(matrix);
}
double det = 0;
for(int i=0; i<matrix.length; i++){
double[][] minor = new double[matrix.length-1][matrix.length-1];
for(int j=0; j<matrix.length; j++){
if(j != i){
for(int k=1; k<matrix.length; k++){
int index = -1;
if(j<i)
index = j;
else if(j>i)
index = j - 1;
minor[index][k-1] = matrix[j][k];
}
}
}
if(i % 2 == 0)
det += matrix[i][0] * detMatrix(minor);
else
det -= matrix[i][0] * detMatrix(minor);
}
return det;
}
Thanks everybody for your help.

Categories

Resources