Strange order in std::map with russian text - c++11

Easy map like this
std::map<std::string, std::vector<int>> container = {
{"первый",{1}},
{"второй",{2}},
{"третий",{3}},
{"четвертый",{ 4 }}
};
for (auto it = container.begin(); it != container.end(); ++it)
{
auto tt = it;
// do smth
}
but in order second element ({"второй",{2}},) go first
and this is text dependent - for example if second element will be with english text "second" ({"second",{2}},) - order will be normal, and this will be second element in order.
Who can explain what happened, or this is just bug in VS 2017 version 15.3 ?

In this case a better desigion will be
std::map<std::vector<int>,std::string> container = {
{{1},"первый"},
{{2},"второй"},
{{3},"третий"},
{{4},"четвертый"}
};
so std::map will be automated sorted by number keys

My mistake was that I forgott about that std::map is a sorted container, and key in my case was "первый" and "второй" - so by russian alphabet "второй" is first.
Working code look like:
std::unordered_map<std::string, std::vector<int>> container = {
{"первый",{1}},
{"второй",{2}},
{"третий",{3}},
{"четвертый",{ 4 }}
};
But remeber that unordered_map has no order guaranteed !

Related

iterator of a set inside a set is equal to the insider set.begin()?

for example :
set<set<T>> outer_set;
set<T> insider_set1, insider_set2;
T a;
insider_set1.insert(a);
outer_set.insert(insider_set1);
outer_set.insert(insider_set2);
set<T>::iterator chosen_itr;
for(auto temp_set: outer_set){
if(temp_set.count(a)){
chosen_itr = temp_set.begin();
break;
}
}
T b = something(...);
*chosen_itr.insert(b);
will this code add b to the insider_set1 inside of outer_set or the chosen_itr belongs to a temporary set that was created at
auto temp_set
if chosen_itr is some random iterator how to get the real one??
As you point out in your question, you're keeping a pointer (iterator) into a temporary. You should use a reference instead:
for(auto& temp_set: outer_set){
Then the given code would be valid, with one more simple change:
chosen_itr->insert(b);
1. > iterator of a set inside a set is equal to the insider set.begin()?
no it insider_set1.begin() will point to the first element in the insider_set
to get an iterator (pointer) to the set it self the for(auto set1: outsider_sit) cant be used instead, which i was trying to avoid, is to use
for(auto itr = outsider_set.begin(); ire != outsider_set.end(); ++itr)
and then save the itr value at the chosen set.
2. will this work ?
no the itr iterator to a set> is an iterator to a constant, sets is immutable in c++ and the values inside a set can not be changed after being add even if those values are containers.
3. how to add b to a set inside the outsider_set ??
sense we cant change the values inside the set we have to remove the old value(insider_set) and insert a new value(insider_set) after being updated like so:
set<set<T>> outer_set;
set<T> insider_set1, insider_set2;
T a;
insider_set1.insert(a);
outer_set.insert(insider_set1);
outer_set.insert(insider_set2);
set<T> chosen_set;
set<T>::iterator chosen_itr; // not needed now
for(auto temp_set: outer_set){
if(temp_set.count(a)){
//chosen_itr = temp_set.begin(); // not working
chosen_set = temp_set;
break;
}
}
T b = something(...);
outsider_set.erase(chosen_set);
chosen_set.insert(b)
outsider_set.insert(chosen_set);
this solution may not be efficient but I think is the only way, besides using const_cast to insert, if any have better one please mention it.

Find element that goes before target with C++ set

I know there's lower_bound and upper_bound method which both find first element that doesn't go before target element, include and exclude the target. But I need a method that can find the last element that goes before target. Is there such method or easy way to do this using set?
Thanks!
You could just decrement the lower bound?
In general you need to check if the lower bound yields the begin() iterator, in which case the element you mention doesn't exist.
Here's some example code (untested, just to give the idea):
template<typename T>
std::set<T>::iterator get_last_before(std::set<T> & s, const T & t) {
auto it = s.lower_bound(t);
if (it == s.begin()) { throw std::runtime_error(); }
return --it;
}

Why auto iteration in C++ cannot perform operation on the element it points to?

I just spent ~2 on trying to figure out a bug introduced to my code due to the usage of auto iteration for containers. I started using it couple of days ago, without doing much background check, just because I found it easier to write.
I have the following map: std::map<int, VectorList>, where VectorList is just a typedef std::vector<double> VectorList.
I wanted to perform .clear() operation on the std::vector<double> of the VectorList.
I tried the following:
std::map<int, VectorList> map;
for(auto elem : map)
{
elem.second.clear();
}
and it did not work. The clear operation was not being performed on the VectorList. However when I was performing .empty() check on it, it would return True.
Then I went back to this approach:
for(std::map<int, VectorList>::iterator elem = map.begin(); elem != map.end(); ++elem)
{
elem->second.clear();
}
And everything worked as expected.
Question:
Why auto iteration does not perform the .clear() operation as expected? Can this be achieved with auto iteration at all?
Because elem is created by value. If you want to modify the value in the loop then loop using references:
for(auto& elem : map)

C#/MVC can I manually append multiple Enum Flags in a foreach loop?

I've seen ways of using HTML Helpers and such to deal with enums in MVC. I've taken a different approach in that I pass a string[] of the checked boxes back to the controller. I am doing this:
foreach (string svf in property.SiteVisibilityFlags)
{
Enums.SiteVisibilityFlags flagTester;
if (Enum.TryParse<Enums.SiteVisibilityFlags>(svf, out flagTester))
{
// add to domainProperty
domainProperty.SiteVisibilityFlags = flagTester; <--Here is where I mean
}
}
Now, I know that normally, with a flagged enum you do something like:
domainProperty.SiteVisibilityFlags = Enums.SiteVisibilityFlags.Corporate | Enums.SiteVisibilityFlags.Properties;
So, if/how can I accomplish the '|'... in this methodology?
You could use the [FlagAttribute] explained here.
From there you can simply use the bit-or (|) operator as follows
domainProperty.SiteVisibilityFlags |= flagTester;
Also there is a really good explanation with examples on stackoverflow about attribute
figured it out. Any enum that has [Flags] as an attribute can be solved by summing up the values of all checked items like this:
// Site Visibility Flags
int SiteVisibilityTotalValue = 0;
foreach (string svf in property.SiteVisibilityFlags)
{
Enums.SiteVisibilityFlags flagTester;
if (Enum.TryParse<Enums.SiteVisibilityFlags>(svf, out flagTester))
{
// sum up values to get total to them convert to enum
SiteVisibilityTotalValue += (int)flagTester;
}
}
// convert total to Enum
domainProperty.SiteVisibilityFlags = (Enums.SiteVisibilityFlags)SiteVisibilityTotalValue;

Print a simply linked list backwards with no recursion, in two passes at most, using constant extra memory, leaving it intact

You must print a simply linked list backwards:
Without recursion
With constant extra memory
In linear time
Leaving the list intact
Added Later Two passes at most
Invert the list, print it forwards, invert again. Each step can be done without violating restrictions except the last one.
EDIT: As cube notes in the comments the second and the third stages can be combined into one pass. This gives two passes – first reverse, then print while reversing again.
Building on sharptooth's reply, you can combine the printing and second inversion in the same pass.
Edit: The "list is left intact" from a single-threaded view because the post-condition equals the pre-condition.
Edit 2: Not sure how I got the answer, but I'll take it since I've hit the rep cap for the day. I gave sharptooth a +1 too.
Here's a C# implementation that holds for all the current rules. It mutates the list during the execution, but the list is restored before returning.
using System;
using System.Diagnostics;
namespace SO1135917.Classes
{
public class ReverseListPrinter
{
public static void Execute(Node firstNode, Action<Node> action)
{
Reverse(Reverse(firstNode, null), action);
}
private static Node Reverse(Node firstNode, Action<Node> action)
{
Node node = firstNode;
Debug.Assert(node != null);
Node nextNode = node.Next;
node.Next = null;
while (node != null)
{
if (action != null)
action(node);
if (nextNode == null)
break;
Node nextNode2 = nextNode.Next;
nextNode.Next = node;
node = nextNode;
nextNode = nextNode2;
}
return node;
}
}
}
There is one problem, however, and that is that the state of the list is undefined if an exception should occur in the above methods. Probably not impossible to handle though.
A subversion repository of the above code, with unit tests, for Visual Studio 2008 is available here, username and password is both 'guest' without the quotes.
You can first check the length of the list. Then create a print-buffer, which you fill in backwards as you traverse the list once again for the information.
Or
You can create another linked list where you add all the printing data in the front when you traverse the first list, and then print the second list from front to back.
Either way makes only two passes at most. The first idea could be done in one pass if you have a header struct that keeps track of the amount of elements in the list.
Edit: I just realised that these ideas does not use constant memory.
The only way to do this sensibly seems to be Sharptooths reply, but that requires three passes.
a function like the following might solver your issue:
void invert_print(PtNo l){
PtNo ptaux = l;
PtNo last;
PtNo before;
while(ptaux != NULL){
last = ptaux;
ptaux = ptaux->next;
}
while(ptaux != last){
printf("%s\n", last->info.title);
ptaux = l;
before = last;
while(ptaux != before){
last = ptaux;
ptaux = ptaux->next;
}
}
}
you will need a structure like the following:
typedef struct InfoNo{
char title20];
}InfoNo;
typedef struct aPtNo{
struct InfoNo info;
struct aPtNo* nextx;
}*PtNo;
Objective-C Link class with reverse method:
Link.h
#import <Foundation/Foundation.h>
#interface Link : NSObject
#property(nonatomic) int value;
#property(nonatomic) Link *next;
- (Link*)reversedList;
#end
Link.m
#import "Link.h"
#implementation Link
- (Link*)reversedList {
Link* head;
Link *link = self;
while (link) {
// save reference to next link
Link *next = link.next;
// "insert" link at the head of the list
link.next = head;
head = link;
// continue processing the rest of the list
link = next;
}
return head;
}
#end

Resources