Java CARD Class compare method - java

int[] value = new int[5];
boolean result = true;
for(int i = 0; i < 5; i++) {
value[i] = cards[i].getValue();
}
for(int i = 0; i < 5; i++) {
for(int j = i;j < 5; j++) {
if(value[i] == value[j + 1]) {
result = false;
}
}
}
return result;
This code is essentially going to compare the values each card object has, and if two cards in the array have the same value return true. We have 5 cards in each hand and that is why the array length is 5. The getValue method returns an integer which is essentially the value of the card. I don't seem to know what I'm doing wrong to be getting errors on my method.

Your array access is incorrect when you use j + 1, that will be out of bounds when j is four (at the end of the length for value). And, I would prefer to use value.length instead of hardcoding. Something like
for (int i = 0; i < value.length - 1; i++) {
for (int j = i + 1; j < value.length; j++) {
if (value[i] == value[j]) {
result = false;
}
}
}
Additionally, as pointed out by Tom, in the comments; it is pointless to continue iteration when the result becomes false. You could simply return when it becomes false and avoid the result variable entirely. Like,
for (int i = 0; i < value.length - 1; i++) {
for (int j = i + 1; j < value.length; j++) {
if (value[i] == value[j]) {
return false;
}
}
}
return true;
Another option, in Java 8+, would be something like
return IntStream.of(value).allMatch(x -> value[0] == x);

Related

Recursive 2D 5x5 counting 'a' function in java

I have to write a method that returns the count of 'a' chars in the matrix but I have to do it with using recursion and it must be O(n.log(n)).
This is the my non-recursive code:
public static int acount(char[][] mat) {
int result = 0;
int i = 0;
int j = 0;
while (i <= 4) {
if (mat[i][j] == 'a') {
result++;
j++;
}
if (mat[i][j] == 'b') {
i++;
j = 0;
}
}
return result;
}
This is what i have tried but there was an error: "Exception in thread "main" java.lang.StackOverflowError":
public static int acount(char[][] mat) {
int result = 0;
int i = 0;
int j = 0;
while (mat[i][j] == 'a') {
result++;
j++;
}
if (i < 5) {
i++;
j = 0;
} else {
return result;
}
return acount(mat);
}
This is the main code:
public static void main(String[] args) {
int n = 5;
Random rand = new Random();
char[][] input = new char[n][n];
for (int i = 0; i < n; i++) {
int a_num = rand.nextInt(n);
for (int j = 0; j < a_num; j++) {
input[i][j] = 'a';
}
for (int j = a_num; j < n; j++) {
input[i][j] = 'b';
}
}
System.out.println(Arrays.deepToString(input));
System.out.println(acount(input));
}
}
How can it resolved?
Okay, let's start with your original version.
public static int acount(char[][] mat) {
int result = 0;
int i = 0;
int j = 0;
while (i <= 4) {
if (mat[i][j] == 'a') {
result++;
j++;
}
if (mat[i][j] == 'b') {
i++;
j = 0;
}
}
return result;
}
This code looks problematic. First, it assumes that your input only contains a or b. If you include other data, you'll never increment either i or j and you loop forever. It also looks like you're assuming that each row in the matrix is a-a-b-who-cares. That is, all a's, but you stop looking at the first b. Is that what you really want? Maybe it is.
I would have written this as:
for (int index1 = 0; index1 < 5; ++index1) {
for (int index2 = 0; index2 < 5; ++index2) {
if (mat[index1][index2] == 'a') {
++result;
}
}
}
And actually, i wouldn't hard-code 5 but would instead use mat.length and mat[index1].length respectively.
As for your stack overflow -- this is because your recursion never ends. You do this:
return acount(mat);
That is, you call acount with the same array again, which calls acount again, which calls acount again...
The only way that doesn't fail is if your code above returns early, which it probably won't. I think what you're missing is that each time you enter acount, you get fresh variables, so i and j start out freshly as zeros again.
You could partially solve this by passing i into acount, and when you recurse:
return acount(mat, i+1);
That will fix some of the problem, although I think you're complexity is still O(n^2).
Then let's look at this:
while (mat[i][j] == 'a') {
result++;
j++;
}
What happens if the row never has any a's in it? It looks past the end of the array. You're making assumptions about the input data, which is going to bite you.

small picture contained inside a bigger picture function doesn't work

