Sudoku debugging issue - java

I'm working on a program that is supposed to take as input a solved Sudoku Puzzle and return if it is a valid solution or not (true or false).
My code is written and running with a few helper methods.
The isSolution method runs through 4 different things to check if the solution is valid or not.
I've written a valid solution as input that should return true.
When I check each of these 4 elements separately, they return true, when I check them together, they return false (which is wrong)
I've spent hours testing them separately, together and in different combinations.
I've tried with different inputs.
I can't figure out why it's returning false when it should be returning true.
Any help would be amazingly appreciated! Thanks
public static void main(String[] args){
int [][] solvedPuzzle = {
{8,3,5,4,1,6,9,2,7},
{2,9,6,8,5,7,4,3,1},
{4,1,7,2,9,3,6,5,8},
{5,6,9,1,3,4,7,8,2},
{1,2,3,6,7,8,5,4,9},
{7,4,8,5,2,9,1,6,3},
{6,5,2,7,8,1,3,9,4},
{9,8,1,3,4,5,2,7,6},
{3,7,4,9,6,2,8,1,5}
};
System.out.println(isSolution(solvedPuzzle));
}
////// Checks if the input is a valid sudoku solution
/* The solvedPuzzle input is a valid solution, so this method should return true.
* Each of the elements in this method return true when tested individually, but for some reason,
* when I run them all together, the method returns false
*/
public static boolean isSolution(int [][] solvedPuzzle){
//Checks if the rows and columns have 9 ints
if (solvedPuzzle.length != 9 || solvedPuzzle[0].length !=9){
return false;
}
//Checks if every column is made up of unique entries
for (int j = 0; j < 9; j++){
if (uniqueEntries(getColumn(solvedPuzzle, j)) !=true){
System.out.println("HERE!"); //these are just here to try to figure out WHERE I've gone wrong
return false;
}
}
//Checks if every row is made up of unique entries
for (int i = 0; i < 9; i++){
if (uniqueEntries(solvedPuzzle[i]) !=true){
System.out.println("HERE!!!");
return false;
}
}
//Checks if every sub 3x3 grid is made up of unique entries
for (int x = 0; x < 9; x = x+3){
for (int y = 0; y < 9; y = y+3){
if (uniqueEntries(flatten(subGrid(solvedPuzzle, x,y,3))) != true){
System.out.println("HERE22");
return false;
}
}
}
return true;
}
///Below are the helper methods
////// Creates a smaller grid of size m starting at indexI,indexJ (x,y).
public static int [][] subGrid(int [][] original, int indexI, int indexJ, int m){
int [][] subGrid = new int [m][m];
for (int i = indexI; i < indexI+m ; i++){
for (int j = indexJ; j < indexJ+m ; j++){
subGrid [i - indexI][j - indexJ] = original[i][j];
}
}
return subGrid;
}
////// Sorts the intergers in a 1D array in asceding order
public static int [] sort(int [] originalArray){
int temp;
for(int i = 0; i < originalArray.length - 1; i++){
for(int j = 0; j < originalArray.length - 1; j++){
if(originalArray[j] > originalArray[j+1]){
temp = originalArray[j];
originalArray[j] = originalArray[j+1];
originalArray[j+1] = temp;
}
}
}
return(originalArray);
}
////// Checks if the intergers in a 1D array are all unique by first using the sort method
public static boolean uniqueEntries(int [] original){
int [] sorted = sort(original);
for (int i = 0; i < original.length-1; i++){
if (sorted[i+1] == sorted[i]) {
return false;
}
}
return true;
}
////// Takes a 2D array where each subarray is of the same size and creates a 1D array made up of the i-th element of each sub array
public static int [] getColumn(int [][] original, int indexJ){
int [] column = new int[original[0].length];
for (int i = 0; i < original[0].length; i++){
column[i] = original[i][indexJ];
}
return column;
}
////// takes a 2D array and flattens it into a 1D array
public static int [] flatten(int [][] original){
int [] flattenedArray = new int[original.length*original[0].length];
int counter = 0;
for (int i = 0; i < original.length; i++){
for(int j = 0; j < original.length; j++) {
flattenedArray[counter] = original[i][j];
counter++;
}
}
return flattenedArray;
}

