median and mode displaying -1 - java

Hey guys I have been learning coding recently and got an assignment of finding the mean, median and mode of a number of integers in an integer array. The issue that I am facing is that my median and mode displays -1 and I'm not too sure how to fix it, my "if user inputs no, print an error statement" is also not working and I would be very grateful if someone could help me out.
This is my code:
package com.company;
import java.io.File;
import java.io.FileNotFoundException;
import static com.company.ProjectConstants.*;
import java.util.*;
public class Main {
public static void main(String[] args) {
int[] a = new int[MAXDATA];
int counter = 0;
boolean fileDone = false;
boolean inputOk;
String userInput;
String theDataFile;
Scanner s = new Scanner(System.in);
genProgInfo();
userInput = s.nextLine();
userInput = userInput.toLowerCase();
while (!userInput.equals("yes") && (!userInput.equals("no"))) {
System.out.println("ERROR: Please input either yes or no: ");
userInput = s.nextLine();
userInput = userInput.toLowerCase();
}
inputOk = userInput.equals("yes");
initDataStorage(a);
//do {
try {
// create file & scanner objects
System.out.println("enter one of the file names:\nData10File.txt\nData30file.txt\nData35file.txt");
theDataFile = s.next();
theDataFile = theDataFile.toLowerCase();
//fName = userInput;
File f = new File(theDataFile);
Scanner sc = new Scanner(f);
// store file data in array, a
for (int i = 0; i < MAXDATA; i++) {
if (sc.hasNext()) {
a[i] = sc.nextInt();
} else {
fileDone = true;
sc.close();
break;
}
}
// print error message if file data exceeds the range of array
if (!fileDone) {
System.out.println("\n\tCAUTION: file has additional data, consider making array larger.");
}
} catch (FileNotFoundException e) {
System.out.println(e);
e.printStackTrace();
}
//} while (inputOk);
s.close();
for (int i=0; i<MAXDATA; i++) {
if (a[i] != -1) {
counter = a[i];
}
}
System.out.println("counter: "+ counter);
displayResults(calcMean(a), calcMedian(a), calcMode(a));
}
public static void initDataStorage(int[] data) {
for (int i = 0; i < MAXDATA; i++) {
data[i] = INVALID;
}
}
public static double calcMean(int[] data) {
int counter = 0;
int mean;
int sum = 0;
for (int i = 0; i < MAXDATA; i++) {
if (data[i] != -1) {
sum += data[i];
counter++;
}
}
mean = sum / counter;
return mean;
}
public static double calcMedian(int[] data) {
int middle = data.length / 2;
if (data.length % 2 == 1) {
return data[middle];
} else {
return (data[middle -1] + data[middle]) / 2.0;
}
}
public static int calcMode(int[] data) {
int mode = 0, maxCount = 0;
for (int i = 0; i < data.length; ++i) {
int count = 0;
for (int j = 0; j < data.length; ++j) {
if (data[j] == data[i]) {
count++;
}
}
if (count > maxCount) {
maxCount = count;
mode = data[i];
}
}
return mode;
}
public static void genProgInfo() {
System.out.println("This program will calculate the mean, median, and mode of a number of integers stored in the array");
System.out.println("Would you like to continue?");
}
public static void displayResults(double mean, double median, int mode) {
System.out.println("mean: " + mean);
System.out.println("median: " + median);
System.out.println("mode: " + mode);
}
}

I'm assuming the value of INVALID is -1 based on the other code I see and your description of what it outputs. Your array is of length MAXDATA and is initially filled with value INVALID in all elements. You then fill it with n values where n may be less than MAXDATA, and in that (probably common) case, many or even most of the values in the array are the INVALID value.
Your calcMean function is correctly skipping over the -1 (INVALID?) values and not including them in the calculation. Note however that the valid values are all at the beginning of the array and once you find an invalid value, you could break out of the loop in calcMean.
But the calcMedian and calcMode functions are not accounting for the invalid values. If n is significantly less than MAXDATA, then -1 probably really is the mode. Your calcMedian function has an additional problem as well, in that the (valid) data needs to be sorted in order for the "middle" or median value to be in the middle of the array.
Bonus question for your assignment: What if -1 occurs in the input file?

