java scan coordinates as (X, Y) format - java

How can I scan coordinates with (x, y) format?
For example:
(1, 3)
(2, 4)
(4, 1)
(3, 2)
What I've tried is this:
String m = input.next();
String parts[] = m.split(",");
String part1 = parts[0];
String part2 = parts[1];
part1 = part1.substring(1, part1.length());
part2 = part2.substring(0, part2.length()-1);
That code works for a coordinate with (x,y) format but doesn't work for (x, y)

You mentioned you could get it working with format (x,y) but not (x, y) with the space in between. I would suggest using .trim() to get rid of the spaces:
public static void main(String args[])
{
Scanner input = new Scanner(System.in);
System.out.println("Enter a coordinate: ");
String coordinate = input.nextLine();
String[] parts = coordinate.split(",");
// if input is (x, y)
// then parts[0] is "(x"
// and parts[1] is " y)"
String x = parts[0].trim().substring(1).trim();
String y = parts[1].trim().substring(0, parts[1].trim().length() - 1).trim();
System.out.println("x: " + x + "\ny: " + y);
}
I trimmed the part before getting the substring, and then trimmed the part after getting the substring as well, so that when the brackets are ignored in the substrings, the spaces will also be removed. It seems to work for all cases no matter how much whitespace there is.
Samples:
Without a space
Enter a coordinate:
(155,54)
x: 155
y: 54
With a space
Enter a coordinate:
(118, 43)
x: 118
y: 43
With a lot of spaces
Enter a coordinate:
( 155 , 4 )
x: 155
y: 4

Here's an outline for one way to go about doing this:
Instantiate a Scanner object.
Read the next token (the next line) from it with the next() method.
Split the read in String on the comma and save the resulting array into a String[] - e.g. nums[].
For the first number, parse the first string in the String[] from the 2nd character (at index 1, not 2) onwards into an int. You can use Integer.valueOf() and substring(1) to do this.
For the second number, substring from the 1st character of the second string in the nums[] array (index 0) until the character before the last character. So substring(0, nums[1].length()-1). Again, use Integer.valueOf().
Hopefully that helps and doesn't completely give away the solution without some more effort on your part. Also, note that you should handle exceptions that might pop up.

Related

Printf in Java with variable spaces before the output

With printf I can decide how many space characters should be before the variable i that I want to print. In the example below, it is 10. Is it possible to have there a variable instead of the number 10? So that the spaces characters depend on the value of a variable?
System.out.printf("%10d" , i);
The format string is still a string, so assuming a width variable System.out.printf("%" + width + "d", x); does the trick.
So for example
var width = 10; var x = 123;
System.out.printf("%" + width + "d", x);
prints 123 (7 leading spaces + 3 digits = 10), while
var width = 3; var x = 123;
System.out.printf("%" + width + "d", x);
prints 123
Define a lambda to create the desired width and then call that prior to printing the value.
Function<Integer, String> format = width-> "%%%dd\n".formatted(width);
int x = 4567;
System.out.printf(format.apply(10),x);
System.out.printf(format.apply(5),x);
// or create it once for multiple printf calls.
String form = format.apply(3);
System.out.printf(form, 2);
System.out.printf(form, 4);
prints
4567
4567
2
4
%%%dd - the first % escapes the second so on the last %d formats the width value.
then that format string is returned and used to format the supplied argument in the printf statement

How would I add two int that are in the same array to each other and convert them into an int. In the Luhn Algorithm

