Right now I have a program that puts an inputted expression into Postfix Evaluation. Below is a copy of my console.
Enter an expression: ((5*2-1)/6+14/3)*(2*3-5)+7/2
5 2 * 1 - 6 / 14 3 / + 2 3 * 5 - * 7 2 / +
I now need to walk through the output, however this output is just a bunch of System.out.print 's put together. I tried using a stringBuilder however it cant tell the difference between 14 and a 1 and 4.
Is there anyway I can go through each character of this output? I need to put these numbers into a stack.
You can use String.split() and if you need only numbers regular expression.
Here is an Example:
public class Test {
public static void main(String[] args) {
String str = "1 * 2 3 / 4 5 6";
String[] arr = str.split(" ", str.length());
for (int i=0;i < arr.length;i++)
System.out.println(arr[i] + "is diggit? " + arr[i].matches("-?\\d+(\\.\\d+)?"));
}
}
str holds the long String. arr will hold the split sub strings.
you just need to make sure that each sub string differ one space from the other.
Well, you deleted your code while I was reading it, but here's a conceptually developed answer.
As you input every character, you want to push that to the stack.
The unique scenario you've mentioned 14 is unique in that it's two characters.
So what you would want to do is track if the last character was ALSO a number.
Here's a rough pseudo. Your stack should be all Strings to support this.
//unique case for digit
if(s.charAt(0).isDigit()) {
//check to see if the String at the top of a stack is a number by peeking at its first character
if(stack.peek().charAt(0).isDigit()) {
int i = Integer.parseInt(stack.pop()) * 10;
//we want to increment the entire String by 10, so a 1 -> 10
i = i + Character.getNumericValue(s.charAt(0)); //add the last digit, so 10 + 4 = 14
stack.push(Integer.toString(i)); //put the thing back on the stack
}
else {
//handle normally
stack.push(s.substring(0,1));
}
}
Is there a reason you need to parse the actual string?
If so, then what you do is, create a StringBuffer or StringBuilder, and wherever you put System.out.print in your code, append the buffer - including the spaces, which are what will help you differentiate between 1 4 and 14. Then you can convert that to a String. Then you can parse the String by splitting it by the spaces. Then iterate through the resulting String array.
If there is no reason for you to use the actual full string, you can instead use a List object and just add to it in the same places in the code. In this case, you don't need the spaces. Then you'll be able to simply iterate through the list.
You'll still be able to print you output - by printing the elements in the list.
Related
This is for AOC day 2. The input is something along the lines of
"6-7 z: dqzzzjbzz
13-16 j: jjjvjmjjkjjjjjjj
5-6 m: mmbmmlvmbmmgmmf
2-4 k: pkkl
16-17 k: kkkkkkkkkkkkkkkqf
10-16 s: mqpscpsszscsssrs
..."
It's formatted like 'min-max letter: password' and seperated by line. I'm supposed to find how many passwords meet the minimum and maximum requirements. I put all that prompt into a string variable and used Pattern.quote("\n") to seperate the lines into a string array. This worked fine. Then, I replaced all the letters except for the numbers and '-' by making a pattern Pattern.compile("[^0-9]|-"); and running that for every index in the array and using .trim() to cut off the whitespace at the end and start of each string. This is all working fine, I'm getting the desired output like 6 7 and 13 16.
However, now I want to try and split this string into two. This is my code:
HashMap<Integer,Integer> numbers = new HashMap<Integer,Integer>();
for(int i = 0; i < inputArray.length; i++){
String [] xArray = x[i].split(Pattern.quote(" "));
int z = Integer.valueOf(xArray[0]);
int y = Integer.valueOf(xArray[1]);
System.out.println(z);
System.out.println(y);
numbers.put(z, y);
}
System.out.println(numbers);
So, first making a hasmap which will store <min, max> values. Then, the for loop (which runs 1000 times) splits every index of the 6 7 and 13 16 string into two, determined by the " ". The System.out.println(z); and System.out.println(y); are working as intended.
6
7
13
16
...
This output goes on to give me 2000 integers seperated by a line each time. That's exactly what I want. However, the System.out.println(numbers); is outputting:
{1=3, 2=10, 3=4, 4=7, 5=6, 6=9, 7=12, 8=11, 9=10, 10=18, 11=16, 12=13, 13=18, 14=16, 15=18, 16=18, 17=18, 18=19, 19=20}
I have no idea where to even start with debugging this. I made a test file with an array that is formatted like "even, odd" integers all the way up to 100. Using this exact same code (I did change the variable names), I'm getting a better output. It's not exactly desired since it starts at 350=351 and then goes to like 11=15 and continues in a non-chronological order but at least it contains all the 100 keys and values.
Also, completely unrelated question but is my formatting of the for loop fine? The extra space at the beginning and the end of the code?
Edit: I want my expected output to be something like {6=7, 13=16, 5=6, 2=4, 16=17...}. Basically, the hashmap would have the minimum and maximum as the key and value and it'd be in chronological order.
The problem with your code is that you're trying to put in a nail with a saw. A hashmap is not the right tool to achieve what you want, since
Keys are unique. If you try to input the same key multiple times, the first input will be overwritten
The order of items in a HashMap is undefined.
A hashmap expresses a key-value-relationship, which does not exist in this context
A better datastructure to save your Passwords would probably just be a ArrayList<IntegerPair> where you would have to define IntegerPair yourself, since java doesn't have the notion of a type combining two other types.
I think you are complicating the task unnecessarily. I would proceed as follows:
split the input using the line separator
for each line remove : and split using the spaces to get an array with length 3
build from the array in step two
3.1. the min/max char count from array[0]
3.2 charachter classes for the letter and its negation
3.3 remove from the password all letters that do not correspond to the given one and check if the length of the password is in range.
Something like:
public static void main(String[] args){
String input = "6-7 z: dqzzzjbzz\n" +
"13-16 j: jjjvjmjjkjjjjjjj\n" +
"5-6 m: mmbmmlvmbmmgmmf\n" +
"2-4 k: pkkl\n" +
"16-17 k: kkkkkkkkkkkkkkkqf\n" +
"10-16 s: mqpscpsszscsssrs\n";
int count = 0;
for(String line : input.split("\n")){
String[] temp = line.replace(":", "").split(" "); //[6-7, z, dqzzzjbzz]
String minMax = "{" + (temp[0].replace('-', ',')) + "}"; //{6,7}
String letter = "[" + temp[1] + "]"; //[z]
String letterNegate = "[^" + temp[1] + "]"; //[^z]
if(temp[2].replaceAll(letterNegate, "").matches(letter + minMax)){
count++;
}
}
System.out.println(count + "passwords are valid");
}
I have s string in which * can come at arbitrary number. The regex pattern I use doesnt split at the beginning. I do not want to do the String.substring() to remove the * in the beginning. It can be that I have something like "***place1*place2**place3*". Or something like placeStr=**
String placeStr="*place1*place2**place3*";
String[] places=placeStr.split("(\\*)+");
System.out.println("array size" + places.length);
Also while using String.split("(\\*)+")to remove the placeStr=** gives a wrong array size if the input string is something like ***. In this case I get array size as one. But I expect array size to be zero, since there is no places inside the array. What I want to count is the number of places.
If you don't want to deal with empty strings while doing split in case there are multiple stars in the beginning, just replace the stars in beginning and then just do a simple split.
Sample code,
public static void main(String[] args) {
String placeStr = "***place1*place2**place3*";
placeStr = placeStr.replaceAll("^[*]+", "");
String[] places = placeStr.split("[*]+");
System.out.println("places.length: " + places.length);
Arrays.asList(places).forEach(System.out::println);
}
Prints,
places.length: 3
place1
place2
place3
Let me know if this is what you wanted to do.
Editing answer to clarify about split:
Considering your code,
String placeStr="*place1*place2**place3*";
String[] places=placeStr.split("(\\*)+");
System.out.println("array size: " + places.length);
You will get,
array size: 4
because the first star in the string splits and gives empty string. But if you remove all the stars in the beginning of string and make your code like this,
String placeStr="place1*place2**place3*";
String[] places=placeStr.split("(\\*)+");
System.out.println("array size: " + places.length);
Then this will output array size as,
array size: 3
The last star(s) (or any char) characters in the string does not behave like the first characters, and upon splitting, they don't give empty string in the last array elements.
This is how splitting a string by a regex works in java. Let me know if you had some other expectation, may be due to which you are saying it is giving you wrong output.
Hope this clarifies.
Also, can you let me know what you want to achieve logically?
A problem I'm having in my programming class is asking me to make a pattern like this:
I used the following code:
public static void ch5ex18c() {
System.out.println("Pattern C");
String num = "6 5 4 3 2 1";
for (int count = 10; count >= 0; count-=2){
System.out.printf("%-10s", num.substring(count, 11) + "\n");
}
}
and I got everything to print out well except the first number line:
I know I can fix this using an if statement, but I'd just prefer not to and I want to know why it would do this in the first place.
The problem is that your new lines are inserted before extra spaces ("1\n" + spaces), you need to remove the minus sign (that justifies left) and make some minor math alterations.
1\n spaces (shown on next line to make it seem like your justifying right
2 1\n spaces
and so on
I'm doing some error checking for my BigInteger Calculator class. If an input has a space in between numbers and no valid operator (+,-,*,/,%,^) in between those numbers like the one below it is supposed to return "Error". Is there any way to check for this case using string methods?
Should return error because there is space in between numbers and no operator in between them:
2 + 1 1 1 1 1 + 2 //in this case the 1's do not have operators in between
2 2 2 //has spaces in between
valid:
2 + 2
22 + 2 + 1
2 + 11111 + 2
One option would be to split the string using String[] temp = [stringName].split(" "); and check to see that every other index is a valid operator.
Perhaps you can use regex to find space in between numbers.
String input = "1+2 2 2";
boolean found = Pattern.compile("[0-9]+\\s+[0-9]+").matcher(input).find();
You don't need to find the space between numbers specifically. In fact you should be ignoring spaces completely other than as delimiting the tokens.
You just need to scan and parse according to a grammar that doesn't have a syntax for two consecutive numbers. Or operators. At any given point you should know what's expected and what isn't.
For example, say I want to write to a text file, and I want to line up my results into columns like so:
Peanut Butter Crunchy
Jelly Purple
Bread Wheat
Milk Whole
\t obviously doesn't line up the second column when the first words are different lengths. Is lining them up possible?
Yes, it is possible. You want to pad the strings to the right with white spaces. For example, if you specify that each column starts every 20 characters and your string is 12 characters, you need to add 8 whitespace characters to the end.
You could hand code a loop or you could use string.format(). I took a look around online and found this easy method which you can use. http://www.rgagnon.com/javadetails/java-0448.html
public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}
s is the string that you want to pad, n is the ideal length.
For example,
padRight("test", 10") -> "test "
To add to your code, just format each line. For example, for your first line, you could do
String line = padRight(peanutButterString, 20) + peanutButterAttribute
Make sure your values are in an array and you can easily loop through it and create the properly formatted string.