Java Algorithm - Merge Sorting with ArrayLists - java

I'm an AP Computer Science student and my current assignment is that I have to make a program that takes an ArrayList of numbers and, only using the standard Java API, sort it using a Merge Sort. There aren't any compiling errors, but on run-time it doesn't even return the ArrayList! After a little debugging I found that it isn't populating the original list. Please help! Code:
import java.io.*;
import java.util.*;
public class MergeSort {
public static void main(String[] args) throws IOException{
Scanner in = new Scanner(System.in);
Random r = new Random();
int size, largestInt, holder;
System.out.println("How many integers would you like me to create?");
size = in.nextInt();
ArrayList<Integer>list = new ArrayList<Integer>(size);
System.out.println("What would the largest integer be?");
largestInt = in.nextInt();
for(int i = 0; i < list.size(); i++){
holder = r.nextInt(largestInt + 1);
list.add(holder);
}
mergeSort(list);
for (int j = 0; j < list.size(); j++) {
if(j == 19 || j == 39 || j == 59 || j == 79 || j == 99 || j == 119 || j == 139 || j == 159 || j == 179 || j == 199){
System.out.print(list.get(j));
System.out.println();
}
else{
System.out.println(list.get(j) + "\t");
}
}
}
static void mergeSort(ArrayList<Integer> list) {
if (list.size() > 1) {
int q = list.size()/2;
ArrayList<Integer> leftList = new ArrayList<Integer>();
for(int i = 0; i > 0 && i <= q; i++){
leftList.add(list.get(i));
}
ArrayList<Integer> rightList = new ArrayList<Integer>();
for(int j = 0; j > q && j < list.size(); j++){
rightList.add(list.get(j));
}
mergeSort(leftList);
mergeSort(rightList);
merge(list,leftList,rightList);
}
}
static void merge(ArrayList<Integer> a, ArrayList<Integer> l, ArrayList<Integer> r) {
int totElem = l.size() + r.size();
int i,li,ri;
i = li = ri = 0;
while ( i < totElem) {
if ((li < l.size()) && (ri<r.size())) {
if (l.get(li) < r.get(ri)) {
a.set(i, l.get(li));
i++;
li++;
}
else {
a.set(i, r.get(ri));
i++;
ri++;
}
}
else {
if (li >= l.size()) {
while (ri < r.size()) {
a.set(i, r.get(ri));
i++;
ri++;
}
}
if (ri >= r.size()) {
while (li < l.size()) {
a.set(i, l.get(li));
li++;
i++;
}
}
}
}
}

This is because list.size() returns 0 for an empty list. In your loop where you populate the list, replace list.size() with size.
I haven't checked the actual mergeSort part of your program, but the change that I suggested will at least make the initial population of the list work.

Related

Array program not running correctly. How do I fix it?

Trying to write a program that asks the a user for 10 integers as input. The program
places the even integers into an array called evenList, the odd integers into
an array called oddList, and the negative numbers into an array called
negativeList. The program displays the contents of the three arrays after
all of the integers have been entered.
This is my code:
import java.util.Scanner;
public class Main
{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int countNeg = 0;
int countOdd = 0;
int countEven = 0;
int[] list = new int[10];
System.out.println("Please enter 10 integers:");
for(int i = 0; i < list.length; i++)
{
list[i] = scan.nextInt();
if(list[i] < 0)
{
countNeg++;
}
if(list[i] % 2 == 0 && list[i] > 0)
{
countEven++;
}
if(list[i] % 2 == 1 && list[i] > 0)
{
countOdd++;
}
}
int[] oddList = new int[countOdd];
int[] evenList = new int[countEven];
int[] negativeList = new int[countNeg];
for(int i = 0; i < list.length; i++)
{
if(list[i] < 0)
{
for(int j = 0; j < countNeg; j++)
{
negativeList[j] = list[i];
}
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 0 && list[i] > 0)
{
for(int j = 0; j < countEven; j++)
{
evenList[j] = list[i];
}
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 1 && list[i] > 0)
{
for(int j = 0; j < countOdd; j++)
{
oddList[j] = list[i];
}
}
}
for (int i : negativeList)
{
System.out.print(i + " ");
}
System.out.println();
for (int i : evenList)
{
System.out.print(i + " ");
}
System.out.println();
for (int i : oddList)
{
System.out.print(i + " ");
}
}
}
The program prints the Arrays with the correct amount of values but the wrong numbers. It prints only the last negative, even, or odd number to be input. ex input is 1, 2, 3, 4, 5, 6, -1, -2, -3, -4. For negativeList it prints -4 -4 -4 -4. Im guessing something is wrong in the loops after the arrays are created. Please help!!
you can very much simplify your code with using ArrayList instead of array. For example:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int length = 10;
System.out.println("Please enter 10 integers:");
List<Integer> oddList = new ArrayList<>();
List<Integer> evenList = new ArrayList<>();
List<Integer> negativeList = new ArrayList<>();
for (int i = 0; i < length; i++) {
int n = scan.nextInt();
if (n < 0) {
negativeList.add(n);
} else if (n % 2 == 0) {
evenList.add(n);
} else {
oddList.add(n);
}
}
for (int i : negativeList) {
System.out.print(i + " ");
}
System.out.println();
for (int i : evenList) {
System.out.print(i + " ");
}
System.out.println();
for (int i : oddList) {
System.out.print(i + " ");
}
}
there are a few issues with the code you provided.
First, in the for loops that initialize the negativeList, evenList, and oddList arrays, you are overwriting the values at each iteration. This means that the final arrays will only contain the last value that was assigned to them. To fix this, you can use a counter variable to keep track of the next index to be filled in each array, like this:
int negCounter = 0;
int evenCounter = 0;
int oddCounter = 0;
for(int i = 0; i < list.length; i++)
{
if(list[i] < 0)
{
negativeList[negCounter] = list[i];
negCounter++;
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 0 && list[i] > 0)
{
evenList[evenCounter] = list[i];
evenCounter++;
}
}
for(int i = 0; i < list.length; i++)
{
if(list[i] % 2 == 1 && list[i] > 0)
{
oddList[oddCounter] = list[i];
oddCounter++;
}
}
Second, you are not checking if the input values are integers. If the user enters a non-integer value, the program will throw an exception. You can add a check to make sure that the input is an integer like this:
if(scan.hasNextInt())
{
list[i] = scan.nextInt();
// ... rest of the code
}
else
{
System.out.println("Please enter an integer.");
// If the input is not an integer, discard it and move to the next
input
scan.next();
}

