Matching array values with variables - java

In this code I have an array with 5 elements and each element contains a value. Below in the while loop, I'm trying to give the user 3 attempts to guess what number is contained in the array (the user enters their guesses). My problem is that I don't know how to make match the user's guess (stored in a variable choose) with the array values caja[i] to print whether the user won or lost depending on a correct or incorrect guess respectively.
public static void main(String[] args)
{
int[] caja = new int [5];
caja[0] = 1;
caja[1] = 3;
caja[2] = 5;
caja[3] = 7;
caja[4] = 9;
System.out.println("Mostrando todos los numeros del arreglo");
for (int i = 0; i < caja.length; i++)
{
System.out.println(caja[i]);
}
System.out.println();
int electionGame = 3;
int o = 0;
while(electionGame > 0)
{
Scanner sc = new Scanner(System.in);
int choose = sc.nextInt();
for (int i = 0; i < caja.length; i++)
{
o = o + 1;
if(choose == caja[i])
{
System.out.println("Ganastes");
break;
}
else
{
System.out.println("Perdiestes");
break;
}
}
electionGame--;
}
}
}

Your problem is that you break out of your loop in every case:
if(choose == caja[i])
{
System.out.println("Ganastes");
break;
}
else
{
System.out.println("Perdiestes");
break;
}
Instead of doing this (and printing the result after only the first comparison), you should have a Boolean indicating whether the number was found in the array:
int electionGame = 3;
boolean found = false; //indicates whether user has found right number
while (electionGame > 0 && !found) {
Scanner sc = new Scanner(System.in);
int choose = sc.nextInt();
for (int i = 0; i < caja.length && !found; i++) {
if (choose == caja[i]) {
found = true;
}
}
electionGame--;
if (found) {
System.out.println("you won");
} else {
System.out.println("nope");
}
}
This way, you can check the variable and tell the user whether he won or lost.

