java method returning a modified string - java

I'm trying to create a method that will accept 2 strings as arguments. The first string will be a phrase, the second also a prhase. What I want the method to do is to compare both strings for matching chars. If string 2 has a char that is found in string 1 then replace string 2's instance of the char with an underscore.
Example:
This is the input:
phrase1 = "String 1"
phrase2 = "Strone 2"
The output string is called newPhrase and it will have the string built from the underscores:
newPhrase = "___one 2"
Its not working for me I am doing something wrong.
public class DashedPhrase
{
public static void main(String[] args)
{
dashedHelp("ABCDE","ABDC");
}
public static String dashedHelp(String phrase1, String phrase2)
{
String newPhrase = "_";
for(int i = 0; i < phrase.length(); i++)
{
if(phrase.charAt(i) == phrase2.charAt(i))
{
newPhrase.charAt(i) += phrase2.charAt(i);
}
}
System.out.print(newPhrase);
return newPhrase;
}
}

To make it easier for you to understand, you can use StringBuilder and its method setCharAt().
Notice the i < phrase1.length() && i < phrase2.length() in the condition for the for loop. This is to make sure you don't get any ArrayIndexOutOfBounds exception.
public static void main(String[] args)
{
System.out.println("ABCDE");
System.out.println("ABDC");
dashedHelp("ABCDE","ABDC");
System.out.println();
System.out.println();
System.out.println("String 1");
System.out.println("Strone 2");
String phrase1 = "String 1";
String phrase2 = "Strone 2";
dashedHelp(phrase1, phrase2);
}
public static String dashedHelp(String phrase1, String phrase2)
{
StringBuilder newPhrase = new StringBuilder(phrase1);
for(int i = 0; i < phrase1.length() && i < phrase2.length(); i++)
{
if(phrase1.charAt(i) == phrase2.charAt(i))
{
newPhrase.setCharAt(i, '_');
}
}
System.out.print(newPhrase);
return newPhrase.toString();
}
Output:
ABCDE
ABDC
__CDE
String 1
Strone 2
___i_g_1

newPhrase.charAt(i) doesn't let you replace a character, it just returns it. Java's Strings are immutable. I you want to change it you should use StringBuilder. Look into the replace(int start, int end, String str) method.

Since you need to return a string that has the same length as phrase2, you need to iterate over each character of phrase2, and replace the matching characters of both phrases. And, of course, if phrase2 is longer than phrase1, you need to include the remaining characters in the answer. You can try this:
public static String dashedHelp(String phrase1, String phrase2) {
String ans = "";
String subChar = "_";
int i;
for(i = 0; i<phrase2.length(); i++) {
if(i<phrase1.length() && phrase1.charAt(i) == phrase2.charAt(i))
ans += subChar;
else
ans += phrase2.charAt(i);
}
return ans;
}
Hope it helps
Of course, if you need to output phrase1 with underscores in the places where phrase2 has equal characters, you can interchange phrase2 with phrase1 in the above code.
Testing it
The complete class would look like this:
public class MyClass {
public static String dashedHelp(String phrase1, String phrase2) {
// The method code goes here
}
public static void main(String[] args) {
System.out.println(dashedHelp("String 1", "Strone 2"));
}
}
The output of this program is ___o_e_2. This matches (approximately) your desired output.

The code in the example won't even compile.
newPhrase.charAt(i) += phrase2.charAt(i);
That's a bad assignment. It's the same as writing
newPhrase.charAt(i) = newPhrase.charAt(i) + phrase2.charAt(i);
but the expression on the left side of the '=' isn't something to which you can properly assign a value.

Related

Is there a way to find out how many numbers are at the end of a string without knowing the exact index?

