Monthly Archives: Август 2014

Музыка для программирования

Музыка для программирования
|| Музыка для кодинга
|| Хакерская музыка
|| Программистский транс

  1. Blue_Stahli_-_Contre_Strike-CS-GO.mp3
  2. DJ-Velocity-Exposure.mp3
  3. dj_slyter_-_kazantip.mp3
  4. glide_-_extasy_(mf_remix).mp3
  5. KaZantip.mp3
  6. Na_igre_2_prodoljenie_-_Gamers.mp3
  7. nobody.one-Trapper.mp3
  8. Quake3track2.mp3
  9. Quake3track5.mp3
  10. RedAlertTrack9.mp3
  11. The_Prodigy_-_Youll_Be_Under_My_Wheels.mp3
  12. TheAlgorithm-Null.mp3
  13. Vibrasphere-ForestFuel.mp3
  14. StreetHacker Music — Traction 4 Heavy

Замена и удаление повторяющихся символов в строке

В данной статье будет рассмотрена замена и удаление повторяющихся символов в строке с помощью регулярных выражений Java.
Заменять и удалять повторяющиеся символы будет через функции замены класса String.
У класса String есть четыре метода для замены символов. Вот их сигнатуры:

  1. replace(char oldChar, char newChar):String
  2. replace(CharSequence target, CharSequence replacement):String
  3. replaceAll(String regex,String replacement):String
  4. replaceFirst(String regex,String replacement):String

Первые два метода в нашем случае не пригодятся, т.к. они нужны для замены одного символа (char) на другой символ или последовательности символов (CharSequence) на другую последовательность. CharSequence — это интерфейс, который реализуют классы: String, StringBuilder и StringBuffer.
Остановимся на двух последних методах: replaceAll и replaceFirst. Оба метода первым параметром принимают регулярное выражение (regex), а вторым параметром текст замены (replacement). replaceAll— заменяет все совпадения, а replaceFirst заменяет только первое совпадение. В данной статье будет использоваться только replaceAll.

  1. Представим себе следующую задачу: требуется удалить из строки все стоящие рядом два одинаковых символа. Например, из строки «keeshh» должна в итоге получиться строка «ks»
    String text = "keeshh";
    String result = text.replaceAll("([a-z])\\1", "");
    System.out.println(result);//"ks"

    replaceAll — функция для замены всех совпадений
    [a-z] — выражение говорит о том, что на этом месте должен быть символ в диапазоне от a до z.
    () — круглые скобки означают группировку, сослаться на которую можно по номеру, причем нумерация начинается с единицы
    \1 — указывает на то, что в этом месте должен быть такой же текст, как в группировке под номером 1. Обратный слэш «\» необходимо экранировать, поэтому в выражении два слэша «\\»

  2. После удаление двух повторных символов, могут снова образоваться повторные символы.
    Например, если в строке «keeshhs» заменить два подряд повторяющихся символа, то получится «kss», но подстроку «ss» также можно удалить. Поместим описанный выше код в цикл, который будет повторяться до тех пор, пока не будут заменены все повторные символы. В данной реализации будем пытаться удалять повторения, пока меняется (укорачивается) длина строки

    String text = "keeshhs";
    int len;		
    do{
    	len = text.length();//сохраняем длину строки
    	text = text.replaceAll("([a-z])\\1", "");
    }while(len != text.length());//сравниваем новую длину строки с сохраненной длиной
    System.out.println(text);//"k"
  3. Рассмотрим следующий пример. Нужно удалить все повторяющиеся подряд символы.
    Например, для строки «keeeshh» результат должен быть «ks». Реализация:

    String text = "keeeeshh";
    text = text.replaceAll("([a-z])\\1+", "");
    System.out.println(text);//"ks"
    

    Как вы, наверное, заметили после единички добавился символ +. Плюс в регулярных означает, что предшествующий плюсу символ или группировка должна встретиться от одного раза и более. Можно также включить этот код в цикл, чтобы снова заменить появившиеся повторения.

  4. Теперь рассмотрим замену. Задача: имеется строка, необходимо из двух подряд идущих одинаковых символов оставить только один.
    Пример: из строки «kkeesshh» получится строка «kesh».
    Реализация:

    String text = "kkeesshh";
    text = text.replaceAll("([a-z])\\1", "$1");
    System.out.println(text);//"kesh"

    Для замены мы использовали выражение $1, которое говорит о том, что текст, соответствующий регулярному выражению, необходимо заменить на текст, соответствующий группировке с номером 1. В нашем случае группировка с номером — это текст, соответствующий шаблону [a-z].
    Можно переписать код, используя группу с номером 2 для замены:

    String text = "kkeesshh";
    text = text.replaceAll("([a-z])(\\1)", "$2");
    System.out.println(text);//"kesh"

    Вторая группа соответствует шаблону \\1

  5. И напоследок заменим в строке все подряд повторяющиеся символы одним символом.
    Например, строка «keeeeessshh» преобразуется в «kesh».
    Реализация:

    String text = "keeeeessshh";
    text = text.replaceAll("([a-z])\\1+", "$1");
    System.out.println(text);//"kesh"