I tried to code the naive solution for that, which tries to match a first index and then go deeper.
But I get true when I shouldn't and I cant find why.
this is my code (Java):
boolean contains(BufferedImage img, BufferedImage subImg, int[] coordinates){
boolean result = false;
int verticalLimit = img.getWidth() - subImg.getWidth();
int horizontalLimit =img.getHeight() - subImg.getHeight();
for (int i = 0; i <= horizontalLimit; i++) {
for (int j = 0; j <= verticalLimit; j++) {
if(img.getRGB(j, i) == subImg.getRGB(0, 0)){
result = true;
coordinates[0] = j; // stores the first indices for self use
coordinates[1] = i;
for (int k = i; k < subImg.getHeight() && result; k++) {
for (int l = j; l < subImg.getWidth() && result; l++) {
if(img.getRGB(l, k) != subImg.getRGB(l, k)){
result = false;
}
}
}
if(result) return result;
}
}
}
return result;
}
your search for the sub image is off. you jump way far into the sub image by indexing with k,l i've changed to 0 and using k,l as offsets from i,j. also use a labeled break from having to hold "found" state. if all of the pixels match it reaches the end of the loop and returns true otherwise it breaks and tries again until all possible locations are tried and returns false if none found.
static boolean contains(BufferedImage img, BufferedImage subImg, int[] coordinates) {
int verticalLimit = img.getWidth() - subImg.getWidth();
int horizontalLimit = img.getHeight() - subImg.getHeight();
for (int i = 0; i <= horizontalLimit; i++) {
for (int j = 0; j <= verticalLimit; j++) {
subSearch:
for (int k = 0; k < subImg.getHeight(); k++) {
for (int l = 0; l < subImg.getWidth(); l++) {
if (img.getRGB(l + j, k + i) != subImg.getRGB(l, k)) {
break subSearch;
}
}
if (k==subImg.getHeight()-1){
coordinates[0] = j;
coordinates[1] = i;
return true;
}
}
}
}
return false;
}

Making a nested for loop into a single for loop

