Invalid result from coderbyte - java

Refer to the test below, some test cases are failed in fact even the output is correct. Can anyone advise?
https://coderbyte.com/editor/Longest%20Word:Java
Longest Word
Have the function LongestWord(sen) take the sen parameter being passed and return the largest word in the string. If there are two or more words that are the same length, return the first word from the string with that length. Ignore punctuation and assume sen will not be empty.
Examples
Input: "fun&!! time"
Output: time
Input: "I love dogs"
Output: love
Below are the invalid failing test cases
For input "a beautiful sentence^&!" the output was incorrect. The correct output is beautiful
For input "oxford press" the output was incorrect. The correct output is oxford
For input "123456789 98765432" the output was incorrect. The correct output is 123456789
For input "a b c dee" the output was incorrect. The correct output is dee
For input "a confusing /:sentence:/[ this is not!!!!!!!~" the output was incorrect. The correct output is confusing
The program
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static final String REG_EXP_CHAR_ONLY = "(?=.*?[a-zA-Z0-9 ])";
public static String LongestWord(String sen) {
StringBuffer strBuffer = new StringBuffer();
for (String c : sen.split("")) {
//System.out.println("c--------->" + c);
if (isValid(c)) {
strBuffer.append(c);
}
}
//System.out.println(strBuffer.toString());
String longest = Arrays.stream(strBuffer.toString().split(" ")).max(Comparator.comparingInt(String::length))
.orElse(null);
return longest;
}
public static boolean isValid(String c) {
// System.out.println("char -->" + c);
Pattern pattern = Pattern.compile(REG_EXP_CHAR_ONLY);
Matcher matcher = pattern.matcher(c);
boolean matchFound = matcher.find();
if (matchFound) {
// System.out.println("Match found");
return true;
}
return false;
}
public static void main (String[] args) {
// keep this function call here
Scanner s = new Scanner(System.in);
System.out.print(LongestWord(s.nextLine()));
}
}

It seems that this is a problem from coderbyte. I copied your code and submitted. Then it passed.
==================================================================
Edit:
maybe you should use "StringBuilder"(not StringBuffer) instead.
I just fixed all warnings in ide and then all tests pass.
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static final String REG_EXP_CHAR_ONLY = "(?=.*?[a-zA-Z0-9 ])";
public static String LongestWord(String sen) {
StringBuilder strBuffer = new StringBuilder();
for (String c : sen.split("")) {
//System.out.println("c--------->" + c);
if (isValid(c)) {
strBuffer.append(c);
}
}
return Arrays.stream(strBuffer.toString().split(" ")).max(Comparator.comparingInt(String::length))
.orElse(null);
}
public static boolean isValid(String c) {
// System.out.println("char -->" + c);
Pattern pattern = Pattern.compile(REG_EXP_CHAR_ONLY);
Matcher matcher = pattern.matcher(c);
// System.out.println("Match found");
return matcher.find();
}
public static void main (String[] args) {
// keep this function call here
Scanner s = new Scanner(System.in);
System.out.print(LongestWord(s.nextLine()));
}
}

Related

grab last four digits approach after deleting non digits using regex

I'm getting the URL(http://localhost:8080/CompanyServices/api/creators/2173) shown below from a HTTP Response header and I want to get the id after the creators which is 2173.
So, I deleted all non digits as shown below and got the following result : 80802173.
Is it a good approach to get the last 4 digits from the above set of digits?
One thing is that, this part localhost:8080 could change depending upon the server I deploy my application so I'm wondering if I should just grab something after creators/ ? If yes, then what is the best way to go about it?
public class GetLastFourIDs {
public static void main(String args[]){
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
String replaceString=str.replaceAll("\\D+","");
System.out.println(replaceString);
}
}
You can use regex API e.g.
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
Pattern pattern = Pattern.compile("(creators/\\d+)");
Matcher matcher = pattern.matcher(str);
int value = 0;
if (matcher.find()) {
// Get e.g. `creators/2173` and split it on `/` then parse the second value to int
value = Integer.parseInt(matcher.group().split("/")[1]);
}
System.out.println(value);
}
}
Output:
2173
Non-regex solution:
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
int index = str.indexOf("creators/");
int value = 0;
if (index != -1) {
value = Integer.parseInt(str.substring(index + "creators/".length()));
}
System.out.println(value);
}
}
Output:
2173
[Update]
Incorporating comment by Andreas as follows:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String str = "http://localhost:8080/CompanyServices/api/creators/2173";
Pattern pattern = Pattern.compile("creators/(\\d+)");
Matcher matcher = pattern.matcher(str);
int value = 0;
if (matcher.find()) {
value = Integer.parseInt(matcher.group(1));
}
System.out.println(value);
}
}
Output:
2173

