Should I make every method and instance variable in my code static? - java

I tried to write a code that finds NashEquilibrium in given matrix.
I was keep getting errors that says I can't call non static method from static method so I turned every method and instance variable to static, is that a problem?
There are tons of logic errors in my code and it gives wrong answer, could it be because they are all static or its only logic error?
import java.util.ArrayList;
import java.util.Scanner;
public class Nash
{
public static String nes;
public static String str;
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the amount of strategies for each player");
int stratA = scan.nextInt();
int stratB = scan.nextInt();
String[][] utilities = new String[stratA][stratB];
System.out.println("Please enter the utilities");
for(int row = 0; row<stratA; row++)
for(int column = 0; column<stratB; column++)
utilities[row][column] = scan.next();
// Creates a 2D array with given utilities
if (nashExists(stratA, stratB, utilities) == true)
System.out.println(nes);
else
System.out.println("No NE found");
// Prints the results
}
public static boolean nashExists(int strA, int strB, String[][] util)
{
int[][] movesA = new int[strA][strB];
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
movesA[row][column] = Integer.parseInt(util[row][column].substring(0,1));
int[][] movesB = new int[strA][strB];
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
movesA[row][column] = Integer.parseInt(util[row][column].substring(2,3));
// Creates a 2d integer array for utilites of every strategy of A and B
ArrayList<String> aNE = new ArrayList<String>();
ArrayList<String> bNE = new ArrayList<String>();
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
if (nashExistsA(row, column, movesA) == true)
aNE.add((row+1) + "," + (column+1));
for(int row = 0; row<strA; row++)
for(int column = 0; column<strB; column++)
if (nashExistsB(row, column, movesB) == true)
bNE.add((row+1) + "," + (column+1));
// Checks if there are NE for one of players
if (compareArrayLists(aNE, bNE) == true)
return true;
else
return false;
}
// Checks if there are any matchs between both players NE's
public static boolean nashExistsA(int r, int c, int[][] a)
{
int max = a[r][c];
for (int i = 0; i<a.length; i++)
if (max < a[i][c])
max = a[i][c];
if (a[r][c] == max)
return true;
else
return false;
}
public static boolean nashExistsB(int r, int c, int[][] b)
{
int max = b[r][c];
for (int i = 0; i<b[0].length; i++)
if (max < b[r][i])
max = b[r][i];
if (b[r][c] == max)
return true;
else
return false;
}
public static boolean compareArrayLists(ArrayList<String> aN, ArrayList<String> bN)
{
for (int i=0; i<aN.size(); i++)
{
String potNE = aN.get(i);
if (bN.indexOf(potNE) >= 0)
str += "(" + potNE + ") ";
}
nes = str;
if (str.length()>0)
return true;
else
return false;
}
}

Turning members (methods and fields) into static is the classic mistake that novices tend to make when learning their first object-oriented language.
Don't do this.
I have seen this happening twice in workplaces where we hired fresh college graduates who had practically no programming experience. Predictably, after struggling with it for a while, the colleague would come to one of the older guys asking for help, and the help invariably was "lose static everywhere".
The more things you turn into static, the less object-oriented you are; if you turn everything static, then you are not object-oriented at all; you might as well be programming in BASIC or in COBOL.
When you become more familiar with the language and you start doing more advanced stuff, you will discover legitimate uses for static, which are very rare. When you come across such a situation, you will know it. Until then, stick with the rule that says:
Generally, avoid static like the plague.

Related

Print user inputs from 2D array using another class in Java?