How to find common numbers or an anomaly in a 2D array and cause it to trigger something else

I have a 2D array (a matrix of 10x10) with values ranging from 0 to -5.
I want a method to be triggered when there is a sequence of a value found within the array.
For example, there is a sequence of two negative 2. I want it to trigger an event/method that will give a bonus score of 4. This should happen only when there are two -2's and not if there is just one -2.
I tried achieving something like that but I cant figure out how to tell the program to only trigger when 'n' number of a value is found within the matrix.
public class Test {
static int board[][] = new int[10][10];
public static void Test() {
int i, j;
board[0][0] = -1;
board[0][1] = -1;
board[1][1] = -2;
board[1][2] = -2;
board[1][3] = -2;
board[1][4] = -2;
for (i = 0; i < board.length; i++) {
System.out.println("");
for (j = 0; j < board.length; j++) {
//board[i][j] = 0;
System.out.print(board[i][j]);
}
}
System.out.println();
}
public static void scanBoard() {
int i, j;
for (i = 0; i < board.length; i++) {
for (j = 0; j < board.length; j++) {
if (board[i][j] == -1) {
System.out.println("Hello");
}
}
}
}
public static void main(String[] args) {
Test(); //prints out whole array
scanBoard(); //scans for
}
}
public class Main {
static final int size = 10;
static int[][] matrix = new int[size][size];
public static void main(String[] args) {
System.out.println("The first matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 3 && j > 3) {
matrix[i][j] = -2; //-2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
System.out.println("\nThe second matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 9 && j > 5) {
matrix[i][j] = 2; //changed it from -2 to 2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
}
static void scanBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (matrix[i][j] == -2 && (j + 3 < size)) {
if (matrix[i][j + 1] == -2 && matrix[i][j + 2] == -2 && matrix[i][j + 3] == -2) {
System.out.println("\nThere you go, a special effect!".toUpperCase());
}
}
}
}
}
}
I am not sure if this is the result you wished to see according to your request. I hope this helps you. And I did some changes in your code so it will be easier to read (In my opinion lol).
public class Main {
static final int size = 10;
static int[][] matrix = new int[size][size];
public static void main(String[] args) {
System.out.println("The first matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 9 && (j == 0 || j == 1)) {
matrix[i][j] = -2; //-2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
System.out.println("\nThe second matrix.\n");
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (i == 8 && (j == 5 || j == 6)) {
matrix[i][j] = 2; //changed it from -2 to 2
} else {
matrix[i][j] = 1;
}
System.out.print(matrix[i][j]);
}
System.out.println();
}
scanBoard();
}
static void scanBoard() {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if (matrix[i][j] == -2 && (j + 1 < size)) {
if (matrix[i][j + 1] == -2) {
//You can remove the '.toUpperCase()', it's just my personal preference
System.out.println("\nThere you go, a special effect!".toUpperCase());
}
}
}
}
}
}
From what I understood from the problem statement and comments, you want your scanBoard to behave like this:
public static void scanBoard(int value, int frequency) {
int i, j;
if (value <= 0 && value >= -5 && frequency >= 2 && frequency <= 10) {
for (i = 0; i < board.length; i++) {
int rowFrequency = 0;
for (j = 1; j < board.length; j++) {
if (board[i][j] == value && board[i][j - 1] == value) {
rowFrequency++;
} else {
rowFrequency = 0;
}
if (rowFrequency + 1 >= frequency) {
System.out.println("Hello");
}
}
}
}
}
public static void main(String[] args) {
Test(); //prints out whole array
scanBoard(-2, 4); //prints Hello once
scanBoard(-2, 3); //prints Hello twice
scanBoard(-2, 3); //prints Hello thrice
}

