Comparing too many variables in if statement - java

I wrote a code for my homework which says do inputs create a magic square matrix or don't. In magic square matrix, all of the rows, columns and diagonals sum must be equal. I wrote some functions to calculate the sum of the rows, columns and diagonals. At the end of the code I need to compare them to see they are equal or not. I assigned the results of the functions to different variables and I compared them in if statement at the end of the code. I am wondering is there any smarter way for comparison. I mean in my if statement there are too many variables and too many equality. I believe there is a smarter way for this.
package lab03;
import java.util.Scanner;
public class E7_15 {
public static boolean checkNumbers(int[][] array){
for(int i=0; i<4; i++){
for(int j=0; j<4; j++){
if (array[i][j] < 1 || array[i][j] > 16){
System.out.println("You entered a wrong value");
return false;
}
}
}
return true;
}
public static int sumRow(int[][] array, int i){
int sum = 0;
for(int j=0; j<array[i].length; j++){
sum += array[i][j];
}
return sum;
}
public static int sumColumn(int[][] array, int j){
int sum = 0;
for(int i=0; i<array[j].length; i++){
sum += array[i][j];
}
return sum;
}
public static int diagonalSumRightToLeft(int[][] array){
int sum = 0;
for(int i=0; i<array.length; i++){
sum += array[i][array.length-1-i];
}
return sum;
}
public static int diagonalSumLeftToRight(int[][] array) {
int sum = 0;
for(int i=0; i<array.length; i++){
sum += array[i][i];
}
return sum;
}
public static void main (String [] args){
int[][] intArray = new int [4][4];
Scanner in = new Scanner(System.in);
for (int i=0; i<4; i++) {
for ( int j=0; j<4; j++) {
System.out.println("!!!Please enter your numbers between 1-16!!!");
System.out.println("Enter your number for row " + (i+1) + " and column " + (j+1) + ": ");
intArray[i][j] = in.nextInt();
}
}
boolean done = checkNumbers(intArray);
int sumLRD = diagonalSumLeftToRight(intArray);
int sumRLD = diagonalSumRightToLeft(intArray);
int r1 = sumRow(intArray, 0);
int r2 = sumRow(intArray, 1);
int r3 = sumRow(intArray, 2);
int r4 = sumRow(intArray, 3);
int c1 = sumColumn(intArray, 0);
int c2 = sumColumn(intArray, 1);
int c3 = sumColumn(intArray, 2);
int c4 = sumColumn(intArray, 3);
if (done == true){
if(sumLRD==sumRLD && sumLRD==r1 && sumLRD==r2 && sumLRD==r3 && sumLRD==r4 &&
sumLRD==c1 && sumLRD==c2 && sumLRD==c3 && sumLRD==c4 && sumRLD==r1 && sumRLD==r2 &&
sumRLD==r3 && sumRLD==r4 && sumRLD==c1 && sumRLD==c2 && sumRLD==c3 &&
sumRLD==c4 && r1==r2 && r1==r3 && r1==r4 && r1==c1 && r1==c2 && r1==c3 && r1==c4 &&
r2==r3 && r2==r4 && r2==c1 && r2==c2 && r2==c3 && r2==c4 && r3==r4 && r3==c1 &&
r3==c2 && r3==c3 && r3==c4 && r4==c1 && r4==c2 && r4==c3 && r4==c4 && c1==c2 &&
c1==c3 && c1==c4 && c2==c3 && c2==c4 && c3==c4){
System.out.println("This is a magic square matrix");
}
else {
System.out.println("This is NOT a magic square matrix");
}
}
if (done == false){
System.out.println("WRONG VALUE! START AGAIN!");
}
in.close();
}
}

It seems like you're trying to see if all those numbers are equal. Just use a loop that compares every variable in the list with the one following it:
public boolean allEqual(int... values) {
for (int i = 0; i < values.length-1; i++) {
if (values[i] != values[i+1]) {
return false;
}
}
return true;
}
Then replace your megacondition with:
if (allEqual(sumLRD, sumRLD, r1, r2, ...)) {
// ...
}
This works because equality is transitive - i.e. if a == b and b == c then a == c. (The same for any number of variables.)
An alternative would be to refactor the whole check into something like:
boolean isMagicSquare(int[][] intArray) {
// check diagonals
int sum = diagonalSumLeftToRight(intArray);
if (sum != diagonalSumRightToLeft(intArray)) {
return false;
}
// check rows and columns
for (int i = 0; i < 4; i++) {
if (sum != sumRow(intArray, i) || sum != sumColumn(intArray, i)) {
return false;
}
}
return true;
}
// ...
if (isMagicSquare(intArray)) {
// ...
}

You could put all your sums in an array and use a function like this one in order to check if all the values are equal:
public static boolean allElementsTheSame(int[] array) {
if (array.length == 0) {
return true;
} else {
int first = array[0];
for (int element : array) {
if (element != first) {
return false;
}
}
return true;
}
}

Related

