Оптимальный алгоритм поиск текста в массиве
- Войдите на сайт для отправки комментариев
Пнд, 27/07/2015 - 14:43
Доброго времени суток!
Подскажите начинающему оптимальный алгоритм поиск текста в массиве.
Например есть массив char sym[] = "alpha beta gamma delta"
необходимо определить в нем наличие слова gamma
как это можно реализовать в наилучшем виде?
Just Google it: https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D0%BE%D0%B4%D1%81%D1%82%D1%80%D0%BE%D0%BA%D0%B8
Единого наилучшего алгоритма нет и не может существовать в принципе.
Во-первых, два существенно различающихся варианта, когда входной массив отсортирован, и когда - нет.
Потом поиск можкт быть регистро-зависимый и независимый и т.п.
Опять же, если мы сравниваем алгоритмы практически одинаковой сложности, оазличающиеся только константами, важным оказывается, какую именно операцию мы используем для оценки сложности. Операция сравнения не всегда отражает реальную скорость работы алгоритмов.
Почитал по ссылке, понял что мне нет необходимости реализовывать весь алгоритм поиска.
Объясню что пытаюсь реализовать.
В массив попадают данные принимаемые GPRS модулем. Мне необходимо определить момент приема СМС сообщения. Все СМС начинаются с +CMT:
т.е. это можно реализовать просто:
if (sym[0] == "+") && (sym[1] == "C") && (sym[2] == "M") && (sym[3] == "T") && (sym[4] == ":") { Serial.print("SMS") }Смущает детский подход к реализации. Есть ли более красивое решение?
Как говорится: Если работает, не трож!
А вообще есть функция strcmp или strncmp, которая сравнивает две строки (или только первые n символов строк) и говорит, равны они или нет. В Вашем случае, как я понимаю, она должна вполне подойти.
Спасибо!
А чем не кошерна специально для этого предназначенная функция strstr?
Да, это хороший вариант, спасибо за совет!
rene, вы получаете данные из serial?
Хороший вариант обрабатывать их побайтно с помощью автомата, а не складировать во временную строку, imho
Да, наверное если бы я писал с нуля, я так бы и сделал, но поскольку я взял готовый пример и адаптировал его под себя, переписывать все с нуля нет желания. Но за имхо спасибо.
Здравствуйте!
Не могли бы выложить скетч полностью, тоже пытаюсь изучать этот вопрос.
/*-------------------------------------------------------------- ----------------------- ИНИЦИАЛИЗАЦИЯ -------------------------- --------------------------------------------------------------*/ #include <SoftwareSerial.h> // библиотека для работы с GPRS модулем SoftwareSerial GPRS(7, 8); // пины для работы с GPRS модулем (програмный серийный порт) char buffer[64]; // буфер для принятия данных с GPRS модуля int count = 0; // счетчик символов буфера /*-------------------------------------------------------------- -------------------- ПЕРВИЧНАЯ НАСТРОЙКА ----------------------- --------------------------------------------------------------*/ void setup() { GPRS.begin(19200); // скорость работы порта GPRS Serial.begin(9600); // скорость работы серийного порта _StartGPRS(); // Запуск устройства } /*-------------------------------------------------------------- ---------------------- ТЕЛО ПРОГРАММЫ -------------------------- --------------------------------------------------------------*/ void loop() { // Проверяем наличие входящих данных с GPRS модуля if (GPRS.available()) // if date is comming from softwareserial port ==> data is comming from gprs shield { _GPRSRead(); // Проверям не СМС ли это сообщение if ((buffer[2] == '+') && (buffer[3] == 'C') && (buffer[4] == 'M') && (buffer[5] == 'T') && (buffer[6] == ':')) { Serial.println("SMS"); } // Или входящий звонок else if ((buffer[2] == 'R') && (buffer[3] == 'I') && (buffer[4] == 'N') && (buffer[5] == 'G')) { Serial.println("RING"); } } if (Serial.available()) // если есть данные поступающие с ПК GPRS.write(Serial.read()); // отправляем их на GPRS модуль. Позволяет вводит вручную АТ команды } /*-------------------------------------------------------------- -------------------------- ФУНКЦИИ ----------------------------- --------------------------------------------------------------*/ // ------------- Функция инициализации GPRS модуля ------------- void _StartGPRS() { while (true) { _GPRSPower(); // функция для програмного включения GPRS модуля _AT("ATE0"); // отключаем эхо // Ждем ответа ОК if (_OK) { // Настраиваем приём сообщений с других устройств _AT("AT+CMGF=1\r"); _AT("AT+IFC=1, 1\r"); _AT("AT+CPBS=\"SM\"\r"); _AT("AT+CNMI=1,2,2,1,0\r"); break; } delay(5000); } } // ------------- Функция програмного включения GPRS модуля ------------- void _GPRSPower() { pinMode(9, OUTPUT); digitalWrite(9, LOW); delay(1000); digitalWrite(9, HIGH); delay(2000); digitalWrite(9, LOW); delay(3000); } // ------------- Функция отправки АТ комманд на GPRS модуль ------------- void _AT(char* at) { Serial.print("> "); Serial.println(at); GPRS.print(at); GPRS.print("\r"); delay(500); _GPRSRead(); } // ------------- Функция наличия ответа ОК с GPRS модуля ------------- boolean _OK() { if ((buffer[2] == 'O') && (buffer[3] == 'K')) return true; else return false; } // ------------- Функция чтения ответов с GPRS модуля ------------- void _GPRSRead() { count = 0; // set counter of while loop to zero while (GPRS.available()) // reading data into char array { buffer[count++] = GPRS.read(); // writing data into array if (count == 64) break; } Serial.println(buffer); // if no data transmission ends, write buffer to hardware serial port } // ------------- Функция отправки СМС ------------- void _SendTextMessage() { // Устанавливает текстовый режим для SMS-сообщений GPRS.print("AT+CMGF=1\r"); delay(100); // даём время на усваивание команды // Устанавливаем адресата: телефонный номер в международном формате GPRS.println("AT + CMGS = \"+79170000000\""); delay(100); // Пишем текст сообщения GPRS.println("ALARM!"); delay(100); // Отправляем Ctrl+Z, обозначая, что сообщение готово GPRS.println((char)26); }Спасибо!
Если не трудно, приведите пожалуйста како нибудь простой код обработки побайтно, с помощью автомата
!
Здравствуйте!
Не могли бы выложить скетч полностью, тоже пытаюсь изучать этот вопрос.
Вот окончательный вариант. Последняя функция _SendTextMessage() в программе не используется, оставил на случай необходимости отправки СМС.
/*-------------------------------------------------------------- ----------------------- ИНИЦИАЛИЗАЦИЯ -------------------------- --------------------------------------------------------------*/ #include <SoftwareSerial.h> // библиотека для работы с GPRS модулем SoftwareSerial GPRS(7, 8); // пины для работы с GPRS модулем (програмный серийный порт) char buffer[64]; // буфер для принятия данных с GPRS модуля int count = 0; // счетчик символов буфера unsigned long updateTime = 0; // счетчик времени обновления /*-------------------------------------------------------------- -------------------- ПЕРВИЧНАЯ НАСТРОЙКА ----------------------- --------------------------------------------------------------*/ void setup() { GPRS.begin(19200); // скорость работы порта GPRS Serial.begin(9600); // скорость работы серийного порта pinMode(13, OUTPUT); // пин для включения кнопки ДУ _StartGPRS(); // Запуск устройства } /*-------------------------------------------------------------- ---------------------- ТЕЛО ПРОГРАММЫ -------------------------- --------------------------------------------------------------*/ void loop() { // Проверяем наличие входящих данных с GPRS модуля if (GPRS.available()) { _GPRSRead(); // Проверям не СМС ли это сообщение if ((buffer[2] == '+') && (buffer[3] == 'C') && (buffer[4] == 'M') && (buffer[5] == 'T') && (buffer[6] == ':')) { Serial.println("SMS"); digitalWrite(13, HIGH); // включаем на секунду пин 13 delay(1000); digitalWrite(13, LOW); } // Или входящий звонок else if ((buffer[2] == 'R') && (buffer[3] == 'I') && (buffer[4] == 'N') && (buffer[5] == 'G')) { _AT("AT+CLCC"); // узнать номер звонящего _AT("AT+CHUP"); // отклонить вызов // _AT("ATH"); // повесить трубку digitalWrite(13, HIGH); // включаем на секунду пин 13 delay(1000); digitalWrite(13, LOW); } } // Переодическая проверка доступности GPRS модуля if (millis() >= updateTime) { _AT("AT"); if (!_OK()) _StartGPRS(); // если нет ответка ОК, перезагружаем устройство updateTime = millis() + 60000; // переодичность проверки } if (Serial.available()) // если есть данные поступающие с ПК GPRS.write(Serial.read()); // отправляем их на GPRS модуль. Позволяет вводит вручную АТ команды } /*-------------------------------------------------------------- -------------------------- ФУНКЦИИ ----------------------------- --------------------------------------------------------------*/ // ------------- Функция инициализации GPRS модуля ------------- void _StartGPRS() { while (true) { _GPRSPower(); // включение GPRS модуля _AT("ATE0"); // отключаем эхо _AT("AT"); // проверяем доступность GPRS модуля // Ждем ответа ОК if (_OK()) { // Настраиваем приём сообщений с других устройств _AT("AT+CMGF=1\r"); _AT("AT+IFC=1, 1\r"); _AT("AT+CPBS=\"SM\"\r"); _AT("AT+CNMI=1,2,2,1,0\r"); break; } delay(1000); } } // ------------- Функция програмного включения GPRS модуля ------------- void _GPRSPower() { Serial.println("> PressPowerKey\n"); pinMode(9, OUTPUT); digitalWrite(9, LOW); delay(1000); pinMode(9, INPUT); delay(3000); } // ------------- Функция отправки АТ комманд на GPRS модуль ------------- void _AT(char* at) { Serial.print("> "); Serial.println(at); GPRS.print(at); GPRS.print("\r"); delay(500); _GPRSRead(); } // ------------- Функция наличия ответа ОК с GPRS модуля ------------- boolean _OK() { if ((buffer[2] == 'O') && (buffer[3] == 'K')) return true; else return false; } // ------------- Функция чтения ответов с GPRS модуля ------------- void _GPRSRead() { count = 0; // обнуляем счетчик for (int i = 0; i < 64; i ++) // обнуляем буфер { buffer[i] = 0; } while (GPRS.available()) // запысываем все поступающие данные в буфер { buffer[count++] = GPRS.read(); if (count == 64) break; } Serial.println(buffer); } // ------------- Функция отправки СМС ------------- void _SendTextMessage() { // Устанавливает текстовый режим для SMS-сообщений GPRS.print("AT+CMGF=1\r"); delay(100); // даём время на усваивание команды // Устанавливаем адресата: телефонный номер в международном формате GPRS.println("AT + CMGS = \"+79172676866\""); delay(100); // Пишем текст сообщения GPRS.println("ALARM!"); delay(100); // Отправляем Ctrl+Z, обозначая, что сообщение готово GPRS.println((char)26); }