Посмотр рубрик

Строки и массивы

Строки #

StringUtils #

Больше алгоритмов (unicode decode, urlencode, urldecode, base64...) смотри у меня в библиотеке StringUtils.

Разделение по символу #

Вариант 1 #

class StrSplit {
   public:
    StrSplit(const char* str) : p(str) {}

    bool split(char div) {
        if (!*p) return false;
        s = s ? ++p : p;
        while (*p && *p != div) ++p;
        return true;
    }
    size_t len() const {
        return p - s;
    }
    const char* str() const {
        return s;
    }

   private:
    const char* p;
    const char* s = nullptr;
};
const char* topic = ";hello;;test;123foo";
StrSplit sp(topic);

while (sp.split(';')) {
    Serial.write(sp.str(), sp.len());
    Serial.println();
}

Вариант 2 #

struct StrSplit2 {
    StrSplit2(const char* str) : str(str) {}

    bool split(char div) {
        if (len >= 0) str += len;
        if (!*str) return false;

        if (len >= 0) ++str;
        const char* p = str;
        while (*p && *p != div) ++p;
        len = p - str;
        // len = 0;
        // while (str[len] && str[len] != div) ++len;
        return true;
    }

    const char* str;
    int len = -1;
};
const char* topic = ";hello;;test;123foo";
StrSplit2 sp(topic);

while (sp.split(';')) {
    Serial.write(sp.str, sp.len);
    Serial.println();
}

Вариант 3 #

void splitStr(const char* str, char div, void (*cb)(const char* chunk, size_t len)) {
    while (true) {
        const char* p = str;
        while (*p && *p != div) ++p;
        cb(str, p - str);
        if (!*p) break;
        str = p + 1;
    }
}
const char* topic = ";hello;;test;123foo";

splitStr(topic, ';', [](const char* chunk, size_t len) {
    Serial.write(chunk, len);
    Serial.println();
});

Изменить раскладку (RU в QWERTY) - String #

const char _qwerty_ru[] PROGMEM = "F<DULT:PBQRKVYJGHCNEA{WXIO}SM\">Zf,dult;pbqrkvyjghcnea[wxio]sm'.z~`";

String ru_to_qw(const String& ru) {
  String qw;
  uint8_t prev = 0;
  for (int i = 0; i < ru.length(); i++) {
    uint8_t cur = ru[i];
    if (cur > 127) {
      uint8_t thiscur = cur;
      if (cur > 191) cur = 0;
      else if (prev == 209 && cur == 145) cur = 193;   // ё
      else if (prev == 208 && cur == 129) cur = 192;   // Ё
      prev = thiscur;
    }
    if (!cur) continue;

    if (cur <= 127) {
      qw += (char)cur;
      continue;
    }
    else if (cur <= 143) cur -= 80;
    else if (cur <= 191) cur -= 144;
    else cur -= 128;
    qw += (char)pgm_read_byte(&_qwerty_ru[cur]);
  }
  return qw;
}
Serial.println(ru_to_qw("123abcПривет")); // 123abcGhbdtn

Изменить раскладку (RU в QWERTY) - char* #

const char _qwerty_ru[] PROGMEM = "F<DULT:PBQRKVYJGHCNEA{WXIO}SM\">Zf,dult;pbqrkvyjghcnea[wxio]sm'.z~`";

uint16_t ru_to_qw(const char* ru, char* qw) {
  uint16_t len = strlen(ru);
  uint16_t idx = 0;
  uint8_t prev = 0;
  for (int i = 0; i < len; i++) {
    uint8_t cur = ru[i];
    if (cur > 127) {
      uint8_t thiscur = cur;
      if (cur > 191) cur = 0;
      else if (prev == 209 && cur == 145) cur = 193;   // ё
      else if (prev == 208 && cur == 129) cur = 192;   // Ё
      prev = thiscur;
    }
    if (!cur) continue;

    if (cur <= 127) {
      qw[idx++] = (char)cur;
      continue;
    }
    else if (cur <= 143) cur -= 80;
    else if (cur <= 191) cur -= 144;
    else cur -= 128;
    qw[idx++] = (char)pgm_read_byte(&_qwerty_ru[cur]);
  }
  qw[idx] = 0;
  return idx;
}
char* ru = "Привет";
char qw[strlen(ru)];
ru_to_qw(ru, qw);

Serial.println(qw);  // Ghbdtn

Длина строки с кириллицей #

int strlen_ru(const char* data) {
  int i = 0;
  int count = 0;
  while (data[i]) {
    if ((data[i] & 0xc0) != 0x80) count++;
    i++;
  }
  return count;
}
strlen_ru("Привет");    // 6

Encode unicode #

String u_encode(uint32_t c) {
  char b1 = 0, b2 = 0, b3 = 0, b4 = 0;
  if (c < 0x80) {
    b1 = c & 0x7F | 0x00;
  } else if (c < 0x0800) {
    b1 = c >> 6 & 0x1F | 0xC0;
    b2 = c >> 0 & 0x3F | 0x80;
  } else if (c < 0x010000) {
    b1 = c >> 12 & 0x0F | 0xE0;
    b2 = c >> 6 & 0x3F | 0x80;
    b3 = c >> 0 & 0x3F | 0x80;
  } else if (c < 0x110000) {
    b1 = c >> 18 & 0x07 | 0xF0;
    b2 = c >> 12 & 0x3F | 0x80;
    b3 = c >> 6 & 0x3F | 0x80;
    b4 = c >> 0 & 0x3F | 0x80;
  }
  String s;
  s.reserve(4);
  s += b1;
  s += b2;
  s += b3;
  s += b4;
  return s;
}
Serial.println(u_encode(0x2605));  // ★

wchar_t строка в String #

wchar_t str[] = {'П', 'р', 'и', 'в', 'е', 'т'};
  char* p = (char*)str;
  for (int i = 0; i < sizeof(str); i += 2) {
  Serial.print(p[i + 1]);
  Serial.print(p[i]);
}

Массивы #

Переворот #

for (int i = 0; i < len / 2; i++) {
    int t = arr[i];
    arr[i] = arr[len - i - 1];
    arr[len - i - 1] = t;
}

Перемешивание Fisher-Yates #

void shuffleArr(int* arr, size_t size) {
    int i = size / sizeof(int);
    while (i--) {
        int idx = rand() % (i + 1);
        int t = arr[i];
        arr[i] = arr[idx];
        arr[idx] = t;
    }
}

Сравнение элементов (диагональный цикл) #

// len - размер массива
for (int i = 0; i < len - 1; i++) {
  for (int j = i + 1; j < len; j++) {
    // сравниваем [i] и [j]
  }
}

Рекурсивная сортировка #

Быстрый алгоритм сортировки, но потребляет много оперативной памяти для вызова (рекурсия):

void quickSort(int arr[], int low, int high) {
  if (low < high) {
    int pivot = arr[high];
    int idx = low;
    for (int i = low; i <= high; i++) {
      if (arr[i] <= pivot) {
        int buf = arr[idx];
        arr[idx] = arr[i];
        arr[i] = buf;
        idx++;
      }
    }
    idx--;
    quickSort(arr, low, idx - 1);
    quickSort(arr, idx + 1, high);
  }
}
int arr[] = {53, 2, 654, 32, 34, 6843, 84, 358};
quickSort(arr, 0, sizeof(arr)/sizeof(arr[0]) - 1);
// quickSort(массив, 0, длина - 1)

Полезные страницы #

Подписаться
Уведомить о
guest

2 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх