Is there any way to do n-level nested loops in Java? - java

In other words, can I do something like
for() {
for {
for {
}
}
}
Except N times? In other words, when the method creating the loops is called, it is given some parameter N, and the method would then create N of these loops nested one in another?
Of course, the idea is that there should be an "easy" or "the usual" way of doing it. I already have an idea for a very complicated one.

jjnguy is right; recursion lets you dynamically create variable-depth nesting. However, you don't get access to data from the outer layers without a little more work. The "in-line-nested" case:
for (int i = lo; i < hi; ++i) {
for (int j = lo; j < hi; ++j) {
for (int k = lo; k < hi; ++k) {
// do something **using i, j, and k**
}
}
}
keeps the variables i, j, and k in scope for the innermost body to use.
Here's one quick hack to do that:
public class NestedFor {
public static interface IAction {
public void act(int[] indices);
}
private final int lo;
private final int hi;
private final IAction action;
public NestedFor(int lo, int hi, IAction action) {
this.lo = lo;
this.hi = hi;
this.action = action;
}
public void nFor (int depth) {
n_for (0, new int[0], depth);
}
private void n_for (int level, int[] indices, int maxLevel) {
if (level == maxLevel) {
action.act(indices);
} else {
int newLevel = level + 1;
int[] newIndices = new int[newLevel];
System.arraycopy(indices, 0, newIndices, 0, level);
newIndices[level] = lo;
while (newIndices[level] < hi) {
n_for(newLevel, newIndices, maxLevel);
++newIndices[level];
}
}
}
}
The IAction interface stipulates the role of a controlled action which takes an array of indices as the argument to its act method.
In this example, each instance of NestedFor is configured by the constructor with the iteration limits and the action to be performed by the innermost level. The parameter of the nFor method specifies how deeply to nest.
Here's a sample usage:
public static void main(String[] args) {
for (int i = 0; i < 4; ++i) {
final int depth = i;
System.out.println("Depth " + depth);
IAction testAction = new IAction() {
public void act(int[] indices) {
System.out.print("Hello from level " + depth + ":");
for (int i : indices) { System.out.print(" " + i); }
System.out.println();
}
};
NestedFor nf = new NestedFor(0, 3, testAction);
nf.nFor(depth);
}
}
and the (partial) output from its execution:
Depth 0
Hello from level 0:
Depth 1
Hello from level 1: 0
Hello from level 1: 1
Hello from level 1: 2
Depth 2
Hello from level 2: 0 0
Hello from level 2: 0 1
Hello from level 2: 0 2
Hello from level 2: 1 0
Hello from level 2: 1 1
Hello from level 2: 1 2
Hello from level 2: 2 0
Hello from level 2: 2 1
Hello from level 2: 2 2
Depth 3
Hello from level 3: 0 0 0
Hello from level 3: 0 0 1
Hello from level 3: 0 0 2
Hello from level 3: 0 1 0
...
Hello from level 3: 2 1 2
Hello from level 3: 2 2 0
Hello from level 3: 2 2 1
Hello from level 3: 2 2 2

It sounds like you may want to look into recursion.

2015 Edit: Along the same vain as the previous incantation, I made the following package to handle this; https://github.com/BeUndead/NFor
The usage would be as follows
public static void main(String... args) {
NFor<Integer> nfor = NFor.of(Integer.class)
.from(0, 0, 0)
.by(1, 1, 1)
.to(2, 2, 3);
for (Integer[] indices : nfor) {
System.out.println(java.util.Arrays.toString(indices));
}
}
resulting in
[0, 0, 0]
[0, 0, 1]
[0, 0, 2]
[0, 1, 0]
[0, 1, 1]
[0, 1, 2]
[1, 0, 0]
[1, 0, 1]
[1, 0, 2]
[1, 1, 0]
[1, 1, 1]
[1, 1, 2]
It also supports conditions other than lessThan. The usage there being (with import static NFor.*;):
NFor<Integer> nfor = NFor.of(Integer.class)
.from(-1, 3, 2)
.by(1, -2, -1)
.to(lessThanOrEqualTo(1), greaterThanOrEqualTo(-1), notEqualTo(0));
Resulting in:
[-1, 3, 2]
[-1, 3, 1]
[-1, 1, 2]
[-1, 1, 1]
[-1, -1, 2]
[-1, -1, 1]
[0, 3, 2]
[0, 3, 1]
[0, 1, 2]
[0, 1, 1]
[0, -1, 2]
[0, -1, 1]
[1, 3, 2]
[1, 3, 1]
[1, 1, 2]
[1, 1, 1]
[1, -1, 2]
[1, -1, 1]
Obviously, loops of different lengths and different classes (all boxed, numeric primitives) are supported. The default (if not specified) is from(0, ...).by(1, ...); but a to(...) must be specified.
The NForTest file should demonstrate several different ways to use it.
The basic premise of this being to simply advance the 'indices' each turn rather than use recursion.

You might want to explain what you really want to do.
If the outer for loops are doing nothing but controlling a count, then your nested for loops are simply a more complicated way of iterating by a count that could be handled by a single for loop.
For example:
for (x = 0; x < 10; ++x) {
for (y = 0; y < 5; ++y) {
for (z = 0; z < 20; ++z) {
DoSomething();
}
}
}
Is equivalent to:
for (x = 0; x < 10*5*20; ++x) {
DoSomething();
}

I was actually thinking about this the other day.
An example that is probably not perfect but pretty close to what I think is being asked would be printing out a directory tree
public void printTree(directory) {
for(files in directory) {
print(file);
if(file is directory) {
printTree(file);
}
}
}
this way you end up with a stack of for loops nested inside each other, without the hassle of figuring out exactly how they should go together.

