Format the output in JAVA - java

I am little confused about how I can format my output cleanly like the output given below:
My code:
import java.io.*;
import java.util.Scanner;
public class CountChar {
public static void main(String[] args) {
File file = new File("test1.txt");
BufferedReader reader = null;
int numCount = 0;
int otherCount = 0;
Scanner sc = new Scanner(System.in);
System.out.println("Please specify the # of intervals: ");
int N = sc.nextInt();
while (true) {
if (N == 2 || N == 4 || N == 5 || N == 10) {
break;
} else {
System.out.println("Your input is not supported, please choose another value: ");
N = sc.nextInt();
}
}
int interval_at = 100 / N;
int[] histogram = new int[N];
try {
reader = new BufferedReader(new FileReader(file));
String text = null;
while ((text = reader.readLine()) != null) {
int num = 0;
try {
num = Integer.parseInt(text);
if (num > 0 && num <= 100) {
numCount++;
int inRange = (num - 1) / interval_at;
histogram[inRange] = histogram[inRange] + 1;
} else {
otherCount++;
}
} catch (NumberFormatException e) {
otherCount++;
continue;
}
}
// creating a file in which the output is stored
File myObj = new File("result1.txt");
if (myObj.createNewFile()) {
System.out.println("File created: " + myObj.getName());
} else {
System.out.println("File already exists.");
}
// Writting in a file
FileWriter myWriter = new FileWriter("result1.txt");
myWriter.write("Please specify the # of intervals: ");
myWriter.write("\n" + N);
myWriter.write("\nNumber of integers in the interval [1,100]: " + numCount);
myWriter.write("\nOthers: " + otherCount);
for (int i = 0; i < N; i++) {
myWriter.write("\n" + ((i * interval_at) + 1) + " - " + ((i + 1) * interval_at) + " | ");
for (int j = 0; j < histogram[i]; j++) {
myWriter.write("*");
}
}
myWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
My code output:
1 - 25 | ****************
26 - 50 | *******************
51 - 75 | ***********************
76 - 100 | **********************
I need to format my output as given in the picture above.

Related

Can this lengthy if-else Java code be improved by using arrays?

I'm trying to simplify this Java code by adding arrays, but I'm having difficulty.
The code that I have so far that works:
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Homework4A {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
char number0 = '0';
char number1 = '1';
char number2 = '2';
char number3 = '3';
char number4 = '4';
char number5 = '5';
char number6 = '6';
char number7 = '7';
char number8 = '8';
char number9 = '9';
int count0 = 0;
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
int count5 = 0;
int count6 = 0;
int count7 = 0;
int count8 = 0;
int count9 = 0;
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) == number0) {
count0++;
}
else if (line.charAt(i) == number1) {
count1++;
}
else if (line.charAt(i) == number2) {
count2++;
}
else if (line.charAt(i) == number3) {
count3++;
}
else if (line.charAt(i) == number4) {
count4++;
}
else if (line.charAt(i) == number5) {
count5++;
}
else if (line.charAt(i) == number6) {
count6++;
}
else if (line.charAt(i) == number7) {
count7++;
}
else if (line.charAt(i) == number8) {
count8++;
}
else if (line.charAt(i) == number9) {
count9++;
}
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
System.out.println(" 0 " + count0);
System.out.println(" 1 " + count1);
System.out.println(" 2 " + count2);
System.out.println(" 3 " + count3);
System.out.println(" 4 " + count4);
System.out.println(" 5 " + count5);
System.out.println(" 6 " + count6);
System.out.println(" 7 " + count7);
System.out.println(" 8 " + count8);
System.out.println(" 9 " + count9);
System.out.println(" -----------");
}
}
}
However, it's kind of a brute-force attack. The spot of difficulty I'm running into is figuring out where to create and pass arrays. Since the code has to read the external file, should the arrays be created and passed in the while statement?
For further reference, the text file that is being read looks like this:
Thistle Map
The goal is to count the occurrences of digits only.
As you stated, you could use arrays.
I would suggest 2 arrays
One to hold the digits to catch
Second one for the counts
Initialization of the arrays
char[] numbers = new char[10];
//initialize of numbers(char) to count
for(int i = 0; i < numbers.length; i++) {
numbers[i] = (char) ('0' + i);
}
int[] counts = new int[10]; //no initialization needed because int is default 0
In the for-loop where you iterate over the line, add a nested for loop, that iterates over the numbers-array. Here is the whole while loop:
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
for(int j = 0; j < numbers.length; j++) {
if(line.charAt(i) == numbers[j]) {
counts[j]++;
}
}
}
}
For the output just use another for over the arrays:
for(int i = 0; i < numbers.length; i++) {
System.out.println(" "+ numbers[i] +" " + counts[i]);
}
Edit: Another solution using a Map
//...
Map<Character, Integer> charCounts = new HashMap<>();
for (int i = 0; i < 10; i++) {
charCounts.put((char) ('0' + i), 0);
}
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
charCounts.computeIfPresent(line.charAt(i), (key, val) -> val + 1);
}
}
//...
for (Character number : charCounts.keySet()) {
System.out.println(" " + number + " " + charCounts.get(number));
}
With this solution you can easily extend your program to count any occuring character. Just remove the initialization of the map and add this line below the computeIfPresent.
charCounts.putIfAbsent(line.charAt(i), 1);
With Java 8 you can use Files.lines to get a Stream of all the lines in a file.
Then you can transform the stream to a stream over every char using flatMap and in the end collect it to a map that has the Character as key and the count of the character as value.
try (Stream<String> stream = Files.lines(Paths.get(fileName)) {
Map<Character, Long> charCountMap = stream
.flatMap(line -> line.chars().mapToObj(c -> (char) c))
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
System.out.println(" 0 " + charCountMap.getOrDefault('0', 0));
} catch (IOException e) {
e.printStackTrace();
}
Probably the way I would do it in a real world scenario, because it's short, but just for practice the other answers are better.
Yes. I would say it can be simplified a great deal with an array. You don't need seperate sentinels for the values, you can check they are in range and then use Character.digit to parse them. Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
int[] count = new int[10];
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
if (line.charAt(i) >= '0' && line.charAt(i) <= '9') {
count[Character.digit(line.charAt(i), 10)]++;
}
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
for (int i = 0; i < count.length; i++) {
System.out.printf(" %d %d%n", i, count[i]);
}
System.out.println(" -----------");
}
You can use a single array for this and index notation. Each array index should hold the quantity of digits. Much more clear.
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Homework4A {
public static void main(String[] args) throws FileNotFoundException {
Scanner scan = new Scanner(System.in);
System.out.print("Enter name of the input file: ");
String fileName = scan.next();
try (Scanner inFile = new Scanner(new FileReader(fileName))) {
int[] count = new int[10];
while (inFile.hasNextLine()) {
String line = inFile.nextLine();
for (int i = 0; i < line.length(); i++) {
try {
int c = Character.getNumericValue(line.charAt(i));
count[c] += 1;
} catch (Exception e) { }
}
}
System.out.println("\n-= Count of Thistles in =-");
System.out.println("-= the Hundred Acre Wood =-\n");
System.out.println(" -----------");
System.out.println(" type count");
System.out.println(" -----------");
for (int i = 0; i < 10; i++)
System.out.println(" " + i + " " + count[i]);
System.out.println(" -----------");
}
}
}

