C++ 알고리즘 기초20 -문자열 심화1(마지막 문자 인덱싱, length()함수 overflow 문제, to_string()함수, 문자열의 끝)-

1. 문자열에서 마지막 문자 인덱싱

 

알파벳으로 이루어진 10개의 문자열과 문자가 하나 주어지면 그 문자로 끝나는 문자열들을 입력에서 주어진 순서대로 출력하는 프로그램을 작성해보세요.

 

string arr[10];으로 string 타입을 원소로 가지는 크기 10의 배열을 선언할 수 있다.

 

파이썬과 비슷하게 문자열 인덱싱이 가능하지만, 파이썬처럼 s[-1]로 마지막 문자를 가져올 수는 없다..

 

음수 인덱스를 사용하지 못한다는 소리

 

s.length()로 문자열 s의 길이를 가져오고, s.length()-1로 바로 마지막 문자에 접근할 수 있다.

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string arr[10];

    for(int i = 0; i < 10; i++){
        cin >> arr[i];
    }

    char c;
    cin >> c;

    bool exist = false;

    for(int i = 0; i< 10; i++){
        if (arr[i][arr[i].length()-1] == c){
            cout << arr[i] << endl;
            exist = true;
        }
    }

    if(exist == false){
        cout << "None";
    }
    return 0;
}

 

2. 문자열의 끝

 

기본적으로 문자열의 끝은 안보이지만 '\0'으로 끝난다.

 

문자열의 길이를 모르더라도 문자열을 순회하고 싶다면, '\0'을 만나면 중단하도록 for문을 작성하면 된다

 

#include <iostream>
#include <string>
using namespace std;

int main() {

	string arr;
	cin >> arr;

	for (int i = 0; arr[i] != '\0'; i++) {
		cout << arr[i] << endl;
	}

	return 0;

}
>> app
a
p
p

 

3. .length() 함수의 return값

 

다음은 문자열과 정수 n을 입력받아, 맨 뒤에서부터 n개만큼 출력하고자 하는 코드

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string s;
    cin >> s;

    int n;
    cin >> n;

    for(int i = s.length()-1; i >= s.length()-n; i--){
        cout << s[i];
    }
    return 0;
}

 

근데 이러면 s = b이고 n = 63이면 아무것도 출력이 안된다

 

왜 그런지 확인해봤더니 s.length() - n이 이상한 값이 나온다

 

cout << s.length() - n;

18446744073709551554

 

왜 이럴까 생각해보면 overflow밖에 없는데, n이 63이고 s.length()가 1인데 int범위를 벗어날리 없는데.. 왜 overflow지?

 

해서 찾아보니..

 

c++의 string.length()의 return값이 unsigned int값이기 때문에.. 음수를 가질수가 없다..

 

C++ string.length() Strange Behavior - Stack Overflow

 

C++ string.length() Strange Behavior

