Basically i built this rudementary tim sort built for a simple project and it works with a sub of 32 all the way up to 1000 integers (the next thing i tried was 5000) and then it crashes with a index out of bounds exeception i tried increasing the sub to 64 but it just dosent seem to work i was wondering if anyone could tell me what im doing wrong here.
public static void timSort(List<Comparable> nums) {
int sub = 32;
for (int i = 0; i < nums.size(); i += sub)
{
if((nums.size() -1) < (i + 31)) {
inPlaceInsertion(nums, i, (nums.size() - 1));
}else {
inPlaceInsertion(nums, i, (i + 31));
}
}
for (int size = sub; size < nums.size(); size = 2 * size)
{
for (int left = 0; left < nums.size(); left += 2 * size)
{
int mid = left + size - 1;
int right;
if((nums.size() - 1) < (left + 2 * size - 1)) {
right = nums.size() -1;
}else {
right = left + 2 * size -1;
}
merge(nums, left, mid, right);
}
}
}
public static void inPlaceInsertion(List<Comparable> nums, int first, int last){
for(int i = first; i <= last; i++){
Comparable hold = nums.get(i);
int j;
steps++;
for(j = i; j > first && hold.compareTo(nums.get(j - 1)) < 0; j--) {
nums.set(j, nums.get(j - 1));
steps+=4;
}
nums.set(j, hold);
steps++;
}
}
private static void merge(List<Comparable> nums, int first, int mid, int last){
List<Comparable> newList = new ArrayList<Comparable>();
int loopCountA = 0;
int loopCountB = 0;
while(true) {
if(loopCountB == (last - mid)) {
while(first + loopCountA <= mid) {
newList.add(nums.get(first + loopCountA)); loopCountA++;
steps++;
}
break;
}else if(first + loopCountA > mid) {
while(loopCountB < (last - mid)) {
newList.add(nums.get(mid + (loopCountB + 1))); loopCountB++;
steps++;
}
break;
}else {
if(nums.get(mid + (loopCountB + 1)).compareTo(nums.get(first + loopCountA)) < 0) {
// here is where error is (line above)
newList.add(nums.get(mid + (loopCountB + 1)));
steps += 5;
loopCountB++;
}else {
newList.add(nums.get(first + loopCountA));
steps += 5;
loopCountA++;
}
}
}
for(int i = 0; (i - 1) < (last - first); i++) {
nums.set(first + i, newList.get(i));
steps+=2;
}
}
Here's the error...
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 5024 out of bounds for length 5000
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:372)
at java.base/java.util.ArrayList.get(ArrayList.java:458)
at Sorts.merge(Sorts.java:772)
at Sorts.timSort(Sorts.java:1193)
at Sorts.sortMenu(Sorts.java:255)
at Sorts.main(Sorts.java:33)
Simple main method which demonstrates it not working
int depthLimit
= (int)(2 * Math.floor(Math.log(nums.size()) /
Math.log(2)));
introSort(nums, 0, nums.size() -1, depthLimit);
I have matrix each cell contain number I need to calculate the cell and its neighbor cells and come out with an average of that cells.
Look at the code that I wrote.
public Matrix imageFilterAverage() {
for (int i=0; i < _array.length;i++)
for (int j=0; i < _array[i].length;j++){
_array[i][j] = (_array[i][j] + _array[i][j+1] + _array[i+1][j] + _array[i+1][j+1]) / 4;
}
return this;
}
My code return error on index issue when j+1 reach 3 it is out of bound because the cells are 0 1 2.
So for example, if I have a matrix like this
10 5 7 3
50 3 2 1
60 2 5 2
The results matrix should be like this.
17 12 3 3
21 16 2 3
28 20 2 2
I have posted the images one matrix source and matrix results
Thank you very much for your time and help.
/**
* Takes the given array and transforms each slot in the array as an average of the slots around it.
* #return an array with each where each slot in the array is "blurred" by the slots around it.
*/
public Matrix imageFilterAverage() {
int avgArray[][] = new int[_twoDiPicture.length][];
int numOfCellsAround = 0;
int cellsSum = 0;
for (int y = 0; y < _twoDiPicture.length; y++) {
avgArray[y] = new int[_twoDiPicture[y].length];
for (int x = 0; x < _twoDiPicture[y].length; x++) {
numOfCellsAround = 0;
cellsSum = 0;
numOfCellsAround += cellsAround(y, x);
cellsSum += cellsSum(y, x);
avgArray[y][x] = cellsSum / numOfCellsAround;
}
}
return new Matrix(avgArray);
}
/* a private method that deals with index out of bound exceptions. */
private boolean isInBounds(int y, int x) {
return y < _twoDiPicture.length && y >= 0 && x < _twoDiPicture[y].length && x >= 0;
}
/* A private methods that uses "isInBounds" to find how many cells are surrounding the target array. */
private int cellsAround(int y, int x) {
int cells = 1;
if (isInBounds(y + 1, x)) {
cells++;
}
if (isInBounds(y - 1, x)) {
cells++;
}
if (isInBounds(y, x + 1)) {
cells++;
}
if (isInBounds(y, x - 1)) {
cells++;
}
if (isInBounds(y - 1, x + 1)) {
cells++;
}
if (isInBounds(y - 1, x - 1)) {
cells++;
}
if (isInBounds(y + 1, x - 1)) {
cells++;
}
if (isInBounds(y + 1, x + 1)) {
cells++;
}
return cells;
}
/*A private method that returns the sum of all the adjacent cells around target cell. */
private int cellsSum(int y, int x) {
int sum = _twoDiPicture[y][x];
if (isInBounds(y + 1, x)) {
sum += _twoDiPicture[y + 1][x];
}
if (isInBounds(y - 1, x)) {
sum += _twoDiPicture[y - 1][x];
}
if (isInBounds(y, x + 1)) {
sum += _twoDiPicture[y][x + 1];
}
if (isInBounds(y, x - 1)) {
sum += _twoDiPicture[y][x - 1];
}
if (isInBounds(y - 1, x + 1)) {
sum += _twoDiPicture[y - 1][x + 1];
}
if (isInBounds(y - 1, x - 1)) {
sum += _twoDiPicture[y - 1][x - 1];
}
if (isInBounds(y + 1, x - 1)) {
sum += _twoDiPicture[y + 1][x - 1];
}
if (isInBounds(y + 1, x + 1)) {
sum += _twoDiPicture[y + 1][x + 1];
}
return sum;
}
I have an ugly solution which can be improved:
public static void main(String[] args) {
int[][] matrix = {{10, 5, 7, 3},
{50, 3, 2, 1},
{60, 2, 5, 2}};
int[][] average = new int[matrix.length][matrix[0].length];
for(int i = 0; i< matrix.length; i++){
for(int j = 0; j< matrix[0].length; j++){
int sum = 0;
int div = ((i==0 && j ==0) ||
(i==0 && j == matrix[0].length-1) ||
(i== matrix.length-1 && j ==0)||
(i== matrix.length-1 && j == matrix[0].length-1)) ? 4 :
((i==0 && j > 0) ||
(i>0 && j == 0) ||
(i== matrix.length-1 && j >0)||
(i> 0 && j == matrix[0].length-1))? 6 : 9;
for(int k = Math.max(i-1, 0); k <= Math.min(i+1, matrix.length-1); k++){
for(int t = Math.max(j-1, 0); t <= Math.min(j+1, matrix[0].length-1); t++){
sum += matrix[k][t];
}
}
average[i][j] = sum / div;
}
}
for(int[] r:average){
System.out.println(Arrays.toString(r));
}
}
I made an implementation of Wagner Fischer algorithm in java with input cost, but I want to display all steps.
I search but can't find any idea.After a long time I tried to keep each transformation in matrix alongside cost and to go through back to first solution then reverse it... is this a good idea, if it is, how should I set condition?
kitten -> sitting
1.replace k with s
2.keep i
3.keep t
4.keep t
5.replace t
6.add g
I tried to make function for display steps and can't figure out how to solve it.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Principal {
static int c1, c2, c3;
static String word1, word2;
public static void main(String[] args) throws FileNotFoundException {
Scanner data_in = new Scanner(new File("data.in"));
word1 = data_in.next();
word2 = data_in.next();
c1 = data_in.nextInt();
c2 = data_in.nextInt();
c3 = data_in.nextInt();
System.out.printf("\nInsert: %s, Delete: %s, Replace: %s\n", c1, c2, c3);
System.out.printf("\nLevenstheinDistance: %s", LevenshteinDistance(word1, word2, c1, c2, c3));
}
private static int LevenshteinDistance(String str1, String str2, int InsCost, int DelCost, int ReplCost)
{
if(word1.length() == 0)
return InsCost*str1.length();
if(word2.length() == 0)
return DelCost*str2.length();
int substitutionCost = ReplCost;
if(ReplCost > InsCost + DelCost)
ReplCost = InsCost + DelCost;
Solution[][] ManageSol = new Solution[str1.length()+1][str2.length()+1];
for(int i = 0; i <= str1.length(); i++)
{
for(int j = 0; j <= str2.length(); j++){
ManageSol[i][j] = new Solution();
}
}
System.out.printf("\nLungime str1: %s", str1.length());
System.out.printf("\nLungime str2: %s", str2.length());
for(int i = 0; i <= str1.length(); i++)
{
for (int j = 0; j <= str2.length(); j++)
{
if (i == 0)
ManageSol[i][j].solution = j;
else if (j == 0)
ManageSol[i][j].solution = i;
else if (str1.charAt(i - 1) == str2.charAt(j - 1))
{
substitutionCost = 0;
ManageSol[i][j].ecqualTo(minimum(
ManageSol[i][j - 1].solution + InsCost,
ManageSol[i - 1][j].solution + DelCost,
ManageSol[i - 1][j - 1].solution + substitutionCost));
System.out.printf("\nManagerSol[%s, %s]: ch1: %s, ch2: %s", i, j, str1.charAt(i - 1), str2.charAt(j - 1));
}
else
{
substitutionCost = 1;
ManageSol[i][j].ecqualTo(minimum(
ManageSol[i][j - 1].solution + InsCost,
ManageSol[i - 1][j].solution + DelCost,
ManageSol[i - 1][j - 1].solution + substitutionCost));
System.out.printf("\nManagerSol[%s, %s]: ch1: %s, ch2: %s", i, j, str1.charAt(i - 1), str2.charAt(j - 1));
}
}
}
System.out.printf("\n");
path(ManageSol, str1.length(), str2.length(), str1, str2);
System.out.printf("\n");
for(int i = 0; i <= str1.length(); i++)
{
for (int j = 0; j <= str2.length(); j++)
{
System.out.printf("[%s,%s]:(%s,%s) ", i, j, ManageSol[i][j].solution, ManageSol[i][j].operation);
}
System.out.printf("\n");
}
return ManageSol[str1.length()][str2.length()].solution;
}
static int minimum(int x, int y)
{
if(x >= y)
return x;
return y;
}
static Solution minimum(int Ins, int Del, int Replace)
{
Solution solution = null;
if(Ins <= Del && Ins <= Replace)
{
solution = new Solution();
solution.operation = 1;
solution.solution = Ins;
return solution;
}
else if(Del <= Ins && Del <= Replace)
{
solution = new Solution();
solution.operation = 2;
solution.solution = Del;
return solution;
}
else
{
solution = new Solution();
solution.solution = Replace;
solution.operation = 0;
return solution;
}
}
//my failure, function that should display steps
static void path(Solution[][] ManagerSol, int i, int j, String str1, String str2)
{
if(ManagerSol[i][j].operation == 0)
{
System.out.printf("\nReplace %s -> %s", str1.charAt(i-1), str2.charAt(j-1));
if(i > 1 && j > 1)
path(ManagerSol, i-1,j-1, str1, str2);
}
if(ManagerSol[i][j].operation == 1)
{
System.out.printf("\nAdd %s on position %s", str2.charAt(j-1), i-1);
if(j > 1)
path(ManagerSol, i,j-1, str1, str2);
}
if(ManagerSol[i][j].operation == 2)
{
System.out.printf("\nDelete %s", str1.charAt(i-1));
if(j > 1)
path(ManagerSol, i-1,j, str1, str2);
}
}
}
Output for kitten to sitting:
[0,0]:(0,3) [0,1]:(1,3) [0,2]:(2,3) [0,3]:(3,3) [0,4]:(4,3) [0,5]:(5,3) [0,6]:(6,3) [0,7]:(7,3)
[1,0]:(1,3) [1,1]:(1,0) [1,2]:(2,1) [1,3]:(3,1) [1,4]:(4,1) [1,5]:(5,1) [1,6]:(6,1) [1,7]:(7,1)
[2,0]:(2,3) [2,1]:(2,2) [2,2]:(1,0) [2,3]:(2,1) [2,4]:(3,1) [2,5]:(4,1) [2,6]:(5,1) [2,7]:(6,1)
[3,0]:(3,3) [3,1]:(3,2) [3,2]:(2,2) [3,3]:(1,0) [3,4]:(2,1) [3,5]:(3,1) [3,6]:(4,1) [3,7]:(5,1)
[4,0]:(4,3) [4,1]:(4,2) [4,2]:(3,2) [4,3]:(2,2) [4,4]:(1,0) [4,5]:(2,1) [4,6]:(3,1) [4,7]:(4,1)
[5,0]:(5,3) [5,1]:(5,2) [5,2]:(4,2) [5,3]:(3,2) [5,4]:(2,2) [5,5]:(2,0) [5,6]:(3,1) [5,7]:(4,1)
[6,0]:(6,3) [6,1]:(6,2) [6,2]:(5,2) [6,3]:(4,2) [6,4]:(3,2) [6,5]:(3,2) [6,6]:(2,0) [6,7]:(3,1)
In general your idea is correct. It's even simpler than that. You don't need to store any additional information.
You can go backwards (starting from the end of the given strings) and use your dynamic programming values in the following way:
If one of the indices is 0, there is only one way to go.
Otherwise, you can look at 3 possible transitions "backwards" (from (i, j) to (i - 1, j - 1), (i - 1, j) and (i, j - 1)) and choose the one which yields the actual value for (i, j). If there are several possible options, you can choose any of them.
Once you know where to go from the given pair of positions, the operation is uniquely determined.
I'm not versed in Java but here is an illustration in JavaScript:
var a = 'kitten',
b = 'sitting';
var m = new Array(a.length + 1);
for (var i=0; i<m.length; i++){
m[i] = new Array(b.length + 1);
for (var j=0; j<m[i].length; j++){
if (i === 0) m[i][j] = j;
if (j === 0) m[i][j] = i;
}
}
for (var i=1; i<=a.length; i++){
for (var j=1; j<=b.length; j++){
// no change needed
if (a[i - 1] === b[j - 1]){
m[i][j] = m[i - 1][j - 1];
// choose deletion or insertion
} else {
m[i][j] = Math.min(m[i - 1][j], m[i][j - 1], m[i - 1][j - 1]) + 1;
}
}
}
console.log('a: ' + JSON.stringify(a));
console.log('b: ' + JSON.stringify(b));
var i = a.length,
j = b.length,
steps = '';
while (i !== 0 && j !== 0){
if (a[i - 1] === b[j - 1]){
steps = 'no change; ' + steps;
i--;
j--;
} else if (m[i - 1][j] < m[i][j - 1]){
steps = 'delete \'' + a[i - 1] + '\'; ' + steps;
i--;
} else if (m[i - 1][j] === m[i][j - 1]){
steps = 'replace \'' + a[i - 1] + '\' with \'' + b[j - 1] + '\'; ' + steps;
i--;
j--;
} else {
steps = 'insert \'' + b[j - 1] + '\'; ' + steps;
j--;
}
}
if (i === 0 && j > 0){
steps = 'insert first ' + j + ' elements from b; ' + steps;
} else if (j === 0 && i > 0){
steps = 'delete first ' + i + ' elements from a; ' + steps;
}
console.log('\n' + steps[0].toUpperCase() + steps.substr(1));
console.log('\nMatrix:\n');
for (var i in m){
console.log(JSON.stringify(m[i]));
}
i'm try find most similar string in a array, and i found a code in c sharp that is this one
public static int LevenshteinDistance(string s, string t)
{
int n = s.Length;
int m = t.Length;
int[,] d = new int[n + 1, m + 1];
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
Console.WriteLine(cost);
d[i, j] = Math.Min(
Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
d[i - 1, j - 1] + cost);
}
}
return d[n, m];
}
and i'm trying to convert it into java but i get 1 error this is my code in java
public static int LevenshteinDistance(String s, String t)
{
int n = s.length();
int m = t.length();
int[][] d = new int[n + 1][ m + 1];
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
int cost = (t[j - 1] == s[i - 1])? 0 : 1;
d[i][ j] = Math.min(
Math.min(d[i - 1][ j] + 1, d[i][ j - 1] + 1),
d[i - 1][ j - 1]+cost );
}
}
return d[n] [m];
}
i get the error in this line of code
int cost = (t[j - 1] == s[i - 1]) ? 0 : 1;
the error that i have is "Array is required,but string found" this is what i have in my main
String []ray ={"food","drinks","stuffs"};
String fa="drink";
for (int i = 0; i < ray.length; i++)
{
System.out.print(LevenshteinDistance(fa, ray[i]));
}
i would appreciate any help
Use t.charAt(j-1) == s.charAt(i-1) as to access characters (letters) in string You cannot access them directly via index (brackets []).
int cost = (t.charAt(j - 1) == s.charAt(i - 1))? 0 : 1;
You are accessing the strings as arrays here with the [] array operator:
t[j - 1] == s[i - 1]
to get the nth char of a string, instead use .charAt(n)
so in this case change it to:
t.charAt(j - 1) == s.charAt(i - 1)
the same applies to the rest of the code.
I have the following code translated as best I could from Java to C#:
public double maxProfit(double[] prices, int K)
{
if (K == 0 || prices.Length == 0)
{
return 0;
}
var dp = new double[K + 1, prices.Length];
for (int i = 1; i < K + 1; i++)
{
double maxDiff = -prices[0];
for (int j = 1; j < prices.Length; j++)
{
dp[i, j] = Math.Max(dp[i, j - 1], prices[j] + maxDiff);
maxDiff = Math.Max(maxDiff, dp[i - 1, j] - prices[j]);
}
}
printTrans(dp, prices, K);
return dp[K, prices.Length - 1];
}
public void printTrans(double[,] dp, double[] prices, int K)
{
int i = K - 1;
int j = prices.Length;
var priceList = new List<double>();
while (true)
{
if (i == 0 || j == 0)
{
break;
}
if (dp[i, j] == dp[i, j - 1])
{
j = j - 1;
}
else
{
priceList.Add(j);
double maxDiff = dp[i, j] - prices[j];
for (int z = j - 1; z >= 0; z--)
{
if (dp[i - 1, z] - prices[z] == maxDiff)
{
i = i - 1;
j = z;
priceList.Add(j);
break;
}
}
}
}
while (priceList.Count > 0)
{
Console.WriteLine("Buy # " + prices[priceList.IndexOf(0)]);
Console.WriteLine("Sell # " + prices[priceList.IndexOf(0)]);
}
}
Error occurs in the second method on lines:
if (dp[i, j] == dp[i, j - 1])
and
for (int z = j - 1; z >= 0; z--)
{
if (dp[i - 1, z] - prices[z] == maxDiff)
I am getting an Index was outside the bounds of the array. error. I understand what this error means but I have no clue on my to fix it. It took me quite a bit to understand the first part of this code but for the second part, I am at a loss.
Also what is the C# equivalent of the Java pollFirst() method?
Probably this line is the cause
public void printTrans(double[,] dp, double[] prices, int K)
{
int i = K - 1;
int j = prices.Length; // <=== this line is the cause
its causing the j to refer an index outside the bounds of the 2D array.
If you have ported from java recheck your java code.
Either make that line
int j = prices.Length - 1;
Or you need to make changes to how you create your array
var dp = new double[K + 1, prices.Length]; // <-- prices.Length would have to change here