2009-12-14 28 views
11

Giả sử tôi có một mảngcách tối ưu để thực hiện một hoạt động thay đổi trên một mảng

unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9}; 

Có cách nào để thực hiện thao tác thay đổi trên chúng bên cạnh chỉ cần sao chép tất cả chúng vào mảng khác. Chúng tôi có thể dễ dàng làm điều đó bằng cách sử dụng danh sách liên kết nhưng tôi đã tự hỏi nếu chúng ta có thể sử dụng một nhà điều hành thay đổi và hoàn thành công việc nhanh hơn.

Lưu ý: Dữ liệu trong câu hỏi này chỉ là một ví dụ. Câu trả lời phải là không phân biệt dữ liệu trong mảng.

+0

Bạn đang cố gắng thực hiện điều gì, sao chép mảng? –

+4

Có lẽ nó chỉ là tôi, nhưng tôi là một chút không rõ ràng - bạn có muốn bitwise thay đổi mỗi phần tử trong mảng, hoặc thay đổi tròn toàn bộ mảng? – maxaposteriori

+0

Bạn có đang dịch chuyển các phần tử mảng, tức là arr [0] = arr [1], vâng, hay bạn đang bithifting từng phần tử của mảng, tức là arr [0] = arr [0] << 2? Nếu trước đây, hãy xóa thẻ "bitwise". – mch

Trả lời

20

Nếu bạn muốn có một sự thay đổi tròn của các yếu tố:

std::rotate(&arr[0], &arr[1], &arr[10]); 

... sẽ làm các trick. Bạn cần phải #include tiêu đề thuật toán.

+1

Liên kết nhanh http://www.cplusplus.com/reference/algorithm/rotate/ – wardw

+2

Liên kết nhanh http: //en.cppreference.com/w/cpp/algorithm/rotate –

7

Nếu bạn là người duy nhất có con trỏ vào mảng, chỉ cần tăng con trỏ và giảm độ dài.

Chỉ cần nhớ giữ con trỏ ban đầu xung quanh khi bạn giải phóng nó.

9

Chừng mảng là sửa đổi, bạn có thể sử dụng memmove chuyển họ (nhưng không nhầm lẫn sử dụng memcpy như memcpy không có nghĩa là cho chồng chéo vùng):

memmove(&arr[0], &arr[1], sizeof(arr) - sizeof(*arr)); 

(sizeof (arr) - sizeof (* arr) là kích thước tính theo byte của tất cả trừ 1 phần tử của mảng).

+0

Điều này hoàn toàn mất giá trị của 'arr [0]' - cho một thay đổi tròn, bạn phải lưu giá trị đó và lưu trữ nó trong phần tử cuối cùng sau khi 'memmove'. – caf

+0

câu trả lời ngọt ngào và nhỏ gọn – ssj

+0

Hoạt động trên Arduino – Jacksonkr

0

Tôi tự hỏi có lẽ bạn nên sử dụng std :: valarray hay không.

6

Nếu bạn đang tìm kiếm giải pháp C thuần túy, tại đây, bao gồm chương trình điều khiển. Hóa ra là khá đơn giản: để xoay bởi n, bạn:

  1. đảo ngược n yếu tố đầu tiên tại chỗ,
  2. đảo ngược các yếu tố còn lại tại chỗ, và
  3. đảo ngược toàn bộ mảng trong -địa điểm.

Điều này yêu cầu một phần tử đáng giá thêm bộ nhớ (để đảo ngược).

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 

/* print an array */ 
static void print_array(unsigned char *arr, size_t n, const char *prefix) 
{ 
    size_t i; 

    if (prefix) { 
     printf("%s: ", prefix); 
    } 
    for (i=0; i < n; ++i) { 
     printf("%02x ", (unsigned int)arr[i]); 
    } 
    printf("\n"); 
} 

/* reverse 'arr', which has 'narr' elements */ 
static void reverse(unsigned char *arr, size_t narr) 
{ 
    size_t i; 

    for (i=0; i < narr/2; ++i) { 
     unsigned char tmp = arr[i]; 
     arr[i] = arr[narr-i-1]; 
     arr[narr-i-1] = tmp; 
    } 
} 

/* rotate 'arr' of size 'narr' by 'shift' */ 
static void rotate(unsigned char *arr, size_t narr, unsigned long shift) 
{ 
    reverse(arr, shift); 
    reverse(arr + shift, narr - shift); 
    reverse(arr, narr); 
} 

/* driver program */ 
int main(int argc, char *argv[]) 
{ 
    unsigned char arr[]= {0,1,2,3,4,5,6,7,8,9,10}; 
    size_t narr = sizeof arr/sizeof arr[0]; 
    unsigned long shift = 2; 

    if (argc > 1) { 
     char *eptr; 
     shift = strtoul(argv[1], &eptr, 0); 
     if (*eptr || errno == ERANGE) { 
      perror("strtoul"); 
      return EXIT_FAILURE; 
     } 
    } 
    print_array(arr, narr, "before shift"); 
    rotate(arr, narr, shift); 
    print_array(arr, narr, "after shift"); 
    return EXIT_SUCCESS; 
} 
+0

@Alok: Cảm ơn người đàn ông này ... trông rất hữu ích – tomkaith13

Các vấn đề liên quan