I am trying to make a calculator that adds and subtracts numbers entered from the user that are in parenthesis.
Here is a sample run:
Welcome to the Expression Program
Enter a line of expressions:
( 2 + 3 + -4 + 5 ) (6+7+8+-9)( 3 + -2 +7+0)
The value of “( 2 + 3 + -4 + 5 )” is 6
The value of “(6+7+8+-9)” is 12
The value of “( 3 + -2 +7+0)” is 8
Goodbye!
Welcome to the Expression Program
Enter a line of expressions:
(6) () (hello + friend ) ( 1 * 2 + 4 ) 7+8+9)
The value of “(6)” is 6
ERROR: “” is not an integer
ERROR: “hello” is not an integer
ERROR: “*” is not a valid operator
ERROR: Illegal start character ‘7’Goodbye!
This is what I have so far but it is not working:
import java.util.Scanner;
public class ExprParser
{
public static void main(String args[])
{
Scanner g=new Scanner(System.in);
System.out.println("Welcome to the Expression Program!");
System.out.println("Enter a line of expressions(between parenthesis):");
String exp=g.next();
String[] arr=exp.split("\\)");
for (int i = 0; i < arr.length; ++i)
{ System.out.println(arr[i]+")");
int result=calculate(arr[i]);
System.out.println(calculate(Integer.toString(result)));
}
}
public static int calculate(String a)
{
int sum=0;
for (int i=0;i<a.length();++i)
{
char sign='+';
a.indexOf(sign);
sum+=Integer.parseInt(a.substring(0,sign))+Integer.parseInt(a.substring(sign+1,sign));
}
return sum;
}
}
I think what you are looking for is Reverse Polish Notation which allows you to evaluate expressions. There is a video here that explains how it works: http://www.youtube.com/watch?v=QzVVjboyb0s
In this code:
char sign='+';
a.indexOf(sign);
sum+=Integer.parseInt(a.substring(0,sign))+Integer.parseInt(a.substring(sign+1,sign));
sign is a character, and characters are actually integer values. The character '+' has the value 43 (that's where the plus sign is on the ASCII chart). So you're trying to compute a.substring(0,43), which will get you an out-of-bounds error if a is shorter than 43 characters.
You used indexOf to find out where the '+' sign is, but you threw away the result. Store the result of indexOf in a variable, then use that variable, not sign, in the substring calls. Also make sure you handle the case when indexOf returns -1 (it can't find a plus sign); if you just pass that to a.substring, you'll get another out of bounds error.
Related
Trying to design a simple lottery program. Everything works except checking if the numbers entered are between 1 to 59.
Exercise says the numbers must be stored in a String variable.
so
if(num<0 || num>59) //wont work for me
Tried making another variable
int numConverted = Integer.parseInt(num)
We haven't covered converting String to int in class though so I don't think this is what expected. Got confused trying that way anyway so probably this is wrong.
Here is the code I have currently.
{
Scanner scan = new Scanner(System.in);
String num=""; //num variable is empty untill user inputs numbers
for(int i =0; i<6; i++)
{
System.out.println("Enter your number between 1-59");
num = num +" "+ scan.nextLine();
}
System.out.println("Ticket printed £2. Your numbers are " + num);
}
In your posted code it's obvious that you want the User to supply 6 specific numerical values. These values are appended to the String variable named num (space delimited). You need to obviously do a few things here:
1) Make sure the value supplied by the user is indeed a numerical value;
2) Make sure the numerical values supplied fall within the minimum and maximum scope of the lottery itself (which you have stated is: 1 to 59);
3) Make sure the number entered by the User hasn't been supplied already.
You've been tasked to store the entered values into a String data type variable and that is all fine but at some point you want to carry out value comparisons to make sure that all the entered values actually play within the limits of the lottery.
When the User completes his/her entries, you end up with a space delimited string held in the num string variable. You now need to make sure that these values entered are indeed....numbers from 1 to 59 and none contain alpha characters.
In my opinion (and this is only because you need to store entered values into a String variable), it's best to use your String variable to gather User input, then test the input to make sure it is indeed a string representation of an actual integer number. Once this is established then we test to make sure if falls within the value min/max limits (1-59). Now we need to test to make sure the number entered hasn't already been entered before for this ticket.
Of course with each test described above, if one fails then the User should be prompted to re-enter a proper value. You can do this by utilizing a while loop. Plenty examples of this in StackOverflow but here's a quick example:
Scanner scan = new Scanner(System.in);
String ticketNumbers = "";
for(int i = 0; i < 6; i++) {
Boolean isOK = false;
while (!isOK) {
System.out.println("\nPlease enter your desired 6 ticket numbers:\n"
+ "(from 1 to 59 only)");
String num = scan.nextLine();
//Is the string entered an actual integer number?
//We use the String.matches() method for this with
//a regular expression.
if(!num.matches("\\d+")) {
System.out.println("You must supply a numerical value! "
+ "Try Again...");
continue;
}
if (ticketNumbers.contains(num + " ")) {
System.out.println("The number you supplied has already been chosen!"
+ " Try Again...");
continue;
}
if (Integer.parseInt(num) >= 1 && Integer.parseInt(num) <= 59) {
ticketNumbers+= num + " ";
isOK = true;
}
else {
System.out.println("The number you supply must be from "
+ "1 to 59! Try Again...");
}
}
}
System.out.println("Ticket printed £2. Your numbers are " + ticketNumbers);
How about -
if(Integer.parseInt(num) < 0 || Integer.parseInt(num) > 59)
This should work, place it after the input.
If it works, please mark this as correct, I need the rep!!!
Easy way would be add available numbers (suppose it wont grow more than 60. You can use a loop to add to this as well)
String numbers[] = {"1","2","3", "..."};
Then inside the loop
Arrays.asList(numbers).contains(num);
You can remove prefixing zero in order avoid conflicts with values like '02'
Here everything is String related.
If you don't want to explicitly convert to int, you could use a regular expression.
if (num.matches("[1-5]?[0-9]")) {
...
This checks whether the String consists of (1) maybe a digit from 1 to 5, followed by (2) definitely a digit from 0 to 9. That'll match any number in the range 0-59.
If you've got a whole series of numbers separated by spaces, you could expand this to cover a whole series like this.
if (num.matches("([1-5]?[0-9]\\s+)*[1-5]?[0-9]")) {
This matches any number of repetitions (including zero) of "a number followed by spaces", followed by a single repetition without a space. The "\\s" means "any whitespace character", the "+" after it means "one or more of what precedes", and the "*" means "zero more of what precedes" - which in this case is the term in parentheses.
Oh I see what you are trying to do
This is what you want
Scanner scan = new Scanner(System.in);
String allNums = "";
for(int i =0; i<6; i++)
{
System.out.println("Enter your number between 1-59");
int num = scan.nextInt();//Take the number in as an int
if(num >0 && num < 59)//Check if it is in range
{
allNums += num + " ";//if it is add it to a string
}
else
{
System.out.println("Number not in range");
i--;//go back one iteration if its not in range
}
}
System.out.println("Ticket printed £2. Your numbers are " + allNums);
I've searched for this on the internet but was unable to find a precise solution, one possible solution I found was to read the integer as a String, and use charAt method and then cast the character to int to print the ascii value.
But is there any other possible way to do it other than the above stated method?
int a=sc.nextInt();
//code to convert it into its equivalent ASCII value.
For example, consider the read integer as 1, and now I want the ASCII value of 1 to be printed on the screen,which is 49
I assume you're looking for this:
System.out.print((char)a);
The easy way to do that is:
For the Whole String
public class ConvertToAscii{
public static void main(String args[]){
String number = "1234";
int []arr = new int[number.length()];
System.out.println("THe asscii value of each character is: ");
for(int i=0;i<arr.length;i++){
arr[i] = number.charAt(i); // assign the integer value of character i.e ascii
System.out.print(" "+arr[i]);
}
}
}
For the single Character:
String number="123";
asciiValue = (int) number.charAt(0)//it coverts the character at 0 position to ascii value
I'm reading my game map
FileHandle file = Gdx.files.internal("data/" + level + ".txt");
StringTokenizer tokens = new StringTokenizer(file.readString());
while(tokens.hasMoreTokens()){
String type = tokens.nextToken();
if(type.equals("Car")){
carLiist.add(new Car(Integer.parseInt(tokens.nextToken()), Integer.parseInt(tokens.nextToken()), Float.parseFloat(tokens.nextToken()), Float.parseFloat(tokens.nextToken())));
}
And here is my text file
Block 0 0
Block 64 0
Car 1 5 9 5
Car 1 5 2
Block 1
Car 7
Is it possible in java to count number in each line?
EDIT:
How I need to get whole line using stringtokenizer? Here what I'm trying to do, but I get only first word in each line
while(tokens.hasMoreTokens()){
String type = tokens.nextToken();
System.out.println(type);
if(type.equals("Block")){
//System.out.println(type);
list.add(new Brick(Integer.parseInt(tokens.nextToken()), Integer.parseInt(tokens.nextToken())));
Yes there is. Java provides a method to check whether a character is digit or not. Check the character and and increase count if its digit like this:
int digitCount = 0;
if(isDigit(characterToCheck)) {
digitCount++;
}
Method: boolean isDigit(char ch). See here for example
The problem goes like this:
If a is assigned the value 1, b=2,c=3,...z=26, check if a given string is a Super Ascii String or not. A string is said to be a Super Ascii String, if the number of times a character is repeated matches its value. The string must be only in lowercase letters
Eg. abbccc is super ascii because a=1,b=2,c=3. Similarly, bab, "bb a ccc"
This is my attempt in solving the problem
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;
public class SuperAsciiNew
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
System.out.print("Enter a string : ");
String input = in.nextLine();
char[] inputArray = input.replaceAll("\\s+","").toCharArray();
Arrays.sort(inputArray);
String customInput = new String(inputArray);
char currentChar = customInput.charAt(0);
int increment=0;
Map<Character, Integer> characterMap = new HashMap<Character, Integer>();
char a='a';
boolean superascii = true;
for(int i=1;a<='z';i++,a++)
characterMap.put(new Character(a), new Integer(i));
while(increment<=customInput.length())
{
int nooftimes = customInput.lastIndexOf(currentChar) - customInput.indexOf(currentChar) + 1;
if(characterMap.get(currentChar) == nooftimes)
{
System.out.println("The character "+currentChar+" is repeated "+nooftimes);
increment += nooftimes;
currentChar = customInput.charAt(increment);
}
else
{
superascii = false;
break;
}
}
if(superascii == true)
System.out.println("The given string "+input+" is a Super Ascii string");
else
System.out.println("The given string "+input+" is not a Super Ascii string");
}
}
Here, first I am removing spaces (if any), sorting the string. Then, I find the first character in the string, what is its value and how many times is it repeated. If these two values are not equal then the loop is broken else, the number of times the character is repeated is incremented in increment variable and the next character is found.
The output I get for various test cases:
java SuperAsciiNew
Enter a string : abb ccc
The character a is repeated 1
The character b is repeated 2
The character c is repeated 3
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6
at java.lang.String.charAt(String.java:658)
at SuperAsciiNew.main(SuperAsciiNew.java:30)
java SuperAsciiNew
Enter a string : bab
The character a is repeated 1
The character b is repeated 2
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 3
at java.lang.String.charAt(String.java:658)
at SuperAsciiNew.main(SuperAsciiNew.java:30)
java SuperAsciiNew
Enter a string : hello world
The given string hello world is not a Super Ascii string
When the string "hello world" is given, the output is generated without any exceptions. What is the issue here?
I have one more doubt in Java:
What is the difference between importing individual classes like java.util.Scanner and importing the package as whole java.util.*? Are there any performance issues? What I feel is, the second one might consume more memory while the first, the system has to search the appropriate class and include it. Am I right in my thinking?
You are checking for a character one too many times.
Use the following condition:
while(increment<=customInput.length()-1)
instead of:
while(increment<=customInput.length())
Edit: the reason you are not getting the error on "hello world" is because it fails before reaching that extra char, thus not throwing an exception.
Instructions:
Write a program that will read a line of text that ends
with a period, which serves as a sentinel value. Display all the
letters that occur in the text, one per line and in alphabetical
order, along with the number of times each letter occurs in the text.
Use an array of base type int of length 26 so that the element at
index 0 contains the number of as. and index 1 contain number of bs etc.
package alphabetize;
import java.util.*;
public class Alphabetize
{
private static void number(String s)
{
int[] array = new int[26];
s = s.toUpperCase();
System.out.println(s);
for (int i = 0; i < s.length(); ++i)
{
if (s.charAt(i) >= 'A' && s.charAt(i) <= 'Z')
{
++array[s.charAt(i) - 'A'];
}
}
for (int i = 0; i < 26; ++i)
{
System.out.println("|" + (char) ('A' + i) + "|" + array[i] + "|");
}
}
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
String aString = ".";
while (true)
{
System.out.println("Please enter sentence with a period to end");
aString = keyboard.nextLine();
if (".".equals(aString))
{
System.exit(0);
}
number(aString);
}
}
}
Still having problem with the period thing.. it does not seem to work the way i did it.
Considering this is a homework and instructions are very specific, you should read the text character by character instead of using built-in functions
If your text file was something like
abcabca.
The output should be something a appears three times, b appears two times etc etc.
So your algo should be something like
Read next character
If char is period goto 5
If char is space goto 1.
If char is between a <-> z. update the counter in arr[0..25] and goto 1
output arr[0..25] one per line
Was it mandated that this assignment is done in Java? The whole idea of a "sentinal character" rather than just using a line terminator is pretty bizarre.
Anyway, you can achieve the behaviour you want by setting the delimiter of Scanner:
keyboard.useDelimiter("\\.");
As for the looping, a big hint is this:
int[] counts;
counts[chars[0] - 'a'] = counts[chars[0] - 'a'] + 1;
or simply
counts[chars[0] - 'a']++;
I'll leave it up to you to include that in a loop.
Edit
If you are looking for character-at-a-time input, I would suggest you use an InputStreamReader instead of Scanner for your input. Here's a basic skeleton of what that looks like:
Reader reader = new InputStreamReader(System.in);
while (true) {
int nextInput = reader.read();
if (nextInput == -1) {
System.out.println("End of input reached without sentinal character");
break;
}
char nextChar = (char) nextInput;
//deal with next character
}
Still, read() will typically block until either the end of input is reached (CTRL-D or CTRL-Z from most consoles) or a new line is sent. Thus the sentinal character is of limited use since you still have to do something after typing ".".
You have to check whether period is there at the end or not. So the last character should be '.'.
Then take the length of string before last '.'.
For the counting part create an array like u are doing :
int [] name = new int[26]
where each index starting from 0, 25 corresponds to 'a' till 'z'.
Now you put the string characters in a loop and have to check what that character is like :
if its a 'a' : increase the value at index 0 by 1.
if its a 'd' : increase the value at index 3 by 1.
like wise.
later you display the whole array with a, z along with indexes from 0 till 25.
Suggestion: If its not required to use an array, and you can use any other data-structure you can implement the same in a HashMap very easily. by keeping 'a', 'z' as the keys and count as the corresponding values. and then retrieving and showing the values will also be easier.
You need an int array (e.g., int[] counts = new int[26];) After you read the input line, examine it character by character in a loop. If the character is a not period, then increment the appropriate element of the counts array. (If the character is a, then increment counts[0]; if it is b, increment counts[1]; etc. Hint: you can subtract a from the character to get the appropriate index.) When you find a period, exit the loop and print the results (probably using a second loop).