Cod sursa(job #281531)

Utilizator tomescu_alinTomescu Alin tomescu_alin Data 15 martie 2009 11:43:29
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 6.07 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;

typedef unsigned char byte;
typedef unsigned short ushort;
typedef unsigned int uint;
typedef unsigned long ulong;
typedef unsigned long long ulonglong;

template<class T>
class Sort {
	public:
		typedef std::vector<T> Vector;
		typedef void (*FuncPtr)(Vector& vect);
		typedef typename Vector::difference_type Index;
		typedef typename Vector::size_type Size;
		
	public:
		
		static void Merge(Vector& vect) {
			Sort::Helper::improvedMergeSort(vect, 0, vect.size());
		}
		
		static void Quick(Vector& vect) {
			
		}
		
		static void StlSort(Vector& vect) {
			sort(vect.begin(), vect.end());
		}
		
		static void Heap(Vector& vect) {
			
		}
		
		static void Intro(Vector& vect) {
			
		}
		
		static void Bubble(Vector& vect) {
			bool sorted;
			Size size = vect.size();
			
			do {
				sorted = true;
				for(Index i = 0; i < size-1; i++) {
					if(vect[i] > vect[i+1]) {
						swap(vect[i], vect[i+1]);
						sorted = false;
					}
				}
			} while(!sorted);
		}
		
		static void Select(Vector& vect) {
			Size size = vect.size();
			Index swapIndex;
			
			for(Index i = 0; i < size-1; i++) {
				swapIndex = i;
				
				for(Index j = i+1; j < size; j++) {
					if(vect[swapIndex] > vect[j]) {
						swapIndex = j;
					}
				}
				
				if(swapIndex != i) {
					swap(vect[i], vect[swapIndex]);
				}
			}
			
		}
		
		static void Insertion(Vector& vect) {		
			Size size = vect.size();
			
			for(Index i = 1; i < size; i++) {
				T data = vect[i];
				Index j = i-1;
				
				while(j >= 0 && vect[j] > data) {
					vect[j+1] = vect[j];
					j--;
				}
				
				vect[j+1] = data;
			}
		}
		
	public:
		class Helper {
			public:
				static void improvedMergeSort(Vector& vect, Index begin, Index end) {
					static Vector merged(vect.size());
					
					cout << "improvedMergeSort(begin: " << begin << ", end: " << end << ")" << endl;
					
					if(begin == end) {
						cout << "begin == end <=> " << begin << " == " << end << endl;
						return;
					} else {
						Index middle = (end+begin)/2;
						
						clog << "Left: ";
						copy(vect.begin()+begin, vect.begin()+middle, ostream_iterator<T>(clog, " "));
						clog << endl;
						
						clog << "Right: ";
						copy(vect.begin()+middle, vect.begin()+end, ostream_iterator<T>(clog, " "));
						clog << endl;
						
						//	Recurse
						improvedMergeSort(vect, begin, middle);
						improvedMergeSort(vect, middle, end);
						
						//	Merge the two sorted subvectors
						Size firstLength = middle-begin, secondLength = end-middle;	
						Index firstPos = begin, secondPos = middle;
						Index i = 0;
						
						while(firstPos < firstLength && secondPos < secondLength) {
							if (vect[firstPos] < vect[secondPos]) {
								merged[i++] = vect[firstPos++];
							} else {
								merged[i++] = vect[secondPos++];
							}
						}

						while (firstPos < firstLength) {
							merged[i++] = vect[firstPos++];
						}
						while (secondPos < secondLength) {
							merged[i++] = vect[secondPos++];
						}
						
						clog << "Merged: ";
						copy(merged.begin(), merged.begin()+i, ostream_iterator<T>(clog, " "));
						clog << endl;
						
						//	Copy the sorted subvector back into the vector
						for(int j = begin; j < end; j++)
							vect[j] = merged[j-begin];
							
						clog << "Full array: ";
						copy(vect.begin(), vect.end(), ostream_iterator<T>(clog, " "));
						clog << endl;
					}
				}
				
				static Vector mergeSort(const Vector& vect) {
					if(vect.size() <= 1) {
						return vect;
					} else {
						Size size = vect.size();
						Index middle = size/2;
						
						Vector 
							result(vect.size()),
							left(vect.begin(), vect.begin() + middle), 
							right(vect.begin() + middle, vect.end());
						
						// clog << "Left: ";
						// copy(left.begin(), left.end(), ostream_iterator<T>(clog, " "));
						// clog << endl;
						
						// clog << "Right: ";
						// copy(right.begin(), right.end(), ostream_iterator<T>(clog, " "));
						// clog << endl;
						
						left = mergeSort(left);
						right = mergeSort(right);
												
						result = merge(left, right);
						// clog << "Merged: ";
						// copy(result.begin(), result.end(), ostream_iterator<T>(clog, " "));
						// clog << endl;
						return result;
					}
				}
				
				static Vector merge (const Vector& first, const Vector& second) {
					Size firstLength = first.size(), secondLength = second.size();
					Vector merged(firstLength + secondLength);
					Index firstPos = 0, secondPos = 0;
					Index i = 0;
						
					while(firstPos < firstLength && secondPos < secondLength) {
						if (first[firstPos] < second[secondPos]) {
							merged[i++] = first[firstPos++];
						} else {
							merged[i++] = second[secondPos++];
						}
					}

					while (firstPos < firstLength) {
						merged[i++] = first[firstPos++];
					}
					while (secondPos < secondLength) {
						merged[i++] = second[secondPos++];
					}
							
					return merged;
				}
		};
};

int main(int argc, char * argv[]) {
	
	/*
		Open up the files...
	*/
	const char * inFile = "algsort.in";
	const char * outFile = "algsort.out";
	
	ifstream fin(inFile);
	ofstream fout(outFile);
	
	// if(!fin || !fout) {
		// cerr << "Error opening one of \"" << inFile << "\" or \"" << outFile << "\"" << endl;
		// return -1;
	// }
	
	/*
		Read in the number of elements in the vector
		And then read each element
	*/
	ulong n;
	fin >> n;
	std::vector<ulong> vect(n);
	
	for(ulong i = 0; i < n; i++) {
		fin >> vect[i];
	}
	
	/*
		Choose your sorting algorithm.
		Sort!
	*/
	Sort<ulong>::FuncPtr sorter = Sort<ulong>::StlSort;
	
	//clog << "Sorting...\n";
	sorter(vect);
	//clog << "Sorted!";
	
	//	Store the sorted vector in a file
	ostream& target = fout;	
	copy(vect.begin(), vect.end(), ostream_iterator<ulong>(target, " "));
	
	fout.close();
	fin.close();
	
	return 0;

}