String Manipulation Comparison [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
EDITED
I have this kind of string
"A-B-C-D"
"B-C-A"
"D-A"
"B-A-D"
"D-A-B-C"
Now my problem is if the user input has a value of "A-C" or "C-A" the numbers 1,2,5 will be my output because the those numbers has a value "A-C" if for example the user has a input value of either of this three "A-B-D","B-A-D","A-D-B" the the output will be 1,4,5. hope it clears the question
Note:
the search sequence depends on user input and i want it to be more efficient because I have 10 thousand of data I don't want to use as much loop as possible.

This might change based on you needs to have the String in the exact pattern you have it or not, but REALLY simply...
public class Simple {
public static void main(String[] args) {
System.out.println("1. " + matches("A-B-C-D"));
System.out.println("2. " + matches("B-C-A"));
System.out.println("3. " + matches("D-A"));
System.out.println("4. " + matches("B-A-D"));
System.out.println("5. " + matches("D-A-B-C"));
}
public static boolean matches(String value) {
return value.contains("A") && value.contains("C");
}
}
Which outputs
1. true
2. true
3. false
4. false
5. true
Extended example using variable matchers
So, the basic idea is to provide some kind of list of values to be matched against. This example simply uses a String varargs (or String array), but it wouldn't be hard to make it use something like List
public class Simple {
public static void main(String[] args) {
String[] match = new String[]{"A", "D", "C"};
System.out.println("1. " + matches("A-B-C-D", match));
System.out.println("2. " + matches("B-C-A", match));
System.out.println("3. " + matches("D-A", match));
System.out.println("4. " + matches("B-A-D", match));
System.out.println("5. " + matches("D-A-B-C", match));
}
public static boolean matches(String value, String... matches) {
boolean doesMatch = true;
for (String match : matches) {
if (!value.contains(match)) {
doesMatch = false;
break;
}
}
return doesMatch;
}
}
This outputs...
1. true
2. false
3. false
4. false
5. true

Use an array and go through each index and see if it contains "C-A" or "A-C" then if it does print the number.
String stringArray[] = {"A-B-C-D", "B-C-A", "D-A", "B-A-D", "D-A-B-C"};
for(int i = 0; i < stringArray.length; i++) {
String pattern = ".*C-.*A.*";
String pattern2 = ".*A-.*C.*";
if(stringArray[i].matches(pattern) || stringArray[i].matches(pattern2))
System.out.println(i + 1);
}

Edit: This applies to an older version of the OP that was unclear about finding the sequence in order; and so this searches for sequences in order, which isn't correct now.
There are many options. Below I outline one approach that tokenizes the strings first, and another that uses a simple regex generated from the input string.
Approach 1: Parsing Strings
Start by parsing each String into an array of substrings, that will make this all easier to work with. You may want to parse each of the strings when you originally read them instead of every time you need to:
String myString = "A-B-C-D";
String[] sequence = myString.split("-");
Next, consider using an List<String> instead of a String[], because it will make the rest of this a bit easier (you'll see). So, instead of the above:
String myString = "A-B-C-D";
List<String> sequence = Arrays.asList(myString.split("-"));
Now the problem becomes checking if two of these arrays match:
public static boolean containsSequence (List<String> searchIn, List<String> searchFor) {
}
You need to check both directions, but you can simply reverse the array and reduce this problem further to just checking the forward direction (there are certainly ways to do this and avoid the copy but they can get complicated and it's only worth it if you have high performance requirements):
public static boolean containsSequence (List<String> searchIn, List<String> searchFor) {
// first check forward
if (containsSequenceForward(searchIn, searchFor))
return true;
// now check in reverse
List<String> reversedSearchFor = new ArrayList<String>(searchFor);
Collections.reverse(reversedSearchFor);
return containsSequenceForward(searchIn, reversedSearchFor);
}
public static boolean containsSequenceForward (List<String> searchIn, List<String> searchFor) {
}
// usage example:
public static void example () {
List<String> searchIn = Arrays.asList("D-A-B-C".split("-"));
List<String> searchFor = Arrays.asList("A-C".split("-"));
boolean contained = containsSequence(searchIn, searchFor);
}
Now you just need to implement containsSequenceForward. I'd like you to do this yourself, but I will provide an algorithm as a hint:
Start at the beginning of searchIn and searchFor.
Go through searchIn one element at a time.
When you find the current element of searchFor in searchIn, advance searchFor to next element.
If you hit the end of searchFor you've found the sequence.
If you hit the end of searchIn but not searchFor, then the sequence doesn't match.
Now you have the ability to check if one sequence contains another in any order. To apply it to your entire collection, I recommend preparsing all of the strings into a List<String> once at the start, then you can go through each of those using the above algorithm.
There are many alternative options. For example, you could use indexOf on searchIn to find the each element in searchFor and make sure the indices are in increasing order.
Approach 2: Regular Expressions
Another option here is to use a regular expression to find the search sequence in the source string. You can build the regular expression dynamically from the search sequence quite easily:
String searchIn = "D-C-B-A";
String searchFor = "C-A";
String searchForPattern = searchFor.replace("-", ".*"); // yields "C.*A"
if (searchIn.matches(".*" + searchForPattern + ".*"))
/* then it matches forwards */;
Then to match in reverse, if the forward match fails, you can just reverse searchFor and repeat:
String searchForReverse = new StringBuilder(searchFor).reverse().toString();
String searchForReversePattern = searchForReverse.replace("-", ".*"); // yields "A.*C"
if (searchIn.matches(".*" + searchForReversePattern + ".*"))
/* then it matches backwards */;
Note that this particular regex solution assumes that each element is only one character long.
Also both of the above approaches assume case-sensitive matches -- to make the first case-insensitive I would just convert the strings to lowercase before parsing. For the second you can use a case-insensitive regex.
Hope that helps. Work it out on a piece of paper if you have to.
The general take home point here is it helps to reduce these problems to their smallest components first.

Call this function on every string you wish to check. If it returns true, add that string to your result set.
boolean matches(String s, char[] chars) {
for(char c : chars) {
if (s.indexOf(c) == -1) {
return false;
}
}
return true;
}

Related

Add numbers in a string with recursion in Java with substring

I'm trying to add some numbers from a string
For example the string is "5 + 3 +2". This should return 10
This is my code for getting the number of the operator is a "+"
int opIndex= expression.indexOf("+");
Double lhs = Double.parseDouble(expression.substring(0, opIndex));
Double rhs = Double.parseDouble(expression.substring(opIndex+1));
What I got in return is
lhs = 5 (which is what I wanted)
rhs = returned a string error (3+2);
How can I get number 3 only then do + 2 after the (5+3) or any other approach?
Thanks.
If you do things recursively with a list of things, always think in the following pattern:
handle the first element of the list
handle the rest of the list using a recursive call
So in the case of "5 + 3 +2", split off 5 and "+" and then pass the rest ("3+2") to the same method again.
It's also far easier to remove the spaces before you start.
public static void main(String[] args) {
String input = "5 + 3 + 2";
//remove spaces:
input = input.replaceAll(" +", "");
int r = evaluate(input);
System.out.println(r);
}
private static int evaluate(String s) {
int operatorIndex = s.indexOf('+');
if(operatorIndex == -1) {
//no operator found, s is the last number
//this is the base case that "ends" the recursion
return Integer.parseInt(s);
}
else {
//this is left hand side:
int operand = Integer.parseInt(s.substring(0, operatorIndex));
//this performs the actual addition of lhs and whatever rhs might be (here's where recursion comes in)
return operand + evaluate(s.substring(operatorIndex+1));
}
}
This code prints 10. It gets a more complex if you also want to support substraction, but you will figure it out.
The "RHS" string ends up being something like " 3 + 2". Your job is not to get the 3. Your job is to recurse: Give that string to your own algorithm, trust that it works.
That's how recursion works: You assume your algorithm already works, and then you write it, calling yourself, with the additional rule that you can only call yourself with a 'simpler' case (because otherwise it'll never end), and that you write code to deal with the simplest case explicitly (which in this case would presumably be if I hand your method just a number. If I hand it "5", it needs to return 5, and not recurse).
you can split the spring using the split method
String array[]=expression.split("+")
now itrate the aray and you can

Looking for similar strings in a string array [duplicate]

This question already has answers here:
How to search an array for a part of string?
(6 answers)
Closed 1 year ago.
I have a string array. For example:
["Tartrazine","Orange GGN", "Riboflavin-5-Phosphate"]
And I have a string. For example:
"Riboflvin"
I want to look for most similar string in the array and get it if it exists.
So I need this output:
"Riboflavin-5-Phosphate"
But if the array looks like this:
["Tartrazine","Orange GGN", "Quinoline"]
I want something like this output:
"No similar strings found"
I tried using FuzzyWuzzy library, but it shows a lot of false alarms.
You can use String#contains method, sequentially reducing the length of the string to search if the full string is not found:
String[] arr = {"Tartrazine", "Orange GGN", "Riboflavin-5-Phosphate"};
String element = "Riboflvin";
boolean found = false;
for (int i = 0; i < element.length(); i++) {
// take shorter substring if nothing found at previous step
String part = element.substring(0, element.length() - i);
// if any string from array contains this substring
if (Arrays.stream(arr).anyMatch(str -> str.contains(part))) {
System.out.println("Found part: " + part);
// then print these strings one by one
Arrays.stream(arr).filter(str -> str.contains(part))
.forEach(System.out::println);
found = true;
break;
}
}
// if nothing found
if (!found) {
System.out.println("No similar strings found");
}
Output:
Found part: Ribofl
Riboflavin-5-Phosphate
Well, it depends what you want to do exactly.
There are a couple of things you can do you can check wether the array contains an exact match of the String you are looking for by just calling list.contains("yourStr") the list directly. You could also check each value to see whether it contains a certain substring like so:
foreach(String s : list) {
if (s.contains(subStr) {
return s;
}
}
Otherwise, if you really would like to check similarity it becomes a bit more complicated. Then we really have to answer the question: "how similar is similar enough?". I guess this post as a decent answer to that problem: Similarity String Comparison in Java

Explain how this permutation works

I searched a code for permutation in java:
public class MainClass {
public static void main(String args[]) {
permuteString("", "String");
}
public static void permuteString(String beginningString, String endingString) {
if (endingString.length() <= 1)
System.out.println(beginningString + endingString);
else
for (int i = 0; i < endingString.length(); i++) {
try {
String newString = endingString.substring(0, i) + endingString.substring(i + 1);
permuteString(beginningString + endingString.charAt(i), newString);
} catch (StringIndexOutOfBoundsException exception) {
exception.printStackTrace();
}
}
}
}
I can't understand it even though I know it was only a basic code. I want someone to explain it to me to make it clearer. Thank you guys
One can construct a permutation, by picking items from a bag repeatedly and thus constructing a sequence. For a string, the bag is a collection of characters. We can use a String to represent this.
If we thus want to construct a random permutated string, we first look if the bag is empty. In the above code, the bag is the endingString and the emptiness check is done with:
if (endingString.length() <= 1)
System.out.println(beginningString + endingString);
As you can see the check does not look whether the bag is completely empty: from the moment the string has only one character (one element), it is evidently we will pick that one. So we pick it and print it after the sequence we've already constructed.
Problem: a problem with this approach is that if we want to list the permutations of the empty string (there is exactly one: the empty string), one will get errors.
Now we need the iterative case. Remember that beginningString stores the sequence we've constructed up till now and endingString stores the list of characters we still can pick from. Now a way to pick is to select a valid index i in the endingString. The character at that index is then picked.
We update the sequence (beginningString by simply appending the character that was placed at i, thus:
beginningString + endingString.charAt(i)
In order to update the bag, it means that the bag now contains all the characters before the index, and the ones after the index. This is formalized as:
String newString = endingString.substring(0, i) + endingString.substring(i + 1);
newString is here the new bag. We can then do the recursive call to pick the next item from the bag. So for a given index i, in order to pick and call recursively, the code reads:
String newString = endingString.substring(0, i) + endingString.substring(i + 1);
permuteString(beginningString + endingString.charAt(i), newString);
Now since we wish to enumerate over all possible permutations, we loop over all possible indices for i. Since we do this recursively as a consequence, we will enumerate all permutations.

How do you check to compare a string value to each element in an array?

So I have a String Array (sConsonantArray) and have all of the consonants stored in it.
String[] sConsonantArray = new String[] {"q","w","r","t","p","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m"};
I need to check if the second last value of a word (sWord) equals a value in the array and I don't know how to call each value in the array to compare the letters other than doing sConsonantArray[5] (checking them each one at a time). I am looking for an easier way to call them, thanks for your help. Also, it doesn't appear that the (&&) operator will work, other suggestions would be appreciated.
else if (sWord.substring(sWord.length()-2,sWord.length()-1).equals(sConsonantArray I DONT KNOW WHAT TO PUT HERE)) && (sWord.substring(sWord.length()-1,sWord.length()).equalsIgnoreCase("o"))
{
System.out.println("The plural of " + sWord + " is " + (sWord + "es"));
}
It seems to me that it would be simpler to have the consonants as a string and then use charAt:
private static final String CONSONANTS = "bcdfgh...z";
if (CONSONANTS.indexOf(word.charAt(word.length() - 2)) {
...
}
If you really want to use an array, you could change your array to be in order and then call Arrays.binarySearch. Another alternative would be to create a HashSet<String> of the consonants and use contains on that.
Try something like
else if (Arrays.asList(sConsonantArray).contains(
sWord.substring(sWord.length()-2,sWord.length()-1))
&& (sWord.substring(sWord.length()-1,sWord.length()).equalsIgnoreCase("o"))) {
// do something
}
or Write a small Util method
public static boolean isInConstants(String yourString){
String[] sConsonantArray = new String[] {"q","w...}
for (String item : sConsonantArray) {
if (yourString.equalsIgnoreCase(item)) {
return true;
}
}
return false;
}

Splitting string algorithm in Java

I'm trying to make the following algorithm work. What I want to do is split the given string into substrings consisting of either a series of numbers or an operator.
So for this string = "22+2", I would get an array in which [0]="22" [1]="+" and [2]="2".
This is what I have so far, but I get an index out of bounds exception:
public static void main(String[] args) {
String string = "114+034556-2";
int k,a,j;
k=0;a=0;j=0;
String[] subStrings= new String[string.length()];
while(k<string.length()){
a=k;
while(((int)string.charAt(k))<=57&&((int)string.charAt(k))>=48){
k++;}
subStrings[j]=String.valueOf(string.subSequence(a,k-1)); //exception here
j++;
subStrings[j]=String.valueOf(string.charAt(k));
j++;
}}
I would rather be told what's wrong with my reasoning than be offered an alternative, but of course I will appreciate any kind of help.
I'm deliberately not answering this question directly, because it looks like you're trying to figure out a solution yourself. I'm also assuming that you're purposefully not using the split or the indexOf functions, which would make this pretty trivial.
A few things I've noticed:
If your input string is long, you'd probably be better off working with a char array and stringbuilder, so you can avoid memory problems arising from immutable strings
Have you tried catching the exception, or printing out what the value of k is that causes your index out of bounds problem?
Have you thought through what happens when your string terminates? For instance, have you run this through a debugger when the input string is "454" or something similarly trivial?
You could use a regular expression to split the numbers from the operators using lookahead and lookbehind assertions
String equation = "22+2";
String[] tmp = equation.split("(?=[+\\-/])|(?<=[+\\-/])");
System.out.println(Arrays.toString(tmp));
If you're interested in the general problem of parsing, then I'd recommend thinking about it on a character-by-character level, and moving through a finite state machine with each new character. (Often you'll need a terminator character that cannot occur in the input--such as the \0 in C strings--but we can get around that.).
In this case, you might have the following states:
initial state
just parsed a number.
just parsed an operator.
The characters determine the transitions from state to state:
You start in state 1.
Numbers transition into state 2.
Operators transition into state 3.
The current state can be tracked with something like an enum, changing the state after each character is consumed.
With that setup, then you just need to loop over the input string and switch on the current state.
// this is pseudocode -- does not compile.
List<String> parse(String inputString) {
State state = INIT_STATE;
String curr = "";
List<String> subStrs = new ArrayList<String>();
for(Char c : inputString) {
State next;
if (isAnumber(c)) {
next = JUST_NUM;
} else {
next = JUST_OP;
}
if (state == next) {
// no state change, just add to accumulator:
acc = acc + c;
} else {
// state change, so save and reset the accumulator:
subStrs.add(acc);
acc = "";
}
// update the state
state = next;
}
return subStrs;
}
With a structure like that, you can more easily add new features / constructs by adding new states and updating the behavior depending on the current state and incoming character. For example, you could add a check to throw errors if letters appear in the string (and include offset locations, if you wanted to track that).
If your critera is simply "Anything that is not a number", then you can use some simple regex stuff if you dont mind working with parallel arrays -
String[] operands = string.split("\\D");\\split around anything that is NOT a number
char[] operators = string.replaceAll("\\d", "").toCharArray();\\replace all numbers with "" and turn into char array.
String input="22+2-3*212/21+23";
String number="";
String op="";
List<String> numbers=new ArrayList<String>();
List<String> operators=new ArrayList<String>();
for(int i=0;i<input.length();i++){
char c=input.charAt(i);
if(i==input.length()-1){
number+=String.valueOf(c);
numbers.add(number);
}else if(Character.isDigit(c)){
number+=String.valueOf(c);
}else{
if(c=='+' || c=='-' || c=='*' ||c=='/'){
op=String.valueOf(c);
operators.add(op);
numbers.add(number);
op="";
number="";
}
}
}
for(String x:numbers){
System.out.println("number="+x+",");
}
for(String x:operators){
System.out.println("operators="+x+",");
}
this will be the output
number=22,number=2,number=3,number=212,number=21,number=23,operator=+,operator=-,operator=*,operator=/,operator=+,

Categories

Resources