2016-12-16 3 views
-2

Я немного ржавет с C++, и после одного дня мышления я не могу найти эффективный способ вычисления этой проблемы.C++ сортировать по возрастанию ненулевые значения

Предположим, что у меня есть массив из 5 поплавка значения

lints[5]={0, 0.5, 3, 0, 0.6}; 

Я хотел бы представить новый массив: ranks[5], который содержит восходящий знак не-0 значений массива Линц.

в этом случае ответ будет читать

ranks[1]=0; 

ranks[2]=1; 

ranks[3]=3; 

ranks[4]=0; 

ranks[5]=2; 

В этом примере 0 значения возвращает ранг 0, но они не имеют отношения, так как мне нужно только ранг положительных значений.

Заранее спасибо

редактировать: Спасибо всем за помощь, это то, что я нашел подходящий мои потребности в случае, если у вас есть та же задача :)

double lengths[5], ranks[5]; 
double temp; 
int i,j; 

lengths[0] = 2,lengths[1] = 0,lengths[2] = 1,lengths[3] = 0,lengths[4] = 4; 
ranks[0] = 1, ranks[1] = 2, ranks[2] = 3, ranks[3] = 4, ranks[4] = 5; 

for(i=0;i<4;i++){ 
    for(j=0;j<4-i;j++){ 
     if((lengths[j]>lengths[j+1] && lengths[j+1]) || lengths[j]==0){ 
      // swap lenghts 
      temp=lengths[j]; 
      lengths[j]=lengths[j+1]; 
      lengths[j+1]=temp; 
      // swap ranks 
      temp=ranks[j]; 
      ranks[j]=ranks[j+1]; 
      ranks[j+1]=temp; 
     } 
    } 
}  

ура.

+0

вы можете сортировать вектор-структуры, которая содержит номера и исходное положение в массиве. После сортировки вы можете использовать исходный индекс для создания желаемого массива – user463035818

+2

'ranks [5] = 2;' У вас есть неопределенное поведение –

+0

он означает ранги [4] == 2 должно быть истинным – cokceken

ответ

0

Вы можете использовать любой алгоритм сортировки с простым добавлением. При замене двух значений вы также можете менять значения индекса.

Создание значений индексов для исходных индексов

ranks[5] = {1,2,3,4,5}; //or 0,1,2,3,4 

for (int i = 0 ; i < 5 ; i++){ 
    for(int j = 0 ; j < 5 ; j++){ 
     //if array[i] < array[j] 
     //swap array[i] - array[j] 
     //swap ranks[i] - ranks[j] 
    } 
} 
+0

Спасибо за ваш ответ, однако, я думаю, ваши решения также сортируют 0 значений. Я бы хотел, чтобы код либо игнорировал их, либо оценивал их как длительность. –

+0

Вы можете написать свою логику. Просто измените часть swap – cokceken

0

Как @cokceken сказал (я знаю ответы не должны ссылаться на другие ответы, но я не достаточно высокий ранг Stack Overflow комментировать ответы: /) , используйте любой простой алгоритм сортировки и просто добавьте свои собственные функции для любых особых случаев, таких как значения 0 или отрицательные значения в вашем примере.

Например, если вы на самом деле не хотите, чтобы отсортировать исходный массив и просто создать новый массив, который связывает индексы в массиве их отсортированного ранга,

array[arraySize] = // insert array here; 
ranks[arraySize]; 

for (int i = 0; i < arraySize; i++){ 
    int indexRank = 0; 
    for (int j = 0; j < arraySize; j++){ 
     if (array[j] < array[i]){ 
      indexRank++; 
     } 
    } 
    if (array[i] <= 0) { 
     ranks[i] = -1 // or whatever implementation you want here 
    } else { 
     ranks[i] = indexRank; 
    } 
} 

(обратите внимание, что ARRAYSIZE должен быть значение, а не переменная, так как C++ не позволяет статически определять массив с переменным размером)

+0

спасибо за ваш комментарий! –

0

Я нашел, что это было проще, если вы сохраняете отдельные значения для значения, исходного положения и ранга в классе:

#include <vector> 
#include <iostream> 
#include <algorithm> 

struct Item { 
    float value; 
    int original_position; 
    int rank; 
}; 

int main() { 
    float lints[5] = {0, 0.5, 3, 0, 0.6}; 
    std::vector<Item> items{}; 
    int index{}; 
    for(auto i : lints) 
     items.push_back(Item{i,index++,0}); // assign index to original_position 
    std::sort(items.begin(), items.end(), [](auto& l, auto& r) {return l.value < r.value; }); // sort by float value 
    auto it = std::find_if(items.begin(), items.end(), [](auto& i) {return i.value > 0; }); // find first non-zero position (as iterator) 
    int new_rank_value{1}; // start numbering non-zero numbers from 1 
    std::for_each(it, items.end(), [&new_rank_value](auto& i) {i.rank = new_rank_value++; }); // assign non-zero numbers a rank value 
    std::sort(items.begin(), items.end(), [](auto& l, auto& r) {return l.original_position < r.original_position ; }); // sort by original position again 
    for(auto i : items) 
     std::cout << "ranks[" << i.original_position << "]=" << i.rank << ";\n"; 
} 

Выход:

ranks[0]=0; 
ranks[1]=1; 
ranks[2]=3; 
ranks[3]=0; 
ranks[4]=2; 
+0

спасибо за ваш комментарий! –

Смежные вопросы