filtering algorithm trouble - java

public static String filterPhoneNumber(String phoneNumber) {
Character[] characters = new Character[phoneNumber.length()];
if (characters.length > 9)
{
for (int i = 0; i < characters.length; i++)
{
if (characters[i] != ' ')
{
characters[i] = phoneNumber.charAt(i);
} else
{
Log.d("asd", "wrroooonggggggggg");
}
}
}
return phoneNumber;
}
Im trying to filter empty chars in the number, but when 2 or more empty chars are found in the string, it removes only the first.

Your problem is that you increase i in the for-loop and when you find a space you skip it. When you in the next loop set the number in characters you have skipped one entry. You must use two stepping variables, one for stepping phoneNumber and one for characters.
It looks like you want to return a filter phone number, but are returning the values that you sent in.
There is a search and replace method on String that you can use.
public static String filterPhoneNumber(String phoneNumber) {
return phoneNumber.replaceAll(" ","");
}
Here is how it is used: http://runnable.com/VUfHvPvHoEdLO3id/filterphonenumber-for-java

If you use
char[] characters = new char[phoneNumber.length()];
it works.

your characters array should be of the type char[]
characters array is never initialized, so characters[i] != ' ' is always true (provided that you fix the array type, else should throw a NullPointerException)
you're assign characters[i] = phoneNumber.charAt(i) but you never read it afterwards.
If your goal is to remove spaces just do this:
public static String filterPhoneNumber(String phoneNumber) {
return phoneNumber.replaceAll(" ", "");
}

Working 100%
public static String filterPhoneNumber(String phoneNumber) {
byte[] number = phoneNumber.getBytes();
byte[] array = new byte[phoneNumber.length()];
int count=0;
for (int i = 0; i < number.length; i++){
if (number[i] != ' '){
array[count++] = number[i];
}
}
return new String(array);
}
public static void main(String[] args) {
String res = filterPhoneNumber(" +28 23");
System.out.println(res); //OUTPUT "+2823"
}

Related

I'm stuck. I need to adjust my loops so they continue to compare my two arrays but not print out all the extra characters

