Время в данном случае приемлимы вариант , т.к вызываться сортировка должна очень редко … ну по крайне мере по замыслу ![]()
Всегда приходится выбирать, или время, или память, согласись? Не только на Arduino.
да , в большинстве своем почти всегда
Попытался использовать просто двухмерный массив , но возникла проблема как передать указатели на строки в массиве
пытаюсь так
int *(MyStr)[30])
#include <EEPROM.h>
#include <stdlib.h>
#include <string.h>
#define MAS "int *(MyStr)[30])" //указатель на массив из 30 строк
char fd[20];
void setup() {
Serial.begin(19200);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
Serial.print("Read float from EEPROM: ");
WriteEEP(); //заполнить еепром для проверки
MySort(); // попытка отсортировать
}
void loop() {
/* Empty loop */
}
void MySort(void) {
int z, zz;
char MyStr[30][20]; // массив указателей на строки для сортировки
zz = 0;
for (z = 0; z < 8; z ++) {
EEPROM.get(z*20, fd);
Serial.println(fd); // строки считаные из еепром
// if (strlen(fd) != 0) { // если строка пустая игнорируем
MyStr[zz][z]=fd;
zz++;
// }
}
//int MyStrU= &MyStr[0][0];
int SiZe = sizeof(MAS)/ sizeof(char *);
qsort(MAS, SiZe, sizeof(char *), MyCmp);
for (z = 0; z < 8; z++) {
Serial.println(MyStr[z]);
}
}
int MyCmp(const void *p1, const void *p2)
{
const char *s1 = *(const char **)p1;
const char *s2 = *(const char **)p2;
return strcmp(s1, s2);
}
void WriteEEP(void) {
char mem[20];
const String ff = " ";
String f0 = "A.CURRENT";
String f5 = "Akai";
String f2 = "Costa";
String f3 = "India";
String f4 = "Traton";
String f1 = "Old";
ff.toCharArray(mem, 18); // очищенная строка
f0.toCharArray(mem, 18); //строка со значением определенной длины 20 символов
mem[19] = 0; // 20 символ - код строки от (0-150)
EEPROM.put(20, mem);
ff.toCharArray(mem, 18);
f1.toCharArray(mem, 18);
mem[19] = 5;
EEPROM.put(40, mem);
ff.toCharArray(mem, 18);
f2.toCharArray(mem, 18);
mem[19] = 2;
EEPROM.put(60, mem);
ff.toCharArray(mem, 18);
f3.toCharArray(mem, 18);
mem[19] = 4;
EEPROM.put(80, mem);
ff.toCharArray(mem, 18);
f4.toCharArray(mem, 18);
mem[19] = 3;
EEPROM.put(100, mem);
ff.toCharArray(mem, 18);
f5.toCharArray(mem, 18);
mem[19] = 1;
EEPROM.put(120, mem);
}
ничего не вшло … пытался передать указатель на первый элемент массива - тоже мусор на выходе…
ты по пояс деревянный, или весь?
Не, пока с указателями не разберешьса, я - пас.
Попытайтесь сами себе ответить на такой вопрос: если Вы, один хер, вычитываете свой массив в ОЗУ целиком, на кой йюх Вы его изначально в прогмем пихали? Ну пусть бы себе был в ОЗУ сразу, хоть не вычитывать.
В Верхнем коде была ошибка при заполнении массива строка 30
MyStr[zz][z]=fd;
надо
strcpy(MyStr[zz],fd);
теперь он заполняется правильно , но роли не играет т.к сним получается работать только как с символами ![]()
ну не в прогмем а веепром … Ответ прост - острая нехватка памяти!
если я храню в еепром то выводить на экран я могу прямо оттдуда, а для ссылок использовать индексы! В моем случае эти строки добавляются очень редко раз в месяц а может и раз в 3 месяца , поэтому занимать под них оперативку сильно расточительно. Функция сортировки вызывается только в момент добавления новой строки и только в самом начале работы , таким образом я иммею возможность вызвать функцию использовать массив локально для сортировки , а потом использовать тоже место для моих нужд , т.к оно будет свободно во время основной работы…
ах да … и суть то не в том где он хранится , а втом что я не могу с ним работать как раз в опперативки из за отсутсвий знаний… так что все равно надо разбираться…
так а что я сейчас и делаю
Ну как бы я выше и написал , что очень туго у меня с указателями, даже прочитав книжки о сайты все равно много написано непонятно … поэтому разобрался только частично . вот и пытаюсь разобраться, причем как сейчас оказалось один хрен двухмерный массив ,что масив из указателей… один хрен с указателями надо разбираться
эта запись пока остается для меня непонятной
Сортировка только для того, чтобы вставить строку в нужное место - слишком расточительная операция. И по времени и по памяти.
Достаточно единственного прохода и памяти под одну строку.
В общем , после читания книжек заполнить массив у меня получилось с помощью malloc и new char . Я так понял это одно и тоже … а вот с сортировкой проблемы.
первые 5 раз все сортировалась хорошо , все было идеально , но стоило мне попробовать увеличить кол-во строк для считывания до 20 , как на выходе сортировки стал появляться какой то бред , причем даже после того , что я все вернул как было , работа кода не восстановилось. код который до этого работал , теперь тоже выдает бред , сижу бьюсь пытаясь понять , что же все таки случилось и где я опять налажал…
EEPROM полностью очищал …
#include <EEPROM.h>
#include <stdlib.h>
#include <string.h>
void setup() {
Serial.begin(19200);
Serial.println("Read float from EEPROM: ");
WriteEEP(); //заполнить еепром для проверки
MySort(); // попытка отсортировать
}
void loop() {
/* Empty loop */
}
void MySort(void) {
int z, qq;
char fd[20];
char *MyStr[30];
for (z = 0; z < 7; z++) { // вот здесь изменил поставил до 20 и все поламалась :no_mouth: :woozy_face:
EEPROM.get(z * 20, fd);
Serial.println(fd);
//MyStr[z] = new char[20]; // выделили свободное место под строку
MyStr[z] = (char *) malloc(20); //таже хрень
strcpy(MyStr[z], fd);
}
Serial.println("-----------------------------");
qq = sizeof(MyStr) / sizeof(char *);
qsort(MyStr, qq, sizeof(char *), MyCmp); // если закоментировать эту строку
// то выходной текст такой-же, как и при
// выходе из еепрома
for (z = 0; z < 7; z++) {
Serial.println(MyStr[z]);
}
Serial.println("-----------------------------");
//for (int zzz=0;zzz<7;zzz++){ //запихать обратно в еепром
//EEPROM.put(zzz*20, fd);
//}
for (z = 0; z < 7; z++) { //очистить память что я выделил
free(MyStr[z]);
MyStr[z] = NULL;
}
Serial.println("-----------------------------");
Serial.println("-----------------------------");
Serial.println("-----------------------------");
//for (z = 0; z < 7; z ++) { // распечатать новыфй список в еепром
//EEPROM.get(z*20, fd);
// Serial.println(fd);
// }
}
int MyCmp(const void *p1, const void *p2) {
const char *s1 = *(const char **)p1;
const char *s2 = *(const char **)p2;
return strcmp(s1, s2);
}
void WriteEEP(void) {
char mem[20];
const String ff = " ";
String f0 = "A.CURRENT";
String f5 = "Akai";
String f2 = "Costa";
String f3 = "India";
String f4 = "Traton";
String f1 = "Old";
ff.toCharArray(mem, 20); // очищенная строка
EEPROM.put(0, mem);
ff.toCharArray(mem, 20); // очищенная строка
f0.toCharArray(mem, 20); //строка со значением определенной длины 20 символов
mem[19] = 0; // 20 символ - код строки от (0-150)
EEPROM.put(20, mem);
ff.toCharArray(mem, 20);
f1.toCharArray(mem, 20);
mem[19] = 5;
EEPROM.put(40, mem);
ff.toCharArray(mem, 20);
f2.toCharArray(mem, 20);
mem[19] = 2;
EEPROM.put(60, mem);
ff.toCharArray(mem, 20);
f3.toCharArray(mem, 20);
mem[19] = 4;
EEPROM.put(80, mem);
ff.toCharArray(mem, 20);
f4.toCharArray(mem, 20);
mem[19] = 3;
EEPROM.put(100, mem);
ff.toCharArray(mem, 20);
f5.toCharArray(mem, 20);
mem[19] = 1;
EEPROM.put(120, mem);
ff.toCharArray(mem, 20);
f5.toCharArray(mem, 20);
mem[19] = 1;
EEPROM.put(140, mem);
}
Согласен, но по другому не предумал как сделать . Список строк- это названия групп , которые оычно почти не меняются, но иногда нужно добавить новые . и при выводе на экран желательно , чтобы он были по алфавиту. Если сортировать перед выводом на экран в оперативке , то сжирается много памяти , если во время вывода очень тормозит дисплей … из всех зол выбрал меньшее…
Но суть не в этом , а втом , что у меня сортировка по сути пока нормально так и не получается независимо от того где я буду хранить список и как им пользоваться
А в каком процессоре всё это происходит? Может просто МК с большей памятью взять. Если на 5 строках работает…
Элементарно: один раз проходим по массиву в поисках места, куда нужно вставить строку (т.е. нужно найти строку, перед которой вставить новую). С этого места вычитываем символы в память на место новой строки, а саму строку запихиваем в EEPROM. И так продолжаем по типу кольцевого буфера пока не перепишем все, что было ранее записано в EEPROM. Для этого рационально использовать символ-терминатор массива строк в EEPROM. Как только его обнаружили, дописываем ровно одно “кольцо” из строки-буфера.
по сути таже сортировка… только не полностью а с места вставки новой строки, если учесть что это может быть 1,2,3 и т.д строчка то особо ничего не выйграю , а телодвижений больше. как я уже писал сортировка происходит после вставки новой строки , которую можно вставить лишь после включения аппарата в самом начале, и которую нужно вставлять очень очень редко … Таким образом время в данном случае некритично … по памяти -она выделяется на короткий момент, соответственно тоже можно не сильно упираться…
в предварительно сортированном списке один из самых быстрых методов, шейкерная совмещённая с методом половинного деления, я делил массив на 4 части
мега 2560 … можно конечно и взять например кортекс , а можно и малинку… только вот если после каждой проблемы переходить на что-то новое из-за того что не получается решить на более старым— ну незнаююю…К тому же пока что я не вижу , что не хватает ресурсов - а вот кривое программирование вижу . И пока не выпотрашу мегу до конца смысла не вижу переходить на что-то более дорогое… это первое . второе даже если я сейчас уду от проблемы написание данного кода с помощью мк с большой памятью , где гарантия, что мне он не понадобится всмысле данный код при решении другой задачи , (поэтому всетаки хотелосьбы разобраться до конца)
и еще у меня все подготовленно для меги , датчики плата дисплеи, соответственно даже если переходить на тот же кортекс все надо будет переделывать заново покупать новые дисплеи , датчики либо лепить кучу преобразователе- както не сильно хороший выход из положения…
Она не виновата ![]()
Читаем литературу, алгоритмов сортировки текстовых строк куча, на все случаи жизни.
Да все так !Вопрос не в том как сделать быстрее , а вопрос вообще как сделать…
не уверен , что шейкерная совмещённая с методом половинного деления будет в этом плане легче сделать чем по методу хоара… СТолкнусь скорее всего все с тем же
- указатели и работа с ними… а если так то какая разница на каком методе изучать…