Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.09.2013, 17:38   #1
Chainik!
Форумчанин
 
Регистрация: 10.11.2008
Сообщений: 120
По умолчанию Сортировка массива

Не могу решить легкую на слух задачу!

Дан массив, элементы которого равны либо единицы либо двойки. Написать программу, которая расставит элементы таким образом, чтобы за каждой единицой следовала двойка, причем если каких то елементов больше, то они выписываются в конец. Например, последовательность {2,1,1,1,2,1} должна преобразовываться в {1,2,1,2,1,1}.

Код:
#include "stdafx.h"
#include "iostream"
#include "conio.h"
#include "time.h"
using namespace std;
//----------------------------------------
void print(int arr[], int n)
{
	for(int i = 0; i < n; i++)
		cout << arr[i] << " ";
}
//----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
	const int n = 6;
	int arr[] = {2,1,1,1,2,1};
	cout << "Massiv imeet vid: ";
	print(arr,n);
	for(int i = 0; i < n; i++)
	{
		for(int j = n - 1; j >= 0; j--)
		{
			if(arr[i] > arr[j] && arr[i + 1], arr[j]) swap(arr[i],arr[j]);
		}
	}
	cout << "\n\n";
	print(arr,n);
	_getch();
	return 0;
}
помог - жми на весы
Chainik! вне форума Ответить с цитированием
Старый 08.09.2013, 18:33   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я бы в таком направлении двигался:
Код:
	const int n = 6;
	int arr[] = {2,1,1,1,2,1};
	cout << "Massiv imeet vid: ";
	print(arr,n);
        int uno=0,duo=0;for(int i=0;i<n;i++) if(arr[i]==1) uno++; else duo++;
        for(int i=0;i<n;i++){
         if(i<=uno) printf("%5f",uno);
         if(i<=duo) printf("%5f",duo);
        }
	_getch();
	return 0;
Р.S. Не проверял...
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.09.2013, 18:38   #3
Chainik!
Форумчанин
 
Регистрация: 10.11.2008
Сообщений: 120
По умолчанию

У меня былы такая мысль, полностью поддерживаю.
помог - жми на весы
Chainik! вне форума Ответить с цитированием
Старый 08.09.2013, 18:42   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,291
По умолчанию

Вроде работает (красивое решение не приходит в голову):
Код:
#include "stdafx.h"
#include "iostream"
#include "conio.h"
#include "time.h"
#include "algorithm"

using namespace std;
//----------------------------------------
void print(int arr[], int n)
{
	for(int i = 0; i < n; i++)
		cout << arr[i] << " ";
}
//----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
	const int n = 6;
	int arr[] = {2,1,1,1,2,1};
	cout << "Massiv imeet vid: ";
	print(arr, n);
	int t1 = 0, t2 = 0;
	for (int i = 0; i < n; ++i) {
		t1 += arr[i] == 1;
		t2 += arr[i] == 2;
	}
	for (int i = 0; i < 2 * min(t1, t2); i += 2) {
		arr[i] = 1;
		arr[i + 1] = 2;
	}
	for (int i = 2 * min(t1, t2), k = (t1 > t2) ? 1 : 2; i < n; ++i)
		arr[i] = k;
	cout << "\n\n";
	print(arr,n);
	_getch();
	return 0;
}
Более "веселый" вариант:
Код:
#include "stdafx.h"
#include "iostream"
#include "conio.h"
#include "time.h"
#include "algorithm"
using namespace std;
//----------------------------------------
void print(int arr[], int n)
{
	for(int i = 0; i < n; i++)
		cout << arr[i] << " ";
}
//----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
	const int n = 6;
	int arr[] = {2,1,1,1,2,1};
	cout << "Massiv imeet vid: ";
	print(arr, n);
	int fl = 1, j;
	for (int i = 0; i < n && fl; ++i) {
		if (arr[i] % 2 == i % 2) {
			for(j = i + 1; j < n && arr[i] == arr[j]; ++j);
			if (j < n)
				swap(arr[i], arr[j]);
			else
				fl = 0;
		}
	}
	cout << "\n\n";
	print(arr, n);
	_getch();
	return 0;
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 08.09.2013 в 19:36.
BDA вне форума Ответить с цитированием
Старый 09.09.2013, 22:35   #5
Chainik!
Форумчанин
 
Регистрация: 10.11.2008
Сообщений: 120
По умолчанию