if you check your puzzle before and after running //Checks if every row is made up of unique entries you will see that you are actually changing the original format of your puzzle. So the next test is not going to run over the original puzzle but a sorted one! If you add a simple loop before and after the second test you will understand what I am talking about
for (int i = 0; i < 9; i++){ //ADD THAT LOOP BEFORE AND AFTER THE TEST
for (int j = 0; j<9; j++) {
System.out.print(solvedPuzzle[i][j]);
}
System.out.println();
}
System.out.println('\n');
//Checks if every row is made up of unique entries
for (int i = 0; i < 9; i++){
if (uniqueEntries(solvedPuzzle[i]) !=true){
System.out.println("HERE!!!");
return false;
}
}
for (int i = 0; i < 9; i++){
for (int j = 0; j<9; j++) {
System.out.print(solvedPuzzle[i][j]);
}
System.out.println();
}
the code above will help you visualise what the puzzle looks before and after the test. A test should never change the format/contents/attributes of anything tested. The results of the above will be:
835416927
296857431
417293658
569134782
123678549
748529163
652781394
981345276
374962815
123456789
123456789
123456789
123456789
123456789
123456789
123456789
123456789
123456789
As you can see the original puzzle is not "original" anymore.
So as I told you on my comment, flipping the tests around will NOT actually fix the problem. Instead the bug will still be produced; but without any tests to run after it is not going to affect the CURRENT code.
Hope that helps
EDIT: I don't know if I will be online later on; so in the case that even that hint didn't help you find the bug so I am also going to give you the solution :p
The issue is that you are using the sort() method that doesn't ONLY return the array sorted BUT ALSO actually sorts the input array! SO in order to avoid that you simply need to pass in a copy of the array instead of the array itself whenever you are calling the sort method:
////// Checks if the intergers in a 1D array are all unique by first using the sort method
public static boolean uniqueEntries(int [] original){
int [] sorted = sort(original.clone()); //pass in a copy of the array
for (int i = 0; i < original.length-1; i++){
if (sorted[i+1] == sorted[i]) {
return false;
}
}
return true;
}

Related

Why are my arrays returned blank from a method but the code works fine when running in the main-Method?

