Index Outside of Bounds on Stock Maximization Algorithm - java

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

Related

Tim sort implementation working at low array size but crashing at high

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);

problems trying to convert c sharp code into java

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.

Array OutOfBounds Exception with MergeSort

I am doing a simple MergeSort implementation taking it form a pseudocode. I use Java Generics for that purpose. However I get such exception on the last element in the first for-loop. I have already made some changes (hope for the better) but still this one inevitably comes up. Why is that so?
private Comparable[] mergesort(Comparable[] elements, int l, int r) {
if(l < r){
int m = (l + r - 1)/2;
mergesort(elements, l, m);
mergesort(elements, m + 1, r);
int i = l;
int j = m + 1;
int k = l;
Comparable[] elements1 = (Comparable[])new Comparable[l + r]; //changed from [l + r - 1] and in the function caller also mergesort(elements, elements.length - elements.length, elements.length - 1)
while(i <= m && j <= r){
if(elements[i].compareTo(elements[j]) <= 0 ){
elements1[k] = elements[i];
i++;
} else {
elements1[k] = elements[j];
j++;
}
k++;
}
for(int h = i; i <= m; h++){
elements[k + (h - i)] = elements[h];
//ArrayIndexOutOfBoundsException: 4(the length of the input array)
}
for(int h = j; h <= k - 1; h++){
elements[h] = elements1[h];
}
}
return elements;
}
While your code is hard to read, I think you are comparing the wrong value.
for(int h = i; i <= m; h++){
^
should be h
elements[k + (h - i)] = elements[h];
//ArrayIndexOutOfBoundsException: 4(the length of the input array)
}
You use:
for(int h = i; i <= m; h++) {
elements[k + (h - i)] = elements[h];
}
You always increase h but compare i <= m. Since you never change i you have an endless loop.

Is it possible to implement a BubbleSort with only one cycle? (Not recursive)

What Im trying to implement is a BubbleSort/similar algorithm, but with just one single cycle.
What that means is, I want to change this:
for (i = 0; i < N - 1; i++)
for(j = i+1; j < N; j++)
//code
into this:
for (ij = 0; ij < N * (N - 1) / 2; ij++)
i = ?
j = ?
//code
The problem is, I need to implement the values of 'i' and 'j' manually. Does anybody know if this is possible?
Assuming you meant i+1, not 1+1, the code
for (i = 0; i < N - 1; i++)
for(j = i+1; j < N; j++)
//code
is equivalent to
int k = 2 * N - 1;
for (int ij = 0; ij < N * (N - 1) / 2; ij++) {
int i = (int) Math.floor((k - Math.sqrt(k * k - 8 * ij)) / 2);
int j = i + 1 + ij - (k - i) * i / 2;
//code
}
This is completely pointless though...
You could do it like this:
while (ij < N * (N - 1) / 2) {
j = (j + 1) % N;
if (j==0)
i++;
}
I don't see the benefit though
Here is a while-loop version, though I also don't see the point. Generally, you can turn almost anything into one loop by having a boolean that indicates whether to continue, and various if-tests to decide what to do inside the loop. If applied to a naturally nested loop algorithm, the result will be less readable and maintainable than using multiple loops.
public static void weirdSort(int[] data) {
boolean sortDone = false;
boolean swapDone = false;
if (data.length < 2) {
// Lengths 0 and 1 create special cases, and are already sorted.
return;
}
int i = 0;
while (!sortDone) {
if (data[i] > data[i + 1]) {
swapDone = true;
int temp = data[i + 1];
data[i + 1] = data[i];
data[i] = temp;
}
i++;
if (i == data.length - 1) {
sortDone = !swapDone;
swapDone = false;
i = 0;
}
}
}

longest common subsequence printdDiff

Just a quick question about the longest Common subsequence algorithm.
I have done the part where you need to generate the subsequence as follow:
public int[][] lcsLength(char[] input1, char[] input2) {
int[][] opt = new int[M][N];
for (int i = 1; i < input1.length; i++) {
for (int j = 1; j < input2.length; j++) {
if (input1[i] == input2[j]) {
opt[i][j] = opt[i - 1][j - 1] + 1;
} else {
opt[i][j] = Math.max(opt[i][j - 1], opt[i - 1][j]);
}
}
}
return opt;
}
and the printDiff function as follow:
private static void printDiff(int[][] opt,String x,String y,int i, int j) {
if(i>0 &&j>0 && x.charAt(i-1)==y.charAt(j-1)){
printDiff(i-1,j-1);
System.out.println(x.charAt(i-1));
}
else{
if(j>0&&(i==0||opt[i][j-1]>=opt[i-1][j])){
printDiff(i-1,j-1);
System.out.println("-"+y.charAt(j-1));
}
else if(i>0&&(j==0|| opt[i][j-1]<=opt[i-1][j])){
printDiff(i-1,j-1);
System.out.println(x.charAt(i-1));
}
}
}
And then if I use this as parameters:
String input1="ABCDE"
String input2="ACDC"
int i=input1.length()
int j=input2.length()
after generating the opt matrix with lcsLength() I wish that printdiff woul give me :
ABCDE-
A-CD-C
but instead I get:
ABCDE-
ABCD-C
any ideas on what I did wrong would help me a lot
Thanks
Laurent
From wiki:
function printDiff(C[0..m,0..n], X[1..m], Y[1..n], i, j)
if i > 0 and j > 0 and X[i] = Y[j]
printDiff(C, X, Y, i-1, j-1)
print " " + X[i]
else if j > 0 and (i = 0 or C[i,j-1] ≥ C[i-1,j])
printDiff(C, X, Y, i, j-1)
print "+ " + Y[j]
else if i > 0 and (j = 0 or C[i,j-1] < C[i-1,j])
printDiff(C, X, Y, i-1, j)
print "- " + X[i]
else
print ""
This line:
else if(i>0&&(j==0|| opt[i][j-1]<=opt[i-1][j])){
Should be:
else if(i>0&&(j==0|| opt[i][j-1]<opt[i-1][j])){
(change <= to just <)
Don't know if it's a related issue, but I think your LCS code should be:
public int[][] lcsLength(char[] input1, char[] input2) {
int[][] opt = new int[input1.length+1][input2.length+1];
for (int i = 1; i <= input1.length; i++) {
for (int j = 1; j <= input2.length; j++) {
if (input1[i-1] == input2[j-1]) {
opt[i][j] = opt[i - 1][j - 1] + 1;
} else {
opt[i][j] = Math.max(opt[i][j - 1], opt[i - 1][j]);
}
}
}
return opt;
}

Categories