2011-09-01 3 views
2

나는 팀 내의 모든 선수 수를 저장하는 배열 int *playerNum을 가지고 있습니다. 각 슬롯 (예 : playerNum[1];)은 팀의 새 직책에 새 플레이어를 추가하려는 경우 팀의 위치를 ​​나타냅니다. 즉, 중간에 배열 어딘가에 새로운 요소를 삽입하는 방법, 내가 어떻게이 일을 갈 것이라고?배열 중간에 삽입

현재로서는 새로운 배열에 플레이어를 삽입하고 나머지 플레이어를 삽입하려는 위치까지 memcpy까지 생각했습니다.

당신이이 경우 삽입에서 항목을 이동하는 memmove를 사용 (필요한 경우 realloc를 사용하여) 당신이 충분한 저장되어 있는지 만든 후에, 배열을 사용하는

답변

3

(I 배열을 사용해야합니다) 끝까지 한 지점 씩 가리킨 다음 새 플레이어를 원하는 위치에 저장하십시오.

소스 및 대상 영역이 겹치는 경우 memcpy을 사용할 수 없습니다.

배열에있는 객체가 단순한 복사 생성자를 가지 자마자 실패하며, 관용적 인 C++가 아닙니다. 컨테이너 클래스 중 하나를 사용하면 훨씬 안전합니다 (예 : std::vector 또는 std::list). 당신의 C++를 사용하는 경우

+3

(앞으로) 그는이 코드를 평범하지 않은 복사본 생성자가있는 유형에 사용하기 때문에'memmove' (또는'memcpy')는 작동하지 않습니다. –

3

, 나는 memcpy 또는 memmove를 사용하는 대신 copy 또는 copy_backward 알고리즘을 사용하지 않는 것이 좋습니다 것입니다. 이것들은 일반적인 오래된 정수가 아닌 모든 데이터 유형에서 작동하며 대부분의 구현은 어쨌든 memmove까지 컴파일 될만큼 충분히 최적화되어 있습니다. 더 중요한 것은 배열의 요소의 기본 유형을 사용자 정의 복사 생성자 또는 할당 연산자가 필요한 것으로 변경하는 경우에도 작동합니다.

1

memcpy을 사용하는 귀하의 솔루션은 정확합니다 (다른 가정의 일부 가정하에).

그러나 C++로 프로그래밍 중이므로. std::vector 및 그 insert 방법을 사용하는 것이 더 좋은 선택 일 수 있습니다.

vector<int> myvector (3,100); 
    myvector.insert (10 , 42); 
+1

+1'std :: vector'에 +1합니다. –

0

배열은 인접한 메모리 블록을 사용하므로 중간에 요소를 삽입 할 수있는 기능이 없습니다. 그런 다음 새 플러스 신규 회원

for(int i=0;i<arSize/2;i++) 
{ 
    newarray[i]<-ar[i]; 
} 
newarray[i+1]<-newelemant; 
for(int j=i+1<newSize;j++,i++) 
{ 
    newarray[i]<-ar[i]; 
} 

당신이 STL을 사용하는 경우, 팅은 사용 목록 쉬워집니다에 원래 배열을 복사 기원의 하나보다 큰 크기의 새 만들 수 있습니다.

+0

사용 된 데이터 구조와 관계없이 루프를 사용하지 말고'std :: copy'를 사용하십시오! –

+0

C++의'<-' ??? – log0

+0

"var1 ** <- ** var2"는 무엇입니까? C++ 11 뭔가? 그리고 벡터가 더 좋을 수도 있습니다 (랜덤 액세스) –

0

배열에 대해 이야기하고 "삽입"하면 정렬 된 배열이라고 가정합니다. 기존 배열의 용량이 N 인 경우 두 번째 배열이 필요하지 않습니다 (N>n, 여기서 n은 현재 항목 수임). 항목을 k에서 n-1 (0으로 색인 됨)에서 k+1에서 n까지 이동할 수 있습니다. 여기서 k은 원하는 삽입 위치입니다. 새 요소를 인덱스 위치 k에 삽입하고 n을 1 씩 늘립니다. 배열의 크기가 처음에는 충분히 크지 않은 경우 제안 된 방법을 따르거나 더 큰 용량의 새로운 배열 N'을 다시 할당하고 위에서 설명한 실제 삽입 작업을 적용하기 전에 기존 데이터를 복사 할 수 있습니다.

현재 : C++을 사용하는 경우 std::vector을 쉽게 사용할 수 있습니다.

0

이 경우에도 배열을 사용할 수 있지만 C++에는 더 나은 솔루션이 있습니다. 우선, 동적으로 할당 된 배열을 기반으로 적절한 일반 컨테이너 인 std::vector을 시도하십시오. 많은 경우 어레이와 똑같이 작동합니다.

  • 지수 0 기반 및 연속으로왔다 :

    문제를 보면, 그러나, 두 개의 배열하는 단점이나 벡터가있다 제거 된 요소 이후의 모든 것에 대한 키/값 연결을 잃지 않고 중간에서 요소를 제거 할 수는 없습니다. 그래서 4 위 자리에있는 플레이어를 제거하면 9 위 자리의 플레이어가 8 위치로 이동합니다.

  • 무작위 삽입 및 삭제 (즉, 끝을 제외한 모든 곳)는 비용이 많이 듭 깁니다 - O (n), 즉 실행 시간 배열 크기에 따라 선형 적으로 커집니다. 이는 삽입하거나 삭제할 때마다 배열의 일부를 이동해야하기 때문입니다.

키/값의 일이 당신에게 중요하지 않은 경우는, 삽입/삭제, 컨테이너 결코 정말 큰 될 것 없습니다 시간이 중요하지, 모든 수단으로 사용 벡터. 무작위 삽입/삭제 성능이 필요하지만 키/값의 중요성이 중요하지 않은 경우 std::list (무작위 액세스가 없어도 구현됩니다. 즉, [] 연산자는 정의되지 않았습니다. 연결리스트는 매우 비효율적이며, 연결리스트 또한 매우 배가 고파서, 요소 당 2 개의 포인터의 오버 헤드가있다). 키/값 연결을 유지하려면 std::map이 (가) 친구입니다.

+0

성능을 위해'std :: list'를 보지 마십시오. 'std :: list'는 노드 기반 컨테이너이기 때문에 사용자 정의 풀 할당자를 사용하여 성능을 향상시킬 수 있지만 결국 대부분의 작업 부하에 대해 가장 느린 비 연관 컨테이너입니다. 'std :: list'의 장점은 다음과 같습니다 : 반복자 무효화가 거의없고'splice' 연산입니다. 그러나 일반 목적의 성능은 아닙니다 (속도 나 메모리가 차지하지 않습니다 ...) –

+0

무작위 삽입과 삭제가 병목 현상이 발생하면'std :: list'는 여전히 성능면에서 흥미 롭습니다. 이론적으로는 – tdammers

+0

이다. 실제로 목록을 걷는 데 드는 비용 (노드가 메모리에있는 모든 노드에 있기 때문에 캐시 미스를 모두 얻음)은 너무 높아서이를 보충하기 위해 많은 복사본이 필요합니다. 메모리 지역은 CS 클래스에서 논의되지 않았지만 실제로는 매우 중요합니다. 'vector'는 캐시와 함께 잘 작동하는 구조가 훨씬 간단하고'memmove'는 매우 효율적입니다. –

관련 문제