모름

이번에는 크로아티아 알파벳의 개수를 세는 문제를 풀어보겠습니다.

코드전문미리보기

...더보기
static void Main(string[] args)
{
    string input = Console.ReadLine();
    string[] croaAlphabets = new string[]
        { "c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z=" };
    Console.WriteLine(CountSomeWord(input, croaAlphabets));
}

static int CountSomeWord(string word, string[] someWords)
{
    int someWordCount = 0;
    int emptyCount = 0;


    for (int i = 0; i < word.Length; i++)
    {
        bool hasCounted = false;

        for (int j = 0; j < someWords.Length; j++)
        {
            if (IsThereSomeWord(word, i, someWords[j]))
            {
                someWordCount++;
                hasCounted = true;
                i += someWords[j].Length - 1;
                break;
            }
        }

        if (!hasCounted)
            emptyCount++;
    }

    return someWordCount + emptyCount;
}

private static bool IsThereSomeWord(string caseWord, int fromIndex, string someWord)
{
    bool canCheck = caseWord.Length - fromIndex >= someWord.Length;
    if (!canCheck)
        return false;

    for (int i = 0; i < someWord.Length; i++)
    {
        bool isSpellingSame = caseWord[fromIndex + i] == someWord[i];
        if (isSpellingSame) { }
        else
            return false;
    }

    return true;
}

 

 

 

목표

예전에는 운영체제에서 크로아티아 알파벳을 입력할 수 없었다. 그래서 아래와 같이 알파벳을 변형해서 입력했다.

 

예를 들어 ljes=njak 가 입력된다면, 이는 크로아티아 알파벳 6개 (lj, e, š, nj, a, k)로 이루어진 단어다. 단어가 주어졌을 때 크로아티아 알파벳 몇개가 사용됐는지 출력하면된다.

 

 

 

입력과 출력

 

입력

첫째 줄에 단어가 입력된다. 단어는 크로아티아 알파벳으로 이루어져 있고 알파벳은 위 표에 나와있는 변형된 형태로 입력된다

 

출력

주어진 단어에 크로아티아 알파벳이 몇 개 쓰였는지 출력한다

 

 

 

예제 입력과 출력

 

입력

ljes=njak

 

출력

6

 

 

 


 

풀이

 

1) 크로아티아 알파벳을 입력받는다.

2) 크로아티아 알파벳과 대응하여 비교한다.

3) 알파벳 카운트를 출력한다.

 

 

 

코드

 

1) 크로아티아 알파벳을 입력받는다.

string input = Console.ReadLine();

 

 

 

2) 크로아티아 알파벳과 대응하여 비교한다.

char[] word = input.ToCharArray();
int croaCount = 0;

for (int i = 0; i<word.Length; i++)
{
    if (word[i] == 'c')
    {
        if (word[i + 1] == '=')
        {
            croaCount++;
        }
        else if(word[i + 1] == '-')
        {
            croaCount++;
        }
    }
    else if (word[i] == 'd')
    {
        if (word[i + 1] == 'z' && word[i + 2] == '=')
        {
            croaCount++;
        }
        else if (word[i + 1] == '-')
        {
            croaCount++;
        }
    }
    else if (word[i] == 'l')
    {
        if (word[i + 1] == 'j')
        {
            croaCount++;
        }
    }
    else if (word[i] == 'n')
    {
        if (word[i + 1] == 'j')
        {
            croaCount++;
        }
    }
    else if (word[i] == 's')
    {
        if (word[i + 1] == '=')
        {
            croaCount++;
        }
    }
    else if (word[i] == 'z')
    {
        if (word[i + 1] == '=')
        {
            croaCount++;
        }
    }
}

Console.WriteLine(word.Length - croaCount);

입력받은 문자를 word[]: char에 담아줬습니다. 그리고 반복문을 통해 철자철자마다 if문에세 체크를 해준 뒤 사용된 크로아알파벳이 몇갠지 카운트합니다. 그리고 입력받은 단어의 길이에서 크로아 알파벳만큼을 빼게되면, 사용된 크로아 알파벳이 몇 갠지 확인 할 수 있습니다.

 

하지만 이대로 제출하면 너무 지저분한거 같습니다. 가독성도 너무 안좋습니다. 함수로 기능을 나눠 주겠습니다.

 

 

 


 

풀이(2)

 

먼저 필요한 기능은 두 가지입니다.

 

(1) 특정단어의 i번째부터 크로아알파벳(특정단어)가 있는지 여부를 확인해야합니다.

(2) 전체 단어를 돌면서 크로아 총 크로아알파벳이 몇개 있는지 체크합니다.

 

 

 

(1) 특정 단어 포함 여부 체크 함수

CheckSomeWord(): bool

private static bool CheckSomeWord(string caseWord, int from, string checkWord)
{
    int maxCheckCount = checkWord.Length;
    int trueCount = 0;

    if (caseWord.Length - from < checkWord.Length)
        return false;

    for (int i = 0; i < maxCheckCount; i++)
    {
        if (caseWord[from + i] == checkWord[i])
        {
            trueCount++;
        }
    }

    if (trueCount == maxCheckCount)
        return true;
    else
        return false;
}

멋진 기능을 가진 함수 CheckSomeWord(): bool 를 만들었습니다. 특정 문자열의 몇 번 인덱스에서부터 특정 단어가 존재하는지 체크해주는 녀석입니다. 수정할 부분이 조금 보이기 때문에 좀 더 보기 편하게 바꿔주겠습니다.

 