I have a method that extracts a certain substring from a string. This substring consists of the numbers in the string. Then this is parsed to an integer.
Method:
protected int startIndex() throws Exception {
String str = getWorkBook().getDefinedName("XYZ");
String sStr = str.substring(10,13);
return Integer.parseInt(sStr) - 1;
}
Example:
String :
'0 DB'!$B$460
subString :
460
Well, I manually entered the index range for the substring. But I would like to automate it.
My approach:
String str = getWorkBook().getDefinedName("XYZ");
int length = str.length();
String sStr = str.substring(length - 3, length);
This works well for this example.
Now there is the problem that the numbers at the end of the string can also be 4 or 5 digits. If that is the case, I naturally get a NullPointerException.
Is there a way or another approach to find out how many numbers are at the end of the string?
You can use the regex, (?<=\D)\d+$ which means one or more digits (i.e. \d+) from the end of the string, preceded by non-digits (i.e. \D).
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Test
System.out.println(getNumber("'0 DB'!$B$460"));
}
static String getNumber(String str) {
Matcher matcher = Pattern.compile("(?<=\\D)\\d+$").matcher(str);
if (matcher.find()) {
return matcher.group();
}
// If no match is found, return the string itself
return str;
}
}
In your case I would recommend to use regex with replaceAll like this:
String sStr = str.replaceAll(".*?([0-9]+)$", "$1");
This will extract the all the digits in the end or your String or any length.
Also I think you are missing the case when there are no digit in your String, for that I would recommend to check your string before you convert it to an Integer.
String sStr = str.replaceAll(".*?([0-9]+)$", "$1");
if (!sStr.isEmpty()) {
return Integer.parseInt(sStr) - 1;
}
return 0; // or any default value
If you just want to get the last number, you can go through the entire string on revert and get the start index:
protected static int startIndex() {
String str = getWorkBook().getDefinedName("XYZ");
if(Character.isDigit(str.charAt(str.length() - 1))) {
for(int i = str.length() - 1; i >= 0; i--){
if(!Character.isDigit(str.charAt(i)))
return i+1;
}
}
return -1;
}
and then print it:
public static void main(String[] args) {
int start = startIndex();
if(start != -1)
System.out.println(getWorkBook().getDefinedName("XYZ").substring(start));
else
System.out.println("No Number found");
}
You will have to add the
Simple and fast solution without RegEx:
public class Main
{
public static int getLastNumber(String str) {
int index = str.length() - 1;
while (index > 0 && Character.isDigit(str.charAt(index)))
index--;
return Integer.parseInt(str.substring(index + 1));
}
public static void main(String[] args) {
final String text = "'0 DB'!$B$460";
System.out.println(getLastNumber(text));
}
}
The output will be:
460
If I were going to do this I just search from the end. This is quite efficient. It returns -1 if no positive number is found. Other return options and the use of an OptionalInt could also be used.
String s = "'0 DB'!$B$460";
int i;
for (i = s.length(); i > 0 && Character.isDigit(s.charAt(i-1)); i--);
int vv = (i < s.length()) ? Integer.valueOf(s.substring(i)) : -1;
System.out.println(vv);
Prints
460
If you know that there will always be a number at the end you can forget the ternary (?:) above and just do the following:
int vv = Integer.valueOf(s.substring(i));

How do I replace more than one type of Character in Java String