Related

How to stop FileNotFoundException from popping up?

So I'm trying to find the two closest pairs in a text file and then find how close they are. I have most of it worked out but for some reason whenever I try to run the code the file not found exception keeps popping up. I can't seem to get it to run the actual code. Any help would be greatly appreciated.
import java.util.*;
import java.io.FileNotFoundException;
import java.io.File;
/**
*
* #author birnbook
*/
public class ClosestPair {
public static void ClosePair() { // string compare
try{
File text = new File("/Lab2%20Output.txt");
double temp = 0;
double x = 0;
double y = 0;
double stormag = 0;
// scanning the file in
Scanner scnr = new Scanner(text);
int lines = 0;
while (scnr.hasNextLine()) {
lines++;
}
Scanner scnnr = new Scanner(text);
double[] arr = new double[lines];
while (scnnr.hasNextLine()) {
String num = scnnr.nextLine();
arr[1] = Double.parseDouble(num);
}
stormag = arr[0] - arr[1];
if (stormag == 0){
stormag *= -1;
}
for(int i=0; i< arr.length;i++){
for(int k=1;k< arr.length; k++){
if(i != k){
temp = arr[i] - arr[k];
if(temp <= 0){
temp *= -1;
}
if (temp < stormag){
stormag = temp;
x = arr[i];
y = arr[k];
}
}
}
}
System.out.println("The numbers " + x + " and " + y + "are the closest pair with a difference of " + stormag);
} catch (FileNotFoundException e){
System.out.println("FileNotFoundException");
}
}
public static void main(String[] args) {
ClosePair();
}
}

Java - NumberFormatException when using .parseInt(String)

I am trying to run a loop to see if an int is sorted. however the int has to be converted from a string. here is my code.
public static void main(String[] args) {
// TODO code application logic here
Scanner maxVal = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
System.out.println("enter the max value of ordered squares:");
int max = maxVal.nextInt();
for(int i = 0; i*i <= max; i++){
int L = String.valueOf(i*i).length();
String sq = String.valueOf(i*i);
String [] digits = new String[L];
for(int a = 0; a < L; a++){
digits [a] = Character.toString(sq.charAt(a));
if(L == 1){
System.out.print(sq + "");
}else if(Integer.parseInt(digits [a]) < Integer.parseInt(digits[a+1])){
System.out.print(sq);
}else{
}
}
}
}
when I run it, I get an error :
Exception in thread "main" java.lang.NumberFormatException: null
0149 at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
why does Integer.parseInt() not work
Your problem is that digits[a+1] hasn't been defined yet. I see that on line 2 you have
digits[a] = Character.toString(sq.charAt(a));
and you're iterating over a in a for loop, so I daresay that digits[a+1] hasn't been assigned yet.
UPDATE 1
Check out this solution, it shows how to properly catch that exception and how to avoid it:
Java: Good way to encapsulate Integer.parseInt()
UPDATE 2
I decided to add a fixed version of your code:
public static void main(String[] args) {
// TODO code application logic here
Scanner maxVal = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
System.out.println("enter the max value of ordered squares:");
int max = maxVal.nextInt();
for(int i = 0; i*i <= max; i++){
int L = String.valueOf(i*i).length();
String sq = String.valueOf(i*i);
String [] digits = new String[L];
for(int a = 0; a < L; a++){
digits [a] = Character.toString(sq.charAt(a));
if(L == 1 || a == 0){
System.out.print(sq + "");
}else if(Integer.parseInt(digits [a]) < Integer.parseInt(digits[a+1])){
System.out.print(sq);
}else{
}
}
}
}
While I don't know the utility of your code, but this implementation might be simpler:
public static void main(String[] args) {
// TODO code application logic here
Scanner maxVal = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
System.out.println("enter the max value of ordered squares:");
int max = maxVal.nextInt();
for(int i = 0; i*i <= max; i++){
long sq = i*i;
if(sq > 9){
String[] digits = sq.toString().split("");
//Notice that I start at index 1, so I can do [a-1] safely
for(int a = 1; a < digits.length; a++){
if(Integer.parseInt(digits [a-1]) < Integer.parseInt(digits[a])){
System.out.print(sq);
//I guess we don't want a number like 169 (13*13) to be displayed twice, so:
break;
}
}
} else {
System.out.print(sq);
}
}
}

