Compare arraylists for non identical elements - java

Hello there I am being confused in comparing two array lists, one of my array list is as:
private ArrayList<String> members = new ArrayList<>();
members.add("member123keyxyzmember123 number");
members.add("member456keyxyzmember456 number");
members.add("member789keyxyzmember789 number");
members.add("member2233keyxyzmember2233 number");
members.add("member1122keyxyzmember1122 number");
The second arraylist is as:
private ArrayList<String> syncMembers = new ArrayList<>();
syncMembers.add("member123keyxyz123statuskeyxyz123photokeyxyzmember123 number");
syncMembers.add("member456keyxyz456statuskeyxyz456photokeyxyzmember456 number");
The problem is that I am comparing both so that they give me the numbers that are in members list and are not in syncMembers list!
That is the out put should be:
member789 number
member2233 number
member1122 number
only!
What I have been trying is:
for (int i = 0; i < members.size(); i++) {
String stringFromMembersList = members.get(i);
String[] memberParts = stringFromMembersList.split("keyxyz");
String memberNumber = memberParts[1];
//Log.e("hgax", "sync:::" + memberNumber);
for (int j = 0; j < syncMembers.size(); j++) {
String stringFromSyncList = syncMembers.get(j);
String[] syncParts = stringFromSyncList.split("keyxyz");
String n = syncParts[3];
if (memberNumber.equals(n)) {
//Log.e("hgax", "hee:::" + n);
break;
} else {
Log.e("hgax", "ssshee:::" + memberNumber);
}
}
}
The output I am getting is:
member456 number
member789 number
member789 number
member2233 number
member2233 number
member2233 number
member1122 number
member1122 number
member1122 number
member1122 number
I am bit confuse what is happeing to me and What i have been doing wrong? Can somebody please tell what blunder I am doing Thanks in advance

Try to think about what you need to check to reach your goal. In order to determine that a member in the list members does not exist in syncMembers you have to check the entirety of the syncMembers list for that member. Since the lists are not identical (as your question states), you cannot use Collection.contains(Object o).
This should achieve your goal:
// We need this initial check as if syncMembers is empty it'll display all members
// And why bother to do this if syncMembers is empty anyway!
if (!syncMembers.isEmpty()) {
for (String member : members) {
String memberNo = member.split("keyxyz")[1];
int i = 0;
boolean found = false;
while (!found && i < syncMembers.size()) {
// Iterate over syncMembers until a match if found
// or we have exhausted the list
found = syncMembers.get(i).split("keyxyz")[3].equals(memberNo);
i++;
}
if (!found) {
// Display only if not found
System.out.println(memberNo);
}
}
}

Edit: updated answer to include the original mixed values in the arrayList
ArrayList<String> membersList = new ArrayList<>();
ArrayList<String> syncMembersList = new ArrayList<>();
for (int i = 0; i < members.size(); i++) {
String s = members.get(i).substring(members.get(i).lastIndexOf("member"));
membersList.add(s);
}
for (int j = 0; j < syncMembers.size(); j++) {
String s = syncMembers.get(j).substring(syncMembers.get(j).lastIndexOf("member"));
syncMembersList.add(s);
}
for (int i = 0; i < membersList.size(); i++) {
if (!syncMembersList.contains(membersList.get(i))) {
System.out.println(membersList.get(i));
}
}
This will print the output you require.

Related

Scanner input values are not all being stored

I have a scanner which reads in strings as coordinate inputs. I have to convert these strings into integers and store them in an Arraylist of coordinates but the last values I input are not being stored in the arraylist.
I have tried using the startEndLineScan.nextLine(); outside the for-loop but still no change I have also tried using a while loop instead of a for loop when storing and parsing the strings but I get the same results.
ArrayList<Integer> convertedCoords = new ArrayList<Integer>();
String samplePointsCoords[];
Scanner startEndLineScan = new Scanner(System.in);
int count = 1;
while (startEndLineScan.hasNextLine()) {
startEndPointsInputs = startEndLineScan.nextLine();
samplePointsCoords = startEndPointsInputs.split(",");
if (count < 2) {
for (int i = 0; i < samplePointsCoords.length; ++i) {
convertedCoords.add(Integer.parseInt(samplePointsCoords[i]));
}
count++;
} else {
break;
}
}
System.out.print("Points: " + convertedCoords)
Input:
1,2
3,4
Expected results:
Points: [1,2,3,4]
Actual Results
Points: [1,2]
ArrayList<Integer> convertedCoords = new ArrayList<Integer>();
String samplePointsCoords[];
Scanner startEndLineScan = new Scanner(System.in);
int count;
while (startEndLineScan.hasNextLine()) {
count = 1;
startEndPointsInputs = startEndLineScan.nextLine();
samplePointsCoords = startEndPointsInputs.split(",");
if (count < 2) {
for (int i = 0; i < samplePointsCoords.length; ++i) {
convertedCoords.add(Integer.parseInt(samplePointsCoords[i]));
}
count++;
} else {
break;
}
}
System.out.print("Points: " + convertedCoords)
Notice int count; is declared and reinitialized at the start of every loop
This will fix your code but you should really try to understand what you are writing! cheers.

