Сортировка двухмерного массива.

 

Есть массив связанных данных вида:

Текст1 13
Текст2 12
Текст3 11
Текст4 10
Текст5 9
Текст6 8
Текст7 7
Текст8 6
Текст9 5
Текст10 4
Текст11 3
Текст12 2
Текст13 1

 

Нужно сортировать столбец №2 (в котором только числа), но с условием сохранения связи ячеек между столбцами. Например "Текст1" и "13" после любой сортировки быть на одной строке. 

Первое, что пришло в голову - это соединить столбец №1 и столбец №2: было "Текст1" и "13", стало "13Текст1" и теперь можно уже сортировать, но потом нужно будет провести разделение снова на две ячейки. 

 

Я бы решил так: каждая строка представляет собой некий объект CObject, а вся таблица: CArrayObj. В своем классе наследнике CObject перегрузите метод Compare. Вот накидал полностью рабочую демонстрацию в виде скрипта:

//+------------------------------------------------------------------+
//|                                                   MultiArray.mq5 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#define EQUAL 0
#define LESS -1
#define MORE 1
#include <Object.mqh>
#include <Arrays\ArrayObj.mqh>

enum ENUM_SORT_TYPE
{
   SORT_BY_TEXT,
   SORT_BY_NUMBER
};

class CLineTable: public CObject
{
private:
   string m_text;
   int m_number;
public:
   CLineTable();
   CLineTable(string text, int number)
   {
      m_text = text;
      m_number = number;
   }
   string Text()const{return m_text;}
   int Number()const{return m_number;}
   virtual int Compare(const CObject *node,const int mode=0) const
   { 
      const CLineTable* line = node;
      switch (mode)
      {
         case SORT_BY_TEXT:
            if(line.Text() == this.Text())
               return EQUAL;
            else if(line.Text() < this.Text())
               return MORE;
            else
               return LESS;
         case SORT_BY_NUMBER:
            if(line.Number() == this.Number())
               return EQUAL;
            else if(line.Number() < this.Number())
               return MORE;
            else
               return LESS;
      }
      return EQUAL;
   }
};
CArrayObj Table;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
    //Добавляем в таблицу 13 строк CLineTable
    int limit = 13;
    Table.Sort(SORT_BY_TEXT);
    for(int i = 0; i < limit; i++)
    {
      string n = (string)(i+1);
      if(StringLen(n) < 2)n = "0"+n;
      string text = "Текст" + n;
      Table.InsertSort(new CLineTable(text, limit-i));
    }
    //Смотрим что получилось:
    for(int i = 0; i < Table.Total(); i++)
    {
      CLineTable* line = Table.At(i);
      printf(line.Text() + "\t" + (string)line.Number());
    }
    //Сортируем по второму фактору: номера
    Table.Sort(SORT_BY_NUMBER);
    //Смотрим что получилось:
    printf("");
    for(int i = 0; i < Table.Total(); i++)
    {
      CLineTable* line = Table.At(i);
      printf(line.Text() + "\t" + (string)line.Number());
    }
    Table.Clear();
  }
//+------------------------------------------------------------------+

 Смотрим вывод:

 
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст01 13
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст02 12
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст03 11
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст04 10
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст05 9
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст06 8
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст07 7
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст08 6
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст09 5
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст10 4
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст11 3
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст12 2
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст13 1
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст13 1
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст12 2
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст11 3
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст10 4
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст09 5
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст08 6
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст07 7
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст06 8
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст05 9
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст04 10
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст03 11
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст02 12
2015.03.21 18:41:34.832 MultiArray (USDCAD,M1)  Текст01 13
 

barabashkakvn: 

Самый простой способ сортировки - пузырьковый. Пример прикрепил

void  MapSort(double &D[],string &S[])
  {
   double d_tmp = 0.0;
   string s_tmp = "";

   for(int i=0; i<ArraySize(D); i++)
      for(int j=0; j<ArraySize(S)-i-1; j++)
         if(D[j]>D[j+1])
           {
            d_tmp = D[j];
            s_tmp = S[j];
            D[j] = D[j+1];
            S[j] = S[j+1];
            D[j+1] = d_tmp;
            S[j+1] = s_tmp;
           }

  }
Файлы:
Sort.mq5  2 kb
 
MigVRN:

Самый простой способ сортировки - пузырьковый. Пример прикрепил

Вопрос был не о способах сортировки. Не надо изобретать велосипед. Пользуйтесь готовыми алгоритмом сортировки CArray.mqh. Он оптимизирован и проверен на корректность, используется уже годами сотнями программистов.
 
barabashkakvn:

Есть массив связанных данных вида:

Как вы связали в двумерный массив строковые переменные и целочисленные? Или массивов таки 2 одномерных а строки связаны одинаковыми индексами? В этом разе строковый массив можно не сортировать, достаточно получить новую (отсортированную) последовательность индексов - 2й целочисленный массив
 
C-4:
Вопрос был не о способах сортировки. Не надо изобретать велосипед. Пользуйтесь готовыми алгоритмом сортировки CArray.mqh. Он оптимизирован и проверен на корректность, используется уже годами сотнями программистов.

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

Мой пример рабочий, максимально сжат и приведен для понимания работы алгоритма - Вы посмотрите в первом посте, что топикстартер делать хотел.

 
f2011:
Как вы связали в двумерный массив строковые переменные и целочисленные? Или массивов таки 2 одномерных а строки связаны одинаковыми индексами? В этом разе строковый массив можно не сортировать, достаточно получить новую (отсортированную) последовательность индексов - 2й целочисленный массив
:facepalm
 
MigVRN:

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

Мой пример рабочий, максимально сжат и приведен для понимания работы алгоритма - Вы посмотрите в первом посте, что топикстартер делать хотел.

Я смотрел. Этот способ сработает, но лучше так не делать. А если факторов сортировки будет не два, а двадцать два? Запутаетесь в StringConcatenate. Хотя дело каждого какие способы использовать. Но ООП все равно рулит:)
 
C-4:
Я смотрел. Этот способ сработает, но лучше так не делать. А если факторов сортировки будет не два, а двадцать два? Запутаетесь в StringConcatenate. Хотя дело каждого какие способы использовать. Но ООП все равно рулит:)
Спору нет :) Если делать таблицу - то Ваш вариант гораздо лучше.  Пускай топикстартер сам выбирает - где и как он будет это юзать известно только ему. 
 
f2011:
Как вы связали в двумерный массив строковые переменные и целочисленные? Или массивов таки 2 одномерных а строки связаны одинаковыми индексами? В этом разе строковый массив можно не сортировать, достаточно получить новую (отсортированную) последовательность индексов - 2й целочисленный массив

Схитрил, у меня прототип таблицы.


C-4:

Я бы решил так: каждая строка представляет собой некий объект CObject, а вся таблица: CArrayObj. В своем классе наследнике CObject перегрузите метод Compare. Вот накидал полностью рабочую демонстрацию в виде скрипта:

 Смотрим вывод:

Спасибо! Всё получилось так, как я хотел.
Причина обращения: