0

Given an array of int, and an index k. The task is to output the array that has been left-shift rotated by k.

eg...

a = [1,2,3,4,5], k = 4

Output:
5 1 2 3 4

In Javascript the code is:

var result = a.slice(d).join(' ') + ' ' + a.slice(0, d).join(' ')

I'm really struggling to find a concise equivalent in Java.

Shammoo
  • 1,084
  • 10
  • 22
  • 1
    Possible duplicate of [Java, Shifting Elements in an Array](https://stackoverflow.com/questions/7970857/java-shifting-elements-in-an-array) – tnw Jul 11 '17 at 14:54
  • [this](https://stackoverflow.com/a/26610474/7381547) is probably the easiest way, note that it takes Integers and not ints – Tom K Jul 11 '17 at 14:55
  • Didn't came back to accept some answer ? – azro Jul 12 '17 at 13:03

2 Answers2

2

As you say you only need to output, this will work :

int[] a = new int[]{1, 2, 3, 4, 5};
int k = 4;
for (int i = 0; i < a.length; i++) {
      System.out.print(a[(i + k) % a.length] + " ");
}
Michael Markidis
  • 4,163
  • 1
  • 14
  • 21
azro
  • 53,056
  • 7
  • 34
  • 70
1

This depends on your definition of concise, I suppose. Here's a bit of Java 8 Stream capability that does what you want, in a similar way to your JS code, and is arguably somewhat concise.

int[] arr = {1, 2, 3, 4, 5};
int k = 4;
String result = Arrays.stream(arr).skip(k).mapToObj(Integer::toString).collect(Collectors.joining(" ")) +  " " + Arrays.stream(arr).limit(k).mapToObj(Integer::toString).collect(Collectors.joining(" "));

To break down what each bit does:

  • Arrays.stream(arr) just creates a Stream of ints (Specifically, an IntStream, since int, as a built-in type, must have its own wrapper stream class rather than the generic Stream<T>).
  • skip(k) essentially discards as many elements as the provided input, so we can start with the part from the index forward.
  • mapToObj(Integer::toString) is how we convert the Stream from an IntStream to a Stream<String>, so that we can join it into a single String. It takes each element in the Stream and applies the Integer.toString method to it, i.e. if each element of the Stream were in turn referred to as int, it would be like calling Integer.toString(int). We are now left with a Stream of Strings representing the numbers.
  • collect(Collectors.joining(" ")) takes each value, and gives it to a Collector. Collectors take Streams and reduce them to single objects. In this case, the joining Collector takes each object and joins them all to a single string, and the argument we have provided is the delimiter it uses.
  • Looking at the second half of the procedure, the only really different part is limit(k), which simply takes the first k elements of the Stream and ignores the rest.

It's a bit more long-winded that your JS example (necessary partly because of Java's strong typing and partly because Java arrays aren't objects and therefore don't do anything useful by themselves), but fairly easy to understand and very powerful.

Tim M.
  • 598
  • 5
  • 15
  • `String result=IntStream.concat(Arrays.stream(arr,k,arr.length), Arrays.stream(arr,0,k)) .mapToObj(Integer::toString).collect(Collectors.joining(" "));` – Holger Jul 21 '17 at 08:44