How should I deal with space character when using split - java

So apparently when I am using S.split(" ") and I have " " (space) in my code file, it gets ignored. I was wondering if there's a way to overcome that. What I had in mind and is written in the following code doesn't work however it works for every other character.
String codeArr[] =code.split("\\r?\\n");
int k=0;
while (k<codeArr.length-1)
{
String[] tmpCode=codeArr[k].split(" ");
if (tmpCode.length!=2)
HuffCodeToCh.put(tmpCode[0]," ");
else
HuffCodeToCh.put(tmpCode[1],tmpCode[0]);
k+=1;
}
My input is of the following type (in a file):
i 000
r 001
e 01
s 100
n 101
. 110000
" 110001
E 1100100
k 11001010
H 11001011
f 110011
t 1101
1110
a 111100
I want to save the character as well as its binary code in a hashMap as shown in the code. However the code I have written above doesn't save " " in the hashmap. I am not sure how to fix it.

try this:
codeArr[k].split(" (?=\\S)");
so that
x 100 -> {"x","100"}
100 -> {" ","100"}
11 -> {" ", "11"} (two spaces)

Use String.substring.
String c = codeArr[k].substring(0, 1);
String b = codeArr[k].substring(2);

Specifically, your whole loop is simply:
for (String line : code.split("\\r?\\n"))
HuffCodeToCh.put("" + line.charAt(0), line.substr(2));
On a largely unrelated note, your variable HuffCodeToCh does not follow Java naming conventions, which strongly suggest that initial capitals be reserved for types.

Related

Why do I get a different sum and errors for addition in Java

I am really new to Java. I have a question regarding the numbers. I was given a task of printing 2 numbers side by side.
For example, if there are 2 numbers: a = 5, b = 9, I should print both of them side by side. So the output would look 59.
In python, we can do:
print(a,b)
Even though it adds a space, I can remove that later.
But in Java. when I do System.out.println(a,b), I get:
error: no suitable method found for println(int,int)
System.out.println(a,b);
^
So after scratching my head for a little bit, I came up with System.out.println(a+''+b)
And then it gives:
error: empty character literal
System.out.println(a+''+b);
^
So, looking at the error, it looked like '' is invalid. So I did ' '
And the result I got was:
46
Why did I get an error?
When I do:
System.out.println(a+""+b);
It prints what I want: 59
Here is my code (working):
public class Main
{
public static void main(String[] args) {
int a=5;
int b=6;
System.out.println(a+""+b);
}
}
I just want to know why does this above work while doing ' ' doesn't. It is related to the data type?
' ' is a char. It will be autocasted to an int (the ASCII code of blank is used, it has the value 32). Then the addition is executed (5 + 32 + 9, which will evaluate to 46). That explain why we see the 46 being printed out.
Replacing ' ' with "" will force the int-values being autocasted to Strings, which will then work as expected.
Another possible solution woudl be to use System.out.printf("%d%d%n", a, b);.
Ideone Demo
The single quote ' ' is a space character, and printing 5 + ' ' + 9 results in adding the integers with its ASCII value which is 32 (5 + 32 + 9 = 46).
You can either use "" or printf:
System.out.printf("%d%d", 5, 9);
for '' it represents a char value, so it recognizes as ASCII value(32).that's why it gives you a different output (5 + 32 + 9) . By using "", int will auto-cast into a string
example :
1+2+""+4 =34

Hashmap in for loop not reading all the input

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");
}

Why does the expression x+x not print the same result in the two places it appears? [duplicate]