I just came across an extremely strange problem. The function I have is simply: int strStr(string haystack, string needle) { for(int i=0; i<=(haystack.length()-needle.length()); i++){ ...

stackoverflow.com

 

그래서 원하는대로 동작시키고 싶으면 int x라는 변수를 선언해서.. s.length() - n의 결과가 int 변수에 저장시켜야한다

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string s;
    cin >> s;

    int n;
    cin >> n;

    int x = s.length() - n;

    for(int i = s.length()-1; i >= x; i--){

        if (i == -1){
            break;
        }

        cout << s[i];
    }
    return 0;
}

 

4. to_string()과 concat연산자

 

문자열 A가 주어졌을 때 문자열 A에 Run-Length Encoding을 적용한 이후의 결과를 구해보려고 합니다. Run-Length Encoding이란 간단한 비손실 압축 방식으로, 연속해서 나온 문자와 연속해서 나온 개수로 나타내는 방식입니다.

예를 들어, 문자열 A가 aaabbbbcbb인 경우 순서대로 a가 3번, b가 4번, c가 1번 그리고 b가 2번 나왔으므로 Run-Length Encoding을 적용하게 되면 a3b4c1b2가 됩니다.

문자열 A가 주어졌을 때, Run-Length Encoding을 적용한 이후의 결과를 출력하는 프로그램을 작성해보세요.

 

아무 잡기술이 없을때 순수 코딩...

 

첫 글자 s[0]를 잡고, 문자열 s를 순회하면서 s[0]랑 같다면 count를 1 증가시켜가고

 

s[0]랑 다르다면, 새로운 문자 s[i]로 교체한다음 count 1로 초기화해준다

 

여기서 encoding한 전체 길이를 구해야하므로, count가 몇자리 숫자인지 구해줘야한다..

 

그것은 10으로 나눠서 몫이랑 나머지를 반복적으로 구한 다음에 (나머지는 필요없네 생각해보니까..)

 

몇번 나눴는지 세면 그것이 count의 자리수

 

for문을 전부 끝나고 나서도 count 몇번했는지 추가해줘야하는거 잊지 말아야한다

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string arr1[1001];
    int arr2[1001];

    string s;
    cin >> s;

    int count = 0;
    int len = 0;
    char c = s[0];
    int j = 0;

    for(int i = 0; i < s.length(); i++){

        if(s[i] == c){
            count += 1;
        } else {
            int q = 0;
            int r = 0;
            arr2[j] = count;
            while(1) {
                q = count / 10;
                r = count % 10;
                len += 1;

                if(q == 0){
                    break;
                }
                count = q;
            }
            len += 1;
            arr1[j] = s[i-1];
            count = 1;
            c = s[i];
            j += 1;
        }
    }
    int q = 0;
    int r = 0;
    arr2[j] = count;
    while(1) {
        q = count / 10;
        r = count % 10;
        len += 1;

        if(q == 0){
            break;
        }
        count = q;
    }
    arr1[j] = s[s.length()-1];
    len += 1;

    cout << len << endl;
    for (int i = 0; i <= j; i++){
        cout << arr1[i] << arr2[i];
    }
    return 0;
}

 

여기서 꼭 필요한게 정수형을 문자열로 바꿔주는 함수가 필요한데, to_string()으로 바꿀 수 있나보다

 

그리고 파이썬처럼 +연산자로 문자열을 서로 붙일 수 있나보다.

 

그러면 조금 더 간단하게 할 수 있을 것 같다

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string s;

    cin >> s;

    int count = 0;
    char c = s[0];

    string encoding = "";

    for(int i = 0; i < s.length(); i++){

        if(s[i] == c){
            count += 1;
        } else {
            encoding += s[i-1];
            encoding += to_string(count);

            count = 1;
            c = s[i];
        }
    }

    encoding += c;
    encoding += to_string(count);

    cout << encoding.length() << endl << encoding;
    return 0;
}

 

5. 사고력 향상 - 짝수번째 문자만 거꾸로 출력하기

 

문자열이 주어졌을 때, 주어진 문자열의 짝수 번째로 주어진 문자만을 고른 문자열을 역순으로(거꾸로) 출력하는 프로그램을 작성해보세요.

 

문자열 순회해서 짝수번째 문자를 배열에 저장한다음 역으로 출력하긴 했는데

 

나름 생각하면서 멋있게하긴 했지만 뭔가 깔끔하지 못해

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string s;
    cin >> s;

    string arr[s.length()/2+1];
    int count = 0;

    for(int i = 1; i <= s.length(); i++){
        
        if(i % 2 == 0){
            arr[i/2] = s[i-1];
            count += 1;
        }
    }

    for(int i = count; i >= 1; i--){
        cout << arr[i];
    }
    return 0;
}

 

마지막 짝수번째 index가 몇번인지 구해보자

 

원래 문자열의 마지막 index는 s.length() - 1이고, 얘는 s.length()번째 문자잖아

 

s.length()가 짝수라면 s.length() - 1부터 2씩 감소시켜가면서 역으로 출력하면 될거고

 

s.length()가 홀수라면, s.length() - 2부터 2씩 감소시켜가면서 역으로 출력하면 될것이다

 

#include <iostream>
#include <string>
using namespace std;

int main() {
    // 여기에 코드를 작성해주세요.

    string s;
    cin >> s;

    int index = s.length();

    if(index % 2 == 1){
        index -= 1;
    }

    for(int i = index - 1; i >= 0; i-=2){
        cout << s[i];
    }
    return 0;
}
TAGS.

Comments