6
Đảo ngược mảng các chữ số trong C/C++?
1
kimthu92110 đã đăng:

Chào các bạn, mình là newbie về lập trình C/C++. Mình không biết đoạn code mình viết dưới đây sai chỗ nào mà mãi vẫn cho ra kết quả sai.

#include <conio.h>
#include <stdio.h>


void main()
{
    int A[100];
    int n;
    printf("Nhap vao so luong phan tu cua mang la: ");
    scanf("%d", &n);

    //nhap mang
    for(int i=0; i<n; i++)
    {
        printf("Nhap phan tu thu %d: ", i);
        scanf("%d", &A[i]);
    }

    //dao nguoc mang
    int B[100];
    for(int i=n-1; i>=0; i--)
    {
        for(int j=0; j < n; j++)
        {
            B[j] = A[i];
        }
    }

    //xuat mang
    for(int i=0; i<n; i++)
    {
        printf("%4d", B[i]);
    }
    printf("\n");

}

Input mình đưa vào là: {1, 2, 3, 4, 5}

Output của chương trình là: {1, 1, 1, 1, 1}

Trong khi output mình mong muốn là: {5, 4, 3, 2, 1}

Bạn nào chuyên ngành IT giúp mình xem lại đoạn chương trình trên với ạ hoặc chương trình khác cũng được ạ, mình không chuyên IT lắm có khi mình viết sai. Thanks mọi người.

thêm bình luận...
2
xuans2huy510 đã đăng:

Vấn đề nằm ở đoạn mã nguồn đảo ngược mảng của bạn,

int B[100];
for(int i=n-1; i>=0; i--)
{
    for(int j=0; j < n; j++)
    {
        B[j] = A[i];
    }
}

Đọc đoạn mã nguồn trên thì mình giả sử ý tưởng của bạn là cho hai mảng cùng chạy, mảng A chạy từ vị trí cuối cùng i = n - 1 về lại đầu mảng, còn mảng B chạy ngược lại từ vị trí đầu tiên j = 0 cho đến cuối mảng, sau đó cứ mỗi vị trí i và j, bạn gán B[j] = A[i] với hy vọng rằng phần tử cuối của mảng A sẽ là phần tử đầu của mảng B, như vậy là bạn đã đảo ngược được mảng.

Ý tưởng của bạn đúng nhưng việc thể hiện ý tưởng bằng mã nguồn của bạn có vấn đề như thế này, thay vì sử dụng một vòng lặp for thôi là đủ bạn sử dụng tới hai vòng lặp for dẫn đến kết quả bị sai, nó sẽ sai ở chỗ chúng ta chỉ muốn ở mỗi lần lặp, i giảm 1 thì j tăng 1, cụ thể:

  • Khi i = 4, j sẽ chạy từ 0 cho tới 4 (sai, chúng ta chỉ muốn i giảm 1 thì j tăng 1 tại một lần lặp, đằng này j tăng từ 0 tới 4)

    Kết quả mảng B tại thời điểm này: B = [5, 5, 5, 5, 5] do tại mỗi vị trí i, j chạy 5 lần, còn i không thay đổi, cho nên tất cả phần tử trong mảng B chỉ được cập nhật bằng một giá trị tại A[i]

  • Khi i = 3, j vẫn sẽ chạy từ 0 cho tới 4 (sai)

    Kết quả mảng B tại thời điểm này: B = [4, 4, 4, 4, 4] (tương tự)

  • .... (tương tự)
  • Khi i = 0, j vẫn sẽ chạy từ 0 cho tới 4 (sai)

    Kết quả mảng B cuối cùng: B = [1, 1, 1, 1, 1] (tương tự)

Cho nên, bạn sửa lại đoạn mã nguồn có vấn đề ở trên như sau,

for(int i=0; i<n/2; i++)
{
    int index = n - i - 1;
    int tmp = A[index];
    A[index] = A[i];
    A[i] = tmp;
}

Ý tưởng cũng đơn giản như bạn thôi, i chạy từ đầu mảng đến giữa mảng, mỗi lần i lặp, ta thực hiện hoán vị phần tử bên vế trái và phần tử bên vế phải bằng cách tính chỉ số index của phần tử bên vế phải của mảng A dựa vào index của vế trái, ví dụ với mảng 5 phần tử n = 5:

  • i = 0 thì index = 5 - 0 - 1 = 4 (chính xác)
  • i = 1 thì index = 5 - 1 - 1 = 3 (chính xác)
  • .... (tương tự)

Chương trình cuối cùng của bạn được sửa như sau:

#include <conio.h>
#include <stdio.h>


void main()
{
    int A[100];
    int n;
    printf("Nhap vao so luong phan tu cua mang la: ");
    scanf("%d", &n);

    //nhap mang
    for(int i=0; i<n; i++)
    {
        printf("Nhap phan tu thu %d: ", i);
        scanf("%d", &A[i]);
    }

    //dao nguoc mang
    for(int i=0; i< n/2; i++)
    {
        int index = n - i - 1;
        int tmp = A[index];
        A[index] = A[i];
        A[i] = tmp;
    }

    //xuat mang
    for(int i=0; i<n; i++)
    {
        printf("%4d", A[i]);
    }
    printf("\n");

}