I am trying to print user inputs in another class in Java. I have made a chessboard which asks the user to input strings on the board, and then, when these strings are printed on screen, I would like the output to be "You have placed piece [name] at coordinate [coordinate]". I am trying to do this in another class rather in the main method, but what I have tried so far doesn't seem to work. Here's my code.
import java.util.Arrays;
import java.util.Scanner;
public class ChessBoard
{
public static void main(String[] args)
{
char rows = 'a';
String spot;
Scanner scanner = new Scanner(System.in);
String[][] grid = new String [8][8];
for(int i = 0; i < grid.length; i++, rows++)
{
for(int col = 0; col < grid[i].length; col++);
String input = null; // will be changed to a valid position
boolean validCoordinate = false; // will be true if position is valid
while ( ! validCoordinate) {
System.out.println("Enter a coordinate (for example, a5): ");
input = scanner.next();
validCoordinate = input.matches("[a-h][1-8]");
};
// now we now that the input is valid
int row = input.charAt(0) - 'a';
int col = input.charAt(1) - '1';
String temp = input + " - ";
System.out.println("Insert your piece:");
input = scanner.next();
grid[row][col] = temp + input;
}
System.out.println(Arrays.deepToString(grid));
}
}
So what I'd like to do is have a new class that uses that last print line to instead print the desired output that I mentioned earlier. Any help would be appreciated, thanks!
EDIT:
import java.util.Arrays;
import java.util.Scanner;
public class ChessBoard1
{
public static void main(String[] args)
{
userInputs input = new userInputs();
showInput show = new showInput();
String grid[][] = input.takeInput();
show.show(grid);
}
}
public class userInputs
{
public String[][] takeInput()
{
char rows = 'a';
String spot;
Scanner scanner = new Scanner(System.in);
String[][] grid = new String [8][8];
for(int i = 0; i < grid.length; i++, rows++) {
for (int col = 0; col < grid[i].length; col++) ;
String input = null; // will be changed to a valid position
boolean validCoordinate = false; // will be true if position is valid
while (!validCoordinate) {
System.out.println("Enter a coordinate (for example, a5): ");
input = scanner.next();
validCoordinate = input.matches("[a-h][1-8]");
}
;
// now we now that the input is valid
int row = input.charAt(0) - 'a';
int col = input.charAt(1) - '1';
String temp = input + " - ";
System.out.println("Insert your piece:");
input = scanner.next();
grid[row][col] = temp + input;
}
return grid;
}
}
public class showInput {
public void show(String [][] inputs)
{
for(int i=0 ; i<inputs.length ; i++){
for(int j=0 ; j < inputs[0].length ; j++)
{
System.out.println(Arrays.deepToString(grid));
}
}
}
}
I have 2 separate files userInputs and showInput but they it says that they should still be declared in a separate file?
It's wrong to write main Function in every class, the program uses the main function to start from it, So you should write it only in the main project class and call inside it the other classes.
Your code should be:
package com.company;
public class ChessBoard
{
public static void main(String[] args)
{
userInputs input = new userInputs();
showInput show = new showInput();
String grid[][] = input.takeInput();
show.show(grid);
}
}
and other classes in separate files like:
package com.company;
import java.util.Scanner;
public class userInputs
{
public String[][] takeInput()
{
char rows = 'a';
String spot;
Scanner scanner = new Scanner(System.in);
String[][] grid = new String [8][8];
for(int i = 0; i < grid.length; i++, rows++) {
for (int col = 0; col < grid[i].length; col++) ;
String input = null; // will be changed to a valid position
boolean validCoordinate = false; // will be true if position is valid
while (!validCoordinate) {
System.out.println("Enter a coordinate (for example, a5): ");
input = scanner.next();
validCoordinate = input.matches("[a-h][1-8]");
}
;
// now we now that the input is valid
int row = input.charAt(0) - 'a';
int col = input.charAt(1) - '1';
String temp = input + " - ";
System.out.println("Insert your piece:");
input = scanner.next();
grid[row][col] = temp + input;
}
return grid;
}
}
and another class to output:
package com.company;
public class showInput {
public void show(String [][] inputs)
{
for(int i=0 ; i<inputs.length ; i++){
for(int j=0 ; j < inputs[0].length ; j++)
{
//Print Your Data
}
}
}
}
Like #Atef Magdy said, You should have one class which holds all the data and functions
and a main class which executes the functions.
and the explanation for this error ( it states that using public int is an "illegal start" to the expression, and that it needs a ";" after it?) I have seen that you made the 2d Array of Type String?
String[] [] grid = new String [8][8];
and then returning it as a 1D Array of Type int?
public int[] getGrid(){
return grid.clone();
}
I should say that this is the source of this error. You should change the 'int[]' to 'string[][]'
if there is any error please reply to this answer!

How to pass variables with 2 2D Arrays in Java?

