code keep giving me exception. im not sure why - java

sorry if this is not allowed. it's my first time asking a question. anyways I'm supposed to implement a program that read a grade level base on the text.
"Implement a program that computes the approximate grade level needed to comprehend some text, per the below.
Text: Congratulations! Today is your day. You're off to Great Places! You're off and away! Grade 3"
after finishing the code. every time I compile it, it gives me an exception that I'm dividing by zero. almost like after I ask the user to enter the text, it's not read at all in letter count to it stays at zero. I'm not sure how to go around it.
here's my code below
import java.util.*;
import java.lang.Math;
public class Readability {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int letterCount=0;
int wordCount = 0;
int sentenceCount = 0;
// Just taking the input
System.out.println("Please provide some text as input");
String text = sc.nextLine();
for (int i = 0; i< text.length(); i++) {
// checking letters
if ((text.charAt(i) == 'a' && text.charAt(i) == 'z') || (text.charAt(i) == 'A' && text.charAt(i) == 'Z' ))
{
letterCount++;
}
// any chars separated by space is a word
if (text.charAt(i) == ' ' || text.charAt(i) == '\0')
{
wordCount++;
}
// when you see a . ! or ? count as sentence
if (text.charAt(i) == '!' || text.charAt(i) == '.'|| text.charAt(i) == '?')
{
sentenceCount++;
}
}
double averageWordsPer100 = (letterCount * 100) / wordCount;
double averageSentencePer100 = (sentenceCount * 100) / wordCount;
int readingIndex = (int) Math.round(0.0588 * averageWordsPer100 - 0.296 * averageSentencePer100 - 15.8);
if (readingIndex < 1)
{
System.out.println("Before Grade 1");
}
else if (readingIndex > 16)
{
System.out.println("Grade 16");
}
else
{
System.out.println("Grade " + readingIndex);
}
}
}

I compiled and executed the project and no problem is shown, except when the input has 0 words. To avoid the divided by 0 exception you can add this piece of code:
int readingIndex = 0;
if (wordCount != 0){
double averageWordsPer100 = (letterCount * 100) / wordCount;
double averageSentencePer100 = (sentenceCount * 100) / wordCount;
readingIndex = (int) Math.round(0.0588 * averageWordsPer100 - 0.296 * averageSentencePer100 - 15.8);
}
You can set the initial value of readingIndex to the value you want. Then, if the wordCount is 0, the readingIndex initial value will be used.

Related

I dont understand why my Java code isnt reading IX as 9 but is reading LIX as 59