Correct me if I'm wrong ^^!

đã bổ sung 6.0 năm trước bởi
xuans2huy510

Vậy ý bạn là mình tính chỉ số giữa của mảng bằng cách lấy số lượng phần tử chia 2, vậy trường hợp mảng có số lượng phần tử lẻ thì có đúng không ạ?

kimthu921 03.05.2018
1

Hoàn toàn đúng bạn nhé, xét hai trường hợp:

  • Số lượng phần tử của mảng là số chẵn, ví dụ n = 4, thì 4 / 2 = 2, tức là i chạy từ 0 $\rightarrow$ 1, index chạy từ 4 $\rightarrow$ 3.
  • Số lượng phần tử của mảng là số lẻ, ví dụ n = 5, thì 5 / 2 = 2 ( / là phép chia lấy nguyên trong C/C++), tức là i vẫn chạy từ 0 $\rightarrow$ 1, index chạy từ 4 $\rightarrow$ 3, còn vị trí A[2] vẫn giữ nguyên, kết quả vẫn đúng nhé.
xuans2huy 03.05.2018

Đã hiểu, cảm ơn bạn rất nhiều ạ.

kimthu921 03.05.2018
thêm bình luận...
2
Ðức Bình30 đã đăng:

Chỉ một dòng mã nguồn bạn có thể giải quyết được bài toán này,

#include <iostream>
using namespace std;

int main(){
    const int n = 5;
    int A[n] = {1, 2, 3, 4, 5};

    reverse(begin(A), end(A));

    for(int i=0; i<n; i++){
        printf("%4d", A[i]);
    }

    printf("\n");
}

Cheer !!!

Cảm ơn bạn @Đức Bình nhé, nhưng mình không được phép sử dụng thư viện có sẵn ạ (T_T).

kimthu921 03.05.2018

Oh, bạn sử dụng IDE nào để lập trình vậy? Bạn có thể sử dụng công cụ Debug của nó chạy từng dòng lệnh để xem thử không đúng ở đoạn code nào.

Ðức Bình 03.05.2018

Visual Studio 2012 bạn ơi, mình kiểm tra rồi không có lỗi về mặt cú pháp, chương trình vẫn chạy và cho ra kết quả nhưng kết quả sai thôi.

kimthu921 03.05.2018
thêm bình luận...
0
thanhtrungjt0 đã đăng:
#include <stdio.h>
#include <conio.h>

void main()
{
    int n, a=0;
    printf("moi nhap mot so: ");
    scanf("%d", &n);
    while (n > 0)
    {
        a = 10*(a) + (n%10);
        n = (n - n%10) / 10;
    }
    printf("%d",a);
}

mình cũng newbie nên viết kiểu này thôi

Cảm ơn bạn @thanhtrungjt ạ, cơ mà mình thực hiện trên mảng các số ấy, của bạn hình như là nhập trực tiếp một số vào luôn phải không ạ?

kimthu921 03.05.2018
thêm bình luận...
0
Cộng đồng đã đăng:
#include <stdio.h>
#include <conio.h>

int main(){

    int A[100];
    int n;
    printf("Nhap vao so luong phan tu cua mang la: ");
    scanf("%d", &n);

    //nhap mang
    for(int i=0; i<n; i++)
    {
        printf("Nhap phan tu thu %d: ", i);
        scanf("%d", &A[i]);
    }

    //dao nguoc mang (and display)
    for(int i=n-1; i>=0; i--)
    {
        printf("\n%d", A[i]);
    }

   getch();
   return 0;
}
thêm bình luận...
0
Cộng đồng đã đăng:

Bằng cách sử dụng vòng lặp while để lấy ra từng ký tự và so sánh chúng với nhau, chúng ta có thể tiến hành đảo ngược ký tự trong chuỗi C theo thứ tự trong bảng chữ cái.

Để so sánh các ký tự với nhau, chúng ta có thể sử dụng tới toán tử so sánh, hoặc là hàm strcmp() chẳng hạn.

Link tham khảo: Đảo ngược chuỗi trong C

thêm bình luận...
0
Cộng đồng đã đăng:

Tương tự như ngôn ngữ C thì trong C++, bằng cách sử dụng vòng lặp while để lấy ra từng ký tự và so sánh chúng với nhau, chúng ta có thể tiến hành đảo ngược thứ tự các từ trong chuỗi C++ theo thứ tự trong bảng chữ cái.

Link tham khảo: Đảo ngược chuỗi trong C++

thêm bình luận...
Bạn đang thắc mắc? Ghi câu hỏi của bạn và đăng ở chế độ cộng đồng (?)