How to fix my merge sort? - java

When I compile my merge sort, it compiles fines but there is no output.
This needs to be done recursively. Also, I do run my printList() function in my main, so it isn't that I am forgetting to print the list. I've been staring at this for the past 30 minutes.
public void printList(){
for(int i = 0; i < fullNames.size(); i++){
System.out.println(fullNames.get(i));
}
}
public void sort(){
fullNames = mergeSort(fullNames);
}
public ArrayList<String> extract(ArrayList<String> ex, int low, int high){
ArrayList<String> answer = new ArrayList<String>();
for(int i = low; i <= high; i++){
answer.add(ex.get(i));
}
return answer;
}
public ArrayList<String> merge(ArrayList<String> first, ArrayList<String> second){
int f = 0;
int s = 0;
ArrayList<String> answer = new ArrayList<String>();
while(first.size() > 0 || second.size() > 0){
if(s != second.size() && f != first.size()){
if(first.get(f).compareTo(second.get(s)) > 0){
answer.add(second.get(s));
s++;
}
else if(first.get(f).compareTo(second.get(s)) < 0){
answer.add(first.get(f));
f++;
}
}
else if(f == first.size()){
while(s != second.size()){
answer.add(second.get(s));
s++;
}
}
else{
while(f != first.size()){
answer.add(first.get(f));
f++;
}
}
}
return answer;
}
public ArrayList<String> mergeSort(ArrayList<String> names){
int k = names.size()-1;
if(k > 1){
ArrayList<String> first = extract(names, 0, k / 2);
ArrayList<String> second = extract(names, (k / 2) + 1, k);
mergeSort(first);
mergeSort(second);
return merge(first, second);
}
else{
return names;
}
}

The while condition in your merge will never be false because the size of first and second is never adjusted within the loop:
while(first.size() > 0 || second.size() > 0){
if(s != second.size() && f != first.size()){
if(first.get(f).compareTo(second.get(s)) > 0){
answer.add(second.get(s));
s++;
}
else if(first.get(f).compareTo(second.get(s)) < 0){
answer.add(first.get(f));
f++;
}
}
else if(f == first.size()){
while(s != second.size()){
answer.add(second.get(s));
s++;
}
}
else{
while(f != first.size()){
answer.add(first.get(f));
f++;
}
}
}

Related

Does not print out the last number for array using for loops

The result gives me this but does not print out the last int (200). I add some random numbers in the main method and the by using the for loops it puts them in order. However, it completely ignores the last (greatest) integer, which is 200. How can I fix this?
0: 13
1: 21
2: 25
3: 44
4: 50
5: 63
6: 88
7: 99
8: 100
Here is the main method where I add random integers.
public static void main(String[] args) {
SortedIntList myList = new SortedIntList(10);
myList.add(100);
myList.add(50);
myList.add(200); // Does not print this line
myList.add(25);
myList.add(13);
myList.add(63);
myList.add(21);
myList.add(99);
myList.add(88);
myList.add(44);
System.out.println(myList);
}
}
Here is the for loop method to print all the integers sorted in order from least to greatest. It sets them in order just fine, it just does not add 200 for some reason.
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
if (numElements == 0) {
list[numElements] = value;
numElements++;
} else {
int oldValue = 0;
boolean flag = false;
for (int i = 0; i < numElements; i++) {
if (value < list[i] && !flag) {
oldValue = list[i];
list[i] = value;
flag = true;
if (numElements + 1 != list.length) {
numElements++;
}
} else if (flag) {
int temp = list[i];
list[i] = oldValue;
oldValue = temp;
if (i == list.length - 1) {
list[i + 1] = temp;
numElements++;
break;
}
if (temp == 0) {
break;
}
if (numElements + 1 != list.length) {
numElements++;
}
}
else if (i == numElements - 1) {
list[numElements] = value;
if (numElements + 1 != list.length) {
numElements++;
break;
}
}
}
}
}
}
This is what the toString method looks like
public String toString()
{
String returnString = "";
for (int i = 0; i < numElements; i++) {
returnString += i + ": " + list[i] + "\n";
}
return returnString;
}
I had a closer look at your add implementation and found it is faaar to complicated for what you want to achieve. I
removed a lot of code
renamed your flag variable
changed the loop upper limit from < to <= since your list should grow by one
changed the last else if
simplified the numElements++ which should really happen at once place, everything else is / was a big code smell already
to end up with
public void add(int value) {
if (numElements == list.length) {
System.out.println("Can't add, list is full");
} else {
if (numElements == 0) {
list[numElements] = value;
} else {
int oldValue = 0;
boolean moveUpward = false;
for (int i = 0; i <= numElements; i++) {
if (value < list[i] && !moveUpward) {
oldValue = list[i];
list[i] = value;
moveUpward = true;
} else if (moveUpward) {
int temp = list[i];
list[i] = oldValue;
oldValue = temp;
} else if (i == numElements) {
list[i] = value;
}
}
}
numElements++;
}
}
which now correctly outputs
0: 13
1: 21
2: 25
3: 44
4: 50
5: 63
6: 88
7: 99
8: 100
9: 200

