So I'm making a palindrome checker in java, and i've seemed to hit a roadblock this is my code so far:
public class StringUtil
{
public static void main(String[] args)
{
System.out.println("Welcome to String Util.");
Scanner word = new Scanner(System.in);
String X = word.nextLine();
String R = palindrome(X);
System.out.println();
System.out.println("Original Word: " + X);
System.out.println("Palindrome: " + R);
}
public static boolean palindrome(String word)
{
int t = word.length(); //length of the word as a number
int r = 0;
if(word.charAt(t) == word.charAt(r))
{
return true;
}
else
return false;
}
so far I only want it to check if the first letter is the same as the last, but when i compile it i get an incompatible types error on "String R = palindrome(X);" How would i get it to print true or false on the output statement below it?
Your palindrome method returns a boolean, but you're attempting to assign it to a String. Change the definition of the R variable to boolean.
Since the characters are 0-indexed in a string (or array) in java, the last character is at length - 1
try
int t = word.length() - 1;
Oops, that's not the problem you're having. However, you would notice it immediately once the type error is resolved.
word.charAt(t - 1), otherwise you over counted the string, also return "true"; and return "false" if you'd like to use String as your result type;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
public static void main(String args[]) {
// String to be scanned to find the pattern.
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}
}
Related
write a function which increments a string, to create a new string.
If the string already ends with a number, the number should be incremented by 1.
If the string does not end with a number. the number 1 should be appended to the new string.
Examples:
foo - foo1
foobar23 - foobar24
foo0042 - foo0043
foo9 - foo10
foo099 - foo100
Attention: If the number has leading zeros the amount of digits should be considered.
The program passed tests on the CodeWars platform, except for one
For input string: "1712031362069931272877416673"
she falls on it
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
but in IJ it works correctly ...
Any idea why?
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
System.out.println(incrementString("foo001"));
System.out.println(incrementString("33275375531813209960"));
System.out.println(incrementString("0000004617702678077138438340108"));
}
public static String incrementString(String str) {
boolean isNumeric = str.chars().allMatch( Character::isDigit );
if(str.isEmpty())
return "1";
else if (isNumeric) {
BigInteger b = new BigInteger(str);
return String.format("%0"+str.length() + "d",b.add(BigInteger.valueOf(1)));
}
String timeRegex = "(.*)(\\D)([0-9]*)";
Pattern pattern = Pattern.compile(timeRegex);
Matcher matcher = pattern.matcher(str);
if (matcher.matches()) {
String sec = matcher.group(3);
StringBuilder sb = new StringBuilder();
if (sec.isEmpty()) {
sec = "0";
return str + sb+(Integer.parseInt(sec) + 1);
} else {
int length = String.valueOf(Integer.parseInt(sec) + 1).length();
if (sec.length() > length) {
for (int i = length; i < sec.length(); i++) {
sb.append("0");
}
}
return str.substring(0,str.length() - sec.length()) + String.format("%0"+sec.length() + "d",Integer.parseInt(sec)+1);
}
}
else
return "";
}
}
The issue is with Integer.parseInt(sec) when trying to parse a value too long to fix in a int (max is 2 billion)
You need to use BigInteger everywhere, also there is much useless code. You can also capture the zeros in the first group of the regex, so you don't have leading zeros to take care
public static String incrementString(String str) {
boolean isNumeric = str.chars().allMatch(Character::isDigit);
if (str.isEmpty()) {
return "1";
} else if (isNumeric) {
BigInteger b = new BigInteger(str);
return String.format("%0" + str.length() + "d", b.add(BigInteger.ONE));
}
String timeRegex = "(.*\\D0*)([1-9][0-9]*)";
Matcher matcher = Pattern.compile(timeRegex).matcher(str);
if (matcher.matches()) {
String sec = matcher.group(2);
if (sec.isEmpty()) {
return str + 1;
} else {
BigInteger new_value = new BigInteger(sec).add(BigInteger.ONE);
return matcher.group(1) + new_value;
}
}
return "";
}
How would you solve this problem by hand? I'll bet you wouldn't require a calculator.
The way I would do would be to just look at the last character in the string:
If the string is empty or the last character is not a digit, append the character 1.
If the last character is one of the digits 0 to 8, change it to the next digit.
If the last character is the digit 9:
Remove all the trailing 9s
Apply whichever of (1) or (2) above is appropriate.
Append the same number of 0s as the number of 9s you removed.
You can implement that simple algorithm in a few lines, without BigInteger and without regexes.
This seems to work, although I didn't test it thoroughly with different Unicode scripts (and I'm really not a Java programmer):
public static String incrementString(String str) {
if (str.isEmpty())
return "1";
char lastChar = str.charAt(str.length()-1);
if (!Character.isDigit(lastChar))
return str + "1";
String prefix = str.substring(0, str.length()-1);
if (Character.digit(lastChar, 10) != 9)
return prefix + (char)(lastChar + 1);
return incrementString(prefix) + (char)(lastChar - 9);
}
I have a string in format AB123. I want to split it between the AB and 123 so AB123 becomes AB 123. The contents of the string can differ but the format stays the same. Is there a way to do this?
Following up with the latest information you provided (2 letters then 3 numbers):
myString.subString(0, 2) + " " + myString.subString(2)
What this does: you split your input string myString at the 2nd character and append a space at this position.
Explanation: \D represents non-digit and \d represents a digit in a regular expression and I used ternary operation in the regex to split charter to the number.
String string = "AB123";
String[] split = string.split("(?<=\\D)(?=\\d)");
System.out.println(split[0]+" "+split[1]);
Try
String a = "abcd1234";
int i;
for(i = 0; i < a.length(); i++){
char c = a.charAt(i);
if( '0' <= c && c <= '9' )
break;
}
String alphaPart = a.substring(0, i);
String numberPart = a.substring(i);
Hope this helps
Although I would personally use the method provided in #RakeshMothukur's answer, since it also works when the letter or digit counts increase/decrease later on, I wanted to provide an additional method to insert the space between the two letters and three digits:
String str = "AB123";
StringBuilder sb = new StringBuilder(str);
sb.insert(2, " "); // Insert a space at 0-based index 2; a.k.a. after the first 2 characters
String result = sb.toString(); // Convert the StringBuilder back to a String
Try it online.
Here you go. I wrote it in very simple way to make things clear.
What it does is : After it takes user input, it converts the string into Char array and it checks single character if its INT or non INT.
In each iteration it compares the data type with the prev character and prints accordingly.
Alternate Solutions
1) Using ASCII range (difficulty = easy)
2) Override a method and check 2 variables at a time. (difficulty = Intermediate)
import org.omg.CORBA.INTERNAL;
import java.io.InputStreamReader;
import java.util.*;
import java.io.BufferedReader;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
char[] s = br.readLine().toCharArray();
int prevflag, flag = 0;
for (int i = 0; i < s.length; i++) {
int a = Character.getNumericValue(s[i]);
String b = String.valueOf(s[i]);
prevflag = flag;
flag = checktype(a, b);
if ((prevflag == flag) || (i == 0))
System.out.print(s[i]);
else
System.out.print(" " + s[i]);
}
}
public static int checktype(int x, String y) {
int flag = 0;
if (String.valueOf(x).equals(y))
flag = 1; // INT
else
flag = 2; // non INT
return flag;
}
}
I was waiting for a compile to finish before heading out, so threw together a slightly over-engineered example with basic error checking and a test.
import java.text.ParseException;
import java.util.LinkedList;
public class Main {
static public class ParsedData {
public final String prefix;
public final Integer number;
public ParsedData(String _prefix, Integer _number) {
prefix = _prefix;
number = _number;
}
#Override
public String toString() {
return prefix + "\t" + number.toString();
}
}
static final String TEST_DATA[] = {"AB123", "JX7272", "FX402", "ADF123", "JD3Q2", "QB778"};
public static void main(String[] args) {
parseDataArray(TEST_DATA);
}
public static ParsedData[] parseDataArray(String[] inputs) {
LinkedList<ParsedData> results = new LinkedList<ParsedData>();
for (String s : TEST_DATA) {
try {
System.out.println("Parsing: " + s);
if (s.length() != 5) throw new ParseException("Input Length incorrect: " + s.length(), 0);
String _prefix = s.substring(0, 2);
Integer _num = Integer.parseInt(s.substring(2));
results.add(new ParsedData(_prefix, _num));
} catch (ParseException | NumberFormatException e) {
System.out.printf("\"%s\", %s\n", s, e.toString());
}
}
return results.toArray(new ParsedData[results.size()]);
}
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexMatches {
public static void main(String args[]) {
// String to be scanned to find the pattern.
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d+)(.*)";
// Create a Pattern object
Pattern r = Pattern.compile(pattern);
// Now create matcher object.
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
} else {
System.out.println("NO MATCH");
}
}
}
The output
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT300
Found value: 0
Please I want to understand this code in regular expression in java.
I think that you want to extract a number from the given string.
Pattern pattern = Pattern.compile("(?<prefix>\\D*)(?<number>\\d+)(?<suffix>\\D*)");
Matcher matcher = pattern.matcher("This order was placed for QT3000! OK?");
if (matcher.matches()) {
System.out.println("Prefix: " + matcher.group("prefix")); // Prefix: This order was placed for QT
System.out.println("Number: " + matcher.group("number")); // Number: 3000
System.out.println("Suffix: " + matcher.group("suffix")); // Suffix: ! OK?
} else
System.out.println("NO MATCH");
In case you want to capture whole string, then you should use Matcher.matcher() to check regular expression.
if(matcher.matches()) {
// string matches with regular expression
} else {
// string does not match with regular expression
}
If you want to find multiple matches, then you should use Matcher.hasNext().
while (matcher.matches()) {
// next match found
}
Demo at www.regex101.com
You can use the Scanner class to parse the integers inside of a string of text. I also added utility methods to grow and fit an array.
import java.util.*;
public class NumberExtractor {
public static void main(String[] args) {
String test = "This order was placed for QT3000! OK?";
int[] numbers = extractNumbers(test);
System.out.println(Arrays.toString(numbers)); // [ 3000 ]
}
public static int[] extractNumbers(String str) {
return extractNumbers(str, 10);
}
public static int[] extractNumbers(String str, int defaultSize) {
int count = 0;
int[] result = new int[defaultSize];
Scanner scanner = new Scanner(str);
scanner.useDelimiter("[^\\d]+"); // Number pattern
while (scanner.hasNextInt()) {
if (count == result.length) {
result = growArray(result, 1.5f);
}
result[count++] = scanner.nextInt();
}
scanner.close();
return clipArray(result, count);
}
private static int[] growArray(int[] original, float growthPercent) {
int[] copy = new int[(int) (original.length * growthPercent)];
System.arraycopy(original, 0, copy, 0, Math.min(original.length, copy.length));
return copy;
}
private static int[] clipArray(int[] original, int length) {
return clipArray(original, 0, length);
}
private static int[] clipArray(int[] original, int start, int length) {
int[] copy = new int[length];
System.arraycopy(original, start, copy, 0, length);
return copy;
}
}
Firstly, as Aaron explained, the regex engine matches all the input string by first group. Secondly it backtracks to the find the part of the string matches with the second group and by just one digit the second group would be satisfied. Eventually, the rest of the string would be matched by the last group(3rd one).
Now Consider below code based on your sample code with some changes on pattern and one more printing statement:
String line = "This order was placed for QT3000! OK?";
String pattern = "(.*)(\\d{4})(.*)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
if (m.find()) {
System.out.println("Found value: " + m.group(0));
System.out.println("Found value: " + m.group(1));
System.out.println("Found value: " + m.group(2));
System.out.println("Found value: " + m.group(3));
} else {
System.out.println("NO MATCH");
}
printing added statement: m.group(0) is equivalent of m.group() which means return all the matches of the given pattern in the given input string. By having such a pattern we have three other group indexes too. So by printing whole groups it can help us to find out what is happening right now by applying that pattern to that string.
pattern change: the change in the pattern can confirm the asserted statement about how the java regex engine works toward the original statement. So, the new pattern can select all the digits present in the input string and the output would change to below one:
Found value: This order was placed for QT3000! OK?
Found value: This order was placed for QT
Found value: 3000
Found value: ! OK?
Suppose that I want to build a very large regex with capture groups on run-time based on user's decisions.
Simple example:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
static boolean findTag, findWordA, findOtherWord, findWordX;
static final String TAG = "(<[^>]+>)";
static final String WORD_A = "(wordA)";
static final String OTHER_WORD = "(anotherword)";
static final String WORD_X = "(wordX)";
static int tagCount = 0;
static int wordACount = 0;
static int otherWordCount = 0;
static int wordXCount = 0;
public static void main(String[] args) {
// Boolean options that will be supplied by the user
// make them all true in this example
findTag = true;
findWordA = true;
findOtherWord = true;
findWordX = true;
String input = "<b>this is an <i>input</i> string that contains wordX, wordX, anotherword and wordA</b>";
StringBuilder regex = new StringBuilder();
if (findTag)
regex.append(TAG + "|");
if (findWordA)
regex.append(WORD_A + "|");
if (findOtherWord)
regex.append(OTHER_WORD + "|");
if (findWordX)
regex.append(WORD_X + "|");
if (regex.length() > 0) {
regex.setLength(regex.length() - 1);
Pattern pattern = Pattern.compile(regex.toString());
System.out.println("\nWHOLE REGEX: " + regex.toString());
System.out.println("\nINPUT STRING: " + input);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
// only way I know of to find out which group was matched:
if (matcher.group(1) != null) tagCount++;
if (matcher.group(2) != null) wordACount++;
if (matcher.group(3) != null) otherWordCount++;
if (matcher.group(4) != null) wordXCount++;
}
System.out.println();
System.out.println("Group1 matches: " + tagCount);
System.out.println("Group2 matches: " + wordACount);
System.out.println("Group3 matches: " + otherWordCount);
System.out.println("Group4 matches: " + wordXCount);
} else {
System.out.println("No regex to build.");
}
}
}
The problem is that I can only count each group's matches only when I know beforehand which regex/groups the user wants to find.
Note that the full regex will contain a lot more capture groups and they will be more complex.
How can I determine which capture group was matched so that I can count each group's occurrences, without knowing beforehand which groups the user wants to find?
construct the regex to used named groups:
(?<tag>wordA)|(?<wordx>wordX)|(?<anotherword>anotherword)
I want to find in a Text the starting is number followed by .
example:
1.
11.
111.
My code for x. ( x is number) this is working . issue is when x is more than 2 digits.
x= Character.isDigit(line.charAt(0));
if(x)
if (line.charAt(1)=='.')
How can I extend this logic to see if x is a integer followed by .
My first issue is :
I need to fond the given line has x. format or not where x is a integr
You can use the regex [0-9]\. to see if there exists a digit followed by a period in the string.
If you need to ensure that the pattern is always at the beginning of the string you can use ^[0-9]+\.
Why not using a regular expression?
([0-9]+)[.]
You can use regex:
Pattern.compile("C=(\\d+\\.\\d+)")
However, more general would be:
Pattern.compile("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?")
Now to work with the Pattern you do something like:
Pattern pattern = Pattern.compile("[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
Matcher matcher = pattern.matcher(EXAMPLE_TEST);
// Check all occurances
while (matcher.find()) {
System.out.print("Start index: " + matcher.start());
System.out.print(" End index: " + matcher.end() + " ");
System.out.println(matcher.group());
}
Edit: Whoops, misread.
try this:
public static boolean prefix(String s) {
return s.matches("[0-9]+\\.");
}
public class ParsingData {
public static void main(String[] args) {
//String one = "1.";
String one = "11.";
int index = one.indexOf(".");
String num = (String) one.subSequence(0, index);
if(isInteger(num)) {
int number = Integer.parseInt(num);
System.out.println(number);
}
else
System.out.println("Not an int");
}
public static boolean isInteger(String string) {
try {
Integer.valueOf(string);
return true;
} catch (NumberFormatException e) {
return false;
}
}
}