Java Code solves 3x3 and 5x5 magic squares but not 4x4 and 6x6

Hey guys new to programming here. I have a project on magic squares and my code can solve 3x3 and 5x5 but not 44 and 6x6 arrays for some reason. To give some info about the project we make a program that should give the user 4 option to solve a magic square (using an arraylist as a stack or as queue, a stack and a linked list as a queue). The code makes copies of the magic square and each of them has a new cell filled with a number according to the check methods and its i,j position. Each copy is created checked and filled if possible in the nextSuccessor() method. if at least a number can fill the cell the copy is returned to the main program to be stored in the data structure the user has chosen in the beginning of the program. If no number could fill the cell the method returns null. The program ends when either all the cells of a copy of a magic square are filled, or if the data structure gets empty.
ps: That first constructor that is in the MagicSquare class is what we were instructed to do so that's why i made the set method.
Here are the two classes:
public class MagicSquare{
int N;
int C;
int[][] magic; // NxN.
int numbers; //counts how many number have been used
boolean[] used; // NxN length
int row, col; //point the cell to be filled
int current_number; // the number that will be checked to fill the magic[row][col]
public MagicSquare(){
N=0;
magic = new int[N][N];
C = N*(N*N + 1)/2;
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
magic[i][j] = 0;
}
}
numbers = 0;
used = new boolean[N*N];
for (int i = 0; i < N*N; i++){
used[i] = false;
}
}
public MagicSquare(MagicSquare obj){
N = obj.N;
C = obj.C;
magic = new int[N][N];
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
magic[i][j] = obj.magic[i][j];
}
}
numbers = obj.numbers;
used = new boolean[N*N];
for (int i = 0; i < N*N; i++){
used[i] = obj.used[i];
}
}
public void setNandValues(int n, int[][] a){
N = n;
C = N*(N*N + 1)/2;
magic = new int[N][N];
used = new boolean[N*N];
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
magic[i][j] = a[i][j];
if (magic[i][j] != 0) {
used[magic[i][j] -1] = true;
numbers++;
}
}
}
}
public void initialize_successor(){
row = -1;
col = -1;
int i = 0;
while (i < N && row == -1){
int j = 0;
while (j<N && col == -1){
if (magic[i][j] == 0){
this.row = i;
this.col = j;
}
j++;
}
i++;
}
current_number=0;
}
public boolean checkRow(){
int m = 0;
int s = current_number;
int a = 0;
int b = 0;
for (int i = 0; i < N; i++){
if (magic[row][i] == 0){
m++;
}
else s += magic[row][i];
}
m--;
if (m>0){
int i = 0;
int k = 0;
while(i<N && k<m){
if(i != current_number-1 && used[i] == false){
a += i+1;
k += 1;
}
i++;
}
/*while(i > 0){
if (used[k] == false){
a += (k+1);
i--;
if (k == current_number - 1){
a -= (k+1);
i++;
}
}
k++;
}*/
/*i = m;
k = 0;
while(i > 0){
if (used[N*N-k-1] == false){
b += (N*N-k);
i--;
if (k == current_number - 1){
b -= (N*N-k);
i++;
}
}
k++;
} */
i = 0;
k = 0;
while(i<N*N && k<m){
if(i != current_number-1 && used[N*N-i-1] == false){
b += N*N - i;
k += 1;
}
i++;
}
}
return (s+a<=C && s+b>=C);
}
public boolean checkCol(){
int m = 0;
int s = current_number;
int a = 0;
int b = 0;
for (int i = 0; i < N; i++){
if (magic[i][col] == 0){
m++;
}
else s += magic[i][col];
}
m--;
if (m>0){
int i = m;
int k = 0;
/*while(i > 0){
if (used[k] == false){
a += (k+1);
i--;
if (k == current_number - 1){
a -= (k+1);
i++;
}
}
k++;
}*/
while(i<N && k<m){
if(i != current_number-1 && used[i] == false){
a += i+1;
k += 1;
}
i++;
}
/*i = m;
k = 0;
while(i > 0){
if (used[N*N-k-1] == false){
b += (N*N-k);
i--;
if (k == current_number - 1){
b -= (N*N-k);
i++;
}
}
k++;
}*/
i = 0;
k = 0;
while(i<N*N && k<m){
if(i != current_number-1 && used[N*N-i-1] == false){
b += N*N - i;
k += 1;
}
i++;
}
}
return (s+a<=C && s+b>=C);
}
public boolean checkMainDiagonal() {
int m = 0;
int s = current_number;
int a = 0;
int b = 0;
for (int i = 0; i < N; i++){
if (magic[i][i] == 0){
m++;
}
else s += magic[i][i];
}
m--;
if (m>0){
int i = m;
int k = 0;
/*while(i > 0){
if (used[k] == false){
a += (k+1);
i--;
if (k == current_number - 1){
a -= (k+1);
i++;
}
}
k++;
}*/
while(i<N && k<m){
if(i != current_number-1 && used[i] == false){
a += i+1;
k += 1;
}
i++;
}
/*i = m;
k = 0;
while(i > 0){
if (used[N*N-k-1] == false){
b += (N*N-k);
i--;
if (k == current_number - 1){
b -= (N*N-k);
i++;
}
}
k++;
}*/
i = 0;
k = 0;
while(i<N*N && k<m){
if(i != current_number-1 && used[N*N-i-1] == false){
b += N*N - i;
k += 1;
}
i++;
}
}
return (s+a<=C && s+b>=C);
}
public boolean checkSecondaryDiagonal() {
int m = 0;
int s = current_number;
int a = 0;
int b = 0;
for (int i = 0; i < N; i++){
if (magic[i][N-i-1] == 0){
m++;
}
else s += magic[i][N-i-1];
}
m--;
if (m>0){
int i = m;
int k = 0;
/*while(i > 0){
if (used[k] == false){
a += (k+1);
i--;
if (k == current_number - 1){
a -= (k+1);
i++;
}
}
k++;
}*/
while(i<N && k<m){
if(i != current_number-1 && used[i] == false){
a += i+1;
k += 1;
}
i++;
}
/*i = m;
k = 0;
while(i > 0){
if (used[N*N-k-1] == false){
b += (N*N-k);
i--;
if (k == current_number - 1){
b -= (N*N-k);
i++;
}
}
k++;
}*/
i = 0;
k = 0;
while(i<N*N && k<m){
if(i != current_number-1 && used[N*N-i-1] == false){
b += N*N - i;
k += 1;
}
i++;
}
}
return (s+a<=C && s+b>=C);
}
public MagicSquare nextSuccessor(){
MagicSquare m;
while( current_number < N*N){
current_number++;
if( !used[ current_number -1]){
if(((this.row != this.col && this.row != N-this.col -1) && (this.checkRow() && this.checkCol())) ||
(this.row == this.col && this.row != N-this.col -1) && (this.checkRow() && this.checkCol() && this.checkMainDiagonal()) ||
(this.row != this.col && this.row == N-this.col -1) && (this.checkRow() && this.checkCol() && this.checkSecondaryDiagonal()) ||
(this.row == this.col && this.row == N-this.col -1) && (this.checkRow() && this.checkCol() && this.checkMainDiagonal() && this.checkSecondaryDiagonal())){
magic[row][col] = current_number;
used[current_number - 1] = true;
m = new MagicSquare();
m.setNandValues(N, magic);
return m;
}
}
}
return null;
}
/*
public MagicSquare nextSuccessor(){
MagicSquare m;
while( current_number < N*N){
current_number++;
if( !used[ current_number -1] && checkRow() && checkCol()){
magic[row][col] = current_number;
used[current_number - 1] = true;
m = new MagicSquare();
m.setNandValues(N, magic);
return m;
}
}
return null;
}
*/
public void display(){
for (int i =0; i<N; i++){
for(int j = 0; j<N; j++){
System.out.print(magic[i][j] + " ");
}
System.out.println();
}
}
}
/*
public MagicSquare nextSuccessor(){
MagicSquare m;
while( current_number < N*N){
current_number++;
if( !used[ current_number -1] && checkRow() && checkCol()){
magic[row][col] = current_number;
used[current_number - 1] = true;
m = new MagicSquare();
m.setNandValues(N, magic);
return m;
}
}
return null;
}
*/
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.Stack;
import java.util.LinkedList;
import java.util.ArrayList;
public class MainSolver {
static int[][] pin;
static int N;
static ArrayList<MagicSquare> frontierAL;
static Stack<MagicSquare> frontierST;
static LinkedList<MagicSquare> frontierLL;
//String filename = args[0];
//int option = Integer.parseInt(args[1]);
static String filename = "/Users/panagiotispagonis/Documents/ΠΜΣ/ΠΛΣ 50/Εργασίες ΠΛ50/Εργασία 3/Εργασία 3 (code)/Thema1/p4-01.txt";
static int option;
static void readMagicSquare(String filename){
try {
File obj = new File(filename);
Scanner read = new Scanner(obj);
N = Integer.parseInt(read.nextLine());
pin = new int[N][N];
for(int i = 0; i<N; i++) {
String data = read.nextLine();
String[] row =data.split(" ");
for (int j= 0; j < N; j++){
pin[i][j] = Integer.parseInt(row[j]);
}
}
read.close();
}
catch (FileNotFoundException e) {
System.out.println("An error has occurred.");
e.printStackTrace();
}
}
static void initialize_search(MagicSquare s, int datastructure) {
switch (datastructure) {
case 1:
case 2:
frontierAL = new ArrayList<MagicSquare>();
frontierAL.add(s);
break;
case 3:
frontierST=new Stack<MagicSquare>();
frontierST.push(s);
break;
case 4:
frontierLL=new LinkedList<MagicSquare>();
frontierLL.add(s);
break;
default:
break;
}
}
// arxikopoiei ti domi pou tha xrisimopoiithei apo to programma se kathe periptosi. auto krinetai apo to poia epilogi patise o xristis (option)
static void search(int datastructure) {
MagicSquare current = null, next;
switch (datastructure) {
case 1:
System.out.println("Search using ArrayList as a Stack");
break;
case 2:
System.out.println("Search using ArrayList as a Queue");
break;
case 3:
System.out.println("Search using Stack as a Stack");
break;
case 4:
System.out.println("Search using LinkedList as a Queue");
break;
default:
break;
}
boolean empty_frontier=false;
while (!empty_frontier) {
if (datastructure==1) {
current=frontierAL.get(frontierAL.size()-1);
frontierAL.remove(frontierAL.size()-1);
}
else if (datastructure==2) {
current=frontierAL.get(0);
frontierAL.remove(0);
}
else if (datastructure==3)
current=frontierST.pop();
else if (datastructure==4)
current=frontierLL.removeFirst();
current.initialize_successor();
while((next=current.nextSuccessor())!=null)
{
if (next.numbers==N*N)
{
System.out.println("\nSOLUTION FOUND ");
System.out.println("==============");
next.display();
return;
}
else
switch (datastructure) {
case 1: ;
case 2: {frontierAL.add(next);
break;}
case 3: { frontierST.push(next);
break;}
case 4:{ frontierLL.addLast(next);
break;
}
}
}
switch (datastructure) {
case 1:
if (frontierAL.isEmpty())
empty_frontier=true;
break;
case 2:
if (frontierAL.isEmpty())
empty_frontier=true;
break;
case 3:
if (frontierST.isEmpty())
empty_frontier=true;
break;
case 4:
if (frontierLL.isEmpty())
empty_frontier=true;
break;
}
}
System.out.println("\nPUZZLE CANNOT BE SOLVED");
}
public static void main(String[] args){
//Scanner input = new Scanner(System.in);
//String filename = args[0];
//int option = Integer.parseInt(args[1]);
readMagicSquare(filename);
MagicSquare sqr = new MagicSquare();
sqr.setNandValues(N, pin);
initialize_search(sqr, option);
search(option);
}
}
At first i thought i was missing something in my while loops so i wrote them as "childish" as possible. Still nothing... Everything i tried is as a comment in the classes' code.
So Any ideas?

