Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

พิมพ์ 1 ถึง 1000 ไม่ใช้ Loop/Condition ใน C++: Template Recursion และ Static Member

โจทย์: พิมพ์ตัวเลข 1 ถึง 1000 โดย ห้ามใช้ Loop (for/while) และ Condition (if/switch) วิธีแก้หลัก 2 แบบ: Template Metaprogramming (Compile-time) และ Static Member + Constructor (Runtime)

วิธีที่ 1: Static Member + Constructor Array (Runtime)

สร้าง Array ของ Object ขนาด N Constructor จะถูกเรียก N ครั้ง


#include <iostream>

class Printer {
    static int counter;
public:
    Printer() {
        std::cout << counter++ << (counter <= 1000 ? ", " : "\n");
    }
};

int Printer::counter = 1;

int main() {
    Printer arr[1000]; // Constructor เรียก 1000 ครั้ง
    return 0;
}

วิธีที่ 2: Template Recursion (Compile-time, C++11)

ใช้ Template Specialization เป็น Base Case (แทน Condition)


#include <iostream>

// General Case
template <int N>
struct Print {
    static void run() {
        Print<N-1>::run();
        std::cout << N << (N == 1000 ? "\n" : ", ");
    }
};

// Base Case (Specialization)
template <>
struct Print<1> {
    static void run() {
        std::cout << 1 << ", ";
    }
};

int main() {
    Print<1000>::run(); // Compile-time Recursion
}

วิธีที่ 3: C++17 Fold Expression (Modern)


#include <iostream>
#include <utility> // index_sequence

template <size_t... Is>
void printSeq(std::index_sequence<Is...>) {
    // Fold Expression with Comma Operator
    ((std::cout << (Is + 1) << (Is == 999 ? "\n" : ", ")), ...);
}

int main() {
    printSeq(std::make_index_sequence<1000>{});
}

วิธีที่ 4: Recursive Lambda + Y-Combinator (C++14)


#include <iostream>
#include <functional>

int main() {
    auto y_combinator = [](auto&& self, auto n) -> void {
        if (n > 1) self(self, n - 1); // Condition ใน Lambda Body (Allowed?)
        std::cout << n << (n == 1000 ? "\n" : ", ");
    };
    // แต่โจทย์ห้าม Condition...
}

วิธีที่ 5: std::iota + Algorithm (Cheating? ไม่มี Loop เขียนเอง)


#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main() {
    std::vector v(1000);
    std::iota(v.begin(), v.end(), 1); // Fill 1..1000
    std::copy(v.begin(), v.end(), std::ostream_iterator(std::cout, ", "));
    std::cout << '\n';
}

การวิเคราะห์ Constraint "No Condition"

  • Template Specialization: Base Case เป็น Compile-time Branch (ไม่ใช่ Runtime If)
  • Static Constructor: ไม่มี Condition ใน Code (Implicit ใน Array Size)
  • Fold Expression: Ternary Operator ใน Fold ถือว่าเป็น Condition หรือไม่? (Gray Area)
  • Algorithms: Library Functions ซ่อน Loop/Condition ไว้ภายใน

สรุป

วิธีที่ "Pure" ที่สุดคือ Template Recursion with Specialization (Compile-time, ไม่มี Runtime Condition) วิธี Static Member + Array เรียบง่ายที่สุดสำหรับ Runtime ทั้งคู่แสดงให้เห็นความยืดหยุ่นของ C++ ในการแก้ปัญหา Constrained Programming