algorithm file fragmentation - andstudy/forge GitHub Wiki

CynicJJ

    Public Class FileFragments
    
    	Function GetOriginalFile(ByVal fragments As List(Of String)) As String
    		Dim frags As New List(Of String)(fragments)
    		frags.Sort(AddressOf CompareLength)
    
    		Dim candidate As List(Of String) = GetCombined(frags(0), frags)
    		RemoveDuplicated(candidate)
    		For i As Integer = 1 To frags.Count - 1
    			If candidate.Count = 1 Then Exit For
    
    			Dim combined As List(Of String) = GetCombined(frags(i), frags)
    			RemoveWrongCandidate(candidate, combined)
    		Next
    
    		Return candidate(0)
    	End Function
    
    	Private Sub RemoveDuplicated(ByVal candidate As List(Of String))
    		Dim i As Integer
    		While i < candidate.Count
    			Dim duplicated As Integer = candidate.IndexOf(candidate(i), i + 1)
    			If duplicated <> -1 Then
    				candidate.RemoveAt(i)
    			Else
    				i += 1
    			End If
    		End While
    	End Sub
    
    	Private Sub RemoveWrongCandidate(ByVal candidate As List(Of String), ByVal combined As List(Of String))
    		Dim i As Integer
    		While i < candidate.Count
    			If combined.IndexOf(candidate(i)) = -1 Then
    				candidate.RemoveAt(i)
    			Else
    				i += 1
    			End If
    		End While
    	End Sub
    
    	Private Function GetCombined(ByVal frag, ByVal frags) As List(Of String)
    		Dim originalLength As Integer = frags(0).Length + frags(frags.Count - 1).Length
    
    		Dim combined As New List(Of String)
    		For i As Integer = frags.Count - 1 To 0 Step -1
    			Dim compared As String = frags(i)
    			If compared.Length + frag.Length = originalLength Then
    				combined.Add(frag + compared)
    				combined.Add(compared + frag)
    			End If
    		Next
    		Return combined
    	End Function
    
    	Private Shared Function CompareLength(ByVal str1 As String, ByVal str2 As String) As Integer
    		If str1.Length > str2.Length Then
    			Return 1
    		ElseIf str1.Length < str2.Length Then
    			Return -1
    		Else
    			Return 0
    		End If
    	End Function
    
    End Class

Outbreak

๋ฌธ์ œ ์š”์•ฝ

  • ๋™์ผํ•œ ํŒŒ์ผ n ๊ฐœ๊ฐ€ ๋ชจ๋‘ ๋‹ค๋ฅธ ์œ„์น˜์—์„œ 2๊ฐœ์”ฉ ์ชผ๊ฐœ์ ธ 2n ๊ฐœ ๋๋‹ค.
  • ์ด ํŒŒ์ผ ์กฐ๊ฐ๋“ค์„ ์ด์šฉํ•ด ์›๋ณธ ํŒŒ์ผ ์•Œ์•„๋‚ด๊ธฐ!

๋ฌธ์ œ ํ•ด๊ฒฐ

  • ๋ฌด์กฐ๊ฑด ๋ฐ˜์œผ๋กœ ์ชผ๊ฐœ์ง€๋ฏ€๋กœ ์กฐ๊ฐ ๊ธธ์ด๋ฅผ ์‚ฌ์šฉ
  • ์กฐ๊ฐ์€ ํŒŒ์ผ์˜ ์•ž๋ถ€๋ถ„์ด๋‚˜ ๋’ท๋ถ€๋ถ„

์†Œ๊ฐ

  • ๋Œ€์ถฉ ์งœ๊ณ  ๊ทธ๋ƒฅ ๋Œ๋ ค ๋ดค๋Š”๋ฐ.. Solved.. ํ—ˆํ—ˆ..
  • Solved ๋์œผ๋ฏ€๋กœ.. ์ˆ˜์ •์€ ์—†์Šต๋‹ˆ๋‹ค. ใ…‹ใ…‹

