So I have a document on excel and I have a list of data saying how many people use x or y and how many times. So basically i have a column with people ID, a column with type (x and y) then a column saying how many times the people use x or y. I want to be able to iterate through the list without changing it so as it get the number of people using each type and i want the list to be sorted in ascending order or frequency. So I wanted to use a for loop to go through the list and put an if statement inside of it saying that if x, then another for loop to be able to group them by frequency.
The actual code I have is not good but I am really stuck on that and do not really know how to proceed :
for(int i = 0; i < type1.size(); i++){
if(events.get(i).isX()){
for(int j = 0; j < /*max value of the data in the list*/; j++ )
//here list should group all common frequency
}
else
//do same thing but for y
Excel table eg
QUESTION
Under the assumption that you have an excel-file with three columns:
id | type | frequency
And a List representing the data of your excel-file. You might want to order your Entrys with the Collections.sort(Comparator<T>) method.
Here is an example on how you can achieve that:
Example a:
Arraylist<Row> yourList = new ArrayList();
fillListWithExlData(yourList);
for(int i = 0; i < yourList.size(); i++){
Collections.sort(yourList, new Comparator<Row>()){
//compares row i with the following row
compare(Row oneRow, Row followingRow){
//if the result is 1 =< the entry moves on higher in the list if the result is = 0 it stays on its position and if its <= -1 it moves down.
return oneRow.getFrequenzy() - followingRow.getFrequenzy();
}
});
}
Notice: that you can also use the Comparator to order your "types".
Example b:
return (oneRow.getType() == followingRow.getType()) ? 0 : -1;
Or you might even want to match both, id and frequency. Then you might try this:
Example c:
return (oneRow.getType() == followingRow.getType() &&
oneRow.getFrequenzy() == followingRow.getFrequenzy())
? 0 : -1;
example a should Order a potential List:
id | type | frequency
1 | x | 12
2 | y | 10
3 | x | 12
into:
id | type | frequency
1 | x | 12
3 | x | 12
2 | y | 10
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm working on a simple algorithm of trying to find the kth to last element from the Linearly Linked Lists
However, at my solution, it's not outputting the correct number that I expect.
I know how to solve the problem, but I'm wondering why doesn't the head recursion work the way I intended. And I would appreciate it if I receive another pair of eyes.
Wrapper function
public int findKthToLast(int kth){
//If zero items in the list
if(head == null){
System.out.println("List is empty");
return 0;
}
//If 1 item in the list
if(head.getNext() == null){
System.out.println("Only 1 item in the list which is: " + head.getData());
return 0;
}
//Allocating an array of size 1. This will help me keep track on what kth element when I go back from the recursion
int[] array = new int[1];
array[0] = -1;
//the '1' below represents the length. it will increment as you see in the recursive solution
return findKthToLast(head,kth,1,array);
}
Recursion
public int findKthToLast(Node head,int kth,int length, int [] array){
//if final item in the list
if(head.getNext() == null){
//if kth element is greater then total length just return 0
if(kth >= length){
return 0;
}
//kth = 0 means output the final item in the list. returns head.data
if(kth == 0){
return head.getData();
}
//when I backtrack from the stack I need to know if the kth to final element is equal to length. That's where the array comes from
array[0] = length - kth;
return 0;
}
int element;
element = findKthToLast(head.getNext(),kth,++length,array);
//if equal then I'm done. return the head.data
if(length == array[0]){
return head.getData();
}
return element;
}
the Problem:
In the list: 8 -> 4 -> 2 -> 1. If kth = 1 (I want the item before last so in this case the value "2") the output should be "2". However, in my current code, I'm receiving 1 number higher so the value "4"
I don't want the correct code. I know if I changed my base case from
if(head.getNext() == null)
to
if(head == null)
then my code works completely fine. What I want is why doesn't my current solution work. Am I visualizing the call stack incorrectly? Thank you
You probably outsmarted yourself because you have a really perverse way of computing the length of your list on each recursion call. Instead of just adding one to the current length, you modified the length variable so that you correctly pass in the increased length into the next recursive call... however you then use that incremented length when your function pops out, causing you to miscount.
Let's step through the example below:
8 -> 4 -> 2 -> 1
findKthToLast(8, 1, 1, [-1])
|
|-> 8.next is NOT null
|
| element = findKthToLast(4, 1, ++1, [-1])
|
| -> 4.next is NOT null
|
| element = findKthToLast(2, 1, ++2, [-1])
|
| -> 2.next is NOT null
|
| element = findKthToLast(1, 1, ++3, [-1])
|
| -> 1.next IS null
| kth is NOT 0
| => array[0] <- 4 - 1 = 3 (correct)
| return 0
| element = 0
| length is 4 != 3 because of prefix increment (length should be 3 but you incremented before calling the function)
| return 0
| element = 0
| length is 3 == 3 because of prefix increment, so return current node
| return 2 (not correct but this is what you told the code to do)
| element = 2
| length is 2 != array[0]
| return 2
| return 2
Personally, I'd go for a two pointer slow/fast approach, but if you must use recursion, then I would make it easier on myself and maintain a length counter that is incremented in the back (the last element returns 0, then on subsequent calls return element + 1) and store the correct value in the array instead.
I'm trying to create an algorithm which determines whether or not all of the rows in a 2D array of integers are unique (i.e. disjoint). Currently, I have a brute force algorithm which checks each value in each row to each value in the other rows, but I'd like to speed this up. Is there some kind of divide and conquer method to handle this? I have found some semi-solutions for this in single arrays and lists, but not in 2d arrays.
If you want to check whether there are two rows that contain the same number, you can put all the numbers along with numbers of rows that they belong to into one long list. Then sort this list which will make all the identical numbers stand next to each other. Than you can easily determine for each cluster of identical numbers whether they originally belonged to the same row or not.
If your table is n × m, the algorithm will run in O(nm × (log(n) + log(m))).
To test whether any two rows are disjoint**, make two sets (like java sets that reject duplicates and do so in almost O(1) time), one for each row and count the elements of each.
The two rows are disjoint if:
count(rowASet) + count(rowBSet) == count( union(rowASet, rowBSet) )
This suggests an algorithm for a 2D array where a rows are successively added (as sets) to a running total set. The count of the total set is measured before and after the addition of each row's set. If that count increases by the size of the row set just added, then the row just added is disjoint from those added so far.
**See the conversation with #CandiedOrange. I'm taking "disjoint row" to mean a row that contains no element found in any other row, but might itself contain repeated elements internally.
EDIT: my answer was slow and stupid. Or to put it more kindly, it was doing unnecessary work because it computed which two rows intersect instead of whether or not any two rows intersect.
After I posted I thought of 2 faster algorithms but they turned out to be Danylo Mysak's answer and the "running total set" danh hinted at.
I would still like to benchmark these different approaches.
If you are allowed to use java collections consider using java's HashSet. It was designed for things like this:
areDisjoint() inspired by http://www.geeksforgeeks.org/check-two-given-sets-disjoint/
import java.util.*;
public static void main (String[] args)
{
int[][] twoD = {{3,3,3},{4,4,4},{5,5,5}};
if ( disjointRows(twoD) )
{
System.out.println("Mutually disjoint rows");
}
else
{
System.out.println("Some element duplicated in other row");
}
}
public static boolean disjointRows(int[][] twoD)
{
// -- Copy 2D array into data structure -- //
ArrayList<HashSet<Integer>> rows = new ArrayList<HashSet<Integer>>();
for (int[] row : twoD)
{
HashSet<Integer> hs = new HashSet<Integer>();
for (int elem : row)
{
hs.add(elem);
}
rows.add( hs );
}
// Above is O = r*c time just as it would be to copy the 2D array.
// or you can express it as O(n^2)
// -- Mutual disjoint rows test -- //
// Compare every combination of rows
for (int y=1; y< rows.size(); y++)
{
for (int x=0; x<y; x++)
{
//TODO remove debugging code
System.out.print(areDisjoint( rows.get(x), rows.get(y) ) );
System.out.print("=");
System.out.print("(" + x + "," + y + ") ");
if (! areDisjoint( rows.get(x), rows.get(y) ) )
{
return false;
}
}
System.out.println("");
}
return true;
//Above is O = r(r-1)/2 * c
//or you can express it as O(n^3)
}
static boolean areDisjoint(Set<Integer> set1, Set<Integer> set2)
{
//set1 must not contain anything in set2
for (int i : set2)
{
if ( set1.contains(i) )
return false;
}
return true;
// Above is c or O(n) because contains lookup is O(1)
}
Output:
// true=(0,1)
// true=(0,2) true=(1,2)
// Mutually disjoint rows
I can't tell if this is better than your "brute force" solution since you didn't post it.
I can tell from a big O notation perspective this is neck and neck with japreiss's solution. We're both at O(n^3). This solution uses more memory because it copies the 2D array rather than mutate it. When performance is equal I strongly urge you to pick your algorithm based on readability. I admit mine is longer. I took the time to comment it.
See also: Is a Java hashmap really O(1)?
// If each row is to be disjoint from all other rows then
// then testing them all against each other would produce
// this truth table.
//
// 0 1 2
// |----|----|----|
// 0 | F | T | T |
// |----|----|----|
// 1 | T | F | T |
// |----|----|----|
// 2 | T | T | F |
// |----|----|----|
//
// Testing a row against it self can be ignored as can
// tests that simply transpose the input rows. Leaving us with
//
// 0 1 2
// |
// 0 |
// |----|
// 1 | T |
// |----|----|
// 2 | T | T |
// |----|----|
//
// So long as that's true, the rows are mutually disjoint
I'm working on an textbook assignment and am having trouble understanding arrays. I'm looking at a practice question and am confused.
Declare an array of integers containing the first five prime numbers.
This would be int[]primes = {2,3,5,7,11}
Assume the array 'primes' has been initialized. What does it contain after executing the following loop?
for(int i = 0; i < 2; i++)
{
primes[4 - i] = primes[i];
}
The textbook gives the answer {2,3,5,3,2} for this...can anyone explain how this loop works?
I assume you understand practice 1. For practice 2, the loop
for (int i = 0; i < 2; i++)
iterates twice: once at i=0, and once at i=1. At i=2, the condition i<2 is broken, and the loop does not execute.
The actual line of code inside the loop
primes[4-i] = primes[i];
sets the 4-i'th element in the array to be equal to the i'th element in the array.
Initialized, the array primes is {2,3,5,7,11}
After one loop, the array primes is {2,3,5,7,2} (primes[4] = primes[0] has been executed).
After both loops, the array primes is {2,3,5,3,2} (primes[3] = primes[1] has been executed).
Remember that arrays are indexed by zero. Hope this helped.
the for loop exceutes two times, for i=0 and i=1
primes[4-0] = primes[0] = 2 -> primes[4] = 2
primes[4-1] = primes[1] = 3 -> primes[3] = 3
so the first 3 fields in the array are not changed, just the 4th and the 5th
It seems like you don't understand for loops that well at all, since this is a pretty simple example. For loops are basically shortcuts in code that iterate through data structures. You can type out for loops line by line, but they would be way longer. In this example,
for (int i = 0; i < 2; i++)
{
primes[4 - i] = primes[i];
}
becomes:
primes[4 - 0] = primes[0];
primes[4 - 1] = primes[1];
So all this loop is doing is setting the last element of the array to the first, and the second-to-last element to the second.
Starting with
int[]primes = {2,3,5,7,11}
the for-loop works like this
i=0 -> primes[4-0] = primes[0]; //array {2,3,5,7,2}
i=1 -> primes[4-1] = primes[1]; //array {2,3,5,3,2}
Imagine you have a zoo(memory) with a row of cages(array) next to each other. each cage is the exact size needed to hold an animal(data type like int)
Zoo---------------------
[animal][animal][animal][animal][animal]
------------------------
You decide to label each cage with a number(index)
Zoo---------------------
[animal][animal][animal][animal][animal]
0 1 2 3 4
------------------------
You get some initial funding to purchase animals for your cages (initialize the array). So you buy a Zebra, Panda, Owl, Tiger, and a Bear and put them in the cages. The order you purchased the animals is the order you place them in their cages.
Zoo---------------------
[Zebra][Panda][Owl][Tiger][Bear]
0 1 2 3 4
------------------------
Your zoo just perfected cloning so you are able to make copies of the animals. You Decide people are really enjoying Pandas & Zebras but don't care for Tigers and Bears. You delegate your tasks(algorithm) by having a sequential stack of index cards with instructions(loop). Each index card has a page number going from 0 up to less than 2, so your last index card has the page number 1
_________________________ ___________________________
|0 | |1 |
| | | |
| | | |
| | | |
| | | |
|_________________________| |___________________________|
You love the number 4 and believe that it is way better then any number and should be the starting point of counting instead of the number 0. So you give all instructions using the number 4 as a reference point.
_____________________________ _____________________________
|0 | |1 |
|Yo zoo keeper, | |Yo zoo keeper, |
|Copy the animal | |Copy the animal |
|in the cage that has this | |in the cage that has this |
|card number and put it in | |card number and put it in |
|cage 4 minus this card number| |cage 4 minus this card number|
|-The Boss | |-The Boss |
|_____________________________| |_____________________________|
Your zoo keeper reads the first index card(with the number 0). He makes a copy of the Zebra and puts in the cage with the Bear. The Zebra immediately eats the bear and is the only inhabitant of the cage.
Zoo---------------------
[Zebra][Panda][Owl][Tiger][Zebra]
0 1 2 3 4
------------------------
Your zoo keeper reads the second index card(with the number 1). He makes a copy of the Panda and puts in the cage with the Tiger. The Panda immediately eats the Tiger and is the only inhabitant of the cage.
Zoo---------------------
[Zebra][Panda][Owl][Panda][Zebra]
0 1 2 3 4
------------------------
And that is how arrays work for primitives. For Objects instead of cages in your zoo you just have a map that points to where you can find the animals in the zoo. Any animal that is not on the list gets marked with a tag and swept to the wild, freeing up space in your zoo.
I have to solve the following problem. So initially i had a bubble sort and now i modified it to make it bidirectional. The following is my solution.
public void bubbleSort() {
int temp;
int out;
int outNew = 0;
int in;
for (out = nElems - 1; out > outNew; out--) {
for (in = 0; in < out; in++) {
if (a[in] > a[in + 1]) {
temp = a[in + 1];
a[in + 1] = a[in];
a[in] = temp;
}
}
for (int j = in - 1; j > outNew; j--) {
if (a[j] < a[j - 1]) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
outNew++;
}
}
When i call my bubble sort to sort few random numbers in an array i created it seems to be sorting fine. My question is rather to all you developers whether my solution is satisfying the question posted above and also what could i have done differently to make this solution more effective (if possible) . I am sorry if this is a little open question , i am usually on here looking for hints and suggestions rather than code as it helps me learn better. I appreciate all answers and am open to any suggestions.
Your first inner loop seems a bit inefficient, since your array will be partially sorted at both ends. After the first round (one time incrementing the index, one time decreasing it) the first and the last element will already be correct, hence no need to start at index 0 (and the task/exercise requires that btw).
The following ASCII art demonstrates, on which indices the algorithm should operate on at the example of a array with 9 elements (including the indices reached with in+1 and j-1; all indices between the | should be considered):
position: 0 1 2 3 4 5 6 7 8
------------------------------------------------------------
| -> |
| <- |
| -> |
| <- |
| -> |
| <- |
| -> |
| <- |
But what your algorithm does is:
position: 0 1 2 3 4 5 6 7 8
------------------------------------------------------------
| -> |
| <- |
| -> |
| <- |
| -> |
| <- |
| -> |
| <- |
You'll have to fix the the initial index of the first inner for loop.
In short, I don't think you can me more effective AND answer the question at the same time. It's pretty explicit in that you have to carry your item to the right until you find one smaller, then take that slightly smaller than the last you carried and bring it up. I don't think there's any performance gain from the regular unidirectional bubble sort but if you're going to make it bidirectional, then this is the way to do it.
How can you tell? Well since there's no performance gain/deterioration to get, the left->right code and the right->left code should be perfectly symmetrical (since they're identical in performance terms). In your case, there are so I'd say it looks good.
Thinking a bit deeper, there's probably some slight optimization to get from being bidirectional, just because you're getting an item you just looked at so you know you can bring to the left from it's initial position, skipping the right side of the array. But in the end, it's negligible and it's still O(n²) performance, no matter how you slice it.
I have a 2-D array where each cell is a Set.
In each set is a different size, say for example, ranging from 0 to 5.
I want to print out the 2-D array in a format such that it's easily readable.
Example
HashSet<String>[][] schedule = (HashSet<String>[][]) new HashSet[3][5];
schedule[0][0].add("A");
schedule[0][0].add("B");
schedule[0][0].add("C");
schedule[0][2].add("D");
schedule[0][2].add("E");
schedule[1][0].add("F");
schedule[1][1].add("G");
schedule.print();
will produce
-----------------
| A | | D | | |
| B | | E | | |
| C | | | | |
-----------------
| F | G | | | |
-----------------
| | | | | |
-----------------
obviously without the '-' and '|', but you get the point.
The only viable solution I can think of is creating and remembering the iterator for each column (so remembering 5 iterators at the same time) and iterating through each column, outputting one element at a time until there are no more elements in any of the iterators.
One problem is that in the case of G, it expands the second column even though there are not any values in the first row, second column. I can get around this by buffering each column with tabs.
Obviously this hack does not scale with additional columns, so I was wondering if there were any cute tricks that I might have forgotten.
Thanks!
With a few modifications to the code (you forgot to instantiate the positions in the array!), you can definitely print out the jagged sets.
Hint: Make use of the iterator() method that's provided with the HashSet. An iterator moves over a collection of objects, returning one at a time, then pausing until it's invoked again, or there's nothing left to iterate over. You can find more information about iterators in general at Wikipedia's Iterator article.
Using this, you can gather up the results in each HashSet inside of a String (in any way you desire), and print them out at the end.
Code Snippet:
Iterator first = schedule[0][0].iterator();
Iterator second = schedule[0][2].iterator();
// And so forth
String firstResult = "";
String secondResult = "";
// And so forth
while (first.hasNext()) {
firstResult += first.next() + "\t";
if (!first.hasNext()) {
firstResult += "\n";
}
}
while (second.hasNext()) {
secondResult += second.next() + "\t";
if (!second.hasNext()) {
secondResult += "\n";
}
}
// And so forth
System.out.print(firstResult + secondResult + someResult + anotherResult);
Filling in the blanks is an exercise for the reader.
With this, the result is as follows:
A B C
D E
F
G