Here are some additional suggestions. The answer by Alex (https://stackoverflow.com/a/36133864/6077352) is good. Please note the comments in the code.
import java.util.Scanner;
/** https://stackoverflow.com/q/36133524/6077352 */
public class GuessNumber {
public static void main(String[] args) {
int[] caja = new int[5];
caja[0] = 1;
caja[1] = 3;
caja[2] = 5;
caja[3] = 7;
caja[4] = 9;
System.out.println("Mostrando todos los numeros del arreglo");
for (int i = 0; i < caja.length; i++) {
System.out.println(caja[i]);
}
System.out.println();
int tries = 3;
Scanner sc = new Scanner(System.in);// no need to create scanners in loop
while (tries-- > 0) {// count down tries
System.out.print("Please guess a number... ");
int guess = sc.nextInt();
boolean win = false;// flag to determine if won
for (int i : caja) {// iterate through array and check if guess is inside
win |= (i == guess);// when inside: win=true
}
System.out.println("Answer right? " + win);
System.out.println();
}
}
}

So if the user can attempt to get any of the values of the array you might to change your while loop to this one:
while (electionGame > 0) {
Scanner sc = new Scanner(System.in);
int choose = sc.nextInt();
boolean ganaste = false;
for (int i = 0; i < caja.length; i++) {
o = o + 1;
if (choose == caja[i]) {
ganaste = true;
break;
}
}
if (ganaste)
System.out.println("Ganastes");
else
System.out.println("Perdiestes");
electionGame--;
}

Related

tictactoe minmax recursion causing confusion

I read a number of tic tac toe examples using the minmax algorithm but haven't found a good one that really explains what's going on. I've written one that works but need help understanding a small section of the recursion process.
If you load the code below, enter your name, O (not zero), and 0 (zero) you'll get the results I'm looking at. After the computer moves stop the program and look at the console.log.
If you look at the console output, you see the line best 0 7 [[0, 7]] that happens just before the return statement. Where is the next line coming from 0 simulateMove = 6 scoreMove[1] = 7 depth = 2
The other question is why on line 423 do I need scoreMoveAvailable[i][1] = simulateMove; instead of scoreMoveAvailable[i][1] = scoreMove[1];
import java.util.Scanner;
import java.util.ArrayList;
import java.util.Random;
import java.util.Arrays;
public class TicTacToeV2{
private static final int boardRowDim = 3;
private static final int boardColDim = 3;
private String[][] board;
private String playerName;
private String playerMark;
private String computerMark;
private boolean humanGoes;
private boolean winner;
private boolean draw
private int gameTargetScore;
private boolean output = true;
private boolean toSeed = true;
private ArrayList<Integer> availableMoves;
public TicTacToeV2(String name, boolean whoGoesFirst){
availableMoves = new ArrayList<Integer>();
board = new String[boardRowDim][boardColDim];
for (int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
board[i][j] = ((Integer)(double2single(i,j))).toString();
availableMoves.add(double2single(i,j));
}
}
playerName = name;
humanGoes = whoGoesFirst;
playerMark = "X";
computerMark = "O";
gameTargetScore = 15;
if(!humanGoes){
playerMark = "O";
computerMark = "X";
gameTargetScore = - 15;
}
winner = false;
draw = false;
}
public static void main(String[] args)throws Exception{
System.out.println("\u000C");
Scanner kboard = new Scanner(System.in);
printHeader();
System.out.print(" Please enter your name ; ");
String name = kboard.next();
name = capitalize(name);
System.out.print("\n\n X's go first. " + name + ", please enter your mark ('X' or 'O')");
String mark = kboard.next().toUpperCase();
boolean whoPlaysFirst = (mark.equals("X")) ? true : false;
TicTacToeV2 myGame = new TicTacToeV2(name,whoPlaysFirst);
myGame.playGame(kboard);
}
public void playGame(Scanner kboard)throws Exception{
Integer move = null;
boolean goodMove;
String kboardInput = null;
Scanner input;
int[] cell2D = new int[2];
Random random = new Random();
int nextComputerMove;
if(toSeed){
board = seedBoard();
availableMoves = seedAvailable(board);
int x = 0;
int o = 0;
for(int i = 0; i < 3;i++){
for(int j = 0;j < 3;j++){
if(board[i][j].equals("X"))x++;
else if(board[i][j].equals("O"))o++;
}
}
if((x - o) == 1) humanGoes = true;
else if((x - o) == 0) humanGoes = false;
else{
System.out.println("Fatal Error: seed bad");
System.exit(0);
}
System.out.println("humangoes = " + humanGoes + x + o);
}
while(!winner && !draw){
printHeader();
goodMove = false;
drawBoard(board);
if(!humanGoes && availableMoves.size() < 9){
System.out.println("That's a great move, I'll have to think about this");
Thread.sleep(2000);
}
if(humanGoes){
while(!goodMove){
System.out.print("\n\n Please enter a number for your move : ");
kboardInput = kboard.next();
input = new Scanner(kboardInput);
if(input.hasNextInt()){
move = input.nextInt();
if(move == 99){
System.out.println("You found the secret exit code");
Thread.sleep(2000);
printHeader();
System.out.println("bye");
System.exit(0);
}
goodMove = checkMove(move);
if(!goodMove)System.out.println(" WARNING: Incorrect input, try again");
}else{
System.out.println(" WARNING: Incorrect input, try again");
}
}
cell2D = single2Double(move);
board[cell2D[0]][cell2D[1]] = playerMark;
}else{
//nextComputerMove = random.nextInt(availableMoves.size());
//move = availableMoves.get(nextComputerMove);
String[][] currentBoard = new String[boardRowDim][boardColDim];
currentBoard = copyBoard(board);
ArrayList<Integer> currentAvailableMoves= new ArrayList<Integer>();
currentAvailableMoves = copyAvailableMoves(availableMoves);
//System.out.println(System.identityHashCode(currentAvailableMoves));
int[] bestScoreMove = new int[2];
bestScoreMove = findBestMove(currentBoard,currentAvailableMoves,true,0,kboard);
move = availableMoves.get(availableMoves.indexOf(bestScoreMove[1]));
cell2D = single2Double(move);
board[cell2D[0]][cell2D[1]] = computerMark;
}
humanGoes = humanGoes ? false:true;
availableMoves = updateAvailableMoves(move,availableMoves);
if (Math.abs(score(board)) == 15) winner = true;
if (availableMoves.size() == 0) draw = true;
if(winner || draw){
printHeader();
drawBoard(board);
}
if(score(board) == gameTargetScore)System.out.println(playerName + " you are too good for me. \n" +
"Congratulations you won!!\n\n");
else if(score(board) == -gameTargetScore)System.out.println("IWONIWONIWONohboyIWONIWONIWON");
else if(draw)System.out.println("Good game. It's a draw!");
}
}
public void drawBoard(String[][] someBoard){
String mark = " ";
Integer row,col;
String type;
for( int i = 0;i < 15; i++){
System.out.print(" ");
for (int j = 0; j < 27; j++){
mark = " ";
if(i==5 || i == 10)mark = "-";
if(j==8 || j == 17)mark = "|";
row = i/5;
col = j/9;
type = someBoard[row][col];
if(type == "X"){
if( ((i%5 == 1 || i%5 == 3) &&
(j%9 == 3 || j%9 == 5)) ||
(i%5 == 2 &&
j%9 == 4))mark = "X";
}else if(type == "O"){
if( ((i%5 == 1 || i%5 == 3) &&
(j%9 == 3 || j%9 == 4 || j%9 == 5)) ||
((i%5 == 2) &&
(j%9 == 3 || j%9 == 5))) mark = "O";
}else{
if( i%5 == 2 && j%9 == 4){
mark = ((Integer)(row * 3 + col)).toString();
}
}
System.out.print(mark);
}
System.out.println();
}
System.out.println("\n\n\n");
}
public boolean checkMove(Integer move){
/*
* to sanitize user input we have to check if what
* they entered is an available square
*/
boolean goodMove = false;
for(Integer available : availableMoves){
if (available == move) goodMove = true;
}
return goodMove;
}
public int score(String[][] newBoard){
int row;
int newCol;
int score = 0;
for (int strategy = 0; strategy < 8; strategy++){
score = 0;
for (int col = 0; col < 3; col++){
if(strategy < 3){ //rows
row = strategy ;
newCol = col;
}else if (strategy < 6){ //cols
row = col;
newCol = strategy - 3;
}else{//diag
int diag = strategy - 6;
row = col - 2 * diag * (col - 1);
newCol = col;
}
if(newBoard[row][newCol].equals("X")){
score+=5;
}else if(newBoard[row][newCol].equals("O")){
score+=-5;
}
}
score = (Math.abs(score)== 15) ? score : 0;
if(Math.abs(score) == 15) break;
}
return score;
}
public String[][] copyBoard(String[][] originalBoard){
String[][] duplicateBoard = new String[boardRowDim][boardColDim];
for (int i = 0;i < boardRowDim; i++){
for(int j = 0; j < boardColDim; j++){
duplicateBoard[i][j] = originalBoard[i][j];
}
}
return duplicateBoard;
}
public String[][] updateBoard(Integer move, String mark, String[][]oldBoard){
String[][] currentBoard = new String[boardRowDim][boardColDim];
int[] cell2D = new int[2];
currentBoard = copyBoard(oldBoard);
cell2D = single2Double(move);
currentBoard[cell2D[0]][cell2D[1]] = mark;
return currentBoard;
}
public ArrayList<Integer> copyAvailableMoves(ArrayList<Integer> originalAvailableMoves){
ArrayList<Integer> duplicateAvailableMoves = new ArrayList<Integer>();
for(int i = 0; i < originalAvailableMoves.size();i++){
duplicateAvailableMoves.add(originalAvailableMoves.get(i));
}
return duplicateAvailableMoves;
}
public ArrayList<Integer> updateAvailableMoves(Integer move, ArrayList<Integer> oldAvailableMoves){
ArrayList<Integer> currentAvailableMoves = new ArrayList<Integer>();
currentAvailableMoves = copyAvailableMoves(oldAvailableMoves);
currentAvailableMoves.remove(move);
return currentAvailableMoves;
}
public String[][] seedBoard(){
String[][] sampleBoard ={{"0","O","X"},{"X","4","O"},{"6","7","X"}};
//String[][] sampleBoard ={{"X","O","O"},{"3","4","X"},{"6","7","8"}};
return sampleBoard;
}
public ArrayList<Integer> seedAvailable(String[][] seedBoard){
ArrayList seedMoves = new ArrayList<Integer>();
int index = -1;
for(int i = 0; i < 3;i++){
for (int j = 0; j < 3; j++){
if(!seedBoard[i][j].equals("X") && !seedBoard[i][j].equals("O")){
index = i*3 + j;
seedMoves.add(index);
}
}
}
//System.out.println(seedMoves);
return seedMoves;
}
public int[] findBestMove(String[][] currentBoard, ArrayList<Integer> currentAvailableMoves,boolean currentComputerMoves,int depth,Scanner kboard){
ArrayList<Integer> simulateAvailableMoves = new ArrayList<Integer>();
String[][] simulateBoard = new String[boardRowDim][boardColDim];
//System.out.println(System.identityHashCode(currentAvailableMoves));
int[] scoreMove = new int[2]; //return array with score and associated move
int[] cell2D = new int[2]; //array holding i and j of board to place Mark (X or O)
int computerTargetScore = (computerMark.equals("X")) ? 15:-15;
/*
* scoreMoveAvailable is an array that holds scores for each available move
* inside loop. The bestScoreMove will be the min or max of this array
* depending on whether it's X's or O's turn to move
*/
int[][] scoreMoveAvailable = new int[currentAvailableMoves.size()][2];
Integer simulateMove = null; //current move inside loop
Boolean simulateComputerMoves = null;
for(int i = 0; i < currentAvailableMoves.size(); i++){
scoreMoveAvailable[i][0] = 0; //score
scoreMoveAvailable[i][1] = -1; // square 0 - 8
}
if(output)System.out.println("on enter available moves " + currentAvailableMoves);
for (int i = 0; i < currentAvailableMoves.size() ;i++){
simulateAvailableMoves = copyAvailableMoves(currentAvailableMoves);
simulateBoard = copyBoard(currentBoard);
simulateComputerMoves = currentComputerMoves;
if(output)System.out.println("in loop available moves " + i + " " + simulateAvailableMoves);
simulateMove = simulateAvailableMoves.get(i);
simulateAvailableMoves = updateAvailableMoves(simulateMove,simulateAvailableMoves);
cell2D = single2Double(simulateMove);
if(simulateComputerMoves){
if(output)System.out.println("computer moves " + simulateMove);
simulateBoard[cell2D[0]][cell2D[1]] = computerMark;
simulateComputerMoves = false;
if(score(simulateBoard) == computerTargetScore || simulateAvailableMoves.size() == 0){
scoreMove[0] = score(simulateBoard);
scoreMove[1] = simulateMove;
if(output)System.out.println("score computer" + Arrays.toString(scoreMove) +" computer moves = " + simulateMove + " i = " + i);
if(output)drawBoard(simulateBoard);
}else{
depth++;
if(output)System.out.println("computer calling findbest " +simulateAvailableMoves);
if(output)drawBoard(simulateBoard);
scoreMove = findBestMove(simulateBoard,simulateAvailableMoves,simulateComputerMoves,depth,kboard);
}
}else{
if(output)System.out.println("human moves" + simulateMove);
simulateBoard[cell2D[0]][cell2D[1]] = playerMark;
simulateComputerMoves = true;
if(score(simulateBoard) == (-computerTargetScore) || simulateAvailableMoves.size() == 0){
scoreMove[0] = score(simulateBoard);
scoreMove[1] = simulateMove;
if(output)System.out.println("score human "+ Arrays.toString(scoreMove) +" human moves " + simulateMove + " i = " + i);
if(output)drawBoard(simulateBoard);
}else{
depth++;
if(output)System.out.println("human calling findbest " + simulateAvailableMoves);
if(output)drawBoard(simulateBoard);
scoreMove = findBestMove(simulateBoard,simulateAvailableMoves,simulateComputerMoves,depth,kboard);
}
}
if(output)System.out.println(i + " simulateMove = " + simulateMove + " scoreMove[1] = " + scoreMove[1] + " depth = " + depth);
// drawBoard(simulateBoard);
scoreMoveAvailable[i][0] = scoreMove[0] ;
scoreMoveAvailable[i][1] = simulateMove;
if(output)System.out.println("score array = " + i + " " + Arrays.deepToString(scoreMoveAvailable));
}
int[] bestScoreMove = new int[2];
bestScoreMove[0] = scoreMoveAvailable[0][0]; //set bestScoreMove to first element in arraylist
bestScoreMove[1] = scoreMoveAvailable[0][1];
if(output)System.out.println("****************************************");
if( (currentComputerMoves && computerMark.equals("X") ) || (!currentComputerMoves && computerMark.equals("O") ) ) {
for (int i = 0; i < scoreMoveAvailable.length;i++){
if(scoreMoveAvailable[i][0] > bestScoreMove[0]){
bestScoreMove[0] = scoreMoveAvailable[i][0] ;
bestScoreMove[1] = scoreMoveAvailable[i][1];
}
if(output)System.out.printf("MAX X scores and moves = %d %d %d %s\n",i,scoreMoveAvailable[i][0],scoreMoveAvailable[i][1],"XXX");
}
if(output)System.out.println("\n");
}else{
for (int i = 0; i < scoreMoveAvailable.length;i++){
if(scoreMoveAvailable[i][0] < bestScoreMove[0]){
bestScoreMove[0] = scoreMoveAvailable[i][0] ;
bestScoreMove[1] = scoreMoveAvailable[i][1];
}
if(output)System.out.printf("MIN O scores and moves =%d %d %d %s\n",i,scoreMoveAvailable[i][0],scoreMoveAvailable[i][1],"OOO");
}
if(output)System.out.println("\n");
}
if(output)System.out.println("best " + bestScoreMove[0] + " " + bestScoreMove[1] + " " + Arrays.deepToString(scoreMoveAvailable));
return bestScoreMove;
}
/*
* just some static methods to help make things easy
*/
public static void printHeader(){
System.out.println("u000C Welcome to TicTacToe\n" +
" where you can match wits\n" +
" against the computer\n" +
"(the real challenge is making it a draw)\n");
}
public static int double2single(int row, int col){
int singleCell = 0;
singleCell = boardRowDim * row + col;
return singleCell;
}
public static int[] single2Double(int cell){
int[] cell2D = new int[2];
cell2D[0] = cell / boardColDim;
cell2D[1] = cell % boardColDim;
return cell2D;
}
public static String capitalize(String word){
word = word.substring(0,1).toUpperCase() + word.substring(1);
return word;
}
}
Note that the below diagram assumes that you are not doing "depth++", but just using "depth + 1" in the recursive call. The former is a benign bug in your code, which leads to printing misleading depths.
findBestMove is first invoked when bestScoreMove = findBestMove... is used to find the computer's move. Based on the seeded board and human taking "0", the moves now available are 4, 6, and 7.
First, the computer simulates moving 4
This creates a recursive call, adding a frame to the function stack. The human now has 6 and 7 as possible moves. Since 6 is first, the human "tries" 6 first. In this simulation now, it's computer/4 -> human/6
Again, a frame is added to the function stack for the recursive call from the human "running a simulation". Now, there's one move left: the computer takes 7. This is where best 0 7 [[0, 7]] is printed.
After the last recursive call returns, the function stack is popped, and we're again where the human is moving 6, and that's where 0 simulateMove = 6.. is printed.
You can use a debugger to show more detailed information about the stack, but here is some extra advice (mostly to make functions shorter) to make it easier to debug:
There's a lot of Thread.sleep(2000); right after a println. You can wrap these two lines in a function
In many but not all places, the logic assumes a board size of 3x3, e.g. && availableMoves.size() < 9). It's inconsistent, and this logic can be confusing. To make it clear, you can create a function "noMovesMade()" that computes this based on the available variables.
Additionally, if(!humanGoes && availableMoves.size() < 9){ can simply go in the "else" block (since that already implies it's the computer's turn)
if((x - o) == 1) humanGoes = true; is assuming that the human is playing "O" when the rest of the code does not assume this.
There are a lot of cases variables are initialized, assigned, and then reassigned without being used. For example, String[][] currentBoard = new String[boardRowDim][boardColDim]; currentBoard = copyBoard(board); is redundant, and the same with bestScoreMove.
Arrays.copyOf can be used to copy arrays (in the inner loop of the copyBoard, for example)
ArrayList.contains can be used instead of iterating through the array in checkMove
humanGoes = humanGoes ? false:true; can be shortened to humanGoes = !humanGoes

Going back and forth with methods in Java

I built a tic tac toe game using java but I just have one issue. I want my code to bounce back and forth from the validPlayerOneInput and validPlayerTwoInput methods. As you can see in my main, I'm calling both methods procedurally which be incorrect as it just stops after the method is called. I want this to keep running until a winner is determined.
How do I do so?
import java.util.*;
public class tictactoe {
private static char board[][] = {{1,2,3}, {4,5,6}, {7,8,9}};
char p1Sym, p2Sym;
public tictactoe() {
p1Sym ='X';
p2Sym = 'O';
boardFill();
}
void boardFill() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(board[i][j]);
System.out.print(" | ");
}
System.out.println();
}
}
void validInputPlayerOne() {
boolean isSet = true;
int player1Input, player1CorrectedInput;
System.out.println("Player 1, enter a number between 1-9: ");
Scanner player1 = new Scanner(System.in);
player1Input = player1.nextInt();
Scanner correctedInput = new Scanner(System.in);
while(player1Input < 1 || player1Input >= 10) {
System.out.println("This isn't a number between 1-9, try again: ");
player1CorrectedInput = correctedInput.nextInt();
player1Input = player1CorrectedInput;
}
// or
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == player1Input) {
// set new value
board[i][j] = p1Sym;
// set
isSet = true;
}
}
}
if (!isSet) {
System.out.println("not found");
}
}
void validInputPlayerTwo() {
boolean isSet = true;
int player2Input, player2CorrectedInput;
System.out.println("Player 2, enter a number between 1-9: ");
Scanner player2 = new Scanner(System.in);
player2Input = player2.nextInt();
Scanner correctedInput = new Scanner(System.in);
while(player2Input < 1 || player2Input >= 10) {
System.out.println("This isn't a number between 1-9, try again: ");
player2CorrectedInput = correctedInput.nextInt();
player2Input = player2CorrectedInput;
}
// or
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == player2Input){
board[i][j] = p2Sym;
isSet = true;
}
}
}
if (!isSet) {
System.out.println("not found");
}
}
public static void main(String[] args) {
tictactoe t = new tictactoe();
t.validInputPlayerOne();
t.boardFill();
t.validInputPlayerTwo();
t.boardFill();
}
}
You could do something like:
int turn = 0;
while (t.noWinner()) {
if (turn % 2 == 0) t.validInputPlayerOne();
else t.validInputPlayerTwo();
t.boardFill();
turn += 1;
}
Of course, now you have to actually write the noWinner function.
Answering your question directly, you could have a boolean that toggles on each move:
boolean firstPlayer = true;
while (t.gameIsNotFinished()) {
if (firstPlayer)
t.validInputPlayerOne();
else
t.validInputPlayerTwo();
firstPlayer = !firstPlayer;
}
However you have a lot of other issues with your code that you need to address. For example if a player enters an invalid value then it goes to the next player rather than asking for them to reenter the value.
You should also try to have a single validInputPlayer method that works for both players with the firstPlayer variable passed in. At the moment you have a lot of repeated code in those methods.