I have to compare two string arrays. If the any of the characters in myArray match a character in argArray then I need to swap the case of the character in myArray. I'm almost there but am getting extra output.
This is what I have so far -
public class Main {
public static void main(String[] args) {
Main ob = new Main();
ob.reverse("bcdxyz#3210.");
}
public String reverse(String arg) {
String reverseCap = "";
String myStr = "abc, XYZ; 123.";
char[] argArray = arg.toCharArray();
char[] myArray = myStr.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++){
if (myArray[i] == argArray[j] && Character.isLowerCase(myArray[i])){
reverseCap += Character.toUpperCase(myArray[i]);
} else if (myArray[i] == argArray[j] && Character.isUpperCase(myArray[i])){
reverseCap += Character.toLowerCase(myArray[i]);
} else {
reverseCap += myArray[i];
}
}
}
System.out.println(reverseCap);
return null;
}
I want reverseCap to be "aBC, xyz, 123." but am getting the following -
"aaaaaaaaaaaaBbbbbbbbbbbbcCcccccccccc,,,,,,,,,,,, XXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZZZZZ;;;;;;;;;;;; 111111111111222222222222333333333333............
".
I've been staring at this for hours so I figured it was time to ask for help before I pluck my eyes out.
Marce noted the problem of adding characters to reverseCap on every iteration. Here is a solution that solves that problem and performs the case changes in place. Checking for a match first and then changing the case simplifies the logic a bit. Note myArray[i] needs to be lowercased before checking against arg[i] because the former may be an uppercase character; this is not needed for argArray[j] because those characters are assumed to be all lowercase. Finally, once the inner loop has matched, further iterations of it are no longer needed.
public class Main {
public static void main(String[] args) {
Main ob = new Main();
String testStr = "abc, XYZ; 123.";
String testArg = "bcdxyz#3210.";
System.out.println(testStr + " using " + testArg + " =>");
System.out.println(ob.reverse(testStr, testArg));
}
public String reverse(String myStr, String myArg) {
char[] myArray = myStr.toCharArray();
char[] argArray = myArg.toCharArray();
for (int i =0; i < myArray.length; i++) {
for (int j =0; j < argArray.length; j++) {
if (Character.toLowerCase(myArray[i]) == argArray[j]) {
if (Character.isLowerCase(myArray[i])) {
myArray[i] = Character.toUpperCase(myArray[i]);
} else if (Character.isUpperCase(myArray[i])) {
myArray[i] = Character.toLowerCase(myArray[i]);
}
break;
}
}
}
return String.valueOf(myArray);
}
}
With this part
} else {
reverseCap += myArray[i];
}
you're adding a character to reverseCap with every iteration, regardless if the characters match or not.
In your specific example, you could just leave that out, since every character in myStr also appears in arg, but if you want to add characters to reverseCap, even if they don't appear in arg, you'll need a way of checking if you already added a character to reverseCap.
Change
String reverseCap = "";
to
char[] reverseCap = new char[myStr.length()];
and then for each occurrence of
reverseCap +=
change that to read
reverseCap[i] =
Finally, convert reverseCap to a String:
String result = String.valueOf(reverseCap);
You are currently returning null. Consider returning result, and moving the System.out.println(...) into the main() method.
Update:
I think a better way to approach this is to use a lookup map containing upper/lower case pairs and their inverse to get the replacement character. The nested for loops are a bit gnarly.
/**
* Example: for the string "bcdxyz#3210."
* the lookup map is
* {B=b, b=B, C=c, c=C, D=d, d=D, X=x, x=X, Y=y, y=Y, Z=z, z=Z}
* <p>
* Using a map to get the inverse of a character is faster than repetitively
* looping through the string.
* </p>
* #param arg
* #return
*/
public String reverse2(String arg) {
Map<Character, Character> inverseLookup = createInverseLookupMap(arg);
String myStr = "abc, XYZ; 123.";
String result = myStr.chars()
.mapToObj(ch -> Character.toString(inverseLookup.getOrDefault(ch, (char) ch)))
.collect(Collectors.joining());
return result;
}
private Map<Character, Character> createInverseLookupMap(String arg) {
Map<Character, Character> lookupMap = arg.chars()
.filter(ch -> Character.isLetter(ch))
.mapToObj(this::getPairs)
.flatMap(List::stream)
.collect(Collectors.toMap(Pair::key, Pair::value));
System.out.println(lookupMap);
return lookupMap;
}
private List<Pair> getPairs(int ch) {
char upperVariant = (char) Character.toUpperCase(ch);
return List.of(
new Pair(upperVariant, Character.toLowerCase(upperVariant)),
new Pair(Character.toLowerCase(upperVariant), upperVariant));
}
static record Pair(Character key, Character value) {
}
But if one is not used to the Java streaming API, this might look a bit gnarly too.

I need help converting strings into camelCase with multiple "_" using loop