Is there a solution to prevent this recursion?

In this program, a randomly generated 2D array is populated with 1's or 0's and I attempt to find a path of 1's (no diagonal movement). I have got the program to work for smaller dimensions of the 2D array, but when the dimensions are too large, the error Exception in thread "main" java.lang.StackOverflowError occurs.
import java.util.Scanner;
import java.util.Random;
public class Daft {
private int counter = 0;
public static void main(String[] args) {
Daft punk = new Daft();
punk.run();
}
public void run() {
int ans;
int[][] array;
int[][] solvedPath;
do {
counter = 1;
array = populate(defineArray(firstDimension(),secondDimension()));
solvedPath = findPath(array);
System.out.println("Times before solvable: " + counter);
print(solvedPath);
ans = continuity();
}while(ans != 0);
}
public int[][] findPath(int[][] array) {
int r = 0, c = 0;
while(true) {
array[0][0] = 7;
if(c == 0 && r == array.length-1) { //reached the bottom left, checks right
if(array[r][c+1] == 1) {
array[r][c+1] = 7;
c+=1;
} else {
array[r][c] = 7;
break;
}
} else if(c == array[0].length-1 && r == array.length-1) { //reached the bottom right, checks left
if(array[r][c-1] == 1) {
array[r][c-1] = 7;
} else {
array[r][c] = 7;
break;
}
} else if(r == array.length-1) { //reached the bottom, checks left/right
if(array[r][c+1] == 1 && array[r][c-1] == 1) {
counter++;
newPath(array);
break;
} else if(array[r][c+1] == 1) { //checks right
array[r][c+1] = 7;
c+=1;
} else if(array[r][c-1] == 1) { //checks left
array[r][c-1] = 7;
c-=1;
} else { //end of path
array[r][c] = 7;
break;
}
} else if(c == 0) { //reached the left, checks right/bottom
if(array[r][c+1] == 1 && array[r+1][c] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r][c+1] == 1) {
array[r][c+1] = 7;
c+=1;
} else if(array[r+1][c] == 1) {
array[r+1][c] = 7;
r+=1;
} else {
counter++; //path has ended, not solvable
newPath(array);
break;
}
} else if(c == array[0].length-1) { //reached the right, checks left/bottom
if(array[r+1][c] == 1 && array[r][c-1] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r+1][c] == 1) {
array[r+1][c] = 7;
r+=1;
} else if(array[r][c-1] == 1) {
array[r][c-1] = 7;
c-=1;
} else {
counter++; //path has ended, not solvable
newPath(array);
break;
}
} else if(array[r][c+1] == 1 && array[r+1][c] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r][c-1] == 1 && array[r+1][c] == 1) { //checks if path is unique
counter++;
newPath(array);
break;
} else if(array[r][c+1] == 1) { //checks right
array[r][c+1] = 7;
c+=1;
} else if(array[r+1][c] == 1) { //checks bottom
array[r+1][c] = 7;
r+=1;
} else if(array[r][c-1] == 1) { //checks left
array[r][c-1] = 7;
c-=1;
} else {
counter++;
newPath(array);
break;
}
}
return array;
}
public int firstDimension() {
Scanner in = new Scanner(System.in);
System.out.println("Size of the first dimension:");
return in.nextInt();
}
public int secondDimension() {
Scanner in = new Scanner(System.in);
System.out.println("Size of the second dimension:");
return in.nextInt();
}
public int[][] defineArray(int firstDimension, int secondDimension) {
return new int[firstDimension][secondDimension];
}
public int[][] populate(int[][] array) {
Random rand = new Random();
for(int i = 0; i < array.length; i++) {
for(int j = 0; j < array[i].length; j++) {
array[i][j] = rand.nextInt(2);
}
}
return array;
}
public int continuity() {
Scanner in = new Scanner(System.in);
System.out.println("Enter a number to continue (0 to quit):");
return in.nextInt();
}
public void print(int[][] array) {
for(int[] ints : array) {
for(int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
System.out.println();
}
public void newPath(int[][] array) {
findPath(populate(array));
}
}

return issues in java

So I'm writing a mersense script for codeeval in java to get some practice with the language (I'm fairly new to it). At one point I'm checking if the number is prime and in my method I do the normal checks and everything looks great
public static boolean isPrime (int testValue){
if (testValue < 4){
return true;
} else if (testValue % 2 == 0){
return false;
} else {
for (int I = 1; I < Math.sqrt (testValue); I++){
if (testValue % I == 0 ){
return false;
}
}
return true;
}
}
however the only things getting through seem to be 1 and 3. Can I not do that return after the for loop is that what's wrong? Any ideas?
Edit:
Here is the full code:
import java.io.*;
import java.lang.Math;
public class Main{
public static void main(String[] args) throws IOException {
File file = new File(args[0]);
BufferedReader buffer = new BufferedReader(new FileReader(file));
String line;
int n;
StringBuilder result = new StringBuilder();
int candidate;
while((line = buffer.readLine()) != null){
n = Integer.parseInt(line.trim());
for(int i = 1; i < n; i++){
candidate = mersenne(i);
if(isPrime(candidate)){
System.out.println(candidate + " "+ isPrime(candidate));
if((i+1) >= n){
result.append(candidate);
}else{
result.append(candidate + ", ");
}
}
}
System.out.println(result.toString());
result = new StringBuilder();
}
}
public static int mersenne (int testValue){
return (int)Math.pow(2,testValue) - 1;
}
public static boolean isPrime(int testValue){
if(testValue < 4 && testValue > 1){
return true;
}else if(testValue % 2 == 0){
return false;
}else{
for(int i = 3; i <= Math.sqrt(testValue); i++){
if(testValue % i == 0){
return false;
}
}
return true;
}
}
}
You're starting the loop at 1. Everything % 1 is 0. Start at 3.
your code in the else block:
for (int I = 1; I < Math.sqrt (testValue); I++){
if (testValue % I == 0 ){
return false;
}
}
you should start with I=3:
for (int I = 3; I < Math.sqrt (testValue); I++)
Since every number % 1 equals to 0 so false will be returned.

