Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Запись чисел через тире или запятую


Автор: avatara 22.11.2007, 12:47
Подскажите пожалуйста как организовать запись чисел в строку, через тире или запятую

Например есть массив чисел:
1, 2, 3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 22, 23, 24, 25, 27, 29, 40, 41

В строку необходимо вывести:
1 - 4, 6, 7, 10 - 15, 22 - 25, 27, 29, 40, 41

Заранее благодарен, Алексей

Автор: LostSoul 22.11.2007, 13:16
itoa(Val,m_Buf,10) поможет преобразовать в строку, а потоместь уже у стринга  или сстринга есть оператор +=

Автор: Greeen 22.11.2007, 13:19
Код

int array[] = { 1, 2, 3, 4, 6, 7, 10, 11, 12, 13, 14, 15, 22, 23, 24, 25, 27, 29, 40, 41 };
std::ofstream file("c:\\1.txt");
file << array[0] << '-' << array[3] << ',' << array[5] << ... // и так далее
file.close();

Автор: avatara 22.11.2007, 14:16
Наверно я немного не так объяснил.  
Сами числа заранее неизвестны. 
и такой вариант:
Код

cout << array[0] << '-' << array[3] << ',' << array[5] << ... // и так далее

не пройдет.
Есть массив, который заполняется  любыми неповторяющимися числами.
Далее этот массив сортируется. 
И если, допустим, идут подряд числа "1,2,3,4",  то записываются как "1 - 4" (с 1 по 4)
те, которые на попадают в диапазон, записываются просто через запятую и так далее.

Еще один пример, на всякий случай
Есть EditBox1, EditBox2, ListBox, Button1, Button2
В EditBox1 вы вводите число и по нажатию Button1 число добавляется в ListBox 
и так много раз (числа все разные) 1, 2, 4, 3, 7, 6, 12, 14, 13, 10, 11, 15 и т.д. (и необязательно такие числа, могут быть совершенно другие в пределах unsigned int)
потом в ListBox числа сортируются и по нажатию Button2 в EditBox2 выводится уже запись следующего вида: 1 - 4, 6, 7, 10 - 15, 22 - 25, 27, 29, 40, 41

Вот и интересует, как осуществить проверку и подстановкутире и запятых там где это надо.
Спасибо.

Автор: ano360 22.11.2007, 14:40
Помоему все просто:
Берёшь первое число массива-вставляешь в строку,если след число равно пред+1 и не fl-вставляешь тире и fl =труе
еспи след число равн пред+1 и fl ничего не делаешь,

если число не равно пред + 1 и fl вставляешь пред число,запятую и число,fl=false
Если число неравно пред+1 и не fl тогд запятую и число

Автор: avatara 22.11.2007, 16:15
Проверьте пожалуйста:
Код

            m_str = " ";
    int kol;
    kol = m_list.GetCount();
    bool flag = FALSE;
    int prev, next;
    CString textprev, textnext, tempprev, tempnext;
    m_list.GetText(0, m_str);
    for (int i = 0; i < kol; i++)
    {
        m_list.GetText(i, textprev);
        m_list.GetText(i+1, textnext);
        prev = atoi(textprev);
        next = atoi(textnext);
        if (next == prev + 1 && flag == FALSE)
        {
            m_str = m_str + '-';
            flag = TRUE;
        } 
        else if (next == prev + 1 && flag == TRUE)
        {

        }
        else if (next != prev +1 && flag == TRUE)
        {
            tempprev.Format("%i", prev);
            tempnext.Format("%i", next);
            m_str = m_str + tempprev + ',' + tempnext;
            flag = FALSE;
        }
        else if (next != prev +1 && flag == FALSE)
        {
            tempnext.Format("%i", next);
            m_str = m_str + ',' + tempnext;
        }
        
    }

Программа вылетает с сообщением 
Debug  Assertion filed!
Programm: .......
File: ......../atlsimpstr.h
Line: 790


Expression nLength >= 0

Автор: ASSERT 23.11.2007, 16:20
avatara, это называется объединение - поиск:

Сортируем массив;
В цикле перебираем все элементы, пользуясь след формулой сравнения форматируем строку как нужно:

ЕСЛИ последующий член массива  равен предыдущий + 1 - объединяем его с предыдущим
( записываем в отдельный массив или другую структуру данных, назовем его ОБЪЕДИНЕНИЕ )
ИНАЧЕ 
 {
  выводим на экран первый и последний член ОБЪЕДИНЕНИЯ ( если он один, то, естественно, только    первый );
  очищаем объединение и продолжаем в том же духе далее
}

Если не получится реализовать - спрашивай, напишу в коде 

Автор: avatara 23.11.2007, 16:59
Хотелось бы реализацию кода, не могу понять.  
Тут еще одна проблема. Если в самом конце списка идут допустим ...... 22, 23, 24, 25, 26
То не будет ли  Ошибкой условие -  Следущее == Предыдущее +1 
ведь после числа 26 уже нет других чисел (конец массива)
Тогда в каких пределах производить цикл:
от 0_го_элемента или от 1_го_элемента
и до
 Кол_во_элементов -1 или Кол_во_элементов


Автор: ASSERT 23.11.2007, 18:51
Код


void main()
{  
  int array[] = { 1, 2, 3, 4, 5, 6, 7, 9, 10, 15, 21, 22, 23, 25, 27, 28, 29, 30, 31, 33, 35, 36, 37, 38 };
  int size = sizeof( array ) / sizeof( int ); // размер массива
  
  int first = array[0], last = array[0];

  char *buff = new char[ 10 ]; // сюда форматируем временную строку
  char *outstr = new char[size * 2];// буфер для конечной строки
  outstr[0] = '\0';

  for( int i = 1; i < size; ++i  )// главный цикл
  {
    if( array[i] == array[i - 1] + 1 )
    {
      last = array[i];
    }
    else
    {
      if( first != last )
        sprintf( buff, "%d - %d, ", first, last );
      else
        sprintf( buff, "%d, ", first );
      
      strcat( outstr, buff );

      first = array[i];
      last = array[i];
    }
  }
  printf( "%s\n", outstr );  
  delete[] buff;
  delete[] outstr;
  system( "pause" );
}



Обрати внимание, что главный цикл начинается с 1 , а не с 0.

От массива с ОБЪЕДИНЕНИЕМ ушел, ввел две переменные first и last - так будет лучше.

И вообще, может, кто-нибудь предложит лучше ;))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)