newbie here. Any help with this problem would be appreciated:
You are given a String variable called data that contain letters and spaces only. Write the Java class to print a modified version of the String where all lowercase letters are replaced by ? and all whitespaces are replaced by +. An example is shown below: I Like Java becomes I+L???+J???.
What I have so far:
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
String data;
//prompt
System.out.println("Enter a sentence: ");
//input
data = input.nextLine();
for (int i = 0; i < data.length(); i++) {
if (Character.isWhitespace(data.charAt(i))) {
data.replace("", "+");
if (Character.isLowerCase(data.charAt(i))) {
data.replace(i, i++, ); //not sure what to include here
}
} else {
System.out.print(data);
}
}
}
any suggestions would be appreciated.
You can do it in two steps by chaining String#replaceAll. In the first step, replace the regex, [a-z], with ?. The regex, [a-z] means a character from a to z.
public class Main {
public static void main(String[] args) {
String str = "I Like Java";
str = str.replaceAll("[a-z]", "?").replaceAll("\\s+", "+");
System.out.println(str);
}
}
Output:
I+L???+J???
Alternatively, you can use a StringBuilder to build the desired string. Instead of using a StringBuilder variable, you can use String variable but I recommend you use StringBuilder for such cases. The logic of building the desired string is simple:
Loop through all characters of the string and check if the character is a lowercase letter. If yes, append ? to the StringBuilder instance else if the character is whitespace, append + to the StringBuilder instance else append the character to the StringBuilder instance as it is.
Demo:
public class Main {
public static void main(String[] args) {
String str = "I Like Java";
StringBuilder sb = new StringBuilder();
int len = str.length();
for (int i = 0; i < len; i++) {
char ch = str.charAt(i);
if (Character.isLowerCase(ch)) {
sb.append('?');
} else if (Character.isWhitespace(ch)) {
sb.append('+');
} else {
sb.append(ch);
}
}
// Assign the result to str
str = sb.toString();
// Display str
System.out.println(str);
}
}
Output:
I+L???+J???
If the requirement states:
The first character of each word is a letter (uppercase or lowercase) which needs to be left as it is.
Second character onwards can be any word character which needs to be replaced with ?.
All whitespace characters of the string need to be replaced with +.
you can do it as follows:
Like the earlier solution, chain String#replaceAll for two steps. In the first step, replace the regex, (?<=\p{L})\w, with ?. The regex, (?<=\p{L})\w means:
\w specifies a word character.
(?<=\p{L}) specifies a positive lookbeghind for a letter i.e. \p{L}.
In the second step, simply replace one or more whitespace characters i.e. \s+ with +.
Demo:
public class Main {
public static void main(String[] args) {
String str = "I like Java";
str = str.replaceAll("(?<=\\p{L})\\w", "?").replaceAll("\\s+", "+");
System.out.println(str);
}
}
Output:
I+l???+J???
Alternatively, again like the earlier solution you can use a StringBuilder to build the desired string. Loop through all characters of the string and check if the character is a letter. If yes, append it to the StringBuilder instance and then loop through the remaining characters until all characters are exhausted or a space character is encountered. If a whitespace character is encountered, append + to the StringBuilder instance else append ? to it.
Demo:
public class Main {
public static void main(String[] args) {
String str = "I like Java";
StringBuilder sb = new StringBuilder();
int len = str.length();
for (int i = 0; i < len; i++) {
char ch = str.charAt(i++);
if (Character.isLetter(ch)) {
sb.append(ch);
while (i < len && !Character.isWhitespace(ch = str.charAt(i))) {
sb.append('?');
i++;
}
if (Character.isWhitespace(ch)) {
sb.append('+');
}
}
}
// Assign the result to str
str = sb.toString();
// Display str
System.out.println(str);
}
}
Output:
I+l???+J???
package com.company;
import java.util.*;
public class dat {
public static void main(String[] args) {
System.out.println("enter the string:");
Scanner ss = new Scanner(System.in);
String data = ss.nextLine();
for (int i = 0; i < data.length(); i++) {
char ch = data.charAt(i);
if (Character.isWhitespace(ch))
System.out.print("+");
else if (Character.isLowerCase(ch))
System.out.print("?");
else
System.out.print(ch);
}
}
}
enter the string:
i Love YouU
?+L???+Y??U
Firstly, you are trying to make changes to String object which is immutable. Simple way to achieve what you want is convert string to character array and loop over array items:
Scanner input = new Scanner(System.in);
String data;
//prompt
System.out.println("Enter a sentence: ");
//input
data = input.nextLine();
char[] dataArray = data.toCharArray();
for (int i = 0; i < dataArray.length; i++) {
if (Character.isWhitespace(dataArray[i])) {
dataArray[i] = '+';
} else if (Character.isLowerCase(dataArray[i])) {
dataArray[i] = '?';
}
}
System.out.print(dataArray);
See the below code and figure out what's wrong in your code. To include multiple regex put the char within square brackets:
import java.util.Scanner;
public class mainClass {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a sentence: ");
String data = input.nextLine();
String one = data.replaceAll(" ", "+");
String two = one.replaceAll("[a-z]", "?");
System.out.println(two);
}
}
You can use String.codePoints method to get a stream over int values of characters of this string, and process them:
private static String replaceCharacters(String str) {
return str.codePoints()
.map(ch -> {
if (Character.isLowerCase(ch))
return '?';
if (Character.isWhitespace(ch))
return '+';
return ch;
})
.mapToObj(Character::toString)
.collect(Collectors.joining());
}
public static void main(String[] args) {
System.out.println(replaceCharacters("Lorem ipsum")); // L????+?????
System.out.println(replaceCharacters("I Like Java")); // I+L???+J???
}
See also: Replace non ASCII character from string