I'm having following problem with my program.
It's a "connect four" Java console application.
When starting my program, I reset 3 things.
A multi-dimensional char array
public final int rows = 8, columns = 8;
public char[][] board = new char[rows][columns];
I reset it with a for-loop, overwriting every array field with the character '.', which is my default board texture.
public char[][] resetBoard() {
// for loops cycle through every array field
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
board[i][j] = '.';
}
}
return board;
}
An integer-array
public int[] nums = new int[columns];
I reset it with a for-loop using the variable i, since I just need an array with the length of columns, which just counts up from 1. It is used so the user know which column he's choosing. Like in chess "A6" e.g., except without letters.
public int[] resetNums() {
for (int i = 0; i < nums.length; i++) {
nums[i] = i + 1;
}
return nums;
}
An integer
public int roundCounter = 0;
The integers keeps track of how many rounds there have been in the current game. I want it to be printed while playing.
public int resetRoundCounter() {
// Resetting Round Counter, by initializing it to 0
return roundCounter = 0;
}
I reset these looking like this:
gameMain main = new gameMain();
gameMode mode = new gameMode();
gameCheck check = new gameCheck();
main.board = main.resetBoard();
main.nums = main.resetNums();
check.roundCounter = check.resetRoundCounter();
My problem is when printing the game board, the nums-array and the round counter none seem to work.
The game board is just completely blank. The nums-array is only 0's and the round counter stays at 0.
When running the code in the main-method it worked better than running it through classes etc.
My print method:
public void printBoard() {
gameMain main = new gameMain();
gameCheck check = new gameCheck();
// Printing number array with space in between the elements
for (int i = 0; i < main.nums.length; i++) {
System.out.print(main.nums[i] + " ");
}
// Printing the round count next to the number array
System.out.println(" Round " + check.getRoundCounter());
for (int i = 0; i < main.rows; i++) {
for (int j = 0; j < main.columns; j++) {
System.out.print(main.board[i][j] + " ");
}
System.out.println();
}
for (int i = 0; i < main.nums.length; i++) {
System.out.print(main.nums[i] + " ");
}
System.out.println("\n");
}
I could really use some help, since I've been up all night. Originally due to how much fun I was having programming this, now it has become frustrating.
Thanks for reading and thanks in advance!
I think what is happening to you is related to the references of the objects you are using. You are mixing two different ways of working, I give you an example:
You can use the reference of 'roundCounter' and work on it:
public void resetRoundCounter() {
// Resetting Round Counter, by initializing it to 0
roundCounter = 0;
}
or you can return it, like this:
public int resetRoundCounter() {
// Resetting Round Counter, by initializing it to 0
return 0;
}
In the first case, you will have to call the function like this:
resetRoundCounter(); //this function changes the value of your variable.
In the second case, you will have to call the function like this:
roundCounter = resetRoundCounter();
You can choose the way you like to work but I recomend you not working with global variables especially working with methods. I hope it helps you.
Do it as
public void resetBoard() {
// for loops cycle through every array field
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
board[i][j] = '.';
}
}
}
public void resetNums() {
for (int i = 0; i < nums.length; i++) {
nums[i] = i + 1;
}
}
public void resetRoundCounter() {
// Resetting Round Counter, by initializing it to 0
roundCounter = 0;
}
Finally, call them as follows:
gameMain main = new gameMain();
gameCheck check = new gameCheck();
main.resetBoard();
main.resetNums();
check.resetRoundCounter();
I also recommend you follow Java Naming Convention e.g. gameMain should be GameMain and gameCheck should be GameCheck.

(2D array) Java error: constant expression required