How to simplify my methods with tons of if statements [duplicate]

This question already has answers here:
Read a text file and store every single character occurrence
(3 answers)
Closed 6 years ago.
My code is supposed to read an input file and count the uses of each character in the file then print them all out. The code works but I know that there has to be a way to cut down on all the if statements. Right now I'm making methods for reading and one for output so its not all written in my main method. Any and all suggestions are helpful, thanks.
import java.io.FileReader;
import java.io.IOException;
public class CharacterCounts {
static int nl = 0;
static int sp = 0;
static int ex = 0;
static int ap = 0;
static int cm = 0;
static int hy = 0;
static int pd = 0;
static int cn = 0;
static int sm = 0;
static int qu = 0;
static int a = 0;
static int b = 0;
static int c = 0;
static int d = 0;
static int e = 0;
static int f = 0;
static int g = 0;
static int h = 0;
static int ii = 0;
static int j = 0;
static int k = 0;
static int l = 0;
static int m = 0;
static int n = 0;
static int o = 0;
static int p = 0;
static int q = 0;
static int r = 0;
static int s = 0;
static int t = 0;
static int u = 0;
static int v = 0;
static int w = 0;
static int x = 0;
static int y = 0;
static int z = 0;
static int A = 0;
static int B = 0;
static int C = 0;
static int D = 0;
static int E = 0;
static int F = 0;
static int G = 0;
static int H = 0;
static int I = 0;
static int J = 0;
static int K = 0;
static int L = 0;
static int M = 0;
static int N = 0;
static int O = 0;
static int P = 0;
static int Q = 0;
static int R = 0;
static int S = 0;
static int T = 0;
static int U = 0;
static int V = 0;
static int W = 0;
static int X = 0;
static int Y = 0;
static int Z = 0;
public static void main(String args[]) throws IOException {
String file = args[0];
#SuppressWarnings("resource")
FileReader scanner = new FileReader(file);
int i;
while ((i = scanner.read()) != -1) {
if ((char) i == '\n') {
nl++;
} else if ((char) i == ' ') {
sp++;
} else if ((char) i == '!') {
ex++;
} else if ((char) i == '\'') {
ap++;
} else if ((char) i == ',') {
cm++;
} else if ((char) i == '-') {
hy++;
} else if ((char) i == '.') {
pd++;
} else if ((char) i == ':') {
cn++;
} else if ((char) i == ';') {
sm++;
} else if ((char) i == '?') {
qu++;
} else if ((char) i == 'a') {
a++;
} else if ((char) i == 'b') {
b++;
} else if ((char) i == 'c') {
c++;
} else if ((char) i == 'd') {
d++;
} else if ((char) i == 'e') {
e++;
} else if ((char) i == 'f') {
f++;
} else if ((char) i == 'g') {
g++;
} else if ((char) i == 'h') {
h++;
} else if ((char) i == 'i') {
ii++;
} else if ((char) i == 'j') {
j++;
} else if ((char) i == 'k') {
k++;
} else if ((char) i == 'l') {
l++;
} else if ((char) i == 'm') {
m++;
} else if ((char) i == 'n') {
n++;
} else if ((char) i == 'o') {
o++;
} else if ((char) i == 'p') {
p++;
} else if ((char) i == 'q') {
q++;
} else if ((char) i == 'r') {
r++;
} else if ((char) i == 's') {
s++;
} else if ((char) i == 't') {
t++;
} else if ((char) i == 'u') {
u++;
} else if ((char) i == 'v') {
v++;
} else if ((char) i == 'w') {
w++;
} else if ((char) i == 'x') {
x++;
} else if ((char) i == 'y') {
y++;
} else if ((char) i == 'z') {
z++;
} else if ((char) i == 'A') {
A++;
} else if ((char) i == 'B') {
B++;
} else if ((char) i == 'C') {
C++;
} else if ((char) i == 'D') {
D++;
} else if ((char) i == 'E') {
E++;
} else if ((char) i == 'F') {
F++;
} else if ((char) i == 'G') {
G++;
} else if ((char) i == 'H') {
H++;
} else if ((char) i == 'I') {
I++;
} else if ((char) i == 'J') {
J++;
} else if ((char) i == 'K') {
K++;
} else if ((char) i == 'L') {
L++;
} else if ((char) i == 'M') {
M++;
} else if ((char) i == 'N') {
N++;
} else if ((char) i == 'O') {
O++;
} else if ((char) i == 'P') {
P++;
} else if ((char) i == 'Q') {
Q++;
} else if ((char) i == 'R') {
R++;
} else if ((char) i == 'S') {
S++;
} else if ((char) i == 'T') {
T++;
} else if ((char) i == 'U') {
U++;
} else if ((char) i == 'V') {
V++;
} else if ((char) i == 'W') {
W++;
} else if ((char) i == 'X') {
X++;
} else if ((char) i == 'Y') {
Y++;
} else if ((char) i == 'Z') {
Z++;
}
}
if (nl != 0) {
System.out.printf("'/n' %d\n", nl);
}
if (sp != 0) {
System.out.printf("' ' %d\n", sp);
}
if (ex != 0) {
System.out.printf("'!' %d\n", ex);
}
if (ap != 0) {
System.out.printf("''' %d\n", ap);
}
if (cm != 0) {
System.out.printf("',' %d\n", cm);
}
if (hy != 0) {
System.out.printf("'-' %d\n", hy);
}
if (pd != 0) {
System.out.printf("'.' %d\n", pd);
}
if (cn != 0) {
System.out.printf("':' %d\n", cn);
}
if (sm != 0) {
System.out.printf("';' %d\n", sm);
}
if (qu != 0) {
System.out.printf("'?' %d\n", qu);
}
if (A != 0) {
System.out.printf("'A' %d\n", A);
}
if (B != 0) {
System.out.printf("'B' %d\n", B);
}
if (C != 0) {
System.out.printf("'C' %d\n", C);
}
if (D != 0) {
System.out.printf("'D' %d\n", D);
}
if (E != 0) {
System.out.printf("'E' %d\n", E);
}
if (F != 0) {
System.out.printf("'F' %d\n", F);
}
if (G != 0) {
System.out.printf("'G' %d\n", G);
}
if (H != 0) {
System.out.printf("'H' %d\n", H);
}
if (I != 0) {
System.out.printf("'I' %d\n", I);
}
if (J != 0) {
System.out.printf("'J' %d\n", J);
}
if (K != 0) {
System.out.printf("'K' %d\n", K);
}
if (L != 0) {
System.out.printf("'L' %d\n", L);
}
if (M != 0) {
System.out.printf("'M' %d\n", M);
}
if (N != 0) {
System.out.printf("'N' %d\n", N);
}
if (O != 0) {
System.out.printf("'O' %d\n", O);
}
if (P != 0) {
System.out.printf("'P' %d\n", P);
}
if (Q != 0) {
System.out.printf("'Q' %d\n", Q);
}
if (R != 0) {
System.out.printf("'R' %d\n", R);
}
if (S != 0) {
System.out.printf("'S' %d\n", S);
}
if (T != 0) {
System.out.printf("'T' %d\n", T);
}
if (U != 0) {
System.out.printf("'U' %d\n", U);
}
if (V != 0) {
System.out.printf("'V' %d\n", V);
}
if (W != 0) {
System.out.printf("'W' %d\n", W);
}
if (X != 0) {
System.out.printf("'X' %d\n", X);
}
if (Y != 0) {
System.out.printf("'Y' %d\n", Y);
}
if (Z != 0) {
System.out.printf("'Z' %d\n", Z);
}
if (a != 0) {
System.out.printf("'a' %d\n", a);
}
if (b != 0) {
System.out.printf("'b' %d\n", b);
}
if (c != 0) {
System.out.printf("'c' %d\n", c);
}
if (d != 0) {
System.out.printf("'d' %d\n", d);
}
if (e != 0) {
System.out.printf("'e' %d\n", e);
}
if (f != 0) {
System.out.printf("'f' %d\n", f);
}
if (g != 0) {
System.out.printf("'g' %d\n", g);
}
if (h != 0) {
System.out.printf("'h' %d\n", h);
}
if (ii != 0) {
System.out.printf("'i' %d\n", ii);
}
if (j != 0) {
System.out.printf("'j' %d\n", j);
}
if (k != 0) {
System.out.printf("'k' %d\n", k);
}
if (l != 0) {
System.out.printf("'l' %d\n", l);
}
if (m != 0) {
System.out.printf("'m' %d\n", m);
}
if (n != 0) {
System.out.printf("'n' %d\n", n);
}
if (o != 0) {
System.out.printf("'o' %d\n", o);
}
if (p != 0) {
System.out.printf("'p' %d\n", p);
}
if (q != 0) {
System.out.printf("'q' %d\n", q);
}
if (r != 0) {
System.out.printf("'r' %d\n", r);
}
if (s != 0) {
System.out.printf("'s' %d\n", s);
}
if (t != 0) {
System.out.printf("'t' %d\n", t);
}
if (u != 0) {
System.out.printf("'u' %d\n", u);
}
if (v != 0) {
System.out.printf("'v' %d\n", v);
}
if (w != 0) {
System.out.printf("'w' %d\n", w);
}
if (x != 0) {
System.out.printf("'x' %d\n", x);
}
if (y != 0) {
System.out.printf("'y' %d\n", y);
}
if (z != 0) {
System.out.printf("'z' %d\n", z);
}
}
}
This can be easily improved by using a Map<Character, Integer>. Change your declaration to this:
static final Map<Character, Integer> VALUES = new HashMap<>();
Then the body of your code can be changed to this:
Integer val = VALUES.get(i);
if(val == null) VALUES.put(i, 1);
else VALUES.put(i, val + 1);
Then simply iterate over it to display the values at the end.
Keeping the order, or restricting it to just those characters, could be done by using a LinkedHashMap and pre-populating all the desired values with zero.
Here's an example of what that would look like:
private static final Map<Character, Integer> VALUES = new LinkedHashMap<>();
static{
for(char c : "\n !\\,-.:;?".toCharArray()){
VALUES.put(c, 0);
}
for(char c = 'a'; c < 'z'; c++){
VALUES.put(c, 0);
}
for(char c = 'A'; c < 'Z'; c++){
VALUES.put(c, 0);
}
}
public static void main(String args[]){
try{
String file = args[0];
FileReader scanner = new FileReader(file);
int i;
while ((i = scanner.read()) != -1) {
Integer val = VALUES.get((char)i);
if(val != null) VALUES.put((char)i, val + 1);
}
for(Map.Entry<Character, Integer> entry : VALUES.entrySet()){
if(entry.getValue() > 0)
System.out.println(entry.getKey() + " " + entry.getValue());
}
} catch(IOException ioe){
ioe.printStackTrace();
}
}
^Untested, but should at least be close.
Now tested, and the numerous bugs have been fixed.
Same behavior, more maintainable, less likely to contain typos, and 10% of the typing.