Can someone help me with my win scenario in my Gomoku program?

I have written a program for an assignment where we had to write a simple Gomoku program. I thought I had it all, but when I compile and run, it sets off the win scenario even if I only have 4 of a kind and even if they're not next to each other. (It should only set off a win if there are five in a row of one kind...X's or O's). I feel like I should be resetting my counter back to 0 before each turn, but I'm not sure where I should be doing that. Any tips would be appreciated!
import java.util.Scanner;
public class Gomoku1
{
public static void main (String[] args)
{
Scanner input = new Scanner(System.in);
char[][] map = new char [19][19];
int row = 0;
int column = 0;
//fill game with dots
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map[i].length; j++)
{
map[i][j] = '.';
}
}
printMap(map);
char player1Choice = 'X';
char player2Choice = 'O';
int [] place;
while (true)
{
System.out.println("Player 1's turn!");
place = userTurn(map, player1Choice);
if (isValidMove(map, place[0], place[1]) == false)
{
System.out.println("Invalid move! Try again!");
place = userTurn(map, player1Choice);
}
if (isValidMove(map, place[0], place[1])) {
map[place[0]][place[1]] = player1Choice;
printMap(map);
}
if (isBoardFull(map) == true)
{
System.out.println("Board is full. Tied game.");
break;
}
if (hasPlayerWon(map, player1Choice) == true)
{
System.out.println("Player 1 Wins!");
break;
}
else
{
System.out.println("Player 2's turn!: ");
place = userTurn(map, player2Choice);
//System.out.println(isValidMove(map, row, column));
if (isValidMove(map, place[0], place[1]) == false)
{
System.out.println("Invalid move! Try again!");
place = userTurn(map, player2Choice);
}
if (isValidMove(map, place[0], place[1])) {
map[place[0]][place[1]] = player2Choice;
printMap(map);
}
if (isBoardFull(map) == true)
{
System.out.println("Board is full. Tied game.");
break;
}
if (hasPlayerWon(map, player2Choice) == true)
{
System.out.println("Player 2 Wins!");
break;
}
}
}
}
public static void printMap (char[][] map)
{
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map[i].length; j++)
{
System.out.printf("%2c", map[i][j]);
}
System.out.println();
}
}
public static int [] userTurn (char[][] map, char playerChoice)
{
Scanner input = new Scanner(System.in);
System.out.print("Enter row: ");
int row = input.nextInt();
System.out.print("Enter column: ");
int column = input.nextInt();
int place [] = {row, column};
return place;
}
public static boolean isValidMove (char[][] map, int row, int column)
{
//System.out.println ("n is valid move");
if (row < 0 || row > 18 || column < 0 || column > 18 || map[row][column]=='O' || map[row][column]=='X')
{
return false;
}
else
{
return true;
}
}
public static boolean isBoardFull (char[][] map)
{
int openSpots = 0;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (!(map[i][j]=='.'))
openSpots++;
}
}
if (openSpots == 361)
{
return true;
}
return false;
}
public static boolean hasPlayerWon(char[][] map, int player)
{
if (isHorizontalWin(map, player) == true || isVerticalWin(map, player) == true || isDiagonalWin(map, player) == true)
{
return true;
}
return false;
}
public static boolean isHorizontalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count ++;
r += 0;
c += 1;
}
}
}
}
if (count == 5)
{
return true;
}
return false;
}
public static boolean isVerticalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count ++;
r += 1;
c += 0;
}
}
}
}
if (count == 5)
{
return true;
}
return false;
}
public static boolean isDiagonalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count++;
r += 1;
c += 1;
}
}
}
}
if (count == 5)
{
return true;
}
return false;
}
}
You have problems in all three of the function that check win conditions: isHorizontalWin, isVerticalWin, and isDiagonalWin. All three increment the variable count, but this variable is never set back to zero. Additionally, the check to see if count == 5 should be made inside the loop. Here is an example on how to fix isHorizontalWin:
public static boolean isHorizontalWin(char[][] map, int player)
{
int count = 0;
int r;
int c;
for (int i = 0; i < map.length; i++)
{
for (int j = 0; j < map.length; j++)
{
if (map[i][j]==(player))
{
r = i;
c = j;
while (r >= 0 && r <= 18 && c >= 0 && c <= 18 && map[r][c] == player)
{
count ++;
r += 0;
c += 1;
}
if (count == 5)
{
return true;
} else {
count = 0;
}
}
}
}
return false;
}

