【问题标题】:n choose k implementation with conditionn 选择有条件的 k 个实现
【发布时间】:2014-05-31 08:09:50
【问题描述】:

我使用了本主题中的代码 https://stackoverflow.com/a/5097100/3617657

我对其进行了一些编辑以使用 std::vector<std::vector<int>> 而不是 std::vector<int>

在我的例子中,K 有不同的值(从 1 到 4),而不是只有一个值

示例:我的数据

1 2 3 4
1 2 4
1 3

如果 k=3, 那么对于我数据中的每一行n 选择 k=

123
124
134
234

124

13

但我希望我的结果在地图中,其中的值表示子集的频率为:

(123, 1)
(124, 2)
(134, 1)
(234, 1)

(13, 1)

这是我的代码

std::vector<std::vector<int>> data;

std::map <int, set<int>> CandidateSet;
typedef std::pair<set<int>, int> combo;
std::map <int, combo> CandidateSup;





void ScanData()
{
    ifstream in;
    in.open("mydata.txt");
    /* mydata.txt
    1 2 3 4 5
    1 3 4 5
    1 2 3 5
    1 3
    */
    std::string line;
    int i = 0;

    while (std::getline(in, line))
    {
        std::stringstream Sline1(line);
        std::stringstream ss(line);
        std::vector<int> inner;
        int info;

        while (ss >> info)
            inner.push_back(info);

        data.push_back(inner);
    }
}



int main()
{
    ScanData();
    std::size_t k = 0;
    int j = 0;
    int c = 0;
    int supp = 1;
    int Lsize = 1; 
    while (Lsize <= 4) 
    {
        for (unsigned i = 0; i < data.size(); ++i)
        {
            std::vector<int>::iterator items = data[i].begin();
            if (Lsize > data[i].size())
                k = data[i].size();
            else
                k = Lsize;

            do
            {
                for (std::vector<int>::iterator items = data[i].begin(); j < k; ++items)
                {
                    CandidateSet[c].insert(*items);
                    ++j;
                }

                ++c;
                std::cout << "\n";
                j = 0;

            } 
            while (next_combination(data[i].begin(), data[i].begin() + k, data[i].end()));



        /****************************************************************************************************************************** 
            //here my problem
            // check if the (next_combination) is already exist in CandidateSet, if yes add one to existing support

            auto it = CandidateSet.begin();
            set <int> A = it->second;
            set <int> B;

            B = CandidateSet[*items]; // I don't know how to set be as the next_combination


            while (it != CandidateSet.end())
            { // if it found 
                if (!(A < B) && !(B < A))
                {
                    CandidateSup[*items] = std::make_pair(A, ++supp);
                    break;
                }
                else
                { // if not found yet
                    ++it; 
                    A = it->second;
                }
            }//  end while

            // if it is not exist, add this new set with support =1
            ++c;
            CandidateSup[c] = std::make_pair(B, supp);
        /******************************************************************************************************************************/

        }
        ++Lsize;

    }

    data.clear();





    system("PAUSE");
    return 0;
}

这个“combination.h”

template <typename Iterator>
inline bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
    /* Credits: Thomas Draper */
    if ((first == last) || (first == k) || (last == k))
        return false;
    Iterator itr1 = first;
    Iterator itr2 = last;
    ++itr1;
    if (last == itr1)
        return false;
    itr1 = last;
    --itr1;
    itr1 = k;
    --itr2;
    while (first != itr1)
    {
        if (*--itr1 < *itr2)
        {
            Iterator j = k;
            while (!(*itr1 < *j)) ++j;
            std::iter_swap(itr1, j);
            ++itr1;
            ++j;
            itr2 = k;
            std::rotate(itr1, j, last);
            while (last != j)
            {
                ++j;
                ++itr2;
            }
            std::rotate(k, itr2, last);
            return true;
        }
    }
    std::rotate(first, k, last);
    return false;
}

【问题讨论】:

  • 问题是什么?
  • 而不是只打印n选择k,检查next_combination微笑者是否为前一个,如果是则在此映射CandidateSup的值上加一,如果不是,则设置值=1,参见示例, ***之间的代码是我的尝试

标签: c++


【解决方案1】:

以下内容可能会有所帮助:(https://ideone.com/5EPuGd)

std::map<std::set<int>, int> counts;

for (std::size_t Lsize = 1; Lsize <= 4; ++Lsize)
{
    for (unsigned i = 0; i < data.size(); ++i)
    {
        std::size_t k = std::min(Lsize, data[i].size());

        do
        {
            std::set<int> n_k(data[i].begin(), data[i].begin() + k);
            ++counts[n_k];
        }
        while (next_combination(data[i].begin(), data[i].begin() + k, data[i].end()));
    }
}

【讨论】:

  • 我不知道该如何感谢你,我被困在这一点很长时间,并且厌倦了编写许多代码来解决它。非常感谢
  • 我添加了一个条件来生成更多的超集:用户输入特定的阈值,外部循环从 1 开始到最大的数据大小[i]。在生成第一组之后,我将每个集合擦除到阈值以下,我将擦除的集合存储在 Ls 中,然后在外部循环的第二轮中,我检查 n_k 是否在 Ls 中,然后不需要生成这个集合,我会跳转到生成下一个 n_k 程序工作,但是我有很多循环,我不知道是否有有效的方法来最小化运行时间。我希望你能看看更新,并帮助我的想法。 ideone.com/kWCzTM
猜你喜欢
  • 1970-01-01
  • 2017-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多