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

ปัญหาพาร์ติชั่นใน C++


ในปัญหานี้ เราต้องสร้างโค้ด C++ เพื่อกำหนดว่าอาร์เรย์สามารถแบ่งออกเป็นสองอาร์เรย์ย่อยที่เท่ากันหรือไม่ นอกจากนี้ เราต้องตรวจสอบเงื่อนไขด้วยว่าผลรวมขององค์ประกอบทั้งหมดในอาร์เรย์ย่อยทั้งสองเหมือนกันหรือไม่ ปัญหาการแบ่งพาร์ติชั่นเป็นตัวแปรของ Subset Sum Problem ซึ่งในทางกลับกัน ปัญหาของเป้ เราจะใช้ภาษาการเขียนโปรแกรม C++ เพื่อจัดการกับปัญหาพาร์ติชั่น เราต้องส่งคืนสตริงที่มีใช่หรือไม่ใช่ขึ้นอยู่กับว่าเงื่อนไขที่ระบุเป็นจริงหรือไม่

ป้อนข้อมูล

arr[] = {6, 4, 8, 12, 15}

ผลผลิต

Is possible to divide into two subsets of equal sum

แนวทางการแก้ปัญหา

เป้าหมายคือการหาผลรวมขององค์ประกอบทั้งหมดในชุด เมื่อผลรวมอาร์เรย์เป็นเลขคี่ เราไม่สามารถแบ่งออกเป็นสองชุดได้ ระบุเซตย่อยด้วย sum/2 เมื่อผลรวมเป็นคู่ ใช้อาร์เรย์ที่กำหนด ตรวจสอบแต่ละองค์ประกอบทีละรายการ แล้วเลือกตัวเลือกใดตัวเลือกหนึ่งต่อไปนี้:

  • รวมรายการปัจจุบันในชุดย่อยต่อไป จากนั้นเพิ่มส่วนที่เหลือเพื่อให้ได้ยอดรวม

  • เมื่อรายการปัจจุบันถูกลบออกจากชุดย่อยแล้ว ให้ทำซ้ำขั้นตอนสำหรับรายการอื่นๆ

สุดท้าย คืนค่า จริง หากรายการปัจจุบันถูกรวมหรือไม่รวมในชุดย่อย มิฉะนั้นให้คืนค่าเท็จ การเรียกซ้ำจะสิ้นสุดลง หากไม่มีรายการเพิ่มเติมหรือหากผลรวมกลายเป็นลบ ในกรณีของผลรวมเป็น 0 เราจะคืนค่า จริง หมายความว่ามีการระบุเซตย่อยแล้ว

ตัวอย่าง

#include <bits/stdc++.h>
using namespace std;
bool isSubsetSum(int arr[], int n, int sum) {
   if (sum == 0)
      return true;
   if (n == 0 && sum != 0)
      return false;
   if (arr[n - 1] > sum)
      return isSubsetSum(arr, n - 1, sum);
   return isSubsetSum(arr, n - 1, sum) ||
   isSubsetSum(arr, n - 1, sum - arr[n - 1]);
}
bool findPartiion(int arr[], int n) {
   int sum = 0;
   for (int i = 0; i < n; i++)
      sum += arr[i];
   if (sum % 2 != 0)
      return false;
   return isSubsetSum(arr, n, sum / 2);
}
int main() {
   int arr[] = {
      6,
      4,
      8,
      12,
      15
   };
   int n = sizeof(arr) / sizeof(arr[0]);
   if (findPartiion(arr, n) == true)
      cout << "Is possible to divide into two subsets " "of equal sum";
   else
      cout << "Is impossible to divide into two subsets" " of equal sum";
   return 0;
}

ผลลัพธ์

Is impossible to divide into two subsets of equal sum

แนวทางที่ 2

เมื่อส่วนประกอบทั้งหมดไม่ใหญ่เกินไป ปัญหาสามารถจัดการได้โดยใช้โปรแกรมแบบไดนามิก สามารถสร้างส่วนอาร์เรย์ 2 มิติ[][]ขนาด (ผลรวม/2 + 1)*(n+1) ได้ เราอาจสร้างวิธีแก้ปัญหาจากล่างขึ้นบน เพื่อให้แต่ละรายการที่กรอกมีคุณสมบัติดังต่อไปนี้ เราสามารถแก้ปัญหานี้ได้โดยใช้อาร์เรย์ขนาด 2 มิติ (ผลรวม/2 + 1)*(n + 1) แทน ขนาดอาร์เรย์ 2 มิติ (ผลรวม/2 + 1)*(n + 1).

ตัวอย่าง

#include <bits/stdc++.h>
using namespace std;
bool findPartiion(int arr[], int n) {
   int sum = 0;
   int i, j;
   for (i = 0; i < n; i++)
      sum += arr[i];
   if (sum % 2 != 0)
      return false;
   bool part[sum / 2 + 1];
   for (i = 0; i <= sum / 2; i++) {
      part[i] = 0;
   }
   for (i = 0; i < n; i++) {
      for (j = sum / 2; j >= arr[i]; j--){
         if (part[j - arr[i]] == 1 || j == arr[i])
            part[j] = 1;
      }
   }
   return part[sum / 2];
}
int main() {
   int arr[] = {
      6,
      4,
      8,
      12,
      15
   };
   int n = sizeof(arr) / sizeof(arr[0]);
   if (findPartiion(arr, n) == true)
      cout << "Is possible to divide into two subsets of equal " "sum";
   else
      cout << "Is impossible to divide into two subsets" " of equal sum";
   return 0;
}

ผลลัพธ์

Is impossible to divide into two subsets of equal sum

บทสรุป

ในปัญหานี้ เราได้เรียนรู้วิธีแก้ปัญหาพาร์ติชั่นพร้อมกับโค้ด c++ รหัสนี้ยังสามารถเขียนในภาษาจาวา ไพธอน และภาษาอื่นๆ ได้อีกด้วย เราได้แก้ไขปัญหาพาร์ติชั่นโดยใช้อาร์เรย์แบบเรียกซ้ำในภาษาการเขียนโปรแกรม C++ เป็นรหัสพื้นฐานแต่มีประโยชน์มากมายในการแก้ปัญหา