How to check if every other element is even

My code only works for the first index, which just returns 8 true.
If I change the first index (nums[0]) to 9 for example, it skips the 3 and prints 4 true.
How do I make so that it checks the rest of them (every other element that is) so that it works for every other index?
public static boolean solution(int[] nums) {
for(int i = 0; i < nums.length; i++) {
if(i % 2 == 0 && nums[i] % 2 == 0) {
System.out.print(nums[i] + " ");
return true;
}
}
return false;
}
public static void main(String args[]) {
int[] nums = {8,3,4,1,6,5,12,1};
System.out.println(solution(nums));
}
You have one (logical) error in your code, and one part that can be improved:
public static boolean solution(int[] nums) {
for(int i = 0; i < nums.length; i++) {
if(i % 2 == 0 && nums[i] % 2 == 0) {
System.out.print(nums[i] + " ");
return true;
}
}
return false;
}
In your current code, true is returned on the first valid test, which means, you don't test the following cases. Change your code so you'll test them all, and only return during the flow, if you encounter an invalid value.
public static boolean solution(int[] nums) {
for(int i = 0; i < nums.length; i++) {
if(i % 2 == 0 && nums[i] % 2 != 0) {
System.out.print(nums[i] + " ");
return false;
}
}
return true;
}
A second thing you can improve, is not checking for even indices each iteration. Just augment your i value by two instead of one:
public static boolean solution(int[] nums) {
for(int i = 0; i < nums.length; i+=2) {
if( nums[i] % 2 != 0) {
System.out.print(nums[i] + " ");
return false;
}
}
return true;
}
I think what you want to do is check all the even index and look if there are even you can do like this :
public static boolean solution(int[] nums) {
for(int i = 0; i < nums.length; i++) {
if(i % 2 == 0 && nums[i] % 2 != 0) {
System.out.print(nums[i] + " ");
return false;
}
}
return true;
}