I solved the problem, but as it turned out wrong. What needs to be changed in the code?

I solved the problem, but as it turned out wrong, the teacher said that from java.util. *, You can only use java.util.regex. *, Help solve the problem of how to do without java.util.LinkedHashSet and java.util.Set in this situation.
What needs to be changed in the code?
TASK
The task must be solved using regular expressions.
The method should convert input data to string of the following type (mail domain ==> list of logins separated by a comma of those users whose mailboxes are registered in this domain):
mail.com ==> ivanov, bush;
google.com ==> петров, obama
part1.txt
ivanov;Ivan Ivanov;ivanov#mail.com
петров;Петр Петров;petrov#google.com
obama;Barack Obama;obama#google.com
bush;Джордж Буш;bush#mail.com
Part1.java
import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.LinkedHashSet;
import java.util.Set;
import static Util.getMatcher;
public class Part1 {
private static final String TXTP1 = "part1.txt";
public static void main(String[] args) {
System.out.println(convert3(Util.readFile(TXTP1)));
}
public static String convert3(String input) {
String regex = "(?m)^(.+(?=;));.+;.+#(.+)(?=\\b)$";
Matcher matcher = Util.getMatcher(regex, input);
StringBuilder sb = new StringBuilder();
Set<String> set = new LinkedHashSet<>();
while (matcher.find()) {
set.add(matcher.group(2));
}
for (String s : set) {
matcher = Util.getMatcher(regex, input);
sb.append(s).append(" ==> ");
while (matcher.find()) {
if (s.equals(matcher.group(2))) {
sb.append(matcher.group(1)).append(", ");
}
}
sb.delete(sb.length() - 2, sb.length()).append(System.lineSeparator());
}
return sb.toString();
}
}
Util.java
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Util {
private static final String ENCODING = "Cp1251";
public static String readFile(String path) {
String res = null;
try {
byte[] bytes = Files.readAllBytes(Paths.get(path));
res = new String(bytes, ENCODING);
} catch (IOException ex) {
ex.printStackTrace();
}
return res;
}
public static Matcher getMatcher(String regex, String input) {
Pattern p = Pattern.compile(regex);
return p.matcher(input);
}
public static void main(String[] args) {
System.out.println(readFile("part1.txt"));
}
}
You can create a small data class holding user and email domain. (A two-dimensional array of strings would work as well).
static class UserEmailData{
String domain, user;
UserEmailData(String domain, String user){
this.domain = domain;
this.user = user;
}
}
The sample data you have provided is consistent, so we can iterate the input extracting user and domain using regex.
String input = "ivanov;Ivan Ivanov;ivanov#mail.com\n" +
"петров;Петр Петров;petrov#google.com\n" +
"obama;Barack Obama;obama#google.com\n" +
"bush;Джордж Буш;bush#mail.com";
Pattern emailPattern = Pattern.compile("(.*?);(?:.*?)#([A-Za-z]+\\.[A-Za-z]+)");
String [] inputLines = input.split("\n");
UserEmailData [] usersAndDomains = new UserEmailData[inputLines.length];
int currentLine = 0;
for (String line : inputLines){
Matcher emailMatcher = emailPattern.matcher(line);
emailMatcher.find();
String user = emailMatcher.group(1);
String domain = emailMatcher.group(2);
usersAndDomains[currentLine] = new UserEmailData(domain, user);
currentLine++;
}
Once we have the data extracted, we can sort it depending on the domain value:
static void sortData(UserEmailData [] data){
for(int i=0; i<data.length; i++){
for(int j=i+1; j<data.length; j++){
if(data[i].domain.compareTo(data[j].domain)>0) {
UserEmailData temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
}
Now that the user data is sorted, printing it will give following output:
for(UserEmailData data : usersAndDomains){
System.out.println(data.user + " " + data.domain);
}
петров google.com
obama google.com
ivanov mail.com
bush mail.com
What's left is to keep concatenating users, as long as domain remains unchanged, which is a simple task.
Using regex in this task is a bit of an overkill, as you could simply split the string by ";" and use the same approach.

Java Regex Missing a Match

I'm trying to return a string of regular expression matches. Specifically, trying to return all vowels (aeiou) found in a string. The following code returns the 2 oo's but not the e.
Expecting: eoo
Getting: oo
Why is it not finding and appending the e to the StringBuilder object? Thank you.
import java.lang.StringBuilder;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Main {
public static void main(String[] args) {
String inp = "Hello World!";
System.out.println(vowelOnly(inp));
}
public static String vowelOnly(String input) {
Pattern vowelPattern = Pattern.compile("[aeiou]+");
Matcher vowelMatcher = vowelPattern.matcher(input);
StringBuilder sb = new StringBuilder();
int i = 0;
if (vowelMatcher.find()) {
while (vowelMatcher.find( )) {
sb.append(vowelMatcher.group());
i++;
}
return sb.toString();
} else {
return "No matches";
}
}
}
When you call vowelMatcher.find() inside your if condition, you tell the matcher to find the first string matching the specified pattern. In this case, it is "e". When you call it again in your while condition, the matcher finds the next match, in this case it is "o".
From there, it loops through the rest of the String. If you gave it the input "Hello World eeee", it would return "ooeeee", since you always discard the first match by calling .find() without calling .group() immediately after.
Change your loop to be like this, and it should work:
int i = 0;
while (vowelMatcher.find()) {
sb.append(vowelMatcher.group());
i++;
}
return i == 0 ? "No matches" : sb.toString(); // return "no matches" if i is 0, otherwise, string
Your first call to vowelMatcher.find() in the if statement finds the "e" and the subsequent calls to vowelMatcher.find() in the while loop find all subsequent vowels.
Thats what you need:
public static void main(String[] args) {
String inp = "Hello World!";
System.out.println(vowelOnly(inp));
}
public static String vowelOnly(String input) {
Pattern vowelPattern = Pattern.compile("[aeiou]+");
Matcher vowelMatcher = vowelPattern.matcher(input);
StringBuilder sb = new StringBuilder();
int i = 0;
while (vowelMatcher.find()) {
sb.append(vowelMatcher.group());
i++;
}
return i == 0 ? "No matches" : sb.toString();
}
That would probably be the solution you're looking for:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
String inp = "Hello World!";
System.out.println(vowelOnly(inp));
}
public static String vowelOnly(String input) {
Pattern vowelPattern = Pattern.compile("[aeiou]+");
Matcher vowelMatcher = vowelPattern.matcher(input);
StringBuilder sb = new StringBuilder();
while (vowelMatcher.find()) {
sb.append(vowelMatcher.group());
}
if (sb.length() == 0) {
return "No matches";
}
return sb.toString();
}
}
Couple of notes:
You don't need to import java.lang.* classes.
With the matcher, whatever you find, you should group it immediately to collect.
You don't need the iteration variable. StringBuilder.length() would simply reveal if it's empty.

Integers from strings

Hey guys am hoping you could help me with this.
Am trying to get all the integers from this code, just leaving the letters behind and am seriously lost here
public class Tie {
public static void main(String agrs[]){
String fr = "4544FF";
int yu = fr.length();
System.out.print(yu);
}
}
If you only seek to remove the numeric digits from the string, use regex and replace, with regex 'd' you can filter on all digits.
String fr = "4544FF";
fr = fr.replaceAll("\\d","");
//result should be that fr now is contains only "FF", because the digits have bee replaced with nothing.
I haven't tested it, but it should work, if my little experience with regex serves me right.
What you can do is use this method substring(int start, int final).
public static void main(String agrs[]){
String fr = "4544FF";
String numbers= fr.substring(0, 4);
String letters= fr.substring(4);
System.out.println("It will shows 4544" + numbers);
System.out.println("It will shows FF" + letters);
int convertNumber = Integer.parseInt(numbers); //Convert to int
System.out.println("" +convertNumber);
}
It will show you only the numbers 4544.
I hope that solve your problem.
try this code
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Tie {
public static void main(String agrs[]){
Tie tie = new Tie();
String fr = "4544FF";
char[] strings = fr.toCharArray();
List<Integer>integers = new ArrayList<Integer>();
for(int i=0;i<strings.length;i++){
if(tie.validationNumber(strings[i]+"")){
integers.add(Integer.parseInt(strings[i]+""));
}
}
for(Integer i:integers){
System.out.println(i);
}
}
public boolean validationNumber(String s){
Pattern pattern = Pattern.compile("\\d+");
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
return true;
}
return false;
}
}