Concatenation of integers in string

I have a string as follows
String str = "AUTHOR01BOOK"
In this string I want to add this number 00001. How can I do that?
I tried concatenate it but the output I got is AUTHOR01BOOK1. My code is not appending zeros. How can I do that?
You can use the print format.
String str="AUTHOR01BOOK";
int num = 000001;
System.out.printf("%s%06d", str, num);
or use the String.format function to store it in a variable:
String myConcat = String.format("%s%05d", str, num);
EDIT:
To answer raju's follow up question about doing this in a loop,
Create a method that will return the formatted string:
static String myConcatWithLoop(String str, int iteration){
return String.format("%s%05d", str, iteration);
}
then call this in your loop:
for (int i = 1; i <= 100; i++) {
System.out.println(myConcatWithLoop(str, i));
}
if you store '000001' in int datatype it will treat as an octal. That is
int a=000001;
System.out.println(a);
Output: 1
It will treat it as OCTAL number
So you cannot store a number beginning with 0 in int as compiler will typecast it. Therefore for that you have to work with Strings only :)
Another approach is use StringBuilder
public class JavaApplication {
public static void main(String[] args) {
JavaApplication ex = new JavaApplication();
String str = "AUTHOR01BOOK";
System.out.println(ex.paddingZero(str));
}
public String paddingZero(String str) {
StringBuilder sb = new StringBuilder();
sb.append(str);
sb.append("00001");
return sb.toString();
}
}
Please try the below code. It not only displays but also changes the string.
StringUtils help us to pad the left zeros.
Number 4 in the leftPad method denotes the number of zeros.
Its not a dynamic solution but it fulfills your need.
import org.apache.commons.lang.StringUtils;
public class Interge {
public static void main(String[] args) {
int i =00001;
String s= i+"";
String result = StringUtils.leftPad(s, 4, "0");
String fnlReslt = "AUTHOR01BOOK"+result;
System.out.println("The String : " + fnlReslt);
}
}

Java String With Spaces

and thank you for helping me.
So my question is i need a code that asks you for a String like "1234 567" (input), then returns the string numbers like "1 2 3 4 5 6 7" (output) once more
my current code is:
public class StringComEspaços {
public static String formatNumberWithSpaces(String inputString) {
String outputString = "222";
return outputString;
}
public static void main(String[] args) {
System.out.println(formatNumberWithSpaces("123 222 2222"));
}
}
thanks for the help, and sorry for bad english :).
There are many possible ways to solve your problem.
You can do it in an OO way with StringBuilder:
public static String formatNumberWithSpaces(String inputString) {
StringBuilder output = new StringBuilder();
for (char c : inputString.toCharArray()) // Iterate over every char
if (c != ' ') // Get rid of spaces
output.append(c).append(' '); // Append the char and a space
return output.toString();
}
Which you can also do with a String instead of the StringBuilder by simply using the + operator instead of the .append() method.
Or you can do it a more "modern" way by using Java 8 features - which in my opinion is fun doing, but not the best way - e.g. like this:
public static String formatNumberWithSpaces(String inputString) {
return Arrays.stream(input.split("")) // Convert to stream of every char
.map(String::trim) // Convert spaces to empty strings
.filter(s -> !s.isEmpty()) // Remove empty strings
.reduce((l, r) -> l + " " + r) // build the new string with spaces between every character
.get(); // Get the actual string from the optional
}
Just try something that works for you.
Try out this function:
public static String formatNumberWithSpaces(String inputString){
String outputString = ""; //Declare an empty String
for (int i = 0;i < inputString.length(); i++){ //Iterate through the String passed as function argument
if (inputString.charAt(i) != ' '){ //Use the charAt function which returns the char representation of specified string index(i variable)
outputString+=inputString.charAt(i); //Same as 'outputString = outputString + inputString.charAt(i);'. So now we collect the char and append it to empty string
outputString+=' '; //We need to separate the next char using ' '
} //We do above instruction in loop till the end of string is reached
}
return outputString.substring(0, outputString.length()-1);
}
Just call it by:
System.out.println(formatNumberWithSpaces("123 222 2222"));
EDIT:
Or if you want to ask user for input, try:
Scanner in = new Scanner(System.in);
System.out.println("Give me your string to parse");
String input = in.nextLine(); //it moves the scanner position to the next line and returns the value as a string.
System.out.println(formatNumberWithSpaces(input)); // Here you print the returned value of formatNumberWithSpaces function
Don't forget to import, so you will be able to read user input :
import java.util.Scanner;
There are various ways to read input from the keyboard, the java.util.Scanner class is one of them.
EDIT2:
I changed:
return outputString;
..to: return outputString.substring(0, outputString.length()-1);
Just because outputString+=' '; was also appending empty space at the end of string, which is useless. Didn't add an if inside for loop which wouldn't add space when last char is parsed, just because of its low performance inside for loop.
use this code.
public class StringComEspaços {
public static void main(String[] args) {
System.out.println(formatNumberWithSpaces("123 222 2222"));
}
private static String formatNumberWithSpaces(String string) {
String lineWithoutSpaces = string.replaceAll("\\s+", "");
String[] s = lineWithoutSpaces.split("");
String os = "";
for (int i = 0; i < s.length; i++) {
os = os + s[i] + " ";
}
return os;
}
}