The numbers never occur next to each other

I wrote a program that reads an array of integers and two numbers n and m. The program check that n and m never occur next to each other (in any order) in the array.
import java.util.*;
class Main {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner (System.in);
int len = scanner.nextInt();
int [] array = new int [len];
boolean broken = false;
for (int i = 0; i < len; i++){
array [i] = scanner.nextInt();
}
int n = scanner.nextInt();
int m = scanner.nextInt();
for (int j = 1; j < len; j++){
if((array[j]==n)&&(array[j+1]==m) || (array[j]==n)&&(array[j-1]==m) || (array[j]==m)&&(array[j+1]==n) || (array[j]==m)&&(array[j-1]==n)){
broken = true;
break;
}
}
System.out.println(broken);
}
}
Test input:
3
1 2 3
3 4
Correct output: true
My output is blank. What am I doing wrong?
Your code will throw ArrayIndexOutOfBoundsException as you are using array[j+1] whereas you have loop condition as j < len. The condition should be j < len -1.
The following works as expected:
for (int j = 1; j < len - 1; j++) {
if ((array[j] == n && array[j + 1] == m) || (array[j] == n && array[j - 1] == m)
|| (array[j] == m && array[j + 1] == n) || (array[j] == m && array[j - 1] == n)) {
broken = true;
break;
}
}
A sample run:
3
1 2 3
3 4
true
Your code will throw ArrayIndexOutOfBoundsException because of array[j+1] where j can be len-1. Actually you don't need to check both sides(previous and next element), checking combination with previous is enough since in the next iteration combination with next element will be checked.
for (int j = 1; j < len; j++){
if((array[j]==n && array[j-1]==m) || (array[j]==m && array[j-1]==n)){
broken = true;
break;
}
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int len = scan.nextInt();
Map<Integer, Set<Integer>> map = new HashMap<>();
for (int i = 0, prv = 0; i < len; i++) {
int num = scan.nextInt();
if (!map.containsKey(num))
map.put(num, new HashSet<>());
if (i > 0)
map.get(prv).add(num);
prv = num;
}
int n = scan.nextInt();
int m = scan.nextInt();
boolean res = !map.containsKey(n) || !map.containsKey(m) || !map.get(n).contains(m) && !map.get(m).contains(n);
System.out.println(res);
}

Combine 2 2D arrays that both contain chars with java

I have to write a code as a task for my university and we have to recreate Minesweeper with java and it has to be runned in the command line.
For the matchfield we have to make an array that looks in the end like this picture:
Example how it sould look in the end
And to choose the field we have to use the scanner.
For example if you want to chose field C3, you have to type into the scanner C3.
At the moment im struggleing a little bit with the field.
I had 2 ideas but both didn't work out very well.
in the first try i tried to create everything with 2 for loops and 1 array but my problem was that I couldn't add 2 charrs, so I had the chars 0 to 9 and the charrs A to J.
In the second try I created 3 array, one with the numbers 0 to 9 and anothe array A to J and in the third array i wanted to combine both arrays. And now I'm wondering if this it's possible if I can acctually combine them in the way I want and if it's possible could somebody give me some help?
import java.util.Scanner;
import java.util.Arrays;
public class Minesweeper {
public static void main (String[] args) {
char c = 'A';
char d = '0';
char e = '9';
char f = 'J';
char[][] feldz = new char[11][11];
char[][] feldb = new char[11][11];
char[][] feld = new char[11][11];
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (i == 0 && j == 0) {
feldz[i][j] = ' ';
System.out.print(feldz[i][j] + " |");
}
if (d > e) {
d = '0';
}
if (d <= e && i > 0){
feldz[i][j] = d;
System.out.print(feldz[i][j] + " |");
}
if (i > 0 && j == 10) {
d++;
}
}
System.out.println("");
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (i == 0 && j == 0) {
feldb[i][j] = ' ';
System.out.print(feldb[i][j] + " |");
}
if (i > 0 && j == 0){
feldb[i][j] = ' ';
System.out.print(feldb[i][j] + " |");
}
if (c > f) {
c = 'A';
}
if(c <= f && j > 0){
feldb[i][j] = c;
System.out.print(feldb[i][j] + " |");
c++;
}
if (j == 10){
System.out.println("");
}
}
}
}
}
You don't actually need array to print the maze , nested loops is enough for that. 2d Array is only required to store the input. Please try the below code:
int size = 10;
int [][] maze = new int[size][size];
while (true){
System.out.print(' ');
for (int i = 0; i < size; i++) {
System.out.print('|');
System.out.print((char) ('A' + i));
}
for (int i = 0; i < size; i++) {
System.out.println("");
System.out.print(i);
for (int j = 0; j < size; j++) {
System.out.print('|');
if(maze[i][j] > 0) {
System.out.print(maze[i][j]);
} else {
System.out.print(' ');
}
}
}
int row = -1;
int col = -1;
System.out.println("\nEnter CoOrdinates");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
if(input.length() == 2) {
char charAt = input.charAt(0);
if(charAt >= 'A' && charAt <= 'A'+size-1) {
col = charAt-'A';
}
charAt = input.charAt(1);
if(charAt >= '0' && charAt <= '0'+size-1) {
row = charAt-'0';
}
if(row != -1 && col != -1) {
System.out.println("Enter Action");
input = scanner.nextLine();
int action = Integer.parseInt(input);
maze[row][col] = action;
} else {
System.out.println("Incorrect Input");
}
}
}

