Remove elements from ArrayList after finding element with specific char - java

I have an ArrayList that contains a number of Strings, I want to be able to iterate through the ArrayLists contents searching for a string containing a semicolon. When the semicolon is found I then want to delete all of the Strings including and after the semicolon string.
So;
this, is, an, arra;ylist, string
Would become:
this, is, an
I feel like this is a very simple thing to do but for some reason (probably tiredness) I can't figure out how to do it.
Here's my code so far
public String[] removeComments(String[] lineComponents)
{
ArrayList<String> list = new ArrayList<String>(Arrays.asList(lineComponents));
int index = 0;
int listLength = list.size();
for(String str : list)
{
if(str.contains(";"))
{
}
index++;
}
return lineComponents;
}

This becomes trivial with Java 9:
public String[] removeComments(String[] lineComponents) {
return Arrays.stream(lineComponents)
.takeWhile(s -> !s.contains(";"))
.toArray(String[]::new);
}
We simply form a Stream<String> from your String[] lineComponents and take elements until we find a semicolon. It automatically excludes the element with the semicolon and everything after it. Finally, we collect it to a String[].

First of all I think you are confusing arrays and arraylists. String[] is an array of strings while ArrayList<String> is an arraylist of strings. Take into account that those are not the same and you should read Array and ArrayList documentation if needed.
Then, to solve your problem following the ArrayList approach you can go as follows. Probably it's not the optimum way to do it but it will work.
public List<String> removeComments(List<String> lineComponents, CharSequence finding)
{
ArrayList<String> aux = new ArrayList<String>();
for(String str : lineComponents)
{
if(str.contains(finding))
break;
else
aux.add(str);
}
return aux;
}

This example is just for performance and bringing back my old favorite arraycopy:
public String[] removeComments(String[] lineComponents) {
int index = -1;
for (int i = 0; i < lineComponents.length; i++) {
if ( lineComponents[i].contains(";") ) {
index = i;
break;
}
}
if (index == -1) return lineComponents;
return Arrays.copyOf(lineComponents, index);
}

Related

Converting array list to a string array

I've been trying to convert my string array list to a string array so I can print it but have been unable to do so.
This is the class I have, randomQuestion which takes in an array list from the gameQuestions method in the same class.
I have never tried to convert an array list using a loop before hence the difficulty, I was able to convert it fine with the code
String[] questions = data1.toArray(new String[]{});
But I need it to loop through using a for loop to store it in an array which I can then print one at a time once a question is answered successfully.
The error I'm receiving from netbeans is cannot find symbol
Symbol:methodtoArray(String[]) for the .toArray portion below.
public String[] randomQuestion(ArrayList data1) {
Collections.shuffle(data1);
for (int question = 0; question < 10; question++) {
ranquestions = data1.get(question).toArray(new String[10]);
}
return ranquestions;
}
Any help would be greatly appreciated.
You can use List.toArray(). Class List has a method:
<T> T[] toArray(T[] a);
Assuming you have an ArrayList<String>, you can use String.join(delimiter, wordList) in order to concatenate all the elements to a single String:
public static void main(String[] args) {
// example list
List<String> words = new ArrayList<String>();
words.add("You");
words.add("can");
words.add("concatenate");
words.add("these");
words.add("Strings");
words.add("in");
words.add("one");
words.add("line");
// concatenate the elements delimited by a whitespace
String sentence = String.join(" ", words);
// print the result
System.out.println(sentence);
}
The result of this example is
You can concatenate these Strings in one line
So using your list, String.join(" ", data1) would create a String with the elements of data1 delimited by a whitespace.
The question is how to create an array with only 10 elements of the list, if I understood correctly.
Streams (Java 8):
String[] ranquestions = data1.stream()
.limit(10)
.toArray(String[]::new);
Loop (based on question, avoiding unnecessary changes):
String[] ranquestions = new String[10];
for(int question = 0; question < 10; question++) {
ranquestions[question] = data1.get(question);
}
always assuming List<String> data1, if not some conversion is needed.
Example:
String[] ranquestions = data1.stream()
.limit(10)
.map(String::valueOf)
.toArray(String[]::new);
or, loop case:
ranquestions[question] = String.valueOf(data1.get(question));
You can do:
private String[] randomQuestions(ArrayList data){
Collections.shuffle(data);
return (String[]) data.toArray();
}
If you are sure you are getting a list of string (question) you can instead
private String[] randomQuestions(List<String> data){
Collections.shuffle(data);
return (String[]) data.toArray();
}
Edit 1
private static String[] randomQuestions(ArrayList data){
Collections.shuffle(data);
String[] randomQuestions = new String[data.size()];
for(int i=0; i<data.size(); i++){
randomQuestions[i] = String.valueOf(data.get(i));
}
return randomQuestions;
}