My code doesnt convert ex. dog_cat_dog into dogCatDog. The out put of my code is dogCat_dog. Trying to make a loop that doesn't stop at the first "_":
public String underscoreToCamel(String textToConvert) {
int index_= textToConvert.indexOf("_",0);
String camelCase="";
String upperCase = "";
String lowerCase="";
for (int i=0; i < textToConvert.length(); i++){
if(i==index_){
upperCase= (textToConvert.charAt(index_+1)+upperCase).toUpperCase();
upperCase= upperCase+ textToConvert.substring(index_+2);
}
else{
lowerCase=textToConvert.substring(0,index_);
}
camelCase=lowerCase+upperCase;
}
return camelCase;
}
I would do the following: make the method static, it does not use any class state. Then instantiate a StringBuilder with the passed in value, because that is mutable. Then iterate the StringBuilder. If the current character is underscore, delete the current character, then replace the now current character with its upper case equivalent. Like,
public static String underscoreToCamel(String s) {
StringBuilder sb = new StringBuilder(s);
for (int i = 0; i < sb.length(); i++) {
if (sb.charAt(i) == '_') {
sb.deleteCharAt(i);
char ch = Character.toUpperCase(sb.charAt(i));
sb.setCharAt(i, ch);
}
}
return sb.toString();
}
I tested like
public static void main(String[] args) {
System.out.println(underscoreToCamel("dog_cat_dog"));
}
Which outputs (as requested)
dogCatDog
You can split on '_' then rebuild.
public static String underscoreToCamel(String textToConvert) {
String [] words = textToConvert.split("_");
StringBuilder sb = new StringBuilder(words[0]);
for (int i = 1; i < words.length; i++) {
sb.append(Character.toUpperCase(words[i].charAt(0)));
sb.append(words[i].substring(1));
}
return sb.toString();
}
I think an easy way to solve this is to first consider the base cases, then tackle the other cases
public static String underscoreToCamel(String textToConvert){
//Initialize the return value
String toReturn = "";
if (textToConvert == null){
//Base Case 1: null value, so just return an empty string
return "";
} else if (textToConvert.indexOf("_") == -1) {
//Base Case 2: string without underscore, so just return that string
return textToConvert;
} else {
//Primary Case:
//Find index of underscore
int underscore = textToConvert.indexOf("_");
//Append everything before the underscore to the return string
toReturn += textToConvert.substring(0, underscore);
//Append the uppercase of the first letter after the underscore
toReturn += textToConvert.substring(underscore+1, underscore+2).toUpperCase();
//Append the rest of the textToConvert, passing it recursively to this function
toReturn += underscoreToCamel(textToConvert.substring(underscore+2));
}
//Final return value
return toReturn;
}

How to search the largest string in an array of strings

I need to find the largest string from an array of strings and also want to make sure that the string which comes out should include only those chars which are defined in a separate string.
For eg: if an array of strings contains {"ABCAD","ABC","ABCFHG","AB"}
and another string S have chars "ABCD".
Then the largest string return here should be ABCAD as it contains only the characters defined in S.
public String findstring(String a, String[] arr)
{
String s="";
for(i=0; i<arr.length; i++)
{
//int m=0;
if(arr[i].length() > s.length())
{
s = arr[i];
}
}
for(j=0; j<s.length(); j++)
{
int m=0;
for(k=0; k<a.length(); k++)
{
if(m>0)
{
break;
}
if((s.charAt(j)==a.charAt(k)))
{
m++;
}
else
{
continue;
}
}
if(m==0)
{
List<String> list = new ArrayList<String>(Arrays.asList(arr));
list.remove(s);
arr = list.toArray(new String[0]);
findstring("ABCD", arr);
}
}
return s;
}
}
I am not receiving any error and getting the largest string as ABCFABCD whereas F needs to be excluded and largest string should be ABCAA.
Its skipping all the checks, don't know why?
You can do it in better way using Regex:
public String findstring(final String a, final String[] arr) {
String s = "";
// Created pattern of the characters available in the String
final Pattern p = Pattern.compile("^[" + a + "]*$");
for (int i = 0; i < arr.length; i++) {
if (p.matcher(arr[i]).matches()) {
if ("".equals(s)) {
s = arr[i];
} else if (arr[i].length() > s.length()) {
s = arr[i];
}
}
}
return s;
}
You make recursive call but just ignore the returned value.
Try add return on recursive findstring.
arr = list.toArray(new String[0]);
return findstring("ABCD", arr);
If you want to have the luxury of New & Much Better Java Powers with some elegant, readable and less lines of code... you can have a look at below snippet:
public static void main(String args[]) {
final String allowedChars = "ABCD";
final char[] chars = allowedChars.toCharArray();
String result = Stream.of("ABCAD","ABC","ABCFHG","AB")
.filter(s ->{
for(char c: chars){
if(!s.contains(c+""))
return false;
}
return true;
})
.max(Comparator.comparingInt(String::length))
.orElse("No Such Value Found");
System.out.println("Longes Valid String : " + result);
}
Explanation:
The code makes a Stream of String from arrays and filter only valid strings (Strings which are not containing the allowed characters will simply be removed from the further processing) and remaining Stream will be compared for the length (using Comparator), and finally, longest valid String will be returned.
There may be a case where all the strings in array/Stream would be invalid, in such case, the code will return the Message "No Such Value Found" as String, however you can throw an exception, or you can return some own value for your custom logic, or you can return null, etc.
I've intentionally kept the String message and gave you the hint about learning other methods present in Java Stream so that you can explore more.
Keep Coding... and feel the Power of New JAVA. :)