Decimal to Binary conversion using java Errors

I am kind of confused is my program correct or I am missing something!
I could get an output out of it.
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter you String: ");
String bin = sc.nextLine();
int length = bin.length();
int j = 0;
int sum = 0;
if (length != 0) {
for (int i = length - 1; i >= 0; i--) {
if (bin.charAt(i) == "0" || bin.charAt(i) == "1") {
String s = bin.charAt(j) + "";
sum = (int) (sum + (Integer.valueOf(s)) * (Math.pow(2, i)));
j++;
} else {
System.out.println("illegal input.");
}
}
System.out.println(sum);
} else {
System.out.println("illegal input.");
}
}
Remove the quotation marks on this line:
if (bin.charAt(i) == "0" || bin.charAt(i) == "1") {
should become
if (bin.charAt(i) == 0 || bin.charAt(i) == 1) {
Below code works fine:
import java.util.Scanner;
public class test {
public static void main (String args []) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter you String: ");
String bin = sc.nextLine();
int length = bin.length();
int j = 0;
int sum = 0;
if (length != 0) {
for (int i = length - 1; i >= 0; i--) {
if (bin.charAt(i) == '0' || bin.charAt(i) == '1') {
String s = bin.charAt(j) + "";
sum = (int) (sum + (Integer.valueOf(s)) * (Math.pow(2, i)));
j++;
} else {
System.out.println("illegal input.");
}
}
System.out.println(sum);
} else {
System.out.println("illegal input.");
}
}
}

Reading from a .txt file

You are given a text file (customer.txt) in which name, lastname and age of customers are stored:
Ali Aslan 25
Ayse Demir 35
Ahmet Gemici 17 .
.
.
You should process this file and find number of customers for each of the following ranges:
0 - 19
20 - 59
60 -
This is my code:
import java.io.*;
import java.util.*;
public class ass11 {
public static void main(String[] args) {
Scanner inputStream = null;
try {
inputStream = new Scanner(new FileInputStream("customer.txt"));
}
catch (FileNotFoundException e) {
System.out.println("file customer.txt not found");
System.exit(0);
}
int next, x = 0, y = 0, z = 0, sum = 0;
while(inputStream.hasNextInt()) {
next = inputStream.nextInt();
sum = sum + next;
if (next >= 60)
x++;
else if (next >= 19 && next <= 59)
y++;
else
z++;
}
inputStream.close();
System.out.println(x + " customer bigger than 60");
System.out.println(y + " customer between 19 and 59");
System.out.println(z + " customers smaller then 19");
}
}
It reads only numbers. When I write a name and surname to the text file, it doesn't work and I don't use the split() method...
I would recommend testing with the original file:
Ali Aslan 25
Ayse Demir 35
Ahmet Gemici 17
Each line is a name plus age, so you would get a code like:
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("path/to/file" ), "UTF-8"));
String line;
while ((line = reader.readLine()) != null) {
String[] contents = line.split(" ");
// Assume contents is 3 long: name, surname, age
System.out.printf("%s %s is %d", contents[0], contents[1], Integer.parseInt(contents[2]));
}
Yes, this does make use of the split method, which makes it easier in my opinion. You could also use the Scanner by calling it in a loop with next(), next() and nextInt()
Try this code. It works.
import java.io.BufferedReader;
import java.io.FileReader;
public class MyProject {
public static void main(String [] args){
String path = "C:/temp/stack/scores.txt";
processTextFile(path);
}
public static void processTextFile(String filePath) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filePath));
String line = br.readLine();
String [] tokens = null;
int score = 0;
int x = 0;
int y = 0;
int z = 0;
while (line != null) {
tokens = line.split(" ");
score = Integer.parseInt(tokens[tokens.length -1]);
if(score >= 0 && score < 20){
x++;
}
if(score >= 20 && score < 60){
y++;
}
if(score > 60){
z++;
}
line = br.readLine();
}
if (br != null) {
br.close();
}
System.out.println("0-20 = " + x + ", 20-60 = " + y + ", 60+ = " + z);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

