Java pairing names from array - java

So I am trying to create small Java program where names from array are paired. But I don't know how to proceed. I have array with names and the object is to pair two names randomly to make a team. There should be some statement so certain pairs couldn't be made: Miller & James can't be in the same team and no dublicates. How do I do this?
Example output:
James & Hal
import java.util.Random;
public class Teams {
public static void main (String [] args) {
String [] arr = {"John", "James", "George", "Miller", "Hal", "Dan"};
Random random = new Random();
int select = random.nextInt(arr.length);
int selectSecond = random.nextInt(arr.length);
System.out.println(arr[select]);
System.out.println(arr[selectSecond]);
}
}

You can delete the first chosen name from the array and then choose again to get the second one. To delete an element from an array see Removing an element from an Array (Java). Here is one possible implementation (but I didn't test it):
public static void main (String [] args) {
String [] arr = {"John", "James", "George", "Miller", "Hal", "Dan"};
Random random = new Random();
int select = random.nextInt(arr.length);
arr = removeElements(arr, arr[select]);
int selectSecond = random.nextInt(arr.length);
System.out.println(arr[select]);
System.out.println(arr[selectSecond]);
}
// import java.util.LinkedList;
public static String[] removeElements(String[] input, String deleteMe) {
List result = new LinkedList();
for(String item : input)
if(!deleteMe.equals(item))
result.add(item);
return (String[]) result.toArray(input);
}

I would like to use Collections.shuffle instead, and a do while loop like so :
String[] arr = {"John", "James", "George", "Miller", "Hal", "Dan"};
List<String> list = Arrays.asList(arr);
String name1, name2;
do {
Collections.shuffle(list);
name1 = list.get(0);
name2 = list.get(1);
} while ((name2.equals("Miller") && name1.equals("James"))
|| (name1.equals("James") && name2.equals("Miller")));
System.out.println(String.format("%s & %s", name1, name2));
With this solution you don't need to check if the both names are same or not, you just need to check if the two name not equals in the same pair to Miller and James

It will depend which perspective you want to attack here. If you just want to "do the job", you have an extensive list of possibilities (as we already have here), but I would just take care with readability:
public class Teams {
private static String[][] teamsToAvoid = {{"James", "Miller"}, {"John", "Hal"}};
private static String[][] teamsFormed = new String[3][2];
public static void main(String[] args){
String[] names = {"John", "James", "George", "Miller", "Hal", "Dan"};
List<String> namesList = new ArrayList<>(Arrays.asList(names));
Collections.shuffle(namesList);
do {
formTeam(namesList, 0, 1);
} while(namesList != null && !namesList.isEmpty());
for(String[] team : teamsFormed){
System.out.println("Team: {" + team[0] + ", " + team[1] + "}");
}
}
private static void formTeam(List<String> namesList, int firstPlayerIndex, int secondPlayerIndex) {
if(isTeamPossible(namesList.get(firstPlayerIndex), namesList.get(secondPlayerIndex))){
String firstPlayer = namesList.get(firstPlayerIndex);
String secondPlayer = namesList.get(secondPlayerIndex);
teamsFormed[getFormedTeamNextIndex()] = new String[]{firstPlayer, secondPlayer};
namesList.remove(namesList.indexOf(firstPlayer));
namesList.remove(namesList.indexOf(secondPlayer));
} else {
formTeam(namesList, firstPlayerIndex, ++secondPlayerIndex);
}
}
private static boolean isTeamPossible(String player1, String player2) {
for(String[] teamToAvoid : teamsToAvoid){
if(Arrays.asList(teamToAvoid).contains(player1) && Arrays.asList(teamToAvoid).contains(player2)){
return false;
}
}
return true;
}
private static int getFormedTeamNextIndex() {
for(int i = 0; i < teamsFormed.length; i++){
if(teamsFormed[i][0] == null && teamsFormed[i][1] == null)
return i;
}
return 0;
}
}
Doing this you will prevent the same pair in different order and remove those players from the list (preventing their reuse).
I would pay attention when removing from list directly by index also, because when you remove one item the index for items after that one change.

Related

Remove elements from String array using another String array Java

I am trying to remove elements from String A using an array of String B.
My logic is to convert the string A to an array and then check if A contains the same elements as B and write that data to an empty String, but it doesn't work if B has two or more elements.
Can you tell me what I'm doing wrong?
class Test {
public static void main(String[] args) {
WordDeleter wordDeleter = new WordDeleter();
// Hello
System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" }));
// The Athens in
System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" }));
// This cat
System.out.println(wordDeleter.remove("This is cat", new String[] { "is" }));
}
}
class WordDeleter {
public String remove(String phrase, String[] words) {
String[] arrayPhrase = phrase.split(" ");
String result = "";
for (int i = 0; i < arrayPhrase.length; i++) {
for (int j = 0; j < words.length; j++) {
if (!arrayPhrase[i].equalsIgnoreCase(words[j]))
result += arrayPhrase[i] + " ";
}
}
return result.trim();
}
}
Output is:
Hello
The The Athens Athens is in in Greece
This cat
You're close but you need to use the helpful .contains() method. This should work for the multi-length set of words. Your nested for loop checked for both words, thus the copying. Also the not-allowed words were only written once, so it infact "worked" but not the way you intended.
class Test {
public static void main(String[] args) {
WordDeleter wordDeleter = new WordDeleter();
// Hello
System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" }));
// The Athens in
System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" }));
// This cat
System.out.println(wordDeleter.remove("This is cat", new String[] { "is" }));
}
}
class WordDeleter {
public String remove(String phrase, String[] wordsArray) {
List<String> words = Arrays.asList(wordsArray);
String[] arrayPhrase = phrase.split(" ");
String result = "";
for (int i = 0; i < arrayPhrase.length; i++) {
// If the word is not contained in the not allowed array
if(!words.contains(arrayPhrase[i])){
result += arrayPhrase[i] + " ";
}
}
return result.trim();
}
}
Another thing you can do to make it better is use StringBuilder.
Instead of String result = "", use StringBuilder result = new StringBuilder(). And instead of result +=arrayPhrase[i] + " "; use result.append(arrayPhrase[i] + " "); as so:
class Test {
public static void main(String[] args) {
WordDeleter wordDeleter = new WordDeleter();
// Hello
System.out.println(wordDeleter.remove("Hello Java", new String[] { "Java" }));
// The Athens in
System.out.println(wordDeleter.remove("The Athens is in Greece", new String[] { "is", "Greece" }));
// This cat
System.out.println(wordDeleter.remove("This is cat", new String[] { "is" }));
}
}
class WordDeleter {
public String remove(String phrase, String[] words) {
String[] arrayPhrase = phrase.split(" ");
StringBuilder result = new StringBuilder();
for (int i = 0; i < arrayPhrase.length; i++) {
// If the word is not contained in the not allowed array
if(!words.contains(arrayPhrase[i])){
result.append(arrayPhrase[i] + " ");
}
}
return result.toString().trim();
}
}
The most efficient way to remove all occurrences of strings contained in the given array from the given string is to generate a HashSet from the given array and check for every word in the given string, whether it's present in the set or not.
To avoid overheads of string concatenation, we can use StringJoiner.
That's how it can be implemented.
public static String remove(String phrase, String[] words) {
String[] arrayPhrase = phrase.split(" ");
Set<String> wordsToRemove = Arrays.stream(words).collect(Collectors.toSet());
StringJoiner result = new StringJoiner(" ");
for (String word: arrayPhrase) {
if (!wordsToRemove.contains(word)) {
result.add(word);
}
}
return result.toString();
}
And that's how it can be implemented with streams using collector joining():
public static String remove(String phrase, String[] words) {
Set<String> wordsToRemove = Arrays.stream(words).collect(Collectors.toSet());
return Arrays.stream(phrase.split(" "))
.filter(word -> !wordsToRemove.contains(word))
.collect(Collectors.joining(" "));
}
A link to Online Demo

How to merge two string arrays with no duplicates? [duplicate]

This question already has answers here:
Merge two arrays and remove duplicates in Java
(7 answers)
Closed 1 year ago.
I was able to get the two arrays to sort and merge but I can not figure out how to remove the duplicates. Can someone please help me with this? Here is my code so far:
public class FinalArray {
public static void main(String[] args) {
String[] testArray1 = {"coffee", "tea", "water"};
String[] testArray2 = {"lemonade", "juice", "water"};
mergeUniqueValues(testArray1, testArray2);
}
public static void mergeUniqueValues(String[] arr1, String[] arr2) {
String[] arr3 = new String[arr1.length + arr2.length];
for (int i = 0; i < arr1.length; i++) {
arr3[i] = arr1[i];
}
for (int i = arr1.length, index = 0; i < arr1.length + arr2.length; i++, index++) {
arr3[i] = arr2[index];
}
Arrays.sort(arr3);
System.out.println("Your sorted array is: ");
for (String str : arr3) {
System.out.println(str);
}
}
}
Property of Set: It does not allow duplicates.
You can simply convert the array to Set (to avoid duplicates) and then convert it back to an array.
Here is a sample code for your reference:
public class Main {
public static void main(String[] args) {
String[] testArray1 = {"coffee", "tea", "water"};
String[] testArray2 = {"lemonade", "juice", "water"};
mergeUniqueValues(testArray1, testArray2);
}
public static void mergeUniqueValues(String[] arr1, String[] arr2) {
Set noDuplicateSet = new HashSet();
noDuplicateSet.addAll(Arrays.asList(arr1));
noDuplicateSet.addAll(Arrays.asList(arr2));
String[] noDuplicateArray = new String[noDuplicateSet.size()];
noDuplicateSet.toArray(noDuplicateArray);
Arrays.sort(noDuplicateArray);
System.out.println("Your sorted array is: ");
for (String str : noDuplicateArray) {
System.out.println(str);
}
}
}
Output:
Your sorted array is:
coffee
juice
lemonade
tea
water
You can use Java Streams and distinct().
String[] result =
Stream.concat( // combine
Stream.of(array1),
Stream.of(array1))
.distinct() // filter duplicates
.sorted() // sort
.toArray(String[]::new);
You can take advantage from the java.util.TreeSet class, which is a collection which implements java.util.Set, and made of all unique values ordered by the natural order of the given elements. In your case, String does implement Comparable, so it can be naturally ordered when the element are inserted in the collection.
Here is the code you can test:
import java.util.*;
public class MergeArray {
public static void main(String[] args) {
String[] testArray1 = { "coffee", "tea", "water" };
String[] testArray2 = { "lemonade", "juice", "water" };
mergeUniqueValues(testArray1, testArray2);
}
public static void mergeUniqueValues(String[] arr1, String[] arr2) {
Set<String> mergedList = new TreeSet(Arrays.asList(arr1));
mergedList.addAll(Arrays.asList(arr2));
String[] arr3 = mergedList.toArray(String[]::new);
System.out.println("Your sorted array is: ");
for (String str : arr3) {
System.out.println(str);
}
}
}
And here is the output:
Your sorted array is:
coffee
juice
lemonade
tea
water
You can use Java Stream:
String[] testArray1 = {"coffee", "tea", "water"};
String[] testArray2 = {"lemonade", "juice", "water"};
String[] testArray3 = Stream.of(testArray1, testArray2)
.flatMap(Arrays::stream).distinct().sorted().toArray(String[]::new);
Arrays.stream(testArray3).forEach(System.out::println);
//coffee
//juice
//lemonade
//tea
//water

comparing two String Arrays without knowing which one contains more values

I have to compare the values of two String Arrays in Java and save the different String.
I already know how to compare String Arrays with the same size.
But the problem is, that the count of values of these String Arrays is unknown in the beginning. So, it's unclear which String Array is larger.
So I have to handle following scenarios:
Scenario 1 (same size and no difference):
String[] test = {Test1, Test2, Test3}
String[] test2 = {Test1, Test2, Test3}
Scenario 2 (same size, but difference):
String[] test = {Test1, Test2, Test3}
String[] test2 = {Test1, Test2, Test4}
Scenario 3 (different size - first String Array contains more values, than second one):
String[] test = {Test1, Test2, Test3}
String[] test2 = {Test1, Test2}
Scenario 4 (different size - second String Array contains more values, than first one):
String[] test = {Test1, Test2}
String[] test2 = {Test1, Test2, Test3}
Implementation Scenario 1:
for(int i = 0; i < test.length; i++){
if(! ( Arrays.asList(test).contains(test2[i]) ) ) {
} else {
System.out.println("Scenario 1");
}
}
Implementation Scenario 2:
ArrayList<String> compare_String = new ArrayList<>();
for(int i = 0; i < test.length; i++){
if(! ( Arrays.asList(test).contains(test2[i]) ) ) {
compare_String.add(test2[i]);
System.out.println("Scenario2");
} else {
System.out.println("Scenario 1");
}
} System.out.println(compare_String);
But how to handle Scenario 3 and 4 if you don't know whether the first String Array contains more elements than the second one, or the second String Array contains more elements than the first one?
Many Thanks.
Update:
thanks a lot for your answers. This works for me:
ArrayList<String> difference = new ArrayList<>();
int j = 0;
if (test > test2) {
try {
for (int i = 0; i < test; i++) {
if (!(Arrays.asList(test2).contains(test1[i]))) {
difference.add(test[i]);
}
j++;
}
} catch (ArrayIndexOutOfBoundsException ar) {
difference.add(test[j]);
}
I have implement compareArrays method to handle your scenario try like following this may solve your problem
public class Test
{
public static void main(String[] args){
compareArrays(new String[]{"Test1", "Test2", "Test3"},new String[]{"Test1", "Test2", "Test3"});
compareArrays(new String[]{"Test1", "Test2", "Test3"},new String[]{"Test1", "Test2", "Test4"});
compareArrays(new String[]{"Test1", "Test2", "Test3"},new String[]{"Test1", "Test2"});
compareArrays(new String[]{"Test1", "Test2"},new String[]{"Test1", "Test2", "Test3"});
}
private static void compareArrays(String[] test,String[] test2){
if(test.length > test2.length){
System.out.println("Scenario 3");
}
else if(test2.length > test.length){
System.out.println("Scenario 4");
}
else {
boolean same = true;
for (int a=0;a<test.length;a++){
if(!test[a].equalsIgnoreCase(test2[a])){
same = false;
}
}
if (same){
System.out.println("Scenario 1");
}
else {
System.out.println("Scenario 2");
}
}
}
}
Use a boolean array to keep track of repeated Strings, and simply check all elements of one array to see if the other contains it. The unused Strings of the second array are also missing on the first, so you can put them on the difference, regardless of array sizes.
String[] array1;
String[] array2;
ArrayList<String> diff = compare_arrays(array1, array2);
public ArrayList<String> compare_arrays(String[] a1, String[] a2){
ArrayList<String> diff = new ArrayList<String>();
boolean[] rep = new boolean[a2.length];
Arrays.fill(a2, false);
for(String str : a1){
if(!Arrays.asList(a2).contains(str)){
diff.add(str);
}
else{
rep[Arrays.asList(a2).indexOf(str)] = true;
}
}
for(int i = 0; i < a2.length; i++){
if(!rep[i]){
diff.add(a2[i]);
}
}
}

combine two array string to make a list

I am working on my own personal app for minecraft. I would forget what recipe I need, and I would just search, and have it display the recipe.
Now, I have the list and search function with it being alphabetical. Now I am manually adding images, and everything else I need. BUT I think it would be more efficient if I had a array string like this
String test1[] = { "diamond", "Iron", "Leather" };
String test2[] = { "Leggings", "Boots", "Helmet", "Chestplate" }
and in my list view I want the end result to be like this.
Diamond leggings
Diamond boots
Diamond Helmet
Diamond Chestplate
Iron Leggings
...
...
Gold Leggings
...
...
...
What would I need to do to achieve that? I think it would be ineffecient if I did it like this
test3.add("Diamond Chestplate")
test3.add("Diamond boots")
etc..
..
...
and end up having big list instead where I can combine them.
Use 2 nested for loops to merge the arrays:
String test1[] = {"Diamond", "Iron", "Leather"};
String test2[] = {"Leggings", "Boots", "Helmet", "Chestplate"};
List<String> merged = new ArrayList<String>();
for (String str1 : test1) {
for (String str2 : test2)
merged.add(str1 + " " + str2);
}
System.out.println(merged);
If I understand your question, you could do with nested For-Each Loop(s) like
String test1[] = { "Diamond", "Iron", "Leather" };
String test2[] = { "Leggings", "Boots", "Helmet", "Chestplate" };
List<String> al = new ArrayList<>();
for (String i : test1) {
for (String j : test2) {
StringBuilder sb = new StringBuilder(i);
sb.append(' ').append(j);
al.add(sb.toString());
}
}
System.out.println(al);
I am curious to know that If, I can achieve it in a single loop.
How to do it, and finally I have done it.
private static String test1[] = {"Diamond", "Iron", "Leather"};
private static String test2[] = {"Leggings", "Boots", "Helmet", "Chestplate"};
public static void doInSingleLoop() {
int maxLength = test1.length * test2.length;
List<String> al = new ArrayList<String>();
for (int i = 0; i < maxLength; i++) {
String t1 = test1[i / test2.length];
String t2 = test2[i % test2.length];
StringBuilder sb = new StringBuilder(t1);
sb.append(' ').append(t2);
al.add(sb.toString());
}
System.out.println(al);
}
Check below example.
public static void main(String[] args) {
String firstNameArr[] = { "diamond", "Iron", "Leather" };
String lastNameArr[] = { "Leggings", "Boots", "Helmet"};
List<String> fullNameList = new ArrayList<String>();
for (String firstname : firstNameArr) {
for(String lastName : lastNameArr){
fullNameList.add((firstname+" "+lastName));
}
}
}

find duplicate words in java array and return array with unique duplicate words - use method

I am new to java, and am confused with the problem.
This is what I came up so far.
I am still working on it, if I come up with any progress, I'll post it here.
public class charArray {
public static void main(String[] args) {
String[] strArray = new String[] {"apple", "ball", "cat", "apple", "ball", "apple"};
//output should be ["apple", "ball"]
checkDuplicate(strArray);
}
public static String[] checkDuplicate(String[] strArray){
String[] newArray = new String[]{};
for(int i = 0; i < strArray.length; i++){
for(int j = 0; j < i; j++){
if (strArray[i].equals(srtArray[j])){
newArray = strArray[i];
}
}
}
return newArray[];
}
}
New progress:
Ok, my mediocre head has gone this far: (and the solution works)
It prints out the unique array of Duplicate elements.
But now I need to implement the same code, by calling a method.
Any help is appreciated.
import java.util.*;
public class setChar {
public static void main(String[] args) {
String[] strArray = new String[] {"apple", "ball", "cat", "apple", "ball", "apple"};
Set set = new HashSet();
Set uniqueSet = new HashSet();
for(int i = 0; i < strArray.length ; i++ ){
boolean b = set.add(strArray[i]);
if(b == false){
uniqueSet.add(strArray[i]);
}
}
Iterator it = uniqueSet.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
The output is:
ball
apple
Finally implemented with method, with proper return type.
Please let me know, if this can be further optimized.
Thank all for you suggestions. Here is the working code:
public class retUnique {
public static void main(String[] args) {
String[] strArray = new String[] {"apple", "ball", "cat", "apple", "ball", "apple"};
System.out.println(printUnique(strArray));
}
public static Set<String> printUnique(String[] strArray){
Set<String> set = new HashSet<String>();
Set<String> uniqueSet = new HashSet<String>();
for(int i = 0; i < strArray.length ; i++ ){
boolean b = set.add(strArray[i]);
if(b == false){
uniqueSet.add(strArray[i]);
}
}
return(uniqueSet);
}
}
One easy option is to use a Set like container instead of an array. It will automatically ensure that only unique values are present.
You can look at examples of TreeSet and HashSet.
Something like this should work I believe. Been a while since I coded in Java so if anyone wants to make edits, please do.
public String[] returnDups(String[] strArray) {
Set<String> set = new HashSet<String>(strArray);
return set.toArray(new String[0]);
}
But what everyone has been suggesting is the correct idea. Sets make it really easy to remove duplicates so you should utilize them. Let's not reinvent the wheel.
To detect dupplicates, if that is your question, add all elememts of the array to a Set, if set.add() returns false, then it is a dupplicate, so you can add this elemen to your result list of dupplictes.
Or if your question is meaning to return the values without duplicates, then you can retirnthe set, or convert the set to list before returning.

Categories