Bài tập mảng C++ nâng cao: In các phần tử trong 2 mảng A và B

Đề như vầy:
Nhập vào hai dãy số nguyên A 1 , A 2 , …, A n , và B 1 , B 2 , …, B m .

a) Xuất ra tập các số là hội của hai dãy A và B.

b) Xuất ra tập các số là giao của hai dãy A và B.

c) Xuất ra tập các số là hiệu của hai dãy A và B.

Ví dụ: A = {1, 2, 3, 4, 5} B = {4, 5, 6, 7, 8, 9}
a)Hội là có các phần tử của A và B: 1 2 3 4 5 6 7 8 9
b)Giao là các phần tử vừa thuộc A vừa thuộc B: 4 5
c)Hiệu là chỉ có ở A mà không có ở B: 1 2 3

=>A/e giúp nhé!

Thích hướng dẫn hay thích lấy code về xài =))

2 Likes

Hướng dẫn đi ! :slight_smile: :slight_smile: :slight_smile: :slight_smile:

a)
Nhập mảng A có n phần tử
Nhập mảng B có m phần tử
Tạo mảng C có n+m phần tử
Tạo biến KichThuocHoi=0

//Đưa mảng A vào đầu mảng C
for (int i=0;i<n;i++)
    {
        C[i]=A[i];
        KichThuocHoi++;
    }

//Đưa mảng B vào mảng C nối tiếp mảng A
for (int i=0;i<m;i++)
    {
        C[i+n]=B[i];
        KichThuocHoi++;
    }

//Sắp xếp dãy theo chiểu tăng dần, cái này thì vô số thuật toán, mình khỏi nói
Sắp xếp mảng C theo chiều tăng dần

//Nếu C[i] số bằng 1 số cạnh nó thì kéo cả dãy tiến lên từ vị trí đó, và giảm KichThuocHoi đi 1
for (int i=0;i<n+m-1;i++)
    if (C[i]==C[i+1])
        for (int j=i;j<n+m-1;j++)
            {
                C[j]=C[j+1];
                KichThuocHoi--;
            }

Như vậy ta có mảng C bao gồm từ C[0] đến C[KichThuocHoi-1] là hội của A và B

b)
Nếu n<m thì tạo mảng D có n phần tử, không thì mảng D có m phần tử
(Giả sử n<m hay là A có ít phần tử hơn thì ta sẽ dò theo A)

for (int i=0;i<n;i++)
    for (int j=0;i<m;j++)
        if (A[i]==B[j])
            D[i]==A[i];

Làm xong bước trên thì ta có tập D chứa giao của A và B, thực hiện sắp xếp và lọc phần tử trùng tương tự với mảng C ở câu A

c)
Tạo mảng E có kích thước n và tất cả các giá trị bằng 0;
Tạo mảng F có kích thước n và biến đếm mặc định k=0;

for (int i=0;i<n;i++)
    for (int j=0;i<m;j++)
        if (A[i]==B[j])
            E[i]=1; //Lấy những vị trí trong A mà thuộc B
for (int i=0;i<n;i++)
    if (E[i]==0)
        {
            F[k]=A[i];
            k++;
        } //Thu được F gồm các giá trị thuộc A/B và đang lộn xộn

Cuối cùng là thực hiện sắp xếp và thu gọn mảng giống câu a)

2 Likes

Cảm ơn nhiều nhé !!!

Mình nhầm nhé :smiley: Đoạn này dùng để loại bỏ các số trùng nhau khỏi dãy, phải thay bằng:

while (C[i]==C[i+1])

bạn học các thuật toán sắp xếp chưa?

1 Like

rồi ! !!!

xài set_union, set_intersection, set_difference cho khỏe, khỏi mất công rặn óc

#include <iostream>
#include <vector>
#include <algorithm>
 
int main()
{
    std::vector<int> v1{1, 2, 3, 4, 5}; 
    std::vector<int> v2{         4, 5, 6, 7, 8, 9};
    
    std::sort(begin(v1), end(v1));
    std::sort(begin(v2), end(v2));
    
    std::vector<int> v1_union_v2;
    std::set_union(begin(v1), end(v1), begin(v2), end(v2),                  
                   std::back_inserter(v1_union_v2));
    for (int i : v1_union_v2) std::cout << i << ' '; std::cout << '\n';
    
    std::vector<int> v1_intersect_v2;
    std::set_intersection(begin(v1), end(v1), begin(v2), end(v2),                  
                          std::back_inserter(v1_intersect_v2));
    for (int i : v1_intersect_v2) std::cout << i << ' '; std::cout << '\n';
    
    std::vector<int> v1_minus_v2;
    std::set_difference(begin(v1), end(v1), begin(v2), end(v2),                  
                        std::back_inserter(v1_minus_v2));
    for (int i : v1_minus_v2) std::cout << i << ' '; std::cout << '\n';
}
4 Likes

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

cho mình hỏi hàm back_inserter để làm gì vậy?

Có thể hiểu nôm na là “kết quả được chèn phía sau collection này” :slight_smile:
Còn nó hoạt động như vầy https://en.cppreference.com/w/cpp/iterator/back_insert_iterator

4 Likes

output của set_unionset_intersection sẽ được tham số thứ 5 output_iter trong 2 hàm này lưu lại. Code lưu lại có thể được viết là:

*output_iter = result;
++output_iter;

ví dụ 1 hàm myMerge viết thế này:

// hàm này đơn giản là copy "mảng" 1 vào output rồi copy "mảng" 2 vào output
template <typename ForwardIter1, typename ForwardIter2, typename OutputIter>
void myMerge(ForwardIter1 first1, ForwardIter1 last1, ForwardIter2 first2,
             ForwardIter2 last2, OutputIter outIter) {
    // copy [first1, last1) to outIter
    for (; first1 != last1; ++first1, ++outIter) *outIter = *first1;
    // viết "khó hiểu" hơn 1 tí nhưng đẹp hơn:
    // while (first1 != last1) *outIter++ = *first1++;

    // copy [first2, last2) to outIter
    for (; first2 != last2; ++first2, ++outIter) *outIter = *first2;
}

nếu tham số thứ 5 đó là con trỏ hoặc iterator thì nó code trên chạy vô tư, nhưng vì ko biết trước sẽ có bao nhiêu kết quả nên phải xài vector::push_back, mà code trên ko có xài push_back. Vậy ta phải nhờ 1 class trung gian quá tải toán tử =, * (indirection, ko phải phép nhân) và ++ gọi là back_insert_iterator: * chả làm gì cả, trả về chính nó, ++ cũng chả làm gì, chỉ có = là gọi container.push_back(result).

std::back_inserter(container) là 1 hàm để tạo back_insert_iterator này, tên ngắn hơn :V

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?