recursion using a hashmap - java

I have an array that has the following numbers
int[] arr = {2,4,3,1,5,6,0,7,8,9,10,11,12,13,14,15};
Or any other order for that matter.
I need to make all the possible combinations for the numbers using a recursion but satisfying a condition that the next number clubbed with the present one can only be from specific numbers given by a hashmap:
ex When the recursion takes 1 the next number can be from {0,4,5,2,6} (from the HaspMap),and then if i make 10,the next number can be from {1,4,5} and so on
static HashMap<Integer,Integer[]> possibleSeq = new HashMap<Integer,Integer[] >();
private static void initialize(HashMap<Integer,Integer[]> possibleSeq) {
possibleSeq.put(0,new Integer[]{1,4,5});
possibleSeq.put(1,new Integer[]{0,4,5,2,6});
possibleSeq.put(2,new Integer[]{1,3,5,6,7});
possibleSeq.put(3,new Integer[]{2,6,7});
possibleSeq.put(4,new Integer[]{0,1,5,8,9});
possibleSeq.put(5,new Integer[]{0,1,2,4,6,8,9,10});
possibleSeq.put(6,new Integer[]{1,2,3,5,7,9,10,11});
possibleSeq.put(7,new Integer[]{2,3,6,10,11});
possibleSeq.put(8,new Integer[]{9,4,5,12,13});
possibleSeq.put(9,new Integer[]{10,4,5,8,6,12,13,14});
possibleSeq.put(10,new Integer[]{7,6,5,9,11,15,13,14});
possibleSeq.put(11,new Integer[]{6,7,10,14,15});
possibleSeq.put(12,new Integer[]{8,9,13});
possibleSeq.put(13,new Integer[]{8,9,10,12,14});
possibleSeq.put(14,new Integer[]{9,10,11,13,15});
possibleSeq.put(15,new Integer[]{10,11,14});
}
Note: I am required to make all the possible numbers beginning from digit length 1 to 10.
Help!

Try with something like this, for starters:
void findPath(Set paths, Stack path, int[] nextSteps, Set numbersLeft) {
if (numbersLeft.isEmpty()) {
//Done
paths.add(new ArrayList(path));
return;
}
for (int step:nextSteps) {
if (numbersLeft.contains(step)) {
// We can move on
path.push(step);
numbersLeft.remove(step);
findPath(paths, path, possiblePaths.get(step), numbersLeft);
numbersLeft.add(path.pop());
}
}
}
Starting values should be an empty Set, and empty Stack, a nextSteps identical to you initial array, and a set created from your initial array. When this returns, the paths Set should be filled with the possible paths.
I haven't tested this, and there are bugs as well as more elegant solutions.

Related

Adding one to the set of numbers in the array Java

public class Test
{
public static int addOne(int[] numb)
{
for(int i=0;i<numb.length;i++){
System.out.println(numb[i]+1);
int result = numb[i];
}
return (numbers.length);
}
}
Main:
public class Main
{
public static void main(String[] args)
{
int[] numO = {2,2,4,4,6};
System.out.println(Test.addOne(numO)); /
}
}
Output:
3,3,5,5,7,5
I was trying out arrays in java as I am starting to learn arrays, I set five numbers in the array and using a for loop, wanted to add the numbers in the array by 1, e.g. Array containing (1,2,3) would be (2,3,4) and outputting the total number 9, instead of 2,3,4 and a random number. How can I achieve this?
You are never actually changing the value contained within the numb array, what you are doing is taking the existing value and adding outputting it with 1 added to it
System.out.println(numb[i] + 1);
To change the value you must increment the value outside
numb[i]++;
System.out.println(numb[i]);
That should solve your problem of not retaining the changed value in the array. However there is another error that I can see that would prevent you from outputting the correct result value. By doing result + numb[i]; you are preforming an operation but not setting the result variable equal to anything. To set it add to the value it already contains you would do result = result + numb[i] or more properly result += numb[i]
Hope this helps!

When to use for, while, or do-while loops/ How to start it