I am trying to add two parts of an array together to go into an int value. I am using Luhn algorithm to figure out of a credit card is a valid credit card. We are only using 6 digit credit card's just to make sure no one enter's a real credit card number. The part I am confused on is when I go to split a number that is above 10 and add it together. Example if the algorithm was to give me 12 I would need to separate it into 1 and 2 and then add them together to equal 3. I believe I am splitting it currently in the code but when I go to add them together I get some number that makes no since. here is a section of the code with some notes about it.
I have printed out numbers in certain places to show myself what is going on in certain places. I have also added in some comments that say that either the number that is printed out is what is expected, and some comments for when there isn't something I expected
int[] cardNumber = new int[]{ 1,2,3,4,5,5};
int doubleVariablesum = 0;
int singleVariablesum = 0;
int totalSum = 0;
int cutOffVar = 0;
String temp2;
for (int i = cardNumber.length - 1; i >= 0;) {
int tempSum = 0;
int temp = cardNumber[i];
temp = temp * 2;
System.out.println("This is the temp at temp * 2: " + temp);
temp2 = Integer.toString(temp);
if (temp2.length() == 1) {
System.out.println("Temp2 char 0: "+ temp2.charAt(0));
// this prints out the correct number
// Example: if there number should be 4 it will print 4
tempSum = temp2.charAt(0);
System.out.println("This is tempSum == 1: " + tempSum);
// when this goes to add temp2.charAt(0) which should be 4 it prints out //something like 56
} else {
System.out.println("TEMP2 char 0 and char 1: " + temp2.charAt(0) + " " + temp2.charAt(1));
// this prints out the correct number successfully spited
tempSum = temp2.charAt(0) + temp2.charAt(1);
System.out.println("This is tempSum != 1: " + tempSum);
// but here it when I try to add them together it is giving me something
// like 97 which doesn't make since for the numbers I am giving it
}
doubleVariablesum = tempSum + doubleVariablesum;
System.out.println("This is the Double variable: " + doubleVariablesum);
System.out.println();
i = i - 2;
}
Since you are converting the number to a string to split the integer, and then trying to add them back together. You're essentially adding the two characters numerical values together which is giving you that odd number. You would need to convert it back to an integer, which you can do by using
Integer.parseInt(String.valueOf(temp2.charAt(0)))
When adding char symbols '0' and '1' their ASCII values are added - not numbers 0 and 1.
It is possible to use method Character::getNumericValue or just subtract '0' when converting digit symbol to int.
However, it is also possible to calculate sum of digits in a 2-digit number without any conversion to String and char manipulation like this:
int sum2digits = sum / 10 + sum % 10; // sum / 10 always returns 1 if sum is a total of 2 digits
Seems like charAt() type casts into integer value, but the ascii one. Hence for the characters '0' and '1', the numbers 48 and 49 are returned resulting in a sum of 97. To fix this, you could just assign temp2 to (temp / 10) + (temp % 10). Which actually splits a two digit integer and adds their sum.
You need to be aware of the following when dealing with char and String
Assigning the result of charAt(index) to an int will assign the ASCII value and not the actual integer value. To get the actual value you need to String.valueOf(temp2.charAt(0)).
The result of concatenating chars is the sum of the ASCII values.
eg if char c = '1'; System.out.println(c + c); will print "98" not "11".
However System.out.println("" + c + c); will print "11". Note the "" will force String concatenation.

Replace all non digits with a restriction