Two-dimensional array selection sort

I am taking a Java class at school. Java looks simple but complicated for me.
I am having a trouble with sorting a two-dimensional array. Please Please Please help me.
Here is what I coded. I don't know why it doesn't work.
public static void selectionSort(int[][] list) {
for (int k = 0; k < list.length;k++){
for (int i = 0; i < list[k].length;i++) {
int currentMin = list[k][i];
int currentMinIndexRow = k;
int currentMinIndexColumn = i;
if (k == 3 && i == 3) continue;
for (int m = k; m < list.length; m++) {
for (int j = i; j < list[k].length; j++) {
if (m == k && i == j) continue;
if (currentMin > list[m][j]) {
currentMin = list[m][j];
currentMinIndexRow = m;
currentMinIndexColumn = j;
}
}
}
if (currentMinIndexRow != k && currentMinIndexColumn != i) {
list[currentMinIndexRow][currentMinIndexColumn] = list[k][i];
list[k][i] = currentMin;
}
}
}
}
Thank you so much guys!!!!!
I am trying to write a program that prompts the user to enter two lists of integers and displays whether the two are identical.
Such as,
"Enter list1: 51 25 22 6 1 4 24 54 6
Enter list2: 51 22 25 6 1 4 24 54 6
The two arrays are identical
Enter list1: 51 5 22 6 1 4 24 54 6
Enter list2: 51 22 25 6 1 4 24 54 6
The two arrays are not identical
Here is what I wrote.
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
int[][] list1 = new int[3][3];
int[][] list2 = new int[3][3];
System.out.print("Enter list1: ");
for (int row=0 ;row < list1.length ;row++){
for (int column=0;column<list1[row].length; column++){
list1[row][column] = input.nextInt();
}
}
System.out.print("Enter list2: ");
for (int row=0 ;row < list2.length ;row++){
for (int column=0;column<list2[row].length; column++){
list2[row][column] = input.nextInt();
}
}
selectionSort(list1);
selectionSort(list2);
if (equals(list1, list2) == true)
System.out.println("The two arrays are identical");
else
System.out.println("The two arrays are not identical");
}// void main
public static boolean equals(int[][] m1, int[][] m2){
boolean result = true;
for (int row=0 ;row < m1.length ;row++){
for (int column=0 ;column<m1[row].length ; column++){
if (m1[row][column] != m2[row][column]) {result = false; break;}
}
}
return result;
}// boolean equals
public static void selectionSort(int[][] list) {
for(int k = 0; k < list.length;k++){
for(int i = 0; i < list[k].length;i++) {
int currentMin = list[k][i];
int currentMinIndexRow = k;
int currentMinIndexColumn = i;
if(k == 3 && i == 3) continue;
for(int m = k; m < list.length; m++){
for (int j = i; j < list[k].length; j++) {
if (m == k && i == j) continue;
if (currentMin > list[m][j]) {
currentMin = list[m][j];
currentMinIndexRow = m;
currentMinIndexColumn = j;
}
}
}
if (currentMinIndexRow != k && currentMinIndexColumn != i) {
list[currentMinIndexRow][currentMinIndexColumn] = list[k][i];
list[k][i] = currentMin;
}
}
}
}
Thank you for your comments.
Thank you so much guys!!!!
I figured out why I was wrong.
There was a really really really simple error.
if (currentMinIndexRow != k || currentMinIndexColumn != i) {
list[currentMinIndexRow][currentMinIndexColumn] = list[k][i];
list[k][i] = currentMin;
}
The above code is what I corrected. Thank you.

Categories

Resources