I have array of ValueA and ValueB(int type) . I am reading each value from array using a for loop.
I want to concatenate all there values in a single String. these value should be in the form of like these
ValueA1":"valueB1"|"ValueA2":"valueB2"|"ValueA3":"valueB3"|"ValueA4":"valueB4"|"....
I want this in Java, please can some ne help me with code..
You could try something like this
int[] valueA = methodWhichFillsA();
int[] valueB = methodWhichFillsB();
StringBuilder sb = new StringBuilder();
int maxSize = Math.max(valueA.length, valueB.length);
for(int i = 0; i < maxSize; i++){
if(i > 0)
sb.append("|");
if(i < valueA.length)
sb.append(valueA[i]);
sb.append(":");
if(i < valueB.length)
sb.append(valueB[i]);
}
System.out.println(sb.toString());
This will evaluate the size of the biggest array between valueA and valueB, loop on this size. If the element exists it's printed.
The first if is used to add the separator, if it's the first iteration no need for a "|"
Assuming the arrays are of different size, this solution will zip them together up until the end of the shorter array:
StringBuilder sb = new StringBuilder();
for(int i = 0; i < Math.min(arr1.length, arr2.length); i++){
sb.append( arr1[i] ).append("\":\"").append( arr2[i] ).append("\"|\"");
}
System.out.println(sb.toString());
Just a different way of doing it, this uses Guava
private String test(int[] a, int[] b) {
List<Integer> al = Lists.newArrayList();
List<Integer> bl = Lists.newArrayList();
for (Integer ai : a) {
al.add(ai);
}
for (Integer bi : b) {
bl.add(bi);
}
List<String> sets = Lists.newArrayList();
Iterator<Integer> itera = al.iterator();
Iterator<Integer> iterb = bl.iterator();
while(itera.hasNext() && iterb.hasNext()) {
sets.add(itera.next()+":"+iterb.next());
}
return Joiner.on("|").join(sets);
}
I was surprised to find no primitive array to list methods. If you can think of an elegant way to do that besides pulling it out into another method, the this code could be made cleaner.
Related
I have to find the number of elements in two char[] arrays. These arrays are char arrays with a max size of 5, and only letters A to G can be used. I will separate this into two arrays - arr1 and arr0. arr1 has priority over arr2, as in if arr1 has 3 elements of 'A' but arr2 has 4, the max count is 3.
I have to find the number of common elements these arrays share, with arr1 having the priority in maximum count. I am stumped so far. I thought of iterating through the chars:
for (char x = 'A'; x <= G; x++) {
//code
}
But I have no idea what to do after that. Any help would be appreciated.
This feels like homework so instead of giving you a full solution I will give you pointers and the parts you need to disassemble / reassemble to make it work, hoping that this will better allow you to learn and understand the suggested solution.
Here's a solution to count elements in a String using HashMap, you can easily adapt it to count elements in an Array:
// Java prorgam to count frequencies of
// characters in string using Hashmap
import java.io.*;
import java.util.*;
class OccurenceOfCharInString {
static void characterCount(String inputString)
{
// Creating a HashMap containing char
// as a key and occurrences as a value
HashMap<Character, Integer> charCountMap
= new HashMap<Character, Integer>();
// Converting given string to char array
char[] strArray = inputString.toCharArray();
// checking each char of strArray
for (char c : strArray) {
if (charCountMap.containsKey(c)) {
// If char is present in charCountMap,
// incrementing it's count by 1
charCountMap.put(c, charCountMap.get(c) + 1);
}
else {
// If char is not present in charCountMap,
// putting this char to charCountMap with 1 as it's value
charCountMap.put(c, 1);
}
}
// Printing the charCountMap
for (Map.Entry entry : charCountMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
// Driver Code
public static void main(String[] args)
{
String str = "Ajit";
characterCount(str);
}
}
And finally you can sort by occurrence and get the highest occurrences, there are plenty of resources about that, here's an Example from StackOverflow:
Map<String, Person> people = new HashMap<>();
Person jim = new Person("Jim", 25);
Person scott = new Person("Scott", 28);
Person anna = new Person("Anna", 23);
people.put(jim.getName(), jim);
people.put(scott.getName(), scott);
people.put(anna.getName(), anna);
// not yet sorted
List<Person> peopleByAge = new ArrayList<>(people.values());
Collections.sort(peopleByAge, Comparator.comparing(Person::getAge));
for (Person p : peopleByAge) {
System.out.println(p.getName() + "\t" + p.getAge());
}
Source for OccurenceOfCharInString
Source for HashMap sorting
arr1;
arr2;
int find(char) {
int a = 0;
int b = 0;
for(let i = 0; i < arr1.length; i++) {
if(arr1[i] === char)
a++;
}
for(let j = 0; j < arr2.length; j++) {
if(arr2[j] === char)
b++;
}
if(a > 0){
return a;
} else {
return Math.max(a, b);
}
}
numOccurence = find(char);
Consider two Array list
a = [1,4,2,4]
b = [3,5]
I wanted to return the count of numbers for each number in B less than equal to number in A.
So the answer would be [2,4] since 3 in B has 2 numbers in A that are <= 3 i.e. [1,2]
And 5 in B has 4 numbers in A that are <= 5 . i.e [1,4,2,4]
Note: i tried using 2 loops but testcases time out.
this is the code
static ArrayList<Integer> counting(ArrayList<Integer>A, ArrayList<Integer>B)
{
ArrayList<Integer> finallist = new ArrayList<>();
for(int i : B)
{
int count = 0;
for(int j: A)
{
if(j<=i)
count++;
}
finallist.add(count);
}
return finallist;
}
we were supposed to edit the function and return arraylist
When I see an array and I need find smth. in it, so this is a magic key to use binary search. This gives you O(n log n) time complexity.
public static int[] findLessNumbers(int[] a, int[] b) {
TreeMap<Integer, Integer> numCount = new TreeMap<>();
for (int aa : a)
numCount.put(aa, numCount.getOrDefault(aa, 0) + aa);
int total = 0;
for (Map.Entry<Integer, Integer> entry : numCount.entrySet())
numCount.put(entry.getKey(), total += entry.getValue());
int[] res = new int[b.length];
for (int i = 0; i < res.length; i++)
res[i] = Optional.ofNullable(numCount.floorKey(b[i])).orElse(0);
return res;
}
What I understood from Your question was You weren't able to find the answer.
Hope this can help you.
Your code had a problem in counting function parameter, you should declare what is the data type that you are expecting.
static ArrayList counting(List A, List B) this isn't a way
instead you should have wrote static ArrayList counting(ArrayList<Integer> A, ArrayList<Integer> B)
and that will fix your problem.
here's my solution:
Counting function.
private static ArrayList counting(ArrayList<Integer>A, ArrayList<Integer>B ){
ArrayList<Integer> finallist = new ArrayList<>();
for(int i : B) {
int count = 0;
for(int j : A) {
if(j <= i) {
count++;
}
}
finallist.add(count);
}
return finallist;
}
Main from where am calling counting:
ArrayList<Integer> ans = counting(A,B);
for(int i : ans) {
System.out.print(i+" ");
}
Output:
2 4
This could resolve the issue you are facing.
Recently I faced a question in an interview and I was unable to make logic for this question. I have an array like
[ 1,'a',45,'h',56,'d',2,'t',6,'p' ] . How to sort this array ? Output should be in this manner..
intArray = [1,2,6,45,56]
charArray= ['a','d','h','p','t']
If anybody knows its logic please comment. It would be a great help.
Thanks !
One way would be separate the integers and then sort-
Object[] objects = new Object[]{ 1,'a',45,'h',56,'d',2,'t',6,'p' };
List integers = new ArrayList<Integer>();
List characters = new ArrayList<Character>();
// Check and store integers and characters
// Doesn't validate and assumes you either have integers or characters
for(Object o : objects){
if(o instanceof Integer){
integers.add(o);
} else {
characters.add(o);
}
}
//Sort them separately
Collections.sort(integers);
Collections.sort(characters);
System.out.println(integers);
System.out.println(characters);
First of all separate the integers and character into different
arrays by checking its instance type.
If characters are stored in ASCII form (in java it is stored in ASCII form) you can directly sort them using any of the sorting algorithm, treating each value as integer only.
Similarly you can apply any sorting algorithm on integer array.
The following code produces desired result:
import static java.util.stream.Collectors.*;
final Map<Class<?>, Set<Object>> result = Stream.of(array) //
.collect(//
groupingBy(x -> x.getClass(), //
mapping(x -> x, toCollection(TreeSet::new))));
to view results:
System.out.println(Arrays.toString(result.get(Integer.class).toArray()));
System.out.println(Arrays.toString(result.get(Character.class).toArray()));
Below is the implementation of it. I have used two for loops so that we can easily find out the length of the two new subarrays instead of initializing it with the base array;s length.
I have tried not to use any in-built methods except Arrays.sort(). You can also write your own code to sort these two sub arrays.
public static void main(String[] args) {
Object[] array = { 1, 'a', 2, 'f', 5, 'b', 3 };
int intLoc = 0;
int charLoc = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] instanceof Integer) {
intLoc++;
} else {
charLoc++;
}
}
int intArray[] = new int[intLoc];
char charArray[] = new char[charLoc];
for (int i = 0; i < array.length; i++) {
if (array[i] instanceof Integer) {
--intLoc;
intArray[intLoc] = (int) array[i];
} else {
--charLoc;
charArray[charLoc] = (char) array[i];
}
}
Arrays.sort(intArray);
Arrays.sort(charArray);
System.out.println(Arrays.toString(intArray));
System.out.println(Arrays.toString(charArray));
}
As the title reads, I have been thinking about creating multiple nested loops that aim to achieve one purpose. Move two generated random numbers between 0-9 through each possible possition of an array.
For example, App generates first number (fNum) 1 and second number (sNum) 6. It then moves these numbers in the array which containts ABC. However firstNum and secondNum will need to also try all the possible combinations, so each one will need to be different with each loop.
-1ABC6
-A1BC6
-AB1C6
-ABC16
-ABC61
-AB6C1
-A6BC1
-6ABC1
-A6B1C
-A61BC
-A16BC
-A1B6C
-A1BC6
and so on...
I beleive the best way will be to create a method for generating a counter, which increments the numbers which I can call.
private int getNextNumber(int num) {
if (num == 0) {
return num;
} else {
num++;
}
if (num < 10) {
return num;
} else {
return -1;
}
}
Then I will need multiple nested loops... I have decided to go for several loops which will go infinitly.
while (j < maxlen) {
//J = 0 and maxlen = length of text so in this case 3 as it is ABC
//Add two numbers and check against answer
while (fNum != -1 || sNum != -1) {
//incrememnt numbers
fNum = getNextNumber(fNum);
System.out.println(fNum);
sNum = getNextNumber(sNum);
System.out.println(fNum);
}
String textIni = "ABC";
int lenOfText = textIni.length();
char[] split = textIni.toCharArray();
for (int i = 0; i < lenOfText; i++) {
//here it will look at the length of the Text and
//try the possible positions it could be at....
//maybe wiser to do a longer loop but I am not too sure
}
}
Since you don't need to store all possible combinations, we will save some memory using only O(n) storage with an iterative solution. I propose you a basic implementation but don't expect to use it on large arrays since it has a O(n³) complexity.
public static void generateCombinationsIterative(List<Integer> original, int fnum, int snum) {
int size = original.size();
for (int i=0 ; i<=size ; i++) {
List<Integer> tmp = new ArrayList<>(original);
tmp.add(i,fnum);
for (int j=0 ; j<=size + 1 ; j++) {
tmp.add(j,snum);
System.out.print(tmp + (i == size && j == size + 1 ? "" : ", "));
tmp.remove(j);
}
}
}
For your culture, here is an example of a recursive solution, which takes a lot of memory so don't use it if you don't need to generate the lists of results. Nevertheless, this is a more general solution that can deal with any number of elements to insert.
public static List<List<Integer>> generateCombinations(List<Integer> original, Deque<Integer> toAdd) {
if (toAdd.isEmpty()) {
List<List<Integer>> res = new ArrayList<>();
res.add(original);
return res;
}
int element = toAdd.pop();
List<List<Integer>> res = new LinkedList<>();
for (int i=0 ; i<=original.size() ; i++)
// you must make a copy of toAdd, otherwise each recursive call will perform
// a pop() on it and the result will be wrong
res.addAll(generateCombinations(insertAt(original,element,i),new LinkedList<>(toAdd)));
return res;
}
// a helper function for a clear code
public static List<Integer> insertAt(List<Integer> input, int element, int index) {
List<Integer> result = new ArrayList<>(input);
result.add(index,element);
return result;
}
Note that I did not use any array in order to benefit from dynamic data structures, however you can call the methods like this :
int[] arr = { 1,2,3 };
int fnum = 4, snum = 5;
generateCombinationsIterative(Arrays.asList(arr),fnum,snum);
generateCombinations(Arrays.asList(arr),new LinkedList<>(Arrays.asList(fnum,snum));
Note that both methods generate the combinations in the same order.
I am trying to find the union of two string arrays. I have created a new array and have copied all the data from the first set into the new array. I am having trouble adding the information from the second set into the new array.
I need to use loops to search the second array and find the duplicates. I keep getting an ArrayIndexOutOfBoundsException.
Here is my current code:
static String[] union(String[] set1, String[] set2) {
String union[] = new String[set1.length + set2.length];
int i = 0;
int cnt = 0;
for (int n = 0; n < set1.length; n++) {
union[i] = set1[i];
i++;
cnt++;
}
for (int m = 0; m < set2.length; m++) {
for (int p = 0; p < union.length; p++) {
if (set2[m] != union[p]) {
union[i] = set2[m];
i++;
}
}
}
cnt++;
union = downSize(union, cnt);
return union;
}
The standard way of doing intersections or unions is using a set. You should use the Set class from collections framework.
Create two arraylist objects for your two arrays.
Define a Set object.
Add both the arraylist objects into the Set using addAll method.
As set holds unique elements, the set forms the union of
both arrays.
//push the arrays in the list.
List<String> list1 = new ArrayList<String>(Arrays.asList(stringArray1));
List<String> list2 = new ArrayList<String>(Arrays.asList(stringArray2));
HashSet <String> set = new HashSet <String>();
//add the lists in the set.
set.addAll(list1);
set.addAll(list2);
//convert it back to array.
String[] unionArray = set.toArray(new String[0]);
Using Set is going to be one of the easiest way:
public static String[] unionOf(String[] strArr1, String[] strArr2) {
Set<String> result = new HashSet<String>();
result.addAll(Arrays.asList(strArr1));
result.addAll(Arrays.asList(strArr2));
return result.toArray(new String[result.size()]);
}
There are also other utilities that can help in similar work, e.g. Guava:
public static String[] unionOf(String[] strArr1, String[] strArr2) {
return Sets.union(Sets.newHashSet(strArr1),
Sets.newHashSet(strArr2))
.toArray(new String[0]);
}
You have several problems with this part of your code:
for(int m = 0; m < set2.length; m++)
for(int p = 0; p < union.length; p++)
if(set2[m] != union[p])
{
union[i] = set2[m];
i++;
}
cnt++;
First, you should be using !equals() instead of != to compare strings. Second, despite the indenting, the statement cnt++ is not part of the outer loop. You don't need both i and cnt; their values should always match. Finally, you are adding set2[m] once for each element of union that is different from it. You only want to add it once. Here's a version that should work:
static String[] union( String[] set1, String[] set2 )
{
String union[] = new String[set1.length + set2.length];
System.arraycopy(set1, 0, union, 0, set1.length); // faster than a loop
int cnt = set1.length;
for(int m = 0; m < set2.length; m++) {
boolean found = false;
for(int p = 0; p < union.length && !found; p++) {
found = set2[m].equals(union[p]);
}
if(!found)
{
union[cnt] = set2[m];
cnt++;
}
}
union = downSize( union, cnt );
return union;
}
As other posters have noted, an alternative approach is to use a HashSet<String>, add the elements found in the two arrays, and turn the result back into an array.
You get ArrayIndexOutOfBoundsException on this line:
union[i] = set2[m];
because you keep increasing i somewhere around: set2.length * union.length times (nested loops).
Doing what R.J wrote will not give you the union - you'll have many duplicate items since by doing: set2[m].equals(union[p]) you compare every member of set2 to all the members of union and for each member that it's not equal to - you add it. so you end up adding the same items multiple times!
The right way to do it is like Deepak Mishra suggested by using Set which will "take care" of the duplicates.
Example:
int[] a = {1,2,3,4,5};
int[] b = {4,5,6,7};
Set union = new HashSet<Integer>();
for(int i=0; i<a.length; i++) union.add(a[i]);
for(int i=0; i<b.length; i++) union.add(b[i]);
Object[] ans = union.toArray();
for(int i=0; i<ans.length; i++)
System.out.print(ans[i]+" ");
will output:
1 2 3 4 5 6 7
Since it's HW I won't write the code for the answer, but I'll give you a tip: doing it your way requires O(n^2) - if you'll think a bit I'm sure that you can find a way to do it in a better time, say, O(n log n)...
Though using the SETS is the best solution, here is a simple solution.
private static String getUnion(String a, String b, boolean ignoreCase) {
String union = "";
if (a == null || b == null || a.length() < 1 || b.length() < 1) {
return union;
}
char[] shortest;
char[] longest;
if (ignoreCase) {
shortest = (a.length() <= b.length() ? a : b).toLowerCase().toCharArray();
longest = (a.length() <= b.length() ? b : a).toLowerCase().toCharArray();
} else {
shortest = (a.length() <= b.length() ? a : b).toLowerCase().toCharArray();
longest = (a.length() <= b.length() ? b : a).toLowerCase().toCharArray();
}
StringBuilder sb = new StringBuilder();
for (char c : shortest) {
for (int i = 0; i < longest.length; i++) {
if (longest[i] == c) {
sb.append(c);
}
}
}
union = sb.toString();
return union;
}
and following are few tests.
public static void main(String[] args) {
System.out.println("Union of '' and BXYZA is " + getUnion("", "BXYZA", true));
System.out.println("Union of null and BXYZA is " + getUnion(null, "BXYZA", true));
System.out.println("Union of ABC and BXYZA is " + getUnion("ABC", "BXYZA", true));
System.out.println("Union of ABC and BXYZA is " + getUnion("ABC", "bXYZA", false));
}