Rotate List - Java Fundamentals for QA

Здравейте,
Опитвам се върху една задача, но нещо не се получава:

Write a program that rotates a list several times (the first element becomes last).

  • list = 1,2,3,4,5 and N = 2 -> result = 3,4,5,1,2
    Note that N could be larger than the length of the list.
  • list = 1,2,3,4,5 and N = 6 -> result = 2,3,4,5,1

Input

  • On the first line you will receive the list of numbers.
  • On the second line you will receive N

Output

  • On the only line of output, print the numbers separated by a comma.

Ето го и кода:

import java.util.Scanner;

public class Main {
public static void main(String[] args) {

    Scanner scanner = new Scanner(System.in);

    String line1 = scanner.nextLine();
    String line2 = scanner.nextLine(); 
    
    String[] strNumbers = line1.split(",");
    int rotationNumber = Integer.parseInt(line2);
    int[] IntArray = new int [strNumbers.length];
    
    for ( int i = 0; i <= IntArray.length; i++ ){
         IntArray[i] = Integer.parseInt(strNumbers[i]);
    } 
    
   int r = rotationNumber;
   int n = IntArray.length; 
   int [] tempArray = new int[n];
   
   for ( int i = 0; i <= tempArray.length; i ++){
       tempArray[i] = IntArray[i+r];
   }
   
   for ( int i = 0 ; i<= tempArray.length; i++){
       System.out.print(tempArray[i] + " "); 
   }
    
}

}

Здравей,
Започнал си добре, но реално нямаш избистрен алгоритъм за решаване на задачата ще трябва още да помислиш. В момента кода ти хвърля ArrayIndexOutOfBoundsException защото подаваш индекс извън обхвата на array, имай предвид че веднъж създадеш ли го не можеш да му промениш дължината.
Няколко насоки: Какво правиш, когато n e по-голямо число от дължината на масива? На какъв индекс е последния елемент на масива, защото въртиш цикъл от 0 до дължината на масива включително? Колко пъти ще се завърти реално този цикъл, няма ли да удариш отново exception?
Насочвам те малко към моето решение - реално не е необходимо да напълниш tempArray в един цикъл, можеш да го разделиш в 2 като в единия изместваш на дясно елементите с колкото трябва и в другия цикъл допълваш останалите числа. Пиши ако имаш въпроси.
Поздрави,
Теди

Супер. Много добри насоки. И аз малко ще подскажа с въпрос. Какво дава модулното делене и какъв резултат ще върне rotationNumber % IntArray.length ? Дано това да помогне.
Впрочем кръщавай си променливите с малка първа буква.

Привет,
Благодаря за съвета. Ще погледна и https://www.javatpoint.com/java-program-to-right-rotate-the-elements-of-an-array.

Здравей,
Преди много време с JS решавах подобна задача :
https://pastebin.com/REnhD8zE и сега се опитвам да видя с Java как да стане.
Благодаря за насоките.

Супер. Логиката от javatpoint.com също ще свърши работа, като за граница на външния цикъл сложи резултата от модулното делене. Успех.

Привет,

Пробвах това :

смених : границата на външня цикъл с резултата от rotationNumber % IntArray.length,

но ми излиза " Index 4 out of bounds for length 4". Имам съмнения за по горе в кода ако не съм декларирал правилно дължината на IntArray…

Привет,
кода ти работи, само трябва да махнеш едно =

    for (int i = 0; i < intArray.length; i++) {
        intArray[i] = Integer.parseInt(strNumbers[i]);
    }

В първия цикъл за границата трябва да махнеш знака за равно, тъй като индексите са с един по-малко от дължината, защото индексите се броят от нула, а дължината не включва нулата. Тоест ако имаме пет елемента, последния индекс всъщност е 4, защото първия е 0. Характерното за фор-цикъла, е че итератора се инкрементира след като се изпълни тялото му и това обърква много хора, тъй като тази последователност по нищо не личи от начина по който се изписва. Но това е положението, такива са правилата. Дано да си разбрал хаотичните ми разсъждения :smile:
Впрочем не е нужно да парсваш. Ако има нещо пак пиши.

Привет,
Ами махнал съм “=” доколото виждам :slight_smile:
Ами това е последното което сътворих:

input ```
5,3,2,1
2

Output
2,1,5,3      -  тук е ок.


Обаче на следващия тест, нещо не го кефи алгоритъма  ахахах  :)  и дава грешка. 
Съгласно задачта трябва да е така:
Input : ```
2,1,3,4
5

Output

1,3,4,2    

а на мен ми се получава друго… ахах.

Благодаря Теодора,

Поиграх си тази задача и това сътворих, няколко теста минават, но има и тест който не минава.
https://pastebin.com/NeLx68pB и се чудя къде е уловката. Утре пак ще я пробвам.

Ааа, това е защото ги върти на обратно :smile:
Утре опитай да обърнеш цикъла.

  1. last да приеме стойността на елемента с индекс 0;
  2. цикъла да върви от 0 до предпоследния, като всеки текущ елемент приема стойността на следващия елемент;
  3. след това последния елемент да приеме стойността на last.