BubbleSort troubleshooting

It is my first attempt to do sorting in arrays. I am looking in BubbleSort. I looked up many examples on the net. However, I could not get my bubble sort working. Below is a snippet of my code:
//Sort by StudentID (long variable)
public static void BubbleSort(Student[] st) {
long tempID; //holding variable
for (int j = 0; j < st.length - 1; j++) {
if (st[j] != null) {
long studentID1 = st[j].getStudentID();
if (st[j + 1] != null) {
long studentID2 = st[j + 1].getStudentID();
if ((st[j] != null) && (st[j + 1] != null)) {
if (studentID1 < studentID2) // change to > for ascending sort
{
tempID = studentID1; //swap elements
studentID1 = studentID2;
studentID2 = tempID; //shows a swap occurred
}
}
}
}
}
}
//My main method
if (studentIndex >= 0) {
BubbleSort(studentList);
for (int i = 0; i <= studentIndex; i++) {
studentList[i].writeOutput();
}
} else {
System.out.println("No sorting done");
}
You have to swap elements. Your code doesn't.
In addition you have to check if you had modifications in your for loop. If yes you have to repeat the procedure.
So change it as follow
public static BubbleSort(Student[] st) {
Student temp; //holding variable
boolean changed = false;
for (int j = 0; j < st.length - 1; j++) {
if (st[j] != null) {
long studentID1 = st[j].getStudentID();
if (st[j + 1] != null) {
long studentID2 = st[j + 1].getStudentID();
if ((st[j] != null) && (st[j + 1] != null)) {
if (studentID1 < studentID2) // change to > for ascending sort
{
temp = st[j]; //swap elements
st[j] = st[j + 1];
st[j + 1] = temp; //shows a swap occurred
changed = true;
}
}
}
}
}
if (changed) {
BubbleSort(st);
}
}

Categories

Resources