I'm doing my homework for Data Structures and I'm having trouble with 2D Array. Here's what I have to do:
"Suppose you are designing a multiplayer game that has n≥1000 players,
numbered 1 to n, interacting in an enchanted forest. The winner of this
game is the first player who can meet all the other players at least
once (ties are allowed). Assuming that there is a method meet(i, j),
which is called each time a player i meets a player j (with i ̸= j),
describe a way to keep track of the pairs of meeting players and who is the winner."
I can't compile because of this error:
Multiplayer.java:51: error: constant expression required
for this line:
case meet: sb.append("1");
I'm a beginner so I really appreciate any help. Thank you in advance!
/* Suppose you are designing a multiplayer game that has n≥1000
players, numbered 1 to n, interacting in an enchanted forest. The winner
of this game is the first player who can meet all the other players at
least once (ties are allowed). Assuming that there is a method meet(i,
j), which is called each time a player i meets a player j (with i ̸=
j), describe a way to keep track of the pairs of meeting players and
who is the winner. */
public class Multiplayer {
int n; // number of players
int map[][] = new int[n][n]; // create a 2D array
int meet = 1;
int notMeet = 0;
int[] count; // an array to keep the count, player wins when it reaches n
public Multiplayer() {
clearMap();
} // initiate a new game
public void clearMap() { // clear the 2d array
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
map[i][j] = notMeet; // clearing the map
count[i] = 0; // turn every value of count[] into 0
if (i == j)
map[i][j] = map[j][i] = meet; // when i == j give the tile the value of 1
}
}
}
public void meet(int i, int j) {
// when player i meets player j, add 1 to the count[] of each player
count[i] = count[i] + 1;
count[j] = count[j] + 1;
}
public int isWin() {
for (int i = 0; i < n; i++) {
if (count[i] == n)
return i; // player at the index i wins
}
return -1; // no player won yet
}
public String toString() {
// display the map in string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
switch (map[i][j]) {
case meet:
sb.append("1"); // if player i and j meets, put 1 in the map //this line causes error
default:
sb.append("0"); // if they haven't met, put the 0 as default
}
if (j < n - 1)
sb.append("|");
}
if (i < n - 1)
sb.append("\n-----\n");
}
return sb.toString();
}
}
class MultiplayerTest {
public static void main(String[] args) {
Multiplayer newGame = new Multiplayer();
newGame.n = 5; // test for a small number of players
// test for player 1 to meet all other players
for (int i = 2; i <= 5; i++) {
newGame.meet(1, i);
}
// print test to see if player 1 wins the game
System.out.println(newGame.toString());
System.out.println(newGame.isWin());
}
}
You can't use variables as the labels in a switch statement.
If you want to have a constant value in your program, the usual method is to create a static final member:
public static final int MEET = 1;
However, in this case if you only have two values then you are better using a boolean array and just checking for true and false. There is no need for a switch statement.
boolean map[][] = new boolean[n][n];
...
if (map[i][j]) {
...
In this case, it is better to rename the array met, so you code reads like this:
if (met[i][j]) {
...
You need to initialize your count array, like
public void initializeArray(int n) {
this.n = n;
count = new int[n];
for (int i = 0; i < n; i++) count[i] = 0;
}
and then, instead of
newGame.n = 5;
you will need to do:
initializeArray(5);
I can't see where you actually create the array count.
Your code:
boolean met[][] = new boolean[n][n]; //edited
int[] count; // an array to keep the count, player wins when it reaches n
creates the array met (... = new boolean[n][n]), but there is no such statement for the array count. Hence, references to count[i] fail.
So I fixed the code like you guys suggested. Thank you all so much! This code below still has an error, but it's a lot better than my original one. Anyone knows about ArraysIndexOutOfBound error?
import java.util.Arrays;
public class Multiplayer {
int n; //number of players
boolean met[][] = new boolean [n][n];
int[] count; //an array to keep the count, player wins when it reaches n
public Multiplayer() {clearMap(); } //initiate a new game
public void clearMap() {
for (int i = 0; i < n; i ++) {
for (int j = 0; j < n; j++) {
met [i][j] = false; //clearing the map
count [i] = 0; //turn every value of count[] into 0
if (i == j)
met[i][j] = met[j][i] = true;
}
}
}
public int[] meet(int i, int j){
//when player i meets player j, add 1 to the count[] of each player
if (i != j) {
count [i] = count[i] + 1;
count [j] = count [j] + 1;
met [i][j] = met[j][i] = true;
}
//System.out.println(Arrays.toString(count));
return count;
}
public void initializeArray(int n) {
this.n = n;
count = new int[n];
for (int i = 0; i < n; i++) count[i] = 0;
}
public int isWin () {
for (int i = 0; i < n ; i++){
if (count[i] == n-1) //if player i meets all the other players
return i; //player at the index i wins
}
System.out.println(Arrays.toString(count));
return -1;
}
public String toString() {
//display the map
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
for (int j = 0; j <n; j++) {
if (met [i][j]) {sb.append("true");} //this line causes error ArrayIndexOutofBound
else {sb.append("false");}
if (j<n-1) sb.append ("|");
}
if (i<n-1) sb.append("\n-----\n");
}
return sb.toString();
}
}
class MultiplayerTest {
public static void main (String[] args) {
Multiplayer newGame = new Multiplayer ();
newGame.initializeArray(5); //test for a small number of players
//test for player 1 to meet all other players
for (int k = 0; k < 5; k++) {newGame.meet (1,k); }
//print test to see if player 1 wins the game
System.out.println(newGame.isWin());
//System.out.println(newGame.toString()); I tried printing the 2D array output into String but encountered an error and don't know how to fix it, but the other methods are fine.
}
}
In the below snippet:
switch (map[i][j]) {
case meet:
sb.append("1"); // if player i and j meets, put 1 in the map //this line causes error
default:
sb.append("0"); // if they haven't met, put the 0 as default
}
Please note that there is no break; statement and hence, as per fall through logic, it will append 0 anyway.
If you just have one case, you should rather use if, e.g.:
if(map[i][j] == meet) {
sb.append("1");
}else {
sb.append("0");
}
update
Regarding the NullPointerException, you are getting that exception because count array is not initialised and you are trying to access the element.
Change the declaration to the following:
int[] count = new int[n];
The 'constant expression required' suggests that the labels in switch case requires a constant. And as suggested by other answers, its better to use if and use boolean 2d array.
ArraysIndexOutOfBound error is actually due to because you need to create an array using the new operator in the constructor method and then pass the reference to
map asmap = new boolean[n][n];
I've tried here:
public class Multiplayer {
int n; //number of players
boolean[][] map; //not initializing here but in constructor
int[] count; //an array to keep the count, player wins when it reaches n
public Multiplayer(int num){
n=num;
map = new boolean[n][n];
count = new int[n];
//No need to use clearMap as all instance variables are assigned the default value of 0 or false or null;
for(int i=0;i<n;i++){ //self-meeting
count[i]=1;
map[i][i]=true;
}
}
public void meet(int i,int j){
if(i==j) return;
//player number 1 is at index number 0
//Hence player i is at index number i-1
i--;j--;
count[i]+=1;
count[j]+=1;
map[i][j]=map[j][i]=true;
}
public int isWin(){
for(int i =0;i<n;i++)
if(count[i]==n)
return i; // player at the index i wins
return -1; // no player won yet
}
public String toString(){
String s = "";
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(map[i][j]) s+="1";
else s+="0";
if(j<n-1) s+="|";
}
s+="\n";
for(int k=0;k<n && i<n-1;k++)
s+="--";
s+="\n";
}
return s;
}
}
public class MultiplayerTest {
public static void main(String[] args) {
int numberOfPlayers = 5;
Multiplayer newGame = new Multiplayer(numberOfPlayers);
// test for player 1 to meet all other players
for (int i = 2; i <=5; i++) {
newGame.meet(1, i);
}
// print test to see if player 1 wins the game
System.out.println(newGame.toString());
System.out.println(newGame.isWin());
}
}