Reusing input String[] with values from arrayList

I have the following code which sorts a mixed array of items while maintaining the position of types:
For example:
[20, "abc", "moose", 2,1] turns into [1, "abc", "moose", 2, 20]
Algorithm:
public class Algorithm {
public static String[] sortMixedArray(String[] input){
if (input.length == 0){
return input;
}
// make new arraylist for strings and numbers respectively
List<String> strs = new ArrayList<String>();
List<Integer> numbers = new ArrayList<Integer>();
// add values to the arraylist they belong to
for (String item : input){
if (NumberUtils.isNumber(item)){
numbers.add(Integer.valueOf(item));
} else {
strs.add(item);
}
}
// sort for O(nlogn)
Collections.sort(strs);
Collections.sort(numbers);
// reuse original array
for (int i = 0; i < input.length; i++){
if (NumberUtils.isNumber(input[i])) {
input[i] = String.valueOf(numbers.remove(0));
} else {
input[i] = strs.remove(0);
}
}
return input;
}
public static void main(String[] args) {
String[] test = new String[] {"moo", "boo"};
System.out.println(Arrays.toString(sortMixedArray(test)));
}
I have a two-part question:
1. Is switching between array and arraylist efficient? That is, should I have used arrays everywhere instead of arraylist if my input MUST be an array.
2. What is the best way to place arraylist items back into a array? I am checking for type, is there a better way?
1.If you do it the way you have it in your code then it's perfectly fine. If you know beforehand how many elements you will have it's better to use arrays but thats not the case in your example.
2.The best and easiest way is to use the toArray() function of the List interface.
ArrayList<String> list = ...;
String[] array = list.toArray(new String[list.size()]);
But this won't work for your code since you are merging two lists into one array. You can still improve your code a bit because you do not actually have to remove the items from the lists when putting them back in the array. This safes some computation since removing the first element from an ArrayList is very inefficient (O(N) runtime per remove operation).
for (int i = 0, s = 0, n = 0; i < input.length; i++) {
if (NumberUtils.isNumber(input[i])) {
input[i] = Integer.toString(numbers.get(n++));
} else {
input[i] = strs.get(s++);
}
}
No but it highly unlikely to matter unless you have a million of elements.
Do whatever you believe is simplest and most efficient for you, the developer.
BTW the least efficient operations is remove(0) which is O(N) so you might change that.

How can I see how many values in an array are unique. As in do not equal other values in the array forward or backward?

I'm trying to see how many unique values are in an array. Unique being it does not equal any other strings in the array forward or backward. Here is what I have, But it does return the right values every time.
import java.util.ArrayList;
public class Answer {
public static int answer(String[] x) {
ArrayList<String> collectionOfCodes = new ArrayList<String>();
int arrayLength = x.length;
for (int index = 0; index < arrayLength; index++) {
if(collectionOfCodes.contains(x[index]) || collectionOfCodes.contains(x[index])) {}
else {
collectionOfCodes.add(x[index]);
}
}
return collectionOfCodes.size();
}
}
NOTE: Clarification for other readers of this question, from OP's comments to answers:
The phrase "forward or backward" does not mean earlier or later in the array, but instead refers to the string being read left-to-right and right-to-left, e.g. abcde and edcba are considered the "same" value.
Your code above is wrong, you're not checking for reverse, but you're checking twice for the same thing:
if(collectionOfCodes.contains(x[index]) || collectionOfCodes.contains(x[index])) {}
Anyways, you could create a loop and add each string in a cannonical form to a HashSet. The cannonical form could be to always use the one that comes before in a lexical comparison:
HashSet hashset = new HashSet();
for(String str : x) {
String reverse = new StringBuilder(str).reverse().toString();
hashset.add(str.compareTo(reverse) <= 0 ? str : reverse);
}
return hashset.size();

How do I make this combinations/permutations method recursive?

I have an arraylist of Strings that want to have all possible combinations stored into another collection.
For example:
[air,bus,car]
->
[air]
[bus]
[car]
[air,bus]
[air,car]
[bus,air]
[bus,car]
[car,air]
[car,bus]
[air,bus,car]
[air,car,bus]
...
[car,bus,air]
Repetitions are not important. The code right now I have is:
public ArrayList<String> comb(ArrayList<String> wrds, ArrayList<String> str, int size)
{
ArrayList<String> s = new ArrayList<String>();
s.addAll(str);
if(size != a1.size())
{
Iterator e = a1.iterator();
while(e.hasNext())
{
s.add((String)e.next());
}
size++;
}
}
I am trying to get it to recursively call itself so it can store the combinations. Can I get any help as to where or which part I am missing in my code?
Seeing as this is homework, I'll try to give you background to the answer.
The key to solving this is to use recursion.
First imagine you have two items in your array. You'd could remove the first item to give you your first combination. Adding the remaining item to the first item gives you the second combination. Removing the second item give you the third combination. Adding the remaining item gives you the forth combination. If you had ["air", "bus"] it'd be something like:
["air"]
["air", "bus"]
["bus"]
["bus", "air"]
A method that returns that might look like:
String[][] combinations(String[] strings)
The important things to note are the an array containing a single string can be passed to this method and it can return an array containing an array with a single string in it.
The problem is complicated a little because you have to keep a tally of the string combinations, so before we get to solving that, it's important that you understand recursion.
Imagine you wanted to write a multiplication method that takes two numbers and multiplies them but you only have addition and subtraction at your disposal. You could write a recursive function that adds one of the numbers to itself until the other number reaches an exit condition, something like:
public int multiply(int value1, int value2)
{
if (value1 > 1)
{
int remaining = value1 - 1;
return value2 + multiply(remaining, value2);
}
else
{
return value2;
}
}
You can do just the same thing with an array, only instead to exiting when the a value hit's 1 you exit when the array contains one item, something like:
public String[][] combinations(String[] strings)
{
if (strings.length > 1)
{
...
}
else
{
return new String[][]{strings};
}
}
For reasons with the Java API it's much easier to use java.util.List rather than arrays so you want something like:
public List<List<String>> combinations(List<String> strings)
{
if (strings.size()> 1)
{
...
}
else
{
List<List<String>> result = new ArrayList<List<String>>();
result.add(strings);
return result;
}
}
Now it's the ... that's the important bit. You need to keep an list-of-lists that will be the result and iterate over the strings. For each of the strings you can add that string to the results and then you need create a sub-list that is minus the current string, which you use to call the combinations method again iterating over the result adding the current string each list it contains. In code it looks something like:
public List<List<String>> combinations(List<String> strings)
{
if (strings.size() > 1)
{
List<List<String>> result = new ArrayList<List<String>>();
for (String str : strings)
{
List<String> subStrings = new ArrayList<String>(strings);
subStrings.remove(str);
result.add(new ArrayList<String>(Arrays.asList(str)));
for (List<String> combinations : combinations(subStrings))
{
combinations.add(str);
result.add(combinations);
}
}
return result;
}
else
{
List<List<String>> result = new ArrayList<List<String>>();
result.add(new ArrayList<String>(strings));
return result;
}
}
In summary, what you're doing is reducing the list of strings down to a single item, then combining it with the preceeding items to produce all the possible combinations as the thread returns up the call stack.
public static void combination(Object[] array){
for(int x = 0; x < (1 << array.length); x++){
System.out.print("[");
for(int y = 0; y < array.length; y++){
if(checkIsOn(x, y){
System.out.print(array[y]);
}
}
System.out.println("]");
}
}
public static boolean checkIsOn(int mast, int position){
return (mast & (1 << position) > 0);
}
Use the list as a parameter to the recursive function. You can call the function from within itself with a new list containing everything except the first item.

I want to get a specific combination of permutation?

I want to get specific combination of permutation of string like alphabet. To understand me, I'll show you the code that I using:
public class PermutationExample {
public static List<String> getPermutation(String input) {
List<String> collection = null;
if (input.length() == 1) {
collection = new ArrayList<String>();
collection.add(input);
return collection;
} else {
collection = getPermutation(input.substring(1));
Character first = input.charAt(0);
List<String> result = new ArrayList<String>();
for (String str : collection) {
for (int i = 0; i < str.length(); i++) {
String item = str.substring(0, i) + first
+ str.substring(i);
result.add(item);
}
String item = str.concat(first.toString());
result.add(item);
}
return result;
}
}
public static void main(String[] args) {
System.out.println(PermutationExample.getPermutation("ABCD"));
}
}
This code works well and i can get every combination, I can take it from the list, if I need 5-th element, I can receive it. But if the string is the alphabet ... , didn't works, it's too big. What I have to do, to get the specific element like 1221-th from all 26! combinations ?
I solved a similar problem a while ago, only in python.
If what you need is simply the n-th permutation, then you can do a lot better then generating every permutation and returning the n-th, if you try to think about generating only the permutation you need.
You can do this "simply" by figuring out what should be the element in front for the number of permutations you want, and then what should be the remaining of the elements recursively.
Assume a collection of values [0, ... ,X], for any values such that col[n] < col[n+1]
For N elements, there are N! possible permutations, the case when the collection will be perfectly reversed.
We will see the change in the head of the collection after each (N-1)! permutations, so if n < (N-1)!, the head is the head. You then have a remaining number of permutations, and you can apply the same logic recursively.
Does this help? I know it's fairly high level and you'll have to think a bit about it, but maybe it'll get you on the right track.

Categories