简化分子和分母的最快方法

Fastest way to simplify numerator and denominator

本文关键字:方法      更新时间:2023-10-16

比如说,我有两个序列。其中一个可以是分子,第二个是分母。两个序列可能包含相同的变量。去除分子和分母中重复变量的最快算法是什么?

示例:初始序列。

A * B * C * D * O * V
---------------------
B * O * N * A * C

预期成果:A、B、C、O本应消失。

D * V
-----
N

我目前的唯一想法是创建两个数组并使用两个循环来查找和删除匹配的元素。也许有更好的解决方案?

你应该看看std::set_interaction,它可以用来从两个排序集合中确定公共数字。

例如

 std::vector< int > inter;
 std::set_intersection (numerator.begin ( ), numerator.end ( ), 
                        denominator.begin ( ), denominator.end ( ), 
                        std::back_inserter (inter));

现在要删除分子中的常用数字:

 if (inter.size() != 0)
 {
   std::vector<int> leftn;
   std::set_difference (numerator.begin ( ), numerator.end ( ), 
   inter.begin ( ), inter.end ( ), std::inserter (leftn, leftn.begin ( )));
   ...
 then do the same for denominator

但是,我认为您应该首先确保您的分母和分子被分成素数,然后再尝试上述方法以获得最佳结果

例如

  2 * 4               4 
  -----  would yield ---   which obviously could be simplified more
  2 * 2               2
  2 * 2 * 2           2
  ---------   -->    ---
    2 *  2            1

但也许你已经这样做了。

编辑:排序集合

这是我的解决方案对分子和分母进行排序,然后比较相等的范围

std::vector<std::string> num = {"A", "B", "C", "D", "O", "V"};
std::vector<std::string> den = {"B", "O", "N", "A", "C"};
// sort to compare equal_ranges
std::sort(std::begin(num), std::end(num));
std::sort(std::begin(den), std::end(den));
decltype(std::equal_range(std::begin(num), std::end(num), "")) num_er{std::begin(num), std::begin(num)};
decltype(std::equal_range(std::begin(den), std::end(den), "")) den_er{std::begin(den), std::begin(den)};
while(num_er.second != std::end(num) && den_er.second != std::end(den))
{
    // next value to check (numerator or denominator?)
    auto v = num_er.second;
    if(*den_er.second < *v)
        v = den_er.second;
    // find the equal ranges
    num_er = std::equal_range(num_er.second, std::end(num), *v);
    den_er = std::equal_range(den_er.second, std::end(den), *v);
    // count the number of this value for num and den
    auto num_size = std::distance(num_er.first, num_er.second);
    auto den_size = std::distance(den_er.first, den_er.second);
    // erase from either num or den (or both)
    if(num_size >= den_size)
        num_er.second = num.erase(num_er.second - den_size, num_er.second);
    if(den_size >= num_size)
        den_er.second = den.erase(den_er.second - num_size, den_er.second);
}
for(auto const& s: num)
    std::cout << s << ' ';
std::cout << 'n';
std::cout << "-------------------" << 'n';
for(auto const& s: den)
    std::cout << s << ' ';
std::cout << 'n';

输出:

D V 
-------------------
N