what is wrong with my backtracking algorithm? (sudoku solver, stackoverflow) - java

below is a method to solve a sudoku with backtracking algorithm.. or that's what I meant to do
private boolean fillGrid(int[][] a){
if(!find(a)) // this method finds if there's unassigned grid
return true;
for(int i = 0; i<a.length ; i++){
for(int j = 0; j < a.length ; j++){
if(a[i][j] == 0){ // if a[i][j] is unassigned, perform things below
for(int num = 1 ; num <=9; num++){
if(noConflict(a, i, j, num ) && noConflictGrid(a, i, j , num))
a[i][j]= num;
if(fillGrid(a)) // recurse
return true;
a[i][j] = 0; // unassigned to try again whenever false;
}
}
}
}
return false;
}
however when I run it, it gave me stackoverflow. the stackoverflow points to fillGrid(a) the one with 'recurse' comment, and (!find(a)). the method find is below:
private boolean find(int[][] a){
for(int[] b: a){
for(int c: b){
if(c == 0)
return true;
}
}
return false;
}
anyone please tell me what's wrong with the code?

if(noConflict(a, i, j, num ) && noConflictGrid(a, i, j , num))
a[i][j]= num;
Are you sure this is always guaranteed to be true? If it's not, the state of a doesnt change before the next call to fillGrid(a) and we go back to square one, calling the same method with the same input. Which lead to a stackoverflow.

You are creating a lot of branches on each step.
I recomend you to take one cell on each step and try to fill it with the 9 numbers, so you will only carry on with the valid.
Right now you are creating up to 9*9*9 branches on every step, you recursion is too much complex and this is was is creating the stack overflow.
So in every step just seek for the first free cell (with lower i and j index) and try to fill it with the 9 numbers.

Related

THIS java.lang.ArrayIndexOutOfBoundsException ERROR

public static int StringInString(String one, String two) {
if(one==null||two==null||one.equals("")||two.equals("")){
return 0;
}
else{
int x=one.length(),y=two.length(),sum=0,i=0,j=0;
char[] onee=one.toCharArray();
char[] twoo=two.toCharArray();
while(i<x){
while(j<y){
if(onee[i]==twoo[j]){
i++;
j++;
}
else{
if(j==0){
i++;
}
else{
j=0;
i++;
}
}
}
sum++;
i=i-y+1;
j=0;
}
return sum;
}
}
public static void main(String[] args){
int sum;
sum = StringInString("salamsal","sal");
System.out.println(sum);
}
hello I dont know why this ERROR apear?! please HELP me;
this code want count the similar text in two stringsa
and the result of this code should be = 2.
When you are inside the second "while" cycle, even if i > x, the cycle continues as long as j < y. So when it happens that i++ in the second cycle makes i become greater than x-1, and j is still less than y, in the first "if" (always inside the second while cycle) the program tests if onee[8] == twoo[0], and since onee[8] doesn't exist (because the indexes of "salamsal" go from 0 to 7) it shows the error that the index is out of the array bounds. To solve the error you should check for the value of i inside the second cycle, because it may happen that i++ makes this index become greater than x-1, where x is, as you declared, the length of the first string.

Calculating the factorial of every element in an integer array

