Adding values from HashSet to 2D Matrix - java

I have a Map structure that contains an Integer as a key and a set of Objects as the values. However, I have overriden the toString method to get the Integer values of the values. So, example, the Map would look like
Key: 1 Values: [1, 2, 4]
I am having a bit trouble constructing a 2D Matrix out out this Map Structure. When I am looping through, I am checking to see if my iterator value is a key in the Map but I am having trouble checking to see if the second iterator is equal to the set value. This is the part of the code in question
for (int i = 1; i < this.adjacencyMatrix[0].length; i++) {
System.out.print(i + " ");
}
System.out.println();
for (int i = 1; i < this.adjacencyMatrix.length; i++) {
System.out.print(i + " ");
for (int j = 1; j < this.adjacencyMatrix[i].length; j++) {
if (this.nodes.containsKey(i)) {
// Handle the set
this.adjacencyMatrix[i][j] = 1;
} else {
this.adjacencyMatrix[i][j] = 0;
}
System.out.print(this.adjacencyMatrix[i][j] + " ");
}
System.out.println();
}
My matrix right now will print 1's for the entire row of the map keys.
Example, if 4 is a key, the entire 10 rows will all be printing 1. However, say I have a mapping like 4-- [1, 2, 4] only 1, 2, 4 should have 1's in the given row, all the rest should be 0.

The if-condition (containsKey) is true (or false) for every step of the inner loop.
The inner loop should be replaced by two loops: First loop on the index j and initialize all values to 0. Then iterate on the elements in the nodes set, take each value and use it as index:
adjacencyMatrix[i][value] = 1

Related

How to print matching elements in different positions between two arrays? (java)

I have two arrays. Array1 holds 5 randomly generated numbers and array2 holds 5 guesses inputted by the user. I'm trying to count the matches but the only matches that are being read are the ones in the same position. How can I get my program to count the same number even if it's in a different position?
Here's what I've got so far:
int count = 0;
for (i=0;i<array1.length;i++){
if(array1[i] == array2[i]){
count = count +1;
}
}
System.out.println("matching numbers : "+count);
If the two arrays are both small, i.e. each array contains only five elements, then you need a nested loop. For each element in the random numbers array, iterate through the guesses array.
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array2.length; j++) {
if (array1[i] == array2[j]) {
count++;
}
}
}
System.out.println("matching numbers : "+count);
Note that the above is appropriate when both arrays are small. When both arrays are large the above is not appropriate.
You just need the intersection between the two arrays and then to count the size of the result array.
So you can avoid to manually loop over the two arrays just simply using the retainAll method on List class:
https://docs.oracle.com/javase/7/docs/api/java/util/List.html#retainAll
Here is a junit test that shows how to solve using this approach:
#Test
public void TestArraysIntersection() {
Integer[] randomlyGenerated = {1,2,3,4,5};
Integer[] userInput = {4,2,5,3,6};
System.out.println("Randomly generated numbers are: " + Arrays.toString(randomlyGenerated));
System.out.println("Number selected by the user are: " + Arrays.toString(userInput));
List<Integer> intersectionList = new ArrayList<>(Arrays.asList(randomlyGenerated));
intersectionList.retainAll(Arrays.asList(userInput));
System.out.println("Matching numbers are " + intersectionList.size() + " and the values are: "+ intersectionList);
}
Test result is the following:
Randomly generated numbers are: [1, 2, 3, 4, 5]
Number selected by the user are: [4, 2, 5, 3, 6]
Matching numbers are 4 and the values are: [2, 3, 4, 5]
You need to loop through both arrays. In your code you are comparing each element of one array with the element in the same position of the other array, but you have to compare each element of one array with every element of the other array, like this:
public class MyClass {
public static void main(String args[]) {
int[] numbers = {1, 3, 0, 6};
int[] guesses = {3, 8, 5, 1, 2};
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < guesses.length; j++) {
if (numbers[i] == guesses[j]) {
System.out.println("A match on positions "+i+" and "+j+". "+numbers[i]+" = "+guesses[j]);
}
}
}
}
}
Output:
A match on positions 0 and 3. 1 = 1
A match on positions 1 and 0. 3 = 3
Of course, instead of outputting the values that match, you can instead increment a count like in your example, and show instead how many elements matched.

Dynamic programming with Combination sum inner loop and outer loop interchangeable?

