Cod sursa(job #2224208)

Utilizator paul_danutDandelion paul_danut Data 23 iulie 2018 14:18:05
Problema Radix Sort Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.5 kb
#include <fstream>
#include <vector>

std::ifstream f("radixsort.in");
std::ofstream g("radixsort.out");

class RadixSort {

public:
	RadixSort();
	std::vector<int> runAlgorithm(std::vector<int> input);

public:
	void initializeFrequence(std::vector<int>& frequence);
	void initializeIndex(std::vector<int>& frequence);
	int computeIndex(int val, int bucket);
	void computeFrequencies(std::vector<int>& input, std::vector<int>& frequence, int bucket);
	void computePositions(std::vector<int>& frequence, std::vector<int>& index);
	void moveElements(std::vector<int>& input, std::vector<int>& frequence, std::vector<int>& index, int bucket);
	bool isElementInBucket(int val, int bucket);

	void sort();

private:
	std::vector<int>			m_input;
	std::vector<int>			m_temp;
	std::vector<int>			m_index;
	std::vector<int>			m_frequence;
	std::vector<int>::iterator  m_it;
};

const int countsize = 256;
const int bucketsize = 8;
const int mask = (1 << bucketsize) - 1;

RadixSort::RadixSort()
{

}

void RadixSort::initializeIndex(std::vector<int>& index)
{
	index.assign(countsize, 0);
}

int RadixSort::computeIndex(int val, int bucket)
{
	return val >> (bucket * bucketsize) & mask;
}

std::vector<int> RadixSort::runAlgorithm(std::vector<int> input)
{
	m_input = input;
	sort();

	return m_input;
}

void RadixSort::computeFrequencies(std::vector<int>& input, std::vector<int>& frequence, int bucket)
{
	int c;
	for (m_it = input.begin(); m_it != input.end(); ++m_it)
	{
		c = computeIndex(*m_it, bucket);
		frequence[c]++;
	}
}

void RadixSort::computePositions(std::vector<int>& frequence, std::vector<int>& index)
{
	int i, count = frequence[0];

	for (i = 1; i < countsize; i++)
	{
		if (frequence[i])
		{
			index[i] = count;
			count += frequence[i];
		}
	}
}

// RadixSort::isElementInBucket(int val, int bucket)
//{
//	return val >= ((1 << (bucketsize * bucket)));
//}

void RadixSort::moveElements(std::vector<int>& input, std::vector<int>& frequence,  std::vector<int>& index, int bucket)
{
	std::vector<int> temp(input.size(), 0);

	int pos;
	//bool changed = false;
	for (m_it = input.begin(); m_it != input.end(); ++m_it)
	{
		//if ( isElementInBucket(*m_it, bucket) )
		//{
			//changed = true;
			pos = computeIndex(*m_it, bucket);
			frequence[pos] --;
			temp[index[pos]] = *m_it;
			index[pos]++;
		//}
	}

	//if (changed == true)
	//{
	input.assign(temp.begin(), temp.end());
	//}
}

void RadixSort::initializeFrequence(std::vector<int>& frequence)
{
	frequence.assign(countsize, 0);
}

void RadixSort::sort()
{

	for (int bucket = 0; bucket < 4; bucket++)
	{
		initializeFrequence(m_frequence);
		initializeIndex(m_index);
		computeFrequencies(m_input, m_frequence, bucket);
		computePositions(m_frequence, m_index);
		moveElements(m_input, m_frequence, m_index, bucket);
	}
}

std::vector<int> generateElements(int elements, int random1, int random2, int random3)
{
	std::vector<int> v(elements, 0);
	v[0] = random2;
	for (int i = 1; i < elements; i++)
	{
		v[i] = (random1 * v[i - 1] + random2) % random3;
	}

	return v;
}

void printValues(std::vector<int> result)
{
	std::vector<int>::iterator it;
	for (it = result.begin(); it != result.end(); it++)
	{
		g << *it << ' ';
	}
}

int main()
{
    unsigned int N;
	unsigned int A, B, C;

	f >> N >> A >> B >> C;

	RadixSort radixSort;
	std::vector<int> v(generateElements(N, A, B, C));
	v = radixSort.runAlgorithm(v);
    printValues(v);

	return 0;
}