I am having issues passing arrays to my methods it is getting an error of "cannot find symbol"but I am confused on how these 2D arrays should be passed in the method "how many" This program is supposed to prompt for 18 ints and placed into 2 2D arrays then return of they are equal or not. Am I supposed to place the array names in boolean equalOrNot = howmany(FirstArray, SecondArray);
or what?
import java.util.Scanner;
public class n01092281
{
public static void main (String[] args)
{
Scanner input = new Scanner (System.in);
int FirstArray [][] = new int[3][3];
int SecondArray [][] = new int[3][3];
System.out.print("Enter List1 and List2 (18 numbers): ");
for (int row = 0; row < FirstArray.length; row++)
{
for(int column = 0; column < FirstArray[row].length; column++)
{
FirstArray[row][column] = input.nextInt();
}
}
for (int row = 0; row < SecondArray.length; row++)
{
for(int column = 0; column < SecondArray[row].length; column++)
{
SecondArray[row][column] = input.nextInt();
}
}
boolean equalOrNot = howmany(FirstArray, SecondArray);
if (equalOrNot)
{
System.out.println("Two Arrays Are Equal");
}
else
{
System.out.println("Two Arrays Are Not equal");
}
}
public class strict
{
public boolean howmany(int[][] FirstArray, int[][] SecondArray)
{
boolean equalOrNot = true;
if(FirstArray.length == SecondArray.length)
{
for (int i = 0; i < FirstArray.length; i++)
{
if(FirstArray[i] != SecondArray[i])
{
equalOrNot = false;
}
}
}
else
{
equalOrNot = false;
}
}
}
}
Few points that could help over the shared code :
Please follow better-naming conventions.
public boolean howmany does not have a return statement to actually return a boolean value, possibly add at the end of the method :
return equalOrNot;
The comparison should also be over the number of columns of the array and the condition should become somewhat like :
if(FirstArray[i][j] != SecondArray[i][j])
You cannot call howmany method currently from a static context even considering Strict to be an inner class(with those inappropriately matched braces).

Java (specifically Netbeans and JForms): Checking duplicates in each line of 2D array