My Remove Method isn't Working

Create a program that keeps track of the following information input by the user:
First Name, Last Name, Phone Number, Age
Now - let's store this in a multidimensional array that will hold 10 of these contacts.
So our multidimensional array will need to be 10 rows and 4 columns.
You should be able to add, display and remove contacts in the array.
*/
import java.util.Scanner;
public class compLab2 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String[][] contacts = new String [10][4];
System.out.println("Select your options: \n");
while(true){
// Give the user a list of their options
System.out.println("1: Add a new contact to list.");
System.out.println("2: Remove a contact from the list.");
System.out.println("3: Display contacts.");
System.out.println("0: Exit the list.");
// Get the user input
int userChoice = input.nextInt();
switch(userChoice){
case 1:
addContacts(contacts);
break;
case 2:
removeContacts(contacts);
break;
case 3:
displayContacts(contacts);
break;
case 0:
System.out.println("Goodbye!");
System.exit(0);
}
}
}
private static void addContacts (String [][] contacts) {
Scanner input = new Scanner(System.in);
for (int i = 0; i < 10; i++) {
if (contacts[i][0] == null || contacts[i][0].equals(null)) {
contacts[i][0] = input.nextLine();
contacts[i][1] = input.nextLine();
contacts[i][2] = input.nextLine();
contacts[i][3] = input.nextLine();
boolean Inserted = true;
break;
}
}
}
private static void removeContacts(String [][] contacts) {
Scanner input = new Scanner(System.in);
System.out.println("Enter the name of the contact you want to remove: ");
String removeContact = input.nextLine();
for(int i=0; i<contacts.length; i++){
for(int j = 0; j <contacts[i].length; j++){
if(contacts[i][j].equals(removeContact)) {
contacts[i][0]=" ";
contacts[i][1]=" ";
contacts[i][2]=" ";
contacts[i][3]=" ";
}
}
break;
}
}
private static void displayContacts(String [][] contacts) {
for (int i = 0; i< contacts.length; i++) {
for (int j= 0; j < contacts[i].length; j++) {
System.out.print(contacts[i][j] + " ");
}
System.out.println();
}
}
}
You have to move your break inside the if condition(once element is remove break the loop) otherwise your first for loop will break in i=0 condition.
In if condition you have to check removeContact with contacts[i][j] because contacts[i][j] can be null.
Below you can find the code
if (removeContact != null) { //removeContact should not be null
for (int i = 0; i < contacts.length; i++) {
for (int j = 0; j < contacts[i].length; j++) {
if (removeContact.equals(contacts[i][j])) { //removeContact is not null so check removeContact with contacts[i][j]
contacts[i][0] = " ";
contacts[i][1] = " ";
contacts[i][2] = " ";
contacts[i][3] = " ";
break; //break the loop once you remove
}
}
}
}
You should set null insteam of white space(" ")
if (removeContact != null) {
for (int i = 0; i < contacts.length; i++) {
for (int j = 0; j < contacts[i].length; j++) {
if (removeContact.equals(contacts[i][j])) {
contacts[i][0] = null;
contacts[i][1] = null;
contacts[i][2] = null;
contacts[i][3] = null;
break;
}
}
}
}
Because you are checking null while adding a contact. So setting null will free a space in your array and will allow you to add a new contact to that space.
Also you should check null entry during displaying contacts
private static void displayContacts(String [][] contacts) {
for (int i = 0; i < contacts.length; i++) {
if (contacts[i][0] != null) {
for (int j= 0; j < contacts[i].length; j++) {
System.out.print(contacts[i][j] + " ");
}
System.out.println();
}
}
}
An ArrayList with a custom class can solve this problem easily.