Decompressing String method

I need help with decompressing method. I have a working Compress method. Any suggestions as far as what I need to consider? Do I need parseInt or else....? Appreciate the advice. Here is what I have so far. If s = "ab3cca4bc", then it should return "abbbccaaaabc", for example of decompress.
class RunLengthCode {
private String pText, cText;
public RunLengthCode () {
pText = "";
cText = "";
}
public void setPText (String newPText) {
pText = newPText;
}
public void setCText (String newCText) {
cText = newCText;
}
public String getPText () {
return pText;
}
public String getCText () {
return cText;
}
public void compress () { // compresses pText to cText
String ans = "";
for (int i = 0; i < pText.length(); i++) {
char current = pText.charAt(i);
int cnt = 1;
String temp = "";
temp = temp + current;
while (i < pText.length() - 1 && (current == pText.charAt(i + 1))) {
cnt++;
i++;
temp = temp + current;
}
if (cnt > 2) {
ans = ans + current;
ans = ans + cnt;
}
else
ans = ans + temp;
setCText(ans);
}
}
public void decompress () {
}
}
public class {
public static void main(String [] args) {
Scanner in = new Scanner(System.in);
RunLengthCode myC = new RunLengthCode();
String pText, cText;
System.out.print("Enter a plain text consisting of only lower-case alphabets and spaces:");
pText = in.nextLine();
myC.setPText(pText);
myC.compress();
System.out.println(pText+" => "+myC.getCText());
System.out.print("Enter a compressed text consisting of only lower-case alphabets, spaces and digits:");
cText = in.nextLine();
myC.setCText(cText);
myC.decompress();
System.out.println(cText+" => "+myC.getPText());
}
}
You could create break the string into regx groups and combine them.
The following pattern works
(([A-Za-z]+[\d]*))
This will break your string "ab3cca4bc" into groups of
"ab3", "cca4", "bc"
So in a loop if the last character is a digit, you could multiply the character before it that many times.
Ok, so you've got an input string that looks like ab3cca4bc
1.) Loop over the length of the input String
2.) During each loop iteration, use the String.charAt(int) method to pick up the individual character
3.) The Character class has an isDigit(char) function that you can use to determine if a character is a number or not. You can then safely use Integer.parseInt(String) (you can use myChar+"" to convert a char into a String)
4.) If the char in question is a number, then you'll need to have an inner loop to repeat the previous character the correct number of times. How will you know what the last character was? Maybe have a variable that's instantiated outside the loop that you update each time you add a character on the end?

Categories