Java Substring by Keyword - java

I have to make separate Strings from one single String.
For example given the String:
.*C.{0}A.{2}T.{0}T.{0}T.{2}T.{0}G.{8}T.{7}A.{7}T.{2}T.{12}A.{5}T.{4}T.{45}A.{1}A.{10}G.{19}A.{25}T.{3}A.{1}A.{4}G.{1}A.{2}A.{29}A.{0}C.{15}A.{1}C.{1}A.{6}T.{3}G.{5}T.{0}T.{0}C.{3}G.{2}C.{1}G.{4}G.{1}G.*
I have to create a HashSet with the following content:
.*C.{0}A.{2}T.{0}T.*
.*A.{2}T.{0}T.{0}T.*
.*T.{0}T.{0}T.{2}T.*
.*T.{0}T.{2}T.{0}G.*
...
The elements are formed by taking 4 of the entries from the original string and creating a smaller string from them. Then you move one entry along in the original string and repeat.
How can I do this?
Thanks!

You want to take a string, representing a list of elements, and turn it into a set of overlapping shorter lists of elements. You can do this by having a method which returns the elements from the list and then a sliding window which selects sets of elements to display:
private static final Pattern pattern = Pattern.compile("[ACGT]\\.\\{\\d+\\}");
public static List<String> extract(String input) {
Matcher matcher = pattern.matcher(input);
List<String> result = new ArrayList<String>();
while (matcher.find()) {
result.add(matcher.group(0));
}
return result;
}
public static Set<String> compose(List<String> elements, int window) {
Set<String> result = new HashSet<String>();
for (int i = 0; i <= elements.size() - window; i++) {
StringBuilder builder = new StringBuilder(".*");
for (int j = i; j < i + window; j++) {
builder.append(elements.get(j));
}
// This strips the final quantifier turning:
// .*C.{0}A.{2}T.{0}T.{0}
// into
// .*C.{0}A.{2}T.{0}T
builder.delete(builder.lastIndexOf("."), builder.length());
builder.append(".*");
result.add(builder.toString());
}
return result;
}
You can check this with the following method:
public static void main(String[] args) {
String input = ".*C.{0}A.{2}T.{0}T.{0}T.{2}T.{0}G.{8}T.{7}A.{7}";
Set<String> result = compose(extract(input), 4);
// The result will contain
// ".*C.{0}A.{2}T.{0}T.*"
// etc
}

Here is a possible solution:
public class Main {
public static void main(String[] args) {
String s = ".*C.{0}A.{2}T.{0}T.{0}T.{2}T.{0}G.{8}T.{7}A.{7}T.{2}T.{12}A.{5}T.{4}T.{45}A.{1}A.{10}G.{19}A.{25}T.{3}A.{1}A.{4}G.{1}A.{2}A.{29}A.{0}C.{15}A.{1}C.{1}A.{6}T.{3}G.{5}T.{0}T.{0}C.{3}G.{2}C.{1}G.{4}G.{1}G.*";
String[] array = s.split("}");
Set<String> result = new HashSet<String>();
for ( int i = 0 ; i < array.length-3 ; i++) {
String firstElement = array[i].startsWith(".*") ? array[i].substring(2) : array[i];
String lastElement = array[i+2]+"}"+array[i+3].substring(0,1)+".*" ;
String element = ".*"+firstElement+"}"+array[i+1]+"}"+lastElement;
result.add(element);
System.out.println(element);
}
//Your result are in the Set result
}
}

Related

Getting data from a given String separated by (,,-) in java