chatBot conversations challenge, is my code inefficient? Failing hidden test cases

Edit: This is a code challenge. I actually just ran it again and it was more specific that the code is innificient. See here and here.
I can't figure out what exactly is wrong with my code. It passes all the visible test cases but fails 4/5 the hidden test cases.
The challenge is to try to predict the next words of a given conversation (currentConversation) using a history of previous conversations (conversations). If a historical conversation has words matching the currentConversation, append the rest of the historical conversation to the currentConversation.
This is my code in Java:
public String[] chatBot(String[][] conversations, String[] currentConversation) {
int hmNumOfMatches = 0; // highest matched conversation's similar words to the current conversation
ArrayList<String> hmRestOfWords = new ArrayList<>(); // the rest of the words in the matched conversation
// for all given conversations
for (String[] pc : conversations) {
int numOfMatches = 0;
int indexOfLastMatchingWord = -1;
HashSet<String> uw = new HashSet<String>(); // stores the unique words in pc (possible conversation)
// for all words of possible conversation
for (int j = 0; j < pc.length; j++) {
String pw = pc[j]; // possible word
// exclude words that have already been accounted for
if (!uw.contains(pw)) {
// for all words in the current conversation
for (int i = 0; i < currentConversation.length; i++) {
String w = currentConversation[i];
if (w.compareTo(pw) == 0) {
numOfMatches++;
indexOfLastMatchingWord = j;
}
}
uw.add(pw);
}
}
ArrayList<String> restOfWords = new ArrayList<>();
// if there were matching words
if (indexOfLastMatchingWord != -1)
restOfWords = getRestOfWords(pc, indexOfLastMatchingWord);
else continue;
// set the highest number of matches if it has none
if (hmNumOfMatches == 0) {
hmNumOfMatches = numOfMatches;
hmRestOfWords.addAll(restOfWords);
}
// also update it if it's less then the current number of matches
if (hmNumOfMatches < numOfMatches) {
hmNumOfMatches = numOfMatches;
hmRestOfWords = restOfWords;
}
}
/**
* Create the answer
*/
String[] answer = new String[currentConversation.length + hmRestOfWords.size()];
int i;
// append the current conversation to the answer
for (i = 0; i < currentConversation.length; i++) {
answer[i] = currentConversation[i];
}
// and append the rest of the words from the matched historical conversation
for (int j = 0; j < hmRestOfWords.size(); j++) {
answer[i + j] = hmRestOfWords.get(j);
}
return answer;
}
public ArrayList<String> getRestOfWords(String[] pc, int indexOfLastMatchingWord) {
ArrayList<String> restOfWords = new ArrayList<String>();
for (int i = indexOfLastMatchingWord + 1; i < pc.length; i++) {
if (!restOfWords.contains(pc[i])) restOfWords.add(pc[i]);
}
return restOfWords;
}

sub arraylist's size isn't correct