BDA, спасибо
помог - жми на весы
Chainik! вне форума Ответить с цитированием
Старый 15.09.2013, 00:00   #6
Chainik!
Форумчанин
 
Регистрация: 10.11.2008
Сообщений: 120
По умолчанию

А, все понял.

Код:
#include "stdafx.h"
#include "iostream"
#include "conio.h"
#include "time.h"
using namespace std;
//----------------------------------------
void srand(int arr[], int n)
{
	srand(time(NULL));
	for(int i = 0; i < n; i++)
		arr[i] = rand() % 3;
}
//----------------------------------------
void print(int arr[], int n)
{
	for(int i = 0; i < n; i++)
		cout << arr[i] << " ";
}
//----------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
	const int n = 30;
	int arr[n], res[n], k = 0;
	srand(arr,n);
	for(int i = 0; i < n; i++)
	{
		if(arr[i] != 0)
			res[k++] = arr[i];
	}
	cout << "Massiv imeet vid: ";
	print(res,k);
	//-----------------------------------------
	for(int i = 0; i < k; i+=2)
	{
		for(int j = i + 1; j < k; j++)
		{
			if(res[i] != 1 && res[j] == 1)
				swap(res[i],res[j]);
		}
	}
	//-----------------------------------------
	for(int i = 1; i < k; i+=2)
	{
		for(int j = i + 1; j < k; j++)
		{
			if(res[i] != 2 && res[j] == 2)
				swap(res[i],res[j]);
		}
	}
	//-----------------------------------------
	cout << "\n\n";
	print(res,k);
	_getch();
	return 0;
}
помог - жми на весы
Chainik! вне форума Ответить с цитированием
Старый 15.09.2013, 06:34   #7
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

Ну да, тут все предложили сортировку подсчетом )
осталось заметить что это лучший вариант и выполняется за линейное время
rrrFer вне форума Ответить с цитированием
Старый 15.09.2013, 13:45   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

http://ideone.com/MYc0Ab

Код:
#include <algorithm>    // std::random_shuffle
#include <iostream>
using namespace std;
 
template<class T,size_t N> void view(const T (&ar)[N])
{
    cout<<"ar[]={";
    for(size_t n=0;n<N-1;++n) cout<<ar[n]<<",";
    cout<<ar[N-1]<<"}\n";
}
 
template<class T,size_t N> void mysort(T (&ar)[N])
{
    bool needOne=true;
    for(size_t n=0;n<N;++n)
    {
        const bool isOne = ar[n]==1;
        const bool isIgnore = (needOne && isOne) || (!needOne && !isOne);
 
        //--- отладочный вывод в консоль
        if(n<10)   cout<< ((isIgnore)? "ignr "    : "proc "   );
        if(n>10)   cout<< ((isIgnore)? "ignr  "   : "proc  "  );
        if(n>100)  cout<< ((isIgnore)? "ignr   "  : "proc   " );
        if(n>1000) cout<< ((isIgnore)? "ignr    " : "proc    ");
        cout<<" :       "<<std::string(2*n,' ')<<"*"<<endl;
        cout<<"n = "<<n<<" : "; view(ar); 
 
        needOne = !needOne;
 
        if(isIgnore) continue;
 
        T* it = std::find(ar+n,ar+N,  (isOne? 2: 1)  );
        if(it==ar+N) break;
        std::swap(ar[n], *it);
    }
}
 
 
 
template<class T,size_t N> void test_sort(T (&ar)[N])
{
    std::random_shuffle ( ar, ar+N );
    mysort(ar);
}
 
template<class T> bool check_array(const T (&ar)[15])
{
    int re[]={1,2,1,2,1,2,1,2,1,2,1,2,2,2,2};
    cout<<"expected: \n"; view(re);
 
    size_t n=0;
    while( n<15 && re[n]==ar[n]) ++n;
    return n==15;
}
 
 
 
 
int main() 
{
	cout<<"WELLCOME TO TESTING MY ALGORITHM\n\n";
 
 
    bool all_valid=true;
    for(size_t n=0;n<10;++n) 
    {
        int ar[]={2,1,1,1,2,1,2,2,1,1,2,2,2,2,2};
 
        view(ar);
        test_sort(ar);
        cout<<"actual: \n"; view(ar);
 
        const bool is_valid = check_array(ar);
 
        if(is_valid) cout<<"success!!!!\n";
        else
        {
            cout<< "failed";
            all_valid = false;
        }
    }
 
    cout<< (all_valid? "all testing are valid": "part tests are failed" )<<endl;
	return 0;
}
_Bers вне форума Ответить с цитированием
Старый 15.09.2013, 14:30   #9
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Вот другая версия, ещё более быстрого алгоритма:

