I've got an array of String in Java. I'd like to generate a List of String arrays that contains all the sets of String with length <=5. For example, if
String[] s1 = {"a", "b", "c", "d"}
I want the result as:
List<String[]> s2 = {{"a"}, {"b"}, {"c"}, {"d"}, {"a", "b"}, {"a", "c"}, {"a", "d"}, {"b", "c"}, {"b", "d"}, {"c", "d"}, {"a", "b", "c"}, ...}
but I can't figure out how I can generate it automatically.
You will need a K-subset algorithm implementation. I'm sure they exist in maths libraries, or you could code your own.
S1 is your set (or alphabet) and s2 is the set of subsets up to length k (5).
You have to write your own generator I guess, or use some library for permutations/combinations, there should be plenty of math libs that can do so. Example of own implementation is here:
https://codereview.stackexchange.com/questions/41510/calculate-all-possible-combinations-of-given-characters
In my opinion example in link is exactly what you need - just change input array and length. Also author puts it in one string, and I see you want to have it in array of arrays, so output also should be changed
I'll give you idea to solve this problem.
Start from an empty output string.One by one add all characters to prefix. For every character added, print all possible strings with current prefix by recursively calling for k equals to k-1.
Here K is the length in your case 1 to 5.
I used this code:
...
String[] cols = ... //linea in input
Set<String> subSet= new HashSet<String>();
Set<Set<String>> sets = new HashSet<Set<String>>();
//popolo l'insieme - escludo la data
for(int i=1; i<cols.length; i++){
subSet.add(cols[i]);
}
// creo l'insieme delle parti e popolo
sets = powerSet(subSet);
public static Set<Set<String>> powerSet(Set<String> originalSet) {
Set<Set<String>> sets = new HashSet<Set<String>>();
if (originalSet.isEmpty()) {
sets.add(new HashSet<String>());
return sets;
}
List<String> list = new ArrayList<String>(originalSet);
String head = list.get(0);
Set<String> rest = new HashSet<String>(list.subList(1, list.size()));
for (Set<String> set : powerSet(rest)) {
if(set.size() < 5){
Set<String> newSet = new HashSet<String>();
newSet.add(head);
newSet.addAll(set);
sets.add(newSet);
sets.add(set);
}
}
return sets;
}
Related
This is my CSV, first line is header, Akt (pan), Mc1-1 and etc. is content.
I need to create a function that extracts content of SearchTerm column and adds it to a List<String>.
I tried it with this piece of code but my next processing requires to have List<String> and not List<String[]>. Is there a way to do that or is there any way i can take parsed List<String[]> and make it into List<String> only containing all the search terms?
public List<String> listAllSearchTerms() throws FileNotFoundException {
CsvParserSettings settings = new CsvParserSettings();
settings.selectIndexes(0);
CsvParser parser = new CsvParser(settings);
List<String[]> allRows = parser.parseAll(new FileReader("D:\\Projects\\cstocs-test-dev-bitbucket\\cstocs-test-core\\src\\main\\resources\\data\\searchterm.csv"));
List<String> returnList = new ArrayList<>();
allRows.remove(0);
for (String[] strings : allRows) {
returnList.addAll(Arrays.asList(strings));
}
return returnList;
}
If you know which column SearchTerm is you can replace the for loop with
for (String[] strings : allRows) {
returnList.add(strings[0]); //Assumes it's the first column
}
is there any way i can take parsed List and make it into
List only containing all the search terms?
String[] strArr1 = {"a", "b", "c"};
String[] strArr2 = {"d", "e", "f"};
List<String[]> stringArrList = new ArrayList<>();
stringArrList.add(strArr1);
stringArrList.add(strArr2);
List<String> collect = stringArrList.stream()
.map(arr -> arr[0])
.collect(Collectors.toList());
System.out.println(collect);
output:
[a, d]
I want to sort an array based on another array with different values.
Consider the following:
Reference Array: {"A","B","C"}
Obtained Array1: {"C","A","B"}
Obtained Array2: {"cc","aa","bb"}
Obtained Array3: {"123","asrd","sdhg"}
values corresponding to
A -> aa and asrd
B -> bb and sdhg
C -> cc and 123
I want to sort my obtained array 1, 2 and 3 in the order specified by my reference array.
Expected Result:
Obtained Array after sorting: {"A","B","C"}
Obtained Array2 after sorting: {"aa","bb","cc"}
Obtained Array3 after sorting: {"asrd","sdhg","123"}
PS: The reference array elements order can be anything ([A,B,C] or [C,B,A] etc). Obtained arrays 2 and 3 should be sorted accordingly.
I know how to sort Obtained Array 1 in the order of my reference array. I tried a logic to sort obtained arrays 2 and 3 but the result i get is wrong
String[] referenceArray = new String[] { "A", "B", "C" };
String[] obtainedArray1 = new String[] { "C", "A", "B" };
String[] obtainedArray2 = new String[] { "cc", "aa", "bb" };
String[] obtainedArray3 = new String[] { "123", "asrd", "sdhg" };
final List<String> referenceArrayList= Arrays.asList(referenceArray);
ArrayList<String> obtainedArray1_List= new ArrayList<String>(Arrays.asList(obtainedArray1));
ArrayList<String> obtainedArray2_List= new ArrayList<String>(Arrays.asList(obtainedArray2));
ArrayList<String> obtainedArray3_List= new ArrayList<String>(Arrays.asList(obtainedArray3));
// Sorting ObtainedArray1_List - This works Fine
Collections.sort(obtainedArray1_List, Comparator.comparing(s -> referenceArrayList.indexOf(s)));
//Sorting obtainedArray2_List - Not Working
Collections.sort(obtainedArray2_List, Comparator.comparing(s -> referenceArrayList.indexOf(obtainedArray1[obtainedArray2_List.indexOf(s)])));
The result of obtainedArray2_List after sorting: ["aa","cc","bb"]
Expected Result is ["aa","bb","cc"]
As JB Nizet already said, you're making your life complicated. You have three separate arrays, while their contents are related. You're saying that A, aa and asrd belong together, as well as B, bb and sdhg, and C, cc and 123.
These can be thought of three properties of a single object. That's the point of object-orientation. You should define a class which represents these three properties:
public class Holder {
private String letter;
private String lower;
private String text;
public Holder(String letter, String lower, String text) {
this.letter = letter;
this.lower = lower;
this.text = text;
}
public String getLetter() {
return this.letter;
}
#Override
public String toString() {
return String.format("Holder(letter=%s, lower=%s, text=%s)",
this.letter, this.lower, this.text);
}
}
Your three arrays should never exist in the first place, but instead being an array or collection with Holder objects. For convenience, here is a transformation to a List<Holder>.
List<Holder> holders = IntStream.range(0, obtainedArray1.length)
.mapToObj(i -> new Holder(obtainedArray1[i], obtainedArray2[i], obtainedArray3[i]))
.collect(Collectors.toList());
Now you can simply sort collect a new, sorted list, instead of three separate sorted arrays.
List<String> referenceList = Arrays.asList("A", "B", "C");
List<Holder> sorted = holders.stream()
.sorted(Comparator.comparing(t -> referenceList.indexOf(t.letter)))
.collect(Collectors.toList());
I have names in an array of Strings:
["foo", "bar", "baz"]
I want to transform it to be:
["foo", "foo", "bar", "bar", "baz", "baz"]
My current solution:
String[] ns = new String[2 * names.length];
int i = 0;
for (String name : names)
{
ns[i++] = name;
ns[i++] = name;
}
Is there a cleaner solution? In particular, I think the duplicated assignment is poorly done.
Assuming you are using Java 8+, you could use a Stream - flatMap every element to a two element stream and then collect to a List before converting back to an array. Like,
String[] names = { "foo", "bar", "baz" };
String[] ns = Stream.of(names).flatMap(s -> Stream.of(s, s))
.collect(Collectors.toList()).toArray(new String[] {});
A bit cleaner, perhaps:
String[] ns = new String[2 * names.length];
for (int i = 0; i < ns.length; i++)
ns[i] = names[i / 2];
I'm new to Java, and I had a quick question.
I have an array named studentInfo[0] that I created from:String studentInfo[] = line.split(","); I would like to make another array from it's first index.
In other words. I have the array studentInfo that lets say looks like this:
"a,b,c,d,
a1,b1,c1,d1,
a2,b2,d2,c2 etc... "
I want another array that takes all the "a" in my other array. Example: "a,a1,a2 etc..."
How would I do this?
I have tried System.arraycopy(studentInfo, 0, array, 0, studentInfo.length); But doesn't seem to work because it does not just give me the first index.
FYI my code is in a while loop which loops every time it hits a new line. See below:
while ((line = reader.readLine()) != null) {
String studentInfo[] = line.split(",");
String array[] = new String[0];
}
Thank you!
I would do something like.
String[] studentInfoA = new String[50] //You can put the size you want.
for(int i=0; i<studentInfo.length-1; i++){
if(studentInfo[i].substring(0,1).equals("a")){
studentInfoA[i]=studentInfo[i];
}
}
i would recommend Vimsha's answer better but since you are learning i didnt want to make you struggle with collections and such, or at least i wouldnt like you to use them without properly knowing about arrays and loops.
Assuming you have this array,
studentInfo = ["a","b","c","d","a1","b1","c1","d1", "a2","b2","d2","c2"]
and you want another array like
studentInfoWithA = ["a", "a1", "a2"]
then
String studentInfo[] = new String[] { "a", "b", "c", "d", "a1", "b1", "c1", "d1", "a2", "b2", "d2", "c2" };
List<String> newList = new ArrayList<String>();
for (String info : studentInfo) {
if (info.startsWith("a")) {
newList.add(info);
}
}
String[] studentInfoWithA = newList.toArray(new String[0]);
In java 1.8, filtering looks like
String[] result = Arrays.stream(new String[] { "a","b","c","d","a1","b1","c1","d1", "a2","b2","d2","c2" })
.filter(e -> e.startsWith("a"))
.toArray(String[]::new);
Say I have two arrays, e.g. [B,D,C,A] and [B,A,D,C]. What mechanism would generate the same checksum on both arrays (and any array containing a permutation of their elements)?
In the following example, check_a and check_b will not be equal. Putting the elements into an alphabetical order is not an option, as the objects in the array might not be Strings or anything sortable at all.
String[] a = {"B","D","C","A"};
String[] b = {"B","A","D","C"};
String check_a = a.hashCode();
String check_b = b.hashCode();
Quick example
public class ArrayHash {
public static void main(String[] args) {
String[] one = new String[]{"A", "B", "C", "D"};
String[] two = new String[]{"D", "C", "B", "A"};
System.out.println("One = " + one.hashCode());
System.out.println("Two = " + two.hashCode());
System.out.println("Method for one = "+hash(one));
System.out.println("Method for two = "+hash(two));
}
private static int hash(Object[] array) {
int ret = 0;
for (Object c : array) {
ret += (124567890 + c.hashCode()) * c.hashCode();
}
return ret;
}
}
it gives an output
One = 366712642
Two = 1829164700
Method for one = 266
Method for two = 266
as you can see, you have to iterate over all elements and sum (or multiply) their hashes. that will give you same result no matter in what order they are.
Lets suppose you have a function that get checksumm of elements. To get checksum you want you need to find operation with Commutative property there are lot of them. For example +, *, ^