I need to create a Method that has 2 parameters in Java, upperborder and lowerborder. This method must create an array from the number 2 to the number 10.
Then I must implement another method, that calculates the factorial for a given number.
Then I must implement a third method that calculates the factorial for every element in the created array and test all these methods in a TestClass.
I know how to do this, but apparently I'm making some kind of a mistake in my code and it gives me the StackOverflow exception. I read the code a couple of times, but I can't seem to quite understand where I'm wrong.
package fakultaetinarray;
public final class FakultaetinArray{
private int i;
private int[] a;
private int j;
public FakultaetinArray(){
System.out.println("Given array : ");
createArray(1, 9);
System.out.println("Factorial for every element : ");
FakinArray();
}
public int fakRe(int n){
if(n == 1){
return n;
}
return n * fakRe(n - 1);
}
public void createArray(int untergrenze, int obergrenze){
this.a = new int[obergrenze];
for(this.j = 1; j <= a.length; j++){
a[i] = j + 1;
System.out.println(a[i]);
}
}
public void FakinArray(){
a[0] = 2;
for(i = 1; i < a.length; i++){
int fak = fakRe(a[i]);
a[i] = fak;
System.out.println(fak);
}
}
}
The reason you're getting StackOverflowErrors is due to your recursive method not having a case when n == 0.
The reason that your values are coming in as 0 is due to how you're constructing your loop.
for(this.j = 1; j <= a.length; j++){
a[i] = j + 1;
System.out.println(a[i]);
}
It's unclear why you're using j here at all, and i is initialized to its default value of 0, so in all reality, you're only ever filling one element of your array with a positive value and all of the others are at zero.
You need to reconsider how your loops are constructed. I would strongly encourage you not to make them fields, but declare them as part of the loop construct instead.
if(n == 1){ is not a strong enough condition to block the recursion: n can go below 1. In your particular case, you have a situation where n is 0.
Consider unwinding the recursion to a simple loop in any case. As a rule of thumb, recursion is not good for O(N) stuff.

Why I am returning the wrong output?

I am not sure why I am returning false for the first test run as shown in the test table attachment. This was one of my assignments last semester and I never figured out how to solve it:/ My assignment was to:
Write the definition of a method , oddsMatchEvens, whose two parameters are arrays of integers of equal size. The size of each array is an even number. The method returns true if and only if the even-indexed elements of the first array equal the odd-indexed elements of the second, in sequence. That is if w is the first array and q the second array , w[0] equals q[1], and w[2] equals q[3], and so on.
Test table
My code was:
public boolean oddsMatchEvens(int[] w, int[] q) {
int count = 0;
for (int i = 0; i < w.length; i++) {
if (w[i] == q[i + 1])
count++;
if (count == (w.length - 1))
return true;
}
return false;
}
if (count == (w.length - 1))
return true;
This is wrong, since you have only w.length/2 indices which you have to compare.
You should just return false, if w[i] != q[i+1].
And you should increase i by 2, not by 1.
There are two problems with the code:
Firstly, it is clearly mentioned the two input arrays are of equal length and you have to compare them even index to odd index. So the corner case occurs when you are checking last item of first array with last+1 item of second array(which doesn't exist as arrays are of equal length.
Secondly, you have to check first array even with second array odd so increment should be i+=2 and not i++.
Correct code with optimization(if one check fails you can come out of loop):
public boolean oddsMatchEvens(int[] w, int[] q) {
for (int i = 0; i < w.length-1; i+=2) {
if (w[i] != q[i + 1])
return false;
else
continue;
}
return true;
}
public boolean oddsMatchEvens (int []w, int []q) {
for (int j = 0; j < w.length-1; j+=2) {
if (w [j] != q [j+1])
return false;
continue;
}
return true;
}

Quicksort Stack overflow error

while practicing for an exam I encountered a (for me) strange issue with quicksort.
My implementation:
public void quicksort(int l, int r)
{
if(l<r && l>0 && r<=array.length-1)
{
int pivot = array[pivot(l, r)];
int i = l;
int j = r;
if(j==i+1)
{
if(array[i]>array[j])
{
System.out.println(array[i]+"<->"+array[j]);
int help = array[i];
array[i] = array[j];
array[j] = help;
}
}
else{ while(i<=j)
{
if(array[i]>=pivot && pivot>= array[j])
{
System.out.println(array[i]+">="+pivot+">="+array[j]);
int help = array[i];
array[i] = array[j];
array[j] = help;
i++;
j--;
}
else{
i++;
}
}
if(l<j && j<array.length-1)quicksort(l, j);
if(i<r)quicksort(i, r);
}
}
}
But this is giving me a "Java.lang.StackOverflowError: null" in (here) Line 34. This Error can, however, be avoided by swapping j with j-1 and i with j in Lines 34 and 35. I really tried everything that came into my mind, but I really cannot come up with a solution :/
I think there are much better implementations of quicksort, here is my attempt with commentary which will hopefully help you remember it better:
public static void quickSort(int[] theArray, int left, int right) {
//we declare 2 variables
int i = left;
int j = right;
//we calculate a pivot, simply taking the middle value of the array
int pivot = theArray[(left+right)/2];
//check that i hasn't gone beyond j (i starts at 0, j starts at array.length)
while(i<=j){
//if here, must mean i is less-than or equal to j, so check to see if
//the array value i is less than our pivot
while(theArray[i] < pivot){
//if it is less-than pivot, the value theArray[i] is in correct place
//so we can increment i to go to next
i++;
}
//now do exactly same thing for j, however, j starts at array.length, so decrement
while(theArray[j] > pivot){
j--;
}
//if we are here, it likely means we need to swap values
//check that i hasn't gone beyond j
if(i<=j){
//simple swap
temp = theArray[i];
theArray[i] = theArray[j];
theArray[j] = temp;
//we just swapped values, so we don't need to check them again, so continue
i++;
j--;
}
}
//now check if parameter left is < j
//if left has gone beyond j, it means we no longer need to further sort
if(left<j){
//rinse and repeat
quickSort(theArray, left, j);
//and check that i is still less than right parameter
}if(i < right){
//rinse and repeat
quickSort(theArray, i, right);
}
}
Usage:
//you can amend this code so you don't have to pass in an array
quickSort(theArray, 0, theArray.length-1);
It's fairly simple once you understand what quicksort is trying to do. Don't stress out about it, take a 15minute break, watch a graphical representation of the algorithm and think about how the code should behave and what it's trying to achieve. Come back here, look at the code, and start implementing it. Rinse and repeat! Good luck!
Also (not sure how your exam layout is) but you could also mention that to near-enough guarantee runtime of O(n log n), you really ought to shuffle the array before hand.

delete position in array of string

hello i'm new in Java and i'm having a trouble.
My program prints Strings in a Jframe. I generate a array of Strings called v. v[0] is always null. And I request an input from the user to delete one position of the array v, wich i call numberdel. If I have an array
v[0]=[null] v[1]=[hello] v[2]=[my name is] v[3]=[john] and if
numberdel=2
the final result should be
v[0]=[null] v[1]=[hello] v[2]=[john]
I wasn't making it so I created a new array called b. But it still isn't working like a wanted...
public static
(...)
String[] b = new String[v.length-1];
boolean jump = false;
for(int j=1; j<b.length; j++){
if(jump==false){
if(j != numberdel){
b[j] = v[j];
}
else jump = true;
}
else{
b[j] = v[j+1];
}
(...)//action for every cycle
}
(...)
When j == numberdel, your loop will set jump to true and skip right past the else statement.
I'd recommend not using the jump variable since it will basically be false when j < numberdel and true otherwise.
for(int j = 1; j < b.length; j++)
{
if (j < numberdel)
b[j] = v[j];
else
b[j] = v[j + 1];
}
you can do your task in the single array itself...as below...
void delet(int numberdel)
{
for(int i=numberdel ; i< v.length ;i++)
v[i] = v[i+1];
}
i suggest that if you can do the same thing in one array then why to waste space...you are doing the thing its fine,but i guess this is better...hope it works for you...
Use System.arrayCopy starting with array v. numberdel is the 0-based item to delete.
String[] b = new String[v.length-1];
System.arrayCopy(v, 0, b, 0, numberdel);
System.arrayCopy(v, numberdel + 1, b, numberdel, v.length - numberdel);

Categories

Resources