I am having a String like this "5006,3030,8080-8083".
I want each element separately from the String:
5006
3030
8080
8081
8082
8083
Here's my code:
int i=0,j=0;
String delim = "[,]";
String hyphon = "[-]";
String example = "5006,3030,8080-8083";
String p[] = example.split(delim);
int len = p.length;
for(i=0;i<len;i++) {
String ps[]=p[i].split(hyphon);
if(ps.length>1) {
int start = Integer.parseInt(ps[0]);
int finish = Integer.parseInt(ps[1]);
int diff = finish-start+1;
for(j=0;j<diff;j++) {
System.out.println(start+j);
}
} else if(ps.length==1) {
System.out.println(ps[0]);
}
}
Is there any better solution or any class that simplifies my code?
I also want the numbers in a ascending order.
Try this code :
public static void main(String[] args) {
String input = "5006,3030,8080-8083";
List<Integer> list = new ArrayList<Integer>();
String[] numbers = input.split(",");
for (String s : numbers) {
if (s.contains("-")) {
String[] range = s.split("-");
int from = Integer.parseInt(range[0]);
int to = Integer.parseInt(range[1]);
for (int i = from; i <= to; i++) {
list.add(i);
}
}
else {
list.add(Integer.parseInt(s));
}
}
System.out.println("in asc order");
Collections.sort(list);
System.out.println(list.toString());
System.out.println("in desc order");
Collections.reverse(list);
System.out.println(list.toString());
}
My output :
in asc order
[3030, 5006, 8080, 8081, 8082, 8083]
in desc order
[8083, 8082, 8081, 8080, 5006, 3030]
I also want the numbers in a ascending order.
This adds an unexpected twist to your whole program, because once you realize that printing-as-you-go no longer works, you need to start almost from scratch.
The first thing to do is picking an appropriate representation. It appears that you represent ranges of integers, so start by defining a class for them:
class IntRange : Comparable<IntRange> {
private int low, high;
public int getLow() {return low;}
public int getHigh() {return high;}
public IntRange(int low, int high) {
// Add range check to see if low <= high
this.low = low; this.high = high;
}
public IntRange(int point) {low = high = point;}
#Override
public void print() {
for (int i = low ; i <= high ; i++) {
System.out.println(i);
}
}
#Override
public int compareTo(IntRange other) {
...
}
}
Now you can use your code to split on [,], then split on [-], construct IntRange, and put it into an ArrayList<IntRange>. After that you can use sort() method to sort the ranges, and print them in the desired order.
But wait, there is more to your problem than meets the eye. Think what would happen for input like this:
1,5,3-7,6
Where should 5 and 6 be printed? It is not good to print it before or after 3-7, so the trick is to remove points inside ranges.
But even that's not all: what do you do about this input?
1-5,3-7
You should print numbers 1 through 7, inclusive, but this would require merging two ranges. There is a good data structure for doing this efficiently. It is called a range tree. If your input is expected to be large, you should consider using range tree representation.
You are good to go; you can minimize the counter variables using enhanced for loop and while loop.
String example = "5006,3030,8080-8083";
String[] parts=example.split(",")
ArrayList<Integer> numbers = new ArrayList<Integer>();
for(String part: parts)
{
if(part.contains("-"))
{
String subParts[]=part.split("-");
int start = Integer.parseInt(subParts[0]);
int finish = Integer.parseInt(subParts[1]);
while(start <= finish)
{
numbers.add(start);
System.out.println(start++);
}
}
else {
System.out.println(part);
numbers.add(Integer.parseInt(part));
}
}
Integer[] sortedNumbers = new Integer[numbers.size()];
sortedNumbers = Arrays.sort(numbers.toArray(sortedNumbers));
Update (from comment):
Numbers are sorted now.
Try this
String str = "5006,3030,8080-8083";
String[] array = str.split(",");
String ans = "";
for(int i = 0; i < array.length; i++){
if(array[i].contains("-")){
String[] array2 = array[i].split("-");
int start = Integer.parseInt(array2[0]);
int end = Integer.parseInt(array2[array2.length - 1]);
for(int j = start; j <= end; j++){
ans = ans + j + ",";
}
}
else{
ans = ans + array[i] + ",";
}
}
System.out.print(ans);
This code assumes all integers are positive.
public static void main(String[] args) {
String testValue="5006,3030,8080-8083";
Integer[]result=parseElements(testValue);
for (Integer i:result){
System.out.println(i);
}
}
/**
* NumberList is a string of comma-separated elements that are either integers, or a range of integers of the form a-b.
* #param numberList
* #return all the integers in the list, and in ranges in the list, in a sorted list
*/
private static Integer[] parseElements(String integerList) {
ArrayList<Integer> integers=new ArrayList<Integer>();
String[] csvs=integerList.split(",");
for(String csv : csvs){
if(csv.contains("-")){
String[] range=csv.split("-");
Integer left=Integer.decode(range[0]);
Integer right=Integer.decode(range[1]);
for(Integer i=left;i<=right;i++){
integers.add(i);
}
} else {
integers.add(Integer.decode(csv));
}
}
Collections.sort(integers);
return integers.toArray(new Integer[0]);
}
Using Guava's functional idioms you can achive this declaratively, avoiding the verbose, imperative for-loops. First declare a tokenizing function which converts each token in the comma-delimited string into an Iterable<Integer>:
private static final Function<String, Iterable<Integer>> TOKENIZER =
new Function<String, Iterable<Integer>>() {
/**
* Converts each token (e.g. "5006" or "8060-8083") in the input string
* into an Iterable<Integer>; either a ContiguousSet or a List with a
* single element
*/
#Override
public Iterable<Integer> apply(String token) {
if (token.contains("-")) {
String[] range = token.trim().split("-");
return ContiguousSet.create(
Range.closed(Integer.parseInt(range[0]),
Integer.parseInt(range[1])),
DiscreteDomain.integers());
} else {
return Arrays.asList(Integer.parseInt(token.trim()));
}
}
};
then apply the function to the input:
String input = "5006,3030,8080-8083";
Iterable<String> tokens = Splitter.on(',').trimResults().split(input);
SortedSet<Integer> numbers = Sets.newTreeSet();
Iterables.addAll(numbers,
// concat flattens the Iterable<Iterable<Integer>>
// into an Iterable<Integer>
Iterables.concat(Iterables.transform(tokens, TOKENIZER)));
As all of the logic is basically coded into the Function, the client code only needs to tokenize the string into an Iterable<String> (with Splitter), apply the Function through Iterables.transform, flatten the result of the transformation using Iterables.concat and finally add the resulting Iterable<Integer> into a SortedSet<Integer> which keeps the numbers in ascending order.
with java 8 stream api :
public static void main(String[] args) {
String s = "5006,3030,8080-8083";
Arrays.stream(s.split(","))
.flatMap(el -> el.contains("-") ? rangeToStream(el) : Stream.of(Integer.valueOf(el)))
.sorted()
.forEachOrdered(e -> System.out.println(e));
}
private static Stream<? extends Integer> rangeToStream(String el) {
AtomicInteger[] bounds = Arrays.stream(el.split("-")).map(e -> new AtomicInteger(Integer.parseInt(e))).toArray(size -> new AtomicInteger[2]);
return Arrays.stream(new Integer[bounds[1].get() - bounds[0].get() + 1]).map(e -> bounds[0].getAndIncrement());
}
U can code something like this -
String s="5006,3030,8080-8083";
String s2[]=s.split(",");
List<Integer> li= new ArrayList<Integer>();
List<Integer> numbers= new ArrayList<Integer>();
for(int i=0;i<s2.length;i++){
if(s2[i].contains("-")){
li.add(i);
}
else{
numbers.add(Integer.parseInt(s2[i]));
}
}
for(Integer i:li){
String str=s2[i];
String strArr[]=str.split("-");
for(int j=Integer.parseInt(strArr[0]);j<=Integer.parseInt(strArr[1]);j++){
numbers.add(j);
}
}
Collections.sort(numbers);
for(Integer k:numbers){
System.out.println(k);
}
public static void main(String[] args)
{
String example = "5006,3030,8080-8083";
String[] splitString = example.split(",");
List<Integer> soretedNumbers = new ArrayList<>();
for(String str : splitString)
{
String[] split2 = str.split("-");
if(split2.length == 1)
{
soretedNumbers.add(Integer.parseInt(str));
}
else
{
int num1 = Integer.parseInt(split2[0]);
int num2 = Integer.parseInt(split2[1]);
for(int i = num1;i <= num2; i++)
{
soretedNumbers.add(i);
}
}
}
Collections.sort(soretedNumbers);
for(int i : soretedNumbers)
{
System.out.println(i);
}
}