Amicable numbers Java program

So I am having this strange output in which only the first number is checked twice while the second number is not even considered.Please help.
Code :-
import java.util.Scanner;
public class Amicable
{
private static int a,b;
private static String m,n;
public static void main()
{
acceptNumbers();
if (firstNumber() == secondNumber())
{
System.out.println(a+" and "+b+" are amicable numbers");
}
else System.out.println(a+" and "+b+" are not amicable numbers");
}
public static void acceptNumbers()
{
Scanner sc = new Scanner(System.in);
int count=0;
System.out.print("Enter two numbers [ separated by a ',' ] : ");
String input = sc.nextLine();
System.out.println();
for (int i = 0; i < input.length(); i++)
{
char c = input.charAt(i);
if (c == ',')
{
count++;
if (count == 1)
{
m = input.substring(0,i);
n = input.substring(0,i);
}
break;
}
}
if (count == 0)
{
System.out.println("Invalid operation : You have entered only 1 number");
}
m = m.trim(); n = n.trim();
a = Integer.valueOf(m);
b = Integer.valueOf(n);
}
public static int firstNumber()
{
int a1,a2=0;
for (int i = 0; i < m.length()-1; i++)
{
a1 = Integer.valueOf(m.charAt(i));
if (a%a1 == 0) a2 = a2+a1;
}
return a2;
}
public static int secondNumber()
{
int b1,b2=0;
for (int i = 0; i < n.length()-1; i++)
{
b1 = Integer.valueOf(n.charAt(i));
if (b%b1 == 0) b2 = b2+b1;
}
return b2;
}
}
And here is the output :-
Enter 2 numbers [ separated by a ',' ] : 248 , 222
248 and 248 are amicable numbers
your m and n are equal, because you have:
m = input.substring(0,i);
n = input.substring(0,i);
change it to:
m = input.substring(0,i);
n = input.substring(i+1);
Btw you are doing a lot of unnecessary stuff, complete solution (I don't care about exceptions):
import java.util.Scanner;
public class Amicable {
public static void main(String args[]) {
try {
Scanner sc = new Scanner(System.in);
System.out.print("Enter two numbers [ separated by a ',' ] : ");
String input = sc.nextLine();
String[] numbers = input.split(",");
int num1 = Integer.parseInt(numbers[0].trim());
int num2 = Integer.parseInt(numbers[1].trim());
int sum1 = 0, sum2 = 0;
for (int i = 1; i <= num1; i++) {
if (num1 % i == 0)
sum1 += i;
}
for (int i = 1; i <= num2; i++) {
if (num2 % i == 0)
sum2 += i;
}
if (sum1 == sum2)
System.out.println(num1 + " and " + num2
+ " are amicable numbers");
else
System.out.println(num1 + " and " + num2
+ " are not amicable numbers");
} catch (Exception e) {
e.printStackTrace();
}
}
}
parts of code from: http://www.daniweb.com/software-development/java/code/304600/amicable-numbers
a and b are derived from m and n, and the latter are initialized to exactly the same value:
m = input.substring(0,i);
n = input.substring(0,i);
Did you mean to set n to
n = input.substring(i+1);
?
m = input.substring(0,i);
n = input.substring(0,i);
m and n are having the same value.
n should be:
n = input.substring(i+1);
And now the second number will be assigned to n.

Java skipping a number in the sequence

This is very interesting, i notice. Before i can explain further its best i show the code and you will understand what i mean.
This is the code:
public class Qn3 {
static BigDecimal[] accbal = new BigDecimal[19];
private static Integer[] accnums = new Integer[19];
public static void main(String[] args) {
addaccount();
}
public static void addAccount() {
int i = 0, accno, input, j, check;
BigDecimal accbala;
DecimalFormat df = new DecimalFormat("0.00");
Scanner sc = new Scanner(System.in);
Scanner in = new Scanner(System.in);
accnums[1] = new Integer(1);
while (accnums.length >= count(accnums)) {
System.out.print("Enter the account number: ");
while (sc.hasNext("[0-9]{7}")) {
accno = sc.nextInt();
System.out.print("Enter account balance: ");
accbala = in.nextBigDecimal();
for (j = 0; j < accnums.length; j++) {
if (accnums[j] == null)
break;
else if (accnums[j].equals(accno)) {
break;
}
}
if (j == accnums.length) {
System.out.print("No more than 20 accounts can be added.");
} else if (accnums[j] != null) {
if ((accnums[j].equals(accno)))
System.out.println("Account already exists");
break;
} else {
accnums[j] = accno;
accbala = accbala.setScale(2, RoundingMode.HALF_UP);
accbal[j] = accbala;
check = j;
System.out.println("Current number of accounts in the system: "
+ (check + 1)
+ "\nNumber of accounts still can be added: "
+ (20 - (check + 1)));
}
}
while (!sc.hasNext("[0-9]{7}")) {
System.out.println("Wrong NRIC");
break;
}
while (accnums.length <= count(accnums)) {
System.out.println("20 accounts have already been created");
break;
}
break;
}
}
private static int count(Integer[] array) {
int count = 0;
// accnums = new Integer[] {1,2};
for (int index = 0; index < array.length; index++) {
if (array[index] != null) {
count++;
}
}
// System.out.println("You have used " + count + " slots");
return count;
}
}
So now that you have seen the code the problem that is hard to notice is this, take note of the line in the addaccount() method where
System.out.println("Current number of accounts in the system: "+(check+1)+"\nNumber of accounts still can be added: "+(20 - (check+1)));
this line the first check+1 will give me 1 then the next one gives me 3! and then the next time i run the method it gives me 4 and then again 5 and so on so forth, what is happening to 2?
You have that println in an else block, and when j == 1 you're hitting the else if case. Try removing this line
accnums[1] = new Integer (1);

Categories