How to use recursion to sort an array of strings from smallest to largest?

import java.io.File;
import java.util.Scanner;
public class TestDriver {
public static void main(String[] args) {
Scanner x = null;
try {
x = new Scanner(new File("pokemon"));
} catch (Exception e) {
System.out.println("could not find file");
}
#SuppressWarnings("resource")
Scanner input = new Scanner(System.in);
System.out.println("Type in the number of Pokemons (1-15)!");
int userNumber = 0;
boolean userFalse = false;
while (!userFalse) { // Validates user inputs for years
if (input.hasNextInt()) {
int temp = input.nextInt();
if (temp < 1 || temp > 15) { // Years cannot be below 0
System.out.println("Invalid input.");
userFalse = false;
} else {
userFalse = true;
userNumber = temp;
}
} else {
System.out.println("Try Again!");
input.next();
}
}
String[] a = new String[userNumber];
for (int i = 0; i < userNumber; i++) {
a[i] = x.next();
System.out.print(a[i] + " ");
}
sort(a, userNumber);
}
In the pokemon.txt, it reads
Gyarados
Lapras
Eevee
Vaporeon
Snorlax
Abra
Slowbro
Rhyson
Kyogre
Blastoise
Jigglypuff
Miltank
Lugia
Steelix
Arbok
I am trying to sort the Pokemon NAMES from smallest to largest. I don't know the best way to do this. My teacher wants me to do it using recursion. Is that the same thing as quicksort or mergesort? Thanks in advance.
edit: Here's my attempt to sort using mergesort:
public static void sort(String[] pokemon, int userNumber) {
String[] a = new String[pokemon.length / 2]; // Split array into two
String[] b = new String[pokemon.length - a.length]; // halves, a and b
for (int i = 0; i < pokemon.length; i++) {
if (i < a.length)
a[i] = a[i];
else
b[i - a.length] = pokemon[i];
}
sort(a, userNumber); // Recursively sort first
sort(b, userNumber); // and second half.
int ai = 0; // Merge halves: ai, bi
int bi = 0; // track position in
while (ai + bi < pokemon.length) { // in each half.
if (bi >= b.length || (ai < a.length && a[ai].length() < b[bi].length())) {
pokemon[ai + bi] = a[ai]; // (copy element of first array over)
ai++;
} else {
pokemon[ai + bi] = b[bi]; // (copy element of second array over)
bi++;
}
}
}
Quicksort and Mergesort can both be implemented recursively. Since this is homework I will not be providing actual code but I will link you to a few places you can look:
Merge Sort
Quick Sort

Currently compiling, but receiving nothing but end to program?

import java.util.Scanner;
public class PD {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
System.out.print("Enter your number: " );
int number = input.nextInt();
for (int count = 2; count < number; count++) {
String blank = "";
String Snumber = count + blank;
if (isPalindromic(count) && isPrime(count) &&
isPalindromic((int)(Snumber.length())) &&
isPrime((int)(Snumber.length()))){
System.out.println( count + "is double palidromic prime");
}
else
continue;
}
}
// method to find palindromic
public static boolean isPalindromic(int count) {
String blank = "";
String convert = count + blank;
for (int i = 0, q = 1; i <= (convert.length()/2 - 1); i++, q++) {
if (convert.substring(i,q) == convert.substring(convert.length() - q, convert.length() - i)){
return true;
}
}
return false;
}
// method to find prime
public static boolean isPrime(int count ) {
for (int divisor = 2; divisor <= count/2; divisor++) {
if (count % divisor == 0) {
return false;
}
}
return true;
}
}
Currently the thing compiles and ask for input, but it always results in nothing.
Does someone see something wrong with my program that is obvious wrong.
Overall, the program receives input and has to look through values 2 until it hits the value the user wants and print the ones that follow the if statement.
Your isPalindromic method is not functioning properly. It is not returning true for palindromic numbers. Change it to this:
public static boolean isPalindromic(int count) {
String blank = "";
String convert = count + blank;
int n = convert.length();
for (int i = 0; i < (n / 2 + 1); i++) {
if (convert.charAt(i) != convert.charAt(n - i - 1)) {
return false;
}
}
return true;
}