Converting a long int into separate digits and reverse populating into a vector

First of all this is a school project about credit card number validations.
Basically I am trying to convert a long int (the CC number) into a vector so I can manipulate each digit as required. I am doing it by using the %10 way. Since this will end up with my vector having the number from right to left (backwards), I am setting the vector in increments starting from ccNum.size()-1 and working backwards so that the values in the vector are in the same order as the user input.
The problem is that first values that are processed (so the last 9 or so digits of input) are being put in the vector incorrectly. I've tried restructuring the loop, copying into an array and then reversing it into the vector, and various other things that my mind just can't keep track of. I tried to comment my code as best as I could to outline what is going on, here it is:
public static void main(String[] args) {
long creditCardNumber = 0;
Vector<Integer> ccNum = new Vector<Integer>(13,3);
Vector<Integer> oddNum = new Vector<Integer>(6,1);
Vector<Integer> evenNum = new Vector<Integer>(6,1);
creditCardNumber = getInput(creditCardNumber);
int size = getSize(creditCardNumber);
//Pre-populate the vector so that I can add values starting from behind
//this makes it so that the credit card number isn't backwards. I also
//did it so that it matches the size of the input to prevent false values
//Yes, I verified the getSize method works.
for (int k = 0; k < size; k++) {
ccNum.add(k);
}
//I made a copy of the variable so I don't screw it up in the loop
long ccNumber = creditCardNumber;
//THIS IS WHERE THE PROBLEM IS.
for (int j = 0; ccNumber > 0; j++){
//on the first iteration, set the final index of ccNum array to
//final value of input using %10
if (j == 0){
ccNum.set(ccNum.size() - 1, (int) ccNumber % 10);
ccNumber /= 10;
//This just prints the value of ccNumber afterwards so that I can
//keep track of whats going on and make sure everything is "working"
System.out.println(ccNumber);
} else {
//Here I am continuously setting the values going backwards
//I end up with the same amount of values as the input but some
//are wrong
ccNum.set(ccNum.size() - (j+1), (int) ccNumber % 10);
ccNumber /= 10;
System.out.println(ccNumber);
}
}
//Here is where I print out all the values in the ccNum vector.
for (int l = 0; l < size; l++) {
System.out.print(ccNum.get(l));
}
System.out.println("");
for (int i = 0; i < ccNum.size() - 1; i ++) {
if (i % 2 == 0) {
evenNum.add(getDigit(ccNum.get(i)));
} else {
oddNum.add(ccNum.get(i));
}
}
int prefix = getPrefix(ccNum);
int sumEven = sumOfDoubleEvenPlace(evenNum);
int sumOdd = sumOfOddPlace(oddNum);
if (isValid(ccNum, sumEven, sumOdd, size, prefix)) {
System.out.printf("%d: is valid", creditCardNumber);
} else {
System.out.printf("%d: is invalid", creditCardNumber);
}
}
private static int sumOfOddPlace(Vector<Integer> oddNum) {
int sum = 0;
for (int i = 0; i < oddNum.size() - 1; i++) {
sum += oddNum.get(i);
}
return sum;
}
private static int sumOfDoubleEvenPlace(Vector<Integer> evenNum) {
int sum = 0;
for (int i = 0; i < evenNum.size() - 1; i++) {
sum += evenNum.get(i);
}
return sum;
}
private static int getDigit(int x) {
int y = x*2;
if (y < 10) {
return y;
} else {
int sum = 0;
while (y > 0) {
sum += y % 10;
y /= 10;
}
return sum;
}
}
private static int getPrefix(Vector<Integer> ccNum) {
if (ccNum.get(0) == 4) {
return 4;
} else if (ccNum.get(0) == 5) {
return 5;
} else if (ccNum.get(0) == 6) {
return 6;
} else if (ccNum.get(0) == 3 && ccNum.get(1) == 7) {
return 37;
} else {
return 0;
}
}
private static int getSize(long creditCardNumber) {
int size = (int)(Math.log10(creditCardNumber)+1);
return size;
}
private static long getInput(long creditCardNumber){
Scanner input = new Scanner(System.in);
System.out.print("Enter a credit card number: ");
creditCardNumber = input.nextLong();
input.close();
return creditCardNumber;
}
private static boolean isValid(Vector<Integer> ccNum, int sumEven, int sumOdd, int size, int prefix) {
if (size < 13 || size > 16) {
return false;
} else if (prefixMatched(prefix) == false) {
return false;
} else if ((sumEven + sumOdd) % 10 != 0) {
return false;
} else {
return true;
}
}
private static boolean prefixMatched(int prefix) {
if (prefix == 4 || prefix == 5 || prefix == 6 || prefix == 37) {
return true;
} else {
return false;
}
}
Here is the output:
Enter a credit card number: 4388576018410707
438857601841070
43885760184107
4388576018410
438857601841
43885760184
4388576018
438857601
43885760
4388576
438857
43885
4388
438
43
4
0
438857601249-2-16-3
4388576018410707: is invalid
As You can see, the first half of the number comes out correctly (the last half to be looped). If anybody has a solution that'd be awesome.
For future reference for other people who may get stuck - this is what i ended up doing, looks cleaner as well, Thanks for the help everyone.
public class CreditCardNumberValidation {
public static void main(String[] args) {
long creditCardNumber = 0;
//Using ArrayLists because it makes it easier to manipulate data later
ArrayList<Integer> ccNum = new ArrayList<Integer>();
ArrayList<Integer> oddNum = new ArrayList<Integer>();
ArrayList<Integer> evenNum = new ArrayList<Integer>();
//Getting input in different method to clean up the code
creditCardNumber = getInput(creditCardNumber);
int size = getSize(creditCardNumber);
//Split creditCardNumber into separate integers and store in ArrayList
long ccNumber = creditCardNumber;
for (int j = 0; ccNumber > 0; j++){
ccNum.add((int) (ccNumber % 10));
ccNumber /= 10;
}
//Reverse the collection so that the numbers are in order
Collections.reverse(ccNum);
//Using the main List, even and odd numbers are sorted
for (int i = 0; i < ccNum.size(); i ++) {
if (i % 2 == 0) {
evenNum.add(getDigit(ccNum.get(i)));
} else {
oddNum.add(ccNum.get(i));
}
}
int prefix = getPrefix(ccNum);
int sumEven = sumOfDoubleEvenPlace(evenNum);
int sumOdd = sumOfOddPlace(oddNum);
if (isValid(ccNum, sumEven, sumOdd, size, prefix)) {
System.out.printf("%d is valid", creditCardNumber);
} else {
System.out.printf("%d is invalid", creditCardNumber);
}
}
private static int sumOfOddPlace(ArrayList<Integer> oddNum) {
int sum = 0;
for (int i = 0; i < oddNum.size(); i++) {
sum += oddNum.get(i);
}
return sum;
}
private static int sumOfDoubleEvenPlace(ArrayList<Integer> evenNum) {
int sum = 0;
for (int i = 0; i < evenNum.size(); i++) {
sum += evenNum.get(i);
}
return sum;
}
private static int getDigit(int x) {
int y = x*2;
if (y < 10) {
return y;
} else {
int sum = 0;
while (y > 0) {
sum += y % 10;
y /= 10;
}
return sum;
}
}
private static int getPrefix(ArrayList<Integer> ccNum) {
if (ccNum.get(0) == 4) {
return 4;
} else if (ccNum.get(0) == 5) {
return 5;
} else if (ccNum.get(0) == 6) {
return 6;
} else if (ccNum.get(0) == 3 && ccNum.get(1) == 7) {
return 37;
} else {
return 0;
}
}
private static int getSize(long creditCardNumber) {
//Easy way of getting the size of an integer without modifying it
return (int)(Math.log10(creditCardNumber)+1);
}
private static long getInput(long creditCardNumber){
Scanner input = new Scanner(System.in);
System.out.print("Enter a credit card number: ");
creditCardNumber = input.nextLong();
input.close();
return creditCardNumber;
}
private static boolean isValid(ArrayList<Integer> ccNum, int sumEven, int sumOdd, int size, int prefix) {
// Check size, prefix, and sum, if all tests pass return true
if (size < 13 || size > 16) {
return false;
} else if (prefixMatched(prefix) == false) {
return false;
} else if ((sumEven + sumOdd) % 10 != 0) {
return false;
} else {
return true;
}
}
private static boolean prefixMatched(int prefix) {
if (prefix == 4 || prefix == 5 || prefix == 6 || prefix == 37) {
return true;
} else {
return false;
}
}
}
Try to replace
(int) ccNumber % 10
by
(int) (ccNumber % 10)
If you cast to int first and then do the modulo 10, it won't work when the int value overflows.
I recomend you using ArrayList like in my listing. My function returns simple arraylist of integers that was in Long.
public List<Integer>getCardNumbers(Long longCardNumber){
String cardNumber = longCardNumber.toString();
List<Integer> intCardNumberList = new ArrayList<Integer>();
for(int i=0;i<cardNumber.length();i++){
intCardNumberList.add(Integer.parseInt(String.valueOf(cardNumber.charAt(i))));
}
return intCardNumberList;
}