Started learning about loops and the different types today. My question is in this situation which type would i try to use? And what would be the advantage over the others? After looking over my lecture notes it seems that do-while should always be used but I'm certain that it is not the case.
Also how would I start that first one about returning a sum of the "given array." what is the given array? Is it just whatever I'm supposed to be plugging into the run arguments line?
public class SumMinMaxArgs {
// TODO - write your code below this comment.
// You will need to write three methods:
//
// 1.) A method named sumArray, which will return the sum
// of the given array. If the given array is empty,
// it should return a sum of 0.
//
// 2.) A method named minArray, which will return the
// smallest element in the given array. You may
// assume that the array contains at least one element.
// You may use your min method defined in lab 6, or
// Java's Math.min method.
//
// 3.) A method named maxArray, which will return the
// largest element in the given array. You may
// assume that the array contains at least one element.
// You may use your max method defined in lab 6, or
// Java's Math.max method.
//
// DO NOT MODIFY parseStrings!
public static int[] parseStrings(String[] strings) {
int[] retval = new int[strings.length];
for (int x = 0; x < strings.length; x++) {
retval[x] = Integer.parseInt(strings[x]);
}
return retval;
}
// DO NOT MODIFY main!
public static void main(String[] args) {
int[] ints = parseStrings(args);
System.out.println("Sum: " + sumArray(ints));
System.out.println("Min: " + minArray(ints));
System.out.println("Max: " + maxArray(ints));
}
}
All three forms have exactly the same expressive power. What you use in a certain situation depends on style, convention, and convenience. This is much like you can express the same meaning with different english sentences.
That said, do - while is mostly used when the loop should run at least once (i.e. the condition is checked only after the first iteration).
for is mostly used when you are iterating over some collection or index range.
The four kinds of loops supported in Java:
C-style for loop: for (int i = 0 ; i < list.size() ; ++i) { ... } when you want to access the index of some kind of list or array directly, or to do an operation multiple times.
foreach loop, when you want to iterate over a collection, but don't care about the index: for (Customer c : customers) { ... }
while loop: while (some_condition) { ... } when some code must executed as long as the condition is true. If the condition is false to start with, the code inside the block (i.e. inside the brackets) will never be executed.
do while loop: do { statement1; } while (condition); will execute statement1 even if the condition is false to begin with, but it will do so only once.

Determining Base case of a recursive java program

This code generates the powerset of a set of numbers. For example if we have (0,1,2) the power set is {(0,1,2),(0,2),(1,2),(0,1),(2),(1),(0),()}
public static List<List<Integer>> generatePowerSet(List<Integer> inputSet){
List<List<Integer>> powerSet = new ArrayList<>();
directedPowerSet(inputSet,0,new ArrayList<Integer>(), powerSet);
return powerSet;
}
public static void directedPowerSet(List<Integer> inputSet, int toBeSelected, List<Integer> selectedSoFar,List<List<Integer>> powerSet){
if(toBeSelected == inputSet.size()){
powerSet.add(new ArrayList<Integer>(selectedSoFar));
return;
}
//Generate all subsets that contain inputSet[toBeSelected].
selectedSoFar.add(inputSet.get(toBeSelected));
directedPowerSet(inputSet,toBeSelected+1,selectedSoFar,powerSet);
//Generate all subsets that do not contain inputSet[toBeSelected].
selectedSoFar.remove(selectedSoFar.size()-1);
directedPowerSet(inputSet,toBeSelected+1,selectedSoFar,powerSet);
}
Why is the base case when toBeSelected == inputSet.size()?
The recursive code goes through valid indexes into inputSet list one-by-one, starting at zero. The current invocation uses toBeSelected as an index into inputSet, and passes toBeSelected+1 to the invocation of the next level.
Therefore, the meaning of the base case is that there is nothing else to be selected, which happens when toBeSelected becomes invalid.
The last valid value of toBeSelected is inputSet.size()-1; toBeSelected==inputSet.size() detects the first invalid value of toBeSelected, serving as a base case for the recursion.
Because the code is trying to build the power set of an n element set, starting with 0 element empty set, then moving to 1 element sets, then moving to 2 element sets and so on.
When should this end? When you are finally trying to build a n elements set, because there is only one and that's the input set itself.

Deleting and Inserting Elements in Array [duplicate]

