C++ 中的简洁列表/向量

发布于 2024-10-10 07:15:16 字数 2074 浏览 0 评论 0 原文

我目前正在将 Python 中的算法翻译为 C++。

此行 EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n" ]] 现在

    vector<vector<char>> exch_symbols;

    vector<char> vector_1il;
    vector_1il.push_back('1');
    vector_1il.push_back('i');
    vector_1il.push_back('l');

    vector<char> vector_5s;
    vector_5s.push_back('5');
    vector_5s.push_back('s');

    vector<char> vector_8b;
    vector_8b.push_back('8');
    vector_8b.push_back('b');

    vector<char> vector_mn;
    vector_mn.push_back('m');
    vector_mn.push_back('n');

    exch_symbols.push_back(vector_1il);
    exch_symbols.push_back(vector_5s);
    exch_symbols.push_back(vector_8b);
    exch_symbols.push_back(vector_mn);

我讨厌为二维向量中的每个内部变量都有一个中间命名变量。我不太熟悉 C++ 中的多维数据结构。有更好的办法吗?

之后发生的事情是这样的:

multimap<char, char> exch_symbol_map;

/*# Insert all possibilities
    for symbol_set in EXCH_SYMBOL_SETS:
        for symbol in symbol_set:
            for symbol2 in symbol_set:
                if symbol != symbol2:
                    exch_symbol_map[symbol].add(symbol2)*/
void insert_all_exch_pairs(const vector<vector<char>>& exch_symbols) {
    for (vector<vector<char>>::const_iterator symsets_it = exch_symbols.begin();
        symsets_it != exch_symbols.end(); ++symsets_it) {
            for (vector<char>::const_iterator sym1_it = symsets_it->begin();
                sym1_it != symsets_it->end(); ++sym1_it) {
                    for (vector<char>::const_iterator sym2_it = symsets_it->begin();
                        sym2_it != symsets_it->end(); ++sym2_it) {
                            if (sym1_it != sym2_it) {
                                exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it));
                            }
                    }
            }
    }
}

所以这个算法应该以一种或另一种方式与这里的表示一起工作。目标是以后可以轻松更改 EXCH_SYMBOL_SETS 以包含新的 char 组或向现有组添加新字母。谢谢你!

I'm currently translating an algorithm in Python to C++.

This line EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]]
is now

    vector<vector<char>> exch_symbols;

    vector<char> vector_1il;
    vector_1il.push_back('1');
    vector_1il.push_back('i');
    vector_1il.push_back('l');

    vector<char> vector_5s;
    vector_5s.push_back('5');
    vector_5s.push_back('s');

    vector<char> vector_8b;
    vector_8b.push_back('8');
    vector_8b.push_back('b');

    vector<char> vector_mn;
    vector_mn.push_back('m');
    vector_mn.push_back('n');

    exch_symbols.push_back(vector_1il);
    exch_symbols.push_back(vector_5s);
    exch_symbols.push_back(vector_8b);
    exch_symbols.push_back(vector_mn);

I hate to have an intermediate named variable for each inner variable in a 2-D vector. I'm not really familiar with multidimensional datastructures in C++. Is there a better way?

What's happening afterwards is this:

multimap<char, char> exch_symbol_map;

/*# Insert all possibilities
    for symbol_set in EXCH_SYMBOL_SETS:
        for symbol in symbol_set:
            for symbol2 in symbol_set:
                if symbol != symbol2:
                    exch_symbol_map[symbol].add(symbol2)*/
void insert_all_exch_pairs(const vector<vector<char>>& exch_symbols) {
    for (vector<vector<char>>::const_iterator symsets_it = exch_symbols.begin();
        symsets_it != exch_symbols.end(); ++symsets_it) {
            for (vector<char>::const_iterator sym1_it = symsets_it->begin();
                sym1_it != symsets_it->end(); ++sym1_it) {
                    for (vector<char>::const_iterator sym2_it = symsets_it->begin();
                        sym2_it != symsets_it->end(); ++sym2_it) {
                            if (sym1_it != sym2_it) {
                                exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it));
                            }
                    }
            }
    }
}

So this algorithm should work in one way or another with the representation here. The goal is that EXCH_SYMBOL_SETS can be easily changed later to include new groups of chars or add new letters to existing groups. Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

蓝戈者 2024-10-17 07:15:16

我会重构,而不是 vector,使用 std::string 作为内部,即

vector<string> exch_symbols;
exch_symbols.push_back("1il");
exch_symbols.push_back("s5");
exch_symbols.push_back("b8");
exch_symbols.push_back("mn");

然后更改您的插入方法:

