I am new to java trying to use methods from my Histogram class (Which implements a histogram interface) into a main method which reads a file and uses the first digit of each integer to create a histogram.
My histogram class looks like this
public class Histogram implements HistogramInterface
{
protected int min, max;
protected int[] counts;
public Histogram(int min, int max)
{
this.min = min;
this.max = max;
counts = new int[max - min + 1];
}
public Histogram(int max)
{
this.min = 1;
this.max = max;
counts = new int[max - min + 1];
}
public void submit(int i) throws HistogramOutOfBoundsException
{
if ((min <= i) && (i <= max))
counts[i-min] += 1;
else
{
String message = "\n*******\n";
message += "Submitted value " + i + " is outside range [";
message += min + "," + max + "]" + " of Histogram.\n";
message += "*******\n";
throw new HistogramOutOfBoundsException(message);
}
}
public String toString()
{
int weight; // value of a single *
int num; // number of *'s to print
// calculate weight
int highIndex = 0;
for (int i = 1; i < counts.length; i++)
if (counts[highIndex] < counts[i])
highIndex = i;
weight = ((counts[highIndex] - 1) / MAXWIDTH) + 1;
// create "header"
String histoString ="\n";
if (weight != 1)
histoString += "* = approximately " + weight + " occurrences\n\n";
// create histogram
for (int i = 0; i <= max - min; i++)
{
histoString += String.format("%4d",(i + min)) + ": ";
if (counts[i] == 0)
num = 0;
else
num = ((counts[i] - 1) / weight ) + 1;
for (int j = 0; j < num; j++)
histoString += "*";
histoString += "\n";
}
return histoString;
}
}
And the class Reader which I'm struggling with
import java.util.*;
import java.io.*;
public class Reader {
public static void main(String[] args) {
int min = 1;
int max = 9;
Histogram x = new Histogram(min, max);
int firstNum;
int digits;
int num = 0;
int weight = 20;
Scanner scan;
File file = new File("Data.txt");
try
{
scan = new Scanner(file);
while(scan.hasNextLine()){
digits = scan.nextInt();
firstNum = Integer.parseInt(Integer.toString(digits).substring(0,1));
digits++;
}
}
catch(Exception e)
{
}
}
}
I think you're looking for something like:
try {
scan = new Scanner(file);
while(scan.hasNextLine()){
digits = scan.nextInt();
firstNum = Integer.parseInt(Integer.toString(digits).substring(0,1));
x.submit(firstNum);
digits++;
}
} catch(HistogramOutOfBoundsException e) {}
try {
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("Output.txt"), "utf-8")));
out.write(x.toString())
out.close();
} catch (IOException e) {}
Related
I was working on a HackerRank challenge for "Array Manipulation", and there was an unexpected, interesting problem encountered. I'm running a big for loop, where I'm adding prefix sums, and the moment I pass over Integer.MAX_Value in the prefix sum (where the sum is stored as an int), the number jumps down by a few thousand instead of looping into the negative which is my expected behaviour.
Anyone know why this could be occuring? There is no problem if you store the prefix sum as a long.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class ArrayManipulation {
public static long arrayManipulationPrefixSumLong(int n, int[][] queries) {
long[] array = new long[n];
for (int i = 0; i < queries.length; i++) {
int lowIndex = queries[i][0] - 1;
int highIndex = queries[i][1] - 1;
int addend = queries[i][2];
array[lowIndex] += addend;
if (highIndex + 1 < n)
array[highIndex + 1] -= addend;
}
long maxInt = 0;
for (int i = 0; i < array.length; i++) {
if (i != 0)
array[i] = array[i - 1] + array[i];
if (array[i] > maxInt)
maxInt = array[i];
}
return maxInt;
}
public static int arrayManipulationPrefixSumInt(int n, int[][] queries) {
int[] array = new int[n];
for (int i = 0; i < queries.length; i++) {
int lowIndex = queries[i][0] - 1;
int highIndex = queries[i][1] - 1;
int addend = queries[i][2];
array[lowIndex] += addend;
if (highIndex + 1 < n)
array[highIndex + 1] -= addend;
}
int maxInt = 0;
for (int i = 0; i < array.length; i++) {
if (i != 0)
array[i] = array[i - 1] + array[i];
if (array[i] > maxInt)
maxInt = array[i];
}
return maxInt;
}
public static void main(String[] args) {
Scanner scanner = null;
try {
scanner = new Scanner(new File("input10ArrayManipulation_Subset85545.txt"));
// scanner = new Scanner(new File("input10ArrayManipulation.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int n = scanner.nextInt();
// System.out.println(n);
int qn = scanner.nextInt();
// System.out.println(qn);
int[][] queries = new int[qn][3];
for (int i = 0; i < qn; i++) {
queries[i] = new int[]{scanner.nextInt(), scanner.nextInt(), scanner.nextInt()};
}
scanner.close();
System.out.println(new String(new char[85]).replace("\0", "*"));
System.out.println("Trying to find why exceeding Integer.MAX_VALUE in a loop causes unexpected behaviour.");
System.out.println(new String(new char[60]).replace("\0", "-"));
//Relevant part
long arrayManipulationPrefixSumLong = arrayManipulationPrefixSumLong(n, queries);
int arrayManipulationPrefixSumInt = arrayManipulationPrefixSumInt(n, queries);
//Notice these two give different values
System.out.println("The long version: " + arrayManipulationPrefixSumLong);
System.out.println("The int version: " + arrayManipulationPrefixSumInt);
// Adding past the max value in a loop doesn't result in a negative number,
// to see this behaviour, increment the last line of input10ArrayManipulation_Subset85545 by 1.
System.out.println(Integer.MAX_VALUE - arrayManipulationPrefixSumLong);
//The below is my expected behaviour, where integer overflow occurs.
System.out.println("Max integer is: " + Integer.MAX_VALUE + " | Max integer +1 is: " + (Integer.MAX_VALUE + 1));
System.out.println(new String(new char[60]).replace("\0", "-"));
System.out.println("Now testing with the other file that has 1 incremented on the last line, which makes it exceed the Integer.MAX_VALUE");
try {
scanner = new Scanner(new File("input10ArrayManipulation_Subset85545_increment1.txt"));
n = scanner.nextInt();
// System.out.println(n);
qn = scanner.nextInt();
// System.out.println(qn);
queries = new int[qn][3];
for (int i = 0; i < qn; i++) {
queries[i] = new int[]{scanner.nextInt(), scanner.nextInt(), scanner.nextInt()};
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
arrayManipulationPrefixSumLong = arrayManipulationPrefixSumLong(n, queries);
arrayManipulationPrefixSumInt = arrayManipulationPrefixSumInt(n, queries);
//Notice these two give different values
System.out.println("The long version: " + arrayManipulationPrefixSumLong);
System.out.println("The int version: " + arrayManipulationPrefixSumInt);
scanner.close();
}
}
The text files used to test this program can be found at:
https://drive.google.com/drive/folders/1ktlEixYsqeD2l4x12iD4gEVvM-1gVetK?usp=sharing
for my school project I have to create a program that outputs perfect numbers based on how many perfect numbers the user(teacher) want. The user can pick any number from 1-4 and it should display however many number the user chooses. Here is my current code. Please ignore the sumupTo, factorial, isprime, and the testGoldbach methods, please only look at the Perfect numbers method/code.
import java.util.Scanner;
public class MyMathB
{
public static int sumUpTo(int n)
{
int sum = 0;
for (int k = 1; k <= n; k++)
sum += k;
return sum;
}
public static long factorial(int n)
{
long f = 1;
for (int k = 2; k <= n; k++)
f *= k;
return f;
}
public static boolean isPrime(int n)
{
if (n <= 1)
return false;
int m = 2;
while (m * m <= n)
{
if (n % m == 0)
return false;
m++;
}
return true;
}
public static void PerfectNumbers(int number)
{
System.out.println("How many perfect numbers would you like to see? Please enter an integer from 1 to 4");
Scanner s = new Scanner(System.in);
int numbersToSee = s.nextInt();
int counts = 0;
for(counts = 0; counts <= numbersToSee; counts++)
{
for (int n = 5; n <= 10000; n++)
{
int temp = 0;
for(int i = 1; i <= number / 2; i++)
{
if (number % i == 0)
{
temp += i;
}
if (temp == number)
{
System.out.println(number);
}
}
}
}
}
public static boolean testGoldbach(int bigNum)
{
for (int n = 6; n <= bigNum; n += 2)
{
boolean found2primes = false;
for (int p = 3; p <= n/2; p += 2)
{
if (isPrime(p) && isPrime(n - p))
found2primes = true;
}
if (!found2primes)
{
System.out.println(n + " is not a sum of two primes!");
return false;
}
}
return true;
}
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
int n;
do
{
System.out.print("Enter an integer from 4 to 20: ");
n = kb.nextInt();
} while (n < 4 || n > 20);
kb.close();
System.out.println();
System.out.println("1 + ... + " + n + " = " + sumUpTo(n));
System.out.println(n + "! = " + factorial(n));
System.out.println("Primes: ");
for (int k = 1; k <= n; k++)
if (isPrime(k))
System.out.print(k + " ");
System.out.println();
System.out.println("Goldbach conjecture up to " + n + ": " + testGoldbach(n));
}
}
you didn't declare the variable "number" in your method.
Edit: you didn't SET the variable number to anything, I misworded my last statement.
I'm trying to write a code that multiplies two strings of integers. I'm not too sure where it's going wrong... It works for some numbers, but is horribly wrong for others. I'm not asking for a full solution, but just a hint (I seriously appreciate any help possible) as to where I'm making the obviously silly mistake. Thanks in advance.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("Please enter a big integer. ");
String t = scan.nextLine();
System.out.print("And another. ");
String s = scan.nextLine();
BigInt a = new BigInt(t);
BigInt b = new BigInt(s);
System.out.println(a + " + " + b + " = " + a.add(b));
System.out.println(a + " - " + b + " = " + a.sub(b));
System.out.println(a + " * " + b + " = " + a.mul(b));
System.out.println(a + " / " + b + " = " + a.div(b));
}
}
class BigInt {
public BigInt() {
n = new int[1];
}
public BigInt(String s) {
n = new int[s.length()];
for (int i = 0; i < n.length; ++i) {
n[n.length - i - 1] = s.charAt(i) - '0' ;
}
}
private BigInt(int[] n) {
this.n = new int[n.length];
for (int i = 0; i < n.length; ++i) {
this.n[i] = n[i];
}
}
public String toString() {
String s = "";
for (int i : n) {
s = i + s;
}
return s;
}
public BigInt mul(BigInt o) {
int carry = 0;
int s = 0;
int digit;
int subtotal = 0;
int total = 0;
int max = n.length > o.n.length ? n.length : o.n.length;
int[] result = new int[n.length + o.n.length];
for (int i = 0; i < o.n.length; ++i) {
int bottom = i <= o.n.length ? o.n[i] : 0;
for (s = 0; s <= n.length; ++s){
int top = s < n.length ? n[s] : 0;
int prod = (top * bottom + carry);
if (s == (max-1)) {
total = Integer.valueOf((String.valueOf(prod) + String.valueOf(subtotal)));
carry = 0;
digit = 0;
subtotal = 0;
break;
}
if (prod < 10) {
digit = prod;
subtotal += digit;
carry = 0;
}
if (prod >= 10); {
digit = prod % 10;
carry = prod / 10;
subtotal += digit;
}
}
result[i] = total;
}
return new BigInt(trim(result));
}
private int[] trim(int[] nums) {
int size = nums.length;
for (int i = nums.length - 1; i > 0; --i) {
if (nums[i] != 0) {
break;
}
--size;
}
int[] res = new int[size];
for (int i = 0; i < size; ++i) {
res[i] = nums[i];
}
return res;
}
private int[] n;
}
A quick test using:
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
System.out.println(x + " * " + y + " = " + new BigInt(Integer.toString(x)).mul(new BigInt(Integer.toString(y))));
}
}
demonstrates that somehow your multiply of x * y is actually multiplying by 10x * y. That should give you a clear hint to the problem.
How can I get this to calculate properties about arrays of doubles. If everything else is an int inside, would that still as an array of doubles? Or is it still an array of doubles anyway because of the method type? Here is my class. Thanks so much!
import java.util.*;
import java.lang.Math;
public class Statistics {
private double min;
private double max;
private double mean;
private double median;
private double deviation;
private double mode;
public static double findMin(int[] array){
int min = array[0];
for(int i=1;i<array.length;i++){
if(array[i] < min){
min = array[i];
}
}
return min;
}
public static double findMax(int[] array){
int max = array[0];
for(int i=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
}
return max;
}
public static double calcMean(int[] n){
int sum=0;
for (int i=0; i<n.length; i++){
sum+= n[i];
}
return sum/n.length;
}
public static double calcMedian(int[] n){
int middle = n.length/2;
if (n.length%2==1){
return n[middle];
} else {
return (n[middle]+n[middle])/2;
}
}
public static double calcDeviation(int[] n){
int mean = (int)calcMean(n);
int squareSum = 0;
for (int i = 0; i < n.length; i++) {
squareSum += Math.pow(n[i] - mean, 2);
}
return Math.sqrt((squareSum) / (n.length - 1));
}
public static double calcMode(int n[]){
int value=0; int max=0;
for (int i=0;i<n.length;++i){
int count=0;
for (int j=0; j<n.length; ++j){
if (n[j]==n[i]) ++count;
}
if (count>max){
max=count;
value=n[i];
}
}
return value;
}
}
Here is my main method.
import java.util.*;
public class StatisticsTester {
public static void main(String[] args) {
Statistics test = new Statistics();
Scanner input = new Scanner(System.in);
//Read user input.
System.out.print("How many numbers do you want to enter?: ");
int num = input.nextInt();
double array[] = new double[num];
System.out.println("Enter the " + num + "numbers now.");
for (int i = 0; i < array.length; i++ )
{
array[i] = input.nextInt();
}
System.out.print("Here is the minimum, ");
System.out.print("maximum, mean, median, ");
System.out.println("mode, and standard deviation: ");
System.out.print(test.findMin(num) +", " + test.findMax(num));
System.out.print(", "+ test.calcMean(num) +", ");
System.out.print(test.calcMedian(num) +", ");
System.out.print(test.calcMode(num) +", ");
System.out.print(test.calcDeviation(num));
}
}
These are the errors when it compiles.
StatisticsTester.java:25: findMin(int[]) in Statistics cannot be applied to (int)
System.out.print(test.findMin(num) +", " + test.findMax(num));
^
StatisticsTester.java:25: findMax(int[]) in Statistics cannot be applied to (int)
System.out.print(test.findMin(num) +", " + test.findMax(num));
^
StatisticsTester.java:26: calcMean(int[]) in Statistics cannot be applied to (int)
System.out.print(", "+ test.calcMean(num) +", ");
^
StatisticsTester.java:27: calcMedian(int[]) in Statistics cannot be applied to (int)
System.out.print(test.calcMedian(num) +", ");
^
StatisticsTester.java:28: calcMode(int[]) in Statistics cannot be applied to (int)
System.out.print(test.calcMode(num) +", ");
^
StatisticsTester.java:29: calcDeviation(int[]) in Statistics cannot be applied to (int)
System.out.print(test.calcDeviation(num));
^
6 errors
There are two errors :
First : When you do this - test.findMin(num) you are trying to pass parameter num. But num is not array! It is a number. You probably want to do this : test.findMin(array)
Second : You can implicitly convert integer to double, because you can be sure that it remains same. But you cant convert double to integer implicitly, because you cant convert for example 2,7 to integer. And for arrays, even the "implicit" conversion does not work.
Solution for you, change this line double array[] = new double[num]; to int array[] = new int[num]; and then change all your parameters which looks like this test.findMin(num) to this test.findMin(array)
For working with doubles this would compile (does not know if it works as expected) :
import java.util.*;
public class StatisticsTester {
public static void main(String[] args) {
Statistics test = new Statistics();
Scanner input = new Scanner(System.in);
//Read user input.
System.out.print("How many numbers do you want to enter?: ");
int num = input.nextInt();
double array[] = new double[num];
System.out.println("Enter the " + num + "numbers now.");
for (int i = 0; i < array.length; i++) {
array[i] = input.nextDouble();
}
System.out.print("Here is the minimum, ");
System.out.print("maximum, mean, median, ");
System.out.println("mode, and standard deviation: ");
System.out.print(test.findMin(array) + ", " + test.findMax(array));
System.out.print(", " + test.calcMean(array) + ", ");
System.out.print(test.calcMedian(array) + ", ");
System.out.print(test.calcMode(array) + ", ");
System.out.print(test.calcDeviation(array));
}
}
import java.util.*;
import java.lang.Math;
public class Statistics {
private double min;
private double max;
private double mean;
private double median;
private double deviation;
private double mode;
public static double findMin(double[] array) {
double min = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min;
}
public static double findMax(double[] array) {
double max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}
public static double calcMean(double[] n) {
int sum = 0;
for (int i = 0; i < n.length; i++) {
sum += n[i];
}
return sum / n.length;
}
public static double calcMedian(double[] n) {
int middle = n.length / 2;
if (n.length % 2 == 1) {
return n[middle];
} else {
return (n[middle] + n[middle]) / 2;
}
}
public static double calcDeviation(double[] n) {
int mean = (int) calcMean(n);
int squareSum = 0;
for (int i = 0; i < n.length; i++) {
squareSum += Math.pow(n[i] - mean, 2);
}
return Math.sqrt((squareSum) / (n.length - 1));
}
public static double calcMode(double n[]) {
double value = 0;
int max = 0;
for (int i = 0; i < n.length; ++i) {
int count = 0;
for (int j = 0; j < n.length; ++j) {
if (n[j] == n[i]) {
++count;
}
}
if (count > max) {
max = count;
value = n[i];
}
}
return value;
}
}
Other than the bad format why cant this just print out them all once. I dont think im storing it in the array right or at all. So If you guys could please help me with where I am in the wrong it would be greatly appreciated
import java.util.*;
public class LetCount {
public static final int NUMCHARS = 26 + 1; //You define
public static int addr(char ch) {
return (int) ch - (int) 'A' + 1;
}
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in); // for reading input
int[] count = new int [NUMCHARS];
int curIndex = 0;
int max = 0;
System.out.println("Enter text to be read");
while (keyboard.hasNext()) {
String str1 = keyboard.nextLine().toUpperCase();
char ch = str1.charAt(curIndex);
for(curIndex = 0; curIndex < str1.length(); curIndex++) {
ch = str1.charAt(curIndex);
if (ch >= 'A' && ch <= 'Z') {
addr(ch);
count[ch - 'A']++;
}
for (int i = 0; i > 26; ++i) {
int highest;
highest = count[i];
System.out.printf(" %c ", i + 'A');
System.out.println("occurred " + count[i] + " times");
if (highest >= max) {
if (highest > max) {
max = highest;
}
}
}
System.out.println(max);
}
}
}
}
A couple of issues in your code:
You were calculating string length number of times.
Your for loop reads this: for (int i = 0; i > 26; ++i) { It should be for (int i = 0; i < 26; ++i) {
You were printing the entire array string length number of times.
You do not need to use the function addr anymore.
Following is the corrected code:
import java.util.*;
public class LetCount {
public static final int NUMCHARS = 26 + 1; //You define
public static int addr(char ch) {
return (int) ch - (int) 'A' + 1;
}
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in); // for reading input
int[] count = new int [NUMCHARS];
int curIndex = 0;
int max = 0;
System.out.println("Enter text to be read");
while (keyboard.hasNext()) {
String str1 = keyboard.nextLine().toUpperCase();
char ch = str1.charAt(curIndex);
for(curIndex = 0; curIndex < str1.length(); curIndex++) {
ch = str1.charAt(curIndex);
if (ch >= 'A' && ch <= 'Z') {
// addr(ch); No need to use this
count[ch - 'A']++;
}
}
int highest;
for (int i = 0; i < 26; ++i) { //you had the < sign wrong here.
highest = count[i];
if (highest >= max) {
if (highest > max) {
max = highest;
}
}
}
//print the entire thing only once.
for (int i = 0; i < 26; ++i) {
System.out.printf(" %c ", i + 'A');
System.out.println("occurred " + count[i] + " times");
}
System.out.println("Maximum is " + max);
}
}
}