algorithm wheres waldort - andstudy/forge GitHub Wiki
- toupper ์๋ฌ ์ฐธ๊ณ ๋ด์ฉ
- ํ๋ ๋
- Presentation ์๋ฌ๋ฉ๋๋ค.
-
๋ ํ ์คํธ ์ผ์ด์ค ์ฌ์ด์์๋ง ๊ฐํํด์ผ ํฉ๋๋ค. ๋ง์ง๋ง ํ ์คํธ ์ผ์ด์ค ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํํ ๊ฐํ์ด ์์ผ๋ฉด PE๊ฐ ๋ฉ๋๋ค. /* @JUDGE_ID:parkpd 10038 C "test" */
/* @BEGIN_OF_SOURCE_CODE */ #include <iostream> #include <vector> #include <set> #include <string> #include <strstream> #include <algorithm> using namespace std; bool IsInRange(int value, int from, int to) { return (from <= value) && (value <= to); } //#define _UNIT_TEST #ifdef _UNIT_TEST #include "../UnitTest++/src/UnitTest++.h" int main() { UnitTest::RunAllTests(); char temp; cin >> temp; return 0; } #endif // code implement class CWordGrid { public: static bool ConsoleTest(istream& input, ostream& output); CWordGrid() : m_Row(0), m_Col(0) {} void Init(int row, int col); void InputData(int row, string data); bool FindString(string str, int& row, int& col); bool Find(const string& str, int row, int col); bool IsSame(int row, int col, char c); int m_Row; int m_Col; char m_Data[51][51]; // }; void CWordGrid::Init(int row, int col) { m_Row = row; m_Col = col; } void CWordGrid::InputData(int row, string data) { // ์ ๋ถ ๋๋ฌธ์๋ก ๋ฐ๊พผ๋ค. transform( data.begin(), data.end(), data.begin(), //toupper); // gcc ์์ ์ด๊ฑฐ ์๋ฌ๋จ. -.-;; (int(*)(int)) toupper); //strcpy_s(m_Data[row], data.c_str()); strcpy(m_Data[row], data.c_str()); } bool CWordGrid::FindString(string str, int& row, int& col) { transform( str.begin(), str.end(), str.begin(), //toupper); (int(*)(int)) toupper); for (int r = 0; r < m_Row; ++r) { for (int c = 0; c < m_Col; ++c) { if (Find(str, r, c)) { row = r; col = c; return true; } } } return false; } namespace { // <- ๋ถํฐ ์๊ณ๋ฐฉํฅ์ผ๋ก ์ด๋ const int Directions[8][2] = { {-1, 0}, // <- {-1, -1}, { 0, -1}, // ์๋ก { 1, 1}, { 1, 0}, // -> { 1, 1}, { 0, 1}, // ์๋๋ก {-1, 1} }; } bool CWordGrid::Find(const string& str, int row, int col) { if (m_Data[row][col] != str[0]) { return false; } const int length = (int)str.length(); // 8 ๋ฐฉํฅ์ผ๋ก ํ ์คํธํ๊ธฐ for (int i = 0; i < 8; ++i) { bool found = true; int r = row; int c = col; for (int j = 1; j < length; ++j) { r += Directions[i][0]; c += Directions[i][1]; if (!IsSame(r, c, str[j])) { found = false; break; } } if (found) { return true; } } return false; } bool CWordGrid::IsSame(int row, int col, char c) { if (!IsInRange(row, 0, m_Row - 1) || !IsInRange(col, 0, m_Col - 1)) { return false; } return c == m_Data[row][col]; } bool CWordGrid::ConsoleTest(istream& input, ostream& output) { int num = 0; if (!(input >> num)) { return false; } // ์ฐ์ฐ์ ์ฐ์ ์์ ์ฃผ์ if (num <= 0) { return false; } string inputString; int row; int col; for (int i = 0; i < num; ++i) { CWordGrid grid; input >> row >> col; grid.Init(row, col); getline(input, inputString); for (int r = 0; r < row; ++r) { getline(input, inputString); grid.InputData(r, inputString); } int inputNum = 0; input >> inputNum; getline(input, inputString); int rowOut = 0; int colOut = 0; for (int i = 0; i < inputNum; ++i) { getline(input, inputString); grid.FindString(inputString, rowOut, colOut); output << rowOut + 1 << ' ' << colOut + 1 << '\n'; } output << '\n'; } return true; } #ifndef _UNIT_TEST int main() { CWordGrid::ConsoleTest(cin, cout); return 0; } #else // tests struct FixtureWordGrid : public CWordGrid { int row; int col; stringstream testCin; stringstream testCout; }; TEST_FIXTURE(FixtureWordGrid, InputData) { string data1 = "123"; string data2 = "567"; InputData(0, data1); InputData(1, data2); InputData(1, data1); } TEST_FIXTURE(FixtureWordGrid, FindString) { CHECK(!FindString("hi", row, col)); } struct FixtureSetupWordGrid : public FixtureWordGrid { FixtureSetupWordGrid() { Init(2, 2); InputData(0, "hi"); InputData(1, "ab"); } }; TEST_FIXTURE(FixtureSetupWordGrid, IsSame) { CHECK(IsSame(0, 0, 'H')); CHECK(IsSame(0, 1, 'I')); CHECK(!IsSame(1, 0, 'H')); CHECK(!IsSame(1, 1, 'H')); // ๋ฒ์๋ฅผ ๋ฒ์ด๋๋ ๋ ์๋ค๋ false ์์ผ์ค์ผ ํ๋ค. CHECK(!IsSame(-1, -1, 'H')); CHECK(!IsSame(5, 3, 'H')); } TEST_FIXTURE(FixtureSetupWordGrid, FindString) { CHECK(Find("HI", 0, 0)); } TEST_FIXTURE(FixtureWordGrid, ConsoleTest) { string input = "1\n\n" "8 11\n" "abcDEFGhigg\n" "hEbkWalDork\n" "FtyAwaldORm\n" "FtsimrLqsrc\n" "byoArBeDeyv\n" "Klcbqwikomk\n" "strEBGadhrb\n" "yUiqlxcnBjf\n" "4\n" "Waldorf\n" "Bambi\n" "Betty\n" "Dagbert"; testCin << input; CWordGrid::ConsoleTest(testCin, testCout); CHECK_EQUAL("2 5\n2 3\n1 2\n7 8\n", testCout.str()); }; #endif /* @END_OF_SOURCE_CODE */
-
-
Runtime Error๋๋ค์ฉ ใ ๋ฐ๋ชจ
-
Searcher.java
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; public class Searcher { private char [][] crossSource; public Searcher(String[] sourceLine,int height,int width) { initCrossSrouce(sourceLine,height,width); } private void initCrossSrouce(String[] sourceLines,int height,int width) { crossSource = new char[height][width]; for(int i=0;i<sourceLines.length;i++){ String curLine = sourceLines[i]; for(int j=0;j<curLine.length();j++){ crossSource[i][j] = curLine.charAt(j); } } } public boolean isStartWith(String source, String match) { source = source.toLowerCase(); match = match.toLowerCase(); return source.startsWith(match); } public String devideTop(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=y;i>=0;i--){ builder.append(crossSource[i][x]); } return builder.toString().toLowerCase(); } public int getWidth(){ if(crossSource.length < 1){ return 0; } return crossSource[0].length; } public int getHeight(){ return crossSource.length; } public String devideDown(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=y;i<getHeight();i++){ builder.append(crossSource[i][x]); } return builder.toString().toLowerCase(); } public String devideLeft(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=x;i>=0;i--){ builder.append(crossSource[y][i]); } return builder.toString().toLowerCase(); } public String devideRight(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=x;i<getWidth();i++){ builder.append(crossSource[y][i]); } return builder.toString().toLowerCase(); } public String devideUpLeft(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=y,j=x;i>=0 && j>=0;i--,j--){ builder.append(crossSource[i][j]); } return builder.toString().toLowerCase(); } public String devideUpRight(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=y,j=x;i>=0 && j<getWidth();i--,j++){ builder.append(crossSource[i][j]); } return builder.toString().toLowerCase(); } public String devideDownLeft(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=y,j=x;i<getHeight() && j>=0;i++,j--){ builder.append(crossSource[i][j]); } return builder.toString().toLowerCase(); } public String devideDownRight(int y, int x) { StringBuilder builder = new StringBuilder(); for(int i=y,j=x;i<getHeight() && j<getWidth();i++,j++){ builder.append(crossSource[i][j]); } return builder.toString().toLowerCase(); } public Point searchString(String match) { for(int i=0;i<getWidth();i++){ for(int j=0; j<getHeight();j++){ if(isStartWith(devideTop(i, j), match) || isStartWith(devideDown(i, j), match) || isStartWith(devideLeft(i, j), match) || isStartWith(devideRight(i, j), match) || isStartWith(devideUpLeft(i, j), match) || isStartWith(devideUpRight(i, j), match) || isStartWith(devideDownLeft(i, j), match) || isStartWith(devideDownRight(i, j), match) ){ return new Point(i+1,j+1); } } } return null; } public static void main(String[] args) throws NumberFormatException, IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); int cases = Integer.parseInt(reader.readLine().trim()); ArrayList<String> results = new ArrayList<String>(); for(int i=0;i<cases;i++){ reader.readLine(); String line = reader.readLine(); String[] split = line.split(" "); int height = Integer.parseInt(split[0]); int width = Integer.parseInt(split[1]); String [] lines = new String[height]; for(int j=0;j<height;j++){ lines[j] = reader.readLine(); } int numToFind = Integer.parseInt(reader.readLine().trim()); Searcher searcher = new Searcher(lines,height,width); for(int j=0;j<numToFind;j++){ Point result = searcher.searchString(reader.readLine().trim()); results.add(result.toString()); } results.add(""); } for(String line : results){ System.out.println(line); } } } -
Point.java
public class Point { @Override public boolean equals(Object obj) { if (obj instanceof Point) { Point pnt = (Point) obj; return this.x == pnt.getX() && this.y == pnt.getY(); }else{ return false; } } private int x; private int y; public Point(int y , int x){ this.x = x; this.y = y; } public String toString(){ return y+" "+x; } public int getX() { return x; } public int getY() { return y; } } -
TestCase
import junit.framework.TestCase; public class SearcherTest extends TestCase { Searcher searcher ; private String [] crossSource = { "abcDEFGhigg", "hEbkWalDork", "FtyAwaldORm", "FtsimrLqsrc", "byoArBeDeyv", "Klcbqwikomk", "strEBGadhrb", "yUiqlxcnBjf" }; @Override protected void setUp() throws Exception { searcher = new Searcher(crossSource,8,11); super.setUp(); } public void testLineMatch(){ String source = "abcdefg"; assertTrue(searcher.isStartWith(source,"abcdef")); assertTrue(searcher.isStartWith(source,"Abcdef")); assertFalse(searcher.isStartWith(source,"bcdefg")); assertFalse(searcher.isStartWith(source,"Bcdefg")); } public void testDevideTop(){ assertEquals("akd", searcher.devideTop(2,3)); assertEquals("a", searcher.devideTop(0,0)); assertEquals("cmkg", searcher.devideTop(3,10)); } public void testDevideDown(){ assertEquals("ahffbksy", searcher.devideDown(0,0)); assertEquals("bl", searcher.devideDown(6,4)); } public void testDevideLeft(){ assertEquals("eh", searcher.devideLeft(1,1)); assertEquals("erts", searcher.devideLeft(6,3)); } public void testDevideRight(){ assertEquals("ldork", searcher.devideRight(1, 6)); assertEquals("jf", searcher.devideRight(7, 9)); } public void testDevideUpLeft(){ assertEquals("ea", searcher.devideUpLeft(1,1)); assertEquals("th", searcher.devideUpLeft(2,1)); } public void testDevideUpRight(){ assertEquals("di", searcher.devideUpRight(1,7)); assertEquals("srk", searcher.devideUpRight(3,8)); } public void testDevideDownLeft(){ assertEquals("ef", searcher.devideDownLeft(1,1)); assertEquals("btf", searcher.devideDownLeft(1,2)); } public void testDevideDownRight(){ assertEquals("irm", searcher.devideDownRight(0,8)); } public void testSearchString(){ assertEquals(new Point(2,5), searcher.searchString("Waldorf")); assertEquals(new Point(2, 3), searcher.searchString("Bambi")); assertEquals(new Point(1, 2), searcher.searchString("Betty")); assertEquals(new Point(7, 8), searcher.searchString("Dagbert")); } }
- mxn ๊ทธ๋ฆฌ๋์์ ๋ฐฉํฅ์ ์๊ด์์ด ์ฃผ์ด์ง ๋ฌธ์์ด์ด ๋งค์นญ๋๋ ์ฒซ ์์น ์ฐพ๊ธฐ
- ์ ์ฒด ๊ทธ๋ฆฌ๋์ ๋ํด์ 8๋ฐฉํฅ ๋ฌธ์์ด ๋ฉํ ๋ฐ์ดํฐ ์์ฑ
- ๋ฉํ ๋ฐ์ดํฐ = ํน์ ๋ฐฉํฅ ๋ฌธ์์ด + ๊ฐ ๊ธ์์ ์์น์ ๋ณด
- ๋๊ฐ์ ์ ๊ฒฝ์ฐ ์ง์ ์ ๋ฐฉ์ ์ ์ด์ฉํด ๋ฌธ์์ด ์์ฑ
- ์์ฃผ ์ฝ๋ฉ ใฑใฑ
class MetaData
{
public class Dim
{
public int col;
public int row;
public Dim(int row, int col)
{
this.col = col;
this.row = row;
}
}
public string data;
public List<Dim> dimList;
public string Reverse
{
get
{
char[] array = data.ToCharArray();
Array.Reverse(array);
return new string(array);
}
}
public List<Dim> ReverseDimList
{
get
{
List<MetaData.Dim> rDim = new List<MetaData.Dim>(dimList);
rDim.Reverse();
return rDim;
}
}
public MetaData(string str, List<Dim> dim)
{
this.data = str;
this.dimList = dim;
}
}
class MetaDataProcessor
{
public List<MetaData> All = new List<MetaData>();
public MetaDataProcessor(char[][] input)
{
int rowCnt = input.Length;
int colCnt = input[0].GetLength(0);
// rows
for (int i = 0; i < rowCnt; i++)
{
string s = string.Empty;
List<MetaData.Dim> dim = new List<MetaData.Dim>();
for (int j = 0; j < colCnt; j++)
{
s += input[i][j];
dim.Add(new MetaData.Dim(i,j));
}
All.Add(new MetaData(s,dim));
}
// cols
for (int i = 0; i < colCnt; i++)
{
string s = string.Empty;
List<MetaData.Dim> dim = new List<MetaData.Dim>();
for (int j = 0; j < rowCnt; j++)
{
s += input[j][i];
dim.Add(new MetaData.Dim(j, i));
}
All.Add(new MetaData(s, dim));
}
// diagonal
int X = colCnt;
int Y = rowCnt;
int minD = 0;
int maxD = 0;
// diagonal #1
minD = -colCnt;
maxD = rowCnt;
for (int d = minD; d < maxD; d++)
{
string s = string.Empty;
List<MetaData.Dim> dim = new List<MetaData.Dim>();
for (int x = 0; x < X; x++)
{
int y = x + d;
if (y >= Y || y < 0)
continue;
s += input[y][x];
dim.Add(new MetaData.Dim(y, x));
}
All.Add(new MetaData(s, dim));
}
// diagonal #2
minD = 0;
maxD = X + Y;
for (int d = minD; d < maxD; d++)
{
string s = string.Empty;
List<MetaData.Dim> dim = new List<MetaData.Dim>();
for (int x = 0; x < X; x++)
{
int y = -x + d;
if (y >= Y || y < 0)
continue;
s += input[y][x];
dim.Add(new MetaData.Dim(y, x));
}
All.Add(new MetaData(s, dim));
}
// reverse
List<MetaData> rAll = new List<MetaData>();
foreach (MetaData d in All)
{
rAll.Add(new MetaData(d.Reverse, d.ReverseDimList));
}
All.AddRange(rAll);
Console.WriteLine("์ด ๋ฉํ ๋ฐ์ดํฐ ๊ฐ์ : {0}", All.Count);
}
}
class Solver
{
public static void Exec()
{
Input input = new Input();
MetaDataProcessor processor = new MetaDataProcessor(input.RefinedData);
foreach(string question in input.RawData2)
{
foreach (MetaData d in processor.All)
{
int result = d.data.ToLower().IndexOf(question.ToLower());
if (result == -1)
continue;
Console.WriteLine("{0}\t: {1} {2}",
question, d.dimList[result].row + 1, d.dimList[result].col + 1);
}
}
}
}
class Program
{
static void Main(string[] args)
{
Solver.Exec();
}
}