void insert_all_exch_pairs(const vector<string>& exch_symbols) 
{
  for (vector<string>::const_iterator symsets_it = exch_symbols.begin(); symsets_it != exch_symbols.end(); ++symsets_it) 
  {
    for (string::const_iterator sym1_it = symsets_it->begin();  sym1_it != symsets_it->end(); ++sym1_it) 
    {
      for (string::const_iterator sym2_it = symsets_it->begin(); sym2_it != symsets_it->end(); ++sym2_it) 
      {
        if (sym1_it != sym2_it)
          exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it));
      }
    }
  }
}

I would refactor, instead of vector<char>, use std::string as internal, i.e.

vector<string> exch_symbols;
exch_symbols.push_back("1il");
exch_symbols.push_back("s5");
exch_symbols.push_back("b8");
exch_symbols.push_back("mn");

then change your insert method:

void insert_all_exch_pairs(const vector<string>& exch_symbols) 
{
  for (vector<string>::const_iterator symsets_it = exch_symbols.begin(); symsets_it != exch_symbols.end(); ++symsets_it) 
  {
    for (string::const_iterator sym1_it = symsets_it->begin();  sym1_it != symsets_it->end(); ++sym1_it) 
    {
      for (string::const_iterator sym2_it = symsets_it->begin(); sym2_it != symsets_it->end(); ++sym2_it) 
      {
        if (sym1_it != sym2_it)
          exch_symbol_map.insert(pair<char, char>(*sym1_it, *sym2_it));
      }
    }
  }
}
删除→记忆 2024-10-17 07:15:16

您可以通过删除中间值来缩短它

vector<vector<char> > exch_symbols(4, vector<char>()); //>> is not valid in C++98 btw.
//exch_symbols[0].reserve(3)
exch_symbols[0].push_back('i');
etc.

