2015-11-13 3 views
3

Я новичок в переполнении стека, и у меня есть лабораторный вопрос для класса программирования, который ускользал от меня. Задача требует, чтобы мы переместили элементы строки s в левые k раз. Например, если вход «Hello World» и 3, он будет выводить «lo WorldHel»). Он также должен работать относительно эффективно при очень больших значениях k. Это то, что я до сих пор:Смещение символов в строке слева

String cyclicLeftShift(String s, int k){ 
    String result=""; 

    for(int i=0;i<k;i++){ 
     result = s.substring(1, s.length() - 1) +s.charAt(0); 

     s=result; 
    } 
    return s; 
} 

Моя главная проблема в том, что последний символ исходной строки продолжает перезаписываются последующими итераций цикла. Я пробовал множество перестановок, включая преобразование всего объекта в массивы (что нарушает ограничение эффективности в исходной задаче). Я чувствую, что есть только крошечная вещь, которую я не получаю, и мне было интересно, может ли кто-нибудь дать мне толчок в правильном направлении?

Спасибо!

ответ

4

Что вы хотите, чтобы разделить строку в позиции k и объединить обе части вместе снова, но в обратном порядке. Основная проблема заключается в том, что k может быть больше или равно размеру вашей строки. Поэтому вам нужно снова привести k в допустимый диапазон.

public static String cyclicLeftShift(String s, int k){ 
    k = k%s.length(); 
    return s.substring(k) + s.substring(0, k); 
} 

Тестирование метода:

public static void main(String[] args) 
{ 
    String test = "Hello World"; 
    for(int i = 0; i < test.length()*3; i++) 
     System.out.println(cyclicLeftShift(test, i)); 
} 

Выход:

Hello World 
ello WorldH 
llo WorldHe 
lo WorldHel 
o WorldHell 
WorldHello 
WorldHello 
orldHello W 
rldHello Wo 
ldHello Wor 
dHello Worl 
Hello World 
ello WorldH 
llo WorldHe 
lo WorldHel 
o WorldHell 
WorldHello 
WorldHello 
orldHello W 
rldHello Wo 
ldHello Wor 
dHello Worl 
Hello World 
ello WorldH 
llo WorldHe 
lo WorldHel 
o WorldHell 
WorldHello 
WorldHello 
orldHello W 
rldHello Wo 
ldHello Wor 
dHello Worl 
+0

Это работает отлично и с относительной эффективностью. Благодаря! – maniczebra

+0

Хорошо, что мое решение сработало. :) – Jalai

1

Попробуйте это мой мальчик:

String cyclicLeftShift(String s, int k) { 

    String result = s.substring(k); 

    for (int i = 0; i < k; i++) { 

     result += s.charAt(i); 

    } 

    return result; 

} 
+1

** StringIndexOutOfBoundsException ** будет сгенерирован, если ваш к выше, то ваша длина строки. Например, если ваша строка «Hello World» и k равна 15. –

+0

Да, я вижу. этот метод должен только сдвинуть действительный счетчик k. Это исключение должно проверяться перед вызовом этого метода. Я думаю, что случай k выше, чем строка не должна выполняться. Программист должен ответить на сообщение об ошибке для этого случая. Поэтому в этом методе я не добавил никаких исключений. Этот улов должен быть в основном. ОК? –

+0

Это лучший подход. – Praneeth

1

Вы можете попробовать это:

public static String cyclicLeftShift(String s, int k){ 
    String result=s; 

    for(int i=0; i<k; i++){ 
     result = result.substring(1) + result.charAt(0); 
    } 

    return result; 
} 

Вот пример через TutorialsPoint. Просто нажмите скомпилируйте, затем выполните, чтобы увидеть результат.

+0

В tut при компиляции возникает ошибка. вместо смены вы положили рубашку. – Praneeth

+0

Как это дешевле, чем исходный код? –

0

Аргументы для String.substring(): (beginIndex, endIndex), NOT (beginIndex, count). Вам нужно передать s.length() вместо s.length() - 1 ... Или вы могли бы сделать это одним из гораздо более быстрых способов публикации других сообщений

1

Возможно, мне что-то не хватает, но можете ли вы не только mod k длиной s, чтобы получить n (количество символов для смещения), затем возьмите подстроку [0, n) и добавьте ее в подстроку [n, s.length() -1]?

.: например

String cyclicLeftShift(String s, int k){ 
    String result=""; 
    int n = k % s.length(); 
    result = s.substring(n) + s.substring(0,n); 

    return result; 
} 
Смежные вопросы