I am trying to create some code to read roman numerals and turn them into an integer. the issue im having is the 9s and 4s. I am able to get it to read if the 9 or 4 is inside a number (I.E LIV is 54 and LXI is 59) but by its self (IV and IX) it only reads 6 and 11.
here is my code:
public static void RomantoInt(String s) {
HashMap<Character, Integer> RomanNums = new HashMap<>();
int count = 0;
RomanNums.put('I', 1);
RomanNums.put('V', 5);
RomanNums.put('X', 10);
RomanNums.put('L', 50);
RomanNums.put('C', 100);
RomanNums.put('D', 500);
RomanNums.put('M', 1000);
LinkedList<Character> UserInput = new LinkedList<>();
//Adds Each numeral to the Array
for (int i = 0; i < s.length(); i++) {
char userint = s.charAt(i);
UserInput.add(userint);
}
//loop through the array backwards and adds up the count.
for(int j =UserInput.toArray().length -1; j> -1 ; j--) {
int grab = RomanNums.get(UserInput.get(j));
count += grab;
// Checks for 4s and 9s.
if(grab == RomanNums.get('X') && (j - 1) == RomanNums.get('I')) {
count -= 2;
}
}
System.out.println(count);
Comparing j - 1 -- which is a position in a string -- to the value of a roman numeral does not seem to make any sense.
Specifically, it only works when the roman 'I' is the second character, exactly.
What you really want to be testing is whether the character at the (j-1)'th position is 'I'.
The correct formulation should be something like
if (grab == RomanNums.get('X') &&
j > 0 &&
UserInput.get(j-1) == 'I') ...
This was my solution for leetcode: https://leetcode.com/problems/roman-to-integer/
You have the right idea about reading the input backwards and one loop should be enough to get the job done.
All you need to do is account for the cases when you have to subtract the roman numeral, and you can do that by keeping track of the previous roman numeral for comparison.
For example when input string is: "IX"
We start at 'X' in the first iteration and since previous is equal to '?' we just add 10 and set previous to 'X'. Now when we attempt to sum up 'I' in the next iteration, we look at previous and notice that it is an 'X' and instead of adding 1 to the running sum , we should subtract 1. The total should be 9.
public int romanToInt(String s) {
int sum = 0;
char prev = '?';
for(int i = s.length()-1;i >= 0;i--) {
switch(s.charAt(i)) {
case 'I' : sum += prev == 'V' || prev == 'X' ? -1 : 1;
break;
case 'V' : sum += 5;
break;
case 'X' : sum += prev == 'L' || prev == 'C' ? -10 : 10;
break;
case 'L' : sum += 50;
break;
case 'C' : sum += prev == 'D' || prev == 'M' ? -100 : 100;
break;
case 'D' : sum += 500;
break;
case 'M' : sum += 1000;
break;
default :
break;
}
prev = s.charAt(i);
}
return sum;
}
Time complexity is O(n) - Iterated the length of the input string
Space complexity is O(1) - No additional data structure was needed

Adding individual digits from a string

I'm trying to add 13 individual digits from a string together. I thought using a while loop would be the best way to do this, but I think I messed something up. Here's my code:
import java.util.Scanner;
public class ISBNChecker{
public static void main(String [] args){
String isbnNumber;
int isbnTotal= 0;
int index = 0;
Scanner scnr = new Scanner(System.in);
System.out.println("Enter a 13 digit ISBN Number:");
isbnNumber = scnr.nextLine();
if (isbnNumber.length() != 13) {
System.out.println("Error- 13 numerical digits required");
}
char num = isbnNumber.charAt(index);
while (index <13) {
if (index % 2 == 0) {
isbnTotal = isbnTotal + num;
index =index + 1;
}
else {
isbnTotal = isbnTotal + (3 * num);
index = index + 1;
}
}
System.out.println(isbnTotal);
if (isbnTotal % 10 == 0) {
System.out.println("Valid ISBN Number");
}
else {
System.out.println("Invalid ISBN Number");
}
}
}
I'm using the input 9780306406157, which should be an invalid ISBN Number. The value of isbnTotal at the end of the program should be 100, but instead, it is 1425. Any help in figuring out how to fix it would be appreciated.
Also, the formula I'm using for the problem is x1 + 3x2 + x3 + 3x4 ... +x 13 for reference!
I found your bug, you made some mistake.
int index = 0;
while (index < 13) {
char num = (char) (isbnNumber.charAt(index) - '0');
if (index % 2 == 0) {
isbnTotal = isbnTotal + num;
} else {
isbnTotal = isbnTotal + (3 * num);
}
index++;
}
Problem #1
The code
char num = isbnNumber.charAt(index);
Was not in your while loop, causing your code to always run with the same character.
Problem #2
When doing
char num = isbnNumber.charAt(index);
You are actually getting the ASCII value of the character. What you cant to get is the value of the number right ? So you have to do:
char num = (char) (isbnNumber.charAt(index) - '0');
Notice that the zero is between two single quote, that because we want the value of the ZERO ASCII CHARACTER (which is 38).
'1' - '0' = 1
'9' - '0' = 9
EDIT: I forgot to mention that you should check before if the character is a number, else you will maybe try to do something like 'A' - '0' which will be equal to 17
Here is a detailed working code for your ISBN checker
import java.util.Scanner;
public class ISBNChecker{
public static void main(String [] args){
String isbnNumber;
int isbnTotal= 0;
int index = 0;
Scanner scnr = new Scanner(System.in);
System.out.println("Enter a 13 digit ISBN Number:");
isbnNumber = scnr.nextLine();
if (isbnNumber.length() != 13) {
System.out.println("Error- 13 numerical digits required");
}
//Perform other operations if it's length is 13
else{
//initiliizing num for 1st time + convert the character at index to
number
int num = Character.getNumericValue(isbnNumber.charAt(index));
while (index <13) {
if (index % 2 == 0) isbnTotal = isbnTotal + num;
else isbnTotal = isbnTotal + (3 * num);
//increment outside of if else - less code
index = index + 1;
//verify if index is not out of bounds for charAt()
//then change num value + conversion
if(index<13 )
num = Character.getNumericValue(isbnNumber.charAt(index));
}
System.out.println(isbnTotal);
if (isbnTotal % 10 == 0) System.out.println("Valid ISBN Number");
else System.out.println("Invalid ISBN Number");
}
}
}
As mentioned in the answer below, nextLine() gets input in ASCII characters and it is important to convert that into numbers when there are numerical calculations involved.
Well, it seems that you do allow string inputs longer or shorter than 13.
Then you should return after this line:-
System.out.println("Error- 13 numerical digits required");
Otherwise, the code will run even if it's not at the wanted length

Using a return value from a method in another method

I'm trying to use the return value "average" in calcAverage method into the determineGrade method to get out a char value (A B C D F).
However, it repeats the loop when I code this way. Is there a way to just get the return value from the calcAverage and not have to execute the loop again and ask the same test scores?
package Chapter5;
import java.util.Scanner;
public class TestAverageAndGradewithLoop {
public static void main(String[] args) {
Scanner input = new Scanner (System.in);
System.out.print("How many tests?: ");
int test = input.nextInt();
System.out.print("Average test score is: " + calcAvergage(test) );
int mark = calcAvergage(test);
System.out.print("Letter grade is: " + determineGrade(mark) );
}
public static int calcAvergage(int test){
Scanner input = new Scanner (System.in);
int total = 0;
int x;
for (x = 1; x <= test; x++)
{
System.out.print("What is the score for test " + x + " : ");
int scores = input.nextInt();
total = total + scores;
}
int average = total/(x-1); //have to do -1 because the final increment value of x is stored as x+1
return average;
}
public static char determineGrade(int average)
{
char mark = 0;
if (average >= 90 && average <= 100)
{
mark = 'A';
}
else if (average >= 80 && average <= 89)
{
mark = 'B';
}
else if (average >= 70 && average <= 79)
{
mark = 'C';
}
else if (average >= 60 && average <= 69)
{
mark = 'D';
}
else if (average <= 60)
{
mark = 'F';
}
return mark;
}
}
Instead of this:
System.out.print("Average test score is: " + calcAvergage(test) );
int mark = calcAvergage(test);
Do this
int mark = calcAvergage(test);
System.out.print("Average test score is: " + mark );
There is no need to call the function twice when you are playing with the return value. Assign it to a variable and then use it.
Like this?
int mark = calcAvergage(test);
System.out.print("Average test score is: " + mark);
From my understanding you do not want to input a number then press enter then enter another number then press enter and so on...
If you say you have 3 test cases in console just type 3 space separated numbers like 10 12 3.
Your question is confusing and your code has logical errors, im sorry. You have if statements using the same logic.(example below) I would say learn up more on programming logic and you will answer your own question
else if (average >= 60 && average <= 69)
{
mark = 'D';
}
else if (average <= 60)
{
mark = 'F';
}
Thx to Avinash Raj for the pointer. I understand now.
the result of the calcAverage is stored in the variable mark, then I can use the int value from the result to both display what the score is as well as display and execute the determineGrade method.

Incremented by a value x but it gets incremented by value x-1

I am implementing an Algorithm where when user gives input string, every character in string (if it is alphabet) should be incremented by value given(here rotator). I am playing with this code for 2 hr but can't figure out why when i increment by value rotator, it gets incremented by rotator-1.
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner in = new Scanner(System.in);
int length = in.nextInt();
String input = in.next();
int nextvalue = 0;
int temp = 0;
char array[] = input.toCharArray();
int rotator = in.nextInt();
for(int i = 0; i < length; i++){
if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z')){
nextvalue = (int)array[i] + rotator;
array[i] = (char)nextvalue;
if((int)array[i] > (int)'z'){
temp = (int)array[i] - (int)'z';
nextvalue = (int)'a' + temp -1;
array[i] = (char)nextvalue;
}
else if((int)array[i] > (int)'Z'){
temp = (int)array[i] - (int)'Z';
nextvalue = (int)'Z' + temp -1;
array[i] = (char)nextvalue;
}
}
}
System.out.println(array);
}
}
Inside first if there are two if statements to handle(Overflow condition) if letter is > z or >Z. Now if I Remove those two statements everything except overflow condition is correctly printed
(without overflow condition)
Sample I/P :
11 <- String length
middle-Outz
2 <- rotator
Sample O/P :
okffng-Qwv| <- Overflow condition not handled
(with overflow condition)
Sample I/P :
11
middle-Outz
2
Sample O/P :
njeemf-Qvub <- Overflow handled but everything else incremented by rotator - 1 except 'Q'
Why is this happening? I also checked using print statement in inner if condition , it executes only one time for this input since there is only one overflow condition.
Help/Suggestion appreciated.Thanks.
I think the easiest way to handle the overflow cases is to use the modulus operator to let the character wrap-around any number of times to land in the current logical position. Something like this should work:
for (int i=0; i < length; i++) {
if (array[i] >= 'a' && array[i] <= 'z') {
int currDiff = (int)array[i] - (int)'a';
int newPos = (int)'a' + ((rotator + currDiff) % 26);
array[i] = (char)newPos;
}
else if (array[i] >= 'A' && array[i] <= 'Z') {
int currDiff = (int)array[i] - (int)'A';
int newPos = (int)'A' + ((rotator + currDiff) % 26);
array[i] = (char)newPos;
}
}
I tested this code using an input string of abcdefg and a rotator value of 51, which returned zabcdef. This is expected, because we rotated one step short of two complete rounds. Hence, the a landed on z, after one complete rotation, and the following characters followed suit.
Note that there is a much nicer way of handling the calculus of character positions here, but this answer stays true to the way you were doing it in your original question.
Final note:
The modulus operator % returns the remainder of the division of the number which preceeds it and proceeds it. In the solution I gave above, I take the effective rotator % 26. Here, the effective rotator is the current distance of the letter from either a or A plus however many steps we want to rotate. By taking this number mod 26, we always will end up with a number between 0 and 25. Hence, we will always take between 0 and 25 steps from a or A, which is the behavior you want in your program.
Because you are modifying it twice in your loop.
for(int i = 0; i < length; i++){
if((array[i] >= 'a' && array[i] <= 'z') || (array[i] >= 'A' && array[i] <= 'Z')){
nextvalue = (int)array[i] + rotator;
array[i] = (char)nextvalue; //<-- modifies from m to o
if((int)array[i] > (int)'z'){
temp = (int)array[i] - (int)'z';
nextvalue = (int)'a' + temp -1;
array[i] = (char)nextvalue;
}
else if((int)array[i] > (int)'Z'){
temp = (int)array[i] - (int)'Z';
nextvalue = (int)'Z' + temp -1;
array[i] = (char)nextvalue; //<--modifies again from o to n
}
}
}
The mistake is in this line:
if ((int) array[i] > (int) 'Z') {
You have to keep in mind that lowercase letters come "after" uppercase letters: 'Z' is represented by 90, and (for example) 'j ' is represented by 106 (for more info see this). The reason why 'Q' isn't affected by this mistake is because it is also a capital letter, and thus has a smaller decimal representation than 'Z'.
To fix this, you have to replace the line of code above with something along the lines of this:
if ((int) array[i] > (int) 'Z' && (int) array[i] <= (int) 'Z' + rotator) {
Instead of
nextvalue = (int)'Z' + temp -1;
Shouldn't it be
nextvalue = (int)'A' + temp -1;

lottery program without arrays with java

hello guys i am really stuck, its about a lottery program that randomly generate a four-digit number and prompt the user to enter a four-digit number without using array and following this rules
-if the user input match the lottery number in exact order the award is $10000
-if the user input match the four-digit in different order the award is $5000
-if the user input match the three-digit number in different order the award is $2000
-if any 1 or 2-digit in the user input match the lottery the award is $500
i did it for a 3-digit number but i don't know how to do it for a four-digit number without arrays.this is what i have done :
import java.util.Scanner;
public class Programming {
public static void main(String[] args) {
// Generate a lottery
int lottery = (int) (Math.random() * 1000);
// Prompt the user to enter a guess
Scanner input = new Scanner(System.in);
System.out.print("Enter your lottery pick (three digits): ");
int guess = input.nextInt();
// Get digits from lottery
int lotteryDigit1 = lottery / 100;
int lotteryDigit2 = (lottery % 100) / 10;
int lotteryDigit3 = lottery % 10;
// Get digits from guess
int guessDigit1 = guess / 100;
int guessDigit2 = (guess % 100) / 10;
int guessDigit3 = guess % 10;
System.out.println("The lottery number is " + lotteryDigit1
+ lotteryDigit2 + lotteryDigit3);
// Check the guess
if (guess == lottery) {
System.out.println("Exact match: you win $10,000");
} else if ((guessDigit1 == lotteryDigit2 && guessDigit2 == lotteryDigit1 && guessDigit3 == lotteryDigit3)
|| (guessDigit1 == lotteryDigit2
&& guessDigit1 == lotteryDigit3 && guessDigit3 == lotteryDigit1)
|| (guessDigit1 == lotteryDigit3
&& guessDigit2 == lotteryDigit1 && guessDigit3 == lotteryDigit2)
|| (guessDigit1 == lotteryDigit3
&& guessDigit2 == lotteryDigit2 && guessDigit3 == lotteryDigit1)
|| (guessDigit1 == lotteryDigit1
&& guessDigit2 == lotteryDigit3 && guessDigit3 == lotteryDigit2)) {
System.out.println("Match all digits: you win $5,000");
} else if (guessDigit1 == lotteryDigit1 || guessDigit1 == lotteryDigit2
|| guessDigit1 == lotteryDigit3 || guessDigit2 == lotteryDigit1
|| guessDigit2 == lotteryDigit2 || guessDigit2 == lotteryDigit3
|| guessDigit3 == lotteryDigit1 || guessDigit3 == lotteryDigit2
|| guessDigit3 == lotteryDigit3) {
System.out.println("Match one digit: you win $1,000");
} else {
System.out.println("Sorry, no match");
}
}
}
thank you for your help
Another Edit
Sorry for taking a while to get back to you. Been a busy couple days. As requested, here is the complete program. Note that this isn't entirely your original program. I removed a couple things and added a few more in. Perhaps most importantly, I changed the function that I gave you previously. I originally answered your question to try to only give you the four digit match but if I am writing out the whole thing it makes more sense to generalize a bit. Because your lottery awards are based on the number of matching digits, it makes a lot of sense to make a function that counts how many digits match. This simplifies your if-else code a whole lot.
import java.util.Scanner;
public class Programming {
/*
* get the number of matching digits between the guess and the
* answer, ignoring repeated matches
*/
public static int numberDigitsMatch(String guess, String answer) {
int numberMatch = 0;
int currentIndex = 0;
int matchingIndex;
while (currentIndex < guess.length()) {
// check if the current digit of the guess is in the answer
matchingIndex = answer.indexOf(guess.charAt(currentIndex));
if (matchingIndex < 0) {
currentIndex++;
}
else {
currentIndex++;
numberMatch++;
// remove the no longer relevant character from the answer
answer = answer.substring(0, matchingIndex) +
answer.substring(matchingIndex + 1);
}
}
return numberMatch;
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
// generate the winning number
int lotteryNumber = (int) (Math.random() * 10000);
String lotteryString = "" + lotteryNumber;
System.out.println("The lottery number is " + lotteryString);
// Prompt the user to enter a guess
System.out.print("Enter your lottery pick (four digits): ");
// get the user's guess
int guessNumber = in.nextInt();
String guessString = "" + guessNumber;
// NOTE: these guessDigit numbers are not necessary. I am leaving
// them here so you can see how to pick out individual digits
int guessDigit1 = guessNumber % 10;
int guessDigit2 = (guessNumber / 10) % 10;
int guessDigit3 = (guessNumber / 100) % 10;
int guessDigit4 = (guessNumber / 1000) % 10;
int lotteryDigit1 = lotteryNumber % 10;
int lotteryDigit2 = (lotteryNumber / 10) % 10;
int lotteryDigit3 = (lotteryNumber / 100) % 10;
int lotteryDigit4 = (lotteryNumber / 1000) % 10;
System.out.println("The lottery number is " + lotteryString);
int numMatchingDigits = numberDigitsMatch(guessString, lotteryString);
if (guessNumber == lotteryNumber) {
System.out.println("Exact match: you win $10,000");
}
else if (4 == numMatchingDigits) {
System.out.println("Match all digits: you win $5,000");
}
else if (3 == numMatchingDigits) {
System.out.println("Match three digits: you win $2,000");
}
else if (2 == numMatchingDigits) {
System.out.println("Match two digits: you win $500");
}
else if (1 == numMatchingDigits) {
System.out.println("Match two digit: you win $500");
}
else {
System.out.println("Sorry, no match");
}
}
}
Edit
Looks like I did not understand correctly. I believe there are multiple ways to get a given digit of a number but I think this is the easiest to think about. You divide by 1000 to shift the thousands digit into the 1's place then use the modulus operator to get rid of anything that isn't in the 1's place. This leaves you with nothing but the fourth digit of the number.
public static int getFourthDigit(int num) {
return (num / 1000) % 10;
}
Original
If I understand correctly, your difficulty is with matching different ordered four digit numbers. The most obvious way to do this is to just check all possible orderings of the four digits; there are only 15 where they are not exactly equal. However, typing out 15 conditions is prone to errors and just plain boring. It would be twice as boring and tedious if you instead needed to do this with five digits.
Here is a function that avoids this by using String instead of int. It repeatedly checks the first character of the guess and checks if the character is in the answer. It then removes that matching character from the answer to avoid a case like 1111 and 1112, where every character in the guess is also in the answer but they do not match.
public static boolean digitsMatch(String guess, String answer) {
int matchingIndex;
while (guess.length() > 0) {
// check if the first digit of the guess is in the answer
matchingIndex = answer.indexOf(guess.charAt(0));
// if not, there cannot possibly be four matches
if (matchingIndex < 0) {
return false;
}
// look at the rest of the guess
guess = guess.substring(1);
// and remove the no longer relevant character from the answer
answer = answer.substring(0, matchingIndex) +
answer.substring(matchingIndex + 1);
}
return true;
}

Categories

Resources