ํ’€์ด

    // "File Fragmentation" Solution By Outbreak 
    
    #include <iostream>
    #include <map>
    #include <vector>
    #include <string>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    
    //#define _TDD
    
    // ํ•œ ํŒŒ์ผ์˜ ํฌ๊ธฐ ๊ตฌํ•  ์ˆ˜ ์žˆ์Œ.
    
    // ๊ฐ ์กฐ๊ฐ์€ ์•ž๋ถ€๋ถ„ ์•„๋‹ˆ๋ฉด ๋’ท๋ถ€๋ถ„!
    
    // ํด๋ž˜์Šค๋กœ ๋ฆฌํŒฉํ† ๋ง ํ•  ๊ฒƒ!
    namespace Solver
    {
    	static const int MAX_FRAGMENT = 144 * 2;
    
    	static vector<string> VFragment(MAX_FRAGMENT);
    
    	void MakeFragmentTable()
    	{
    		VFragment.clear();
    	}
    
    	void InsertFragment(const string& fragment)
    	{
    		VFragment.push_back(fragment);
    	}
    
    	int FindCompleteFileLength()
    	{
    		int sum = 0;
    		int n = (int)VFragment.size() / 2;
    
    		if(n==0)
    			return -1;
    
    		for( int i=0; i<(int)VFragment.size(); i++ )
    		{
    			sum += (int)VFragment[i].length();
    		}
    
    		return sum / n;
    	}
    
    	bool CheckCompleteFile(string front, string end)
    	{
    		string file = front + end;
    
    		// ๊ฒ€์ฆ
    
    		// ๋ชจ๋“  ์กฐ๊ฐ๋“ค์ด ๋งž์ถฐ์ง€๋Š”์ง€ ํ™•์ธํ•ด ๋ณธ๋‹ค.
    
    		int i;
    
    		// ์•ž, ๋’ค์—์„œ ์ฐพ์•„๋ด„.
    		for( i=0; i<(int)VFragment.size(); i++ )
    		{			
    			size_t pos = file.find(VFragment[i]);
    
    			// ์•ž
    			if( pos == 0 )
    				continue;
    
    			// ๋’ค
    			pos = file.rfind(VFragment[i]);
    			if( pos + VFragment[i].length() == file.length() )
    				continue;
    
    			return false;
    		}
    
    		return true;
    	}
    	
    	string Recovery()
    	{
    		string result = "01110111";
    		
    		// ํŒŒ์ผ์˜ ํฌ๊ธฐ๋ฅผ ์ฐพ๋Š”๋‹ค.
    		int length = FindCompleteFileLength();
    
    		if( length == -1 )
    			return "error";
    
    		const int remain = length - (int)VFragment[0].length();
    		
    		set<string> Set;
    		// ์ฒซ๋ฒˆ์งธ ์กฐ๊ฐ์„ ์•ž์ด๋ผ๊ณ  ๊ฐ€์ •
    		// ์ง์ด ๋  ์ˆ˜ ์žˆ๋Š” ๋…€์„๋“ค ์กฐ์‚ฌ. set ์—๋‹ค ๋„ฃ๋Š”๋‹ค.
    		for( int i=0; i<(int)VFragment.size(); i++ )
    		{
    			if( remain == (int)VFragment[i].length() )
    			{
    				Set.insert(VFragment[i]);
    			}
    		}
    
    		// ์•ž์ผ ๊ฒฝ์šฐ Set ์— ๋“  ๋…€์„๋“ค ํ•ฉํ•ด์„œ ๋ฌธ์žฅ ๋งŒ๋“ค๊ธฐ
    		for( set<string>::iterator it = Set.begin(); it != Set.end(); it++ )
    		{
    			if( CheckCompleteFile(VFragment[0],*it) )
    			{
    				result = VFragment[0] + *it;
    				return result;
    			}
    		}
    
    		// ๋’ค์ผ ๊ฒฝ์šฐ Set ์— ๋“  ๋…€์„๋“ค ํ•ฉํ•ด์„œ ๋ฌธ์žฅ ๋งŒ๋“ค๊ธฐ
    		for( set<string>::iterator it = Set.begin(); it != Set.end(); it++ )
    		{
    			if( CheckCompleteFile(*it, VFragment[0]) )
    			{
    				result = *it + VFragment[0];
    				return result;
    			}
    		}
    
    		return "none";		
    	}
    
    }
    
    namespace Runner
    {
    	void Execute(istream& in, ostream& out)
    	{
    		int sample = 0;
    
            in >> sample;
    
            while( sample-- )
            {                
    			// ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
    			Solver::MakeFragmentTable();
    
                while(true)
                {               
    				string fragment;
    				in >> fragment;
    
                    if( in.fail() )
    					break;
    
    				// ์กฐ๊ฐ ๋„ฃ๊ธฐ
    				Solver::InsertFragment(fragment);
    
    				in.get();
    
                    if( in.peek() == '\n')
                    {										
    					break;
                    }				
                }
    
    			// ์ฒ˜๋ฆฌ ํ•˜๊ธฐ
    			out << Solver::Recovery() << endl;
    		
                if( sample > 0 )
                {
    				out << endl;
                }
            }
    
    	}
    }
    
    
    #ifdef _TDD
    
    #include "unittest++.h"
    
    TEST(Output)
    {
    	stringstream input;
    	stringstream output;
    
    	input <<
    			"2\n\n"
    			"011\n"
    			"0111\n"
    			"01110\n"
    			"111\n"
    			"0111\n"
    			"10111\n"
    			"\n"
    			"011\n"
    			"0111\n"
    			"01110\n"
    			"111\n"
    			"0111\n"
    			"10111";
    			
    	Runner::Execute(input, output);
    
    	CHECK_EQUAL("01110111\n01110111",output.str());	
    }
    
    #endif
    
    int main()
    {
    
    #ifdef _TDD	
    	UnitTest::RunAllTests();
    #else
    	Runner::Execute(cin, cout);
    #endif // _TDD
    	return 0;
    
    }
โš ๏ธ **GitHub.com Fallback** โš ๏ธ