Whats Algorithm or code to get the ordinal position of an element in a list sorted by value in C ++

This seems like a recent question.

I will maintain a sorted list of values. I will insert elements of arbitrary value into the list. Each time I insert a value, I would like to determine its ordinal position in the list (this is the 1st, 2nd, 1000th). What is the most efficient data structure and algorithm for its implementation? Obviously, there are many algorithms that could allow you to do this, but I see no way to easily do this using the simple functions of the STL or QT template. Ideally, I would like to learn about existing open source C ++ libraries or sample code that can do this.

I can imagine how to change the B-tree or a similar algorithm for this purpose, but it seems that there should be an easier way.

Edit3:

Mike Seymour pretty well confirmed that, as I wrote in my original post, there is no way to accomplish this task using a simple STL. Therefore, I am looking for a good btree, balanced tree or similar open source C ++ template that can be executed without changes or with minimal possible changes. Pavel Shved showed that this is possible, but I would prefer not to dive into the implementation of a balanced tree of myself.

(the story should show my unsuccessful attempts to change the Mathieu code to O (log N) using make_heap)

Change 4:

- , btree a, btree ++ - . log n .

+3
8

. : node .

, node, , node. :

if (traverse to left subtree)
  index = index_on_previous_stage;
if (traverse to right subtree)
  index = index_on_previous_stage + left_subtree_size + 1;
if (found)
  return index + left_subtree_size;

O (log N), .

+7

, std::set . , , . . :

std::set<int> s;
std::pair<std::set<int>::iterator, bool> aPair = s.insert(5);
size_t index = std::distance(s.begin(), aPair.first) ;
+5

, - std:: list insert (it, value) . , ?

+1

, , , , - , :

multiset<int> values;

values.insert(value);
int ordinal = values.size() * (value - values.front()) /
                              (values.back()-values.front());

, ( , , ) . . , :

class SortedValues : public multiset<int>
{
public:
    SortedValues() : sum(0), sum2(0) {}

    int insert(int value)
    {
        // Insert the value and update the running totals
        multiset<int>::insert(value);
        sum += value;
        sum2 += value*value;

        // Calculate the mean and deviation.
        const float mean = float(sum) / size();
        const float deviation = sqrt(mean*mean - float(sum2)/size());

        // This function is left as an exercise for the reader.
        return size() * EstimatePercentile(value, mean, deviation);
    }

private:
    int sum;
    int sum2;
};
+1

, , RandomAccessContainer Concept... , std::vector.

std::vector , , std::lower_bound std::upper_bound, , , , - std::equal_range, , lower upper, .

, , , std::distance O (1) RandomAccessIterator.

typedef std::vector<int> ints_t;
typedef ints_t::iterator iterator;

ints_t myInts;

for (iterator it = another.begin(), end = another.end(); it != end; ++it)
{
  int myValue = *it;
  iterator search = std::lower_bound(myInts.begin(), myInts.end(), myValue);
  myInts.insert(search, myValue);
  std::cout << "Inserted " << myValue << " at "
            << std::distance(myInts.begin(), search) << "\n";
  // Not necessary to flush there, that would slow things down
}


// Find all values equal to 50
std::pair<iterator,iterator> myPair =
    std::equal_range(myInts.begin(), myInts.end(), 50);
std::cout << "There are " << std::distance(myPair.first,myPair.second)
          << " values '50' in the vector, starting at index "
          << std::distance(myInts.begin(), myPair.first) << std::endl;

, ?

std::lower_bound, std::upper_bound std::equal_range O (log (n)), std::distance O (1), ...

EDIT: → - O (n), .

+1

? , , , , , .

, , , , , .

0

, , std:: distance, O (1), O (n) , O (1) O (n), O (n) stl.

, , ?

0

( dtrosset), std:: distance (, std:: distance (my_list.begin(), item_it))

0

Source: https://habr.com/ru/post/1723317/


All Articles