Null Pointer Exceptions Without Apparent Reason

StackOverflow. I am attempting to make a program that uses a text menu to to a multitude of things to manipulate a single string. One of the methods turns the string into an array of strings. This works fine. However, all of the methods that manipulate it as an array(one prints it out, one reverses the word order, and one sorts them using an exchange sorting method) return a NullPointerException when called. I have looked all through the code and do not see where it is coming from. Here is the .Java file containing all of the code. My problem is only happening when I call the printArray(), reverse(), and sort() methods, near the bottom. Any and all help is appreciated. Sorry for the sloppy code, I have not cleaned it up yet.
Code:
/*
Computer Programming Lab 11
Jim Kimble
3 Mar 2013
Work with strings and implementing a menu.
Acknowledgements:
Uses main structure of HUTPanel as designed at UMU, 2002-2012
*/
import java.io.*;
import java.awt.*;
import javax.swing.*;
public class HUTPanel extends JPanel
{
/***************************************************
* Class-level data members should be declared here.
***************************************************/
int numVowels;
String[] words;
String str;
String vowels;
String menuChoice;
String oString = "A tong lime ago, a daggy shog bossed a cridge over a pillmond,\n"
+"When in the course of human events\n"
+"Mary had a little lamb.\n"
+"The girls' basketball team repeated as tournament champion this weekend.";
public HUTPanel(JFrame frame)
{
// Set panel background color
setBackground(Color.WHITE);
setLayout(null);
setPreferredSize(new Dimension(810, 410));
/***************************
* Now add your code below:
***************************/
// Create a frame around this panel.
frame.setTitle("Computer Programming Lab/Program # 11");
frame.getContentPane().add(this);
str = "A tong lime ago, a daggy shog bossed a cridge over a pillmond,\n"
+"When in the course of human events\n"
+"Mary had a little lamb.\n"
+"The girls' basketball team repeated as tournament champion this weekend.";
System.out.println("Lab 11: Text Manipulation");
//getTheText();
System.out.println("The string is: '"+str+"'.");
handleTheMenu();
} // end of constructor
/*************************
* Add your methods here:
*************************/
// Get a text sequence from the keyboard and put it in str
public void getTheText()
{
Boolean inputDone = false;
while (!inputDone)
{
System.out.print("Enter your text: ");
inputDone = grabText();
}
}
private Boolean grabText()
{
try {
BufferedReader inputReader = new BufferedReader(new InputStreamReader(System.in));
menuChoice = inputReader.readLine();
return true;
}
catch(IOException e)
{
System.out.println("Error reading input. Please try again.");
}
return false;
}
public void handleTheMenu()
{
int choice = -1;
Boolean OK;
while (choice != 0)
{
choice = -1;
System.out.println("Menu:");
System.out.println();
System.out.println(" 1. Count the vowels"); //"There are ... vowels in the text."
System.out.println(" 2. Remove all letter e's"); //then print it.
System.out.println(" 3. Replace all t's with '+'"); //then print it
System.out.println(" 4. Search for a requested word (will reset the string)"); //Does 'word' exist in the text?
System.out.println(" 5. Print the words on individual lines");
System.out.println(" 6. Reset the string.");//Reset the string to the original
System.out.println(" 7. Put the words in an array"); //then print it
System.out.println(" 8. Reverse the text word order"); //then print it
System.out.println(" 9. Sort the words in an array"); //Once the words are put into an array
System.out.println();
System.out.print(" 0 to quit --> ");
OK = grabText();
if (OK)
{
try
{
choice = Integer.parseInt(menuChoice);
}
catch(NumberFormatException e)
{
System.out.println("Not a number; please try again.");
System.out.println();
}
switch(choice)
{
case 0: System.out.println();
System.out.println("Thank you.");
break;
case 1: countVowels();
break;
case 2: removeAllEs();
break;
case 3: changeTToPlus();
break;
case 4: find();
break;
case 5: listWords();
break;
case 6: reset();
break;
case 7: makeArray();
break;
case 8: reverse();
break;
case 9: sort();
break;
default: System.out.println("Not a valid choice; please try again.");
}
}
}
}
private void countVowels() {
//count the vowels in str
vowels = "aeiouAEIOU";
numVowels = 0;
for( int i = 0; i < vowels.length(); i ++) {
for(int j = 0; j < str.length(); j++) {
if (str.charAt(j) == vowels.charAt(i)) {
numVowels += 1;
}
}
}
System.out.println("The string has " + numVowels + " vowels in it.");
}
private void removeAllEs() {
String str3 = str.replace('e', ' ');
System.out.print(str3);
str = str3;
}
private void changeTToPlus() {
String str2 = str.replace('t', '+');
System.out.println(str2);
str = str2;
}
private void find() {
str = oString;
getTheText();
if(str.indexOf(menuChoice) != -1)
{
System.out.println("The word " +menuChoice+ " is at index " +str.indexOf(menuChoice));
}
else
{
System.out.println("The word " +menuChoice+ " is not in the string.");
}
}
private void listWords() {
int pos = 0;
int i = 0;
while(i > -1)
{
i = str.indexOf(' ', pos);
if (i > -1)
{
System.out.println(str.substring(pos, i));
pos = i + 1;
}
}
}
private void reset() {
str = oString;
System.out.println();
System.out.println("String reset.");
System.out.println();
}
private void makeArray() {
int n = 1;
String[] words = new String[n];
int pos = 0;
int i = 0;
int j = 0;
while(j > -1)
{
for (i = 0; i < 1000; i++)
{
n += 1;
j = str.indexOf(' ', pos);
if (j > -1)
{
words[i] = str.substring(pos, j);
pos = j + 1;
}
}
}
//printArray();
}
//***FIX***
private void printArray() {
for (int k = 0; k < words.length -1; k++){
System.out.println(words[k]);
}
}
//***FIX***
private void reverse() {
int i = 0;
int j = words.length - 1;
String temp;
while (i < j){
temp = words[i];
words[i] = words[j];
words[j] = temp;
i++;
j--;
}
}
private void sort() {
String temp = "";
for (int i = 1; i < words.length - 1; i++) {
for (int j = i + 1; j < words.length; j++) {
int x = words[i].compareTo(words[j]);
if (x > 0) {
temp = words[i];
words[i] = words[j];
words[j] = temp;
}
}
}
for (int p = 0; p < words.length -1; p++) {
System.out.println(words[p]);
}
}
}
You Error is here:
private void makeArray() {
int n = 1;
String[] words = new String[n];//At This line you are creating local array words.The instance variable words is still null.
int pos = 0;
int i = 0;
int j = 0;
while(j > -1)
{
for (i = 0; i < 1000; i++)
{
n += 1;
j = str.indexOf(' ', pos);
if (j > -1)
{
words[i] = str.substring(pos, j);
pos = j + 1;
}
}
}
use:
words = new String[n]; instead of String[] words = new String[n];
As mentioned by Luiggi Mendoza in the comment section, the local variable words defined within makeArray method is shadowing the instance variable words defined within HUTPanel class.
As side note I want to point out the unnecessary creation of new BufferedReader objects in method grabText() each time you are calling it in getTheText(). It would be much efficient if your make inputReader an instance variable in your class , and instantiate it once within the constructor using inputReader = new BufferedReader(new InputStreamReader(System.in));. This way your grabText method becomes like this :
private Boolean grabText()
{
try {
//No more new object creation for BufferedReader for each call of this method.
menuChoice = inputReader.readLine();
return true;
}
catch(IOException e)
{
System.out.println("Error reading input. Please try again.");
}
return false;
}
Make sure you always you always start with option 7, so your words array gets initialized. This is in fact not something that the user should do. The application should handle it so that the user either can't select other options, or does it automatically.
Update: Vishal K is correct, but this is still a weak point in your application.

Categories