I am a little confuse about the dynamic programming solution for combination sum, that you are given a list of numbers and a target total, and you want to count how many ways you can sum up to this target sum. Numbers can be reused multiple times. I am confused about the inner loop and outer loop that whether they are interchangeable or not. Can some explain the difference between the following two, and in what case we would use one but not the other, or they are the same.
int [] counts = new int[total];
counts[0] = 1;
// (1)
for(int i = 0; i <= total; i++) {
for(int j = 0; j < nums.length; j++) {
if(i >= nums[j])
counts[i] += counts[i - nums[j]];
}
}
// (2)
for(int j = 0; j < nums.length; j++)
for(int i = nums[j]; i <= total; i++) {
counts[i] += counts[i - nums[j]];
}
}
The two versions are indeed different, yielding different results.
I'll use nums = {2, 3} for all examples below.
Version 1 finds the number of combinations with ordering of elements from nums whose sum is total. It does so by iterating through all "subtotals" and counting how many combinations have the right sum, but it doesn't keep track of the elements. For example, the count for 5 will be 2. This is the result of using the first element (with value 2) and finding 1 combination in nums[3] and another combination for the second element (value 3) with the 1 combination in nums[2]. You should pay attention that both combinations use a single 2 and a single 3, but they represent the 2 different ordered lists [2, 3] & [3, 2].
Version 2 on the other hand find the number of combinations without ordering of elements from nums whose sum is total. It does so by counting how many combinations have the right sum (fur each subtotal), but contrary to version 1, it "uses" each element completely before moving on to the next element thus avoiding different orderings of the same group. When counting subtotals with the first element (2), all counts will initially be 0 (except the 0 sum sentinel), and any even subtotal will get the new count of 1. When the next element used, it is as if it's coming after all 2's are already in the group, so, contrary to version 1, only [2, 3] is counted, and not [3, 2].
By the way, the order of elements in nums doesn't affect the results, as can be understood by the logic explained.
Dynamic programming works by filling out entries in a table assuming that previous entries in the table have been fully completed.
In this case, we have counts[i] is dependent on counts[i - nums[j]]; for every entry j in nums.
In this code snippet
// (1)
for(int i = 0; i < total; i++) {
for(int j = 0; j < nums.length; j++) {
if(i >= nums[j])
counts1[i] += counts1[i - nums[j]];
}
}
We fill the table in order from 0 to total in that order. This is the action of the outer loop. The inner loop goes through our different nums and updates the current entry in our table based on the previous values, which are all assumed to be completed.
Now look at this snippet
// (2)
for(int j = 0; j < nums.length; j++){
for(int i = nums[j]; i < total; i++) {
counts2[i] += counts2[i - nums[j]];
}
}
Here we are iterating through our list of different counts and updating our totals. This breaks the concept of dynamic programming. None of our entries can ever be assumed to be complete until we are completely finished with our table.
Are they the same? The answer is no they are not. The following code illustrates the fact:
public class dyn {
public static void main(String[] args) {
int total = 50;
int[] nums = new int[]{1, 5, 10};
int [] counts1 = new int[total];
int [] counts2 = new int[total];
counts1[0] = 1;
counts2[0] = 1;
// (1)
for(int i = 0; i < total; i++) {
for(int j = 0; j < nums.length; j++) {
if(i >= nums[j])
counts1[i] += counts1[i - nums[j]];
}
}
// (2)
for(int j = 0; j < nums.length; j++){
for(int i = nums[j]; i < total; i++) {
counts2[i] += counts2[i - nums[j]];
}
}
for(int k = 0; k < total; k++){
System.out.print(counts1[k] + ",");
}
System.out.println("");
for(int k = 0; k < total; k++){
System.out.print(counts2[k] + ",");
}
}
}
This will output 2 different lists.
They are different because we are updating our counts[i] with incomplete information from earlier in the table. counts[6] assumes you have the entry for counts[5] and counts[1], which in turn assume you have the entries for counts[4], counts[3], counts[2], and counts[0]. Thus, each entry is dependent on (in the worst case all of) the previous entries in the table.
Addendum:
Interesting (perhaps obvious) side-note:
The two methods produce the same list up until the smallest pairwise sum of entries in nums.
Why?
This is when the information from previous entries becomes incomplete (with respect to the first loop). That is, if we have int[] nums = new int[]{3, 6}, then counts[3+6] will not be computed correctly, because either
count[3] will not be right or count[6] will not align with the result obtained using the first loop, depending on which stage of the computation we have done yet.
In light of criticism of my previous answer, I thought I'd take a more mathematical approach.
As in #Amit 's answer, I will use nums = {2, 3} in examples.
Recurrence Relations
The first loop computes
S(n) = S(n-3) + S(n-2)
Or, more generally, for some set {x_1, x_2, x_3, ... ,x_k}:
S(n) = S(n- x_1) + S(n- x_2) + ... + S(n- x_k)
It should be clear that each S(n) is dependent on (possibly all) previous values, and so we must start on 0 and populate the table upwards to our desired total.
The second loop computes a recurrence S_2(n) with the following definitions:
S_1(n) = S_1(n-2)
S_2(n) = S_1(n) + S_2(n-3)
More generally, for some set {x_1, x_2, x_3, ... ,x_k}:
S_1(n) = S_1(n- x_1)
S_2(n) = S_1(n) + S_2(n- x_2)
...
S_k(n) = S_{k-1}(n) + S_k(n- x_k)
Each entry in this sequence is like those from the first loop; it is dependent on the previous entries. But unlike the first loop, it is also dependent on earlier sequences.
Put perhaps more concretely:
S_2 is dependent on not only (possibly all) previous entries of S_2, but also on previous entries of S_1.
Thus, when we want to compute the first recurrence, we begin at 0 and compute each entry, for each number in our nums.
When we want to compute the second recurrence, we compute each intermediate recurrence one at a time, each time storing the result in counts.
In Plain English
What do these two recurrences compute? As #Amit 's answer explains, they compute the number of combinations that sum to total, with and without preserving order. It's easy to see why, again using our example of nums = {2, 3}:
Note my use of the word list to denote something ordered, and the word set to denote something unordered.
I use append to mean adding to the former, and add to denote adding to the latter.
If you know
how many lists of numbers add to 2,
and how many add to 3,
and I ask you
how many add to 5?
You can append a 3 to every one of the former lists, and a 2 to every one of the latter lists.
Thus (how many add to 5) = (how many add to 3) + (how many add to 2)
Which is our first recurrence.
For the second recurrence,
If you know
how many sets of just 2's add to 5 (0)
how many sets of just 2's and 3's add to 2 (1)
You can just take all of the first number, and you can add a 3 to all the sets in the second number.
Note how "sets of just 2's" is a special case of "sets of just 2's and 3's". "sets of just 2's and 3's" depends on "sets of just 2's", just like in our recurrence!
Recursive functions written in java
The following recursive function computes the values for the first loop, with example values 3 and 2.
public static int r(int n){
if(n < 0)
return 0;
if(n == 0)
return 1;
return r(n-2) + r(n-3);
}
The following set of recursive functions computes the values for the second loop, with example values 3 and 2.
public static int r1(int n){
if(n < 0)
return 0;
if(n == 0)
return 1;
return r1(n-2);
}
public static int r2(int n){
if(n < 0){
return 0;
}
return r1(n) + r2(n-3);
}
I have checked them up to 10 and they appear to be correct.