This question already has answers here:
How to remove specific element from an array [duplicate]
(6 answers)
Closed 8 years ago.
public class Example {
public static void main(String [] args) {
String [] wombology;
wombology = new String[3];
wombology[0] = "History of Wombology";
wombology[1] = "Why Wombology";
wombology[2] = "Wombology and Me";
Random book = new Random(System.currentTimeMillis());
Scanner choice = new Scanner(System.in);
String yourChoice;
do {
System.out.println("Press enter for random book");
yourChoice = choice.nextLine();
if(yourChoice.equals("")) {
System.out.println(wombology[randomizer.nextInt(3)]);
System.out.println();
}
if(yourChoice == "EXIT") {
break;
}
} while(!yourChoice.equals("EXIT"));
}
}
How could I take out a "book" from the array once chosen randomly?
How could I put back in said "book" later back into the array?
Example: "History of Wombology" is randomly chosen and is taken out.
The next random selection should NOT include "History of Wombology" until it is put back in.
Meaning only "Why Wombology" and "Wombology and Me" should be the only possible choices.
I'm assuming that this is homework and an ArrayList is not possible. And I don't want to give a full, detailed answer.
One option might be to create a parallel array, boolean isCheckedOut[], and track your books there.
You need to manage the array yourself. That means you need to know the real size of the array and the filled size. This is because once the array is created the size cannot change.
If you delete an object from the array you need to shift the adjacent elements towards that position.
For example, your array looks like this:
[A|B|C|D|E|F]
allocatedArraySize = 6
currentSize = 6
If you delete C which is at position 2 then you must shift D, E, F to the left. You could also make the last position null.
[A|B|D|E|F|null]
allocatedArraySize = 6
currentSize = 5
To insert, simply use this:
// Check Array is not full.
if(currentSize != allocatedArraySize)
{
// Then add your object to the last position in the array.
array[currentSize] = obj;
// Increment the index.
currentSize++;
}
else
{
// Don't allow insertion.
// Or create a new-bigger-array;
// then copy all elements of the full array into it.
}
You have to "define" an action for "taking out a book" on the technical level. I can image two possibilities for this
setting the array content at the specific position to null
setting the array content at the specific position to an empty string
As the title of most books consists of one or more letters, the empty string-proposal seems also to be valid.
The second task (putting a book back into the array) can be handled in a similar way. Here you have to find an empty place (an array position with an empty string/null as content) and assign the name of the book to it.
Concerning the randomizer and not allowing already removed books: you can use the aforementioned condition to rerun the randomizer, i.e until an non-empty string/not-null element is found in the array. If you found one, it is a valid choice. But beware, if you removed all books, the randomizer would never stop running (because it finds only invalid choices and hence never returns). Here you can use an additional check condition: if the array only consists of empty strings/ null values, it is not required to run the randomizer.
Hope that helps...

How should I find repeated word sequences

