I am trying to put count of characters into hashMap but it wont insert.
for(int i = 0; i < N; i++) {
str1.put(s.charAt(i),
str1.getOrDefault(str1.get(s.charAt(i)), 0) + 1);
str2.put(t.charAt(i),
str2.getOrDefault(str2.get(t.charAt(i)) ,0) + 1);
}
Thanks.
The correct pattern is:
str1.put(s.charAt(i), 1 + str1.getOrDefault(s.charAt(i), 0));
Your current code is doing a lookup, by key, of the current value mapped to the character, which initially will be null.
Instead of explicitly fetching the value to increment the count, I would use compute.
basically, if v is null, it initializes to 1. Otherwise it takes the current value and adds 1.
String str = "Programming is fun";
Map<Character, Integer> map = new HashMap<>();
for(int i = 0; i < str.length(); i++) {
map.compute(str.charAt(i), (k,v)-> v == null ? 1 : v + 1);
}
map.entrySet().forEach(System.out::println);
Prints
=2
P=1
a=1
r=2
s=1
u=1
f=1
g=2
i=2
m=2
n=2
o=1
And you can also do a frequency count using streams.
Map<Character, Long> map = Arrays.stream(str.split("")).
collect(Collectors.groupingBy(s->s.charAt(0),
Collectors.counting()));
Related
The goal of my daily task is to count how many groups of integers(from 1 to 10000, 10001 to 20000 etc. till 1000000) in a giving array (int [] a) are represented( as for example, a[0] =2, so it belongs to group 1).
My view on that is like:
static int countingGroups(int[] a)
{
Set<Integer> setOfGroupsExposed = new HashSet<>();
// Creating set for counting groups
List<Integer>list = IntStream.iterate(1,i->i+(1*10000)).limit(101).boxed()
.collect(Collectors.toList());
// list.forEach(System.out::println);
int res = setOfGroupsExposed.size();
for (int i = 0; i <a.length ; i++) {
for (int j = 0; j <list.size() ; j++) {
if(a[i]>=list.get(j)&& a[i]<list.get(j++))
setOfGroupsExposed.add(j);
// System.out.println(setOfGroupsExposed); - prints just empty brackets
}
}
return res;
}
And I can't understand what's wrong with my loops over here, and why Set is always empty.
You should change
if (a[i]>=list.get(j)&& a[i]<list.get(j++))
to
if (a[i]>=list.get(j)&& a[i]<list.get(j+1))
otherwise you increment j twice in each iteration, and besides, j++ returns the original value of j, so your condition has the same effect as if (a[i]>=list.get(j)&& a[i]<list.get(j)).
I'm trying to solve an auto-cipher and to find the key length i need to find the 'distance' between all elements in the cipher-text.
I've found the distances between all elements in the array however i now want some way to find the frequency of each jump.
So for example, if i had a string "ababbababba" and wanted to work with a's, the frequency of jumps of 1 is 2 and the frequency of jumps of 2 is 2.
for(int i = 1; i<cipher2.length(); i++ ){
if(cipher2Array[i] == 'f') {
arrayList.add(i);
int jumpDistance = arrayList.get(i) - arrayList.get(i-1);
}
}
So basically from here, with my jumpDistance variable, how would I something like
if(jumpDistance == theSameinAnyOtherPlaceOfArray) {
counter++;
}
And output a type of table with jumpSize, frequency
You would need a HashMap<Integer, Integer>. You can store the jumpSize as a key and the corresponding frequency as value.
Yet again if you want multiple characters to be eveluated at one go, you would need a nested Map ie - a map for each character Map<Character, Map<Integer, Integer>> as suggested by #SAM.
Map<Integer, Integer> counter = new HashMap<Integer, Integer>();
for(int i = 1; i<cipher2.length(); i++ ){
if(cipher2Array[i] == 'f') {
arrayList.add(i);
int jumpDistance = arrayList.get(i) - arrayList.get(i-1);
Integer freq = counter.get(jumpdistance);
freq = freq == null ? 1 : freq+1;
counter.put(jumpDistance, freq);
}
}
This question follows my brevious one on how to Return value of smallest index of repeated number in array.
In this function given to me by #Andreas:
private static void printFirstIndexOfRepeated(int[] values) {
Integer firstIndex = null;
Map<Integer, Integer> mapValueToIndex = new HashMap<>();
for (int i = 0; i < values.length; i++) {
Integer prevIndex = mapValueToIndex.put(values[i], i); // put() returns old value, or null
if (prevIndex != null && (firstIndex == null || prevIndex < firstIndex))
firstIndex = prevIndex;
}
if (firstIndex != null)
System.out.println("First index of repeated: " + firstIndex);
else
System.out.println("No repeat found");
}
Function test:
int [] array = {10,5, 4, 3, 5, 6};
printFirstIndexOfRepeated(array);
Output
First index of repeated: 1 // it looks for 5 and return the value of smallest index of repeated 5 in array.
Due to my lack of programming knowledge with Map, I'm new and I know only Array. I need some help to transform this function and add another parameter like (int number) to decide witch number I'm looking for and not automatically
The desired one: printFirstIndexOfRepeated(int[] values, int number)
So because you basically just want the index of the first occurrence of a given number inside an array, you don't need the Map at all. Instead you can just use a simple for loop:
private static int printFirstIndexOfRepeated(int[] values,int number) {
for(int i = 0; i < values.length; i++){
if(values[i] == number){
//System.out.println("The first index of " + number + " is " + i);
return i;
}
}
//System.out.println(number + " is not a member of the array.");
return -1;
}
This function returns the first index of a given number or -1 if the number was not found. You can uncomment the print lines to also get an output if you like (or just delete them).
I need to create 30 objects of the same kind and their name should start with a capital letter e.g "K" and after the letter i need the index of the object
e.g K1 ; K2 ... K30
Is there any way to enter a loop which has a counter and which will work properly
something like this
for (int i = 0; i<20;i++){
K k = new K();
k.setName("k" + i)
}
I also have a map which is 2d ArrayList 20x20
and all this object need to have a random position x and y into this array list
i could generate random numbers easily but how to use them to put the objects in the array list
Thank you for your time !
Provided you have a class K, with setName() method, you can do the following:
List<K> list = new ArrayList<K>();
for(int i=1 ; i<=30 ; i++){
K k = new K();
k.setName("K" + i);
list.add(k);
}
Your code is fine, just set the limit to 30, if you want a list for your objects, you have to create a list and add objects, for example
List<K> kObjects = new ArrayList<K>();
for (int i = 1; i <= 30; i++){
K k = new K();
k.setName("K" + i);
kObjects.add(k);
}
Hope it helps to you
I was wondering what could be a better solution that could produce less complexity than O(n^2) when printing unique items from two arrays. Any ideas?
int[] a = {1,2,4,5,8};
int[] b = {3,2,5,7,8};
ArrayList unMatch = new ArrayList() ;
for(int i=0; i<a.length; i++){
boolean contains = false;
innerloop:
for(int k =0; k<b.length; k++){
if(a[i]==b[k]){
contains = true;
break innerloop;
}
}
if(!contains){
unMatch.add(a[i]);
}
}
for(int i=0; i<b.length; i++){
boolean contains = false;
innerloop:
for(int k =0; k<a.length; k++){
if(b[i]==a[k]){
contains = true;
break innerloop;
}
}
if(!contains){
unMatch.add(b[i]);
}
}
Output: [1,4,3,7]
I think this sort of solution will be better, if you can use other data structures:
First we will fill up a HashMap<Integer, Integer> with the items and their frequencies:
public static Set<Entry<Integer, Integer>> fillMap(int[] a, int[] b) {
HashMap<Integer, Integer> entries = new HashMap<>();
for (Integer i : a)
entries.put(i, entries.get(i) == null ? 1 : entries.get(i) + 1);
for (Integer i : b)
entries.put(i, entries.get(i) == null ? 1 : entries.get(i) + 1);
return entries.entrySet();
}
And then print the unique items (the ones with value = 1):
for (Entry<Integer, Integer> entry: fillMap(a, b))
if (entry.getValue() == 1)
System.out.println("This value is unique: " + entry.getKey() );
If I'm not mistaken this should run in O(n+m) (or just O(n) if the arrays are the same length always).
convert array to array list
List<Integer> c = Array.asList(a);
List<Integer> d = Array.asList<b>;
c.removeAll(d);
c.addAll(d);
c.froEach(System.out::println);
I did this in java using lambdas it is only O(n)
Hope this code answers your question
Use of Set can reduce your complexity. Sets don't allow duplicates. Sets can be:
HashSet - HashSet is implemented using a hash table. Elements are not ordered. The add, remove, and contains methods have constant time complexity O(1).
LinkedHashSet - uses Trees (RB-Trees). Elements are not ordered. Complexity for the same methods is O(log n)
TreeSet - uses a hash table with a linked list running through it. Elements are ordered. The time complexity of the same methods is O(1).
E.g.
HashSet<Integer> set = new HashSet<>();
for(int n : a) {
set.add(n);
}
for (int n : b) {
set.add(n);
}
So, it provides a linear order here - O(n+m).