현대 C 언어에서 간단한 문제를 해결하는 여러 가지 방법++

나는 단지 c++의 새로운 특성과 완전한 c#와javascript 배경을 깊이 이해하고 싶을 뿐이다.그나저나 저는 12년 동안 전문적인 개발 경험을 가지고 각종 언어를 위해 코드를 작성했습니다. 그래서 저는 이렇게 많은 해가 지난 후에 C++를 배우는 것이 더욱 쉽다고 생각합니다.잘못했습니다: C++는 매우 높은 학습 곡선을 가지고 있기 때문에 나는 문제의 복잡성을 증가시키기 위해 새로운 기능을 추가하기로 결정했습니다.가장 간단한 기포 정렬 방법부터 최신 C++ 표준 (C++11, C++17, C++2a) 에서 얻은 다양한 기능을 사용해서 많은 해결 방법을 찾으려고 합니다.
이렇게 하는 유일한 동기는 바로 학습의 즐거움이다. 그래서 이런 제한을 이용하여 (우리가 여기서 한 가닥의 희망을 보게 하고 우리는 더 많은 시간을 일을 할 수 있도록) 나는 C++를 배우는 데 주력하고 기진맥진하기 전에 내가 얼마나 멀리 갈 수 있는지 볼 것이다. D.
면책 성명: 저는 C++ 전문가가 아니기 때문에 대부분의 내용이 잘못된 것일 수 있습니다. 저는 C++ 분야의 경험도 없고 학술적 성실도 없지만 당신이 발견한 부족한 점을 지적하는 것을 받아들입니다.

기포 정렬법.
이것은 가장 간단한 알고리즘 중의 하나다.이것은 O(n2) 알고리즘으로 해석할 수 있으며, 이것은 정렬되지 않은 숫자를 포함하는 그룹이 두 번 교체된다는 것을 의미한다.그리고 두 개의 연속적인 원소를 찾으면 서로 교환된다.
먼저 c++ 템플릿을 준비합니다.
#include <bits/stdc++.h>

