If I enter an equation like:
9+3*2/1
My output is:
[9,3,2,1]
[,+,*,/]
Why does my second array start off with a "," and how do I get rid of it so the output would be
[+,*,/]
String evaluate(String exp) {
String setExpression = expr.getText();
String[] numbers = setExpression.split("[*/+-]");
String[] ops = setExpression.split("[123456789]");
ArrayList <String> setNumbers = new ArrayList <String>();
ArrayList <String> setOps = new ArrayList <String>();
for(int i=0; i<numbers.length; i++){
setNumbers.add(numbers[i]);
}
for(int i=0; i<numbers.length; i++){
setOps.add(ops[i]);
}
System.out.println(setNumbers);
System.out.println(setOps);
return exp;
}
}
An example similar to yours:
public class DemoSplit {
public static void main(String[] args) {
String s = ",1,2,";
String su[] = s.split(",");
for (String st: su) System.out.println("'"+st+"'");
}
}
Will print:
''
'1'
'2'
The first char is a delimiter, so split there and the element before it is the first element of th esplitted array.
In your case you spliut on numbers:
9+3*2/1
before 9, empty element, after '+' ...
If you feel like looking at the code, String.split calls java.util.regex.Pattern.split
In the split method, you will see that adds to an ArrayList the subStrings between index and the match, since index is zero for the first iteration and the first match in the example is at zero, the first element is an empty string. From the source code of the split method:
ArrayList<String> matchList = new ArrayList<String>();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - 1) {
String match = input.subSequence(index, m.start()).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index,
input.length()).toString();
matchList.add(match);
index = m.end();
}
}
The extra empty string is what comes before 9 in your split. You're telling it to split on digits - there'll clearly be an extra empty string at the beginning and at the end.
The only reason why you don't see an extra empty string at the end is that when you copy the split to the ArrayList, you stop at numbers.length.
You will also have extra empty strings in here if you have numbers with more than one digit.
You can change the start of the second for loop so i = 1. The first element in ops is an empty string because of the way you split it.
Related
I'm trying to create a method that returns the last word in a string but I am having some trouble writing it.
I am trying to do it by finding the last blank space in the string and using a substring to find the word. This is what I have so far:
String strSpace=" ";
int Temp; //the index of the last space
for(int i=str.length()-1; i>0; i--){
if(strSpace.indexOf(str.charAt(i))>=0){
//some code in between that I not sure how to write
}
}
}
I am just beginning in Java so I don't know many of the complicated parts of the language. It would be much appreciated if someone could help me find a simple way to solve this problem. Thanks!
You can do this:
String[] words = originalStr.split(" "); // uses an array
String lastWord = words[words.length - 1];
and you've got your last word.
You are splitting the original string at every space and storing the substrings in an array using the String#split method.
Once you have the array, you are retrieving the last element by taking the value at the last array index (found by taking array length and subtracting 1, since array indices begin at 0).
String str = "Code Wines";
String lastWord = str.substring(str.lastIndexOf(" ")+1);
System.out.print(lastWord);
Output:
Wines
String#lastIndexOf and String#substring are your friends here.
chars in Java can be directly converted to ints, which we'll use to find the last space. Then we'll simply substring from there.
String phrase = "The last word of this sentence is stackoverflow";
System.out.println(phrase.substring(phrase.lastIndexOf(' ')));
This prints the space character itself too. To get rid of that, we just increment the index at which we substring by one.
String phrase = "The last word of this sentence is stackoverflow";
System.out.println(phrase.substring(1 + phrase.lastIndexOf(' ')));
If you don't want to use String#lastIndexOf, you can loop through the string and substring it at every space until you don't have any left.
String phrase = "The last word of this sentence is stackoverflow";
String subPhrase = phrase;
while(true) {
String temp = subPhrase.substring(1 + subPhrase.indexOf(" "));
if(temp.equals(subPhrase)) {
break;
} else {
subPhrase = temp;
}
}
System.out.println(subPhrase);
You can use: (if you are not familiar with arrays or unusual methods)
public static String lastWord(String a) // only use static if it's in the
main class
{
String lastWord = "";
// below is a new String which is the String without spaces at the ends
String x = a.trim();
for (int i=0; i< x.length(); i++)
{
if (x.charAt(i)==' ')
lastWord = x.substring(i);
}
return lastWord;
}
you just need to traverse the input string from tail when first find blank char stop traverse work and return the word.a simple code like this:
public static String lastWord(String inputs) {
boolean beforWords = false;
StringBuilder sb = new StringBuilder();
for (int i = inputs.length() - 1; i >= 0; i--) {
if (inputs.charAt(i) != ' ') {
sb.append(inputs.charAt(i));
beforWords = true;
} else if (beforWords){
break;
}
}
return sb.reverse().toString();
}
You could try:
System.out.println("Last word of the sentence is : " + string.substring (string.lastIndexOf (' '), string.length()));
I have been spending hours trying to work through the logic of finding a palindrome within this context. So we are given an arraylist of strings that are single words and we need to find the biggest palindromes from the list of words. As an example ["mr", "owl", "ate", "my", "metal", "worm", "racecar", "mad", "am"] would construct an araylist with the following result ["mrowlatemymetalworm", "racecar", "madam"]. So far I have been playing around with the iterations but can't seem to get the correct logic of how to iterate from both ends, especially when it comes to switching inner strings indexes from the other end... Here is what I have so far.
List<String> list = Arrays.asList("mr", "owl", "ate", "my", "metal", "worm", "racecar", "mad", "am");
List<String> palindromeList = new ArrayList<String>();
int i = 0;
int j = list.get(i).length();
int l = list.size()-1;
int s = list.get(l).length() -1;
while (i<j){
while (j<list.get(i).length()){
if (s == 0){
//need to reinitialize s for previous index of back end of list for possible palindrome
}
if (list.get(l).charAt(s) == list.get(i).charAt(j)){
l--;
}
else if (list.get(l).charAt(s) != list.get(i).charAt(j)){
j++;
s--;
}
}
}
//once outer loop breaks the result should be added to palindromeList
You can verify if string is a palindrome by comparaing if it's equal with itself reversed (that's exact definition):
public static boolean isPalindrome(String value) {
if (value == null || value.isEmpty())
return false;
return new StringBuilder(value).reverse().toString().equals(value);
}
I'm not sure if I understood the logic you want to apply, but based on the input and output you gave I came up with something like this:
List<String> list = Arrays.asList("mr", "owl", "ate", "my", "metal", "worm", "racecar", "mad", "am");
List<String> palindromeList = new ArrayList<String>();
for (int i = 0; i < list.size(); ++i) {
String longestPalindrome = null;
String candidate = "";
for (int j = i; j < list.size(); ++j) {
candidate += list.get(j);
if (isPalindrome(candidate))
longestPalindrome = candidate;
}
if (longestPalindrome != null)
palindromeList.add(longestPalindrome);
}
To detect if a string is a palindrome, I split the string in half, reverse the string and see if both sides equal each other.
There are 2 scenarios:
Word has even number of characters:
If the string is of odd length, we split the string into 2 substrings excluding the middle character: Ex: ABCBA would be broken into AB and BA. We then reverse the string and compare to see if they equal each other.
Word has odd number of characters:
If the string is of even length, we just split the string into 2 equal size substrings and reverse one of them then compare to see if they are the same string. Ex: Hannah would be Han and nah.
List<String> list = Arrays.asList("mr", "owl", "ate", "my", "metal", "worm", "racecar", "mad", "am");
List<String> palindromeList = new ArrayList<String>();
//Detects if a string is a palindrome.
for (int i = 0; i < list.size(); i ++) {List<String> palindromeList = new ArrayList<String>();
int wordLength = list.get(i);
String leftSide = "";
String rightSide ="";
if (wordLength%2 == 1) { //If word has odd number of characters.
leftSide = list.get(i).subString(0,wordLength/2);
rightSide = list.get(i).subString((wordLength/2) + 1, wordLength);
} else { //If word has even number of characters.
leftSide = list.get(i).subString(0,(wordLength/2));
rightSide = list.get(i).subString((wordLength/2), wordLength);
}
String reversedLeftSide = new StringBuilder(leftSide).reverse().toString();
if (reversedLeftSide.equals(rightSide)) {
palindromeList.add(list.get(i));
}
}
String longestPalindrome = "";
//Searches for longest palindrome in the list of palindromes.
for (int i = 0; i < palindromeList.size(); i++) {
if (palindromeList.get(i).length() > longestPalindrome.length()) {
longestPalindrome = palindromeList.get(i);
}
}
System.out.println(longestPalindrome); //This should give you longest palindrome.
Keep in mind there are probably a dozen ways to solve this problem and I've just proposed one solution. This code might also contain 1 or 2 minor bugs as it has not been tested.
It's important to know whether words can be repeated or not. If they can, then you could have "racecarracecar", "racecarracecarracecar", etc., so I assume they can't. In that case we can proceed as follows. Walk through the list of words, starting with "mr". If the palindrome begins with "mr" it must end with "m". Does "am" work? No. Try other possibilities; "worm" works. Then an "o" must follow "mr". The next word at the beginning must be "owl". That means the next word at the end must end with "l" so must be "metal".
Etc., until you 1) run out of words, 2) have a palindrome, or 3) have a palindrome like "doggod" where word boundaries are exactly in the middle, in which case you can (recursively) search for more palindromes with the remaining words and put anything you get in the middle, like "dogracecargod" or "dogmadamgod" or "dogmrowlatemymetalwormgod".
I have a String ArrayList consisting alphabets followed by a digit as a suffix to each of the alphabet.
ArrayList <String> baseOctave = new ArrayList();
baseOctave.add("S1");
baseOctave.add("R2");
baseOctave.add("G4");
baseOctave.add("M2");
baseOctave.add("P3");
baseOctave.add("D1");
baseOctave.add("N1");
I pass the strings from this baseOctave and few other characters as input pattern for creating an object.
MyClass obj1 = new MyClass ("S1,,R2.,M2''-");
Since I frequently make use of these kind of input patterns during object instantiation, I would like to use simple characters S, R, G, M etc.
Ex:
MyClass obj1 = new MyClass ("S,,R.,M''-");
MyClass obj2 = new MyClass ("S1,G.,M,D1");
So the alphabets used during object creation may contain digits as suffix or it may not have digit as suffix.
But inside the constructor (or in separate method), I would like to replace these simple alphabets with alphabets having suffix. The suffix is taken from the baseOctave.
Ex: above two strings in obj1 and obj2 should be "S1,,R2.,M2''-" and "S1,G4.,M2,D1"
I tied to do this, but could not continue the code below. Need some help for replacing please..
static void addSwaraSuffix(ArrayList<String> pattern) {
for (int index = 0; index < pattern.size(); index++) {
// Get the patterns one by one from the arrayList and verify and manipulate if necessary.
String str = pattern.get(index);
// First see if the second character in Array List element is digit or not.
// If digit, nothing should be done.
//If not, replace/insert the corresponding index from master list
if (Character.isDigit(str.charAt(1)) != true) {
// Replace from baseOctave.
str = str.replace(str.charAt(0), ?); // replace with appropriate alphabet having suffix from baseOctave.
// Finally put the str back to arrayList.
pattern.set(index, str);
}
}
}
Edited information is below:
Thanks for the answer. I found another solution and works fine. below is the complete code that I found working. Let me know if there is any issue.
static void addSwaraSuffix(ArrayList<String> inputPattern, ArrayList<String> baseOctave) {
String temp = "";
String str;
for (int index = 0; index < inputPattern.size(); index++) {
str = inputPattern.get(index);
// First see if the second character in Array List is digit or not.
// If digit, nothing should be done. If not, replace/insert the corresponding index from master list
// Sometimes only one swara might be there. Ex: S,R,G,M,P,D,N
if (((str.length() == 1)) || (Character.isDigit(str.charAt(1)) != true)) {
// Append with index.
// first find the corresponsing element to be replaced from baseOctave.
for (int index2 = 0; index2 < baseOctave.size(); index2++) {
if (baseOctave.get(index2).startsWith(Character.toString(str.charAt(0)))) {
temp = baseOctave.get(index2);
break;
}
}
str = str.replace(Character.toString(str.charAt(0)), temp);
}
inputPattern.set(index, str);
}
}
I assume that abbreviation is only one character and that in full pattern second character is always digit. Code below relies on this assumptions, so please inform me if they are wrong.
static String replace(String string, Collection<String> patterns) {
Map<Character, String> replacements = new HashMap<Character, String>(patterns.size());
for (String pattern : patterns) {
replacements.put(pattern.charAt(0), pattern);
}
StringBuilder result = new StringBuilder();
for (int i = 0; i < string.length(); i++) {
Character c = string.charAt(i);
char next = i < string.length() - 1 ? string.charAt(i + 1) : ' ';
String replacement = replacements.get(c);
if (replacement != null && (next <= '0' || next >= '9')) {
result.append(replacement);
} else {
result.append(c);
}
}
return result.toString();
}
public static void main(String[] args) {
ArrayList<String> baseOctave = new ArrayList<String>();
baseOctave.add("S1");
baseOctave.add("R2");
baseOctave.add("G4");
baseOctave.add("M2");
baseOctave.add("P3");
baseOctave.add("D1");
baseOctave.add("N1");
System.out.println(replace("S,,R.,M''-", baseOctave));
System.out.println(replace("S1,G.,M,D1", baseOctave));
System.out.println(replace("", baseOctave));
System.out.println(replace("S", baseOctave));
}
Results:
S1,,R2.,M2''-
S1,G4.,M2,D1
S1
I am trying to find what array index position contains part of a string.
FullDirPrt = "a1a" "b2b" "c3c"
String doT ="b2";
int DotPos = Arrays.asList(FullDirPrt).indexOf(doT);
If I search for b2b it returns indexOf. If I search for only b2, it returns -1.
You have to check each item in the array individually, as each array item is a separate string:
String[] full = { "a1a", "b2b", "c3c" };
String doT = "b2";
for(int i = 0; i < full.length; i++) {
if(full[i].contains(doT)) {
System.out.println("Found item at index " + i);
}
}
You are matching on the entire string, you are going to have to loop through the whole list or array, and then check each indexOf on each of those strings.
for (String s : FullDirPrt) {
if (s.indexOf("bs") > 0) {
// do something
}
}
With Simple String array without using List also you can do like below.
String[] full={"a1a", "b2b", "c3c"};
String doT = "b2";
for(String str:full){
if(str.contains(doT)){
System.out.println(str+" contains "+doT);
}
}
Having problems trying to show every combination of a character of array without repeating letters.
public static String[] getAllLists(String[] elements, int lengthOfList)
{
//initialize our returned list with the number of elements calculated above
String[] allLists = new String[(int)Math.pow(elements.length, lengthOfList)];
//lists of length 1 are just the original elements
if(lengthOfList == 1) return elements;
else
{
//the recursion--get all lists of length 3, length 2, all the way up to 1
String[] allSublists = getAllLists(elements, lengthOfList - 1);
//append the sublists to each element
int arrayIndex = 0;
for(int i = 0; i < elements.length; i++)
{
for(int j = 0; j < allSublists.length; j++)
{
//add the newly appended combination to the list
allLists[arrayIndex] = elements[i] + allSublists[j];
arrayIndex++;
}
}
return allLists;
}
}
The above code works perfect but use's each letter more than once which cant be done in this case.
And i am stuck how to do this now.
Here's an example implementation. Essentially it takes a String and iterates over every character, putting that character at the front. It then recurses on the remaining characters. That structure removes your issue of repeated letters, because the input to the recursion has removed the character you've already used.
I also stored results in a set to remove semantic equivalences. The input 'aab' can switch char 0 and char 1 but still be 'aab.' I used a TreeSet to preserve ordering for easier verification of the output, but HashSet would be faster.
public static Set<String> permute(String chars)
{
// Use sets to eliminate semantic duplicates (aab is still aab even if you switch the two 'a's)
// Switch to HashSet for better performance
Set<String> set = new TreeSet<String>();
// Termination condition: only 1 permutation for a string of length 1
if (chars.length() == 1)
{
set.add(chars);
}
else
{
// Give each character a chance to be the first in the permuted string
for (int i=0; i<chars.length(); i++)
{
// Remove the character at index i from the string
String pre = chars.substring(0, i);
String post = chars.substring(i+1);
String remaining = pre+post;
// Recurse to find all the permutations of the remaining chars
for (String permutation : permute(remaining))
{
// Concatenate the first character with the permutations of the remaining chars
set.add(chars.charAt(i) + permutation);
}
}
}
return set;
}
Example run:
public static void main(String[] args)
{
for (String s : CharPermuter.permute("abca"))
{
System.out.println(s);
}
}
Generates:
aabc
aacb
abac
abca
acab
acba
baac
baca
bcaa
caab
caba
cbaa