i was working on one issue i am not getting the expected output.
A String array “F1” has got names of Facebook users and their friend association.
For example, if we write: U1,U2 it implies that U1 is a friend of U2. This also implies that U2 is a friend of U1.
Write a program which will read “F1” and remove duplicates and write all the unique pairs to “F2”.
But, before removing duplicates
Input String => ["U1,U2","U3,U4","U2,U1","U1,U5"]
Output String => ["U1,U2","U1,U5","U3,U4"]
public static void main(String args[]) {
List test = new ArrayList();
List<String> list = new ArrayList();
list.add("U1,U2");
list.add("U3,U4");
list.add("U2,U1");
list.add("U1,U5");
Collections.sort(list);
for (String str : list) {
String i1 = str.substring(0, 2);
String i2 = str.substring(3, 5);
System.out.println(i2);
if (!i1.equals(i2)) {
test.add(str);
}
if (!(str.contains(i1) && str.contains(i2)) || !(str.contains(i2) && str.contains(i1))) {
System.out.println(str);
}
}
}
}
This is how it is done ;)
class Program
{
static void Main(string[] args)
{
List<string> test = new List<String>();
List<String> list = new List<String>();
List<String> list1 = new List<String>();
List<String> outputList = new List<String>();
list.Add("MARY,JOE");
list.Add("A,B");
list.Add("B, A");
list.Add("3");
list.Add("3");
list.Add("3,3");
list.Add("3,3");
var aa = compareFriends(list);
Console.ReadLine();
}
public static List<string> compareFriends(List<string> allfrndsList)
{
var frndsList = allfrndsList.Distinct().ToList();
var outputList = new List<string>(frndsList);
var listCount = frndsList.Count();
var startIndex = 1;
foreach (var friend in frndsList)
{
friend.Replace(" ","");
var str = friend.Split(',');
var i1 = str.FirstOrDefault();
var i2 = str.LastOrDefault();
for (var index = startIndex; index < listCount; index++)
{
var innerStr = frndsList[index].Replace(" ","").Split(',');
var temp1 = innerStr.FirstOrDefault();
var temp2 = innerStr.LastOrDefault();
if (innerStr.Length != 1 && str.Length!=1)
{
if (i1.Equals(temp2) && i2.Equals(temp1))
{
outputList.Remove(friend);
}
}
}
startIndex++;
}
return outputList;
}
}
Make a key of every pair, where the first value is smaller than the second value. ("U1,U2" and "U2,U2" will both result in "U1,U2"). Add these keys to a Set (a set removes duplicates for you). In the end you have a unique set of friend relationships.
Set<String> f2=new HashSet<>();
for (String str : list) {
String[] users=str.split(",");
String i1 = users[0];
String i2 = users[1];
String key=i1.compareTo(i2)>0?i2+","+i1:i1+","+i2;
f2.add(key);
}
System.out.println(f2);
List test = new ArrayList();
List<String> list = new ArrayList();
list.add("JOE,MARY");
list.add("A,B");
Set<String> f2 = new HashSet<>();
for (String str : list) {
String[] users = str.split(",");
String i1 = users[0];
String i2 = users[1];
String key = i1.compareTo(i2) > 0 ? i2 + "," + i1 : i1 + "," + i2;
f2.add(key);
}
Iterator val = f2.iterator();
while (val.hasNext()) {
test.add(val.next());
}
Collections.sort(test);
System.out.println("test" + test);
In C#:
class Program
{
static void Main(string[] args)
{
List<string> list1 = new List<string>();
list1.Add("U1,U2");
list1.Add("U3,U4");
list1.Add("U2,U1");
list1.Add("U1,U5");
List<string> list2 = new List<string>();
foreach (string s in list1)
{
var list3 = s.Split(',');
Array.Sort(list3);
list2.Add(list3.FirstOrDefault() + ',' + list3.LastOrDefault());
}
list2.Sort();
var list4 = list2.Distinct().ToList();
Console.WriteLine("Input string:");
foreach (string s in list1)
Console.WriteLine(s);
Console.WriteLine("\nOutput string:");
foreach (string s in list4)
Console.WriteLine(s);
Console.Read();
}
}
We can look at it as an undirected graph
You have to remove duplicate paths
Since it's undirected, "U1, U2" and "U2, U1" are the same path
Therefore, if path U1, U2 already exist, then U2, U1 is duplicate, so remove it.
Any of the suggestions in the comments will yield a viable solution
In Python :
f1 = [("U1", "U2"), ("U3", "U4"), ("U1", "U5"), ("U2", "U1"), ("U3", "U4")]
nw_lst = []
f1 = list(set(filter(lambda x: x[0] != x[1], f1)))
for i in f1:
val1 = int(i[0][1]) + int(i[1][1])
for j in range(f1.index(i) + 1, len(f1)):
val2 = int(f1[j][0][1]) + int(f1[j][1][1])
if val1 == val2:
nw_lst.append(f1[j])
f2 = set(f1).difference(set(nw_lst))
for i in f2:
print(f"{i[0]} , {i[1]}")
The below solution is written in JavaScript.
// Insert Multidimensional Array
arr = [["U1","U2"], ["U3","U4"], ["U1","U5"], ["U1","U2"], ["U3","U4"]];
function friendsArrRemover(arr) {
var a = [];
var itemsFoundArr = {};
for(var i = 0, l = arr.length; i < l; i++) {
var stringified = JSON.stringify(arr[i]);
if(itemsFoundArr[stringified]) { continue; }
a.push(arr[i]);
itemsFoundArr[stringified] = true;
}
return a;
}
friendsArrRemover(arr);
public class Main
{
public static void main(String[] args) {
String a = "ABC";
String b = "BC";
String op1="";
String op2="";
for (int i = 0; i < a.length(); i++) {
if(!b.contains(""+a.charAt(i))){
op1+=a.charAt(i);
}
}
for (int i = 0; i < b.length(); i++) {
if(!a.contains(""+b.charAt(i))){
op2+=b.charAt(i);
}
}
System.out.println(op1);
System.out.println(op2);
}
}
Below is the answer to remove the duplicate pair from list using C#.
protected void Page_Load(object sender, EventArgs e)
{
List<string> list = new List<string>();
list.Add("U1,U2");
list.Add("U3,U4");
list.Add("U2,U1");
list.Add("U1,U5");
var result=compareFriends(list);
foreach (string value in result)
{
Response.Write(value + "");
}
}
public static List<string> compareFriends(List<string> frndsList)
{
List<string> F2 = new List<string>();
frndsList.Sort();
foreach (string str in frndsList)
{
string s1 = str.Substring(0, 2);
string s2 = str.Substring(3, 2);
string key;
if (s1.CompareTo(s2)>0)
{
key = s2 + "," + s1;
}
else
{
key = s1 + "," + s2;
}
F2.Add(key);
}
var result = F2.Distinct();
return result.ToList();
}
Related
i have dataDic that is an array {"ant","bird","cat"}
dataDic is array of word that i want to search on stringPattern
I want to use dataDic to get word result from stringPattern = birdantantcatbirdcat
Ex1.
dataDic = {"ant","bird","cat"}
answer is {bird,ant,ant,cat,bird,cat}
Ex2.
dataDic = {"ant","cat"}
answer is {ant,ant,cat,cat}
this is my code
`private static String stringTest="birdantantcatbirdcat";
private static List dicListWord;
private static ListresultString = new ArrayList<>();
public static void main(String[] args) {
dicListWord = new ArrayList<>();
dicListWord.add("ant");
dicListWord.add("bird");
dicListWord.add("cat");
String[] data = stringTest.split("");
for (String dataDic:dicListWord) {
String [] wordList = dataDic.split("");
String foundWord = "";
for (String charTec:data) {
for (String dicWord:wordList) {
if(charTec.equals(dicWord)){
foundWord = foundWord.concat(charTec);
if(dataDic.equals(foundWord)){
resultString.add(foundWord);
foundWord = "";
}
}
}
}
}
for (String w1:data) {
for (String result:resultString) {
System.out.println(result);
}
}
}`
///////////////////////////////////////////////////////////////////////////////
and Result that i run is
{ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,antbird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird,ant,ant,bird,bird}
Use a TreeMap to store the position of a word as the key and the word itself as the value as you navigate the string to find matches for the word. The reason why you need to choose a TreeMap is that it is sorted according to the natural ordering of its keys which is an important aspect for your requirement.
Your requirement states that the words in the resulting list should be in the order of their occurrences in the string.
Demo:
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> words = List.of("ant", "bird", "cat");
String str = "birdantantcatbirdcat";
System.out.println(getMatchingWords(words, str));
}
static List<String> getMatchingWords(List<String> words, String str) {
Map<Integer, String> map = new TreeMap<Integer, String>();
for (String word : words) {
Pattern pattern = Pattern.compile(word);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
map.put(matcher.start(), matcher.group());
}
}
return map.values().stream().collect(Collectors.toList());
}
}
Output:
[bird, ant, ant, cat, bird, cat]
This is a word break problem and can be solved using a depth-first search. But it is wise to check before if the given string pattern is breakable or not to get better run-time in scenario where we have given a long string pattern that doesn't match any words in the dictionary.
public class P00140_Word_Break_II {
public static void main(String[] args) {
String input = "catsanddog";
List<String> wordDict = Arrays.asList("cat", "cats", "and", "sand", "dog");
P00140_Word_Break_II solution = new P00140_Word_Break_II();
List<String> results = solution.wordBreak(input, wordDict);
System.out.println(results);
String input1 = "birdantantcatbirdcat";
List<String> wordDict1 = Arrays.asList("ant","bird","cat");
List<String> results1 = solution.wordBreak(input1, wordDict1);
System.out.println(results1);
}
public List<String> wordBreak(String s, List<String> wordDict) {
Set<String> dict = new HashSet<>(wordDict);
List<String> result = new ArrayList<>();
if (s == null || s.length() == 0 || !isbreakable(s, dict)) {
return result;
}
helper(s, 0, new StringBuilder(), dict, result);
return result;
}
public void helper(String s, int start, StringBuilder item, Set<String> dict, List<String> results) {
if (start >= s.length()) {
results.add(item.toString());
return;
}
if (start != 0) {
item.append(" ");
}
for (int i = start; i < s.length(); i++) {
String temp = s.substring(start, i + 1);
if (dict.contains(temp)) {
item.append(temp);
helper(s , i+1 , item , dict , results);
item.delete(item.length() + start - i - 1 , item.length());
}
}
if(start!=0) item.deleteCharAt(item.length()-1);
}
private boolean isbreakable(String s, Set<String> dict) {
boolean[] dp = new boolean[s.length() + 1];
dp[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i; j++) {
String subString = s.substring(j, i);
if (dp[j] && dict.contains(subString)) {
dp[i] = true;
break;
}
}
}
return dp[s.length()];
}
}
For the below code, I was hoping that elements of my arraylist would be modified but its not. How can I modify the elements
public class Main {
public static void main(String args[]){
ArrayList<String> aList = new ArrayList<>();
aList .add("aa");
aList .add("bb");
aList .add("cc");
new Main().modifyList(aList );
for(String s: aList ){
System.out.println(s);
}
}
public void modifyList(ArrayList<String> aList ){
for(String s: aList){
System.out.println(s);
s = s + "ss";
}
}
}
Its printing
aa
bb
cc
aa
bb
cc
Expected output
aa
bb
cc
aass
bbss
ccss
public void modifyList(ArrayList<String> aList ){
for(String s: aList){
System.out.println(s);
s = s + "ss";
}
}
Strings are immutable. So when you change s you are creating a new object that is different than the one in the ArrayList.
So you need to iterate over the array and replace the old value with the new using the set method.
for (int i = 0; i < alist.size(); i++) {
String s = aList.get(i) + "ss";
aList.set(i, s);
}
To simply append the changes do the following:
int len = alist.size();
for (int i = 0; i < len; i++) {
String s = aList.get(i) + "ss";
aList.add(s);
}
Prints
aa bb cc aass bbss ccss
Here is the problem, the variable s is unused and visible only in the scope of the for-loop:
for (String s: aList) {
System.out.println(s);
s = s + "ss"; // the variable 's' is unused
}
Either use List::set to replace the current value:
for (int i=0; i<aList.size(); i++) {
String s = aList.get(i);
System.out.println(s);
aList.set(i, s + "ss");
}
... or use the advantage of java-stream as of java-8 and map the list to a new one:
List<String> newList = aList.stream()
.map(s -> s + "ss")
.collect(Collectors.toList());
s = s + "ss" only updates the local variable s, it doesn't update the list.
If you want to update elements in a list, use a ListIterator and the set() method:
public static void modifyList(List<String> aList) {
for (ListIterator<String> iter = aList.listIterator(); iter.hasNext(); ) {
String s = iter.next();
s = s + "ss";
iter.set(s); // replace element in the list with new value
}
}
In Java 8+, you can use a lambda expression with the replaceAll() method:
public static void modifyList(List<String> aList) {
aList.replaceAll(s -> s + "ss");
}
Both will perform well even if the list doesn't handle random access well, e.g. if the list is a LinkedList.
Test
public static void main(String[] args) {
List<String> aList = new ArrayList<>(Arrays.asList("aa", "bb", "cc"));
modifyList(aList);
System.out.println(aList);
}
Output
[aass, bbss, ccss]
In order to solve this, you need to update each element as follows:
public void modifyList(ArrayList<String> aList){
for(int i = 0; i < aList.size(); i++){
String s = aList.get(i);
aList.set(i, s+"ss");
}
}
For an assignment I have been asked to find the largest group of anagrams in a list. I believe I would have to have an accumulation loop inside of another loop that keeps track of the largest number of items. The problem is that I don't know how to count how many of each anagram I have. I have been able to sort the array into groups based on their anagrams. So from the index 1-3 is one anagram, 4-10 is another, etc. How do I search through and count how many of each anagram I have? Then compare each one to the previous count.
Sample of the code:
public static String[] getLargestAnagramGroup(String[] inputArray) {
ArrayList<String> largestGroupArrayList = new ArrayList<String>();
if (inputArray.length == 0 || inputArray == null) {
return new String[0];
}
insertionSort(inputArray, new AnagramComparator());
String[] largestGroupArray = new String[largestGroupArrayList.size()];
largestGroupArrayList.toArray(inputArray);
System.out.println(largestGroupArray);
return largestGroupArray;
}
UPDATE: This is how we solved it. Is there a more efficient way?
public static String[] getLargestAnagramGroup(String[] inputArray) {
int numberOfAnagrams = 0;
int temporary = 1;
int position = -1;
int index = 0;
if (inputArray == null) {
return new String[0];
}
insertionSort(inputArray, new AnagramComparator());
for (index = 0; index < inputArray.length - 1; index++) {
if (areAnagrams(inputArray[index], inputArray[index + 1])) {
temporary++;
} else {
if (temporary > numberOfAnagrams) {
numberOfAnagrams = temporary;
position = index;
temporary = 1;
} else if (temporary < numberOfAnagrams) {
temporary = 1;
}
}
}
if (temporary > numberOfAnagrams) {
position = index;
numberOfAnagrams = temporary;
}
String[] largestArray = new String[numberOfAnagrams];
for (int startIndex = position - numberOfAnagrams + 1, i = 0; startIndex <= position; startIndex++, i++) {
largestArray[i] = inputArray[startIndex];
}
return largestArray;
}
Here is a piece of code to help you out.
public class AnagramTest {
public static void main(String[] args) {
String[] input = {"test", "ttes", "abcd", "dcba", "dbac"};
for (String string : getLargestAnagramGroup(input)) {
System.out.println(string);
}
}
/**
* Gives an array of Strings which are anagrams and has the highest occurrence.
*
* #param inputArray
* #return
*/
public static String[] getLargestAnagramGroup(String[] inputArray) {
// Creating a linked hash map to maintain the order
Map<String, List<String>> map = new LinkedHashMap<String, List<String>>();
for (String string : inputArray) {
char[] charArray = string.toCharArray();
Arrays.sort(charArray);
String sortedStr = new String(charArray);
List<String> anagrams = map.get(sortedStr);
if (anagrams == null) {
anagrams = new ArrayList<String>();
}
anagrams.add(string);
map.put(sortedStr, anagrams);
}
Set<Entry<String, List<String>>> entrySet = map.entrySet();
List<String> l = new ArrayList<String>();
int highestAnagrams = -1;
for (Entry<String, List<String>> entry : entrySet) {
List<String> value = entry.getValue();
if (value.size() > highestAnagrams) {
highestAnagrams = value.size();
l = value;
}
}
return l.toArray(new String[l.size()]);
}
}
The idea is to first find the anangrams. I am doing that using a sorting the string's character array and using the LinkedhashMap.
Then I am storing the original string in the list which can be used to print or reuse as a result.
You have to keep counting the number of times the an anagram occurs and that value can be used solve your problem
This is my solution in C#.
public static string[] LargestAnagramsSet(string[] words)
{
var maxSize = 0;
var maxKey = string.Empty;
Dictionary<string, List<string>> set = new Dictionary<string, List<string>>();
for (int i = 0; i < words.Length; i++)
{
char[] temp = words[i].ToCharArray();
Array.Sort(temp);
var key = new string(temp);
if (set.ContainsKey(key))
{
set[key].Add(words[i]);
}
else
{
var anagrams = new List<string>
{
words[i]
};
set.Add(key, anagrams);
}
if (set[key].Count() > maxSize)
{
maxSize = set[key].Count();
maxKey = key;
}
}
return string.IsNullOrEmpty(maxKey) ? words : set[maxKey].ToArray();
}
I have a string say "abab" and im splitting it in pairs.(i.e ab,ab) If pair already exists then i dont want it to be generated.How do i do it
Here's the code for what ive tried
String r="abab";
String pair[] = new String[r.length()/2];
for( int i = 0; i <pair.length; i++ )
{
pair[i] = r.substring(i*2,(i*2)+2);
}
Before adding it to the pair array you could see if it already exists with the Arrays function .contains. If the pair already exists then don't add it to the pair list. For example here the ab and fe pairs will not be added:
String r="ababtefedefe";
String pair[] = new String[r.length()/2];
String currentPair = "";
for( int i = 0; i <pair.length; i++ )
{
currentPair = r.substring(i*2,(i*2)+2);
if(!java.util.Arrays.asList(pair).contains(currentPair))
pair[i] = currentPair;
System.out.println(pair[i]);
}
I would use a Set to help me out.
private String[] retrieveUniquePair(String input) {
int dim = input.length() / 2;
Set<String> pairs = new LinkedHashSet<>(dim);
for (int i = 0; i <= dim; i += 2) {
String currentPair = input.substring(i, i + 2);
pairs.add(currentPair);
}
return pairs.toArray(new String[] {});
}
Edit:
I post the solution I propose and the test
public class PairTest {
#DataProvider(name = "input")
public static Object[][] input() {
return new Object[][] {
{"abcd", Arrays.asList("ab", "cd")},
{"abcde", Arrays.asList("ab", "cd")},
{"abcdab", Arrays.asList("ab", "cd")},
{"ababcdcd", Arrays.asList("ab", "cd")},
{"ababtefedefe", Arrays.asList("ab", "te", "fe", "de")},
};
}
#Test(dataProvider = "input")
public void test(String input, List<String> expectedOutput) {
String[] output = retrieveUniquePair(input);
Assert.assertNotNull(output);
Assert.assertEquals(output.length, expectedOutput.size());
for (String pair : output) {
Assert.assertTrue(expectedOutput.contains(pair));
}
}
private String[] retrieveUniquePair(String input) {
int pairNumber = input.length() / 2;
Set<String> pairs = new LinkedHashSet<>(pairNumber);
int endIteration = input.length();
if (input.length() % 2 != 0) { // odd number
endIteration--; // ignore last character
}
for (int i = 0; i < endIteration; i += 2) {
String currentPair = input.substring(i, i + 2);
pairs.add(currentPair);
}
return pairs.toArray(new String[pairs.size() - 1]);
}
}
I need to compare the value from List with the value from array.
I wrote the following:
public class JavaApplication3 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic hereut
List<String> l = new ArrayList<String>();
l.add("test");
l.add("b");
String v = "";
String s = "";
String[] arr = {"test", "c", "b"};
for (int i = 0; i < l.size(); i++){
v = "";
s = "";
//System.out.println(l.get(i));
for (int j = 0; j < arr.length; j++){
if (l.get(i).equals(arr[j])){
s = i + "";
}else{
s = arr[i];
}
v = v + s + ",";
}
System.out.println(v);
}
}
}
I obtain the following
0,test,test,
c,c,1
but I need the result like this:
0, c, 1,
Looking at your expected result I guess the requirement like that:
for each element in the array, check if it is on the list. If it is on the list, print the index from the list for this element, otherwise print the element itself. So the algorithm should do:
array[0] = "test" -> found at index 0 -> print "0"
array[1] = "c" -> not found -> print "c"
array[2] = "b" -> found at index 1 -> print "1"
The outer loop should iterate over the array. Then, for each array item, iterate over the list until you find the same element. For a first draft, don't collect the output in a string but print it immediatly. You can create the string when the algorithm works as expected.
You have six iterations, each of which inserts something into the output.
You want three iterations, each of which checks for membership in the first list. You can do that with the List.contains() method. (If the list were long, you might want to consider using a Set instead of a List, to allow checking set membership more quickly.)
How about this:
public static void main(String[] args) {
// TODO code application logic hereut
List<String> l = new ArrayList<String>();
l.add("test");
l.add("b");
String v = "";
String s = "";
String[] arr = {"test", "c", "b"};
int pointer = 0;
for (int i = 0; i < l.size(); i++){
//System.out.println(l.get(i));
for (; pointer < arr.length;){
if (l.get(i).equals(arr[pointer])){
s = i + "";
v = v + s + ",";
pointer++;
break;
}else{
s = arr[i];
}
pointer++;
v = v + s + ",";
}
}
System.out.println(v);
}
Try to break things down to their high level steps.
For each string in the array
find its place in the list
if the item is in the list
print its position
else
print the missing string
print a common and space
Once you have this you can spot that find its place in the list could be a method that returns the place in the list or -1 if it isn't in the list. Here's what I made (might have renamed a few things and used a StringBuilder but you can ignore that for the moment).
import java.util.ArrayList;
import java.util.List;
public class Example {
public static void main(final String[] args) {
final List<String> listToSeach = new ArrayList<String>();
listToSeach.add("test");
listToSeach.add("b");
final String[] arrayElementsToFind = { "test", "c", "b" };
final StringBuilder output = new StringBuilder();
for (final String string : arrayElementsToFind) {
final int firstIndex = findFirstIndex(listToSeach, string);
if (firstIndex > -1) {
output.append(firstIndex);
} else {
output.append(string);
}
output.append(", ");
}
System.out.println(output);
}
private static int findFirstIndex(final List<String> list,
final String element) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).equals(element)) {
return i;
}
}
return -1;
}
}
Well I suggest this:
List<String> l = new ArrayList<String>();
l.add("test");
l.add("b");
String[] arr = {"test", "c", "b"};
for(int i=0;i<arr.length;++i){
if(l.contains(arr[i]))
s = ""+l.indexOf(arr[i]);
else
s = arr[i];
v = v + s + ",";
}
If got what you saying correct,I think this is less verbose