I am doing a Lotto application in a jForm/GUI in Netbeans with 3 rows of 5 numbers, and I don't want duplicates to be allowed on each line. To have one number on line 1 and the same on line 3 is OK, but to have those numbers on the same line is not OK.
The only way I can think of doing it that I know will work is to hard code it, and preferably, I don't want that.
I have tried:
boolean dup = false;
for (int k = 0; k < num[0].length){ //loop through columns
for (i = 0; i < num.length-1; i++) {
for (int j = i; j < inArray.length; j++){
if (num[k][i] == num[k][j]){
dup = true;
break;
}
}
}
}
and this:
public static boolean hasDuplicates(int [][] num) {
for (int row = 0; row < num.length; row++) {
int curRow = num[row];
Set set = Sets.newHashSet(Arrays.asList(curRow));
if (set.size() < curRow.length) {
return true;
}
}
return false;
}
I have also looked at other coding extensively and I can't get one that works.
The exact thing I'm trying to do is:
Get user's input for three lines of Lotto via text field, check each line for duplicates, print to a jLabel if it's a duplicate or leave the jLabel blank and run the rest of the code if there's no duplicates.
The current code I have is:
private void playBtnActionPerformed(java.awt.event.ActionEvent evt) {
num[0][0] = Integer.parseInt(line00Tf.getText());
num[0][1] = Integer.parseInt(line01Tf.getText());
num[0][2] = Integer.parseInt(line02Tf.getText());
num[0][3] = Integer.parseInt(line03Tf.getText());
num[0][4] = Integer.parseInt(line04Tf.getText());
num[1][0] = Integer.parseInt(line10Tf.getText());
num[1][1] = Integer.parseInt(line11Tf.getText());
num[1][2] = Integer.parseInt(line12Tf.getText());
num[1][3] = Integer.parseInt(line13Tf.getText());
num[1][4] = Integer.parseInt(line14Tf.getText());
num[2][0] = Integer.parseInt(line20Tf.getText());
num[2][1] = Integer.parseInt(line21Tf.getText());
num[2][2] = Integer.parseInt(line22Tf.getText());
num[2][3] = Integer.parseInt(line23Tf.getText());
num[2][4] = Integer.parseInt(line24Tf.getText());
duplicateLbl.setText("");
LottoPhase1 p1 = new LottoPhase1();
p1.setNum(num);
p1.createSecret();
secret = p1.getSecret();
p1.computeCheckInput();
correctL1 = p1.getCorrectL1();
correctL2 = p1.getCorrectL2();
correctL3 = p1.getCorrectL3();
//prints secret to output
System.out.println("Phase 1 Main Secret: " + Arrays.toString(secret));
System.out.println();
displayResults0Lbl.setText(Integer.toString(secret[0]) + ", " + Integer.toString(secret[1]) + ", " + Integer.toString(secret[2]) + ", " + Integer.toString(secret[3]) + ", " + Integer.toString(secret[4]));
matched1NumLbl.setText(Integer.toString(correctL1));
matched2NumLbl.setText(Integer.toString(correctL2));
matched3NumLbl.setText(Integer.toString(correctL3));
}
public static boolean hasDuplicates(int[][] num)
{
boolean hasDuplicate = false;
// for each line in num
for(int[] line : num)
{
// for every number in the row
for(int i = 0; i < line.length && !hasDuplicate; i++)
{
// for every number in the row
for(int j = 0; j < line.length; j++)
{
// if we are not comparing the same number
if(i != j)
{
// check for equality
if(line[i] == line[j])
{
hasDuplicate = true; // we have found a duplicate
break; // no need to keep checking; break the loop and return
}
}
}
}
}
return hasDuplicate;
}
The second method has a couple of errors, for instance,
int curRow = num[row];
Should actually be:
int[] curRow = num[row];
Also, you appear to be using Sets, which probably comes from some library you're using (Guava, Google Common, etc.). Assuming you were not using any library, you could change your code to something similar to:
public static boolean hasDuplicates(int [][] num) {
for (int[] curRow : num) {
Set<Integer> set = new HashSet<>();
for (int n : curRow) {
if (!set.add(n)) {
return true;
}
}
}
return false;
}
If you're using Java 8, one way to remove the second for loop is by using a Stream:
public static boolean hasDuplicates(int [][] num) {
for (int[] curRow : num) {
Set<Integer> set = IntStream.of(curRow).boxed().collect(Collectors.toSet());
if (set.size() < curRow.length) {
return true;
}
}
return false;
}
Other alternatives to the Stream can be found in threads like these.
Testing with the following input produces what I think you would expect:
int[][] testA = {{0,1,2,3,4}, {0,1,2,3,4}, {0,1,2,3,4}}; //false
int[][] testB = {{0,1,2,3,4}, {0,2,2,3,4}, {0,1,2,3,4}}; //true
int[][] testC = {{0,1,2,3,4}, {0,1,2,3,4}, {0,4,3,3,4}}; //true
int[][] testD = {{0,1,2,3,4}, {5,6,7,8,9}, {10,11,12,13,14}}; //false

CodeEval Overlapping Rectangles code review

I have been testing my code for the overlapping rectangles challenge on codeeval. I feel my code is close to the solution as I have tested it on my machine and it appears correct. Codeeval is picky however and won't execute the code, claiming it is hanging.No further information is given. It has done this in the past but that was due to me not closing my scanner at the end. Am I violating a similar principle here?
Any recommendations on finding the solution simpler or better coding practices is appreciated.
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class Main {
public static void main(String[] args) throws FileNotFoundException {
File file = new File("C:/Users/minda_000/Desktop/text.txt");
FileReader fr = new FileReader(file);
Scanner scan = new Scanner(fr);
scan.useDelimiter(",");
boolean flag = true;
while (scan.hasNextLine()) {
String line = scan.nextLine();
Scanner scanline = new Scanner(line);
scanline.useDelimiter(",");
int lxa = scanline.nextInt();
int lya = scanline.nextInt();
int rxa = scanline.nextInt();
int rya = scanline.nextInt();
int lxb = scanline.nextInt();
int lyb = scanline.nextInt();
int rxb = scanline.nextInt();
int ryb = scanline.nextInt();
int[] contentsofx = contentsOfX(lxa, rxa);
int[] contentsofy = contentsOfY(lya, rya);
int[] contentsofx2 = contentsOfX(lxb, rxb);
int[] contentsofy2 = contentsOfY(lyb, ryb);
scanline.close();
for (int i = 0; i < contentsofx.length; i++) {
for (int j = 0; j < contentsofx2.length; j++) {
if (contentsofx[i] == contentsofx2[j]) {
if(i<contentsofy.length && i<contentsofy2.length && contentsofy[i]==contentsofy2[j]){
System.out.println(true);
flag=false;
}
}
}
}
if(flag) {
System.out.println(false);
}
flag=true;
}
scan.close();
}
public static int[] contentsOfX(int lx, int rx) {
int[] line = new int[(rx - lx)];
for (int i = 0; i < line.length; i++) {
line[i] = lx + i;
}
return line;
}
public static int[] contentsOfY(int ly, int ry) {
int[] line = new int[(ly - ry)];
for (int i = 0; i < line.length; i++) {
line[i] = ry + i;
}
return line;
}
}
Just to make sure, you are changing "C:/Users/minda_000/Desktop/text.txt" to args[0] before uploading your solution to CodeEval, right?
Some of the other issues:
You're outputting True and False in lowercase when they're supposed to be capitalized.
In this line --
if(i<contentsofy.length && i<contentsofy2.length && contentsofy[i]==contentsofy2[j]){
-- you've got a problem when i and/or j are larger than the lengths of contentsofy and contentsofy2.
And comments would make your code easier to read. :-)
I scrapped this code and started over more or less with a much cleaner solution just using boolean logic. The problems with this code is the contentsOfX and contentsOfY methods should be 1 size greater for one point overlap. Additionally, at this time I implied one rectangle would always be to the left of the other. The nested for loop does not work as intended because of this. Still the arrays are sorted for each value from minimum value of x,y to maximum value of x,y so if you check for the reverse polarity index within the array as well the logic should be the work.

