I have string H2SO4 for example, how can i parse to int 4 after O? I can't use substring(4), because user can type for example NH3PO4 and there 4 is substring(5), so how can I parse any character that is exactly after O?
Thanks for help.
Your question is not clear, but this may work for your case.
String str="NH3PO4";
int lastChar=str.lastIndexOf("O");//replace "O" into a param if needed
String toParse=str.substring(lastChar+1);
System.out.println("toParse="+toParse);
try{
System.out.println("after parse, " +Integer.parseInt(toParse));
}
catch (NumberFormatException ex){
System.out.println(toParse +" can not be parsed to int");
}
}
I think you need to split your String to char array' and then search the 'o' in that array:
String str = "H2SO4";
char[] charArray = str.toCharArray();
Then you got : [H, 2, S, O, 4], and you can search the "O" in this array.
Hope it helped!
There are multiple ways, all of them very simple and taken from Official documentation on String.
//Find character index of O, and parse next character as int:
int index = str.indexOf("O");
Integer.parseInt(str.subString(index, index+1));
//loop trough char array and check each char
char[] arr = str.toCharArray();
for(char ch : arr){
if(isNumber(ch){..}
}
boolean isNumber(char ch){
//read below
}
refer to ascii table and here
you can use regular expression.
.*O([0-9]+).*
And use group to extract the number proceeding character O.
Find out more here:
http://docs.oracle.com/javase/tutorial/essential/regex/groups.html
final int numAfterO;
final String strNum;
final int oIndex = chemicalName.lastIndexOf("O");
if (oIndex >= 0 && chemicalName.length() >= oIndex + 2) {
strNum = chemicalName.subString(oIndex, oIndex + 1);
} else {
strNum = null;
}
if (strNum != null) {
try {
numAfterO = Integer.parseInt(strNum);
} catch (NumberFormatException e) {
numAfter0 = -1;
}
}
android.util.Log.d("MYAPP", "The number after the last O is " + numberAfterO);
I assume this is what you want.
In order to parse every character after exactly O you can use the follow code:
char [] lettersArray = source.toCharArray();
for(int i =0 ;i<lettersArray.length;i++){
if(Character.isLetter(lettersArray[i])){
if(lettersArray[i]=='O'){
try{
int a = Interger.parseInteger(lettersArray[i].toString());
}catch(Exception e){
e.printStackTrace();
}
}
}
}
Convert the String to a char array:
String molecule = "H2SO4 ";
char[] moleculeArray = str.toCharArray();
for(int i = 0; i < moleculeArray.length; i++){
if(Character.isLetter(moleculeArray[i])){
//Huston we have a character!
if(i+1 < moleculeArray.length && Character.isDigit(moleculeArray[i+1]) {
int digit = Character.getNumericValue(Character.isDigit(moleculeArray[i+1]);
//It has a digit do something extra!
}
}
}
then iterate over the array and use Character.isDigit(c) and Character.isLetter(c)
Here's something that parses an entire molecule structure. This one parses integers > 9 as well.
public static class Molecule {
private List<MoleculePart> parts = new ArrayList<MoleculePart>();
public Molecule(String s) {
String name = "";
String amount = "";
for (char c : s.toCharArray()) {
if (inBetween(c, 'A', 'Z')) {
if (!name.isEmpty()) // first iteration, the name is still empty. gotta omit.
save(name, amount);
name = "";
amount = "";
name += c; //add it to the temporary name
}
else if (inBetween(c, 'a', 'z'))
name += c; //if it's a lowercase letter, add it to the temporary name
else if (inBetween(c, '0', '9'))
amount += c;
}
save(name, amount);
}
public String toString() {
String s = "";
for (MoleculePart part : parts)
s += part.toString();
return s;
}
//add part to molecule structure after some parsing
private void save(String tmpMoleculename, String amount) {
MoleculePart part = new MoleculePart();
part.amount = amount.isEmpty() ? 1 : Integer.parseInt(amount);
part.element = Element.valueOf(tmpMoleculename);
parts.add(part);
}
private static boolean inBetween(char c, char start, char end) {
return (c >= start && c <= end);
}
}
public static class MoleculePart {
public Element element;
public int amount;
public String toString() {
return element.name() + (amount > 1 ? amount : "");
}
}
public static enum Element {
O, S, H, C, Se, Ni //add as many as you like
}
public static void main(String[] args) {
System.out.println(new Molecule("Ni84OH43Se"));
}
Related
I have a string s to which I want to append another string s1 at the specified position.
String s = "17.4755,2.0585,23.6489,12.0045";
String s1=",,,,"
Now I want to add the string s1 after the n-th occurrence of "," character.
I have just started learning Java.
You can use the following method:
public String insert(int n, String original, String other) {
int index = original.indexOf(',');
while(--n > 0 && index != -1) {
index = original.indexOf(',', index + 1);
}
if(index == -1) {
return original;
} else {
return original.substring(0, index) + other + original.substring(index);
}
}
Working with Strings directly is not worth the trouble.
One easy way would be to turn your String into a List and manipulate that.
public void test() {
String s = "17.4755,2.0585,23.6489,12.0045";
// Split s into parts.
String[] parts = s.split(",");
// Convert it to a list so we can insert.
List<String> list = new ArrayList<>(Arrays.asList(parts));
// Inset 3 blank fields at position 2.
for (int i = 0; i < 3; i++) {
list.add(2,"");
}
// Create my new string.
String changed = list.stream().collect(Collectors.joining(","));
System.out.println(changed);
}
Prints:
17.4755,2.0585,,,,23.6489,12.0045
I think this is what you want
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s = "17.4755,2.0585,23.6489,12.0045";
String s1=",,,,";
System.out.println("Enter Nth Occurrence");
try {
int n = scanner.nextInt();
long totalOccurrence = 0;
if (n != 0) {
totalOccurrence = s.chars().filter(num -> num == ',').count();
if (totalOccurrence < n) {
System.out.println("String s have only " + totalOccurrence + " symbol \",\"");
} else {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == ',') {
count++;
if (count == n) {
String resultString = s.substring(0, i) + s1 + s.substring(i, s.length());
System.out.println(resultString);
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wrong input");
}
}
}
Output :
1. Enter Nth Occurrence
5
String s have only 3 symbol ","
2. Enter Nth Occurrence
2
17.4755,2.0585,,,,,23.6489,12.0045
I have a question about a programming problem from the book Cracking The Code Interview by Gayl Laakmann McDowell, 5th Edition.
I'm not sure what is wrong with my answer? It varies a lot from the answer given in the book.
public String replace(String str){
String[] words = str.split(" ");
StringBuffer sentence = new StringBuffer();
for(String w: words){
sentence.append("%20");
sentence.append(w);
}
return sentence.toString();
}
Question in the book says:
Note: if implementing in Java, please use a character array so that
you can perform this operation in place.
It also says that the char array that you get as input is long enough to hold the modified string.
By using split and StringBuffer you use additional O(n) space. That's why your answer varies a lot and is incorrect (apart from adding additional "%20").
In this loop, the program adds %20 before each word:
for(String w: words){
sentence.append("%20");
sentence.append(w);
}
That will produce incorrect results, for example for a b it will give %20a%20b.
There's a much simpler solution:
public String replace(String str) {
return str.replaceAll(" ", "%20");
}
Or, if you really don't want to use .replaceAll, then write like this:
public String replace(String str) {
String[] words = str.split(" ");
StringBuilder sentence = new StringBuilder(words[0]);
for (int i = 1; i < words.length; ++i) {
sentence.append("%20");
sentence.append(words[i]);
}
return sentence.toString();
}
You can also do the following, which replaces any space
String s = "Hello this is a string!";
System.out.println(replaceSpace(s, "%20"));
public static String replaceSpace(String s, String replacement) {
String ret = s.replaceAll(" *", replacement);
return ret;
}
Gives
Hello%20this%20is%20a%20string!
One of the simplest way:
public void replaceAll( String str )
{
String temp = str.trim();
char[] arr = temp.toCharArray();
StringBuffer sb = new StringBuffer();
for( int i = 0; i < arr.length; i++ )
{
if( arr[i] == ' ' )
{
sb.append( "%20" );
}
else
{
sb.append( arr[i] );
}
}
}
private static String applyReplaceOperationWithCount(String str) {
if (StringUtils.isEmpty(str)) { //if string is null or empty, return it
return str;
}
char[] strChar = str.toCharArray();
int count = 0; //count spaces in the string to recalculate the array length
for (char c : strChar) {
if (c == ' ') {
count++;
}
}
if (count == 0) { // if there are no spaces in the string, return it
return str;
}
int length = strChar.length;
char[] newChar = new char[length + (count * 2)]; // 1 char will be replaced by 3 chars. So the new length should be count*2 larger than original
int index = 0;
for (char c : strChar) {
if (c != ' ') { // if char is not a space just push it in the next available location
newChar[index++] = c;
} else { // if char is a space just push %,2,0
newChar[index++] = '%';
newChar[index++] = '2';
newChar[index++] = '0';
}
}
return new String(newChar); // convert the new array into string
}
I am using matches and replaceAll it works well.
public class ReplaceSpaces {
public static void main(String[] args) {
String text = " Abcd olmp thv ";
if(text.matches(".*\\s+.*")){
System.out.println("Yes I see white space and I am replacing it");
String newText = text.replaceAll("\\s+", "%20");
System.out.println(newText);
}
else{
System.out.println("Nope I dont see white spaces");
}
}
}
Output
Yes I see white space and I am replacing it
%20Abcd%20olmp%20thv%20
public static String replaceSpaceInString(String string,String toreplace){
String replacedString = "";
if(string.isEmpty()) return string;
string = string.trim();
if(string.indexOf(" ") == -1)return string;
else{
replacedString = string.replaceAll("\\s+",toreplace);
}
return replacedString;
}
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?
I need to replace a repeated char with $% followed by the char followed by $%.
e.g. "HELLO" will become "HE$%L$%O"
The following code that I wrote gives "HE$%L$%LO".
Please guide
int index=0;
String str1="";
String str2="";
String str4="";
String str5="";
for(int i=0;i<str.length();i++) {
char ch=str.charAt(i);
index=str.indexOf(ch);
if(index!=i) {
str4="$%"+str.charAt(index)+ "$%";
str1=str.charAt(index)+str5;
str2=str.replaceFirst(str1,str4);
}
}
return str2;
It looks like there's code missing because i can't see the duplicate character check, but what you want to do is go through str5 before you concat it and strip off all of the duplicate characters that are at the beginning. Then concat to your String.
Here a solution: Id solves the case if duplicates are more than 2 too. So remove all duplicates:
public class Converter {
public static void main(String[] args) {
final String result = replace("HELLO");
System.out.println("result = " + result);
}
private static String replace(String data) {
final StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < data.length();) {
int j = i + 1;
while (j < data.length() && data.charAt(i) == data.charAt(j)) {
j++;
}
if(j > i + 1) { // exist duplicate
stringBuilder.append("$%").append(data.charAt(i)).append("$%");
} else {
stringBuilder.append(data.charAt(i));
}
i = j;
}
return stringBuilder.toString();
}
}
And the result is:
result = HE$%L$%O
I have this
public class Mapper implements ScramblerIF
{
private static String map = "drsjckpwrypwsftylmzxopqtdo";
public static String charAt(String str)
{
//char[] chars = str.toCharArray();
int length = str.length();
for(int i=0; i<length; i++)
{
char aChar = str.charAt(i);
char upper = Character.toUpperCase(aChar);
int num = (upper - 'A');
char mChar = map.charAt(num);
//String chard = Character.toString(mChar);
StringBuffer buf = new StringBuffer( str);
buf.setCharAt( i, mChar );
}
return str;
}
public String scramble(String str) {
return charAt(str);
}
}
I am trying to get it to where the method
public String scramble(String str) {
return charAt(str);
}
returns the computed value from the
public static String charAt(String str)
method. Don't know where i went wrong.
Also instead of using
StringBuffer buf = new StringBuffer( str);
buf.setCharAt( i, mChar );
how would i be able to use the swap function?
When I try
char temp = chars[i];
chars[i] = chars[mChar];
chars[mChar] = temp;
I am given an ArrayIndexOutOfBoundsException.
Summary of what i am trying to do is "For each character in the original string, use its position in the alphabet to look up its replacement in the map string. For example, the string “dog” would be translated to “jtp”."
This scrables with the replacement-map you have provided. It also handles upper and lower case letters:
public class Mapper {
// abcdefghijklmnopqrstuvwxyz
private static String map = "drsjckpwrypwsftylmzxopqtdo";
public static String scramble(String str) {
if (!str.matches("[A-Za-z]*"))
throw new RuntimeException(str + " contains weird characters");
String out = "";
for (char c : str.toCharArray()) {
if (Character.isUpperCase(c)) {
out += Character.toUpperCase(map.charAt(c - 'A'));
} else {
out += map.charAt(c - 'a');
}
}
return out;
}
public static void main(String[] args) {
System.out.println(scramble("David"));
}
}
StringBuffer.setCharAt() will throw an exception if you try to set a character beyond the buffer. You haven't put anything in the buffer.
In addition, take a look at when you are creating the buffer.