Проблемы с сортировкой

Время в данном случае приемлимы вариант , т.к вызываться сортировка должна очень редко … ну по крайне мере по замыслу :laughing:

Всегда приходится выбирать, или время, или память, согласись? Не только на 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);

теперь он заполняется правильно , но роли не играет т.к сним получается работать только как с символами :woozy_face:

ну не в прогмем а веепром … Ответ прост - острая нехватка памяти!
если я храню в еепром то выводить на экран я могу прямо оттдуда, а для ссылок использовать индексы! В моем случае эти строки добавляются очень редко раз в месяц а может и раз в 3 месяца , поэтому занимать под них оперативку сильно расточительно. Функция сортировки вызывается только в момент добавления новой строки и только в самом начале работы , таким образом я иммею возможность вызвать функцию использовать массив локально для сортировки , а потом использовать тоже место для моих нужд , т.к оно будет свободно во время основной работы…
ах да … и суть то не в том где он хранится , а втом что я не могу с ним работать как раз в опперативки из за отсутсвий знаний… так что все равно надо разбираться…

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

эта запись пока остается для меня непонятной

Сортировка только для того, чтобы вставить строку в нужное место - слишком расточительная операция. И по времени и по памяти.
Достаточно единственного прохода и памяти под одну строку.

В общем , после читания книжек заполнить массив у меня получилось с помощью 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 … можно конечно и взять например кортекс , а можно и малинку… только вот если после каждой проблемы переходить на что-то новое из-за того что не получается решить на более старым— ну незнаююю…К тому же пока что я не вижу , что не хватает ресурсов - а вот кривое программирование вижу . И пока не выпотрашу мегу до конца смысла не вижу переходить на что-то более дорогое… это первое . второе даже если я сейчас уду от проблемы написание данного кода с помощью мк с большой памятью , где гарантия, что мне он не понадобится всмысле данный код при решении другой задачи , (поэтому всетаки хотелосьбы разобраться до конца)
и еще у меня все подготовленно для меги , датчики плата дисплеи, соответственно даже если переходить на тот же кортекс все надо будет переделывать заново покупать новые дисплеи , датчики либо лепить кучу преобразователе- както не сильно хороший выход из положения…

Она не виновата :slight_smile:
Читаем литературу, алгоритмов сортировки текстовых строк куча, на все случаи жизни.

Да все так !Вопрос не в том как сделать быстрее , а вопрос вообще как сделать…
не уверен , что шейкерная совмещённая с методом половинного деления будет в этом плане легче сделать чем по методу хоара… СТолкнусь скорее всего все с тем же

  • указатели и работа с ними… а если так то какая разница на каком методе изучать…