int main () {
    using namespace std;

    return EXIT_SUCCESS; // I will use this macro here, which represents de '0' value.
}
그래서 내가 생각한 첫 번째 일은'어떻게 무작위, 정렬되지 않은 숫자로 이 수조를 채울 것인가(지금부터 나는 벡터라고 부른다)'였다.나는 지금 하드코딩된 숫자로 그것을 초기화할 것이다.
vector<int32_t> vec = { 92, 23, 1, 6, 25, 72, 66, 10 };
이 두 단락의 코드를 통해 나는 몇 가지 것을 배웠다.
  • int32_t으로int,long unsigned int,long.int32_t가 오늘날의 관례인 것 같다.정확한 이유는 모르겠지만 현대 언어는 크로스플랫폼의 일치성을 확보하기 위해 매우 특정한 데이터 유형을 필요로 하는 것 같다.
  • 기본 기능 이외의 범위using입니다.
  • 宏 퇴출 성공, 이것은 반드시 강제적인 것은 아니다.
  • 현재는 vec 변수의 두 차례 덧붙임 교체입니다.
    for (size_t i = 0; i < vec.size(); ++i) {
        for (size_t j = 0; j < vec.size() - 1; ++j) {
            if (vec[j] > vec[j + 1]) {
              swap(vec[j], vec[j + 1]);
            }
        }
    }
    
    지금, 나는 무엇을 볼 수 있습니까?
  • size_t로 대체int를 사용했다. vec.size()size_t로 되돌아오기 때문이다int.만약 내가 int를 사용한다면 그것이 작용할 것이다. 이것은 매우 뚜렷한 것 같다. size_tint로 전환할 수 있지만 size_tint가 부족하지 않도록 모든 유형의 크기를 표시할 수 있기 때문이다.실행할 때 (또는 컴파일할 때?) 추가 내부 강제 변환을 피할 수 있습니다.
  • 표준 라이브러리에는 이미 swap 방법이 있다.
  • 연산자pre-increment는 상용++i를 대체한다post-increment.그 결과 i++ 덧셈을 하기 전에 저장된 원시 값을 되돌려 주는 것은 i++ 덧셈과 상반된다.다시 말하면 i++ 최소한 i++ 상황에서는 추가 메모리를 사용하여 이 값을 저장할 필요가 없다.
  • 현재 for...loop 변수의 또 다른 교체는 단지 화면에 결과를 나타내기 위한 것이다.
    for (size_t i = 0; i < vec.size(); ++i) {
        cout << vec[i] << endl; // Replacement of "\n"
    }
    
    컴파일하고 실행하도록 하겠습니다.vec결과:
    92
    72
    66
    25
    23
    10
    6
    1
    
    이제 내가 현대 C++ 기능으로 무엇을 할 수 있는지, 우리가 그것으로 이 간단한 문제를 해결할 수 있는지 봅시다.
    나는 하드코딩 데이터로 벡터를 초기화하는 대신 램바다 표현식을 사용하여 무작위 수를 생성할 것이다.이 하나가 있으면 성능을 최대한 걱정하지 않겠습니다. 지금까지 첫 번째 해결 방안이 더 빠른 것 같습니다.
    vector<int32_t> vec(100); // This time let's make a bigger vector.
    auto genRandomNumber = [](){ return (std::rand() % 100); };
    std::generate(vec.begin(), vec.end(), genRandomNumber);
    
    우리 여기 뭐가 있지?
    벡터를 초기화하는 또 다른 방법은 벡터의 초기 용량을 설정하는 것이다. 이 예에서 100이다.그리고 이 g++ -std=c++2a -O2 -Wall sort.cpp -o sort lambda 표현식을 만들었습니다. 0에서 100 사이의 무작위로 생성된 숫자만 포함하고, 이 숫자는 나중에 genRandomNumber 함수에 사용됩니다.

    1에서 20 사이의 모든 수로 나눌 수 있는 최소수.
    다음 문제는 더욱 간단해질 것이다. 그것은 단지 하나의 순환만 있을 뿐이다.내 머릿속에서 나는 가능한 (효과적인) 해결 방안을 생각해 낼 수 있다.0에서 무한대 사이를 순환하거나 가능한 최대 길이를 순환하며, 추악한 if에서 1부터 20까지의 숫자로 나눌 수 있는지 확인하십시오.
    using namespace std;
    
    for (size_t i = 1; i < std::numeric_limits<size_t>::max(); ++i) {
            if (
                i % 1 == 0 &&
                i % 2 == 0 &&
                i % 3 == 0 &&
                i % 4 == 0 &&
                i % 5 == 0 &&
                i % 6 == 0 &&
                i % 7 == 0 &&
                i % 8 == 0 &&
                i % 9 == 0 &&
                i % 10 == 0 &&
                i % 11 == 0 &&
                i % 12 == 0 &&
                i % 13 == 0 &&
                i % 14 == 0 &&
                i % 15 == 0 &&
                i % 16 == 0 &&
                i % 17 == 0 &&
                i % 18 == 0 &&
                i % 19 == 0 &&
                i % 20 == 0
            ) {
                // Print result
                cout << "Result :: " << i << endl;
                break; 
            }
        }
    
    컴파일하고 실행합시다.정말 쓸모가 있다!
    이제 첫 번째 순환에서 1에서 20으로 교체해서 조금 보기 싫지 않게 하기 위해서 C++11std::generate을 사용하겠습니다.
    
    int32_t x = 1;
    
    for (size_t i = 1; i < numeric_limits<size_t>::max(); ++i) {
        for (auto p: {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}) {
          x = p;
          if (i % p != 0) break;
        }
        if (x == 20) {
            // Print result
            cout << "Result :: " << i << "\n";
            break;
        }
    }
    
    컴파일하고 실행합니다.여전히 유효합니다!
    이제 벡터를 생성하기 위해 lambda 표현식을 다시 사용합니다.
    vector<int32_t> vec(20);
    
    auto funcGen = [counter = 0]() mutable -> int32_t { return ++counter; };
    std::generate(vec.begin(), vec.end(), funcGen);
    
    분석해 보겠습니다.
  • funcGen lambda 표현식에서 매개 변수range-based for loop를 전달했습니다. 이것은 우리가 되돌아오는 숫자를 저장할 수 있도록 합니다. 왜냐하면 우리는 매번 교체할 때마다 1씩 증가하는 숫자를 되돌려 주기를 원하기 때문입니다. 유일한 우아한 방법은 이런 형식을 사용하는 것입니다.
  • counter는 lambda 표현식mutable을 알려준다. 이 표현식은 포획된 모든 변수를 수정할 수 있다. 이 예에서counter.
  • 이렇게

    좋은 웹페이지 즐겨찾기