CheckSomeWord() -> IsThereSomeWord()

private static bool IsThereSomeWord(string caseWord, int fromIndex, string someWord)
{
    bool canCheck = caseWord.Length - fromIndex >= someWord.Length;
    if (!canCheck)
        return false;

    for (int i = 0; i < someWord.Length; i++)
    {
        bool isSpellingSame = caseWord[fromIndex + i] == someWord[i];
        if (isSpellingSame) { }
        else
            return false;
    }
    return true;
}

우선 함수명을 CheckSomeWord() -> IsThereSomeWord() 좀 더 직관적으로 바꿔줬고, 불필요한 부분들을 쳐내고 불값에 변수명을 지어줌으로써 가독성을 높였습니다.

 

 

 

(2) 특정 알파벳 카운트 함수

static int SomeAlphabetCount(string word)
{
    int count = 0;

    for (int i = 0; i < word.Length; i++)
    {
        if (CheckSomeWord(word, i, "c="))
            count++;
        else if (CheckSomeWord(word, i, "c-"))
            count++;
        else if (CheckSomeWord(word, i, "c="))
            count++;
        else if (CheckSomeWord(word, i, "dz="))
            count++;
        else if (CheckSomeWord(word, i, "d-"))
            count++;
        else if (CheckSomeWord(word, i, "lj"))
            count++;
        else if (CheckSomeWord(word, i, "nj"))
            count++;
        else if (CheckSomeWord(word, i, "s="))
            count++;
        else if (CheckSomeWord(word, i, "z="))
            count++;
    }

    return count;
}

처음 짰던 코드보다 훨씬 가독성이 좋아졌습니다. 그 외에도 체크할 알파벳이 더 생겨날 경우 쉽게 유지보수가 가능하다는 점에서 잘 짜여진것 같습니다. 하지만 여전히 반복된 코드가 많아보입니다. 조금 줄여줄 수 있을 것 같네요.

 

static int CountSomeWord(string word, string[] someWords)
{
    int someWordCount = 0;
    int emptyCount = 0;


    for (int i = 0; i < word.Length; i++)
    {
        bool hasCounted = false;

        for (int j = 0; j < someWords.Length; j++)
        {
            if (IsThereSomeWord(word, i, someWords[j]))
            {
                someWordCount++;
                hasCounted = true;
                i += someWords[j].Length - 1;
                break;
            }
        }

        if (!hasCounted)
        {
            emptyCount++;
        }
    }

    return someWordCount + emptyCount;
}

우선 애매한 함수명을 SomeAlphabetCount()에서 CountSomeWord()로 바꿔줬습니다.

 

그리고 검사할 특정 단어를 사용자가 쉽게 넣고 뺄수 있도록 인자로 받게 해줬습니다. 그리고 반복된 함수의 사용은 for문을 사용하여 훨씬 보기 좋게 만들어 줬습니다. 카운트가 됐으면 나머지 반복을 할 필요가 없으므로 break;로 빠져나오도록 조치했습니다.

 

또한 검사한 철자만큼 건너뛰어서 반복문을 수행하게 했고, 만약 찾는 단어가 없다면 기본 알파벳만 남은 상황임으로 기본 알파벳을 체크시켜줍니다.

 

 

 

(3)함수를 이용하여 총 알파벳 개수 출력

static void Main(string[] args)
{
    string input = Console.ReadLine();
    string[] croaAlphabets = new string[]
        { "c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z=" };
    Console.WriteLine(CountSomeWord(input, croaAlphabets));
}

마지막으로 필요한 크로아티아 알파벳을 입력하고, 카운트 함수를 이용하여 출력학만 하면 됩니다.

 

 

 

정상출력됩니다.

 

코드전문보기

...더보기
static void Main(string[] args)
{
    string input = Console.ReadLine();
    string[] croaAlphabets = new string[]
        { "c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z=" };
    Console.WriteLine(CountSomeWord(input, croaAlphabets));
}

static int CountSomeWord(string word, string[] someWords)
{
    int someWordCount = 0;
    int emptyCount = 0;


    for (int i = 0; i < word.Length; i++)
    {
        bool hasCounted = false;

        for (int j = 0; j < someWords.Length; j++)
        {
            if (IsThereSomeWord(word, i, someWords[j]))
            {
                someWordCount++;
                hasCounted = true;
                i += someWords[j].Length - 1;
                break;
            }
        }

        if (!hasCounted)
            emptyCount++;
    }

    return someWordCount + emptyCount;
}

private static bool IsThereSomeWord(string caseWord, int fromIndex, string someWord)
{
    bool canCheck = caseWord.Length - fromIndex >= someWord.Length;
    if (!canCheck)
        return false;

    for (int i = 0; i < someWord.Length; i++)
    {
        bool isSpellingSame = caseWord[fromIndex + i] == someWord[i];
        if (isSpellingSame) { }
        else
            return false;
    }

    return true;
}

 

 

다른 분의 짧은 코딩

...더보기
using System;
using static System.Console;

class MainApp
{
    static void Main(string[] args)
    {
        string s = ReadLine();
        string[] croatia = { "c=", "c-", "dz=", "d-", "lj", "nj", "s=", "z=" };

        for (int i = 0; i < 8; i++)
        {
            s = s.Replace(croatia[i], "a");
        }
        WriteLine(s.Length);
    }
}

 

전 정말.. 어렵게 푼거네요..