Ако не става, пиши.
И ако стане, пак пиши :slight_smile:

Колегата вече ти каза, но само да вметна че забелязах, че си пишеш принтове на някои неща, които не са ти ясни, тях можеш много лесно да ги видиш в debug режим без да е нужно да изпълняваш цялата задача (цъкаш в полето от ляво на реда, който те интересува и се появява break point там ще ти се спре изпълнението на програмата; после вместо триъгълника цъкаш буболечката горе в дясно; програмата спира и има една стрелка с която ръчно изпълняваш кода ред по ред;когато си в дебъг режим има едно като калкулаторче ‘evaluate expression’ в което можеш да си пишеш код, за да видиш какво прави) Ако знаеш за това извинявай, че толкова подробно ти го обясних, но аз като започвах дебъг режима беше game changer за мен :slightly_smiling_face:

1 Like

Привет,
Благодаря за детайлите :slight_smile: .
Когато писах потенциалното решение си пишех и принтове за да видя в даден момент какво се случва,и след това съм ги сложил като коментар. ( примерно да си видя дължината на масива, какво се случва след изпълнението на даден цикъл и др.) Някой от тестовете минават, дава ми 60 т но 2 теста не минават и ще я пробвам пак.
Поздрави,
Владимир

Здравей, и аз се занимавах малко с тази задача, исках да я направя без rotate метода, ето кодът ми, който минава на 100%, сигурно би могъл да се оптимизира, но в общи линии логиката е дали броят на завъртанията е по-голям от дължината на масива, ако не - се взема разликата между двете, ако да - остатъка получен с модулно деление, като е важно да не забравяме и случай ако са равни

import java.util.Scanner;

public class RotateList_Problem4 {
public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);
    String[] list = sc.nextLine().split(",");
    int rotation = Integer.parseInt(sc.nextLine());
    int n = list.length;

    if (n > rotation) {

        int[] tempArr = new int[rotation];
        int[] rest = new int[n - rotation];

        for (int i = 0; i < n - rotation; i++) {
            rest[i] = Integer.parseInt(list[i + rotation]);
            System.out.print(rest[i] + ",");

        }

        for (int i = 0; i < rotation; i++) {
            tempArr[i] = Integer.parseInt(list[i]);
            System.out.print(tempArr[i]);
            if (i != rotation - 1) {
                System.out.print(",");
            }
        }


    } else if (n < rotation) {

        int rotationTimes = rotation % n;
        int[] tempArr = new int[rotationTimes];
        int[] rest = new int[n - rotationTimes];

        for (int i = 0; i < n - rotationTimes; i++) {
            rest[i] = Integer.parseInt(list[i + rotationTimes]);
            System.out.print(rest[i] + ",");
        }

        for (int i = 0; i < rotationTimes; i++) {
            tempArr[i] = Integer.parseInt(list[i]);
            System.out.print(tempArr[i]);

            if (i < rotationTimes - 1) {
                System.out.print(",");
            }
        }


    } else {
        for (int i = 0; i < list.length; i++) {
            System.out.print(list[i]);

            if (i < list.length - 1) {
                System.out.print(",");
            }

        }

    }
}

}

Благодаря @medon3 . Решавах подобна задача с JavaScript …

1 Like
 Scanner scan = new Scanner(System.in);
        String[] numbers = scan.nextLine().split(",");
        ArrayList<String> nums = new ArrayList<>();
        for (int i = 0 ; i < numbers.length ;i++) {
            nums.add(numbers[i]);
        }


        int num  = Integer.parseInt(scan.nextLine());

        for (int i = 0 ; i < num ; i++) {
            String temp = nums.get(0);
            nums.remove(temp);
            nums.add(temp);
        }
        System.out.println(String.join(",",nums));
1 Like

Това е моето решение
Scanner sc = new Scanner(System.in);
String[] line = sc.nextLine().split(",");
int [] inputArray = new int[line.length];
int rotationNumber = Integer.parseInt(sc.nextLine());
int length = inputArray.length;

    System.out.println("Print original array");
    for (int i = 0; i < inputArray.length; i++) {
        inputArray[i] = Integer.parseInt(line[i]);
        System.out.print(inputArray[i] + ", ");
    }

    //Define one temporary variable temp which will hold the first element of inputArray.
    int temp;
    
    //First copy the first element of inputArray into temp and then shift all elements one position left.
    // After shifting, copy back temp into inputArray as last element. Repeat this step n times.

    for (int i = 0; i < rotationNumber; i++) {
        
        temp = inputArray[0];

        for (int j = 0; j < inputArray.length-1; j++) {
           
            inputArray[j] = inputArray[j+1];
        }
        
        inputArray[inputArray.length-1] = temp;
    }
    System.out.println();
    System.out.println(Arrays.toString(inputArray).replace("[", "").replace("]",""));
    }
3 Likes