Java: Cannot get two ArrayLists not to be "connected"

So I'm practicing for UIL when I come across a problem: my ArrayLists, for some odd reason, share the same value with each other. They are both declared as Characters, although declared as different objects, and I cannot figure out a way to separate them.
What I want done is one of them will be a base, while the other one changes throughout the nested loop, however, they both change, even though I don't change the base one after I set it, and I cannot figure out why. I found my answer a bit ago explaining that the main method is static so they point to the same place, but after making a new class and then making an object in the main method to do it it still won't work.
Can anybody explain to me as to why they are connected?
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
public class Boggle
{
public static void main (String args[]) throws Throwable
{
Boggle test = new Boggle();
test.theBoggle();
}
public void theBoggle() throws Throwable
{
Scanner scan = new Scanner(new File("boggle.dat"));
int games = scan.nextInt();
int amtofwords = 0;
int puzzle = 1;
boolean possible = true;
boolean possibleletter = false;
String tempword = "";
int pointcounter = 0;
ArrayList<Character> scrambled = new ArrayList<Character>();
ArrayList<Character> testscramble = new ArrayList<Character>();
ArrayList<String> words = new ArrayList<String>();
scan.nextLine();
for (int i = 0; i < games; i++)
{
for (int w = 0; w < 4; w++)
{
tempword = scan.nextLine();
scrambled.add(tempword.charAt(0));
scrambled.add(tempword.charAt(1));
scrambled.add(tempword.charAt(2));
scrambled.add(tempword.charAt(3));
}
amtofwords = scan.nextInt();
scan.nextLine();
for (int k = 0; k < amtofwords; k++)
{
words.add(scan.nextLine());
}
for (String string : words) //grabs the words
{
possible = true;
testscramble = scrambled; //````````````IMPORTANT WHY ARE THEY BOTH CONNECTED?``````````
System.out.println(scrambled);
for (int k = 0; k < string.length(); k++) //grabs the scrambled letters to compare to string
{
for (int j = 0; j < testscramble.size(); j++) //grabs individual letters to compare to word
{
if (string.charAt(k) == testscramble.get(j))
{
possibleletter = true;
testscramble.remove(j);
break;
}
}
if (possibleletter == false)
{
possible = false;
break;
}
possibleletter = false;
}
if (possible == true)
{
if (string.length() <= 2)
pointcounter += 0;
if (string.length() == 3 || string.length() == 4)
pointcounter += 1;
if (string.length() == 5)
pointcounter += 2;
if (string.length() == 6)
pointcounter += 3;
if (string.length() == 7)
pointcounter += 5;
if (string.length() >= 8)
pointcounter += 11;
}
}
System.out.println("PUZZLE #" + puzzle + " " + pointcounter);
puzzle++;
}
scan.close();
}
}
As was mentioned in the comments, you used references to convert one list variable into a reference to another list variable
testscramble = scramble;
when you should have copied the list as such
testscramble = new ArrayList<>(scrambled);

Categories