您也可以使用 boost.assign 或类似的东西
EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]] 然后变成
向量<向量<字符>> exch_symbols(list_of(向量(list_of('i')('1')('l')))(向量(list_of('s')('5'))(list_of('m') ')('n'))) (未经测试,也从未将其与嵌套向量一起使用,但它应该是这样的)

You could shorten it by getting rid of the intermediate values

vector<vector<char> > exch_symbols(4, vector<char>()); //>> is not valid in C++98 btw.
//exch_symbols[0].reserve(3)
exch_symbols[0].push_back('i');
etc.

You could also use boost.assign or something similiar
EXCH_SYMBOL_SETS = [["i", "1", "l"], ["s", "5"], ["b", "8"], ["m", "n"]] then becomes
vector<vector<char>> exch_symbols(list_of(vector<char>(list_of('i')('1')('l')))(vector<char>(list_of('s')('5'))(list_of('m')('n'))) (not tested and never used it with nested vectors, but it should be something like this)

毁梦 2024-10-17 07:15:16

对于你真正的问题...

我该如何翻译 L = [A, [B],
[[C], D]]] 到 C++ ...根本!

没有直接转换 - 您已从存储相同类型的值切换为存储变量类型的值。 Python 允许这样做是因为它是一种动态类型语言,而不是因为它具有更好的数组语法。

有多种方法可以复制 C++ 中的行为(例如 boost::any 或 boost::variant 的向量,或支持此行为的用户定义的容器类),但它永远不会像 Python 中那样简单。

For your real question of...

how could I translate L = [A, [B],
[[C], D]]] to C++ ... at all!

There is no direct translation - you've switched from storing values of the same type to storing values of variable type. Python allows this because it's a dynamically typed language, not because it has a nicer array syntax.

There are ways to replicate the behaviour in C++ (e.g. a vector of boost::any or boost::variant, or a user defined container class that supports this behviour), but it's never going to be as easy as it is in Python.

屌丝范 2024-10-17 07:15:16

您的代码:

    vector<char> vector_1il;
    vector_1il.push_back('1');
    vector_1il.push_back('i');
    vector_1il.push_back('l');

简洁代码:

char values[] = "1il";
vector<char> vector_1il(&values[0], &values[3]);

您觉得可以吗?


如果您想按照 std::string >Nim,那么你甚至可以使用这个:

//Concise form of what Nim suggested!
std::string s[] = {"1il", "5s", "8b", "mn"};
vector<std::string> exch_symbols(&s[0], &s[4]);

休息你可以按照尼姆的帖子。 :-)

Your code:

    vector<char> vector_1il;
    vector_1il.push_back('1');
    vector_1il.push_back('i');
    vector_1il.push_back('l');

Concise code:

char values[] = "1il";
vector<char> vector_1il(&values[0], &values[3]);

Is it fine with you?


If you want to use std::string as suggested by Nim, then you can use even this:

//Concise form of what Nim suggested!
std::string s[] = {"1il", "5s", "8b", "mn"};
vector<std::string> exch_symbols(&s[0], &s[4]);

Rest you can follow Nim's post. :-)

不气馁 2024-10-17 07:15:16

在c++0x中指令
向量<字符串> EXCH_SYMBOL_SETS={"i1l", "s5", "b8", "mn"} ;
编译并运行良好。可悲的是,明显相似的声明
向量<向量<字符>> EXCH_SYMBOL_SETS={{'i','1','l'},{'s','5'},{'b','8'},{'m','n'}};
不起作用:-(。

这是在 g++ 4.5.0 或更高版本中实现的,您应该添加 -std=c++0x 选项。我认为此功能在 microsoft c ( VC10),不知道其他编译器的状况如何。

In c++0x the instruction
vector<string> EXCH_SYMBOL_SETS={"i1l", "s5", "b8", "mn"} ;
compiles and works fine. Sadly enough the apparently similar statement
vector<vector<char>> EXCH_SYMBOL_SETS={{'i','1','l'},{'s','5'}, {'b','8'}, {'m','n'}};
doesn't work :-(.

This is implemented in g++ 4.5.0 or later you should add the -std=c++0x option. I think this feature is not yet avaliable in microsoft c (VC10), and I don't know what's the status of other compilers.

复古式 2024-10-17 07:15:16

我知道这是一篇旧文章,但以防万一有人偶然发现它,C++ 在处理这些东西方面已经MUCH 做得更好了:

c++11 中 第一个代码块可以简单地重写为:

std::vector<std::string> exch_symbols {"1il", "5s", "8b", "mn"};

这对于 string 来说也不是特殊的,我们可以像这样嵌套 vector

std::vector<std::vector<int>> vov {{1,2,3}, {2,3,5,7,11}};

:整个代码采用 c++14 风格,并在末尾添加了 cout

#include <iostream>
#include <map>
#include <string>
#include <vector>

void add_all_char_pairs (std::multimap<char, char> & mmap, const std::string & str)
{
    // we choose not to add {str[i], str[i]} pairs for some reason...

    const int s = str.size();
    
    for (int i1 = 0; i1 < s; ++i1)
    {
        char c1 = str[i1];
        
        for (int i2 = i1 + 1; i2 < s; ++i2)
        {
            char c2 = str[i2];
            
            mmap.insert({c1, c2});
            mmap.insert({c2, c1});
        }
    }
}

auto all_char_pairs_of_each_str (const std::vector<std::string> & strs)
{
    std::multimap<char, char> mmap;
    
    for (auto & str : strs)
    {
        add_all_char_pairs(mmap, str);
    }
    
    return mmap;
}

int main ()
{
    std::vector<std::string> exch_symbols {"1il", "5s", "8b", "mn"};

    auto mmap = all_char_pairs_of_each_str(exch_symbols);
    
    for (auto e : mmap)
    {
        std::cout << e.first << e.second << std::endl;
    }
}

I know that this is an old post, but in case anyone stumbles across it, C++ has gotten MUCH better at dealing with this stuff:

In c++11 the first code block can simply be re-written in as:

std::vector<std::string> exch_symbols {"1il", "5s", "8b", "mn"};

This isn't special to string either, we can nest vector like so:

std::vector<std::vector<int>> vov {{1,2,3}, {2,3,5,7,11}};

And here's the entire code in c++14-style, with an added cout at the end:

#include <iostream>
#include <map>
#include <string>
#include <vector>

void add_all_char_pairs (std::multimap<char, char> & mmap, const std::string & str)
{
    // we choose not to add {str[i], str[i]} pairs for some reason...

    const int s = str.size();
    
    for (int i1 = 0; i1 < s; ++i1)
    {
        char c1 = str[i1];
        
        for (int i2 = i1 + 1; i2 < s; ++i2)
        {
            char c2 = str[i2];
            
            mmap.insert({c1, c2});
            mmap.insert({c2, c1});
        }
    }
}

auto all_char_pairs_of_each_str (const std::vector<std::string> & strs)
{
    std::multimap<char, char> mmap;
    
    for (auto & str : strs)
    {
        add_all_char_pairs(mmap, str);
    }
    
    return mmap;
}

int main ()
{
    std::vector<std::string> exch_symbols {"1il", "5s", "8b", "mn"};

    auto mmap = all_char_pairs_of_each_str(exch_symbols);
    
    for (auto e : mmap)
    {
        std::cout << e.first << e.second << std::endl;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文