This question already has answers here:
Java: sum of two integers being printed as concatenation of the two
(10 answers)
Closed 7 years ago.
Why does the expression x+x not print the same result in the two places it appears?
String s = args[0];
System.out.println("Hello "+s);
int x = 40;
System.out.println(x);
System.out.println(x+x);
System.out.println(s+" "+x+x);
The result of this code is when I execute in cmd java EG1 kaan
Hello kaan
40
80
kaan4040
why is the last result of the print displaying kaan4040 and not kaan80?
Because of automatic conversion to String.
On this line you "start printing" an integer, so adding another integer to it will again produce integer that is then converted to String and printed out:
System.out.println(x + x); // integer + integer
However on this line you "start printing" a String, so all other values you add to it are at first converted to String and then concatenated together:
System.out.println(s + " " + x + x); // String + String + integer + integer
If you want the two integers to be added together before the concatenation is done, you need to put brackets around it to give it a higher priority:
System.out.println(s + " " + (x + x)); // String + String + integer
In your last print statement, you are doing a string concatenation instead of an arithmetic addition.
Change System.out.println(s+" "+x+x) to System.out.println(s+" "+(x+x)).
Make changes System.out.println(s+" "+x+x); to System.out.println(s+" "+(x+x)); Because it need to add the value and then string concatenation
Because java does some work with your code. When you do System.out.println(x+x);, it sees x+x as an expression with two ints and evaluates it (which is 80). When you do ""+x+x, it sees 3 String, and thus evaluates this expression as a String concatenation.
(btw, by it, I mean javac, and "sees", I mean, well "reads")
Or change print code to System.out.println(x +x+" " +s );
You are performing concatenation instead of addition
Whenever you append anything to string then it will result to string only. You have appended x+x to " " which will append 40 after name. You can use System.out.println(s+" "+(x+x)).
On the last print statement:
System.out.println(s+" "+x+x);
s is a string and is concatenated with " ", from left to right the expression formed by concatenation with s and " ", is then concatenated with x and then ( s + " " + x ) is concatenated with x, yielding kaan4040.
If the + operator is used with:
2 Strings, concatenation occurs
1 String and 1 int, concatenation occurs
2 ints, arithmetic addition
Consider the following scenario:
System.out.println(x + x + " " + "hello");
In this example 80Kaan is printed as arithmetic addition occurs between x and x, then the resulting value (80) is concatenated with the space and hello.
Read from left to right.
int x = 40;
System.out.println(x);
System.out.println(x + x);
System.out.println("" + x + x);
40
80
4040
40 is int 40
80 is int 40 + int 40 (Maths)
4040 is String 40 concat String 40 (because add "" String)
String s = args[0];
System.out.println("Hello "+s);
int x = 40;
System.out.println(x); //1st statement
System.out.println(x+x); //2nd statement
System.out.println(s+" "+x+x); //3rd statement
The first statement simply converts x into String
The second satatement added the numbers because there aren't strings, the compiler thinks of plus sign as addition of two numbers.
the third one sees that there is a string so the compiler thinks like:
print the value of s, add space(" "), add the value of x (convert x into string), add the value of x (convert x into string ).
Hence, Kaan4040.
If you want to print 80, you can do it in two ways:
int sum = x+x;
System.out.println(s+" "+sum); //more readable code
or
System.out.println(s+" "+ (x+x) ); //may confuse you
the compiler will think of x+x as integers since it doesn't find any string inside the parenthesis. I prefer the first one though. :)
why is the last result of the print displaying kaan4040 and not kaan80?
This is because this is how String behaves when used with the + symbol. and it can mean differently when used in a println method.
It means String concatenation when you use it with a String
The 5 even though being an integer will be implicitly converted to String.
E.g:
System.out.println("Hello" + 5); //Output: Hello5
It become mathematical operation:plus when used within a pair of brackets because the brackets will be operated first (add first), then convert to String.
The 1st + is concatenation, and 2nd + is add (Refer to codes below).
E.g:
System.out.println("Hello" + (5+7)); //Output: Hello12
If any one of the '+' operator operand is string, then java internally create 'StringBuilder' and append those operands to that builder. for example:
String s = "a" + 3 + "c";
it's like
String s = new StringBuilder("a").append(3).append("c").toString(); //java internally do this

Finding a string inside a string twice as big effectively

I'm looking to see if the difference between every adjacent number in an array is the same as another array, or a rotation of it, for example
A = {1,2,4}, so the differences are {1,1,2}
B = {4,6,7}, the differences are {1,2,1}
If all elements in {1,2,1} were moved clockwise one-element, the result is {1,1,2}, which is correct.
so far I convert the differences to strings, and then see if the differences of the second array is found in the first concatenated with itself
valid if "1 2 1" is in "1 1 2 1 1 2"
my code so far looks like this
count is the length of the array, both have the same length
int c = count - 1;
StringBuilder b1 = new StringBuilder();
StringBuilder b2 = new StringBuilder();
for (int i = 0; i < c; i++) {
b1.append(array1[i + 1] - array1[i]);
b1.append(" ");
b2.append(array2[i + 1] - array2[i]);
b2.append(" ");
}
b1.append((array1[0] - array1[c]) + d);
b1.append(" ");
b2.append((array2[0] - array2[c]) + d);
String a2 = b2.toString();
String a3 = b1.toString() + b1.toString();
System.out.println(a3.contains(a2) ? "valid" : "not valid"); //bottleneck here
My problem is when I use big arrays (up to about 250,000 elements) I get a massive bottleneck at the last line with the .contains(). I'm wondering if there is either a faster way of check if its inside the method than what I'm using, or if I can check while building up the string, or if there is a completely different way of doing this?
You need a more efficient algorithm then the one that is used in contains method(it actually depends on a concrete implementation, but it looks like it is not efficient in the version of Java you are using).
You can use Knuth-Morris-Pratt algorithm: http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm. It has linear time and space complexity in the worst case so it works fast even for very big arrays. Note that there is no need to convert an array to a string, because this algorithm works for arrays, too.

Get Each Character From Output - Java

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.

Categories