Removing consecutive duplicates words out of text using Regex and displaying the new text

Hy,
I have the following code:
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.*;
/
public class RegexSimple4
{
public static void main(String[] args) {
try {
Scanner myfis = new Scanner(new File("D:\\myfis32.txt"));
ArrayList <String> foundaz = new ArrayList<String>();
ArrayList <String> noduplicates = new ArrayList<String>();
while(myfis.hasNext()) {
String line = myfis.nextLine();
String delim = " ";
String [] words = line.split(delim);
for (String s : words) {
if (!s.isEmpty() && s != null) {
Pattern pi = Pattern.compile("[aA-zZ]*");
Matcher ma = pi.matcher(s);
if (ma.find()) {
foundaz.add(s);
}
}
}
}
if(foundaz.isEmpty()) {
System.out.println("No words have been found");
}
if(!foundaz.isEmpty()) {
int n = foundaz.size();
String plus = foundaz.get(0);
noduplicates.add(plus);
for(int i=1; i<n; i++) {
if ( !noduplicates.get(i-1) .equalsIgnoreCase(foundaz.get(i))) {
noduplicates.add(foundaz.get(i));
}
}
//System.out.print("Cuvantul/cuvintele \n"+i);
}
if(!foundaz.isEmpty()) {
System.out.print("Original text \n");
for(String s: foundaz) {
System.out.println(s);
}
}
if(!noduplicates.isEmpty()) {
System.out.print("Remove duplicates\n");
for(String s: noduplicates) {
System.out.println(s);
}
}
} catch(Exception ex) {
System.out.println(ex);
}
}
}
With the purpose of removing consecutive duplicates from phrases. The code works only for a column of strings not for full length phrases.
For example my input should be:
Blah blah dog cat mice.
Cat mice dog dog.
And the output
Blah dog cat mice.
Cat mice dog.
Sincerly,
First of all, the regex [aA-zZ]* doesn't do what you think it does. It means "Match zero or more as or characters in the range between ASCII A and ASCII z (which also includes [, ], \ and others), or Zs". It therefore also matches the empty string.
Assuming that you are only looking for duplicate words that consists solely of ASCII letters, case-insensitively, keeping the first word (which means that you wouldn't want to match "it's it's" or "olé olé!"), then you can do that in a single regex operation:
String result = subject.replaceAll("(?i)\\b([a-z]+)\\b(?:\\s+\\1\\b)+", "$1");
which will change
Hello hello Hello there there past pastures
into
Hello there past pastures
Explanation:
(?i) # Mode: case-insensitive
\b # Match the start of a word
([a-z]+) # Match one ASCII "word", capture it in group 1
\b # Match the end of a word
(?: # Start of non-capturing group:
\s+ # Match at least one whitespace character
\1 # Match the same word as captured before (case-insensitively)
\b # and make sure it ends there.
)+ # Repeat that as often as possible
See it live on regex101.com.
Bellow code work fine
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DuplicateRemoveEx {
public static void main(String[] args){
String regex="(?i)\\b(\\w+)(\\b\\W+\\1\\b)+";
Pattern p = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
Scanner in = new Scanner(System.in);
int numSentences = Integer.parseInt(in.nextLine());
while(numSentences-- >0){
String input = in.nextLine();
Matcher m = p.matcher(input);
while(m.find()){
input=input.replaceAll(regex, "$1");
}
System.out.println(input);
}
in.close();
}
}
Bellow it is your code. I have used lines to split text and Tim's regular expression.
import java.util.Scanner;
import java.io.*;
import java.util.regex.*;
import java.util.ArrayList;
/**
*
* #author Marius
*/
public class RegexSimple41 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ArrayList <String> manyLines = new ArrayList<String>();
ArrayList <String> noRepeat = new ArrayList<String>();
try
{
Scanner myfis = new Scanner(new File("D:\\myfis41.txt"));
while(myfis.hasNext())
{
String line = myfis.nextLine();
String delim = System.getProperty("line.separator");
String [] lines = line.split(delim);
for(String s: lines)
{
if(!s.isEmpty()&&s!=null)
{
manyLines.add(s);
}
}
}
if(!manyLines.isEmpty())
{ System.out.print("Original text\n");
for(String s: manyLines)
{
System.out.println(s);
}
}
if(!manyLines.isEmpty())
{
for(String s: manyLines)
{
String result = s.replaceAll("(?i)\\b([a-z]+)\\b(?:\\s+\\1\\b)+", "$1");
noRepeat.add(result);
}
}
if(!noRepeat.isEmpty())
{ System.out.print("Remove duplicates\n");
for(String s: noRepeat)
{
System.out.println(s);
}
}
}
catch(Exception ex)
{
System.out.println(ex);
}
}
}
Good luck,

Categories