I had an assignment to create an array of random number from 10-100.
Then I need to sout all the numbers not listed in the array.
I did the assignment with a nested for loops, to cross reference the arrays, then I changed all the found numbers in the array into -1. Finally I printed out the elements in the array that were not -1.
My professor told me that is it possible for me to do this assignment with only one for loop and there is no need to do a nested for loop. and make the computer run 10,000 times instead of just 100.
Is that possible? If so how?
Thank you.
package assignment.pkg1;
import java.util.Random;
public class Assignment1 {
static Random ran = new Random();
public static void main(String[] args) {
int[] arr = new int[100];
for (int i = 0; i < 100; i++) {
arr[i] = (ran.nextInt(90)) + 10;
}
InversingArray(arr);
}
public static void InversingArray(int[] randomArray) {
int[] fullArray = new int[100];
for (int i = 0; i < 100; i++) {
fullArray[i] = i;
}
for (int i = 0; i < 100; i++) {
for (int j = 1; j < 100; j++) {
if (randomArray[j] == fullArray[i]) {
fullArray[i] = -1;
}
}
}
System.out.println("These numbers are not in randomArray: ");
for (int i = 0; i < 100; i++) {
if (fullArray[i] != -1) {
System.out.println(fullArray[i]);
}
}
}
In your code you create an array to hold the possible values. If you think about it, the array index will always be equal to the number stored in the array.
fullArray[i] = i;
This is redundant.
What you are being asked to do is determine which numbers have been used: a boolean test. This means that you should have an array of boolean that is initially false (the default value of booleans in java) and is flipped to true when an equal integer is flipped to true.
Something like
int[] arr = new int[100];
for (int i = 0; i < 100; i++) {
arr[i] = (ran.nextInt(90)) + 10;
}
// ba starts with all false values
boolean ba[] == new boolean[90]; // note that the instructor said 10-100
for(int i=0; i<90; i++) {
ba[arr[i]] = true;
// lets assume arr[0] == 45
// ba[arr[0]] is the same as ba[45]
// ba[45] = true; will set that bucket of the boolean array to true
}
System.out.println("These numbers are not in randomArray: ");
for (int k = 0; k < 10; k++) {
System.out.println(k);
}
for (int j = 0; j < 90; j++) {
if (!ba[j]) { // shorthand for ba[j]==false
System.out.println(j+10); // The array starts at a base of 10
}
}
Be aware (probably the point of the exercise) that you are working with an array [0..90] that represents the numbers [10..100].
The nested loop currently looks like this:
for (int i = 0; i < 100; i++) {
for (int j = 1; j < 100; j++) {
if (randomArray[j] == fullArray[i]) {
fullArray[i] = -1;
}
}
}
But we know, that fullArray[i] is always the same as i.
So you can rewrite it to:
for (int j = 1; j < 100; j++) {
int i = randomArray[j];
fullArray[i] = -1;
}
Or even shorter:
for (int j = 1; j < 100; j++) {
fullArray[randomArray[j]] = -1;
}

How to make while loop work properly to correct given 2D array

I'm trying to write a method that will take a two-dimensional array as an input, and return a new 2D array in which all the zeroes are removed from the array.
Also, if there is an element in the first array that has a value equal to the length of the second array, then it should be removed and all elements in the second array will be subtracted by 1.
The above process should be repeated for the second array also.
This is what I've written for the code implementation so far, but the code gets stuck in a loop and I don't think it's doing what it's supposed to do.
Note: When ArrayUtils is called, the Apache Lang library is being used, and this is the 2D array I inputted:
[[0, 0, 2, 2, 3, 4], [0, 0, 2, 2, 3, 4]]
Code:
public static int[][] removeTrivialCases(int[][] startingSums) {
int[][] correctedSums = startingSums;
int counter = 0;
int numRows = correctedSums[0].length;
int numCols = correctedSums[1].length;
boolean zeroesExist = true;
boolean valueEqualsDimension = true;
boolean trivialCasesRemain = true;
while(trivialCasesRemain) {
for (int i = 0; i < correctedSums.length; i++) {
for (int j = 0; j < correctedSums[i].length; j++) {
if (correctedSums[i][j] == 0) {
trivialCasesRemain = true;
correctedSums[i] = ArrayUtils.removeElement(correctedSums[i], j);
}
for (int h = 0; h < correctedSums[i].length; h++) {
if (correctedSums[i][h] == 0) {
zeroesExist = true;
}
}
}
}
for (int i = 0; i < correctedSums[0].length; i++) {
if (correctedSums[0][i] == numCols) {
trivialCasesRemain = true;
correctedSums[0] = ArrayUtils.removeElement(correctedSums[0], i);
for (int j = 0; j < correctedSums[0].length; j++) {
correctedSums[0][j]--;
}
valueEqualsDimension = false;
for (int h = 0; h < correctedSums[0].length; h++) {
if (correctedSums[0][h] == numCols) {
valueEqualsDimension = true;
}
}
}
}
for (int i = 0; i < correctedSums[1].length; i++) {
if (correctedSums[1][i] == numRows) {
trivialCasesRemain = true;
correctedSums[1] = ArrayUtils.removeElement(correctedSums[1], i);
for (int j = 0; j < correctedSums[1].length; j++) {
correctedSums[1][j]--;
}
}
valueEqualsDimension = false;
for (int h = 0; h < correctedSums[1].length; i++) {
if (correctedSums[1][h] == numRows) {
valueEqualsDimension = true;
}
}
}
if (!zeroesExist || !valueEqualsDimension) {
trivialCasesRemain = false;
}
}
return correctedSums;
}
Regarding,
but the code gets stuck in a loop and I don't think it's doing what it's supposed to do.
Here:
for (int h = 0; h < correctedSums[1].length; i++) {
This loop will never end since h never changes within the loop. It should be:
for (int h = 0; h < correctedSums[1].length; h++) {
If you ran the code in a debugger, or used println's, you'd know what loop the code is stuck in, and this would allow you to inspect it immediately and correct it.

sum digits a number in Java

I have a bunch of numbers.Each digit of those numbers is concatenated n times and then summed. I have to write function which is returns 1 if sum equals number else returns 0.
public static int checkConcatenatedSum(int n, int catlen) {
char[] charArray = String.valueOf(n).toCharArray();
int[] test = new int[charArray.length];
String[] digit = new String[charArray.length];
int sum = 0;
for (int j = 0; j < charArray.length; j++){
for(int i = 0; i < catlen; i++){
digit[j] += charArray[j];
}
test[j] = Integer.parseInt(digit[j]);
sum += test[j];
}
if(sum == n){
return 1;
}
else return 1;
}
digit[j] begins with null every time.
When you initialize a new array of objects (String[] strs = ...) all elements in the array will be initialized to null, but you can then iterate over the array and set them all to some value (like "")
When you create an array (of String in this case), its elements are null at first.
You need to initialize the elements:
String[] digit = new String[charArray.length];
for (int i = 0; i < digit.length) {
digit[i] = new String();
}
for (int j = 0; j < charArray.length; j++){
digit[j] = new String();
for(int i = 0; i < catlen; i++){
digit[j] += charArray[j];
}
test[j] = Integer.parseInt(digit[j]);
sum += test[j];
}
Other answers are right, but just a quick addition to your existing loop that achieves it without making a new loop.
Another way is to test if array[?] is 'null' avoiding to create a temporary object String for Garbage Collector
for (int j = 0; j < charArray.length; j++){
for(int i = 0; i < catlen; i++){
digit[i] = digit[i] == null ? charArray[j] : digit[i] + charArray[j];
}
test[j] = Integer.parseInt(digit[j]);
sum += test[j];
}
EDIT
Your second return is erroneous (0 attempted);

Categories

Resources