I'm taking a binary String like this:
010010010000110100001010
as a String, converting it to Integer Array like this:
int[] DD = new DD[binString.length()];
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
and I'm tying to save these Integer values in to HashMap(I have to store into a HashMap as per instructions given to me) like this:
Map<String, Integer> toMemory = new HashMap<String, Integer>();
for(int i=0;i<binString.length();i++) {
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
if((DD[i] & (DD[i]-1) ) == 0) {
toMemory.put(new String("ON"), new Integer(DD[i]));
} else {
toMemory.put(new String("ON"), new Integer(DD[i]));
}
}
for(String s: toMemory.keySet()) {
if(s.startsWith("ON")) {
System.out.println(toMemory.get(s));
}
}
The issue I'm facing here is that, only one entry is being stored in the HashMap, say {"ON",0}. And no other values are being stored. My expected output is this:
{"ON" , 1 , "OFF" , 0, "ON" , 1 .........}
Is there any better way to store the values to get my expected output? Any help will be much appreciated.
P.S: Please ignore the recurring code, and I'm relatively new to programming.
Your usage of a Map is flawed. Maps take a unique key and return a value.
You are trying to use duplicate keys. Instead, look at using a List with a wrapper class:
class ClassName {
public String status;
public int value;
public ClassName(String status, int value){
this.status = status;
this.value = value;
}
}
List<ClassName> list = new ArrayList();
To add to the list, create a new instance of your class and call List#add:
list.add(new ClassName("ON", 1));
as Infuzed Guy said, you are using the Map the wrong way. It's a unique "key to value mapping".
As long as you are using several times the same key and want to store all the dada, you need to use a List.
Here is what I could come up with the little you gave us: test it here
import java.util.LinkedList;
import java.util.List;
class Main {
public static void main(String[] args) {
class Tuple<X, Y> { //The wrapper object
public final X x;
public final Y y;
public Tuple(X x, Y y) { //Object constructor
this.x = x;
this.y = y;
}
public String toString() //Here for printing purpose
{
return "\"" + this.x + "\", " + this.y;
}
}
//Note here te use of List
List<Tuple> toMemory = new LinkedList<>();
String binString = "10100100101100101011";
int[] DD = new int[binString.length()];
for(int i=0; i < binString.length(); ++i)
{
//Here I use the char value
//to get the by subtraction
DD[i] = binString.charAt(i) - '0';
if(DD[i] == 1) //Simple check with the int value
{
toMemory.add(new Tuple<>("ON", DD[i]));
}
else
{
toMemory.add(new Tuple<>("OFF", DD[i]));
}
}
//Print the List
System.out.print("{ ");
for(Tuple s: toMemory) {
System.out.print(s +", ");
}
System.out.println("}");
}
}
Related
I need to compare the roman letters and get the correct integer out of it.
If I'm correct, there should be a way to compare the hashmap key with the arraylist element and if they match, get the associated value from the key.
The return 2020 is there just for test purposes, since I wrote a JUnit test in a different class. It can be ignored for now.
I hope someone could give me a hint, since I wouldn't like to use the solutions from the web, because I need to get better with algorithms.
package com.company;
import java.util.*;
public class Main {
static HashMap<String, Integer> romanNumbers = new HashMap<String, Integer>();
static {
romanNumbers.put("I", 1);
romanNumbers.put("V", 5);
romanNumbers.put("X", 10);
romanNumbers.put("L", 50);
romanNumbers.put("C", 100);
romanNumbers.put("D", 500);
romanNumbers.put("M", 1000);
}
public static void main(String[] args) {
romanToArabic("MMXX");
}
static int romanToArabic(String roman) {
ArrayList romanLetters = new ArrayList();
roman = roman.toUpperCase();
for (int i = 0; i < roman.length(); i++) {
char c = roman.charAt(i);
romanLetters.add(c);
}
// [M, M, X, X]
System.out.println(romanLetters);
// iterates over the romanLetters
for (int i = 0; i < romanLetters.size(); i++) {
System.out.println(romanLetters.get(i));
}
// retrive keys and values
for (Map.Entry romanNumbersKey : romanNumbers.entrySet()) {
String key = (String) romanNumbersKey.getKey();
Object value = romanNumbersKey.getValue();
System.out.println(key + " " + value);
}
return 2020;
}
}
You could just Map.get each array element.
package com.company;
import java.util.ArrayList;
import java.util.HashMap;
public class Main {
static HashMap<String, Integer> romanNumbers = new HashMap<String, Integer>();
static {
romanNumbers.put("I", 1);
romanNumbers.put("V", 5);
romanNumbers.put("X", 10);
romanNumbers.put("L", 50);
romanNumbers.put("C", 100);
romanNumbers.put("D", 500);
romanNumbers.put("M", 1000);
}
public static void main(String[] args) {
System.out.println(romanToArabic("MMXX"));
}
static int romanToArabic(String roman) {
ArrayList romanLetters = new ArrayList();
roman = roman.toUpperCase();
for (int i = 0; i < roman.length(); i++) {
char c = roman.charAt(i);
romanLetters.add(c);
}
// [M, M, X, X]
System.out.println(romanLetters);
// iterates over the romanLetters
int sum = 0;
for (int i = 0; i < romanLetters.size(); i++) {
String key = String.valueOf(romanLetters.get(i));
if (romanNumbers.containsKey(key)) {
sum += romanNumbers.get(key);
}
}
return sum;
}
}
As stated in the comments, this just answers your question of how to get values from an hashmap where keys are the array elements. It is not a solution to calculate the numeric value out of a roman number. For that, you will have to look at the next letter, and join if it is larger, before consulting the map for the final value to sum.
I'd like to suggest a completly different approach using an enum.
public enum RomanNumber {
I(1), V(5), X(10), L(50), C(100), D(500), M(1000);
private final int arabic;
RomanNumber(int arabic) {
this.arabic = arabic;
}
public int getArabicNumber() {
return arabic;
}
// This is obviously broken. IV wouldn't work for example.
public static int toArabic(String romanLetters) {
romanLetters = romanLetters.toUpperCase();
int arabicResult = 0;
for (int i = 0; i < romanLetters.length(); i++) {
char romanNumber = romanLetters.charAt(i);
// valueOf(String) returns the enum based on its name. So a String of "I" returns the RomanNumber I enum.
int arabicNumber = valueOf(String.valueOf(romanNumber)).getArabicNumber();
arabicResult = arabicResult + arabicNumber;
}
return arabicResult;
}
}
Can be used like this:
String romanNumber = "MMXX";
System.out.println(RomanNumber.toArabic(romanNumber));
Btw. every enum has an ordinal() method which returns the declaration position inside the enum. (I.ordinal() == 1 or V.ordinal() == 2) I think this could help you with the IV problem aswell. :)
user can create as many instances of Thing as they please. a user inputs a string into the object with a number.
eg of created objects
Thing thing1 = new Thing("input1", 3);
Thing thing2 = new Thing("input2", 1);
Thing thing3 = new Thing("input2", 3000);
Thing thing4 = new Thing("input1", 4);
Thing thing5 = new Thing("input4", 200");
ArrayList<Thing> ThingList= new ArrayList<Thing>();
ThingList.add(thing1);
.....
.....
I need to have the the program search through an ArrayList of Things and output the inputed String with the combined total of all integers with the same inputed string
output example
name count
input1 7
input2 3001
input4 200
Im not sure how I can do this without doubling up on inputs with the same name. unless I compare to a name entered by me
what I have done so far (note it can only find and total what I have inputed for it to search.)
for( i= 0; i< ThingList.size(); i++){
inputedThingCheck = ThingList.get(i).getInputedName();
//testInput is the input I know for a fact is inside arraylist
if(inputedThingCheck.equals(testInput)){
thingTotal = ThingList.get(i).getCount() + thingTotal;
}
}
I want to know how to have the program search through each Thing object and add to a total the count of all things with the same name, while skipping the Thing that has already been done
You can try something like this with Collectors.groupingBy
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Thing {
private String key;
private int value;
public Thing(String key, int value) {
super();
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
#Override
public String toString() {
return "Thing [key=" + key + ", value=" + value + "]";
}
public static void main(String[] args) {
List<Thing> source = Arrays.asList(
new Thing("input1", 3),
new Thing("input2", 1),
new Thing("input2", 3000),
new Thing("input1", 4),
new Thing("input4", 200));
List<Thing> target = source.stream().collect(Collectors.groupingBy(thing -> thing.key)).entrySet().stream()
.map(e -> e.getValue().stream().reduce((f1, f2) -> new Thing(f1.key, f1.value + f2.value)))
.map(f -> f.get()).collect(Collectors.toList());
System.out.println(target);
}
}
Thank you!
you can also implement the groupby function for example java 8
Map<String, Integer> sum = list.stream().collect(
Collectors.groupingBy(Thing::getkey, Collectors.summingInt(Thing::getValue)));
Instead of using ArrayList to contain the thing object, I guess it would be easier if we store it as a key, value pair. The key can be the name of the thing, and the value can an array containing the count of that particular key.
ArrayList<Thing> foo = new ArrayList<Thing>();
foo.add(thing1);
foo.add(thing2);
foo.add(thing3);
foo.add(thing4);
foo.add(thing5);
Map<String, ArrayList<Integer>> ThingList = new HashMap<String, ArrayList<Integer>>();
for (Thing x : foo){
if (ThingList.containsKey(x.getName())){
ArrayList value = ThingList.get(x.getName());
value.add(x.getValue());
}
else{
container = new ArrayList<Integer>();
container.add(x.getValue());
ThingList.put(x.getName(), container);
}
}
// Debug to check the key, value pair of ThingList
// System.out.println(Arrays.asList(ThingList));
// Loop through ThingList and get the key + sum of its related values
for (Map.Entry<String, ArrayList<Integer>> entry : ThingList.entrySet()) {
String key = entry.getKey();
ArrayList value = entry.getValue();
int valueSum = 0;
for (int i=0 ; i < value.size() ; i++){
valueSum += (Integer)value.get(i);
}
// Print the output
System.out.println(key + " " + String.valueOf(valueSum));
}
}
i have a situation where i have to read xml files where i get three elements like this
2019-03-19,null,null
2016-11-30,null,null
2016-10-14,null,null
2016-09-30,null,null
2016-09-30,1,YEARS
2016-09-30,3,MONTHS
2016-09-30,4,MONTHS
I have to store all three items on some data structure and apply my logic like below
I have to find the max of last item and then for that i have to find the max of second item then for that i have to find the max of first element of more than one is present .
Please suggest me some idea
Create a single object like below that can hold all three data elements and is also capable of handling a "null" value for the quantity and term length values. You may want to have the constructor convert the String date (2019-03-19) into a real date object or you could handle that before object creation. Then add these objects to a data structure (i.e. list, etc) that you can use to manage and organize them.
public class ListElement {
public Date date;
public Integer qty;
public String termLength;
public ListElement(Date d, Integer q, String t) {
this.date = d;
this.qty = q;
this.termLength = t
}
// getter methods
public Date getDate() {
return this.date;
}
public Integer getQty() {
return this.qty;
}
public String getTermLength() {
return this.termLength;
}
public toString() {
return System.out.println(this.date + "::" +
this.qty + "::" +
this.termLength)
}
}
You can create an enum if you have some predefined terms:
enum Term {
AGES, YEARS, MONTHS, WEEKS, DAYS, HOURS, MINUTES, SECONDS;
}
And use it in your class with other two types as:
public class MyObjects {
private Date date;
private Integer quantity;
private Term term;
public MyObjects(Date date, Integer quantity, Term term) {
this.date = date;
this.quantity = quantity;
this.term = term;
}
// getters, setters
}
Then define the constructor that accepts these 3 arguments and use it while processing XML file.
Two different ways to store the data. One is 2D array and the other is arraylist. All the data is type String. You would have to Parse the Integers using Integer.parseInt() to get int value. You will also have to catch for null values. This assumes that your xml data have newline characters at the end of each line.
public static void main(String[] args) {
// TODO code application logic here
//Assuming there are \n char at end of line
String xml = "2019-03-19,null,null\n" +
"2016-11-30,null,null\n" +
"2016-10-14,null,null\n" +
"2016-09-30,null,null\n" +
"2016-09-30,1,YEARS\n" +
"2016-09-30,3,MONTHS\n" +
"2016-09-30,4,MONTHS";
System.out.println("2D Array Output:");
String[][] twoDArrayExample = twoDArrayVersion(xml);
//print 2D array
for(int i = 0; i < twoDArrayExample.length; i++)
{
for(int z = 0; z < twoDArrayExample[i].length; z++)
{
System.out.print(twoDArrayExample[i][z] + " - ");
}
System.out.println();
}
System.out.println("\n\nArray List Output:");
ArrayList<ArrayList<String>> arrayListExample = arrayListVersion(xml);
//print arraylist
for(ArrayList<String> entry : arrayListExample)
{
for(String item : entry)
{
System.out.print(item + " + ");
}
System.out.println();
}
}//end of main
static String[][] twoDArrayVersion(String xml)
{
String[][] dataHolder;
String[] tempDataHolder = xml.split("\n");
dataHolder = new String[tempDataHolder.length][3];
for(int i = 0; i < tempDataHolder.length; i++)
{
String[] tempDataHolder2 = tempDataHolder[i].split(",");
dataHolder[i][0] = tempDataHolder2[0];
dataHolder[i][1] = tempDataHolder2[1];
dataHolder[i][2] = tempDataHolder2[2];
}
return dataHolder;
}
static ArrayList<ArrayList<String>> arrayListVersion(String xml)
{
ArrayList<ArrayList<String>> dataHolder = new ArrayList();
String[] tempDataHolder = xml.split("\n");
for(int i = 0; i < tempDataHolder.length; i++)
{
ArrayList<String> tempArrayList = new ArrayList();
String[] tempDataHolder2 = tempDataHolder[i].split(",");
tempArrayList.add(tempDataHolder2[0]);
tempArrayList.add(tempDataHolder2[1]);
tempArrayList.add(tempDataHolder2[2]);
dataHolder.add(tempArrayList);
}
return dataHolder;
}
Example:
d1 = "the sky is blue"
d2 = "the car is blue"
Key Value
the [<d1,1>,<d2,1>]
sky [<d1,1>]
is [<d1,1>,<d2,1>]
blue [<d1,1>,<d2,1>]
car [<d2,1>]
Where:
key = String
ex:
<d1,1>
d1 = Document id
1 = How many times the word apear on file
I created a document type object with the docid variables and frequency.
public class Documento {
private final int docid;
private final int frequencia;
public Documento(int docid, int frequencia) {
this.docid = docid;
this.frequencia = frequencia;
}
public int getDocid() {
return docid;
}
public int getFrequencia() {
return frequencia;
}
#Override
public boolean equals(Object o) {
if ((o instanceof Documento) && docid == ((Documento) o).docid && frequencia == ((Documento) o).frequencia) {
return true;
}
return false;
}
And the dictionary class that is a hashmap with
public class Dicionario {
public Map<String, Documento> indice = new HashMap<>();
public void InsereDicionario(String palavra, int docid) {
int cont = indice.containsKey(palavra) ? indice.get(palavra).getFrequencia() : 0;
indice.put(palavra, new Documento(docid, cont + 1));
}
public int frequencia(String palavra) {
return indice.get(palavra).getFrequencia();
}
public void criaDicionario(String entrada) {
String[] palavras = entrada.split("\\s+");
for (int i = 0; i < palavras.length; i++) {
InsereDicionario(palavras[i], 1);
}
}
public void ListaPalavras(){
for(String key:indice.keySet()){
System.out.println("");
}
}
But what I really need the dictionary is a list of documents , and I do not know how to do this , someone could help me ?
or is there an easier way to do this ?
If you need a list of documents, why not create one? With Java8 this becomes even more convenient:
For example:
public Map<String, List<Documento>> indice = new HashMap<>();
//register new word
indice.putIfAbsent(palavra, new ArrayList<>());
//add additional occurence
indice.get(palavra).add(documento);
//get frequency
int frequencia = indice.get(palavra)
.stream()
.map(d -> d.getFrequencia())
.reduce(0, (s, i) -> s + i);
An alternative would be to use Guava's Multimap, see here
Map<String, List<Documento>>
Obviously you need to adapt the rest of the code.
For example, when you need to add something to the dictionary, if it's the first time you need to create the List with that single document, next time you need to take the already created list and add documents there.
I have an declared an ArrayList a = [1,2,3]. I created another ArrayLList b using the loop below:
for(int i = 0; i<a.size(); i++)
{
for(int j=i+1; j<a.size();j++)
{
b.add("{" + a.get(i)+ "," + a.get(j) + "}");
}
}
Now the ArrayList b will contain elements [{1,2},{1,3},{2,3}]. Now if I print the statement using System.out.println(b.get(0)), then the output will be {1,2}.
Now I want to to further explore the array such that I can extract 1 and 2 separately. How can I achieve this?
create class pair
class Pair{
String a
String b
....
///setters and getters
}
now let b will be List<Pair> so instead calling b.add("{" + a.get(i)+ "," + a.get(j) + "}"); you can do simple b.add(new Pair(a.get(i),a.get(j));
then you don't need to play with splitting string and stuff like that, you can easly access your values by doing ie b.get(0).getA() or b.get(0).get()
you can also override method to string in pair
public String toString() {
return "{" + a+ "," + b + "}";
}
so when you do System.out.println(a.get(0)) you will get exactly same output like before
***EDIT
if you want to have a groups of more than 2 elements as you say in comment
you can construct your class little bit different
class MyClass{
List<Integer> fields = new ArrayList<Integer>();
//two constructors
MyClass(int singleVal)
{
fields.add(singleVal);
}
MyClass(MyClass a, MyClass b)
{
fields.addAll(a.fields);
fields.addAll(b.fields);
}
//getters setters depends what you need
}
both of your list will be list of MyClass, when you populate list a, you create objects by using first constructor, when you want to add elements to your b list you can do b.add(new MyClass(a.(i),a.(j))) but you can also do b.add(new MyClass(a.(i),b.(j))) or b.add(new MyClass(b.(i),b.(j)))
I understand that your array b holds just strings. Use any String tokenizing mechanism to achieve this - either String.split or StringTokenizer
Hint : StringTokenizer performs better
You should decompose the presentation from logic.
In your loop you create a pair of element. So create a some type to represent it.
class Pair {
private int left;
private int right
Pair(int left, int right) {
this.left = left;
this.right = right;
}
public int getLeft() {
return this.left;
}
public int getRight() {
return this.right;
}
#Override
public void toString() {
return String.format("{%d , %d}",getLeft(),getRight());
}
}
List list = new ArrayList();
for(int i = 0; i<a.size(); i++)
{
for(int j=i+1; j<a.size();j++)
{
list.add(new Pair(i,j));
}
}
Then to access (extract) items
int l = list.get(0).getLeft();
int r = list.get(0).getRith();
If you want to display on console the result.
for(Pair p : list) {
System.out.println(p);
}
About output format
EDIT
AS the OP mentioned in the comment. He would like to have flexible data structure that allow him to store the data.
List<List<Integer> parent = new ArrayList<List<Integer>()
for(int i = 0; i<a.size(); i++)
{
List<Integer> child = new ArrayList<Integer>();
for(int j=i+1; j<a.size();j++)
{
child.add(a.get(i));
child.add(a.get(j));
}
parent.add(child);
}
String ele = b.get(0);
ele = ele.replace("{", "");
ele = ele.replace("}", "");
StringTokenizer tokens = new StringTokenizer(ele, ",");
while(tokens.hasMoreTokens()) {
int val = Integer.parseInt(tokens.nextToken());
}