Making String data structure more efficient in java [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have the task and homework of creating a data structure that would make the programs given work, it basically generates random nonsensical words and you need to create a data structure that stores them, can add, count and remove them. This is what I have so far but need to make it more efficient, a lot more efficient. Also I can't use the Java API.
public class WordStoringTest implements WordStore {
private StringBuilder[] words;
private int[] array;
private int[] abcdefg;
private int[] hijklmn;
private int[] opqrstu;
private int[] vwxyz;
private int n;
public WordStoringTest(int n) {
this.n = n;
this.words = new StringBuilder[n];
this.array = new int[n];
this.abcdefg = new int[n];
this.hijklmn = new int[n];
this.opqrstu = new int[n];
this.vwxyz = new int[n];
for(int i=0; i<n; i++){
abcdefg[i] = 0;
hijklmn[i] = 0;
opqrstu[i] = 0;
vwxyz[i] = 0;
}
}
public void add(String word) {
StringBuilder word2 = new StringBuilder(word);
int i = word2.hashCode();
StringBuilder[] newWords = new StringBuilder[this.words.length + 1];
System.arraycopy(this.words, 0, newWords, 0, this.words.length);
newWords[newWords.length - 1] = word2;
this.words = newWords;
if(word.charAt(0) >= 'a' && word.charAt(0) <= 'g'){
int count =0;
for(int a=0; a<abcdefg.length; a++){
if(abcdefg[count] !=0){
count++;
}
}
int[] arrayTemp = new int[count+1];
int c =0;
for(int v = 0; v<abcdefg.length; v++){
if(abcdefg[v] !=0){
arrayTemp[v] = abcdefg[v];
c++;
}
}
arrayTemp[c] = i;
abcdefg = arrayTemp;
}
else if(word.charAt(0) >= 'h' && word.charAt(0) <= 'n'){
int count =0;
for(int a=0; a<hijklmn.length; a++){
if(hijklmn[count] !=0){
count++;
}
}
int[] arrayTemp = new int[count+1];
int c =0;
for(int v = 0; v<hijklmn.length; v++){
if(hijklmn[v] !=0){
arrayTemp[v] = hijklmn[v];
c++;
}
}
arrayTemp[c] = i;
hijklmn = arrayTemp;
}
else if(word.charAt(0) >= 'o' && word.charAt(0) <= 'u'){
int count =0;
for(int a=0; a<opqrstu.length; a++){
if(opqrstu[count] !=0){
count++;
}
}
int[] arrayTemp = new int[count+1];
int c =0;
for(int v = 0; v<opqrstu.length; v++){
if(opqrstu[v] !=0){
arrayTemp[v] = opqrstu[v];
c++;
}
}
arrayTemp[c] = i;
opqrstu = arrayTemp;
}
else if(word.charAt(0) >= 'v' && word.charAt(0) <= 'z'){
int count =0;
for(int a=0; a<vwxyz.length; a++){
if(vwxyz[count] !=0){
count++;
}
}
int[] arrayTemp = new int[count+1];
int c =0;
for(int v = 0; v<vwxyz.length; v++){
if(vwxyz[v] !=0){
arrayTemp[v] = vwxyz[v];
c++;
}
}
arrayTemp[c] = i;
vwxyz = arrayTemp;
}
}
public int count(String word) {
int i = word.hashCode();
int count = 0;
int[] temp = null;
if(word.charAt(0) >= 'a' && word.charAt(0) <= 'g'){
temp = abcdefg;
}
else if(word.charAt(0) >= 'h' && word.charAt(0) <= 'n'){
temp = hijklmn;
}
else if(word.charAt(0) >= 'o' && word.charAt(0) <= 'u'){
temp = opqrstu;
}
else if(word.charAt(0) >= 'v' && word.charAt(0) <= 'z'){
temp = vwxyz;
}
for (int w = 0; w<temp.length; w++){
if (array[w] == i) {
count++;
}
}
return count;
}
public void remove(String word) {
int pos = 0;
StringBuilder[] temp = this.words;
while (pos < temp.length) {
StringBuilder w = temp[pos];
if (w.equals(word)) {
StringBuilder[] newTemp = new StringBuilder[temp.length - 1];
if (pos == 0) {
System.arraycopy(temp, 1, newTemp, 0, newTemp.length);
} else if (pos == temp.length - 1) {
System.arraycopy(temp, 0, newTemp, 0, newTemp.length);
} else {
System.arraycopy(temp, 0, newTemp, 0, pos);
System.arraycopy(temp, pos + 1, newTemp, pos, newTemp.length - pos);
}
temp = newTemp;
} else {
pos++;
}
}
this.words = temp;
System.out.println("1" + "*");
int posi = 0;
int f = word.hashCode();
int[] temps = this.array;
while (posi < temps.length) {
int g = temps[posi];
if (g ==f) {
int[] newTemps = new int[temps.length - 1];
if (posi == 0) {
System.arraycopy(temps, 1, newTemps, 0, newTemps.length);
} else if (posi == temps.length - 1) {
System.arraycopy(temps, 0, newTemps, 0, newTemps.length);
} else {
System.arraycopy(temps, 0, newTemps, 0, posi);
System.arraycopy(temps, posi + 1, newTemps, posi, newTemps.length - posi);
}
temps = newTemps;
} else {
posi++;
}
}
this.array = temps;
}
}
I know the remove method doesn't work :)
For a start,
don't use StringBuffer, they were replaced by StringBuilder almost ten years ago and is slightly faster.
don't use wrappers when you can use primitives. This not only performs better but is much clearer as to intent. i.e. don't use an Integer if it can't be null and you don't need to.
I would use an ArrayList as a list of StringBuilders, or I would grow the array the same way. i.e. double the size as required rather than increasing the size on every add()
use range checks like word.charAt(0) >= 'a' && word.charAt(0) <= 'g'
use counter more than once, you appear to move which counter to increment on every iteration which is baffling.
as the code in each of the character ranges is basically the same you should be able to make the code the same and use a collection of counters instead of repeating the code.
From your description, it suggests the code should be far, far simpler. Like this
// unfortunately builtin collections force you to use wrappers.
// Trove for example, does not.
final Map<String, Integer> wordCount = new HashMap<>();
public void add(String word) {
Integer count = wordCount.get(word);
if (count == null)
count = 0;
wordCount.put(word, count+1);
}
public int count(String word) {
Integer count = wordCount.get(word);
return count == null ? 0 : count.intValue();
}
public void remove(String word) {
Integer count = wordCount.get(word);
if (count == null)
return;
if (count <= 1);
wordCount.remove(word);
else
wordCount.put(word, count+1);
}
Using Trove4j by comparison
// No Integer wrappers needed.
final TObjectIntHashMap<String> wordCount = new TObjectIntHashMap<String>();
public void add(String word) {
wordCount.adjustOrPutValue(word, 1, 1);
}
public int count(String word) {
return wordCount.get(word);
}
public void remove(String word) {
int count = wordCount.adjustOrPutValue(word, 0, -1);
if (count <= 0);
wordCount.remove(word);
}

Categories

Resources