I need to detect the presence of multiple blocks of columnar data given only their headings. Nothing else is known about the data except the heading words, which are different for every set of data.
Importantly, it is not known before hand how many words are in each block nor, therefore, how many blocks there are.
Equally important, the word list is always relatively short - less than 20.
So, given a list or array of heading words such as:
Opt
Object
Type
Opt
Object
Type
Opt
Object
Type
what's the most processing-efficient way to determine that it consists entirely of the repeating sequence:
Opt
Object
Type
It must be an exact match, so my first thought is to search [1+] looking for matches to [0], calling them index n,m,... Then if they are equidistant check [1] == [n+1] == [m+1], and [2] == [n+2] == [m+2] etc.
EDIT: It must work for word sets where some of the words are themselves repeated within a block, so
Opt
Opt
Object
Opt
Opt
Object
is a set of 2
Opt
Opt
Object
If the list is made of x repeating groups such that each group contains n elements...
We know there is at least 1 group so we will see if there 2 repeating groups, test by comparing the first half of the list and the second half.
1) If the above is true we know that that the solution is a factor of 2
2) If the above is false we move to the next largest prime number which is divisible by the total number of words...
At each step we check for equality among the lists, if we find it then know we have a solution with that factor in it.
We want to return a list of words for which we have the greatest factor of the first prime number for which we find equality among sub lists.
So we apply the above formula on the sub list knowing all sub lists are equal... therefore the solution is best solved recursively. That is we only need to consider the current sub list in isolation.
The solution will be extremely efficient if loaded with a short table of primes... after this it will be necessary to compute them but the list would have to be non trivial if even a list of only a few dozen primes are taken into account.
Can the unit sequence contain repetitions of its own? Do you know the length of the unit sequence?
e.g.
ABCABCABCDEFABCABCABCDEFABCABCABCDEF
where the unit sequence is ABCABCABCDEF
If the answer is yes, you've got a difficult problem, I think, unless you know the length of the unit sequence (in which case the solution is trivial, you just make a state machine that first stores the unit sequence, then verifies that the each element rest of the sequence corresponds to each element of the unit sequence).
If the answer is no, use this variant Floyd's cycle-finding algorithm to identify the unit sequence:
Initialize pointers P1 and P2 to the beginning of the sequence.
For each new element, increment pointer P1 every time, and increment pointer P2 every other time (keep a counter around to do this).
If P1 points to an identical elements of P2, you've found a unit sequence.
Now repeat through the rest of the sequence to verify that it consists of duplicates.
UPDATE: you've clarified your problem to state that the unit sequence may contain repetitions of its own. In this case, use the cycle-finding algorithm, but it's only guaranteed to find potential cycles. Keep it running throughout the length of the sequence, and use the following state machine, starting in state 1:
State 1: no cycle found that works; keep looking. When the cycle-finding algorithm finds a potential cycle, verify that you've gotten 2 copies of a preliminary unit sequence from P, and go to state 2. If you reach the end of the input, go to state 4.
State 2: preliminary unit sequence found. Run through the input as long as the cycle repeats identically. If you reach the end of the input, go to state 3. If you find an input element that is different from the corresponding element of the unit sequence, go back to state 1.
State 3: The input is a repetition of a unit sequence if the end of the input consists of complete repetitions of the unit sequence. (If it's midway through a unit sequence, e.g. ABCABCABCABCAB then a unit sequence found, but it does not consist of complete repetitions.)
State 4: No unit sequence found.
In my example (repeating ABCABCABCDEF) the algorithm starts by finding ABCABC, which would put it in state 2, and it would stay there until it hit the first DEF, which would put it back in state 1, then probably jump back and forth between states 1 and 2, until it reached the 2nd ABCABCABCDEF, at which point it would re-enter state 2, and at the end of the input it would be in state 3.
A better answer than my other one: a Java implementation which works, should be straightforward to understand, and is generic:
package com.example.algorithms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
interface Processor<T> {
public void process(T element);
}
public class RepeatingListFinder<T> implements Processor<T> {
private List<T> unit_sequence = new ArrayList<T>();
private int repeat_count = 0;
private int partial_matches = 0;
private Iterator<T> iterator = null;
/* Class invariant:
*
* The sequence of elements passed through process()
* can be expressed as the concatenation of
* the unit_sequence repeated "repeat_count" times,
* plus the first "element_matches" of the unit_sequence.
*
* The iterator points to the remaining elements of the unit_sequence,
* or null if there have not been any elements processed yet.
*/
public void process(T element) {
if (unit_sequence.isEmpty() || !iterator.next().equals(element))
{
revise_unit_sequence(element);
iterator = unit_sequence.iterator();
repeat_count = 1;
partial_matches = 0;
}
else if (!iterator.hasNext())
{
iterator = unit_sequence.iterator();
++repeat_count;
partial_matches = 0;
}
else
{
++partial_matches;
}
}
/* Unit sequence has changed.
* Restructure and add the new non-matching element.
*/
private void revise_unit_sequence(T element) {
if (repeat_count > 1 || partial_matches > 0)
{
List<T> new_sequence = new ArrayList<T>();
for (int i = 0; i < repeat_count; ++i)
new_sequence.addAll(unit_sequence);
new_sequence.addAll(
unit_sequence.subList(0, partial_matches));
unit_sequence = new_sequence;
}
unit_sequence.add(element);
}
public List<T> getUnitSequence() {
return Collections.unmodifiableList(unit_sequence);
}
public int getRepeatCount() { return repeat_count; }
public int getPartialMatchCount() { return partial_matches; }
public String toString()
{
return "("+getRepeatCount()
+(getPartialMatchCount() > 0
? (" "+getPartialMatchCount()
+"/"+unit_sequence.size())
: "")
+") x "+unit_sequence;
}
/********** static methods below for testing **********/
static public List<Character> stringToCharList(String s)
{
List<Character> result = new ArrayList<Character>();
for (char c : s.toCharArray())
result.add(c);
return result;
}
static public <T> void test(List<T> list)
{
RepeatingListFinder<T> listFinder
= new RepeatingListFinder<T>();
for (T element : list)
listFinder.process(element);
System.out.println(listFinder);
}
static public void test(String testCase)
{
test(stringToCharList(testCase));
}
static public void main(String[] args)
{
test("ABCABCABCABC");
test("ABCDFTBAT");
test("ABABA");
test("ABACABADABACABAEABACABADABACABAEABACABADABAC");
test("ABCABCABCDEFABCABCABCDEFABCABCABCDEF");
test("ABABCABABCABABDABABDABABC");
}
}
This is a stream-oriented approach (with O(N) execution time and O(N) worst-case space requirements); if the List<T> to be processed already exists in memory, it should be possible to rewrite this class to process the List<T> without any additional space requirements, just keeping track of the repeat count and partial match count, using List.subList() to create a unit sequence that is a view of the first K elements of the input list.
My solution, which works as desired, is perhaps naive. It does have the advantage of being simple.
String[] wta; // word text array
...
INTERVAL:
for(int xa=1,max=(wta.length/2); xa<=max; xa++) {
if((wta.length%xa)!=0) { continue; } // ignore intervals which don't divide evenly into the words
for(int xb=0; xb<xa; xb++) { // iterate the words within the current interval
for(int xc=xb+xa; xc<wta.length; xc+=xa) { // iterate the corresponding words in each section
if(!wta[xb].equalsIgnoreCase(wta[xc])) { continue INTERVAL; } // not a cycle
}
}
ivl=xa;
break;
}

Categories