JAVA Need help involving matrices and arrays

I'm working on a test prep program. Its not homework or for a grade, I just need help finishing and fixing it so I can study and better understand how it works. The directions are "Write a program named Matrix1.java that randonly fills in 0s and 1s into an n-by-n matrix, prints the matrix." I'm still pretty new to coding so any help would be greatly appreciated. This is the code I have so far:
public class Matrix1{
public static void main(String[] args){
Matrix1 matrix=new Matrix1(5);
matrix.fill();
matrix.print();
}
public Matrix1(int n){
int[][] matrix = new int[n][n];
}
public void fill(int n){ // randomly fill in 0s and 1s
Random rand = new Random();
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
Integer r = rand.nextInt;
matrix[i][j] = Math.abs(r);
}
}
}
public void print(int[][]matrix, int n){ //print the matrix, each row is printed in a separate line
for(int i = 0; i< n; i++){
for(int j = 0; j<n; j++){
System.out.println(array[i][j]);
}
}
}
}
I ended up confusing myself and I'm not sure how to fix it or continue. I think I'm partially on the right track though.
Your code after fixes.
import java.util.Random;
public class Matrix1 {
private final int[][] matrix;
private final int n;
public Matrix1(int n) {
this.n = n;
this.matrix = new int[n][n];
}
/**
* randomly fill in 0s and 1s
*/
public void fill() {
Random rand = new Random();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = rand.nextInt(2);
}
}
}
/**
* print the matrix, each row is printed in a separate line
*/
public void print() {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.print(matrix[i][j]);
}
System.out.println();
}
}
public static void main(String[] args) {
Matrix1 matrix = new Matrix1(5);
matrix.fill();
matrix.print();
}
}
So changes I've made:
I've changed "matrix" and "n" variables into class fields, so you don't have to pass them through class methods
filling array - it should be just 0/1 not any integer so you can use rand.nextInt(2) with bounds - it gives values less then 2
printing array - you have to print row in one line, then change line
It looks like the right direction, check your main method to set the necessary parameters (size, array and size).
Also set the Random object to only be 0 or 1 (Check the Java class libraries for the answer) I believe you can set a parameter inside the Random.nextInt method.
Also if its required to print it like a double array, change up your printing logic since you are always writing to a new line
Well, I see a few problems, which if fixed might help get you on the right track.
First of all, for the random integer, you'll probably want to use the method from this answer:
import java.util.concurrent.ThreadLocalRandom;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
ThreadLocalRandom.current().nextInt(min, max + 1);
I don't think you need to use Math.abs in this case, as long as you call ThreadLocalRandom.current().nextInt(0, 2).
Second, there are a couple of problems with your printing code. First of all, you should be using matrix[i][j] instead of array[i][j]. Second, you'll want to use System.out.print instead of System.out.println.
It should be something like this:
for(int i = 0; i< n; i++){
for(int j = 0; j<n; j++){
System.out.print(matrix[i][j]);
}
System.out.println();
}
public class Matrix1{
public static void main(String[] args){
Matrix1 matrix = new Matrix1(5);
matrix.fill();
matrix.print();
}
private int[][] m; //it is easier use a global variable
public Matrix1(int n){
m = new int[n][n];
}
public void fill(){ // randomly fill in 0s and 1s
for(int i = 0; i < m.length; i++){
for(int j = 0; j < m.length; j++){
if (Math.random() > 0.5) {
m[i][j] = 1;
} else {
m[i][j] = 0;
}
}
}
}
public void print(){ //print the matrix, each row is printed in a separate line
for(int i = 0; i< m.length; i++){
for(int j = 0; j<m.length; j++){
System.out.print(m[i][j]); //only use print() for the same row
}
System.out.println("");
}
}
}