The essential idea behind nesting loops is multiplication.
Expanding on Michael Burr's answer, if the outer for loops are doing nothing but controlling a count, then your nested for loops over n counts are simply a more complicated way of iterating over the product of the counts with a single for loop.
Now, let's extend this idea to Lists. If you're iterating over three lists in nested loops, this is simply a more complicated way of iterating over the product of the lists with a single loop. But how do you express the product of three lists?
First, we need a way of expressing the product of types. The product of two types X and Y can be expressed as a generic type like P2<X, Y>. This is just a value that consists of two values, one of type X, the other of type Y. It looks like this:
public abstract class P2<A, B> {
public abstract A _p1();
public abstract B _p2();
}
For a product of three types, we just have P3<A, B, C>, with the obvious third method. A product of three lists, then, is achieved by distributing the List functor over the product type. So the product of List<X>, List<Y>, and List<Z> is simply List<P3<X, Y, Z>>. You can then iterate over this list with a single loop.
The Functional Java library has a List type that supports multiplying lists together using first-class functions and product types (P2, P3, etc. which are also included in the library).
For example:
for (String x : xs) {
for (String y : ys) {
for (String z : zs) {
doSomething(x, y, z);
}
}
}
Is equivalent to:
for (P3<String, String, String> p : xs.map(P.p3()).apply(ys).apply(zs)) {
doSomething(p._1(), p._2(), p._3());
}
Going further with Functional Java, you can make doSomething first-class, as follows. Let's say doSomething returns a String:
public static final F<P3<String, String, String>, String> doSomething =
new F<P3<String, String, String>, String>() {
public String f(final P3<String, String, String> p) {
return doSomething(p._1(), p._2(), p._3());
}
};
Then you can eliminate the for-loop altogether, and collect the results of all the applications of doSomething:
List<String> s = xs.map(P.p3()).apply(ys).apply(zs).map(doSomething);

Problem needs more specification. Maybe recursion will help you, but keep in mind that recursion is almost always an alternative to iteration, and vice versa. It may be that a 2-level nested loop can be sufficient for your needs. Just let us know what problem you're trying to solve.

