2013-03-12 1 views
0

개체 배열 tArray에는 구매자 이름과 구매 한 항목의 numshares가 들어 있으며, 각 구매자는 개체 배열에 두 번 이상 올 수 있습니다. 5 대 구매자의 이름을 배열로 반환해야합니다.C++ - 까다로운 방법 - 필요 해결책

구매자 이름과 병행하여 두 개의 어레이를 실행하려고 시도했지만 다른 볼륨에는 총 볼륨이 있습니다.

내 방법이 일반적으로 잘못 되었기 때문에 결함이 발생합니다. 어떻게이 문제를 해결할 수 있습니까?

감사

ntransactions = 배열 ​​

string* Analyser::topFiveBuyers() 
{ 
//set size and add buyer names for comparison. 
const int sSize = 5; 
string *calcString = new string[sSize]; 
calcString[0] = tArray[0].buyerName; 
calcString[1] = tArray[1].buyerName; 
calcString[2] = tArray[2].buyerName; 
calcString[3] = tArray[3].buyerName; 
calcString[4] = tArray[4].buyerName; 
int calcTotal[sSize] = {INT_MIN, INT_MIN, INT_MIN, INT_MIN, INT_MIN}; 

//checks transactions 
for (int i = 0; i<nTransactions; i++) 
{ 
    //compares with arrays 
    for(int j =0; j<sSize; j++) 
    { 
     //checks if the same buyer and then increase his total 
     if(tArray[i].buyerName == calcString[j]) 
     { 
     calcTotal[j] += tArray[i].numShares; 
     break; 
     } 
      //checks if shares is great then current total then replaces 
      if(tArray[i].numShares > calcTotal[j]) 
      {   
      calcTotal[j] = tArray[i].numShares; 
      calcString[j] = tArray[i].buyerName; 
      break; 
      } 
    } 
} 
return calcString; 
} 
+4

몇 가지 제안 : 모든 경고와 디버깅 정보 (예 : Linux의 경우 'g ++ -Wall -g')를 사용하여 컴파일하십시오. 디버거 (리눅스에서'gdb')를 사용하는 방법을 배우십시오. 'std :: vector'를 사용해보십시오. –

+1

어떤 결과가 나타 납니까? 그리고 당신은 어떤 결과를 기대합니까? –

+1

* "구매자 이름과 병렬로 두 개의 배열을 실행하려고 시도했지만 다른 배열에 전체 볼륨이 있습니다."* - 병렬 배열은 일반적으로 링크 된 데이터를 클래스에 배치하고 해당 클래스의 배열을 만들어야한다는 표시입니다 . – JBentley

답변

1

는 당신이, 내가 표준 : 맵에 값을 축적하여 시작 줄 수있는 가정하면 :

std::map<std::string, int> totals; 

for (int i=0; i<ntransactions; i++) 
    totals[tarray[i].buyername] += tarray[i].numshares; 

이 각 구매자에 대한 주식의 총 수를 추가합니다. 그런 다음 해당 데이터를 std :: vector에 복사하고 공유 수로 상위 5 개를 가져 오려고합니다. 잠시 동안 구조체 (buyernamenumshares을 멤버로 가정)의 이름은 transaction으로 가정합니다. 당신이 수, 당신이 그것을 지탱할 수있을 정도로 새로운 컴파일러를 사용하는 경우,

struct by_shares { 
    bool operator()(transaction const &a, transaction const &b) { 
     return b.numshares < a.numshares; 
    } 
}; 

또는이 들어

std::vector<transaction> top5; 

std::copy(totals.begin(), totals.end(), std::back_inserter(top5)); 

std::nth_element(top5.begin(), top5.begin()+5, top5.end(), by_shares()); 

당신이 뭔가를 보이는 by_shares라는 비교 펑터가 필요합니다 작동합니다 비교를 위해 람다 대신 명시 적 펑를 사용

std::nth_element(totals.begin(), totals.end()-5, totals.end(), 
    [](transaction const &a, transaction const &b) { 
     return b.numshares < a.numshares; 
    }); 

어느 쪽이든을 nth_element이 완료된 후, 상위 5는 벡터의 처음 5 개 요소가됩니다. 이 작업을 수행하기 위해 정상적인 비교를 거꾸로 했으므로 기본적으로 내림차순으로 작업합니다. 또는 오름차순을 사용할 수도 있지만 처음부터 5 대신 모음 끝에서 지점 5를 지정하십시오.

다른 방법이 있다는 것을 덧붙여 야합니다. 예를 들어, Boost bimap은 작업을 훌륭하게 처리합니다.이것이 숙제와 같다고 생각하면 제 생각에 사실상 전체 작업을 처리하는 bimap과 같은 미리 패키지화 된 솔루션은 허용되지 않거나 허용되지 않습니다 (심지어 std::map도 거의 동일하게 금지 될 수 있습니다 이유).

0

외부 루프 시작 인덱스 i가 제로의 거래 횟수, 및 상기 내부 루프 동일. 즉, 첫 번째 조건은 tArray[0].buyerName == calcString[0]이 루프 이전에 그런 식으로 설정 한 것과 동일한 지 확인합니다. 이로 인해 calcTotal[0]-2147483648에서 내부 루프를 벗어나 증가합니다.

나는 확신 할 수 없지만, 이것이 원하는 것 같지 않습니다.

1

동일한 구매자가 여러 번있을 수 있으므로 상위 5 개에서 제거한 구매자가 다음 중 일부가 아니어야한다는 것을 알 수있는 방법이 없으므로 모든 구매자를 위해 카운터를 저장해야합니다. 이 상위 5 개 항목 (이후 구매자에게 더 많은 항목이 나중에 tArray에 링크 될 수 있음).

키가 구매자 이름이고 값이 항목 수 인 STL 맵을 사용하는 것이 좋습니다. tArray에 반복하여 기입하고 동일한 구매자가 구입 한 모든 항목을 합칩니다. 그러면 구매자 당 하나의 항목 만 있으므로 맵에서 반복하여 상위 5 위 구매자를 쉽게 검색 할 수 있습니다.