Java: Formatting issue. Grabbing unique characters from an array of strings and returning them

I'm having a problem getting the unique letters and digits out of an array of strings, and then returning them. I am having a formatting issue.
The given input is: ([abc, 123, efg]) and is supposed to return abcefg123,
however, mine returns: abc123efg
how can I fix this since arrays.sort() will end up putting the numbers first and not last?
Here is my method so far:
public static String getUniqueCharsAndDigits(String[] arr) {
String str = String.join(",", arr);
String myString = "";
myString = str.replaceAll("[^a-zA-Z0-9]", "");
for(int i = 0; i < str.length(); i++) {
if(Character.isLetterOrDigit((i))){
if(myString.indexOf(str.charAt(i)) == -1) {
myString = myString + str.charAt(i);
}
}
}
return myString;
}
What you want to do is create two strings, one with the letters, one with the digits.
public static String getUniqueCharsAndDigits(String[] arr) {
String str = String.join("", arr);
String myLetters, myDigits;
myLetters = myDigits = "";
for(int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if(Character.isLetter(c)){
if(myLetters.indexOf(c) == -1) {
myLetters += c;
}
} else if(Character.isDigit(c)){
if(myDigits.indexOf(c) == -1) {
myDigits += c;
}
}
}
//if they need to be sorted, sort each one individually here
return myLetters + myDigits;
}
I've modified your code and deleted the unnecessary parts of it.

trouble with CharAt

I am suppose to make a simple program that would take a users input, and put spaces between each single letter. So for example, user enters mall, and it returns M A L L(on same line).
I am trying to make a loop with a if statement in it.But I think I would need CharAt for it, so if the string is greater value then 1, I would declare a variable to everysingle character in the string(that the userinput). Then I would say put spaces between each letter. I am in AP computer science A, and we are practicing loops.Everything underthis, is what I have done so far. And the directions are in the comment above code.And im useing eclipse,java.
/**
* Splits the string str into individual characters: Small becomes S m a l l
*/
public static String split(String str) {
for (int i = 0; str.length() > i; i++) {
if (str.length() > 0) {
char space = str.charAt();
}
}
return str;
}
My solution uses concat to build the str2, and trim to remove last white space.
public static String split(String str) {
String str2 = "";
for(int i=0; i<str.length(); i++) {
str2 = str2.concat(str.charAt(i)+" ");
}
return str2.trim();
}
You don't modify method parameters, you make copies of them.
You don't null-check/empty-check inside the loop, you do it first thing in the method.
The standard in a for loop is i < size, not size > i... meh
/**
* Splits the string str into individual characters: Small becomes S m a l l
*/
public static String split(final String str)
{
String result = "";
// If parameter is null or empty, return an empty string
if (str == null || str.isEmpty())
return result;
// Go through the parameter's characters, and modify the result
for (int i = 0; i < str.length(); i++)
{
// The new result will be the previous result,
// plus the current character at position i,
// plus a white space.
result = result + str.charAt(i) + " ";
}
return result;
}
4. Go pro, use StringBuilder for the result, and static final constants for empty string and space character.
Peace!
Ask yourself a question, where is s coming from?
char space = s.charAt(); ??? s ???
A second question, character at?
public static String split(String str){
for(int i = 0; i < str.length(); i++) {
if (str.length() > 0) {
char space = str.charAt(i)
}
}
return str;
}
#Babanfaraj, this a answer from a newbie like you!!
The code is very easy. The corrected program is-
class fopl
{
public static void main(String str)
{
int n=str.length();
for (int i = 0;i<n; i++)
{
if (n>=0)
{
String space = str.charAt(i)+" ";
System.out.print(space);
}
}
}
}
Happy to help you!

Categories

Resources