http://ideone.com/MYc0Ab

#include <set>
#include <algorithm> // std::random_shuffle
#include <iostream>
using namespace std;

Код:
template<class T,size_t N> void view(const T (&ar)[N])
{
    cout<<"ar[]={";
    for(size_t n=0;n<N-1;++n) cout<<ar[n]<<",";
    cout<<ar[N-1]<<"}\n";
}

template<class T,size_t N> void mysort(T (&ar)[N])
{
    typedef multiset<T> Myset;
    typedef typename Myset::iterator It;

    Myset myset(ar,ar+N);

    //отладочный вывод:
    //It it = myset.begin(); size_t n=0;
    //while(it!=myset.end()){ cout<< n<<" : "<< *it<<endl;  ++it;++n; }
    //--------------------------------------------

    const size_t num_one = myset.count(1);
    const size_t num_two = myset.count(2);
    const int tail_el = (num_two>num_one)? 2: 1;

    const size_t lenbody = min(num_two,num_one);
    const size_t lentail = max(num_two,num_one)-lenbody;

	//отладочный вывод:
    //cout<<"number of 1 : "<<num_one<<endl;
    //cout<<"number of 2 : "<<num_two<<endl;
    //cout<<"tail        : "<<lentail<<endl;
    //cout<<"tail_element: "<<tail_el<<endl;
    //cout<<"body        : "<<lenbody<<endl;
    //--------------------------------------------

    const size_t size = lenbody*2;
    for(size_t n=0;n<size;n+=2) { ar[n]=1; ar[n+1]=2; }
    for(size_t n=size;n< N; ++n) ar[n]=tail_el;
}



template<class T,size_t N> void test_sort(T (&ar)[N])
{
    std::random_shuffle ( ar, ar+N );
    mysort(ar);
}

template<class T> bool check_array(const T (&ar)[15])
{
    int re[]={1,2,1,2,1,2,1,2,1,2,1,2,2,2,2};
    cout<<"expected: \n"; view(re);

    size_t n=0;
    while( n<15 && re[n]==ar[n]) ++n;
    return n==15;
}




int main() 
{
	cout<<"WELLCOME TO TESTING MY ALGORITHM\n\n";
	    

    bool all_valid=true;
    for(size_t n=0;n<10;++n) 
    {
        int ar[]={2,1,1,1,2,1,2,2,1,1,2,2,2,2,2};

        view(ar);
        test_sort(ar);
        cout<<"actual: \n"; view(ar);

        const bool is_valid = check_array(ar);

        if(is_valid) cout<<"success!!!!\n";
        else
        {
            cout<< "failed";
            all_valid = false;
        }
    }

    cout<< (all_valid? "all testing are valid": "part tests are failed" )<<endl;
	return 0;
}
Примичание:

Здесь мы теряем всю скорость из-за:

1. Пересоздание массива в виде дерева multiset. Для этого производится обход по всему оригинальному массиву. Это колоссальная потеря времени.

2. При моздании дерева multiset задействуется стандартный аллокатор динамической памяти. Единократное использование которого проссаживает рантайм сильнее, чем вся остальная процедура сортировки вместе взятая.

Таким образом, не смотря на то, что сам по себе алгоритм более быстр, он даст профит к скорости только если изначально в качестве контейнера будет использован multiset, а не сишный массив.

И если стандартный аллокатор будет заменен на какой нибудь пул памяти, который не будет дергать кучу.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Быстрая сортировка(сортировка Хоара). Сортировка фрагмента массива [C++] druger Помощь студентам 0 20.04.2012 15:49
сортировка массива feras Общие вопросы Delphi 6 23.05.2011 09:56
Сортировка массива методами предсортировки и слияния, и пирамидальная сортировка. lenny_24 Помощь студентам 2 17.04.2011 18:57
Сортировка массива Paladast Помощь студентам 2 18.01.2010 16:28
Сортировка массива Paul_AG Общие вопросы C/C++ 16 05.06.2009 21:42