I'm just beginner in programming.
uf is a union-find class with the method union which connects the roots of two node.
This piece of code is responsible for opening a site of a grid and union the site with its neighbor if any of neighbor is opened. And if one of its neighbors is full, then fill all nodes that connected with the site.
This is the actual code:
if(i == 1){
uf.union(len*len, xyTo1D(i,j));
if(existAndOpen(i+1,j)){
uf2.union(xyTo1D(i+1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
}
if(existAndOpen(i-1,j)){
uf2.union(xyTo1D(i-1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
}
if(existAndOpen(i,j-1)){
uf2.union(xyTo1D(i,j-1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
}
if(!(j == len && i == len)){
if(existAndOpen(i,j+1)){
uf2.union(xyTo1D(i,j+1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
}
}
}
else{
if(existAndFull(i+1,j)){
uf2.union(xyTo1D(i+1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
}
if(existAndFull(i-1,j)){
uf2.union(xyTo1D(i-1,j), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
}
if(existAndFull(i,j-1)){
uf2.union(xyTo1D(i,j-1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
}
if(!(j== len && i == len)){
if(existAndFull(i,j+1)){
uf2.union(xyTo1D(i,j+1), xyTo1D(i,j));
uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
}
}
if(existAndOpen(i+1,j)){
uf.union(xyTo1D(i,j), xyTo1D(i+1,j));
}
if(existAndOpen(i-1,j)){
uf.union(xyTo1D(i,j), xyTo1D(i-1,j));
}
if(existAndOpen(i,j-1)){
uf.union(xyTo1D(i,j), xyTo1D(i,j-1));
}
if(!(j== len && i == len)){
if(existAndOpen(i,j+1)){
uf.union(xyTo1D(i,j), xyTo1D(i,j+1));
}
}
}
}
How can I simplify the code?
Try this
boolean f1(int a, int b) { }
boolean f2(int a, int b) { }
void A(int a, int b) { }
void testAndA(BiPredicate<Integer, Integer> p, int a, int b) {
if (p.test(a, b))
A(a, b);
}
and
if(x == 1){
testAndA(this::f1, x + 1, y);
testAndA(this::f1, x, y + 1);
} else {
testAndA(this::f2, x + 1, y);
testAndA(this::f2, x, y + 1);
}
You can write a loop to loop through all of the different values that could be passed to f1(), such as something like:
for (int deltax = -1; deltax <= 1; deltax++) {
for (int deltay = -1; deltay <= 1; deltay++) {
if (f1(x + deltax, y + deltay)) {
A(x + deltax, y + deltay);
}
}
}
Of course change the start and end values of deltax and deltay depending on which conditions you need to check.
You say there are "more if statements in each block." Reading between the lines, I assume that means you need to make more calls to f1/f2 and A, but with different x and y offsets.
Here is a program that shows a way to refactor the code to avoid coding repetition. Its main features are:
It uses object orientation to abstract the inner if blocks.
It uses an offsets array to represent the x/y offsets for each inner if block.
The doIt() method uses a loop to invoke the inner if blocks.
public class Main {
static interface F {
void f(int i, int j);
}
static class F1Caller implements F {
public void f(int a, int b) {
if (f1(a, b)) {
A(a, b);
}
}
}
static class F2Caller implements F {
public void f(int a, int b) {
if (f2(a, b)) {
A(a, b);
}
}
}
static boolean f1(int a, int b) { System.out.print(" f1. "); return true; }
static boolean f2(int a, int b) { System.out.print(" f2. "); return true; }
static void A(int a, int b) { System.out.println("a: " + a + ", b: " + b); }
static F1Caller f1Caller = new F1Caller();
static F2Caller f2Caller = new F2Caller();
// x and y offsets for each call to f1/f2.
// Add more offset rows, as needed.
static int offsets[][] = {
{1, 0},
{0, -1}
};
static void doIt(int x, int y) {
System.out.println("x: " + x + ", y: " + y);
F f = (x == 1) ? f1Caller : f2Caller;
for (int k = 0; k < offsets.length; k++) {
f.f(x + offsets[k][0], y + offsets[k][1]);
}
}
public static void main(String[] args) {
doIt(0, 0);
doIt(1, 0);
}
}
The output of the above program is:
x: 0, y: 0
f2. a: 1, b: 0
f2. a: 0, b: -1
x: 1, y: 0
f1. a: 2, b: 0
f1. a: 1, b: -1
You can combine the function together.
Using a switch.
public static boolean func(int a, int b, int fun)
{
boolean output = false;
switch(fun)
{
case 1:
//do stuff
output = true;
break;
case 2:
//do stuff
output = true;
break;
default:
//unknown function handling
output = false;
}
return output;
}
Integrate it with a for-loop:
public static void main(String[] args)
{
int i;
//Change this to whatever you want or set it to a argument.
int repeat = 2;
for(i = 1; i <= repeat; i++)
{
func(a, b, i);
}
}
Related
The goal of this project is to create a class search. I will need methods of binary search and linear search. For each method you are going to ask the user for a key, then search for this key in an array of numbers (you can assume the numbers in the array). If you found the key return its location, otherwise returns -1. Test these methods by creating an object from the Search class (in the main method) and calling the linear and the binary methods.
Below I have created the code and I am trying to create my main so I can test the linear and binary methods but it is not working. It could be because I'm testing like three different classes in the same main, but I am not sure I formatted them in the right way and that's the reason why I am getting errors. I need help, please.
My Search class.
`
public class Search {
public static int linearsearch(int arr2[], int x2) {
int N = arr2.length;
for (int i = 0; i < N; i++) {
if (arr2[i] == x2)
return i;
}
return -1;
}
public int binarySearch(int arr3[], int l, int r, int x) {
if (r >= l) {
int mid = l + (r-1)/2;
if (arr3[mid] ==x)
return mid;
if(arr3[mid] > x)
return binarySearch(arr3, l, mid -1, x);
return binarySearch(arr3, mid + 1, r, x);
}
return -1;
}
}
My Main class
public class MainTester {
public static void main(String args[]) {
//sorting tester
Sorting obj = new Sorting();
int arr[] = {9,5,4,1,6,10,3,2,7,8};
obj.bubbleSort(arr);
System.out.println("Sorted array:");
obj.printArray(arr);
//binary search tester
int arr3[] = {2,3,5,4,30};
int n = arr3.length;
int x = 10;
int result = binarySearch(arr3, 0, n-1, x);
if (result == -1)
System.out.println("Element not present");
else System.out.println("Element found " + result);
//linear search tester
int arr2[] = {2,3,4,10,30};
int x2 = 10;
int result2 = linearsearch(arr2, x2);
if (result2 == -1)
System.out.print("Element is not present in array.");
else
System.out.print("Element is present " +result2);
}
private static int binarySearch(int[] arr3, int l, int r, int x) {
// TODO Auto-generated method stub
return -1;
}
private static int linearsearch(int[] arr2, int x) {
// TODO Auto-generated method stub
return -1;
}
}
I was expecting this code to test all my methods in the main so I can print the result of my binary and linear search
Here is a working version of your code.
There was still some mistakes. See comments in code below.
Class 'Search'
//Don't mix static and non static method
public class Search {
//linearsearch replaced by linearSearch: use camel case in your class and method names
//Try to use variable names that will help to understand your code.
//Here 'x' has been replaced by 'numberToFind'
public int linearSearch(int arr[], int numberToFind) {
int n = arr.length;//N replaced by n: use Java coding convention
for (int i = 0; i < n; i++) {
if (arr[i] == numberToFind)
return i;
}
return -1;
}
public int binarySearch(int arr[], int l, int r, int numberToFind) {
if (r >= l) {
// There was an error at line below when calculating the 'mid' number
// int mid = l + (r - 1) / 2;
int mid = (l + r) / 2;
if (arr[mid] == numberToFind)
return mid;
if (arr[mid] > numberToFind)
return binarySearch(arr, l, mid - 1, numberToFind);
return binarySearch(arr, mid + 1, r, numberToFind);
}
return -1;
}
}
Class 'MainTester'
Try to avoid repetitive code.
If you have some, extract it to another method and call that method.
public class MainTester {
private Search search;
public MainTester() {
super();
search = new Search();
}
public void testLinearSearch(int[] numberArray, int numberToFind) {
int result = search.linearSearch(numberArray, numberToFind);
printResult("Linear search: ", numberToFind, result);
}
public void testBinarySearch(int[] arr, int numberToFind) {
int result = search.binarySearch(arr, 0, arr.length - 1, numberToFind);
printResult("Binary search: ", numberToFind, result);
}
private void printResult(String searchType, int searchNumber, int arrayIndex) {
if (arrayIndex == -1)
System.out.println(searchType + "Element " + searchNumber + " is not present in array.");
else
System.out.println(searchType + "Element " + searchNumber + " is present at index " + arrayIndex);
}
public static void main(String args[]) {
MainTester tester = new MainTester();
// Try to find a number using linear search
int numbertoFind = 10;
int[] arr2 = { 2, 3, 4, 10, 30 };
tester.testLinearSearch(arr2, 10);
// Try to find a number using binary search with an unsorted array: will not
// work
numbertoFind = 4;
int[] unsortedArray = { 2, 3, 5, 4, 30 };
tester.testBinarySearch(unsortedArray, numbertoFind);
// Try to find a number using binary search with an sorted array: works
int sortedArray[] = { 2, 3, 4, 5, 30 };
tester.testBinarySearch(sortedArray, numbertoFind);
}
}
Hope it helps.
I'm trying to learn java on my own. I am now re-doing some programs I've done before, but in a different way.
Now I am stuck with a for-loop.
I have the following code:
public class Head {
public static void main(String[] args) {
int a = 0;
int b = 0;
int c = 0;
int d = 0;
int e = 0;
int f = 0;
for(int i=0; i<1000; i++){
int dice1 = 1 + (int)(Math.random() * ((6 - 1) + 1));
if (dice1 == 1){
a++;
}
else if(dice1 == 2){
b++;
}
else if(dice1 == 3){
c++;
}
else if(dice1 == 4){
d++;
}
else if(dice1 == 5){
e++;
}
else if(dice1 == 6){
f++;
}
}
System.out.println("Ones: " + a);
System.out.println("Twos: " + b);
System.out.println("Threes: " + c);
System.out.println("Fours: " + d);
System.out.println("Fives: " + e);
System.out.println("Sixes: " + f);
}
}
This works all fine and do what I want it to.
Now I want to create a constructor with a method that do all the countings for me. So far so good. But when it comes to printing it out, the output returns everything the number of times it does the calculation.
i.e, if I set i<5 it prints
1
2
3
4
5
6
five times, and not only one time.
Here is the bad code:
public class Head {
public static void main(String[] args) {
int a=0;
int b=0;
int c=0;
int d=0;
int e=0;
int f=0;
for(int i=0; i<5; i++){
int dice1 = 1 + (int)(Math.random() * ((6 - 1) + 1));
Dice diceObject = new Dice(dice1, a, b, c, d, e, f);
diceObject.CountNumbers();
// System.out.println(diceObject);
}
}
}
public class Dice {
private int a=0, b=0, c=0, d=0, e=0, f=0;
private int dice1;
public Dice(int dice1, int a, int b, int c, int d, int e, int f){
this.dice1 = dice1;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
}
public int getDice1(){
return dice1;
}
public void CountNumbers(){
if (dice1 == 1){
a++;
}
else if(dice1 == 2){
b++;
}
else if(dice1 == 3){
c++;
}
else if(dice1 == 4){
d++;
}
else if(dice1 == 5){
e++;
}
else if(dice1 == 6){
f++;
}
}
}
Any help on this?
Thank you very much for your time!
There are multiple things.
One is that some of your code is unnecessary.
public Dice(int dice1 /*, int a, int b, int c, int d, int e, int f*/ ){
this.dice1 = dice1;
//this.a = a;
//this.b = b;
//this.c = c;
//this.d = d;
//this.e = e;
//this.f = f;
}
You don't need the commented lines of code because they will reset the integers a-f and that is already being done. That also means that you don't need the variables a-f in the Head class.
public class Head {
public static void main(String[] args) {
//int a=0;
//int b=0;
//int c=0;
//int d=0;
//int e=0;
//int f=0;
for(int i=0; i<5; i++){
int dice1 = 1 + (int)(Math.random() * ((6 - 1) + 1));
Dice diceObject = new Dice(dice1 /*, a, b, c, d, e, f*/ );
diceObject.countNumbers();
diceObject.saveResults();
}
System.out.println("A B C D E F");
Dice.displayResults();
} }
Again, the snips of code not needed are commented out.
The next thing is that when you write the code
System.out.println(diceObject);
that doesn't work because diceObject is an instance of a class (Dice) and it isn't a variable.
The way I got everything to work was by having the variables sa, sb, sc, sd, se, and sf added.
private static int sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0;
I added these so that the results from each time the loop runs will be saved. I created a void to do this called saveResults(); The variables had to be static because the void was static too. I made the displayResults void (i'll get into that later) static so it could be accessed from a the Head class.
public void saveResults() {
sa += a;
sb += b;
sc += c;
sd += d;
se += e;
sf += f;
}
The += just means to add;
The last thing I did was make the displayResults void. It just displays the variables sa-sf using System.out.println();
public static void displayResults() {
System.out.println(sa + " " + sb + " " + sc + " " + sd + " " + se + " " + sf);
}
This all went together to make the final product. Here is the code:
Head class:
public class Head {
public static void main(String[] args) {
for(int i=0; i<5; i++){
int dice1 = 1 + (int)(Math.random() * ((6 - 1) + 1));
Dice diceObject = new Dice(dice1);
diceObject.countNumbers();
diceObject.saveResults();
}
System.out.println("A B C D E F");
Dice.displayResults();
}
}
Dice class:
public class Dice {
private int a=0, b=0, c=0, d=0, e=0, f=0;
private static int sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0;
private int dice1;
public Dice(int dice1){
this.dice1 = dice1; }
public int getDice1(){
return dice1;
}
public void countNumbers(){
if (dice1 == 1){
a++;
}
else if(dice1 == 2){
b++;
}
else if(dice1 == 3){
c++;
}
else if(dice1 == 4){
d++;
}
else if(dice1 == 5){
e++;
}
else if(dice1 == 6){
f++;
}
}
public void saveResults() {
sa += a;
sb += b;
sc += c;
sd += d;
se += e;
sf += f;
}
public static void displayResults() {
System.out.println(sa + " " + sb + " " + sc + " " + sd + " " + se + " " + sf);
} }
I am a beginner at java too. And a coincidence, for some time I was trying to teach it to myself. There is a course on codecademy.com that teaches you the basics. I recommend it and it is free. Sorry it took long to post this answer, it took a while to figure out what was wrong.
public class Solution {
public int pow(int A,int B,int d)
{
if(A<0){ A=A+d;}
if (B==0)
{
if(A==0){return 0;}
return 1;
}
else if(B%2==0)
{
int y=pow(A,B/2,d);
return (y*y)%d;
}
else
{
return (A%d*pow(A,B-1,d))%d;
}
}
}
My code overflows for,
A : 71045970
B : 41535484
d : 64735492
my code gives o/p: -17412928
expected o/p : 20805472
Where it goes wrong?
can someone modify my code?
Please try this
public int Mod(int a, int b, int c) {
if(b==0){
if(a==0) return 0;
else
return 1;
}
else if(b%2==0){
long y=Mod(a,b/2,c);
return (int)(((long)(y*y))%(long)c);
}else{
int k=a%c;
if(k<0){
k+=c;
}
return (int)(((long)((long)k * (long)Mod(a,b-1,c)))%(long)c);
}
}
BigInteger as a modPow method that does this for you trivially.
Not giving your expected result but giving a different result:
public int pow(int a, int b, int mod) {
if (a < 0) {
a = a + mod;
}
if (b == 0) {
if (a == 0) {
return 0;
}
return 1;
} else if (b % 2 == 0) {
int y = pow(a, b / 2, mod);
return (y * y) % mod;
} else {
return (a % mod * pow(a, b - 1, mod)) % mod;
}
}
public int bigPow(int a, int b, int mod) {
return BigInteger.valueOf(a).modPow(BigInteger.valueOf(a), BigInteger.valueOf(mod)).intValue();
}
private void test(int a, int b, int mod) {
System.out.println("Old - modPow(" + a + "," + b + "," + mod + ") = " + pow(a, b, mod));
System.out.println("New - modPow(" + a + "," + b + "," + mod + ") = " + bigPow(a, b, mod));
}
public void test() {
test(71045970, 41535484, 64735492);
}
prints
Old - modPow(71045970,41535484,64735492) = -17412928
New - modPow(71045970,41535484,64735492) = 44382800
In case you actually aren't looking for modPow (which now looks likely) here's a rough attemt at duplicating youyr aalgorithm using BigInteger.
public BigInteger bigPow(BigInteger a, BigInteger b, BigInteger mod) {
if (a.compareTo(BigInteger.ZERO) < 0) {
a = a.add(mod);
}
if (b.compareTo(BigInteger.ZERO) == 0) {
if (a.compareTo(BigInteger.ZERO) == 0) {
return BigInteger.ZERO;
}
return BigInteger.ONE;
} else if (!b.testBit(0)) {
BigInteger y = bigPow(a, b.shiftRight(1), mod);
return y.multiply(y).mod(mod);
} else {
return a.mod(mod).multiply(bigPow(a, b.subtract(BigInteger.ONE), mod));
}
}
Now gives the expected answer.
Old - modPow(71045970,41535484,64735492) = -17412928
New - modPow(71045970,41535484,64735492) = 20805472
input 3,5 output should be 3,4,5
input 5,3 output should be 5,4,3
And the code
public static void test(int a, int b) {
if(a>b) {
for (int i = a; i >= b; i--) {
System.out.print(i + "\t");
}
}else if(a<b) {
for (int i = a; i <= b; i++) {
System.out.print(i + "\t");
}
}
}
It works but looks a little messy. Is it possible to do without if else thing? Only one loop.
One solution which handle also boundary values correctly could be
public static void test(int start, int end) {
int current = start;
int stepWidth = current <= end ? +1 : -1;
while (current != (end + stepWidth)) {
System.out.print(current + "\t");
current += stepWidth;
}
System.out.println("");
}
edit Another one using a for loop.
public static void test(int start, int end) {
int stepWidth = start <= end ? 1 : -1;
for (int current = start; current != end + stepWidth; current += stepWidth) {
System.out.print(current + "\t");
}
System.out.println("");
}
executions
test(3, 5);
test(5, 3);
test(Integer.MAX_VALUE - 3, Integer.MAX_VALUE);
test(Integer.MIN_VALUE, Integer.MIN_VALUE + 3);
output
3 4 5
5 4 3
2147483644 2147483645 2147483646 2147483647
-2147483648 -2147483647 -2147483646 -2147483645
How about this version?
public static void test(int a, int b) {
int d = b > a ? 1 : -1;
for (int i = a; i != b; i+=d) {
System.out.print(i + "\t");
}
System.out.println(b);
}
This my solution, feedback appreciated.
public static void test(int a, int b) {
int middle = (a < b) ? (b - 1) : (a - 1);
System.out.println(a + "," + middle + ","+b);
}
Above will work only when a != b.
Given an array of integers f, I want to see if f[k]=k for some k in the array. I'm having some trouble because I would like to return on the left and right half of the array, but I am not sure how to go about doing that. This is what I have so far:
public class Find {
int a = 0;
public boolean find(int[] f) {
if(f.length < 1) {
return false;
}
System.out.println(f[0] + " " + a);
if(f.length == 1 && f[0] == a) {
return true;
}
if(f.length == 1 && f[0] != a) {
return false;
}
int[] L = Arrays.copyOfRange(f, 0, f.length / 2);
int[] R = Arrays.copyOfRange(f, f.length / 2, f.length);
find(L);
a++;
//find(R);
return find(R); //only finds in the right half...
}
public static void main(String[] args) {
Find F = new Find();
int[] test = {0, 13, 2, 3, 4};
System.out.println(F.find(test));
}
}
You could do the following, you currently search the left side but do not return the result:
return find(R) || find(L);