#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
bool FileOpen(std::string& sFileName, std::ifstream& plik);
long int* CreateTab(const int& iTabSize);
void ReadDates(long int* TabWithDates, const int& iSize, int& iCountLookingNumbers, std::ifstream& plik);
void CheckDataCorrect(const int& iSize, const int& iCount);
void CheckLookingNumbersCountCorrect(const int& iCountLookingNumbers, const int& iSize);
long int LookNumberOfInstance(long int* TabWithDates, const long int& LookingValue, const int& iSize);
void WriteToFile(const std::string& sFileName, const int& iCountOccurance, const long int& LookingValue);
int main()
{
std::string sFileName;
std::ifstream plik;
int iSize, iCount, iCountLookingNumbers;
do
{
std::cin >> sFileName;
} while (!FileOpen(sFileName, plik));
plik >> iCount;
int j = 0;
while (j < iCount)
{
plik >> iSize;
CheckDataCorrect(iSize, iCount);
long int * lTabWithDates = CreateTab(iSize);
ReadDates(lTabWithDates, iSize, iCountLookingNumbers, plik);
int i = 0;
while (i < iCountLookingNumbers)
{
long int LookingValue;
int iCountOccurance;
plik >> LookingValue;
iCountOccurance = LookNumberOfInstance(lTabWithDates, LookingValue, iSize);
WriteToFile(sFileName, iCountOccurance, LookingValue);
++i;
}
delete[] lTabWithDates;
++j;
}
plik.close();
std::cin.get();
std::cin.get();
}
bool FileOpen(std::string& sFileName, std::ifstream & plik)
{
try
{
if (sFileName.find(".txt") != std::string::npos)
{
plik.open(sFileName.c_str());
}
else
{
sFileName += ".txt";
plik.open(sFileName.c_str());
}
if (!plik)
{
throw "Nie znaleziono pliku. Podaj jeszcze raz: ";
}
}
catch (char * cWhatWrong)
{
plik.clear();
std::cout << cWhatWrong;
return false;
}
return true;
}
long int* CreateTab(const int& iTabSize)
{
long int* lTabForDates;
try
{
lTabForDates = new long int[iTabSize];
return lTabForDates;
}
catch (std::bad_alloc & bad)
{
std::cout << "Wystapil problem z przydzialem pamieci. Program zostanie zakonczony.";
exit(EXIT_FAILURE);
}
}
void CheckDataCorrect(const int& iSize, const int& iCount)
{
if (iCount < 1 || iSize < 1 || iSize > 1000000)
{
std::cout << "Bledne dane w pliku. Aplikacja zostala zatrzymana !";
exit(EXIT_FAILURE);
}
}
void ReadDates(long int* lTabWithDates, const int& iSize, int& iCountLookingNumbers, std::ifstream & plik)
{
for (int i = 0; i < iSize; ++i)
{
plik >> lTabWithDates[i];
}
plik >> iCountLookingNumbers;
CheckLookingNumbersCountCorrect(iCountLookingNumbers, iSize);
}
void CheckLookingNumbersCountCorrect(const int& iCountLookingNumbers, const int& iSize)
{
if (iCountLookingNumbers < 1 || iCountLookingNumbers > iSize)
{
std::cout << "Bledne dane.";
exit(EXIT_FAILURE);
}
}
long int LookNumberOfInstance(long int* lTabWithDates, const long int& lLookingValue, const int& iSize)
{
int iTabCenter = (iSize - 1) / 2;
int ValueCount = 0;
int iPointer = iTabCenter;
int iFirst = 0;
int iLast = iSize - 1;
bool NotFind = false;
bool IfFind = false;
while (!NotFind && !IfFind)
{
if (lTabWithDates[iTabCenter] == lLookingValue)
{
iPointer = iTabCenter;
++ValueCount;
++iPointer;
while (lTabWithDates[iPointer] == lLookingValue && iPointer < iSize)
{
++ValueCount;
++iPointer;
}
iPointer = iTabCenter - 1;
while (lTabWithDates[iPointer] == lLookingValue)
{
++ValueCount;
--iPointer;
}
IfFind = true;
}
if (lTabWithDates[iTabCenter] < lLookingValue)
{
iFirst = iTabCenter;
iTabCenter = iLast - (iLast - iFirst) / 2;
}
else
if (lTabWithDates[iTabCenter] > lLookingValue)
{
iLast = iTabCenter;
iTabCenter = iFirst + (iLast - iFirst) / 2;
}
if (iLast == iFirst)
{
NotFind = true;
}
}
return ValueCount;
}
void WriteToFile(const std::string& sFileName, const int& iCountOccurance, const long int& LookingValue)
{
std::ofstream outFile;
outFile.open(sFileName, std::ios::app);
outFile << std::endl << LookingValue << " " << iCountOccurance;
outFile.close();
}