I'm trying to extract the first number from expressions:
Here's my code for while:
String[] strArray = input.split("\\+ ");
double[] numbers = getNumbersFromString();
public static double[] getNumbersFromString() {
double[] numbers = new double[strArray.length];
for (int i = 0; i < strArray.length; i++) {
numbers[i] = Double.parseDouble(strArray[i].replaceAll("\\D", ""));
}
return numbers;
}
Inputs and their expected outputs:
Z = 4x1 + 3x2 + 6x3 // 4 3 6
Z = 24x1 + 33x2 + 68x3 // 24 33 68
Z = 412x1 + 309x2 + 612x3 // 412 309 612
Z = 4329x1 + 3901x2 + 6716x3 // 4329 3901 6716
Actually, it's removing but it retrieves besides the first number, the second also. Eg.(In the first case): // 41 32 63, while it should be only // 4 3 6.
I could do something like "\\w = |x\\d", "", but it will only work for this specific case, I want a more general thing.
Thanks in advance.
Edit:
I got the following answer for the original question:
String input = "Z = 4329x1 + 3901x22 + 6716x3";
input = input.replaceAll("^\\D+", "");
double[] numbers = Pattern.compile("x\\d+\\D*")
.splitAsStream(input)
.mapToDouble(Double::parseDouble)
.toArray();
But now appeared a new thing to be done. Inputs that has no numbers before the x1/x2/x3.. or any kind of this" should be replaced by the number "1".
Some inputs and their respective expected outputs:
Z = x11 + x2 + x90 // 1 1 1
Z = 2x1 + 2x4 + x9 // 2 2 1
By the way, I have made this regex: (?<!\d)x\d+.
Then I modified the code to:
return Pattern.compile("x\\d+\\D*")
.splitAsStream(input.replaceAll("(?<!\\d)x\\d+","1").replaceAll("^\\D+", ""))
.mapToDouble(Double::parseDouble)
.toArray();
But it's returning me `java.lang.NumberFormatException: For input string: "1 + 3".
PS: it should work for either the old and new case.
This should work as required:
String s = "Z = 4329x1 + 3901x22 + 6716x3";
String[] split = s.replaceAll("^\\D+", "").split("x\\d+\\D*");
System.out.println(Arrays.toString(split)); //[4329, 3901, 6716]
With streams you could do something like this to obtain your array of doubles:
String input = "Z = 4329x1 + 3901x22 + 6716x3";
input = input.replaceAll("^\\D+", "");
double[] numbers = Pattern.compile("x\\d+\\D*")
.splitAsStream(input)
.mapToDouble(Double::parseDouble)
.toArray();
EDIT
To also accept expressions such as x1 + x2, you can default to 1 when the string returned by split is empty (and amend the regex slightly):
String input = "Z = x1 + x2 + 6716x3";
input = input.replaceAll("^[^x\\d]+", "");
double[] numbers = Pattern.compile("x\\d+[^x\\d]*")
.splitAsStream(input)
.mapToDouble(s -> s.isEmpty() ? 1d : Double.parseDouble(s))
.toArray();
RE-EDIT
Add the missing 1 before the x manually:
String input = "Z = x1 + x2 + 6716x3 + x4";
input = input.replace(" x", " 1x")
.replaceAll("^[^x\\d]+", "");
double[] numbers = Pattern.compile("x\\d+[^x\\d]*")
.splitAsStream(input)
.mapToDouble(Double::parseDouble)
.toArray();
You could do the whole grabbing in a single regex (per row which I assume from your example what you're interested in) -
(?:=|\+)\s*(\d+)
It matches either a = or a +, skipping any spaces and then captures the number. Make it global and it'll capture the entire row. The result will be in the capture group array. (Don't speak java well enough to tell you exactly how from the top of my head).
Check it here at regex101. (Note - sample shows all the rows at once - you'd have to do them one by one.)
Since you pattern is a number followed by an x, using positive lookahead like this will work.
Regex: \d+(?=x)
Explanation:
(?=x) looks ahead and checks if x is present. If yes then \d+ is matched.
Regex101 Demo
Note: Use double escape \\d if necessary.

Specific digit detector issue

I have written a small piece of code where you enter a 3 digit number via the command line, and then it detects how many 5's are in the code.
public class fivedet {
public static void main (String[] args) {
String input = args[0];
int[] a = {0,0,0};
int x = 0;
int y = 0;
int z = 0;
for(int i = 0; i<input.length();i++) {
a[i] = input.charAt(i) - 48;
}
if(a[0]==5) {
x=5;
}
if(a[1]==5) {
y=5;
}
if(a[2]==5) {
z=5;
}
System.out.println("5 digits here:" + x + y + z);
}
}
My main question is why I require the -48 term after the input.charAt(i) method in order for each value in a[] to be equal to the actual number I input.
For example I enter
java fivedet 505
and without the -48 the array a[]={53,48,53} instead of a[]={5,0,5} and I unfortunately am not experienced enough with coding java (began learning 3 months ago) to understand why this is happening.
I also do want to develop it to be able to detect different digits and for different lengths of input numbers.
I would appreciate any insight as to why this happens.
Subtracting 48 is a quick but slightly confusing way of converting from a character to an integer. It so happens that the character code for each digit is 48 away from its numeric value.
See this table of ASCII values. (Java uses unicode, not ascii - strings are UTF-16 internally - but the values are valid in this specific case). So the character '0' has the value 48; the character '9' has the value 57.
Another way of doing this would be to take 1-character substrings of input, then call Integer.parseInt() on that string, converting "1" to 1, "2" to 2, etc.
You don’t need to convert to int in order to detect character 5. Just count them as chars.
for (char i : args[0].toCharArray()) {
System.out.print(i == '5' ? i : '0');
}
Also this question has good answers to count occurrences of a char in string

Why is myArrayList.size(); producing incorrect/gigantic numbers?

Basically, I'm trying to write a program that converts a number from base 2 to base 10. What I tried doing was translating the process listed on this website under the "Doubling method" into a for loop, but for some reason the numbers I'm getting are way to big.
The basic formula is (2 * previousTotal) + (currentDigit of the ArrayList that holds the user's inputted binary number) = previousTotal.
So for 1011001 in binary, the math would be:
(0 x 2) + 1 = 1
(1 x 2) + 0 = 2
(2 x 2) + 1 = 5
(5 x 2) + 1 = 11
(11x 2) + 0 = 22
(22 x 2) + 0 = 44
(44 x 2) + 1 = 89
The console however, prints out 6185 as the result. I'm thinking it might have something to do with me using an ArrayList of characters, but the charWhole.size() returns 7, which is how many digits are in the user's binary number. As soon as I do charsWhole.get(w); however, I start getting big numbers such as 49. I'd really appreciate some help!
I wrote out this loop, and according to some print statements that I placed throughout the code and my variable addThis seems to be where the problem is. The console prints out a final total of 6185, when 1011001 in base 10 is actually 89.
public static void backto2(){
System.out.println("What base are you coming from?");
Scanner backToB10 = new Scanner(System.in);
int bringMeBack = backToB10.nextInt();
//whole
System.out.println("Please enter the whole number part of your number.");
Scanner eachDigit = new Scanner(System.in);
String theirNumber = eachDigit.nextLine();
String str = theirNumber;
ArrayList<Character> charsWhole = new ArrayList<Character>();
for (char testt : str.toCharArray()) {
charsWhole.add(testt);
}
System.out.println(theirNumber); // User's number
System.out.println(charsWhole); // User's number separated into elements of an ArrayList
System.out.println(charsWhole.size()); // Gets size of arrayList, comes out as 7 which seems fine.
int previousTotal = 0, addThis = 0, q =0;
for( int w = 0; w < charsWhole.size(); w ++) {
addThis = charsWhole.get(w); //current digit of arraylist PROBLEM
q = previousTotal *2;
previousTotal = q + addThis; // previous total gets updated
System.out.println(q);
System.out.println(addThis);
System.out.println(q + " and " + addThis + "equals " + previousTotal);
}
System.out.println(previousTotal);
You are attempting to add a character to an integer. The implicit conversion uses the ASCII value of the character, so that '1' gets converted to 49, not 1, because 49 is the code for the character '1'. Subtract '0' to get the actual integer value.
addThis = charsWhole.get(w) - '0';
This works because the digits 0-9 are represented in ASCII as the codes 48-57, so in effect you will, for '1', subtract 49 - 48 to get 1.
You'll still have to handle cases when the character is outside the range of allowable characters.
EDIT
Java uses Unicode, but for the purposes of the codes for the digits 0-9, the codes are the same (48 thru 57, or 0x30 thru 0x39) in both ASCII and Unicode.
The problem is that you're using the chars rather than the number value they represent. In the line
addThis = charsWhole.get(w);
the value of addThis is the ascii value of the character. For '0', this is 48. Use this instead:
addThis = Integer.parseInt(charsWhole.get(w));
Another suggestion to solve the same problem:
addThis = charsWhole.getNumericValue(w);
See here for more information.

Categories

Resources