Removing NullPointerException in Java

public class leftrec {
static int isleft(String[] left,String[] right)
{
int f=0;
for(int i=0;i<left.length;i++)
{
for(int j=0;j<right.length;j++)
{
if(left[i].charAt(0)==right[j].charAt(0))
{
System.out.println("Grammar is left recursive");
f=1;
}
}
}
return f;
}
public static void main(String[] args) {
// TODO code application logic here
String[] left=new String[10];
String[] right=new String[10];
Scanner sc=new Scanner(System.in);
System.out.println("enter no of prod");
int n=sc.nextInt();
for(int i=0;i<n;i++)
{
System.out.println("enter left prod");
left[i]=sc.next();
System.out.println("enter right prod");
right[i]=sc.next();
}
System.out.println("the productions are");
for(int i=0;i<n;i++)
{
System.out.println(left[i]+"->"+right[i]);
}
int flag=0;
flag=isleft(left,right);
if(flag==1)
{
System.out.println("Removing left recursion");
}
else
{
System.out.println("No left recursion");
}
}
}
I've written this code to find out if the given grammar is left recursive or not. When i compile the program it gives me NullPointerException in lines
if(left[i].charAt(0)==right[j].charAt(0))
and
isleft(left,right);
How do i remove the exception ?
I Guess the problem with your inputs , You are just taking the String Array lengths as 10.
String[] left=new String[10];
String[] right=new String[10];
Dont HardCode the String Array length
int n=sc.nextInt();
String[] left=new String[n];
String[] right=new String[n];
for(int i=0;i<n;i++){
System.out.println("enter left prod");
left[i]=sc.next();
System.out.println("enter right prod");
right[i]=sc.next();
}
Might ,this would be the problem
You need to change the code as follows::
package com.cgi.ie2.common;
import java.util.Scanner;
public class LeftRecursive {
static int isleft(String[] left, String[] right)
{
int f = 0;
for (int i = 0; i < left.length; i++) {
for (int j = 0; j < right.length; j++)
{
if (left[i].charAt(0) == right[j].charAt(0)) {
System.out.println("Grammar is left recursive");
f = 1;
}
}
}
return f;
}
public static void main(String[] args) {
// TODO code application logic here
Scanner sc = new Scanner(System.in);
System.out.println("enter no of prod");
int n = sc.nextInt();
//Changes done here::::
String[] left = new String[n];
String[] right = new String[n];
for (int i = 0; i < n; i++) {
System.out.println("enter left prod");
left[i] = sc.next();
System.out.println("enter right prod");
right[i] = sc.next();
}
System.out.println("the productions are");
for (int i = 0; i < n; i++) {
System.out.println(left[i] + "->" + right[i]);
}
int flag = 0;
flag = isleft(left, right);
if (flag == 1) {
System.out.println("Removing left recursion");
} else {
System.out.println("No left recursion");
}
}
}
This code will eliminate the NullpointerExceptions
If you getting the no. of prod from the console, the String arrays need to set accordingly,for that the changes i have done are::
System.out.println("enter no of prod");
int n = sc.nextInt();
//Changes done here::::
String[] left = new String[n];
String[] right = new String[n];
And for better codes what i can suggest you is you need to follow basic coding conventions,which makes your codes readable,codes are not perfect only if it runs corectly,codes are perfect if a coding conventions are follow,so please go through the following links to undestand basic idea of coding conventions::
http://www.javacodegeeks.com/2012/10/java-coding-conventions-considered-harmful.html
http://java.about.com/od/javasyntax/a/nameconventions.htm
you can`t initialize an array without size. You have already given the array sizes as 10 and if you enter products which bigger than 10 or smaller than 10 you will get errors. There fore if you want to use dynamic size , you should use a java collection. best approach for this is array list
static int isLeft(ArrayList left, ArrayList right)
{
int f = 0;
for (int i = 0; i < left.size(); i++) {
for (int j = 0; j < right.size(); j++)
{
if (left.get(i).charAt(0) == right.get(j).charAt(0)) {
System.out.println("Grammar is left recursive");
f = 1;
}
}
}
return f;
}
public static void main(String[] args) {
// TODO code application logic here
ArrayList<String> left = new ArrayList<String>();
ArrayList<String> right = new ArrayList<String>();
Scanner sc = new Scanner(System.in);
System.out.println("enter no of prod");
int n = sc.nextInt();
for (int i = 0; i < n; i++) {
System.out.println("enter left prod");
String leftText = sc.next();
left.add(leftText);
System.out.println("enter right prod");
String rightText = sc.next();
right.add(rightText);
}
System.out.println("the productions are");
for (int i = 0; i < n; i++) {
System.out.println(left.get(i) + "->" + right.get(i));
}
int flag;
flag = isLeft(left, right);
if (flag == 1) {
System.out.println("Removing left recursion");
} else {
System.out.println("No left recursion");
}
}

while loop for boolean user input

After getting the program to work for the most part (the help is appreciated :)). All I needed was to add the while loop so the user gets the menu option as many times he wants to. It starts giving me errors as "; expected" at the line where continue switches to false. Here is the code.
import java.io.*;
import java.util.*;
class Matrix {
double[][] element;
int rows, cols;
Matrix(int rows, int cols) {
this.rows = rows;
this.cols = cols;
element = new double[rows][cols];
}
public double getValue(int row, int col) {
return element[row][col];
}
public void setValue(int row, int col, double value) {
element[row][col] = value;
}
public int getNoRows() { // returns the total number of rows
return rows;
}
public int getNoCols() { // returns the total number of cols
return cols;
}
// The methods for the main calculations
public Matrix AddMatrix(Matrix m2) {
int row1 = getNoRows();
int col1 = getNoCols();
Matrix result = new Matrix(row1, col1);
for (int i = 0; i < row1; i++) {
for (int j = 0; j < col1; j++) {
result.setValue(i, j, this.getValue(i, j) + m2.getValue(i, j));
}
}
return result;
}
public Matrix MultiplyMatrix(Matrix m2) {
if (this.getNoCols() != m2.getNoRows()) {
throw new IllegalArgumentException("matrices can't be multiplied");
}
int row2 = this.getNoRows();
int col2 = m2.getNoCols();
Matrix result = new Matrix(row2, col2);
for (int i = 0; i < row2; i++) {
for (int j = 0; j < col2; j++) {
result.setValue(i, j, result.getValue(i, j) + this.getValue(i, j) * m2.getValue(i, j));
}
}
return result;
}
public Matrix TransposeMatrix() {
int row3 = this.getNoCols();
int col3 = this.getNoRows();
Matrix result = new Matrix(row3, col3);
for (int i = 0; i < row3; i++) {
for (int j = 0; j < col3; j++) {
result.setValue(i, j, this.getValue(j, i));
}
}
return result;
}
public void DisplayMatrix() {
for (int i = 0; i < this.getNoRows(); i++) {
for (int j = 0; j < this.getNoCols();
j++) {
System.out.print((this.getValue(i, j)) + " ");
}
System.out.print("\n");
}
}
}
public class Lab1 {
public static void main(String args[]) throws FileNotFoundException {
int choice;
Scanner in = new Scanner(System.in);
Boolean continue = true;
while (continue){
System.out.println("Enter your choice /n");
choice = in.nextInt();
System.out.println("1. Add two matrices \n");
System.out.println("2. Multiplymatrix two matrices \n");
System.out.println("3. Take transpose of a matrix \n");
System.out.println("4. Display a matrix \n");
System.out.println("5. Exit \n");
if (choice == 1) {
Matrix m1 = MatrixReader();
m1.DisplayMatrix();
Matrix m2 = MatrixReader();
m2.DisplayMatrix();
Matrix m3 = new Matrix(m1.getNoRows(), m1.getNoCols());
m3 = m1.AddMatrix(m2);
m3.DisplayMatrix();
}
if (choice == 2) {
Matrix m1 = MatrixReader();
m1.DisplayMatrix();
Matrix m2 = MatrixReader();
m2.DisplayMatrix();
Matrix m3 = new Matrix(m1.getNoRows(), m2.getNoCols());
m3 = m1.MultiplyMatrix(m2);
m3.DisplayMatrix();
}
if (choice == 3) {
Matrix m1 = MatrixReader();
m1.DisplayMatrix();
Matrix m3 = new Matrix(m1.getNoRows(), m1.getNoCols());
m3 = m1.TransposeMatrix();
m3.DisplayMatrix();
}
if (choice == 4) {
System.out.println("Will need to call the DisplyMatrix method for the object \n");
}
if (choice == 5) {
continue = false;
}
else {
System.out.println("Incorrect input. Kindly enter again \n");
}
}
}
public static Matrix MatrixReader() throws FileNotFoundException {
System.out.println("Give the filename for the matrix");
Scanner filescanner = new Scanner(System.in);
Scanner scanner = new Scanner(new File(filescanner.nextLine()));
scanner.nextLine(); // removes the first line in the input file
String rowLine = scanner.nextLine();
String[] arr = rowLine.split("=");
int rows = Integer.parseInt(arr[1].trim());
String colLine = scanner.nextLine();
String[] arr2 = colLine.split("=");
int cols = Integer.parseInt(arr2[1].trim());
Matrix test = new Matrix(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
test.setValue(i, j, scanner.nextDouble());
}
}
return test;
}
}
Everything looks fairly good except
Boolean continue = true;
and
continue = false;
etc.
continue is a reserved word and may not be used as an identifier. Rename the variable to cont or something similar.
And by the way, I would recommend you to use boolean instead of Boolean in this application.
Also, I believe there is an error in your if-structures:
if (choice == 1)
...
if (choice == 2)
...
if (choice == 5)
...
else
...
The else branch will be taken in all cases when choice != 5 (that is, even when choice is 1, 2, 3, .... So perhaps you want to change it to
if (choice == 1)
...
else if (choice == 2)
...
else if (choice == 3)
...
else
...
Finally, you may also want to consider using a switch for the choice:
switch (choice) {
case 1:
...
break;
case 2:
...
break;
...
default:
...
}
I'm not sure if this may cause conflicts, but "continue" is also a statement within Java. Maybe, by changing the variable name of continue, your problem will be solved. The link attached refers to how continue is used as a statement within Java: http://download.oracle.com/javase/tutorial/java/nutsandbolts/branch.html And what you could also do is make a switch() statement from the if() construction you have, but that's something of personal taste :)
To avoid getting the "m1 is already defined" error, write the switch like that (including the curly braces):
switch (choice) {
case 1: {
...
break;
}
case 2: {
...
break;
}
...
default: {
...
}
}
If you have converted to 'switch' then declare the 'Matrix m1 = null;' just before the switch statement. And in the initialization of each 'case' just use 'm1 = new MatrixReader()'. Do the same for 'm2' variable.

Categories

Resources