The neatest general approach I could come up with in Java 7 is
// i[0] = 0..1 i[1]=0..3, i[2]=0..4
MultiForLoop.loop( new int[]{2,4,5}, new MultiForLoop.Callback() {
void act(int[] i) {
System.err.printf("%d %d %d\n", i[0], i[1], i[2] );
}
}
Or in Java 8:
// i[0] = 0..1 i[1]=0..3, i[2]=0..4
MultiForLoop.loop( new int[]{2,4,5},
i -> { System.err.printf("%d %d %d\n", i[0], i[1], i[2]; }
);
An implementation that supports this is:
/**
* Uses recursion to perform for-like loop.
*
* Usage is
*
* MultiForLoop.loop( new int[]{2,4,5}, new MultiForLoop.Callback() {
* void act(int[] indices) {
* System.err.printf("%d %d %d\n", indices[0], indices[1], indices[2] );
* }
* }
*
* It only does 0 - (n-1) in each direction, no step or start
* options, though they could be added relatively trivially.
*/
public class MultiForLoop {
public static interface Callback {
void act(int[] indices);
}
static void loop(int[] ns, Callback cb) {
int[] cur = new int[ns.length];
loop(ns, cb, 0, cur);
}
private static void loop(int[] ns, Callback cb, int depth, int[] cur) {
if(depth==ns.length) {
cb.act(cur);
return;
}
for(int j = 0; j<ns[depth] ; ++j ) {
cur[depth]=j;
loop(ns,cb, depth+1, cur);
}
}
}

If you are having a general nested-loop structure like:
for(i0=0;i0<10;i0++)
for(i1=0;i1<10;i1++)
for(i2=0;i2<10;i2++)
....
for(id=0;id<10;id++)
printf("%d%d%d...%d\n",i0,i1,i2,...id);
where i0,i1,i2,...,id are loop variables and d is the depth of the nested loop.
Equivalent Recursion Solution:
void nestedToRecursion(counters,level){
if(level == d)
computeOperation(counters,level);
else
{
for (counters[level]=0;counters[level]<10;counters[level]++)
nestedToRecursion(counters,level+1);
}
}
void computeOperation(counters,level){
for (i=0;i<level;i++)
printf("%d",counters[i]);
printf("\n");
}
counters is an array of size d, representing the corresponding variables i0,i1,i2,...id respectively int counters[d].
nestedToRecursion(counters,0);
Similarly we can convert other variables like initializing of recursion or ending by using arrays for them, i.e. we could have initial[d], ending[d].

A Java 8 solution based on streams:
public static Stream<int[]> nest(Supplier<IntStream> first, Supplier<IntStream>... streams) {
Stream<int[]> result = first.get().mapToObj(i -> new int[]{i});
for (Supplier<IntStream> s : streams) {
result = nest(result, s);
}
return result;
}
private static Stream<int[]> nest(Stream<int[]> source, Supplier<IntStream> target) {
return source.flatMap(b -> target.get().mapToObj(i -> {
int[] result = new int[b.length + 1];
System.arraycopy(b, 0, result, 0, b.length);
result[b.length] = i;
return result;
}));
}
Another one which is not thread-safe, but avoid extra copies:
public static Stream<int[]> nest(Supplier<IntStream>... streams) {
final int[] buffer = new int[streams.length];
Stream<int[]> result = Stream.of(buffer);
for (int n = 0; n < streams.length; n++) {
result = nest(result, streams[n], n);
}
// Might need to perform a copy here, if indices are stored instead of being consumed right away.
// return result.map(b -> Arrays.copyOf(b, b.length));
return result;
}
private static Stream<int[]> nest(Stream<int[]> source, Supplier<IntStream> target, int index) {
return source.flatMap(b -> target.get().mapToObj(i -> {
b[index] = i;
return b;
}));
}
Usage:
nest(
() -> IntStream.range(0, 2),
() -> IntStream.range(0, 2),
() -> IntStream.range(0, 3))
.forEach(indices -> System.out.println( Arrays.toString(indices)));
Output:
[0, 0, 0]
[0, 0, 1]
[0, 0, 2]
[0, 1, 0]
[0, 1, 1]
[0, 1, 2]
[1, 0, 0]
[1, 0, 1]
[1, 0, 2]
[1, 1, 0]
[1, 1, 1]
[1, 1, 2]

public void recursiveFor(Deque<Integer> indices, int[] ranges, int n) {
if (n != 0) {
for (int i = 0; i < ranges[n-1]; i++) {
indices.push(i);
recursiveFor(indices, ranges, n-1);
indices.pop();
}
}
else {
// inner most loop body, access to the index values thru indices
System.out.println(indices);
}
}
Sample call:
int[] ranges = {2, 2, 2};
recursiveFor(new ArrayDeque<Integer>(), ranges, ranges.length);

String fors(int n){
StringBuilder bldr = new StringBuilder();
for(int i = 0; i < n; i++){
for(int j = 0; j < i; j++){
bldr.append('\t');
}
bldr.append("for() {\n");
}
for(int i = n-1; i >= 0; i--){
for(int j = 0; j < i; j++){
bldr.append('\t');
}
bldr.append("}\n");
}
return bldr.toString();
}
Creates a nice nested for-loop skeleton ;-)
Not completely serious and i'm aware that a recursive solution would have been more elegant.

my first time answering a question but i felt like i needed to share this info
of
`
for (x = 0; x < base; ++x) {
for (y = 0; y < loop; ++y) {
DoSomething();
}
}
being equivalent to
for (x = 0; x < base*loop; ++x){
DoSomething();
}
so if you wanted an n number of nests, it can be written using division between base and loop so it could look something as simple as this:
char[] numbs = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public void printer(int base, int loop){
for (int i = 0; i < pow(base, loop); i++){
int remain = i;
for (int j = loop-1; j >= 0; j--){
int digit = remain/int(pow(base, j));
print(numbs[digit]);
remain -= digit*pow(base, j);
}
println();
}
}
so if you were to type printer(10, 2); it would print out:
00
01
02
03
04
...
97
98
99

This worked for me really nice - I had to select from some alternatives, which were stored in myAlternativePaths and the basic idea is that I was trying to construct next selection, and when there was an "overflow" in one dimension / component, you just reinitialize that dimension and add one to the next.
public boolean isValidAlternativeSelection (int[] alternativesSelected) {
boolean allOK = true;
int nPaths= myAlternativePaths.size();
for (int i=0; i<nPaths; i++) {
allOK=allOK & (alternativesSelected[i]<myAlternativePaths.get(i).myAlternativeRoutes.size());
}
return allOK;
}
public boolean getNextValidAlternativeSelection (int[] alternativesSelected) {
boolean allOK = true;
int nPaths= myAlternativePaths.size();
alternativesSelected[0]=alternativesSelected[0]+1;
for (int i=0; i<nPaths; i++) {
if (alternativesSelected[i]>=myAlternativePaths.get(i).myAlternativeRoutes.size()) {
alternativesSelected[i]=0;
if(i<nPaths-1) {
alternativesSelected[i+1]=alternativesSelected[i+1]+1;
} else {
allOK = false;
}
}
// allOK=allOK & (alternativesSelected[i]<myAlternativePaths.get(i).myAlternativeRoutes.size());
}
return allOK;
}

I also tried to solve this problem and eventually have created this simple solution.
For example, suppose we need to generate loops like this dynamically:
for (int i = 0; i < 2; i++) {
for (int j = 1; j < 3; j++) {
for (int k = 2; k < 4; k++) {
System.out.println(Arrays.asList(i, j, k));
}
}
}
So, we can implement it with a such builder:
new Loops()
.from(0).to(2)
.from(1).to(3)
.from(2).to(4)
.action(System.out::println);
The result of execution:
[0, 1, 2]
[0, 1, 3]
[0, 2, 2]
[0, 2, 3]
[1, 1, 2]
[1, 1, 3]
[1, 2, 2]
[1, 2, 3]
I hope it will useful for someone else too.

In case if you want to work on data and not just numbers. Following solution could be tried:
class WordGenerator {
//My custom spell checker.
//It returns an empty string if the word is not there in dictionary
public static MySpellChecker spellCheck;
public static void main(String args[]) throws Exception {
spellCheck = new MySpellChecker();
List<String> consonants = List.of("c","t");
List<String> vowels = List.of("a","o","");
//adding to this list will increase nesting
List<List<String>> input = new ArrayList<>();
input.add(consonants);
input.add(vowels);
input.add(vowels);
input.add(consonants);
MyForLoop fLoop = new MyForLoop(input.listIterator(), //for nesting loops
new ArrayList<String>(), //loop state
//action to perform in innermost loop
(state)->spellCheck.check(String.join("", state)));
//start execution
fLoop.accept("");
//print results
System.out.println("No of iterations: " + fLoop.getResult().size());
System.out.println("\nFound words: " + String.join(", ", fLoop.getResult()));
}
}
class MyForLoop implements Consumer<String> {
private static List<String> result = new ArrayList<>();
private ListIterator<List<String>> itr;
private Function<List<String>, String> action;
private List<String> state = new ArrayList<>();
public MyForLoop(ListIterator<List<String>> itr, List<String> collected, Function<List<String>, String> action) {
this.itr = itr;
this.action = action;
state = new ArrayList<>(collected);
}
#Override
public void accept(String s) {
if(!s.isBlank())
state.add(s);
if(itr.hasNext()) {
itr.next().stream().forEach(new MyForLoop(itr, state, action));
if(!state.isEmpty())
state.remove(state.size()-1);
itr.previous();
} else {
result.add(action.apply(state));
state.remove(state.size()-1);
}
}
public static List<String> getResult() {
return result;
}
}
Output:
No of iterations: 36
Found words: , , , , , cat, , coat, , coot, , cot, , , , , , , , , , , , tat, , toat, , toot, toc, tot, , , , , ,
Here the code is generating words starting and ending with 'c' and 't', with at max two vowels in between them. You change sequence in input list to change word creation.
The MyForLoop object maintains a state list, that holds current iteration state. Each element of the state list gives state of corresponding level of the nested for loop. The state can be used in action, that gets executed in inner most loop.
To keep the demo code short and simple I've cut corners.šŸ˜‹ It can be improved in many ways.
I've used Jazzy library to check spellings.
<dependency>
<groupId>net.sf.jazzy</groupId>
<artifactId>jazzy</artifactId>
<version>0.5.2-rtext-1.4.1-2</version>
</dependency>

In the interest of conciseness I am putting my code here :
void variDepth(int depth, int n, int i) {
cout<<"\n d = "<<depth<<" i = "<<i;
if(!--depth) return;
for(int i = 0;i<n;++i){
variDepth(depth,n,i);
}
}
void testVariDeapth()
{ variDeapth(3, 2,0);
}
Output
d = 3 i = 0
d = 2 i = 0
d = 1 i = 0
d = 1 i = 1
d = 2 i = 1
d = 1 i = 0
d = 1 i = 1

Related

How to get all possible combinations from two arrays?

I have the two arrays:
String[] operators = {"+", "-", "*"};
int[] numbers = {48, 24, 12, 6};
And I want to get all possible combination in a String format like this:
48+24+12+6
48+24+12-6
48+24+12*6
48+24-12+6
48+24-12-6
48+24-12*6
..........
48*24*12*6
This what I have tried:
for (int i = 0; i < operators.length; i++) {
System.out.println(numbers[0] + operators[i] + numbers[1] +
operators[i] + numbers[2] + operators[i] + numbers[3]);
}
But it only prints:
48+24+12+6
48-24-12-6
48*24*12*6
How to solve this?
This is not a duplicate because I don't want to get every two pairs of data, I want to get every combination in 4 pairs. The duplicate is different.
Use a triple loop:
for (int i=0; i < operators.length; ++i) {
for (int j=0; j < operators.length; ++j) {
for (int k=0; k < operators.length; ++k) {
System.out.println(numbers[0] + operators[i] + numbers[1] + operators[j] +
numbers[2] + operators[k] + numbers[3]);
}
}
}
You essentially want to take the cross product of the operators vector (if it were a vector). In Java, this translates to a triply-nested set of loops.
While #TimBiegeleisen solution would work like a charm, its complexity might be an issue. The better approach would be a code like this:
static void combinationUtil(
int[] arr, int n, int r, int index, int[] data, int i) {
// Current combination is ready to be printed, print it
if (index == r) {
for (int j = 0; j < r; j++)
System.out.print(data[j] + " ");
System.out.println("");
return;
}
// When no more elements are there to put in data[]
if (i >= n)
return;
// current is included, put next at next location
data[index] = arr[i];
combinationUtil(arr, n, r, index + 1, data, i + 1);
// current is excluded, replace it with next (Note that
// i+1 is passed, but index is not changed)
combinationUtil(arr, n, r, index, data, i + 1);
}
// The main function that prints all combinations of size r
// in arr[] of size n. This function mainly uses combinationUtil()
static void printCombination(int arr[], int n, int r) {
// A temporary array to store all combination one by one
int data[] = new int[r];
// Print all combination using temprary array 'data[]'
combinationUtil(arr, n, r, 0, data, 0);
}
Source: GeeksForGeeks and my IDE :)
This sounds like a textbook case for a recursive solution:
public static void combineAndPrint(String[] pieces, String[] operators) {
if (pieces.length < 1) {
// no pieces? do nothing!
} else if (pieces.length == 1) {
// just one piece? no need to join anything, just print it!
System.out.println(pieces[0]);
} else {
// make a new array that's one piece shorter
String[] newPieces = new String[pieces.length - 1];
// copy all but the first two pieces into it
for (int i = 2; i < pieces.length; i++) {
newPieces[i - 1] = pieces[i];
}
// combine the first two pieces and recurse
for (int i = 0; i < operators.length; i++) {
newPieces[0] = pieces[0] + operators[i] + pieces[1];
combineAndPrint(newPieces, operators);
}
}
}
public static void main(String[] args) {
String[] operators = {"+", "-", "*"};
String[] numbers = {"48", "24", "12", "6"};
combineAndPrint(numbers, operators);
}
Try it online!
BTW, to generalize this method so that you can do more things with the generated expressions than just printing them, I would recommend making it accept an extra Consumer<String> parameter. That is, you could rewrite the method declaration as:
public static void combine(String[] pieces, String[] operators, Consumer<String> consumer) {
and replace the System.out.println(pieces[0]) with consumer.accept(pieces[0]) and the recursive call to combineAndPrint(newPieces, operators) with combine(newPieces, operators, consumer). Then just call it from your main method e.g. as:
combine(numbers, operators, s -> System.out.println(s));
Try it online!
(Of course, doing it in this more flexible way requires a somewhat modern Java version ā€” Java 8 or later, to be specific ā€” whereas the first example I showed above should work on even ancient versions all the way down to Java 1.0. Maybe in some future version of Java we'll get proper support for coroutines and generators, like Python and Kotlin and even modern JS already have, and then we won't even need to pass the consumer around any more.)
As already pointed out by findusl in his answer, the problem here is, strictly speaking, not to find any sort of "combination of two arrays". Instead, you basically just want to find all possible combinations of the available operators.
(The fact that you later want to "interveave" them with operands is rather unrelated to the core of the question)
So here is another option for solving this: You can create an iterable over all combinations of a certain number of elements from a certain set (in your case: the operators) and then simply combine the results with the other set (in your case: the operands).
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
public class OperatorsTest {
public static void main(String[] args) {
String[] operators = {"+", "-", "*"};
int[] numbers = {48, 24, 12, 6};
CombinationIterable<String> iterable =
new CombinationIterable<String>(3, Arrays.asList(operators));
for (List<String> element : iterable) {
System.out.println(interveave(element, numbers));
}
}
private static String interveave(List<String> operators, int numbers[]) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < operators.size(); i++) {
sb.append(numbers[i]);
sb.append(operators.get(i));
}
sb.append(numbers[numbers.length - 1]);
return sb.toString();
}
}
class CombinationIterable<T> implements Iterable<List<T>> {
private final List<T> input;
private final int sampleSize;
private final int numElements;
public CombinationIterable(int sampleSize, List<T> input) {
this.sampleSize = sampleSize;
this.input = input;
numElements = (int) Math.pow(input.size(), sampleSize);
}
#Override
public Iterator<List<T>> iterator() {
return new Iterator<List<T>>() {
private int current = 0;
private final int chosen[] = new int[sampleSize];
#Override
public boolean hasNext() {
return current < numElements;
}
#Override
public List<T> next() {
if (!hasNext()) {
throw new NoSuchElementException("No more elements");
}
List<T> result = new ArrayList<T>(sampleSize);
for (int i = 0; i < sampleSize; i++) {
result.add(input.get(chosen[i]));
}
increase();
current++;
return result;
}
private void increase() {
int index = chosen.length - 1;
while (index >= 0) {
if (chosen[index] < input.size() - 1) {
chosen[index]++;
return;
}
chosen[index] = 0;
index--;
}
}
};
}
}
The task resembles that of finding a set of operations that can be done with a certain number of operands and operators, and thus, this Q/A may be related. But whether or not things like associativity or commutativity should be considered here was not mentioned in the question.
I made an alternative, overengineered (but flexible!) "business" solution. The array lengths and values (numbers and operators) can be flexible.
package test1;
import java.io.IOException;
import java.util.ArrayList;
public class MainClass {
public static void main(String[] args) throws IOException {
String[] operators = {"+", "-", "*"};
int[] numbers = {48, 24, 12, 6};
ArrayList<String> strings =
new MainClass().getAllPossibleCombinations(numbers, operators);
for (String string : strings) {
System.out.println(string);
}
}
private ArrayList<String> getAllPossibleCombinations(
int[] numbers, String[] operators) {
if (numbers.length < 2)
throw new IllegalArgumentException(
"Length of numbers-array must be at least 2");
if (operators.length < 1)
throw new IllegalArgumentException(
"Length of operators-array must be at least 1");
ArrayList<String> returnList = new ArrayList<>();
int[] indexes = new int[numbers.length - 1];
while (true) {
StringBuilder line = new StringBuilder();
for (int i = 0; i < numbers.length; i++) {
int number = numbers[i];
line.append(number);
if (i < indexes.length) {
line.append(operators[indexes[i]]);
}
}
returnList.add(line.toString());
try {
this.updateIndexes(indexes, operators.length - 1);
} catch (NoMoreCombinationsException e) {
break;
}
}
return returnList;
}
private void updateIndexes(int[] currentIndexes, int maxValue)
throws NoMoreCombinationsException {
if (this.intArrayIsOnly(currentIndexes, maxValue)) {
throw new NoMoreCombinationsException();
}
for (int i = currentIndexes.length - 1; i >= 0; i--) {
int currentIndex = currentIndexes[i];
if (currentIndex < maxValue) {
currentIndexes[i] = currentIndex + 1;
break;
} else {
currentIndexes[i] = 0;
}
}
}
private boolean intArrayIsOnly(int[] array, int value) {
for (int iteratedValue : array) {
if (iteratedValue != value) return false;
}
return true;
}
}
class NoMoreCombinationsException extends Exception {
public NoMoreCombinationsException() {
}
public NoMoreCombinationsException(String message) {
super(message);
}
public NoMoreCombinationsException(String message, Throwable cause) {
super(message, cause);
}
public NoMoreCombinationsException(Throwable cause) {
super(cause);
}
public NoMoreCombinationsException(
String message, Throwable cause,
boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Works like a charm :)
A bit of background information why the answers are they way they are. This problem is not really called "all possible combinations" as that is usually the problem where you can represent the elements as bits and switch them to 0 or 1 whether the element is included or not. This has a complexity of 2^N where N is the amount of operators you have. This can be solved easily in a single loop.
However in your case you have the "urn problem with replacement and sequence". The complexity of this is N^n where n is the amount of spots you have to fill with operators. (This is often seen for pincodes where each spots can be 10 values). So because this is of higher complexity than the "all possible combinations" problem you need multiple loops or recursive calls.
So to answer the question, "how to solve this?". You have to solve it with multiple loops or recursion because of the underlying problem's complexity.
I've developed a class that covers this use case and many others. I call it the TallyCounter. Your question would be answered with this class like this:
package app;
import java.util.HashMap;
import java.util.Map;
import app.TallyCounter.Type;
public class App {
public static void main(String args[]) throws Exception {
Map<Long, String> map = new HashMap<>();
map.put(0l, "+");
map.put(1l, "-");
map.put(2l, "*");
TallyCounter counter = new TallyCounter(3, Type.NORMAL, 2);
do {
System.out.format("48%s24%s12%s6\n",
map.get(counter.getArray()[2]),
map.get(counter.getArray()[1]),
map.get(counter.getArray()[0])
);
counter.increment();
} while (!counter.overflowFlag);
}
}
You don't need multiple loops or recursion.
Here's an example showcasing a limited number of loops and no recursion at all.
int[][] combine(int[] values) {
int size = values.length;
int combinations = 1;
for (int i = 0; i < size; i++) {
combinations *= size;
}
// or int combinations = (int)Math.pow(size, size);
int[][] result = new int[combinations][size];
for (int i = 0; i < combinations; i++) {
int index = i;
for (int j = 0; j < size; j++) {
result[i][j] = values[index % size];
index /= size;
}
}
return result;
}
If you use it with three elements, [1, 2, 3], as in the code below:
void testCombine() {
int[][] combinations = combine(new int[]{1, 2, 3});
for (int[] combination : combinations) {
System.out.println(Arrays.toString(combination));
}
}
You end up with the following result:
[1, 1, 1]
[2, 1, 1]
[3, 1, 1]
[1, 2, 1]
[2, 2, 1]
[3, 2, 1]
[1, 3, 1]
[2, 3, 1]
[3, 3, 1]
[1, 1, 2]
[2, 1, 2]
[3, 1, 2]
[1, 2, 2]
[2, 2, 2]
[3, 2, 2]
[1, 3, 2]
[2, 3, 2]
[3, 3, 2]
[1, 1, 3]
[2, 1, 3]
[3, 1, 3]
[1, 2, 3]
[2, 2, 3]
[3, 2, 3]
[1, 3, 3]
[2, 3, 3]
[3, 3, 3]
You can use streams to get all possible combinations of two arrays. First, iterate over the numbers array and append the operator signs to each number, you get an array like this: {"48+", "48-", "48*"} for each number. The number of operators may vary. Then reduce this stream of arrays to a single array by sequentially multiplying array pairs, you get an array of possible combinations.
Try it online!
String[] operators = {"+", "-", "*"};
int[] numbers = {48, 24, 12, 6};
// an array of possible combinations
String[] comb = IntStream.range(0, numbers.length)
// append each substring with possible
// combinations, except the last one
// return Stream<String[]>
.mapToObj(i -> numbers.length - 1 > i ?
Arrays.stream(operators)
.map(op -> numbers[i] + op)
.toArray(String[]::new) :
new String[]{"" + numbers[i]})
// reduce stream of arrays to a single array
// by sequentially multiplying array pairs
.reduce((arr1, arr2) -> Arrays.stream(arr1)
.flatMap(str1 -> Arrays.stream(arr2)
.map(str2 -> str1 + str2))
.toArray(String[]::new))
.orElse(null);
// column-wise output (three columns in this case)
int columns = (int) Math.pow(operators.length, numbers.length - 2);
IntStream.range(0, columns)
.mapToObj(i -> IntStream.range(0, comb.length)
.filter(j -> j % columns == i)
.mapToObj(j -> comb[j])
.collect(Collectors.joining(" | ")))
.forEach(System.out::println);
Output:
48+24+12+6 | 48-24+12+6 | 48*24+12+6
48+24+12-6 | 48-24+12-6 | 48*24+12-6
48+24+12*6 | 48-24+12*6 | 48*24+12*6
48+24-12+6 | 48-24-12+6 | 48*24-12+6
48+24-12-6 | 48-24-12-6 | 48*24-12-6
48+24-12*6 | 48-24-12*6 | 48*24-12*6
48+24*12+6 | 48-24*12+6 | 48*24*12+6
48+24*12-6 | 48-24*12-6 | 48*24*12-6
48+24*12*6 | 48-24*12*6 | 48*24*12*6
See also: Generate all possible string combinations by replacing the hidden ā€œ#ā€ number sign

Java how to return an array with fibonacci values starting at 1?

I'm writing a void function fibFill which fills an array with Fibonacci numbers. It doesn't have to return anything.
Here's what I have so far:
void fibFill(int[] fibo) {
fibo[0] = 1;
fibo[1] = 1;
for (int i = 2; i < fibo.length; i++) {
fibo[i] = fibo[i - 1] + fibo[i - 2];
}
int pos(int position) {
return fibo[pos];
}
}
For example, if I pass an array of length 5 to the method, it will override the contents of the passed array like this: [1, 1, 2, 3, 5]
Your fibFill method shouldn't have a pos method embedded in it; and I would make it static (so it can be called without an instance), like
static void fibFill(int[] fibo) {
fibo[0] = 1;
fibo[1] = 1;
for (int i = 2; i < fibo.length; i++) {
fibo[i] = fibo[i - 1] + fibo[i - 2];
}
}
Then you can test it with something like
public static void main(String[] args) {
int[] fib = new int[10];
fibFill(fib);
System.out.println(Arrays.toString(fib));
}
Which outputs (as requested) the fibonacci values starting at 1
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
fixed:
static void fibFill(int [] fibo) {
if(fibo.length==0) return;
if(fibo.length==1)
{
fibo[0]=1;
return;
}
fibo[0] = 1;
fibo[1] = 1;
for (int i = 2;i < fibo.length; i++)
{
fibo[i]=fibo[i-1]+fibo[i-2];
}
}
//there is no need for pos, as you can get it by type fibo[index]
Note that this solution cost you O(n), you can also do it directly by formula and there is also more ways to calculate fibonacci. for more information:
five ways to calculate fibonacci
if (n==0||n==1) {
return n;
}
int smallassumption=fib(n-1);
int smallassumption2=fib(n-2);
int ans=smallassumption+smallassumption2;
return ans;

Is there a way to define the value of the index in an arraylist?

I had an assignment due today ( its late already so i wont be getting credit for this but the problem is eating at me) that I could not figure out for the life of me. The assignment goes as followed: withoutTen: Return a version of the given array where all the 10's have been removed.
The remaining elements should shift left towards the start of the array as needed,
and the empty spaces at the end of the array should be 0.
So {1, 10, 10, 2} yields {1, 2, 0, 0}.
You may modify and return the given array or make a new array.
withoutTen({1, 10, 10, 2}) --> {1, 2, 0, 0}
withoutTen({10, 2, 10}) --> {2, 0, 0}
withoutTen({1, 99, 10}) --> {1, 99, 0}
I have tried various things to make the program work but failed.
`
// The arraylist is already defined to an Integer class with a name of list
int i= 0;
//loop
for(i = 0; i < list.size(); i++)
{
if( list.get(i) == 10)
{
list.remove(i);
list.add(0);
}
}
return list;
`
This shows the right result {1,2,0,0} but that is the only one. Can anyone explain to me if there is a way to change the value of the index if it equals 10 and send it to the back of the line as a 0?
I think you do not fully understand Java syntax. I do not say that to feel smug, but the code probably does not do what you think it does. Review your Java syntax knowledge and then try again. :-)
You could simply do
int nbOccur = Collections.frequency(yourList, 10);
yourList.removeAll(Collections.singleton(10));
yourList.addAll(Collections.nCopies(nbOccur, 0));
Get the number of occurences(n) of 10.
Remove them all.
Add a List that contains n times 0.
A one liner with Java 8 would be
yourList.stream()
.filter(i -> i != 10)
.collect(Collectors.toList())
.addAll(Collections.nCopies(Collections.frequency(yourList, 10), 0));
Basically - you treat it as a copy process where you walk a from and a to up the array making sure from skips 10 whenever it sees it.
public int[] withoutTen(int[] a) {
// Where we are copying to.
int to = 0;
// Where we are copying from.
int from = 0;
// Zero padding at the end so carry on 'till to gets there.
while (to < a.length) {
// Skip all 10s.
while (from < a.length && a[from] == 10) {
// Skip it.
from += 1;
}
// Copy it (or 0 if we're past the end).
a[to++] = from < a.length ? a[from++] : 0;
}
return a;
}
public void test() {
int[][] tests = new int[][]{
{1, 10, 10, 2},
{10, 2, 10},
{1, 99, 10}
};
for (int[] a : tests) {
System.out.println("\t" + Arrays.toString(a) + " -> " + Arrays.toString(withoutTen(a)));
}
}
prints
[1, 10, 10, 2] -> [1, 2, 0, 0]
[10, 2, 10] -> [2, 0, 0]
[1, 99, 10] -> [1, 99, 0]
Equivalent using for loop is a little tidier:
public int[] withoutTen(int[] a) {
// Zero padding at the end so carry on 'till to gets there.
for (int to = 0, from = 0; to < a.length; to++, from++) {
// Skip all 10s.
while (from < a.length && a[from] == 10) {
// Skip it.
from += 1;
}
// Copy it (or 0 if we're past the end).
a[to] = from < a.length ? a[from] : 0;
}
return a;
}
Do you have to worry about the data space complexity ? if yes then -- obviously you can do better --but this should work for your purpose..
psudo code
List<Integer> beforeList = Arrays.asList(1,10,10,0,2);
//create array
int[] myFinalArray = new int[beforeList.size]()
int arrayIdx =0;
for (Integer i : beforeList){
if (i != 10){
myFinalArray[arrayIdx++ ] = i;
}
}
//print/return your finalArray
Thank you guys for the help, it seems that my code was almost correct but i did have my list.get() method wrong. I had placed a (1) instead of (i) which in fact caused me a lot of pain and errors. for(int i=0; i<list.size();i++)
{
if(list.get(i)==10)
{
list.remove(i);
list.add(0);
}
Take a look at my answer for this
public int[] withoutTen(int[] nums) {
if (nums == null) {
return nums;
}
int non10pos = 0;
for (int i = 0; i < nums.length; ++i) {
if (nums[i] != 10) {
int temp = nums[i];
nums[i] = nums[non10pos]; // move the non-zero number to position i
nums[non10pos] = temp; // move the non-10 number toward the front
++non10pos;
}
else{
nums[i] = 0;
}
}
return nums;
}
My solution passes all the tests:
public int[] withoutTen(int[] nums) {
if (nums.length == 0) {
return nums;
}
int[] withoutTen = new int[nums.length];
int counter = 0;
for (int i = 0; i < withoutTen.length; i++) {
if (nums[i] != 10) {
for (int j = counter; j < withoutTen.length; j++) {
withoutTen[j] = nums[i];
break;
}
counter++;
}
}
return withoutTen;
}

Removing duplicates from array without using Util classes

Please read the question before marking it as duplicate
I have written following code to remove duplicates from array without using Util classes but now I am stuck
public class RemoveDups{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
int temp;
for (int i : a) {
for (int j = 0; j < a.length - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
a = removeDups(a);
for (int i : a) {
System.out.println(i);
}
}
private static int[] removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
}
}
return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
and now the output is
1
2
3
4
5
6
45
52
0
0
0
0
0
0
0
0
0
0
Here my problem is
My code is not working in case of 0s
I am not able to understand how sorting an array can reduce time of execution
Is there any way to remove elements from array without using Util classes I know one way to remove convert array into list and then remove but for that also we need Util classes is there any way to implement by myself.
Since the numbers you deal with are limited to a small range you can remove duplicates by a simple "counting sort": mark the numbers you have found in a set-like data structure and then go over the data structure. An array of boolean works just fine, for less memory usage you could create a basic bitset or hash table. If n is the number of elements in the array and m is the size of the range, this algorithm will have O(n+m) complexity.
private static int[] removeDups(int[] a, int maxA) {
boolean[] present = new boolean[maxA+1];
int countUnique = 0;
for (int i : a) {
if (!present[i]) {
countUnique++;
present[i] = true;
}
}
int[] result = new int[countUnique];
int j = 0;
for (int i=0; i<present.length; i++) {
if (present[i]) result[j++] = i;
}
return result;
}
I am not able to understand how sorting an array can reduce time of execution
In a sorted array you can detect duplicates in a single scan, taking O(n) time. Since sorting is faster than checking each pair - O(n log n) compared to O(nĀ²) time complexity - it would be faster to sort the array instead of using the naive algorithm.
As you are making the result array of the same length as array a
so even if you put only unique items in it, rest of the blank items will have the duplicate values in them which is 0 for int array.
Sorting will not help you much, as you code is searching the whole array again and again for the duplicates. You need to change your logic for it.
You can put some negative value like -1 for all the array items first in result array and then you can easily create a new result array say finalResult array from it by removing all the negative values from it, It will also help you to remove all the zeroes.
In java , arrays are of fixed length. Once created, their size can't be changed.
So you created an array of size18.
Then after you applied your logic , some elements got deleted. But array size won't change. So even though there are only 8 elements after the duplicate removal, the rest 10 elements will be auto-filled with 0 to keep the size at 18.
Solution ?
Store the new list in another array whose size is 8 ( or whatever, calculate how big the new array should be)
Keep a new variable to point to the end of the last valid element, in this case the index of 52. Mind you the array will still have the 0 values, you just won't use them.
I am not able to understand how sorting an array can reduce time of execution
What ? You sort an array if you need it to be sorted. Nothing else. Some algorithm may require the array to be sorted or may work better if the array is sorted. Depends on where you are using the array. In your case, the sorting will not help.
As for your final question , you can definitely implement your own duplicate removal by searching if an element exists more than once and then deleting all the duplicates.
My code is not working in case of 0
There were no zeroes to begin with in your array. But because its an int[], after the duplicates are removed the remaining of the indexes are filled with 0. That's why you can see a lot of zeroes in your array. To get rid of those 0s, you need to create another array with a lesser size(size should be equal to the no. of unique numbers you've in your array, excluding 0).
If you can sort your array(I see that its already sorted), then you could either bring all the zeroes to the front or push them to the last. Based on that, you can iterate the array and get the index from where the actual values start in the array. And, then you could use Arrays.copyOfRange(array, from, to) to create a copy of the array only with the required elements.
try this
package naveed.workingfiles;
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45, };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
public class RemoveDups {
public static void main(String[] args) {
int[] a = { 1, 2, 0, 3, 1,0, 3, 6, 2};
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
boolean zeroExist = false;
for (int i : a) {
if(i==0 && !zeroExist){
result[j++] = i;
zeroExist = true;
count++;
}
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i=0;i<count;i++) {
System.out.println(result[i]);
}
// return result;
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}
// It works even Array contains 'Zero'
class Lab2 {
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 3, 1, 4, 52, 1, 45 };
removeDups(a);
}
private static void removeDups(int[] a) {
int[] result = new int[a.length];
int j = 0;
int count = 0;
for (int i : a) {
if (!isExist(result, i)) {
result[j++] = i;
count++;
}
}
System.out.println(count + "_____________");
for (int i = 0; i < count; i++) {
System.out.println(result[i]);
}
}
private static boolean isExist(int[] result, int i) {
for (int j : result) {
if (j == i) {
return true;
}
}
return false;
}
}

What's wrong with my Dutch National Flag algorithm?

I'm trying to turn an array like this:
0, 1, 2, 2, 1, 0, 1, 0, 0, 1, 2
into this:
0 0 0 0 1 1 1 1 2 2 2
Here is my code:
public static int[] sortDNF(int[] tape) {
int smaller = 0; // everything with index < smaller is 0
int bigger = tape.length - 1; // everything with index > bigger is 2
int current = 0; // where we are looking now
int tmp;
while (current <= bigger) {
if (tape[current] == 0) {
tmp = tape[smaller];
tape[smaller] = tape[current];
tape[current] = tmp;
smaller++;
}
if (tape[current] == 2) {
tmp = tape[bigger];
tape[bigger] = tape[current];
tape[current] = tmp;
bigger--;
}
current++;
}
return tape;
}
This is what it produces:
0 0 0 1 1 1 1 0 2 2 2
What is my problem?
A guess:
You should not be increasing current every time through the loop since that is supposed to represent the partition between the 1's and the unknowns. For example, when you hit the first 2 you end up swapping it with another 2 and then moving on. The fact that the 2 later gets swapped for a 0 is accidental. The elements between smaller and current should always be 1's and that is broken.
current++ should only be done in the tape[current] != 2 case. It's ok to do it when tape[current] = 0 because you haven't changed the [smaller -> current] = 1-only condition. And it's ok to move it when tape[current] = 1 because that satisfies the 1-only condition.
...but I haven't tried it.
For those who haven't studied the problem, sorting is sufficient to provide a solution, but it is (or can be) more than necessary. Solving the DNF problem only requires that all like items be moved together, but you don't have to place unequal items in any particular order.
It's pretty easy to solve DNF with expected O(N) complexity, where (most normal forms of) sorting have O(N lg N) complexity. Instead of rearranging the input elements, it's much easier to simply count the elements with any given value, then print out the right number of each. Since the order of unequal elements doesn't matter, you normally store your counts in a hash table.
The problem is that you reply on (possible nonexistent) values later in the chain to swap incorrectly skipped 1 values, try your algo on the trivial case of:
1 2 0
the 2 gets swapped in the right spot, but the current index has been advanced over the index 0 ends up in resulting in:
1 0 2
So don't increment current before you inspect the new value at that index.
You need to increment current only during the check for 1 and check for 2. When you are checking for 3 you just need to decrement bigger. Here the working solution. BTW this works for the array of values between 1-3. You can change it to 0-2 if you so wish.
The program produces the following output given a random number array as follows:
Original Array : [1, 3, 3, 3, 2, 2, 2, 1, 2, 2, 1, 3, 3, 2, 1, 1, 3]
Sorted Array : [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3]
private static int[] sortUsingDutchNationalFlagProblem(int[] array)
{
System.out.println("Original Array : " + Arrays.toString(array));
int smaller = 0; // everything with index < smaller is 1
int bigger = array.length - 1; // everything with index > bigger is 3
int current = 0; // where we are looking now
int tmp;
while (current <= bigger) {
if (array[current] == 1) {
tmp = array[smaller];
array[smaller] = array[current];
array[current] = tmp;
smaller++;current++;
}
if(array[current] == 2)
current++;
if (array[current] == 3) {
tmp = array[bigger];
array[bigger] = array[current];
array[current] = tmp;
bigger--;
}
}
System.out.println("Sorted Array : " + Arrays.toString(array));
return array;
}
Here is my approach using Java
public static void dutchNationalFlagProblem(int[] input) {
int low=0, mid=0, high = input.length -1;
while(mid <=high) {
switch (input[mid]) {
case 0:
swap(input, low++, mid++);
break;
case 1:
mid++;
break;
default :
swap(input, mid, high--);
break;
}
}
}
private static void swap(int[] input, int firstIndex, int secondIndex) {
int temp = input[firstIndex];
input[firstIndex] = input[secondIndex];
input[secondIndex] = temp;
}
Here is the corresponding test cases
#Test
public void dutchNationalFlagProblemTest() {
int[] input = new int[]{0,1,0,2,2,1};
ArrayUtils.dutchNationalFlagProblem(input);
assertThat(input, equalTo(new int[]{0,0,1,1,2,2}));
}
I'm going to propose an easier solution :-)
public static int[] sortDNF(int[] tape) {
Arrays.sort(tape);
return tape;
}
As far as what's wrong with your solution, when the current element is 2 and it's swapped with the element near the end of the list, the element it's swapped with may not be 2, but you're incrementing current and not looking at this position again.
public static int[] sortDNF(int[] tape) {
int smaller = 0; // everything with index < smaller is 0
int bigger = tape.length - 1; // everything with index > bigger is 2
int current = 0; // where we are looking now
int tmp;
while (current <= bigger) {
if (tape[current] == 0) {
tmp = tape[smaller];
tape[smaller] = tape[current];
tape[current] = tmp;
smaller++;
}
else if (tape[current] == 2) {
tmp = tape[bigger];
tape[bigger] = tape[current];
tape[current] = tmp;
bigger--;
}
current++;
}
return tape;
}
Below program is giving right result, do you guys see any issue in this simple innocent programming approach?
public class Test {
public static void main(String[] args) {
int arr[] = {1, 2, 0, 2, 1, 1, 1, 0, 0, 2, 2, 1, 0, 1, 2, 0, 2};
int x0 = 0, x1 = 0, x2 = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == 0)
x0++;
if (arr[i] == 1)
x1++;
if (arr[i] == 2)
x2++;
}
int i = 0;
for (int j = i; j < x0; j++)
arr[i++] = 0;
for (int j = i; j < x0+x1; j++)
arr[i++] = 1;
for (int j = i; j < x0+x1+x2; j++)
arr[i++] = 2;
printArray(arr);
}
private static void printArray(int[] arr) {
for (int a : arr) {
System.out.print(a + " ");
}
}
}

Categories