Basic Array Skills: Label Each Element

I have to perform the following basic skills with arrays: Here is a list of everything I had to do:
a) Create an array x of doubles with an initializer list that contains the following values: 8, 4, 5, 21, 7, 9, 18, 2, and 100.
b) Print the number of items in the array.
c) Print the first array item.
d) Print the last array item. Be careful to choose the right index.
e) Use a standard for loop to print all the values in the array.
f) Use a standard for loop to print all the values in the array with labels to indicate the location of each element, such as [0] = xx
g) Use a standard for loop to print all the values in the array in reverse order.
h) Use an enhanced for loop to print all the values in the array.
I am having a lot of trouble with f), I saw that you could label using "JLabel" which I did not learn in my class but I wasn't sure if it could be applied here, here is my code so far. If "JLabel" can't be used, what else would I be able to do? Any help will be appreciated, Thanks!!!
public static void main(String[] args) {
double[] x = {8, 4, 5, 21, 7, 9, 18, 2, 100};
double temp;
System.out.println("The number of items in the array is " + x.length);
System.out.println("The first array item is " + x[0]);
System.out.println("The last array item is " + x[8]);
for(int i = 0; i < 9; i++)
{
System.out.println(x[i] + " ");
}
//F
//JLabel labels[] = new JLabel[8];
//for (int i = 0; i < 9; i++)
//{
//labels[i] = new JLabel("Label" + i);
//}
for(int i =x.length - 1; i >= 0; i--)
{
System.out.println(x[i] + " ");
}
for (double val : x)
{
System.out.println(val + " ");
}
}
}
JLabel is a Swing GUI component. It represents a text label in a GUI. It is not what you want to use here (although I can understand your attraction to the "Label" in its name -- but, you don't make ham with a hammer).
Your requirement is simply "print all the values in the array with labels to indicate the location of each element, such as [0] = xx". That is, "labels" in the dictionary sense, not "labels" as in some explicit special "label" class.
It's simpler than you think, you may be over-complicating this! For example:
for (int i = 0; i < x.length; i ++) {
// 'i' is the index
// 'x[i]' is the value
System.out.println( /* fill this in */ );
}
I'll leave the details as an exercise to you. Hint: If i==1 and x[i]==42 then the output should be [1] = 42.

User input java array

I need to create a program that will query the user for the size of a 2-dimentional array, and then fill the array with sequential integer data, starting with a user defined initial vale. I have some part of the program but I am stuck at the end.
What you want is this:
int value = scanner.nextInt();
for (int i = 0; i < rows; i++){
for (int j = 0; j < columns; j++){
array[i][j] = value + i * columns + j;
}
}
Try that out and it should work as expected.
Input:
2
2
5
Output:
[5, 6]
[7, 8]
Be sure to use Arrays.deepToString(array) to print out the array properly.
This will print out the row and column it is going to request for, then prompt you to fill it in.
Also:
array[rows][columns] = scanner.nextInt();
Will not work as you expect. That will fill in a single cell in the array, not to even mention it will throw an IndexOutOfBounds exception.

Java - Listing the index of duplicate values in an int array

I have to locate and list all duplicate index values in array.
Example:
int[] array = { 0, 7, 9, 1, 5, 8, 7, 4, 7, 3};
7 is located in three different locations at index 1, 6, and 8. How would I go about modifying my existing code in order to have outputResults.setText() show the location of the duplicate values? outputResults.setText() is JTextField if that helps.
String tmp1 = getNumbers.getText();
try {
int search = Integer.parseInt(tmp1);
for (p = 0; p < array.length; p++) {
if(array[p]==search) {
b = true;
index = p;
}
}
if(b==true)
outputResults.setText(search + " was in the following fields of the array " + index);
else
throw new NumberNotFoundException("Your number was not found.");
} catch (NumberFormatException ex) {
JOptionPane.showMessageDialog(getContentPane(), "You can only search for integers.");
} catch (NumberNotFoundException ex) {
JOptionPane.showMessageDialog(getContentPane(), ex.getMessage());
}
At it's current state, it will only list the last time the duplicate number was located which would be index 8 based on my example. The list of numbers in the array is inputted by the user, and I'm not allowed to sort the values. My original guess was to create a nested loop and whenever it located an duplicated number, add p (current index it's searching) to a new array. I would then list the full array in outputResults.setText() but it gave several warnings and errors when I tried.
The full code can be found here if needed: http://pastebin.com/R7rfWAv0
And yes, the full program is a mess but it gets the job done and I was having such a headache with it. Also note, in the full program, the professor asked us to throw an exception if a duplicate value was detected as extra credit. I did it, but I commented it out to finish the original assignment so please disregard it.
I think you should use a List to record the indexs
List<Integer> indexs =new ArrayList<Integer>();
for (p = 0; p < array.length; p++) {
if(array[p]==search) {
indexs.add(p);
}
}
if(p.length()>0){
//print the result
}
No need for Hash tables, lists or whatever, you can do this very easily as so:
int [] array = { 0, 7, 9, 1, 5, 8, 7, 4, 7, 3};
int pointer=0;
int currNumber;
while(pointer<array.length)
{
currNumber=array[pointer];
for(int i=0;i<array.length;i++){
if(currNumber==array[i] && i>pointer){
System.out.println("Duplicate for "+currNumber +" in " +i);
break;
}
}
pointer++;
}
It will print all duplicates for all the numbers in the array.
Duplicate for 7 in 6
Duplicate for 7 in 8
Obviously, you'd probably have to concatenate a string and display it at the end of the loop by calling outputResults.setText()
Demo here.
How about just two for loops?
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[i] == array[j]) {
System.out.println("Duplicate - " + array[i] + " found at index " + i + " and " + j);
}
}
}
One option would be to create a HashMap that used the value as the key, and a collection of indexes for the value. As you scan the array, if the value isn't in the HashMap, add it w/ a new collection of the index. If the value is in the array, pull the collection, add the next index and finish the iteration.
Once that's complete, iterate the HashMap, any entry who has a value with size() > 1 has duplicates.
As you're iterating through the array, you are overwriting any previously found index with the line index = p;. This line only works if there is one occurrence of the value being searched. Let index be a string and concat to it each time you arrive at that line, so that index += " "+p;. Your line:
outputResults.setText(search + " was in the following fields of the array " + index);
will then print out all of the found indices for the value being searched.
So, there are several ways to complete your solution (some naive and some optimal) with that being said; you should think through what you're trying to achieve and figure out what each line is doing in your code (debug) when you have an issue.

Categories