2-D Array (row and column)

The program below (thanks to Sundial) computes the area of a rectangle
public class ComputeTheArea {
public static int areaOfTheRectangle (char[][] table, char ch) {
int[] first = new int[2];
int[] last = new int[2];
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
if(grid[i][j]==ch) {
first[0] = i;
first[1] = j;
}
}
}
for (int i=2; i>=0; i--) {
for (int j=3; j>=0; j--) {
if(grid[i][j]==ch) {
last[0] = i;
last[1] = j;
}
}
}
int answer = ((Math.max(first[0]+1,last[0]+1) - Math.min(first[0]+1,last[0]+1)) *
(Math.max(first[1]+1,last[1]+1) - Math.min(first[1]+1,last[1]+1)));
return answer;
}
However, when it is run, it outputs the wrong answer. I know there is something wrong with the for loop. I'm new in Java and I need your help for me to fix the method. Please and thank you very much!
EDIT: I edited the code to conform to Michael's answer.
First of all, you don't search all the elements in the matrix with your first loop.
Secondly, you don't break when you found a match.
Also, this approach is a bit flawed. For example, see this matrix:
a b c b
a _ c d
x z b a
Here you wouldn't know which b to stop at at the first row to get the entire b square.
If you instead just loop through the entire matrix once and saves the maximum and minimum (first and last) x and y coordinates, the area can be calculated very easily. See this code:
public static int charArea (char[][] grid, char ch) {
int[] first = new int[] {100, 100};
int[] last = new int[] {-1, -1};
for (int i=0; i<3; i++) {
for (int j=0; j<4; j++) {
if(grid[i][j]==ch) {
first[0] = Math.min(i, first[0]);
first[1] = Math.min(j, first[1]);
last[0] = Math.max(i, last[0]);
last[1] = Math.max(j, last[1]);
}
}
}
int answer = (last[0] - first[0] + 1) * (last[1] - first[1] + 1);
return answer;
}
The for loops should probably break once they find the character.
The first for loop sets j=i. That should probably be j=0 instead.
I don't think the length calculation is correct. A 1 should be added to both terms. I.e. the length of something with first=0 and last=3 should be last+1-first=4, not 3 as it would be now.

Find the mode (most frequent value in an array) using a simple for loop?