Использование регулярных выражений позволяет писать более компактный код и, возможно, сэкономить время на наборе кода, если хорошо освоить регулярные выражения.

org.apache.http.NoHttpResponseException: The target server failed to respond

Случилось так, что в двух моих Android-приложениях перестала работать статистика. Хотя приложения уже работали более года без обновлений, да и сервис статистики я не трогал.
Запустив одно из приложений под отладкой, обнаружил ошибку:

org.apache.http.NoHttpResponseException: The target server failed to respond

Потом локализовал ошибку. Вот фрагмент проблемного кода:

HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);//тайм-аут подключения
HttpConnectionParams.setSoTimeout(httpParams, 10000);//тайм-аут сокета
HttpClient httpClient = new DefaultHttpClient(httpParams);
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);//тут выбрасывается Exception

Попробовал переписать код так (без HTTP-параметров).:

HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);

Статистика в приложении начала работать. Т.е. дело оказалось в передаваемых параметрах. Мне кажется, провайдер хостинга что-то обновил, и теперь сервер перестал понимать передаваемые запросы.
Погуглив, нашел другой способ передачи параметров, способ — работает!

HttpClient httpClient = new DefaultHttpClient();
httpClient.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 5000);
httpClient.getParams().setParameter(HttpConnectionParams.SO_TIMEOUT, 10000);
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);

Как видно из приведенного выше кода:

  1. Нужно создать объект HttpClient, используя конструктор без параметров DefaultHttpClient()
  2. С помощью httpClient.getParams().setParameter(String name,Object value) установить необходимые параметры

Надеюсь, этот код прослужит долго!

Создание резервной копии директорий (WinRAR)

Иногда возникает необходимость в создании полной резервной копии какой-нибудь директории.
Можно, конечно, каждый раз вручную архивировать папку, присваивая название архиву и проставляя номер или дату резервной копии. Но это быстро надоедает. Предлагаю написать скрипт(bat), который будет автоматизировать эту работу.

Допустим, есть директория D:\Projects\ProjectX, для которой нужно сделать резервную копию, заархивировав WinRAR’ом. Название архива будет содержать, кроме названия, еще и дату создания. Для этого нужно выполнить следующие шаги:

  1. Создадим любым текстовым редактором файл с названием projectx.bat.
    Желательно создать специальную директорию для хранения подобных скриптов (Например, D:\Scripts\backups)

  2. Вставьте следующий код в файл
    cls
    set rar="C:\Program Files\WinRAR\Rar.exe"
    set source_dir="D:\Projects\ProjectX"
    set backup_dir="D:\Backup\ProjectX\projectx_"
    %rar% a -r -ep1 -agYYYY-MM-DD[HHMM] %backup_dir% %source_dir%

    cls — необязательная команда, которая очищает консоль

  3. Переменная rar хранит полный путь к утилите rar.exe
    Переменная source_dir хранит полный путь к директории, для которой создается резервная копия
    Переменная backup_dir содержит путь до директории, где хранятся резерный копии(D:\Backup\), поддиректории (ProjectX) и префикса названия файла архива (projectx_)
    Теперь рассмотрим параметры архивирования, которые мы передаем утилите rar.exe:
    a — команда, указывающая на добавление файлов в архив
    -ep1 — опция, которая позволяет исключить базовый путь из имен файлов, но сохраняет внутреннюю иерархию директории
    -agYYYY-MM-DD[HHMM] — генерирует название файла на основе текущей даты и времени
    Последние два параметра передаваемые утилите — это путь до архива (backup_dir) и архивируемая директория (source_dir).

Теперь рассмотрим все в картинках:
Директория для архивирования:
pic1

Запускаемый скрипт:
pic2

Директория с резервными копиями:
pic3

Содержимое архива:
pic4

Содержимое директории:
pic5

Почему лучше использовать абсолютные пути в скрипте?
Во-первых, это позволит хранить скрипты в одном месте, а резервные копии в другом.
Во-вторых, можно запускать скрипты из любого места, не заботясь о текущей директории.

Созданный нами скрипт можно запускать по мере необходимости или запускать планировщиком по расписанию. Если всё же решили использовать в скрипте относительные пути, то при создании задания в планировщике не забудьте указать рабочую директорию скрипта.