After hard searchig I still haven't found the proper answer for my question and there is it:
I have to write a java program that enters an array of strings and finds in it the largest sequence of equal elements. If several sequences have the same longest length, the program should print the leftmost of them. The input strings are given as a single line, separated by a space.
For example:
if the input is: "hi yes yes yes bye",
the output should be: "yes yes yes".
And there is my source code:
public static void main(String[] args) {
System.out.println("Please enter a sequence of strings separated by spaces:");
Scanner inputStringScanner = new Scanner(System.in);
String[] strings = inputStringScanner.nextLine().split(" ");
System.out.println(String.join(" ", strings));
ArrayList<ArrayList<String>> stringsSequencesCollection = new ArrayList<ArrayList<String>>();
ArrayList<String> stringsSequences = new ArrayList<String>();
stringsSequences.add(strings[0]);
for (int i = 1; i < strings.length; i++) {
if(strings[i].equals(strings[i - 1])) {
stringsSequences.add(strings[i]);
} else {
System.out.println(stringsSequences + " " + stringsSequences.size());
stringsSequencesCollection.add(stringsSequences);
stringsSequences.clear();
stringsSequences.add(strings[i]);
//ystem.out.println("\n" + stringsSequences);
}
if(i == strings.length - 1) {
stringsSequencesCollection.add(stringsSequences);
stringsSequences.clear();
System.out.println(stringsSequences + " " + stringsSequences.size());
}
}
System.out.println(stringsSequencesCollection.size());
System.out.println(stringsSequencesCollection.get(2).size());
System.out.println();
int maximalStringSequence = Integer.MIN_VALUE;
int index = 0;
ArrayList<String> currentStringSequence = new ArrayList<String>();
for (int i = 0; i < stringsSequencesCollection.size(); i++) {
currentStringSequence = stringsSequencesCollection.get(i);
System.out.println(stringsSequencesCollection.get(i).size());
if (stringsSequencesCollection.get(i).size() > maximalStringSequence) {
maximalStringSequence = stringsSequencesCollection.get(i).size();
index = i;
//System.out.println("\n" + index);
}
}
System.out.println(String.join(" ", stringsSequencesCollection.get(index)));
I think it should be work correct but there is a problem - the sub array list's count isn't correct: All the sub arrayList's size is 1 and for this reason the output is not correct. I don't understand what is the reason for this. If anybody can help me to fix the code I will be gratefull!
I think it is fairly straight forward just keep track of a max sequence length as you go through the array building sequences.
String input = "hi yes yes yes bye";
String sa[] = input.split(" ");
int maxseqlen = 1;
String last_sample = sa[0];
String longest_seq = last_sample;
int seqlen = 1;
String seq = last_sample;
for (int i = 1; i < sa.length; i++) {
String sample = sa[i];
if (sample.equals(last_sample)) {
seqlen++;
seq += " " + sample;
if (seqlen > maxseqlen) {
longest_seq = seq;
maxseqlen = seqlen;
}
} else {
seqlen = 1;
seq = sample;
}
last_sample = sample;
}
System.out.println("longest_seq = " + longest_seq);
Lots of issues.
First of all, when dealing with the last string of the list you are not actually printing it before clearing it. Should be:
if(i == strings.length - 1)
//...
System.out.println(stringsSequences + " " + stringsSequences.size());
stringsSequences.clear();
This is the error in the output.
Secondly, and most importantly, when you do stringsSequencesCollection.add you are adding an OBJECT, i.e. a reference to the collection. When after you do stringsSequences.clear(), you empty the collection you just added too (this is because it's not making a copy, but keeping a reference!). You can verify this by printing stringsSequencesCollection after the first loop finishes: it will contain 3 empty lists.
So how do we do this? First of all, we need a more appropriate data structure. We are going to use a Map that, for each string, contains the length of its longest sequence. Since we want to manage ties too, we'll also have another map that for each string stores the leftmost ending position of the longest sequence:
Map<String, Integer> lengths= new HashMap<>();
Map<String, Integer> indexes= new HashMap<>();
String[] split = input.split(" ");
lengths.put(split[0], 1);
indexes.put(split[0], 0);
int currentLength = 1;
int maxLength = 1;
for (int i = 1; i<split.length; i++) {
String s = split[i];
if (s.equals(split[i-1])) {
currentLength++;
}
else {
currentLength = 1;
}
int oldLength = lengths.getOrDefault(s, 0);
if (currentLength > oldLength) {
lengths.put(s, currentLength);
indexes.put(s, i);
}
maxLength = Math.max(maxLength, currentLength);
}
//At this point, youll have in lengths a map from string -> maxSeqLengt, and in indexes a map from string -> indexes for the leftmost ending index of the longest sequence. Now we need to reason on those!
Now we can just scan for the strings with the longest sequences:
//Find all strings with equal maximal length sequences
Set<String> longestStrings = new HashSet<>();
for (Map.Entry<String, Integer> e: lengths.entrySet()) {
if (e.value == maxLength) {
longestStrings.add(e.key);
}
}
//Of those, search the one with minimal index
int minIndex = input.length();
String bestString = null;
for (String s: longestStrings) {
int index = indexes.get(s);
if (index < minIndex) {
bestString = s;
}
}
System.out.println(bestString);
Below code results in output as you expected:
public static void main(String[] args) {
System.out.println("Please enter a sequence of strings separated by spaces:");
Scanner inputStringScanner = new Scanner(System.in);
String[] strings = inputStringScanner.nextLine().split(" ");
System.out.println(String.join(" ", strings));
List <ArrayList<String>> stringsSequencesCollection = new ArrayList<ArrayList<String>>();
List <String> stringsSequences = new ArrayList<String>();
//stringsSequences.add(strings[0]);
boolean flag = false;
for (int i = 1; i < strings.length; i++) {
if(strings[i].equals(strings[i - 1])) {
if(flag == false){
stringsSequences.add(strings[i]);
flag= true;
}
stringsSequences.add(strings[i]);
}
}
int maximalStringSequence = Integer.MIN_VALUE;
int index = 0;
List <String> currentStringSequence = new ArrayList<String>();
for (int i = 0; i < stringsSequencesCollection.size(); i++) {
currentStringSequence = stringsSequencesCollection.get(i);
System.out.println(stringsSequencesCollection.get(i).size());
if (stringsSequencesCollection.get(i).size() > maximalStringSequence) {
maximalStringSequence = stringsSequencesCollection.get(i).size();
index = i;
//System.out.println("\n" + index);
}
}
System.out.println(stringsSequences.toString());

how to get all permutations of strings in an array list by specified size

I am trying to get all permutations of strings(words) in a java array list with two words.Following is the code i tried but i am not getting all permutations of words in the list.
for (int y = 0; y<newList.size(); y++){
String first = newList.get(y);
String second = "";
if(y+1<newList.size()){
second = newList.get(y+1);
}
ArrayList<String> tmpArr = new ArrayList<String>();
tmpArr.add(first);
tmpArr.add(second);
ArrayList<String> retArray = combine(tmpArr);
for (int c = 0; c <retArray.size(); c++) {
System.out.println(retArray.get(c));
}
}
public static ArrayList<String> combine(ArrayList<String> arr){
ArrayList<String> retArr = new ArrayList<String>();
if(arr.size()==0){
retArr.add("");
return retArr;
}
ArrayList<String> tmpArr = (ArrayList<String>)arr.clone();
tmpArr.remove(0);
for(String str1 : combine(tmpArr)){
for(String str2 : arr){
retArr.add(str2+","+str1);
if(retArr.size() == 10)
return retArr;
}
}
return retArr;
}
Please let me know how to correct the code to get all permutations of words in the list with size 2(all permutations of words with two words as output)
For example if the input data is as follows
Input - [visit,party,delegation]
Expected Output -
[visit,party
visit,delegation
party,visit
party,delegation
delegation,visit
delegation,party]
Current Output -
[visit,party,
party,party,
party,delegation,
delegation,delegation,]
This will give you all the two-word permutations of a list of words.
List<String> strings = Arrays.asList("party","visit","delegation");
for (int i = 0; i < strings.size(); i++){
for (int j = 0; j < strings.size(); j++){
if (i != j) System.out.println(strings.get(i) + "," + strings.get(j));
}
}
EDIT: added the if statement and changed the loop since you wanted permutations of different orders as well.
You should step through your program with a debugger to see what happens.
My suggestion for the fault reason is: you create a new retArr in every call of combine, so you get only the results of the last call.
See that you use the same retArr for all executions of combine.

Java String Bubble Sorting

I need help sorting this array in alphabetical order using the bubble sort algorithm.
My code is:
public class Strings
{
public static void main(String[] args)
{
Scanner reader = new Scanner(System.in);
String tempStr;
System.out.print("Enter the strings > ");
String s1 = new String(reader.nextLine());
String[] t1 = s1.split(", ");
for (int t=0; t<t1.length-1; t++)
{
for (int i = 0; i<t1.length -1; i++)
{
if(t1[i+1].compareTo(t1[1+1])>0)
{
tempStr = t1[i];
t1[i] = t1[i+1];
t1[i+1] = tempStr;
}
}
}
for(int i=0;i<t1.length;i++)
{
System.out.println(t1[i]);
}
}
}
The code compiles, but it does not sort alphabetical. Please help me.
You have three errors in your code.
The first error is in the inner for loop, in the place where you do the check statement, it should be i < t1.length - t -1 not i < t1.length -1. You subtract t because you do not want to loop through the whole array again, only the first part of it.
The second and third errors are in the if statement. You need to turn the greater than symbol into a lesser than symbol, because the way you have the compareTo method set up, it will return a negative number.
The other error in this line is that in the compareTo parameter you put 1 + 1 it actually should be just i, because you want one less than the object it is comparing to.
The fixed working code is below (Comments are what you originally had):
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
String tempStr;
System.out.print("Enter the strings > ");
String s1 = new String(reader.nextLine());
String[] t1 = s1.split(", ");
for (int t = 0; t < t1.length - 1; t++) {
for (int i= 0; i < t1.length - t -1; i++) {
if(t1[i+1].compareTo(t1[i])<0) {
tempStr = t1[i];
t1[i] = t1[i + 1];
t1[i + 1] = tempStr;
}
}
}
for (int i = 0; i < t1.length; i++) {
System.out.println(t1[i]);
}
}
please change
String[] t1 = s1.split(", ");
to
String[] t1 = s1.split("");
This will solve the issue.

Categories