How do I find the mode (most frequent value in an array) using a simple for loop?
The code compiles with a wrong output.
Here is what I have:
public static void mode(double [] arr)
{
double mode=arr[0];
for(int i = 1; i<arr.length; i++)
{
if(mode==arr[i])
{
mode++;
}
}
return mode;
}
First I sort the array by order and then I count occurrences of one number. No hashmaps only for loop and if statements.
My code:
static int Mode(int[] n){
int t = 0;
for(int i=0; i<n.length; i++){
for(int j=1; j<n.length-i; j++){
if(n[j-1] > n[j]){
t = n[j-1];
n[j-1] = n[j];
n[j] = t;
}
}
}
int mode = n[0];
int temp = 1;
int temp2 = 1;
for(int i=1;i<n.length;i++){
if(n[i-1] == n[i]){
temp++;
}
else {
temp = 1;
}
if(temp >= temp2){
mode = n[i];
temp2 = temp;
}
}
return mode;
}
-Just use a HashMap which contains the array index values as the keys and their occurrence numbers as the values.
-Update the HashMap as you traverse the for loop by checking to see if the current index already exists in the HashMap. IF IT DOES then find that double in the hash map and see how many times it has already occurred and put it back in the HashMap with one more occurrence.
-I did it in Java because that's what it looks like you are using. What's also good is that the time complexity is O(n) which is the best you could possibly get for this type of scenario because you have to visit every element at least once.
-So if you have an array like this of doubles: { 1,2,3,1,1,1,5,5,5,7,7,7,7,7,7,7,7,7}
Then the hash map will look something like this at the end: { 1->4, 2->1, 3->1, 5->3, 7->9 }
Meaning that "1 occurred 4 times, 2 occured 1 time .... 7 occurred 9 times" etc.
public static double mode(double [] arr)
{
HashMap arrayVals = new HashMap();
int maxOccurences = 1;
double mode = arr[0];
for(int i = 0; i<arr.length; i++)
{
double currentIndexVal = arr[i];
if(arrayVals.containsKey(currentIndexVal)){
int currentOccurencesNum = (Integer) arrayVals.get(currentIndexVal);
currentOccurencesNum++;
arrayVals.put(currentIndexVal, currentOccurencesNum );
if(currentOccurencesNum >= maxOccurences)
{
mode = currentIndexVal;
maxOccurences = currentOccurencesNum;
}
}
else{
arrayVals.put(arr[i], 1);
}
}
return mode;
}
This code is a different way that does not use hashmaps. This method, created in java, takes an array as the parameter and creates another array called "numberCount" within the method. This array "numberCount" will set its index to the value in the array. The index of "numberCount"that contains the value in the array passed will add 1 to the value of "numberCount" ("++numberCount[array[i]]") then will go to the next value in the array (repeat until the end of the array). Then creates another for loop to go through each value of the array in "numberCount", which ever index has the highest value/count will be stored and return as "max." This method will have to undergo some difficult changes to use a double array. but seems to work great with an int array.
public static int findMostFrequentValue(int[] array) {
int i;
int[] numberCount = new int[100];
for (i = 0; i < array.length; i++)++numberCount[array[i]];
int max = 0;
int j;
for (j = 0; j < numberCount.length; j++) {
if (numberCount[j] > max) max = j;
}
return max;
}
You should check the number of occurances of every element in your array. You can do it by comparing every element of array with herself and others via 2 inner for loops.
Remember, if the array is not sorted and contains more then 1 modal value (thus repeating number of occurances) this will return the first one. It maybe wise to order the array first by Arrays.sort(array) so that you can pick the smallest or biggest modal value.
public static int modeOfArray(int[] array){
int mode;
int maxOccurance = 0;
for(int i=0; i<array.length; i++){
int occuranceOfThisValue = 0;
for(int j=0; j<array.length; j++){
if(array[i] == array[j])
occuranceOfThisValue++;
}
if(occuranceOfThisValue > maxOccurance){
maxOccurance = occuranceOfThisValue;
mode = array[i];
}
}
return mode;
}

Categories

Resources