2015-01-18 3 views
3

Я попробовал два способа обратить вспять char массивуКаков наиболее эффективный способ обращения к массиву символов?

//method 1 
    char c[] = {'A', 'B', 'C', 'D'}; 
    char c_rev[] = new char[4]; 
    for (int i = 3; i >= 0; i--) { 
     c_rev[i] = c[3 - i]; 
    } 
    System.out.println(Arrays.toString(c_rev)); 

//method 2 
    char c[] = {'A', 'B', 'C', 'D'}; 
    Stack<Character> st = new Stack(); 
    for (int i = 0; i < 4; i++) { 
     st.push(c[i]); 
    } 
    for (int i = 0; i < 4; i++) { 
     c[i] = st.pop(); 
    } 
    System.out.println(Arrays.toString(c)); 

Я просто подумал , что будет наиболее эффективным. Способ 1 или Способ 2? Может ли кто-нибудь помочь мне или дать какие-либо предложения?

+1

С точки зрения временной сложности они оба O (n). – Maroun

+0

@MarounMaroun: да, это правда. Итак, если вам нужно выбрать метод? Что выберете? – prime

+0

Нет, используйте готовый метод. – Maroun

ответ

3

С точки зрения временной сложности, они оба являются O (n). Производительность здесь не будет существенной.

Какой из них выбрать? Никто. Я хотел бы использовать готовый метод StringBuilder#reverse:

String reversed = new StringBuilder(new String(c)).reverse().toString(); 

Если бы я хотел, чтобы выбрать один из двух методов, которые вы корректна, я бы выбрать первый, он имеет только одну петлю, и это просто, никакие методы не будут называться , никакие вспомогательные объекты не будут созданы; вы просто создаете новый массив и прямо нажимаете на него новые элементы.

+0

Я тоже видел этот метод. Поэтому, учитывая, что это было бы лучшим подходом, если вы хотите выбрать один из указанных 2 методов (в вопросе), что вы выберете. Просто для обучения цели. Что касается временной сложности, они оба O (n). Есть ли способ, которым какой-либо метод выполняет другой? – prime

+1

@prime Я бы выбрал первый, у него есть только один цикл, и это просто. – Maroun

+0

Это первое, что мне пришло в голову. Давайте посмотрим, что другие скажут. – prime

1

Я бы сказал, что метод 1, вероятно, быстрее, поскольку он не требует создания, выделения и уничтожения новых объектов (т. Е. Стека и его внутренних объектов). По той же причине он также должен оказывать меньшее влияние на сборщик мусора.

Если это частая операция в вашем коде, вы можете сравнить оба метода, используя что-то вроде Google caliper. В противном случае я бы не стал беспокоиться об этом :)

2

@ MarunMaroun's answer будет работать для массивов символов, которые действительно являются строками. Если вы беспокоитесь только об этих двух методах, то первое включает в себя меньше распределений кучи и GC.

Однако в целом для массива я бы использовать ни один из ваших методов, но вместо этого:

int len = c.length; 
for(int i = 0; i < len/2; i++) { 
    char ch = c[i]; 
    c[i] = c[len - i - 1]; 
    c[len - i - 1] = ch; 
} 

Это:

  1. короче, чем метод 2 типа
  2. только итерацию для половины длина массива (все равно O (n) из-за ops на итерацию)
  3. будет работать для любого типа массива
  4. не требует дополнительных распределений объектов (против метода 2) или двух массивов (против метода 1)

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

+0

это обратит данный массив c ?? – prime

+1

Хороший ответ, обратите внимание, однако, что в терминах «большой O» нет разницы между O (n/2) и O (n). Оба являются линейными в соответствии с n. – Maroun

Смежные вопросы