return multiple values java for removing last part of a word

In my code, fromright method checks the length of last[] and returns only one string. I want to return all matched values. What's the solution?
public static String last[]={"es","e","s"};
public static void main(String[] args) {
text tx=new text();
String checkString = "lives";
String fin=tx.fromright(checkString);
System.out.println("remaining: "+fin);
}
public String fromright(String wrd) {
String tmp="";
for (int i = 0; i < last.length; i++) {
tmp=wrd.substring(0, wrd.length()-last.length);
}
return tmp;
}
You are overriding your tmp variable in your for loop every time. So you can only get one result.
Use this instead or smth. similiar which can hold multiple values.
public List<String> fromright(String wrd) {
List<String> tmp= new ArrayList<String>();
for (int i = 0; i < last.length; i++) {
tmp.add(wrd.substring(0, wrd.length()-last.length));
}
return tmp;
EDIT:
This does not work anymore.
String fin=tx.fromright(checkString);
^
Replace it with
List<String> fin= new ArrayList<String>(tx.fromright(checkString));
And print out all values with this
for(String s : fin) System.out.println(s);
public List<String> fromright(String wrd) {
List<String> result = new ArrayList<>();
for (int i = 0; i < last.length; i++) {
if(wrd.endsWith(last[i]))
result.add(last[i]);
}
return result;

Java split string with combinations

My input string is
element1-element2-element3-element4a|element4b-element5-
Expected output is
element1-element2-element3-element4a-element5-
element1-element2-element3-element4b-element5-
So the dash (-) is the delimiter and the pipe (|) indicates two alternative elements for a position.
I am able to generate combinations for input containing a single pipe:
ArrayList<String> finalInput = new ArrayList<String>();
String Input = getInputPath();
StringBuilder TempInput = new StringBuilder();
if(Input.contains("|")) {
String[] splits = Input.split("\\|", 2);
TempInput.append(splits[0]+"-"+splits[1].split("-", 2)[1]);
finalInput.add(TempInput.toString());
TempInput = new StringBuilder();
String[] splits1 = new StringBuilder(Input).reverse().toString().split("\\|", 2);
finalInput.add(TempInput.append(splits1[0]+"-"+splits1[1].split("-", 2)[1]).reverse().toString());
}
But this logic fails if there are multiple pipe symbols.
How to split a String on the last occurrance only?
Is there any efficient way to use split String with combinations?
Input:
element1-element2-element3-element4a|element4b-element5-element6a|element6b
Output:
element1-element2-element3-element4a-element5-element6a
element1-element2-element3-element4b-element5-element6a
element1-element2-element3-element4a-element5-element6b
element1-element2-element3-element4b-element5-element6b
Recursion helps.
public static void main(String[] args) {
produce("element1-element2-element3-element4a|element4b"
+ "-element5-element6a|element6b");
}
private static void produce(String input) {
String[] sequence = input.split("-");
String[][] elements = new String[sequence.length][];
for (int i = 0; i < sequence.length; ++i) {
elements[i] = sequence[i].split("\\|");
}
List<String> results = new ArrayList<>();
walk(results, elements, 0, new StringBuilder());
}
private static void walk(List<String> results, String[][] elements,
int todoIndex, StringBuilder done) {
if (todoIndex >= elements.length) {
results.add(done.toString());
System.out.println(done);
return;
}
int doneLength = done.length();
for (String alternative : elements[todoIndex]) {
if (done.length() != 0) {
done.append('-');
}
done.append(alternative);
walk(results, elements, todoIndex + 1, done);
done.setLength(doneLength); // Undo
}
}
The String.split method is used twice to get a navigatable String[][]. And to build a final String a StringBuilder is used.
You can use StringTokenizer in Java. Basically it makes tokens of the string.
public StringTokenizer(String str, String delim)
Here's an example:
String msg = "http://100.15.111.60:80/";
char tokenSeparator= ':';
StringTokenizer st = new StringTokenizer(msg, tokenSeparator + "");
while(st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
I have write a demo for you as what I comment after your post, the code may be ugly, but it works
public class TestSplit {
//define a stringList hold our result.
private static List<String> stringList = new ArrayList<String>();
//this method fork the list array when we meet a "|"
public static void forkStringList(){
List<String> tmpList = new ArrayList<String>();
for(String s: stringList){
tmpList.add(s);
}
stringList.addAll(tmpList);
}
//when we meet "|" split two elems, should add it to
//the string list half-half
public static void addTowElems(String s1, String s2){
for(int i=0;i<stringList.size()/2;i++){
stringList.set(i,stringList.get(i)+s1);
}
for(int i = stringList.size()/2;i<stringList.size();i++){
stringList.set(i,stringList.get(i)+s2);
}
}
// if not meet with a "|" just add elem to everyone of the stringlist
public static void addOneElem(String s){
for(int i=0;i<stringList.size();i++){
stringList.set(i,stringList.get(i)+s);
}
}
public static void main(String[] argvs){
//to make *fork* run, we must make sure there is a "init" string
//which is a empty string.
stringList.add("");
// this is your origin string.
String input = "a-b-c-d|e-f";
for (String s: input.split("\\-")){
if(s.contains("|")){
//when meet with "|", first fork the stringlist
forkStringList();
// then add them separately
addTowElems(s.split("\\|")[0],s.split("\\|")[1]);
}else {
// else just happily add the elem to every one
// of the stringlist
addOneElem(s);
}
}
//checkout the result, should be expected.
System.out.println(stringList);
}
}
Here's my iterative solution:
import java.util.*;
public class PathParser {
private static final String DELIMINATOR_CONCAT = "-";
private static final String DELIMINATOR_OPTION = "|";
private List<String> paths;
private List<String> stack;
private List<String> parse(final String pathSpec) {
stack = new ArrayList<String>();
paths = new ArrayList<String>();
paths.add("");
final StringTokenizer tok = createStringTokenizer(pathSpec);
while (tok.hasMoreTokens()) {
final String token = tok.nextToken();
parseToken(token);
}
if (!stack.isEmpty()) {
updatePaths();
}
return paths;
}
private void parseToken(final String token) {
if (DELIMINATOR_CONCAT.equals(token)) {
updatePaths();
} else if (DELIMINATOR_OPTION.equals(token)) {
// nothing to do
} else {
stack.add(token);
}
}
private void updatePaths() {
final List<String> originalPaths = new ArrayList<String>(paths);
paths.clear();
while (stack.size() > 0) {
paths.addAll(createNewPaths(originalPaths));
}
}
private List<String> createNewPaths(final List<String> originalPaths) {
final List<String> newPaths = new ArrayList<String>(originalPaths);
addPart(newPaths, stack.remove(0));
addPart(newPaths, DELIMINATOR_CONCAT);
return newPaths;
}
private void addPart(final List<String> paths, final String part) {
for (int i = 0; i < paths.size(); i++) {
paths.set(i, paths.get(i) + part);
}
}
private StringTokenizer createStringTokenizer(final String pathSpec) {
final boolean returnDelimiters = true;
final String delimiters = DELIMINATOR_CONCAT + DELIMINATOR_OPTION;
return new StringTokenizer(pathSpec, delimiters, returnDelimiters);
}
public static void main(final String[] args) {
final PathParser pathParser = new PathParser();
final String input = "element1-element2-element3-element4a|element4b|element4c-element5-element6a|element6b|element6c";
System.out.println("Input");
System.out.println(input);
System.out.println();
final List<String> paths = pathParser.parse(input);
System.out.println("Output");
for (final String path : paths) {
System.out.println(path);
}
}
}
Output:
Input
element1-element2-element3-element4a|element4b-element5-element6a|element6b
Output
element1-element2-element3-element4a-element5-element6a-
element1-element2-element3-element4b-element5-element6a-
element1-element2-element3-element4a-element5-element6b-
element1-element2-element3-element4b-element5-element6b-
This helps to acheive the same..
public class MultiStringSplitter {
public static void main(String arg[]) {
String input = "a-b|c-d|e-f|g-h";
String[] primeTokens = input.split("-");
String[] level2Tokens = null;
String element = "";
String level2element = "";
ArrayList stringList = new ArrayList();
ArrayList level1List = new ArrayList();
ArrayList level2List = new ArrayList();
for (int i = 0; i < primeTokens.length; i++) {
// System.out.print(primeTokens[i]);
if (primeTokens[i].contains("|")) {
level2Tokens = primeTokens[i].split("\\|");
for (int j = 0; j < level2Tokens.length; j++) {
for (int k = 0; k < stringList.size(); k++) {
element = (String) stringList.get(k);
level2element = element + level2Tokens[j];
level2List.add(level2element);
}
}
stringList = new ArrayList();
for (int w = 0; w < level2List.size(); w++) {
stringList.add(level2List.get(w));
}
level2List = new ArrayList();
}
else {
if (stringList.size() > 0) {
for (int z = 0; z < stringList.size(); z++) {
element = (String) stringList.get(z);
element = element + primeTokens[i];
level1List.add(element);
}
stringList = new ArrayList();
for (int w = 0; w < level1List.size(); w++) {
stringList.add(level1List.get(w));
}
level1List = new ArrayList();
}
else {
element = element + primeTokens[i];
if (stringList.size() == 0) {
stringList.add(element);
}
}
}
}
for (int q = 0; q < stringList.size(); q++) {
System.out.println(stringList.get(q));
}
}
}
Input : a-b|c-d|e-f|g-h
Output:
abdfh
acdfh
abefh
acefh
abdgh
acdgh
abegh
acegh

split ArrayList String

how do I split arrayList String
SCHOOLWORK
BALCONY
INSIST
SALTPETER
BOLTON
KITSCHY
CLIENTELE
I want to split those words to "SCH", "OOL", "WO", "RK".
Here is my code
import java.io.File;
import java.util.ArrayList;
public class HW2 {
public static ArrayList<String> getTiles(ArrayList<String> input_list_of_strings) {
// create a substring by go through the loop first, then .... (instruction)
Object[] subString = new Object[input_list_of_strings.size()];
for (int i = 0; i < input_list_of_strings.size(); i++) {
subString[i] = input_list_of_strings.get(i);
// test just want to see if subString get all String
// System.out.println(subString[i]);
String delim=" ";
String[] splitstrings = ((String) subString[i]).split(delim);
for (int j = 0; j < splitstrings.length; j++) {
splitstrings[j] +=delim;
System.out.println(splitstrings[j]);
}
}
return input_list_of_strings;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> input_words = new ArrayList<String>();
input_words.add("SCHOOLWORK");
input_words.add("BALCONY");
input_words.add("INSIST");
input_words.add("SALTPETER");
input_words.add("BOLTON");
input_words.add("KITSCHY");
input_words.add("CLIENTELE");
System.out.print(getTiles(input_words));
}
}
Thank you...
I would use an interface to encapsulate how you want to split each string.
public static interface StringSplitter {
public List<String> splitString(String s);
}
Then your 'getTiles' method would simply be:
public static ArrayList<String> getTiles(ArrayList<String> input,StringSplitter splitter) {
int initSize = input.size();
for(int i = 0; i < initSize; i++) {
String source = input.remove(0); //Remove from head
input.addAll(splitter.splitString(source)); //Add to end
}
return input;
}
NOTE: This method modifies the original list, it can be easily adapted to simply copy the list if need be. Although, I like it better this way.
Since the exact process for splitting these words is unclear, I am going to guess that you want to keep splitting a word by three characters, unless that would leave only one character, then split by two - else don't split. So your default 'StringSplitter' would be:
public static final StringSplitter DEFAULT_SPLITTER = new StringSplitter() {
#Override
public List<String> splitString(String s) {
List<String> subs = new ArrayList();
while(!s.isEmpty()){
int splitsize = 0;
if(s.length() < 5) {
if(s.length() == 4) {
splitsize = 2;
} else {
splitsize = s.length();
}
} else {
splitsize = 3;
}
subs.add(s.substring(0,splitsize));
s = s.substring(splitsize);
}
return subs;
}
};
Your main method would then be:
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<String> input_words = new ArrayList<String>();
input_words.add("SCHOOLWORK");
input_words.add("BALCONY");
input_words.add("INSIST");
input_words.add("SALTPETER");
input_words.add("BOLTON");
input_words.add("KITSCHY");
input_words.add("CLIENTELE");
System.out.print(getTiles(input_words),DEFAULT_SPLITTER); //Make sure to use DEFAULT_SPLITTER
}
First iterate through your ArrayList<String>. For each word in the ArrayList, split it into chunks. Your example above doesn't make much sense -- why is "SCHOOLWORK" split into "SCH", "OOL", "WO", "RK" and not "SCHOOL" and "WORK" ? Without understanding the logic behind your requirements, all we can give are general suggestions.
So, basically:
// iterate through the arraylist
ArrayList<String> allWords; // instantiate this
...
for(String word : allWords) {
splitWord(word);
}
And create a method splitWord(String) that applies whatever logic you need aginst the word to split it up. I suggest looking into String's substring() method if you need words of a certain size.

java delete reverse string in list

I have struct Array or List String like:
{ "A.B", "B.A", "A.C", "C.A" }
and I want delete reverse string from list that end of only:
{ "A.B", "A.C" }
how type String use and how delete reverse String?
To reverse a string I recommend using a StringBuffer.
String sample = "ABC";
String reversed_sample = new StringBuffer(sample).reverse().toString();
To delete object form you ArrayList use the remove method.
String sample = "ABC";String to_remove = "ADS";
ArrayList<String> list = new ArrayList<Sample>();
list.add(to_remove);list.add(sample );
list.remove(to_remove);
You can get use of a HashMap to determine whether a string is a reversed version of the other strings in the list. And you will also need a utility function for reversing a given string. Take a look at this snippets:
String[] input = { "A.B", "B.A", "A.C", "C.A" };
HashMap<String, String> map = new HashMap<String, String>();
String[] output = new String[input.length];
int index = 0;
for (int i = 0; i < input.length; i++) {
if (!map.containsKey(input[i])) {
map.put(reverse(input[i]), "default");
output[index++] = input[i];
}
}
A sample String-reversing method could be like this:
public static String reverse(String str) {
String output = "";
int size = str.length();
for (int i = size - 1; i >= 0; i--)
output += str.charAt(i) + "";
return output;
}
Output:
The output array will contain these elements => [A.B, A.C, null, null]
A code is worth thousand words.....
public class Tes {
public static void main(String[] args) {
ArrayList<String> arr = new ArrayList<String>();
arr.add("A.B");
arr.add("B.A");
arr.add("A.C");
arr.add("C.A");
System.out.println(arr);
for (int i = 0; i < arr.size(); i++) {
StringBuilder str = new StringBuilder(arr.get(i));
String revStr = str.reverse().toString();
if (arr.contains(revStr)) {
arr.remove(i);
}
}
System.out.println(arr);
}
}
You can do this very simply in O(n^2) time. Psuedocode:
For every element1 in the list:
For every element2 in the list after element1:
if reverse(element2).equals(element1)
list.remove(element2)
In order to make your life easier and prevent ConcurrentModificationException use Iterator. I won't give you the code because it's a good example to learn how to properly use iterators in Java.
Reverse method:
public String reverse(String toReverse) {
return new StringBuilder(toReverse).reverse().toString();
}
Edit: another reverse method:
public String reverse(String toReverse) {
if (toReverse != null && !toReverse.isEmpty) {
String[] elems = toReverse.split(".");
}
StringBuilder reversedString = new StringBuilder("");
for (int i = elems.length - 1; i >= 0; i++) {
reversedString.append(elems[i]);
reversedString.append(".");
}
return reversedString.toString();
}
Check this
public static void main(String arg[]){
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
List<String> strList = new ArrayList<String>();
strList.add("A.B");
strList.add("B.A");
strList.add("A.C");
strList.add("C.A");
Iterator<String> itr = strList.iterator();
while(itr.hasNext()){
String [] split = itr.next().toUpperCase().split("\\.");
if(str.indexOf(split[0])>str.indexOf(split[1])){
itr.remove();
}
}
System.out.println(strList);
}
output is
[A.B, A.C]
You can iterate the list while maintaining a Set<String> of elements in it.
While you do it - create a new list (which will be the output) and:
if (!set.contains(current.reverse())) {
outputList.append(current)
set.add(current)
}
This solution is O(n*|S|) on average, where n is the number of elements and |S| is the average string length.
Java Code:
private static String reverse(String s) {
StringBuilder sb = new StringBuilder();
for (int i = s.length()-1 ; i >=0 ; i--) {
sb.append(s.charAt(i));
}
return sb.toString();
}
private static List<String> removeReverses(List<String> arr) {
Set<String> set = new HashSet<String>();
List<String> res = new ArrayList<String>();
for (String s : arr) {
if (!set.contains(reverse(s))) {
res.add(s);
set.add(s);
}
}
return res;
}
public static void main(String[]args){
String[] arr = { "a.c" , "b.c", "c.a", "c.b" };
System.out.println(removeReverses(arr));
}
will yield:
[a.c, b.c]

Categories